More refactoring
This commit is contained in:
parent
560619ae5b
commit
cdb75019d2
186
src/main.cc
186
src/main.cc
@ -55,11 +55,9 @@ struct Camera {
|
|||||||
|
|
||||||
// View matrix to be sent as uniform to the vertex shader
|
// View matrix to be sent as uniform to the vertex shader
|
||||||
glm::mat4 view_mat;
|
glm::mat4 view_mat;
|
||||||
GLint u_view_idx;
|
|
||||||
|
|
||||||
// Projection matrix to be sent as uniform to the vertex shader
|
// Projection matrix to be sent as uniform to the vertex shader
|
||||||
glm::mat4 projection_mat;
|
glm::mat4 projection_mat;
|
||||||
GLint u_projection_idx;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Transform {
|
struct Transform {
|
||||||
@ -72,20 +70,21 @@ struct Mesh {
|
|||||||
// VAO is an object that stores the state needed to supply the GPU with the vertex data.
|
// VAO is an object that stores the state needed to supply the GPU with the vertex data.
|
||||||
// Think of it as a specification or a C struct that defines the types of data stored for the
|
// Think of it as a specification or a C struct that defines the types of data stored for the
|
||||||
// vertex array including the attributes for each vertex as well the indices buffer if it exists.
|
// vertex array including the attributes for each vertex as well the indices buffer if it exists.
|
||||||
GLuint vao;
|
GLuint vao;
|
||||||
|
|
||||||
// The buffer that contains all the vertex data
|
// The buffer that contains all the vertex data
|
||||||
// e.g. assume 3 vertices with position, colour and uv, the buffer would look like this
|
// e.g. assume 3 vertices with position, colour and uv, the buffer would look like this
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
// | position1 | colour1 | uv1 | position2 | colour2 | uv2 | position3 | colour3 | uv3 |
|
// | position1 | colour1 | uv1 | position2 | colour2 | uv2 | position3 | colour3 | uv3 |
|
||||||
// -----------------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------------
|
||||||
GLuint vbo;
|
GLuint vbo;
|
||||||
|
|
||||||
// Holds the indices of the vertices that draw each triangle. Each triangle constitutes what
|
// Holds the indices of the vertices that draw each triangle. Each triangle constitutes what
|
||||||
// OpenGL refers to as element, hence the name Element Buffer Object
|
// OpenGL refers to as element, hence the name Element Buffer Object
|
||||||
GLuint ebo;
|
GLuint ebo;
|
||||||
|
|
||||||
GLuint shader_program;
|
GLuint shader_program;
|
||||||
|
GLuint vertices_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Model {
|
struct Model {
|
||||||
@ -94,14 +93,18 @@ struct Model {
|
|||||||
|
|
||||||
// Model matrix to be sent as uniform to the vertex shader
|
// Model matrix to be sent as uniform to the vertex shader
|
||||||
glm::mat4 model_mat;
|
glm::mat4 model_mat;
|
||||||
|
|
||||||
GLint u_model_idx;
|
GLint u_model_idx;
|
||||||
|
GLint u_view_idx;
|
||||||
|
GLint u_projection_idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct App {
|
struct App {
|
||||||
SDL_Window *window;
|
SDL_Window *window;
|
||||||
SDL_GLContext context;
|
SDL_GLContext context;
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
Model model;
|
Model plane;
|
||||||
|
Model floor;
|
||||||
Camera camera;
|
Camera camera;
|
||||||
float speed;
|
float speed;
|
||||||
glm::vec2 prev_mouse;
|
glm::vec2 prev_mouse;
|
||||||
@ -109,10 +112,11 @@ struct App {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int init (App &app);
|
int init (App &app);
|
||||||
void create_vertex_spec (Model &model);
|
void create_vertex_spec (Model &model, const std::vector<GLfloat> &vertices, const std::vector<GLuint> &indices);
|
||||||
void create_graphics_pipeline (Model &model, Camera &camera);
|
void create_graphics_pipeline (Model &model, Camera &camera, const char *vs_file, const char *fs_file);
|
||||||
void run_main_loop (App &app);
|
void run_main_loop (App &app);
|
||||||
void cleanup (App &app);
|
void cleanup (App &app);
|
||||||
|
void render_model (const Model &model, const Camera &camera);
|
||||||
GLuint create_shader_program (const std::string &vertex_shader_source, const std::string &fragment_shader_source);
|
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);
|
GLuint compile_shader (GLuint type, const std::string &source);
|
||||||
std::string load_shader (const std::string &filepath);
|
std::string load_shader (const std::string &filepath);
|
||||||
@ -127,11 +131,57 @@ int main() {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const std::vector<GLfloat> plane_vertices = {
|
||||||
|
// vert0
|
||||||
|
-0.5f, -0.5f, 0.0f, // position
|
||||||
|
1.0f, 0.0f, 0.0f, // colour
|
||||||
|
// vert1
|
||||||
|
0.5f, -0.5f, 0.0f, // position
|
||||||
|
0.0f, 1.0f, 0.0f, // colour
|
||||||
|
// vert2
|
||||||
|
-0.5f, 0.5f, 0.0f, // position
|
||||||
|
0.0f, 0.0f, 1.0f, // colour
|
||||||
|
// vert3
|
||||||
|
0.5f, 0.5f, 0.0f, // position
|
||||||
|
1.0f, 1.0f, 0.0f, // colour
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<GLuint> plane_indices = {
|
||||||
|
// first triangle
|
||||||
|
0, 1, 2,
|
||||||
|
// second triangle
|
||||||
|
2, 1, 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<GLfloat> floor_vertices = {
|
||||||
|
// vert0
|
||||||
|
-10.0f, 0.0f, 10.0f, // position
|
||||||
|
0.23529f, 0.43137f, 0.44313f, // colour
|
||||||
|
// vert1
|
||||||
|
10.0f, 0.0f, 10.0f, // position
|
||||||
|
0.23529f, 0.43137f, 0.44313f, // colour
|
||||||
|
// vert2
|
||||||
|
-10.0f, 0.0f, -10.0f, // position
|
||||||
|
0.23529f, 0.43137f, 0.44313f, // colour
|
||||||
|
// vert3
|
||||||
|
10.0f, 0.0f, -10.0f, // position
|
||||||
|
0.23529f, 0.43137f, 0.44313f, // colour
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<GLuint> floor_indices = {
|
||||||
|
// first triangle
|
||||||
|
0, 1, 2,
|
||||||
|
// second triangle
|
||||||
|
2, 1, 3,
|
||||||
|
};
|
||||||
|
|
||||||
// Setup the geometry
|
// Setup the geometry
|
||||||
create_vertex_spec(app.model);
|
create_vertex_spec(app.plane, plane_vertices, plane_indices);
|
||||||
|
create_vertex_spec(app.floor, floor_vertices, floor_indices);
|
||||||
|
|
||||||
// Setup graphics pipeline. At the very minimum creating vertex and fragment shaders
|
// Setup graphics pipeline. At the very minimum creating vertex and fragment shaders
|
||||||
create_graphics_pipeline(app.model, app.camera);
|
create_graphics_pipeline(app.plane, app.camera, "shaders/vert.glsl", "shaders/frag.glsl");
|
||||||
|
create_graphics_pipeline(app.floor, app.camera, "shaders/vert.glsl", "shaders/frag.glsl");
|
||||||
|
|
||||||
run_main_loop(app);
|
run_main_loop(app);
|
||||||
|
|
||||||
@ -183,15 +233,20 @@ int init(App &app) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
app.speed = 0.04f;
|
app.speed = 0.04f;
|
||||||
app.model.transform.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f));
|
app.plane.transform.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.5f, -1.0f));
|
||||||
app.model.transform.rotation = glm::mat4(1.0f);
|
app.plane.transform.rotation = glm::mat4(1.0f);
|
||||||
app.model.transform.scale = glm::mat4(1.0f);
|
app.plane.transform.scale = glm::mat4(1.0f);
|
||||||
app.camera.rotation = glm::vec2(0.0f, -90.0f);
|
app.plane.model_mat = app.plane.transform.translation *
|
||||||
app.camera.position = glm::vec3(0.0f, 0.0f, 3.0f);
|
app.plane.transform.rotation * app.plane.transform.scale;
|
||||||
|
app.floor.transform.translation = glm::mat4(1.0f);
|
||||||
|
app.floor.transform.rotation = glm::mat4(1.0f);
|
||||||
|
app.floor.transform.scale = glm::mat4(1.0f);
|
||||||
|
app.floor.model_mat = app.floor.transform.translation *
|
||||||
|
app.floor.transform.rotation * app.floor.transform.scale;
|
||||||
|
app.camera.rotation = glm::vec2(-5.0f, -90.0f);
|
||||||
|
app.camera.position = glm::vec3(0.0f, 0.5f, 3.0f);
|
||||||
app.camera.view_direction = rotation_to_view_direction(app.camera);
|
app.camera.view_direction = rotation_to_view_direction(app.camera);
|
||||||
app.camera.up = glm::vec3(0.0f, 1.0f, 0.0f);
|
app.camera.up = glm::vec3(0.0f, 1.0f, 0.0f);
|
||||||
app.model.model_mat = app.model.transform.translation *
|
|
||||||
app.model.transform.rotation * app.model.transform.scale;
|
|
||||||
app.camera.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
app.camera.view_mat = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up);
|
||||||
app.camera.projection_mat = glm::perspective(glm::radians(60.0f),
|
app.camera.projection_mat = glm::perspective(glm::radians(60.0f),
|
||||||
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
(float)WINDOW_WIDTH / (float)WINDOW_HEIGHT,
|
||||||
@ -202,29 +257,7 @@ int init(App &app) {
|
|||||||
return EXIT_CODE_SUCCESS;
|
return EXIT_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_vertex_spec(Model &model) {
|
void create_vertex_spec(Model &model, const std::vector<GLfloat> &vertices, const std::vector<GLuint> &indices) {
|
||||||
const std::vector<GLfloat> vertices = {
|
|
||||||
// vert0
|
|
||||||
-0.5f, -0.5f, 0.0f, // position
|
|
||||||
1.0f, 0.0f, 0.0f, // colour
|
|
||||||
// vert1
|
|
||||||
0.5f, -0.5f, 0.0f, // position
|
|
||||||
0.0f, 1.0f, 0.0f, // colour
|
|
||||||
// vert2
|
|
||||||
-0.5f, 0.5f, 0.0f, // position
|
|
||||||
0.0f, 0.0f, 1.0f, // colour
|
|
||||||
// vert3
|
|
||||||
0.5f, 0.5f, 0.0f, // position
|
|
||||||
1.0f, 1.0f, 0.0f, // colour
|
|
||||||
};
|
|
||||||
|
|
||||||
const std::vector<GLuint> indices = {
|
|
||||||
// first triangle
|
|
||||||
0, 1, 2,
|
|
||||||
// second triangle
|
|
||||||
2, 1, 3,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Create and activate the VAO
|
// Create and activate the VAO
|
||||||
glGenVertexArrays(1, &model.mesh.vao);
|
glGenVertexArrays(1, &model.mesh.vao);
|
||||||
glBindVertexArray(model.mesh.vao);
|
glBindVertexArray(model.mesh.vao);
|
||||||
@ -270,11 +303,13 @@ void create_vertex_spec(Model &model) {
|
|||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
glDisableVertexAttribArray(0);
|
glDisableVertexAttribArray(0);
|
||||||
glDisableVertexAttribArray(1);
|
glDisableVertexAttribArray(1);
|
||||||
|
|
||||||
|
model.mesh.vertices_count = indices.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void create_graphics_pipeline(Model &model, Camera &camera) {
|
void create_graphics_pipeline(Model &model, Camera &camera, const char *vs_file, const char *fs_file) {
|
||||||
const std::string vs_source = load_shader("shaders/vert.glsl");
|
const std::string vs_source = load_shader(vs_file);
|
||||||
const std::string fs_source = load_shader("shaders/frag.glsl");
|
const std::string fs_source = load_shader(fs_file);
|
||||||
|
|
||||||
model.mesh.shader_program = create_shader_program(vs_source, fs_source);
|
model.mesh.shader_program = create_shader_program(vs_source, fs_source);
|
||||||
|
|
||||||
@ -284,16 +319,15 @@ void create_graphics_pipeline(Model &model, Camera &camera) {
|
|||||||
printf("Failed to find uniform %s\n", u_model);
|
printf("Failed to find uniform %s\n", u_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO (Abdelrahman): Finding the camera matrices uniforms shouldn't be handled here
|
|
||||||
const char *u_view = "u_view";
|
const char *u_view = "u_view";
|
||||||
camera.u_view_idx = glGetUniformLocation(model.mesh.shader_program, u_view);
|
model.u_view_idx = glGetUniformLocation(model.mesh.shader_program, u_view);
|
||||||
if (camera.u_view_idx < 0) {
|
if (model.u_view_idx < 0) {
|
||||||
printf("Failed to find uniform %s\n", u_view);
|
printf("Failed to find uniform %s\n", u_view);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *u_projection = "u_projection";
|
const char *u_projection = "u_projection";
|
||||||
camera.u_projection_idx = glGetUniformLocation(model.mesh.shader_program, u_projection);
|
model.u_projection_idx = glGetUniformLocation(model.mesh.shader_program, u_projection);
|
||||||
if (camera.u_projection_idx < 0) {
|
if (model.u_projection_idx < 0) {
|
||||||
printf("Failed to find uniform %s\n", u_projection);
|
printf("Failed to find uniform %s\n", u_projection);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,22 +363,9 @@ void run_main_loop(App &app) {
|
|||||||
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
glClearColor(0.36f, 0.34f, 0.42f, 1.0f);
|
||||||
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
glClear (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
glUseProgram(app.model.mesh.shader_program);
|
// Render models
|
||||||
if (app.model.u_model_idx >= 0) {
|
render_model(app.floor, app.camera);
|
||||||
glUniformMatrix4fv(app.model.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model.model_mat));
|
render_model(app.plane, app.camera);
|
||||||
}
|
|
||||||
if (app.camera.u_view_idx >= 0) {
|
|
||||||
glUniformMatrix4fv(app.camera.u_view_idx, 1, GL_FALSE, glm::value_ptr(app.camera.view_mat));
|
|
||||||
}
|
|
||||||
if (app.camera.u_projection_idx >= 0) {
|
|
||||||
glUniformMatrix4fv(app.camera.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.camera.projection_mat));
|
|
||||||
}
|
|
||||||
// End pre draw setup
|
|
||||||
|
|
||||||
// Draw call
|
|
||||||
glBindVertexArray(app.model.mesh.vao);
|
|
||||||
glDrawElements (GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)0);
|
|
||||||
// End draw call
|
|
||||||
|
|
||||||
// Not necessary if we only have one shader program
|
// Not necessary if we only have one shader program
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
@ -359,6 +380,22 @@ void cleanup(App &app) {
|
|||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void render_model(const Model &model, const Camera &camera) {
|
||||||
|
glUseProgram(model.mesh.shader_program);
|
||||||
|
if (model.u_model_idx >= 0) {
|
||||||
|
glUniformMatrix4fv(model.u_model_idx, 1, GL_FALSE, glm::value_ptr(model.model_mat));
|
||||||
|
}
|
||||||
|
if (model.u_view_idx >= 0) {
|
||||||
|
glUniformMatrix4fv(model.u_view_idx, 1, GL_FALSE, glm::value_ptr(camera.view_mat));
|
||||||
|
}
|
||||||
|
if (model.u_projection_idx >= 0) {
|
||||||
|
glUniformMatrix4fv(model.u_projection_idx, 1, GL_FALSE, glm::value_ptr(camera.projection_mat));
|
||||||
|
}
|
||||||
|
|
||||||
|
glBindVertexArray(model.mesh.vao);
|
||||||
|
glDrawElements (GL_TRIANGLES, model.mesh.vertices_count, GL_UNSIGNED_INT, (void *)0);
|
||||||
|
}
|
||||||
|
|
||||||
GLuint create_shader_program(const std::string &vertex_shader_source, const std::string &fragment_shader_source) {
|
GLuint create_shader_program(const std::string &vertex_shader_source, const std::string &fragment_shader_source) {
|
||||||
GLuint shader_program = glCreateProgram();
|
GLuint shader_program = glCreateProgram();
|
||||||
GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source);
|
GLuint vertex_shader = compile_shader(GL_VERTEX_SHADER, vertex_shader_source);
|
||||||
@ -430,40 +467,41 @@ std::string load_shader(const std::string &filepath) {
|
|||||||
void handle_object_movement(App &app) {
|
void handle_object_movement(App &app) {
|
||||||
switch (app.event.key.keysym.sym) {
|
switch (app.event.key.keysym.sym) {
|
||||||
case SDLK_w:
|
case SDLK_w:
|
||||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
app.plane.transform.translation = glm::translate(app.plane.transform.translation,
|
||||||
glm::vec3(0.0f, 0.0f, app.speed));
|
glm::vec3(0.0f, 0.0f, app.speed));
|
||||||
break;
|
break;
|
||||||
case SDLK_s:
|
case SDLK_s:
|
||||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
app.plane.transform.translation = glm::translate(app.plane.transform.translation,
|
||||||
glm::vec3(0.0f, 0.0f, -app.speed));
|
glm::vec3(0.0f, 0.0f, -app.speed));
|
||||||
break;
|
break;
|
||||||
case SDLK_d:
|
case SDLK_d:
|
||||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
app.plane.transform.translation = glm::translate(app.plane.transform.translation,
|
||||||
glm::vec3(app.speed, 0.0f, 0.0f));
|
glm::vec3(app.speed, 0.0f, 0.0f));
|
||||||
break;
|
break;
|
||||||
case SDLK_a:
|
case SDLK_a:
|
||||||
app.model.transform.translation = glm::translate(app.model.transform.translation,
|
app.plane.transform.translation = glm::translate(app.plane.transform.translation,
|
||||||
glm::vec3(-app.speed, 0.0f, 0.0f));
|
glm::vec3(-app.speed, 0.0f, 0.0f));
|
||||||
break;
|
break;
|
||||||
case SDLK_RIGHT:
|
case SDLK_RIGHT:
|
||||||
app.model.transform.rotation = glm::rotate(app.model.transform.rotation,
|
app.plane.transform.rotation = glm::rotate(app.plane.transform.rotation,
|
||||||
glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
break;
|
break;
|
||||||
case SDLK_LEFT:
|
case SDLK_LEFT:
|
||||||
app.model.transform.rotation = glm::rotate(app.model.transform.rotation,
|
app.plane.transform.rotation = glm::rotate(app.plane.transform.rotation,
|
||||||
glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
|
||||||
break;
|
break;
|
||||||
case SDLK_r:
|
case SDLK_r:
|
||||||
app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(1.2f));
|
app.plane.transform.scale = glm::scale(app.plane.transform.scale, glm::vec3(1.2f));
|
||||||
break;
|
break;
|
||||||
case SDLK_e:
|
case SDLK_e:
|
||||||
app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(0.8f));
|
app.plane.transform.scale = glm::scale(app.plane.transform.scale, glm::vec3(0.8f));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
app.model.model_mat = app.model.transform.translation * app.model.transform.rotation * app.model.transform.scale;
|
app.plane.model_mat = app.plane.transform.translation * app.plane.transform.rotation * app.plane.transform.scale;
|
||||||
|
app.floor.model_mat = app.floor.transform.translation * app.floor.transform.rotation * app.floor.transform.scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
void handle_camera_movement(App &app) {
|
void handle_camera_movement(App &app) {
|
||||||
|
Loading…
Reference in New Issue
Block a user