将模型统一更新为相同值时OPENGL闪烁

8e2ybdfx  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(147)

我已经在opengl中查找了几乎所有关于闪烁的相关问题。它们大多与z缓冲区或透视投影有关。然而,我在屏幕上渲染一个单独的四边形,也没有深度测试。我更新模型均匀性每一帧到相同的值,然后我得到闪烁。然而,如果我有我的对象在屏幕周围平移更新均匀性,那么一切都很好。

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。请注意,如果我取消注解上面标记的代码中的一行,闪烁就会停止。Flickering GIF

hfsqlsce

hfsqlsce1#

问题不在于代码的OpenGL部分,而在于转置模型矩阵的方式。
下面的代码


* value = mat4_transpose(*value);

将使用其转置表示覆盖value,这意味着每隔一帧屏幕都会使用错误的矩阵呈现。停止将结果存储在value中(使用局部变量),一切都应该正常。

相关问题