# Why is my OpenGL triangle not drawing on the screen?

I am currently following this tutorial to create a simple game engine, but I am doing it using SDL and C++. I am stumped, however, because I can't get a triangle to draw on the screen, and I'm getting no errors from OpenGL. I have read tens of questions regarding the same problem, but I have already implemented the solutions to those problems (missing VAO, missing shaders, wrong size given to glBufferData). I'm only seeing a one-coloured window.

My shaders are defined like this:

#version 330 core

layout(location = 0) in vec3 position;

void main()
{
gl_Position = vec4(position, 1.0);
}


and

#version 330 core

precision highp float;

out vec4 frag_color;

void main()
{
frag_color = vec4(0.0, 1.0, 1.0, 1.0);
}


and I load/use them like this:

void Shader::add_program(const std::string& shader_code, GLenum shader_type)
{
if (shader == 0) {
throw std::runtime_error{"Could not create shader"};
}

if (shader == GL_INVALID_ENUM) {
throw std::runtime_error{"Invalid shader type: " + std::to_string(shader_type)};
}

// Error check using glGetShaderiv

}

{
// Error checks using glGetProgramiv
}

{
}


Finally, I have the vertices of the triangle stored like this (Math::Vector3 is just a POD struct with three floats):

std::vector<Math::Vector3> vertices{
{-1.0, -1.0, 0.0},
{0.0, 1.0, 0.0},
{1.0, -1.0, 0.0}
};


and the init/draw code is:

Mesh::Mesh(const std::vector<Math::Vector3>& vertices)
{
size = vertices.size();

glGenVertexArrays(1, &vao_id);
glBindVertexArray(vao_id);

glGenBuffers(1, &vbo_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);

glBufferData(
GL_ARRAY_BUFFER,
size * sizeof(Math::Vector3),
vertices.data(),
GL_STATIC_DRAW
);
}

void Mesh::draw() const
{
glBindVertexArray(vao_id);
glBindBuffer(GL_ARRAY_BUFFER, vbo_id);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

glDrawArrays(GL_TRIANGLES, 0, 3);
glDisableVertexAttribArray(0);
}


On every frame I first clear the window, then call the shader's bind method and then the draw method of the mesh.

Any help is highly appreciated, as I have been trying to tackle this for a long time now!

• Have you tried any graphics debugger (like RenderDoc) to see the internal state of things?
– user35344
Jul 6 '20 at 10:51
• After trying out RenderDoc, it seems like the triangle was drawn first, and the screen got cleared (filled with magenta) afterwards. I'm not sure why this happens, as I am clearing the screen before calling the draw methods. I added a call to SDL_GL_SwapWindow after the draw methods, and now I'm getting a triangle, but it is not as vivid colour as it should be and there are text artifacts from my other open programs in the background of the triangle. Jul 6 '20 at 11:12

I was able to debug this using RenderDoc (Thanks Tyyppi_77 for the suggestion). I was calling SDL_GL_SwapWindow every time I cleared the screen, but did not do so after drawing the triangle to the screen. This caused only the background clear to be shown.
The proper fix was to remove the SDL_GL_SwapWindow call from the screen clearing method and only call it once after all the drawing.