You can get a simple base going on with some basic setup code. Download GLEW and get that working if you haven't already.
I will post some code without error checking, and hopefully this step by step will help you understand better.
This is not a full example, and there might even be a typo in here, but if you start from the main function and read what's happening line by line, you will come to an understanding of how it all comes together.
Keep in mind the shader must have input attributes 0: vec4 position, 1: vec4 color and 2: vec2 uv.
This is intended to be a reference if you're stuck, not a complete example.
SDL_GLContext gl_context = nullptr;
std::string read_file(std::string path) {
std::ifstream file(path, std::ios::binary);
if (!file.is_open()) { return ""; }
std::stringstream result;
result << file.rdbuf();
return result.str();
}
void init_gl(SDL_Window* window) {
gl_context = SDL_GL_CreateContext(window);
glewInit();
glShadeModel(GL_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
int load_shader(int type, std::string path) {
int id = glCreateShader(type);
const char* source = read_file(path).c_str();
glShaderSource(id, 1, &source, 0);
glCompileShader(id);
return id; // look at glGetShaderInfoLog later on
}
int load_shader_program(std::string path_vert, std::string path_frag) {
int shader_program_id = glCreateProgram();
int vert_id = load_shader(GL_VERTEX_SHADER, path_vert);
int frag_id = load_shader(GL_FRAGMENT_SHADER, path_frag);
glAttachShader(shader_program_id, vert_id);
glAttachShader(shader_program_id, frag_id);
glLinkProgram(shader_program_id);
// look at glGetProgramInfoLog, glValidateProgram and glGetProgramiv later on
return shader_program_id;
}
struct vector4f { float x = 0.0f, y = 0.0f, z = 0.0f, w = 0.0f; };
struct vector3f { float x = 0.0f, y = 0.0f, z = 0.0f; };
struct vector2f { float x = 0.0f, y = 0.0f; };
struct gl_vertex {
vector4f position;
float r = 1.0f, g = 1.0f, b = 1.0f, a = 1.0f;
vector2f uv;
};
struct gl_shape {
int vao = 0;
int index_buffer = 0, vertex_buffer = 0;
std::vector<unsigned int> indices;
std::vector<gl_vertex> vertices;
};
void use_gl_shape(gl_shape* shape) {
glBindVertexArray(shape->vao);
glBindBuffer(GL_ARRAY_BUFFER, shape->index_buffer);
glBindBuffer(GL_ARRAY_BUFFER, shape->vertex_buffer);
}
gl_shape create_quad() {
gl_shape quad;
quad.indices = { 0, 1, 2, 3, 2, 0 };
quad.vertices.insert(quad.vertices.begin(), 4, gl_vertex());
quad.vertices[0].position = { 0.0f, 0.0f, 0.0f, 1.0f };
quad.vertices[1].position = { 1.0f, 0.0f, 0.0f, 1.0f };
quad.vertices[2].position = { 1.0f, 1.0f, 0.0f, 1.0f };
quad.vertices[3].position = { 0.0f, 1.0f, 0.0f, 1.0f };
quad.vertices[0].uv = { 0.0f, 0.0f };
quad.vertices[1].uv = { 1.0f, 0.0f };
quad.vertices[2].uv = { 1.0f, 1.0f };
quad.vertices[3].uv = { 0.0f, 1.0f };
glGenVertexArrays(1, &quad.vao);
glGenBuffers(1, &quad.index_buffer);
glGenBuffers(1, &quad.vertex_buffer);
use_gl_shape(&quad);
glBufferData(GL_ARRAY_BUFFER, sizeof(unsigned int) * quad.indices.size(), &quad.indices[0], GL_STATIC_DRAW);
glBufferData(GL_ARRAY_BUFFER, sizeof(gl_vertex) * quad.vertices.size(), &quad.vertices[0], GL_STATIC_DRAW);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(gl_vertex), nullptr);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(gl_vertex), (void*) (4 * sizeof(float)));
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(gl_vertex), (void*) (8 * sizeof(float)));
glEnableVertexAttribArray(0);
glEnableVertexAttribArray(1);
glEnableVertexAttribArray(2);
return quad;
}
int main() {
// ... setup ...
init_gl(window);
int shader_program = load_shader_program("shader.vert", "shader.frag");
gl_shape quad = create_quad();
glClearColor(0.2f, 0.2f, 0.2f, 1.0f);
while (true) {
glClear(GL_COLOR_BUFFER_BIT);
glUseProgram(shader_program);
// <- This is where you set your projection and view matrix uniforms ->
// ...
// <- This is where you set your model matrix uniform ->
use_gl_shape(&quad);
glDrawElements(GL_TRIANGLES, shape.indices.size(), GL_UNSIGNED_INT, &shape.indices[0]);
SDL_GL_SwapWindow(window);
}
// ... cleanup ...
return 0;
}
If you need help figuring out projection and view matrices, feel free to ask.