How can I debug OpenTK?
Trying to make a game but textures never reach the screen.
Using just colors for quads works but when I try to texture the quads, it just shows up as black squares.
basic fragment shader:
#version 300 es
precision highp float;
uniform sampler2D SS;
in vec4 Color;
in vec2 UVtrans;
out vec4 color;
void main()
{
color = texture(SS, UVtrans);
//color = Color;
}
vertex shader:
#version 300 es
layout(location = 0) in vec2 Vertex;
layout(location = 1) in vec2 UV;
uniform vec4 ColorIn;
uniform mat4 QuadMatrix;
out vec2 UVtrans;
out vec4 Color;
void main()
{
gl_Position = QuadMatrix* vec4(Vertex, 0.0, 1.0);
gl_Position.w = 1.0;
UVtrans = UV;
Color = ColorIn;
}
part of the code that's used for binding the textures to the quads:
public void Draw()
{
GL.UseProgram(VSID);
Vector3 SS = new Vector3((new Vector(1, 1) * (Position - Offset)));
SS.Z = Layer * 0.1f;
Matrix4 Scale = Matrix4.CreateScale(Width, Height, 0);
Matrix4 Translation = Matrix4.CreateTranslation(SS);
Matrix4 ViewPoint = Matrix4.CreateOrthographic(Game.window.Width , Game.window.Height, -1,1000);
Matrix4 Rotation = Matrix4.CreateRotationZ((float)Angle);
Matrix4 Combined = Scale * Rotation * Translation * ViewPoint ;
GL.ProgramUniformMatrix4(VSID, GL.GetUniformLocation(VSID, "QuadMatrix"), false, ref Combined);
GL.ProgramUniform4(VSID, GL.GetUniformLocation(VSID, "ColorIn"), Color);
GL.ProgramUniform1(VSID, GL.GetUniformLocation(VSID, "SS"), Texture);
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, 0);
GL.BindVertexArray(QID);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
GL.Enable(EnableCap.Texture2D);
GL.Color3(Color);
}
shape maker for the quads:
public static void CreateQuad()
{
QID = GL.GenVertexArray();
GL.BindVertexArray(QID);
int VID =GL.GenBuffer();
float[] Verticles =
{
-0.5f, 0.5f,
0.5f, 0.5f,
-0.5f, -0.5f,
-0.5f, -0.5f,
0.5f, 0.5f,
0.5f, -0.5f
};
GL.BindBuffer(BufferTarget.ArrayBuffer, VID);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float)*Verticles.Length, Verticles,BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(0, 2, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(0);
int UVID = GL.GenBuffer();
float[] UVs =
{
0, 1,
1, 1,
0, 0,
0, 0,
1, 1,
1, 0
};
GL.BindBuffer(BufferTarget.ArrayBuffer, UVID);
GL.BufferData(BufferTarget.ArrayBuffer, sizeof(float) * UVs.Length, UVs, BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(1);
}
texture loader:
public static int LoadTexture(string path)
{
if (!File.Exists("Content/" + path))
{
throw new FileNotFoundException("file not found at Content/" + path);
}
int ID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, ID);
Bitmap BMP = new Bitmap("Content/" + path);
BitmapData data = BMP.LockBits(
new Rectangle(0, 0, BMP.Width, BMP.Height),
ImageLockMode.ReadOnly,System.Drawing.Imaging.PixelFormat.Format32bppArgb);
//int ID = GL.GenTexture();
//GL.BindTexture(TextureTarget.Texture2D, ID);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height,
0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
BMP.UnlockBits(data);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)TextureWrapMode.Clamp);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
return ID;
}
no error messages
Solution 1:
The value which has to be set to the texture sampler uniform is not the texture object (name) value. It has to be the index of the texture unit. This means 0 for TextureUnit.Texture0
, 1 for TextureUnit.Texture1
...
GL.ProgramUniform1(VSID, GL.GetUniformLocation(VSID, "SS"), Texture);
GL.ProgramUniform1(VSID, GL.GetUniformLocation(VSID, "SS"), 0);
But you've to bind the texture object to the texture unit which is set to the uniform, before the object is drawn:
GL.ActiveTexture(TextureUnit.Texture0);
GL.BindTexture(TextureTarget.Texture2D, Texture);
GL.BindVertexArray(QID);
GL.DrawArrays(PrimitiveType.Triangles, 0, 6);
Note, BindTexture
bind a named texture object to the active texture unit of the specified target. The active texture unit is set by ActiveTexture
.
The binding point between the texture sampler uniform and the texture is the index of the texture unit.
In OpenGL ES 3.2 respectively GLSL ES 3.2, the Binding point can also be set in shader code (similar the attribute location):
layout(binding = 0) uniform sampler2D SS;