c++openglglfwopengl-3

OPENGL flickering on updating model uniform to same value


I have looked up almost all related questions regarding flickering in opengl. They all mostly have something to do with z-buffer or perspective projection. However, I'm rendering a single quad on screen that too without depth testing. I update model uniform every frame to the same value and then I get flickering. However if I have my object translate around the screen by updating uniform then it all works fine.

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

This is what shader.use does

void Shader::use()
{
    glUseProgram(this->program_id);
}

My matrices are column major and this is how the shader function sets the uniform

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() doesn't do anything. Consider it as an empty body function.

I'm using my own math library for vector and matrix operations. I trying to learn opengl and have made notes on things I have learned. I hope someone already familiar with how opengl works can help me understand what is happening here.

A gif depicting the flickering. Please note the flickering stops if I uncomment that one line in code as marked above. Flickering GIF


Solution

  • The problem is not with the OpenGL part of your code, but with the way how you transpose your model matrix.

    The following code

    *value = mat4_transpose(*value);
    

    will override value with it's transposed representation, which means that every second frame the screen is rendered with a wrong matrix. Stop storing the result in value (use a local variable) and everything should work.