为什么 glGetUniformLocation 让我失败?

发布于 2024-12-03 14:07:52 字数 2073 浏览 1 评论 0原文

几天前我找到了 Gwen,认为它看起来是适合我的项目的完美 GUI 工具包。但是哦,亲爱的,看看渲染器中的所有 OpenGL 2 代码。所以我想我应该编写一个 OpenGL 3 渲染器,这样我就可以实际使用它,但我对 CG 比 GLSL 更熟悉,而且我一直在编写示例。我想如果我能设置这些统一的变量,基本上就应该完成了。

着色器编译和链接没有问题。我将其范围缩小到 glGetUniformLocation 为正交矩阵和纹理采样器返回 -1,但我不知道它到底为什么这样做。典型的问题似乎是,如果您实际上没有使用它们,它们就会被优化掉,但我已经使用了它们。

如果有人有任何想法,我会洗耳恭听。一旦它正常工作,我们将非常乐意发布/链接完整的内容。这是我第一次尝试 GLSL,所以我很容易做一些愚蠢的事情。我刚刚完成了另一个项目的 CG 设置,所以我并不是完全一无所知。

设置 OpenGL 上下文后调用的着色器初始化代码:

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");
}

着色器作为字符串存储在头文件中,但我删除了所有换行符和反斜杠,这样它们看起来就不那么痛苦了。

顶点着色器:

#version 330

in vec4 position;
out vec4 outPosition;
uniform mat4x4 orthoTransform;
void main(void)
{
    outPosition = position * orthoTransform;
}

片段着色器:

#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);
}

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);
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温馨耳语 2024-12-10 14:07:52

问题非常简单:你的顶点着色器什么都不做,所以 OpenGL 正在优化它。

为了渲染三角形,OpenGL 需要三角形的每个顶点的剪辑空间位置。顶点着色器的工作就是提供这一点。由于 OpenGL 无法判断您打算将哪个顶点着色器输出作为剪辑空间位置,因此 OpenGL 要求您写入 gl_Position 作为输出。避免这种情况是合法的,这就是着色器编译和链接的原因。但正如您所发现的,渲染失败。

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.

随波逐流 2024-12-10 14:07:52

首先,在这种情况下,glBindFragDatalocation 应该绑定 outColor 而不是 color。其次,你给着色器程序的是顶点属性,而不是片段属性。顶点着色器的 out 应与片段着色器的 in 匹配。

textureSampler的位置之所以是-1,是因为你注释掉了代码。
orthoTransform 的位置之所以为-1,是因为它实际上从未被使用和优化过。片段着色器永远不会使用 out outPosition ,这反过来会导致它的 orthoTransform 统一被优化掉。

我认为您正在寻找的是gl_Position

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文