I found Gwen a few days ago and thought it looked like the perfect GUI toolkit for my project. But oh, dear, look at all that OpenGL 2 code in the renderer. So I thought I'd write an OpenGL 3 renderer so I can actually use it, but I'm a lot more familiar with CG than GLSL and I've gotten myself stuck writing up the sample. I think if I can just get these uniform variables set, it should be basically done.
The shaders compile and link without a problem. I narrowed it down to glGetUniformLocation returning -1 for the orthographic matrix and the texture sampler, but I don't know why exactly it's doing that. The typical problem seems to be that if you aren't actually using them, they get optimized out, but I've used them both.
If anybody has any ideas, I'm all ears. Will be more than happy to post/link the full thing once it works properly. This is my first stab at GLSL, so I could easily be doing something dumb. I did just get finished setting up CG for another project, so I'm not completely clueless.
Shader Init code called after setting up the OpenGL context:
void InitializeShaders(void)
{
g_ShaderProgram = glCreateProgram();
g_VertexShader = glCreateShader(GL_VERTEX_SHADER);
g_FragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(g_VertexShader, 1, (const GLchar **)&VertexShaderData, 0);
glShaderSource(g_FragmentShader, 1, (const GLchar **)&FragmentShaderData, 0);
glCompileShader(g_VertexShader);
CheckShaderCompile(g_VertexShader);
glCompileShader(g_FragmentShader);
CheckShaderCompile(g_FragmentShader);
glAttachShader(g_ShaderProgram, g_VertexShader);
glAttachShader(g_ShaderProgram, g_FragmentShader);
glBindAttribLocation(g_ShaderProgram, 0, "position");
glBindAttribLocation(g_ShaderProgram, 1, "color");
glBindAttribLocation(g_ShaderProgram, 2, "texCoord");
glBindFragDataLocation(g_ShaderProgram, 0, "color");
glLinkProgram(g_ShaderProgram);
CheckShaderLink();
g_OrthoTransformLocation = glGetUniformLocation(g_ShaderProgram, "orthoTransform");
g_TextureLocation = glGetUniformLocation(g_ShaderProgram, "textureSampler");
}
The shaders are stored as a string in a header file, but I stripped out all the newlines and backslashes so they aren't so painful to look at.
Vertex shader:
#version 330
in vec4 position;
out vec4 outPosition;
uniform mat4x4 orthoTransform;
void main(void)
{
outPosition = position * orthoTransform;
}
Fragment shader:
#version 330
in vec2 texCoord;
in vec4 color;
out vec4 outColor;
uniform sampler2D textureSampler;
void main(void)
{
//outColor = texture(textureSampler, texCoord) * color;
outColor = vec4(1.0f, 0.0f, 0.0f, 1.0f);
}
The problem is really simple: your vertex shader does nothing, so OpenGL is optimizing it out.
In order to render a triangle, OpenGL needs a clip-space position for each of the triangle's vertices. It is the job of the vertex shader to provide this. Because OpenGL cannot tell what vertex shader output you intend to be the clip-space position, OpenGL requires that you write to gl_Position
as the output. It is legal to avoid this, which is why your shader compiles and links. But as you found, rendering fails.
First of all, glBindFragDatalocation
should bind outColor
and not color
in this case. Second, what you give the shader program are vertex attributes and not fragment attributes. The out
s of the vertex shader should match the in
s of the fragment shader.
The reason why the location of textureSampler
is -1 is because you have commented out the code.
The reason why the location of orthoTransform
is -1 is because it is actually never used and optimized out. The out
outPosition
is never used by the fragment shader which in turn causes it the orthoTransform
uniform to be optimized out.
I think what you are looking for is gl_Position
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With