OpenGL меняет форму изменяет предыдущую ничью - PullRequest
0 голосов
/ 04 мая 2020

У меня есть этот пример кода

// 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 между ними и т. Д. c.
Вы можете увидеть полный код здесь

1 Ответ

4 голосов
/ 04 мая 2020

Исходный код фактический , вызвавший эту проблему, был следующим:

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.

...