我在opengl中查找了几乎所有关于闪烁的相关问题。它们大多与z缓冲区或透视投影有关。然而,我在屏幕上渲染一个单一的四边形,也没有深度测试。我更新模型统一每帧到相同的值,然后我得到闪烁。然而,如果我让我的对象通过更新uniform在屏幕上平移,那么一切都很好。
mat4 model = mat4_identity();
model = mat4_translatev(make_vec3(100.0f, 200.0f, 0.0f));
vec4 color = make_vec4(1.0f, 0.8f, 0.7f, 1.0f);
mat4 projection = mat4_ortho(0.0f, 800.0f, 600.0f, 0.0f, -1.0f, 1.0f);
Shader shader("generic_shader.vs", "generic_shader.fs");
shader.use();
//shader.set_vec4("color", &color);
shader.set_mat4("model", &model);
shader.set_mat4("projection", &projection);
float vertices[] = {
0.0f, 0.0f,
0.0f, 200.0f,
200.0f, 0.0f,
200.0f, 200.0f,
};
unsigned int indices[] = {
0, 1, 2,
2, 1, 3,
};
unsigned int vao, vbo, ebo;
glGenVertexArrays(1, &vao);
glGenBuffers(1, &vbo);
glGenBuffers(1, &ebo);
glBindVertexArray(vao);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 2 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0);
while (!glfwWindowShouldClose(window))
{
float currentFrame = static_cast<f32>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
while(deltaTime < REQUIRED_FRAME_TIME)
{
currentFrame = static_cast<f32>(glfwGetTime());
deltaTime = currentFrame - lastFrame;
}
deltaTime = currentFrame - lastFrame;
lastFrame = currentFrame;
processInput(window);
glDisable(GL_DEPTH_TEST);
glClearColor(1.0f, 0.5f, 0.5f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
shader.use();
//model = mat4_translatev(make_vec3(16.0f * currentFrame, 12.0f * currentFrame, 0.0f)); // <- if I uncomment this then it does not flicker
shader.set_mat4("model", &model);
glBindVertexArray(vao);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
glBindVertexArray(0);
glfwPollEvents();
glfwSwapBuffers(window);
}
这就是shader.use做
void Shader::use()
{
glUseProgram(this->program_id);
}
我的矩阵是列主矩阵,这就是着色器函数设置统一的方式
void Shader::set_mat4(const char* uniform_name, mat4* value)
{
*value = mat4_transpose(*value);
glUniformMatrix4fv(glGetUniformLocation(this->program_id, uniform_name), 1, GL_TRUE, &value->E[0][0]);
}
processInput()
什么都不做。将其视为一个空体函数。
我正在使用我自己的数学库进行向量和矩阵运算。我试着学习opengl,并对我学到的东西做了笔记。我希望熟悉opengl工作原理的人能帮助我理解这里发生了什么。
描述闪烁的gif图。如果我取消注释上面标记的代码中的那一行,请注意闪烁停止。闪烁的GIF
问题不在于代码的OpenGL部分,而在于如何转换模型矩阵。
以下代码
*value = mat4_transpose(*value);
将用它的转置表示覆盖值,这意味着每秒钟屏幕都会用错误的矩阵进行渲染。停止将结果存储在值中(使用局部变量(,一切都应该正常。