开发者

Why is glGetUniformLocation failing me?

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, b开发者_开发百科ut 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 outs of the vertex shader should match the ins 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜