I can't bind my texture to the sampler2D in the fragment shader. In theory my program should draw the whole scene in one color (My image is a red, 64x64 large square). When using textureSize to get the sampler2D's dimensions, it return 1x1.
Neither the TextureID or the SamplerLocation return -1
What I am doing at the moment:
- Load the image into the gpu memory and get the Location (int TextureID) with loadImage().
- Get the UniformLocation of my sampler2D (int SamplerLocation)
- In the render method: Bind the texture and set the uniform location accordingly
SourceCode:
loadImage Method copied from http://neokabuto.blogspot.de/
int loadImage(Bitmap image)
{
int texID = GL.GenTexture();
GL.BindTexture(TextureTarget.Texture2D, texID);
BitmapData data = image.LockBits(new System.Drawing.Rectangle(0, 0, image.Width, image.Height),
ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0,
OpenTK.Graphics.OpenGL4.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
image.UnlockBits(data);
GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
return texID;
}
OnLoad Method called once on startup
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
int status_code;
string info;
Console.Out.WriteLine(GL.GetString(StringName.Version));
m.loadFromOBJ("C:/Users/Anwender/Downloads/lpm_yard.obj");
m.init();
TextureID = loadImage("C:/Users/Anwender/Desktop/test.png");
// Setup openGL
GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
// Create MVP-Matrices and Camera Data
ProjectionMatrix = Matrix4.CreatePerspectiveFieldOfView(MathHelper.PiOver4, Width / (float)Height, 0.5f, 10000.0f);
WorldMatrix = new Matrix4();
ModelviewMatrix = new Matrix4();
CameraPosition = new Vector3(0.5f, 0.5f, 0);
defaultPickSSB = new PickSSB();
defaultPickSSB.DepthValue = float.MaxValue;
defaultPickSSB.PickIndex = -1;
string VertexSource = File.ReadAllText("C:/Users/Anwender/Source/Repos/ShaderDemo/ShaderDemo/Shader/vs.glsl");
string FragmentSource = File.ReadAllText("C:/Users/Anwender/Source/Repos/ShaderDemo/ShaderDemo/Shader/fr.glsl");
// Create Shaders
int VertexID = GL.CreateShader(ShaderType.VertexShader);
int FragmentID = GL.CreateShader(ShaderType.FragmentShader);
// Compile vertex shader
GL.ShaderSource(VertexID, VertexSource);
GL.CompileShader(VertexID);
GL.GetShaderInfoLog(VertexID, out info);
GL.GetShader(VertexID, ShaderParameter.CompileStatus, out status_code);
if (status_code != 1)
throw new ApplicationException(info);
// Compile fragment shader
GL.ShaderSource(FragmentID, FragmentSource);
GL.CompileShader(FragmentID);
GL.GetShaderInfoLog(FragmentID, out info);
GL.GetShader(FragmentID, ShaderParameter.CompileStatus, out status_code);
if (status_code != 1)
throw new ApplicationException(info);
// Create and Link Program
Program = GL.CreateProgram();
GL.AttachShader(Program, FragmentID);
GL.AttachShader(Program, VertexID);
GL.BindFragDataLocation(Program, 0, "color");
GL.LinkProgram(Program);
GL.UseProgram(Program);
// Get Buffer Locations
PickColorLocation = GL.GetAttribLocation(Program, "vertex_pick_index");
PositionLocation = GL.GetAttribLocation(Program, "vertex_position");
NormalLocation = GL.GetAttribLocation(Program, "vertex_normal");
ColorLocation = GL.GetAttribLocation(Program, "vertex_color");
UniformMVPMatrixLocation = GL.GetUniformLocation(Program, "mvp_matrix");
UniformMouseXLocation = GL.GetUniformLocation(Program, "mouse_x");
UniformMouseYLocation = GL.GetUniformLocation(Program, "mouse_y");
SamplerLocation = GL.GetUniformLocation(Program, "main_texture");
GL.GenBuffers(1, out SSB);
GL.BindBuffer(BufferTarget.ShaderStorageBuffer, SSB);
GL.BufferData(BufferTarget.ShaderStorageBuffer, (IntPtr)(4 * sizeof(float)), ref defaultPickSSB, BufferUsageHint.DynamicCopy);
GL.BindBufferBase(BufferRangeTarget.ShaderStorageBuffer, 0, SSB);
GL.UseProgram(0);
}
OnRenderFrame Method
protected override void OnRenderFrame(FrameEventArgs e)
{
base.OnRenderFrame(e);
GL.Viewport(0, 0, Width, Height);
GL.ClearColor(0.0f, 0.8f, 0.8f, 1.0f);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.UseProgram(Program);
GL.BindTexture(TextureTarget.Texture2D, TextureID);
GL.Uniform1(SamplerLocation, TextureID);
m.draw(PositionLocation, NormalLocation, ColorLocation, PickColorLocation);
GL.UseProgram(0);
SwapBuffers();
}
My fragment shader:
#version 430
in vec4 frag_color;
in vec4 gl_FragCoord;
flat in int frag_pick_index;
out vec4 color;
layout (std430, binding = 0) buffer mouse_color { int pick_index; float depth_value; };
uniform int mouse_x;
uniform int mouse_y;
uniform sampler2D main_texture;
void main(void)
{
if (int(gl_FragCoord.x) == mouse_x && int(gl_FragCoord.y) == mouse_y) {
if (gl_FragCoord.z < depth_value)
{
pick_index = frag_pick_index;
depth_value = gl_FragCoord.z;
}
}
// pick_index = textureSize(main_texture, 0).y;
if (int(gl_FragCoord.x) == mouse_x || int(gl_FragCoord.y) == mouse_y) {
color = vec4(0.0f, 1,0,1.0f);
} else {
color = frag_color;
}
color = texture(main_texture, vec2(0.5f, 0.5f));
}