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
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.