无法在OpenGL着色器中设置统一变量的值

6

我正在尝试让简单的着色器工作。更具体地说,我正在尝试设置着色器的一个统一变量值。如果我消除统一变量值,着色器会成功编译并正常工作。以下是(顶点)着色器代码:

#version 440 core

layout(location = 0) in vec3 vertex;

uniform mat4 mvp;

void main()
{
    gl_Position = mvp * vec4(vertex, 1);
}

我使用以下代码设置值(glGetUniformLocation按预期返回0):

mvp = glm::mat4(
    glm::vec4(3.0f, 0.0f, 0.0f, 0.0f),
    glm::vec4(0.0f, 1.0f, 0.0f, 0.0f),
    glm::vec4(0.0f, 0.0f, 1.0f, 0.0f),
    glm::vec4(0.0f, 0.0f, 0.0f, 2.0f)
);

GLuint matrix = glGetUniformLocation(program, "mvp");
glUniformMatrix4fv(matrix, 1, GL_FALSE, glm::value_ptr(mvp));

问题在于它似乎根本没有设置值。如果我使用glGetUniformfv查询uniform的值,它返回默认值(而不是我刚刚设置的值),并且几何图形根本不显示(但这只是一个结果,这不是问题所在)。
如果我在着色器中硬编码uniform的值,则应用程序会正确显示几何图形,并且当再次请求值时(同样使用glGetUniformfv),它返回正确的值。
#version 440 core

layout(location = 0) in vec3 vertex;

uniform mat4 mvp = mat4(
    vec4(1.0f, 0.0f, 0.0f, 0.0f),
    vec4(0.0f, 1.0f, 0.0f, 0.0f),
    vec4(0.0f, 0.0f, 1.0f, 0.0f),
    vec4(0.0f, 0.0f, 0.0f, 2.0f)
);

void main()
{
    gl_Position = mvp * vec4(vertex, 1);
}

你有没有想过为什么会出现这种情况?我正在使用OpenGL 4.4,但我尝试了许多不同的版本,结果都一样。

1个回答

14
你是否在设置uniform之前调用了glUseProgram函数?许多在线示例中都可以找到完整的工作代码,包括我之前写过的(Github: sgxperf/sgxperf_gles20_vg.cpp),其中显示了正确的调用顺序:
glCreateProgram()
glAttachShader()
glLinkProgram()
glUseProgram()
glGetUniformLocation()
glUniformMatrix4fv() 

1
你真是救星,谢谢。我没有意识到在设置uniform之前必须调用glUseProgram,但实际上这是有道理的。 - skreborn
1
“glUseProgram()”和“glGetUniformLocation()”实际上可以交换使用,对吗? - mlvljr
2
不行,因为glUseProgram首先设置正确的状态,而glGetUniformLocation依赖于该状态来获取uniform的位置。 - Prabindh
2
@mlvljr 我认为它们可以交换,因为glGetUniformLocation将要查询的程序作为第一个参数,所以它可以在使用之前进行查询。(实验也证实了这一点。)文档没有说明在查询之前应该使用程序。 - Sipka

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接