【问题标题】:OpenGL changing uniform changes previous drawOpenGL改变统一改变先前的绘制
【发布时间】:2020-08-18 08:00:31
【问题描述】:

我有这个示例代码

// 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

【问题讨论】:

  • 你在代码的什么地方指定了两种颜色?
  • 在顶点着色器中,vertexColor = ...shift...
  • " 假设两个绘图调用实际上都为我绘制了一个相同的矩形。"到目前为止,问题中提供的信息中没有任何内容支持该假设。请显示实际代码以重现问题。
  • @derhass 我在这里用我的所有代码创建了要点gist.github.com/leviska/e2c2ebb15eeb0b7a076a7daa0398ba6d
  • 请不要使用指向源代码的链接,请将相关添加到问题本身。在这种特殊情况下,甚至问题都没有缺少相关部分,它实际上包含 wrong 信息,这些信息隐藏了实际来源中的错误 - 我已经找到了。

标签: c++ opengl sdl glad


【解决方案1】:

触发这个问题的实际源代码是这样的:

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

这意味着shader.Set("shift", 0); 确实调用了int32 重载,导致尝试使用glUniform1i 设置float 统一,这只会产生一个GL 错误并且根本不会更改统一。第一帧实际上是正确的,因为制服默认初始化为 0,但在那之后,它将永远保持在 0.5 上。使用shader.Set("shift", 0.0f);,但IMO,这种过载弊大于利。

旁注:那些glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); 调用不是必需的,VAO 将存储GL_ELEMENT_ARRAY_BINDING

【讨论】:

  • 啊,我明白了。谢谢,我用 OpenGL 尝试了一切,但错过了检查我自己的代码
猜你喜欢
  • 2015-04-06
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 2013-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多