OpenGL 改变制服改变之前的绘制
OpenGL changing uniform changes previous draw
我有这个示例代码
// EBO is just a rectangle
// copypasted from learnopengl
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glUniform1f(glGetUniformLocation(shaderId, shiftName), 0); //shiftName is string "shift"
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUniform1f(glGetUniformLocation(shaderId, shiftName), 0.5);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glFlush();
SDL_GL_SwapWindow(window);
我拥有的着色器:
顶点:
#version 330 core
layout (location = 0) in vec3 pos;
out vec4 vertexColor;
uniform float shift = 0;
void main()
{
gl_Position = vec4(pos.x, pos.y - shift, pos.z, 1.0);
vertexColor = vec4(0, shift, 0, 1.0);
}
片段:
#version 330 core
out vec4 FragColor;
in vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
根据我的理解,每次 glDraw 调用我应该得到两个矩形,一个在另一个下面,有两种颜色。但是我得到一个矩形用于第二次绘制。
我假设,这两个绘制调用实际上为我绘制了一个相同的矩形。但我显然不明白为什么。
我尝试在两者之间进行刷新,创建第二个缓冲区,在两者之间创建 glUseProgram,等等。
你可以看到完整的代码here
触发此问题的实际源代码是这样的:
shader.Select();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
shader.Set("shift", 0);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
shader.Set("shift", 0.5f);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
结合一些包含这些方法的着色器class:
void Shader::Set(const std::string& name, bool value) const {
glUniform1i(glGetUniformLocation(id, name.c_str()), (int32_t)value);
}
void Shader::Set(const std::string& name, int32_t value) const {
glUniform1i(glGetUniformLocation(id, name.c_str()), value);
}
void Shader::Set(const std::string& name, float value) const {
glUniform1f(glGetUniformLocation(id, name.c_str()), value);
}
这意味着 shader.Set("shift", 0);
确实调用了 int32
重载,导致尝试使用 glUniform1i
设置 float
制服,这只会产生 GL 错误并且根本不改变制服。第一帧实际上是正确的,因为制服默认初始化为 0,但在那之后,它将永远保持在 0.5
。使用 shader.Set("shift", 0.0f);
,但在我看来,这种重载弊大于利。
旁注:那些 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
调用不是必需的,VAO 将存储 GL_ELEMENT_ARRAY_BINDING
.
我有这个示例代码
// EBO is just a rectangle
// copypasted from learnopengl
glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shaderId);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glUniform1f(glGetUniformLocation(shaderId, shiftName), 0); //shiftName is string "shift"
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glUniform1f(glGetUniformLocation(shaderId, shiftName), 0.5);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glFlush();
SDL_GL_SwapWindow(window);
我拥有的着色器:
顶点:
#version 330 core
layout (location = 0) in vec3 pos;
out vec4 vertexColor;
uniform float shift = 0;
void main()
{
gl_Position = vec4(pos.x, pos.y - shift, pos.z, 1.0);
vertexColor = vec4(0, shift, 0, 1.0);
}
片段:
#version 330 core
out vec4 FragColor;
in vec4 vertexColor;
void main()
{
FragColor = vertexColor;
}
根据我的理解,每次 glDraw 调用我应该得到两个矩形,一个在另一个下面,有两种颜色。但是我得到一个矩形用于第二次绘制。
我假设,这两个绘制调用实际上为我绘制了一个相同的矩形。但我显然不明白为什么。
我尝试在两者之间进行刷新,创建第二个缓冲区,在两者之间创建 glUseProgram,等等。
你可以看到完整的代码here
触发此问题的实际源代码是这样的:
shader.Select(); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); shader.Set("shift", 0); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); shader.Set("shift", 0.5f); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
结合一些包含这些方法的着色器class:
void Shader::Set(const std::string& name, bool value) const { glUniform1i(glGetUniformLocation(id, name.c_str()), (int32_t)value); } void Shader::Set(const std::string& name, int32_t value) const { glUniform1i(glGetUniformLocation(id, name.c_str()), value); } void Shader::Set(const std::string& name, float value) const { glUniform1f(glGetUniformLocation(id, name.c_str()), value); }
这意味着 shader.Set("shift", 0);
确实调用了 int32
重载,导致尝试使用 glUniform1i
设置 float
制服,这只会产生 GL 错误并且根本不改变制服。第一帧实际上是正确的,因为制服默认初始化为 0,但在那之后,它将永远保持在 0.5
。使用 shader.Set("shift", 0.0f);
,但在我看来,这种重载弊大于利。
旁注:那些 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
调用不是必需的,VAO 将存储 GL_ELEMENT_ARRAY_BINDING
.