Draw first triangle
This commit is contained in:
parent
5ba599981f
commit
16783dc090
134
src/main.cc
134
src/main.cc
@ -6,6 +6,8 @@
|
|||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#define WINDOW_WIDTH 1280
|
#define WINDOW_WIDTH 1280
|
||||||
#define WINDOW_HEIGHT 720
|
#define WINDOW_HEIGHT 720
|
||||||
@ -22,11 +24,29 @@ struct App {
|
|||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
|
|
||||||
|
// Defines the different attributes in the vertex data and how to access them.
|
||||||
|
// Think of it as a specification or a C struct that defines the types of data stored for each
|
||||||
|
// vertex.
|
||||||
|
GLuint vao;
|
||||||
|
|
||||||
|
// The buffer that contains all the vertex data
|
||||||
|
// e.g. assume 3 vertices with position, colour and uv
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
// | position1 | colour1 | uv1 | position2 | colour2 | uv2 | position3 | colour3 | uv3 |
|
||||||
|
// -----------------------------------------------------------------------------------
|
||||||
|
GLuint vbo;
|
||||||
|
|
||||||
|
GLuint shader_program;
|
||||||
};
|
};
|
||||||
|
|
||||||
int init (App &app);
|
int init (App &app);
|
||||||
void run_main_loop(App &app);
|
void create_vertex_spec (App &app);
|
||||||
void cleanup (App &app);
|
void create_graphics_pipeline(App &app);
|
||||||
|
void run_main_loop (App &app);
|
||||||
|
void cleanup (App &app);
|
||||||
|
GLuint create_shader_program (const std::string &vertex_shader_source, const std::string &fragment_shader_source);
|
||||||
|
GLuint compile_shader (GLuint type, const std::string &source);
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
App app = {};
|
App app = {};
|
||||||
@ -35,6 +55,10 @@ int main() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
create_vertex_spec(app);
|
||||||
|
|
||||||
|
create_graphics_pipeline(app);
|
||||||
|
|
||||||
run_main_loop(app);
|
run_main_loop(app);
|
||||||
|
|
||||||
cleanup(app);
|
cleanup(app);
|
||||||
@ -49,7 +73,7 @@ int init(App &app) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint32_t flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI;
|
uint32_t flags = SDL_WINDOW_SHOWN | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI;
|
||||||
app.window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
app.window = SDL_CreateWindow("Window", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||||
WINDOW_WIDTH, WINDOW_HEIGHT, flags);
|
WINDOW_WIDTH, WINDOW_HEIGHT, flags);
|
||||||
if (!app.window) {
|
if (!app.window) {
|
||||||
fprintf(stderr, "Failed to create window: %s", SDL_GetError());
|
fprintf(stderr, "Failed to create window: %s", SDL_GetError());
|
||||||
@ -84,6 +108,57 @@ int init(App &app) {
|
|||||||
return EXIT_CODE_SUCCESS;
|
return EXIT_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void create_vertex_spec(App &app) {
|
||||||
|
const std::vector<GLfloat> vertices = {
|
||||||
|
-0.8f, -0.8f, 0.0f,
|
||||||
|
0.8f, -0.8f, 0.0f,
|
||||||
|
0.0f, 0.8f, 0.0f,
|
||||||
|
};
|
||||||
|
|
||||||
|
glGenVertexArrays(1, &app.vao);
|
||||||
|
glBindVertexArray(app.vao);
|
||||||
|
|
||||||
|
glGenBuffers(1, &app.vbo);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, app.vbo);
|
||||||
|
glBufferData(GL_ARRAY_BUFFER,
|
||||||
|
vertices.size() * sizeof(GLfloat),
|
||||||
|
(void *)vertices.data(),
|
||||||
|
GL_STATIC_DRAW
|
||||||
|
);
|
||||||
|
|
||||||
|
// Defines the vertex attributes and their indices. This defines the attribute for the currently
|
||||||
|
// bound VAO
|
||||||
|
glEnableVertexAttribArray(0);
|
||||||
|
|
||||||
|
// Defines the number of components for the attribute, its type, the stride between the component
|
||||||
|
// for each vertex and the offset of the first instance of the component in the buffer
|
||||||
|
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void *)0);
|
||||||
|
|
||||||
|
// Cleanup. The order matters. Unbind VAO first then disable the attributes. If you do it the
|
||||||
|
// other way around, the VAO will store that the attributes are disabled and nothing will be
|
||||||
|
// drawn during the rendering stage
|
||||||
|
glBindVertexArray(0);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
glDisableVertexAttribArray(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void create_graphics_pipeline(App &app) {
|
||||||
|
const std::string vs_source =
|
||||||
|
"#version 460 core\n"
|
||||||
|
"in vec4 position;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" gl_Position = vec4(position.x, position.y, position.z, position.w);\n"
|
||||||
|
"}";
|
||||||
|
const std::string fs_source =
|
||||||
|
"#version 460 core\n"
|
||||||
|
"out vec4 color;\n"
|
||||||
|
"void main() {\n"
|
||||||
|
" color = vec4(0.93f, 0.42f, 0.35f, 1.0f);\n"
|
||||||
|
"}";
|
||||||
|
|
||||||
|
app.shader_program = create_shader_program(vs_source, fs_source);
|
||||||
|
}
|
||||||
|
|
||||||
void run_main_loop(App &app) {
|
void run_main_loop(App &app) {
|
||||||
bool running = true;
|
bool running = true;
|
||||||
|
|
||||||
@ -96,6 +171,23 @@ void run_main_loop(App &app) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pre draw setup
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glDisable(GL_CULL_FACE);
|
||||||
|
|
||||||
|
glViewport (0, 0, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||||
|
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
||||||
|
glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
glUseProgram(app.shader_program);
|
||||||
|
// End pre draw setup
|
||||||
|
|
||||||
|
// Draw call
|
||||||
|
glBindVertexArray(app.vao);
|
||||||
|
glBindBuffer(GL_ARRAY_BUFFER, app.vbo); // Is this actually needed?
|
||||||
|
glDrawArrays(GL_TRIANGLES, 0, 3);
|
||||||
|
// End draw call
|
||||||
|
|
||||||
SDL_GL_SwapWindow(app.window);
|
SDL_GL_SwapWindow(app.window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,3 +197,37 @@ void cleanup(App &app) {
|
|||||||
SDL_DestroyWindow(app.window);
|
SDL_DestroyWindow(app.window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GLuint create_shader_program(const std::string &vertex_shader_source, const std::string &fragment_shader_source) {
|
||||||
|
GLuint shader_program = glCreateProgram();
|
||||||
|
GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source);
|
||||||
|
GLuint fragment_shader = compile_shader(GL_FRAGMENT_SHADER, fragment_shader_source);
|
||||||
|
|
||||||
|
glAttachShader(shader_program, vertex_shader);
|
||||||
|
glAttachShader(shader_program, fragment_shader);
|
||||||
|
glLinkProgram (shader_program);
|
||||||
|
|
||||||
|
// Validate the shader_program
|
||||||
|
glValidateProgram(shader_program);
|
||||||
|
|
||||||
|
return shader_program;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLuint compile_shader(GLuint type, const std::string &source) {
|
||||||
|
GLuint shader = glCreateShader(type);
|
||||||
|
const char *shader_source = source.c_str();
|
||||||
|
|
||||||
|
glShaderSource (shader, 1, &shader_source, NULL);
|
||||||
|
glCompileShader(shader);
|
||||||
|
|
||||||
|
GLint compile_status;
|
||||||
|
glGetShaderiv(shader, GL_COMPILE_STATUS, &compile_status);
|
||||||
|
if (compile_status != GL_TRUE) {
|
||||||
|
GLsizei log_length = 0;
|
||||||
|
GLchar message[1024];
|
||||||
|
glGetShaderInfoLog(shader, 1024, &log_length, message);
|
||||||
|
fprintf(stderr, "%s\n", message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return shader;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user