Refactor to create Mesh and Model structs
This commit is contained in:
		
							
								
								
									
										163
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										163
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -52,13 +52,23 @@ struct Camera { | ||||
|  | ||||
|   // pitch, yaw | ||||
|   glm::vec2 rotation; | ||||
|  | ||||
|   // View matrix to be sent as uniform to the vertex shader | ||||
|   glm::mat4     view_mat; | ||||
|   GLint         u_view_idx; | ||||
|  | ||||
|   // Projection matrix to be sent as uniform to the vertex shader | ||||
|   glm::mat4     projection_mat; | ||||
|   GLint         u_projection_idx; | ||||
| }; | ||||
|  | ||||
| struct App { | ||||
|   SDL_Window    *window; | ||||
|   SDL_GLContext context; | ||||
|   SDL_Event     event; | ||||
| struct Transform { | ||||
|   glm::mat4     translation; | ||||
|   glm::mat4     rotation; | ||||
|   glm::mat4     scale; | ||||
| }; | ||||
|  | ||||
| struct Mesh { | ||||
|   // 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 | ||||
|   // vertex array including the attributes for each vertex as well the indices buffer if it exists. | ||||
| @@ -76,34 +86,31 @@ struct App { | ||||
|   GLuint        ebo; | ||||
|  | ||||
|   GLuint        shader_program; | ||||
| }; | ||||
|  | ||||
|   Camera        camera; | ||||
|  | ||||
|   float         speed; | ||||
|   glm::mat4     translation; | ||||
|   glm::mat4     rotation; | ||||
|   glm::mat4     scale; | ||||
| struct Model { | ||||
|   Transform transform; | ||||
|   Mesh      mesh; | ||||
|  | ||||
|   // Model matrix to be sent as uniform to the vertex shader | ||||
|   glm::mat4     model_mat; | ||||
|   GLint         u_model_idx; | ||||
|  | ||||
|   // View matrix to be sent as uniform to the vertex shader | ||||
|   glm::mat4     view_mat; | ||||
|   GLint         u_view_idx; | ||||
|  | ||||
|   // Projection matrix to be sent as uniform to the vertex shader | ||||
|   glm::mat4     projection_mat; | ||||
|   GLint         u_projection_idx; | ||||
|   glm::mat4 model_mat; | ||||
|   GLint     u_model_idx; | ||||
| }; | ||||
|  | ||||
| struct App { | ||||
|   SDL_Window    *window; | ||||
|   SDL_GLContext context; | ||||
|   SDL_Event     event; | ||||
|   Model         model; | ||||
|   Camera        camera; | ||||
|   float         speed; | ||||
|   glm::vec2     prev_mouse; | ||||
|  | ||||
|   bool          running; | ||||
| }; | ||||
|  | ||||
| int         init                      (App &app); | ||||
| void        create_vertex_spec        (App &app); | ||||
| void        create_graphics_pipeline  (App &app); | ||||
| void        create_vertex_spec        (Model &model); | ||||
| void        create_graphics_pipeline  (Model &model, Camera &camera); | ||||
| 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); | ||||
| @@ -121,10 +128,10 @@ int main() { | ||||
|   } | ||||
|  | ||||
|   // Setup the geometry | ||||
|   create_vertex_spec(app); | ||||
|   create_vertex_spec(app.model); | ||||
|  | ||||
|   // Setup graphics pipeline. At the very minimum creating vertex and fragment shaders | ||||
|   create_graphics_pipeline(app); | ||||
|   create_graphics_pipeline(app.model, app.camera); | ||||
|  | ||||
|   run_main_loop(app); | ||||
|  | ||||
| @@ -175,27 +182,27 @@ int init(App &app) { | ||||
|          glGetString(GL_SHADING_LANGUAGE_VERSION) | ||||
|   ); | ||||
|  | ||||
|   app.speed                 = 0.04f; | ||||
|   app.translation           = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f)); | ||||
|   app.rotation              = glm::mat4(1.0f); | ||||
|   app.scale                 = glm::mat4(1.0f); | ||||
|   app.camera.rotation       = glm::vec2(0.0f, -90.0f); | ||||
|   app.camera.position       = glm::vec3(0.0f, 0.0f,  3.0f); | ||||
|   app.camera.view_direction = rotation_to_view_direction(app.camera); | ||||
|   app.camera.up             = glm::vec3(0.0f, 1.0f,  0.0f); | ||||
|   app.model_mat             = app.translation * app.rotation * app.scale; | ||||
|   app.view_mat              = glm::lookAt(app.camera.position, app.camera.position + app.camera.view_direction, app.camera.up); | ||||
|   app.projection_mat        = glm::perspective(glm::radians(60.0f), | ||||
|                                                (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, | ||||
|                                                0.1f, | ||||
|                                                20.0f | ||||
|                               ); | ||||
|   app.prev_mouse            = glm::vec2(WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); | ||||
|   app.speed                       = 0.04f; | ||||
|   app.model.transform.translation = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, 0.0f, 1.5f)); | ||||
|   app.model.transform.rotation    = glm::mat4(1.0f); | ||||
|   app.model.transform.scale       = glm::mat4(1.0f); | ||||
|   app.camera.rotation             = glm::vec2(0.0f, -90.0f); | ||||
|   app.camera.position             = glm::vec3(0.0f, 0.0f,  3.0f); | ||||
|   app.camera.view_direction       = rotation_to_view_direction(app.camera); | ||||
|   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.projection_mat       = glm::perspective(glm::radians(60.0f), | ||||
|                                                      (float)WINDOW_WIDTH / (float)WINDOW_HEIGHT, | ||||
|                                                      0.1f, | ||||
|                                                      20.0f); | ||||
|   app.prev_mouse                  = glm::vec2(WINDOW_HALF_WIDTH, WINDOW_HALF_HEIGHT); | ||||
|  | ||||
|   return EXIT_CODE_SUCCESS; | ||||
| } | ||||
|  | ||||
| void create_vertex_spec(App &app) { | ||||
| void create_vertex_spec(Model &model) { | ||||
|   const std::vector<GLfloat> vertices = { | ||||
|     // vert0 | ||||
|     -0.5f, -0.5f, 0.0f, // position | ||||
| @@ -219,12 +226,12 @@ void create_vertex_spec(App &app) { | ||||
|   }; | ||||
|  | ||||
|   // Create and activate the VAO | ||||
|   glGenVertexArrays(1, &app.vao); | ||||
|   glBindVertexArray(app.vao); | ||||
|   glGenVertexArrays(1, &model.mesh.vao); | ||||
|   glBindVertexArray(model.mesh.vao); | ||||
|  | ||||
|   // Create and set up the VBO | ||||
|   glGenBuffers(1, &app.vbo); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, app.vbo); | ||||
|   glGenBuffers(1, &model.mesh.vbo); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, model.mesh.vbo); | ||||
|   glBufferData(GL_ARRAY_BUFFER, | ||||
|                vertices.size() * sizeof(GLfloat), | ||||
|                (void *)vertices.data(), | ||||
| @@ -232,8 +239,8 @@ void create_vertex_spec(App &app) { | ||||
|   ); | ||||
|  | ||||
|   // Create and set up the EBO | ||||
|   glGenBuffers(1, &app.ebo); | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, app.ebo); | ||||
|   glGenBuffers(1, &model.mesh.ebo); | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, model.mesh.ebo); | ||||
|   glBufferData(GL_ELEMENT_ARRAY_BUFFER, | ||||
|                indices.size() * sizeof(GLuint), | ||||
|                (void *)indices.data(), | ||||
| @@ -265,27 +272,28 @@ void create_vertex_spec(App &app) { | ||||
|   glDisableVertexAttribArray(1); | ||||
| } | ||||
|  | ||||
| void create_graphics_pipeline(App &app) { | ||||
| void create_graphics_pipeline(Model &model, Camera &camera) { | ||||
|   const std::string vs_source = load_shader("shaders/vert.glsl"); | ||||
|   const std::string fs_source = load_shader("shaders/frag.glsl"); | ||||
|  | ||||
|   app.shader_program = create_shader_program(vs_source, fs_source); | ||||
|   model.mesh.shader_program = create_shader_program(vs_source, fs_source); | ||||
|  | ||||
|   const char *u_model = "u_model"; | ||||
|   app.u_model_idx = glGetUniformLocation(app.shader_program, u_model); | ||||
|   if (app.u_model_idx < 0) { | ||||
|   model.u_model_idx = glGetUniformLocation(model.mesh.shader_program, u_model); | ||||
|   if (model.u_model_idx < 0) { | ||||
|     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"; | ||||
|   app.u_view_idx = glGetUniformLocation(app.shader_program, u_view); | ||||
|   if (app.u_view_idx < 0) { | ||||
|   camera.u_view_idx = glGetUniformLocation(model.mesh.shader_program, u_view); | ||||
|   if (camera.u_view_idx < 0) { | ||||
|     printf("Failed to find uniform %s\n", u_view); | ||||
|   } | ||||
|  | ||||
|   const char *u_projection = "u_projection"; | ||||
|   app.u_projection_idx = glGetUniformLocation(app.shader_program, u_projection); | ||||
|   if (app.u_projection_idx < 0) { | ||||
|   camera.u_projection_idx = glGetUniformLocation(model.mesh.shader_program, u_projection); | ||||
|   if (camera.u_projection_idx < 0) { | ||||
|     printf("Failed to find uniform %s\n", u_projection); | ||||
|   } | ||||
| } | ||||
| @@ -321,20 +329,20 @@ void run_main_loop(App &app) { | ||||
|     glClearColor(0.36f, 0.34f, 0.42f, 1.0f); | ||||
|     glClear     (GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); | ||||
|  | ||||
|     glUseProgram(app.shader_program); | ||||
|     if (app.u_model_idx >= 0) { | ||||
|       glUniformMatrix4fv(app.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model_mat)); | ||||
|     glUseProgram(app.model.mesh.shader_program); | ||||
|     if (app.model.u_model_idx >= 0) { | ||||
|       glUniformMatrix4fv(app.model.u_model_idx, 1, GL_FALSE, glm::value_ptr(app.model.model_mat)); | ||||
|     } | ||||
|     if (app.u_view_idx >= 0) { | ||||
|       glUniformMatrix4fv(app.u_view_idx, 1, GL_FALSE, glm::value_ptr(app.view_mat)); | ||||
|     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.u_projection_idx >= 0) { | ||||
|       glUniformMatrix4fv(app.u_projection_idx, 1, GL_FALSE, glm::value_ptr(app.projection_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.vao); | ||||
|     glBindVertexArray(app.model.mesh.vao); | ||||
|     glDrawElements   (GL_TRIANGLES, 6, GL_UNSIGNED_INT, (void *)0); | ||||
|     // End draw call | ||||
|  | ||||
| @@ -418,37 +426,44 @@ std::string load_shader(const std::string &filepath) { | ||||
|   return output; | ||||
| } | ||||
|  | ||||
| // Example of moving an object | ||||
| void handle_object_movement(App &app) { | ||||
|   switch (app.event.key.keysym.sym) { | ||||
|     case SDLK_w: | ||||
|         app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, app.speed)); | ||||
|         app.model.transform.translation = glm::translate(app.model.transform.translation, | ||||
|                                                          glm::vec3(0.0f, 0.0f, app.speed)); | ||||
|         break; | ||||
|     case SDLK_s: | ||||
|         app.translation = glm::translate(app.translation, glm::vec3(0.0f, 0.0f, -app.speed)); | ||||
|         app.model.transform.translation = glm::translate(app.model.transform.translation, | ||||
|                                                          glm::vec3(0.0f, 0.0f, -app.speed)); | ||||
|         break; | ||||
|     case SDLK_d: | ||||
|         app.translation = glm::translate(app.translation, glm::vec3(app.speed, 0.0f, 0.0f)); | ||||
|         app.model.transform.translation = glm::translate(app.model.transform.translation, | ||||
|                                                          glm::vec3(app.speed, 0.0f, 0.0f)); | ||||
|         break; | ||||
|     case SDLK_a: | ||||
|         app.translation = glm::translate(app.translation, glm::vec3(-app.speed, 0.0f, 0.0f)); | ||||
|         app.model.transform.translation = glm::translate(app.model.transform.translation, | ||||
|                                                          glm::vec3(-app.speed, 0.0f, 0.0f)); | ||||
|         break; | ||||
|     case SDLK_RIGHT: | ||||
|         app.rotation = glm::rotate(app.rotation, glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f)); | ||||
|         app.model.transform.rotation = glm::rotate(app.model.transform.rotation, | ||||
|                                                    glm::radians(10.0f), glm::vec3(0.0f, 1.0f, 0.0f)); | ||||
|         break; | ||||
|     case SDLK_LEFT: | ||||
|         app.rotation = glm::rotate(app.rotation, glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f)); | ||||
|         app.model.transform.rotation = glm::rotate(app.model.transform.rotation, | ||||
|                                                    glm::radians(-10.0f), glm::vec3(0.0f, 1.0f, 0.0f)); | ||||
|         break; | ||||
|     case SDLK_r: | ||||
|         app.scale = glm::scale(app.scale, glm::vec3(1.2f)); | ||||
|         app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(1.2f)); | ||||
|         break; | ||||
|     case SDLK_e: | ||||
|         app.scale = glm::scale(app.scale, glm::vec3(0.8f)); | ||||
|         app.model.transform.scale = glm::scale(app.model.transform.scale, glm::vec3(0.8f)); | ||||
|         break; | ||||
|     default: | ||||
|         return; | ||||
|   } | ||||
|  | ||||
|   app.model_mat = app.translation * app.rotation * app.scale; | ||||
|   app.model.model_mat = app.model.transform.translation * app.model.transform.rotation * app.model.transform.scale; | ||||
| } | ||||
|  | ||||
| void handle_camera_movement(App &app) { | ||||
| @@ -477,7 +492,7 @@ void handle_camera_movement(App &app) { | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   app.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); | ||||
| } | ||||
|  | ||||
| glm::vec3 rotation_to_view_direction(const Camera &camera) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user