c++ - OpenGL改变统一改变先前的绘制
问题描述
我有这个示例代码
// 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 等。您可以在此处
查看完整代码
解决方案
触发此问题的实际源代码是这样的:
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);
结合一些包含这些方法的着色器类:
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); }
This means that shader.Set("shift", 0);
does call the int32
overload, resulting in trying to use glUniform1i
to set a float
uniform, which will just produce a GL error and not change the uniform at all. THe first frame will acutally be correct since the uniform is intialized to 0 by default, but after that, it will stay on 0.5
forever. Use shader.Set("shift", 0.0f);
, but IMO, that kind of overloads is doing more harm than good.
Side note: Those glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
calls are not necessary, the VAO will store the GL_ELEMENT_ARRAY_BINDING
.
推荐阅读
- typescript - 在函数中接受混合类型元组而不丢失类型检查
- python - 英文数字转整数(迭代函数)
- python - 如何使用 python playwright 读取 span 类的内容
- amazon-web-services - AWS Lambda 层文件位置
- types - 为什么向 HashMap 中插入值总是导致值为 None?
- java - 通过调用其对象名称从数组中删除和对象
- javascript - decodeURIComponent() 抛出格式错误的 URI 序列
- python - pymongo 查询现有集合
- excel - 将列从一张工作表复制到新工作表
- bash - BubbleSort Bash 没有排序