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);
Шейдеры, которые у меня есть:
Vertex:
#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 и т. Д.
Вы можете увидеть полный код здесь
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
uniform, что приведет к ошибке GL и вообще не изменит форму. Первый кадр будет фактически правильным, так как по умолчанию униформа установлена на 0, но после этого она останется включенной.0.5
навсегда. Использоватьshader.Set("shift", 0.0f);
, но ИМО, такого рода перегрузки приносят больше вреда, чем пользы.
Боковое примечание: Те glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
вызовы не требуются, VAO сохранит GL_ELEMENT_ARRAY_BINDING
.