1
\$\begingroup\$

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)
{
    const GLuint shader = glCreateShader(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)};
    }

    const GLchar* programs[1]{shader_code.c_str()};
    const GLint lengths[1]{static_cast<GLint>(shader_code.length())};

    glShaderSource(shader, 1, programs, lengths);
    glCompileShader(shader);

    // Error check using glGetShaderiv

    glAttachShader(shader_program, shader);
}

void Shader::compile_shader()
{
    glLinkProgram(shader_program);
    // Error checks using glGetProgramiv
}

void Shader::bind()
{
    glUseProgram(shader_program);
}

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!

\$\endgroup\$
2
  • \$\begingroup\$ Have you tried any graphics debugger (like RenderDoc) to see the internal state of things? \$\endgroup\$
    – user35344
    Jul 6 '20 at 10:51
  • \$\begingroup\$ 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. \$\endgroup\$
    – j3lp4
    Jul 6 '20 at 11:12
2
\$\begingroup\$

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.

\$\endgroup\$
1
  • \$\begingroup\$ Don't forget to Accept this answer by clicking on the checkmark icon to show that it worked for you and adequately solves your problem. \$\endgroup\$
    – DMGregory
    Jul 7 '20 at 16:59

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .