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!
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\$