Create mesh abstraction
This commit is contained in:
		
							
								
								
									
										171
									
								
								src/main.cc
									
									
									
									
									
								
							
							
						
						
									
										171
									
								
								src/main.cc
									
									
									
									
									
								
							| @@ -69,18 +69,38 @@ class Shader { | ||||
|  | ||||
| class Texture2D { | ||||
|   public: | ||||
|     Texture2D(const char *filename, GLint texture_unit); | ||||
|     Texture2D(const char *filename, GLint texture_unit, const char *name); | ||||
|     ~Texture2D(); | ||||
|     void activate(); | ||||
|     void activate() const; | ||||
|     int width; | ||||
|     int height; | ||||
|     int channels; | ||||
|     GLint texture_unit; | ||||
|     std::string name; | ||||
|   private: | ||||
|     GLuint texture; | ||||
|     GLint texture_unit; | ||||
|     GLint format; | ||||
| }; | ||||
|  | ||||
| struct Vertex { | ||||
|   glm::vec3 position; | ||||
|   glm::vec3 normal; | ||||
|   glm::vec2 tex_coord; | ||||
| }; | ||||
|  | ||||
| class Mesh { | ||||
|   public: | ||||
|     std::vector<Vertex> vertices; | ||||
|     std::vector<GLuint> indices; | ||||
|     std::vector<Texture2D> textures; | ||||
|  | ||||
|     Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures); | ||||
|     void draw(Shader &Shader); | ||||
|   private: | ||||
|     GLuint vao, vbo, ebo; | ||||
|     void setup_mesh(); | ||||
| }; | ||||
|  | ||||
| int main() { | ||||
|   if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { | ||||
|     return EXIT_CODE_SDL_INIT_FAILED; | ||||
| @@ -116,32 +136,32 @@ int main() { | ||||
|  | ||||
|   glEnable(GL_DEPTH_TEST); | ||||
|  | ||||
|   std::vector<GLfloat> vertices = { | ||||
|     // positions         // normals           // texture coords | ||||
|    -0.5f, -0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 1.0f, | ||||
|     0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 0.0f, | ||||
|     0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  1.0f, 1.0f, | ||||
|    -0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 1.0f, | ||||
|     0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 0.0f, | ||||
|     0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 1.0f, | ||||
|    -0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 0.0f, | ||||
|     0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 0.0f, | ||||
|    -0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 1.0f, | ||||
|     0.5f,  0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   1.0f, 1.0f, | ||||
|     0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  1.0f, 0.0f, | ||||
|    -0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,  0.0f, 0.0f, | ||||
|     0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 1.0f, | ||||
|     0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 0.0f, | ||||
|     0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  1.0f, 0.0f, | ||||
|    -0.5f,  0.5f,  0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 0.0f, | ||||
|    -0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  0.0f, 1.0f, | ||||
|    -0.5f, -0.5f,  0.5f,  0.0f,  0.0f, 1.0f,   0.0f, 0.0f, | ||||
|    -0.5f, -0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  0.0f, 0.0f, | ||||
|    -0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,  0.0f, 1.0f, | ||||
|    -0.5f,  0.5f, -0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 1.0f, | ||||
|     0.5f,  0.5f, -0.5f,  0.0f,  1.0f,  0.0f,  1.0f, 1.0f, | ||||
|    -0.5f,  0.5f,  0.5f, -1.0f,  0.0f,  0.0f,  1.0f, 0.0f, | ||||
|     0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,  0.0f, 1.0f, | ||||
|   std::vector<Vertex> vertices = { | ||||
|     // positions                    // normals                      // texture coords | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f,  0.5f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f, -0.5f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f,  0.5f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f,  0.5f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f, -0.5f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f,  0.5f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f, -0.5f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f,  0.5f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f,  0.5f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f,  0.5f), glm::vec3( 0.0f, -1.0f,  0.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f, -0.5f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f,  0.5f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f, -0.5f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f,  0.5f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f, -0.5f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f,  0.5f), glm::vec3( 0.0f,  0.0f,  1.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f, -0.5f,  0.5f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec2(0.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f, -0.5f), glm::vec3( 0.0f,  0.0f, -1.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f, -0.5f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f,  0.5f, -0.5f), glm::vec3( 0.0f,  1.0f,  0.0f), glm::vec2(1.0f, 1.0f)}, | ||||
|     Vertex{glm::vec3(-0.5f,  0.5f,  0.5f), glm::vec3(-1.0f,  0.0f,  0.0f), glm::vec2(1.0f, 0.0f)}, | ||||
|     Vertex{glm::vec3( 0.5f, -0.5f, -0.5f), glm::vec3( 1.0f,  0.0f,  0.0f), glm::vec2(0.0f, 1.0f)}, | ||||
|   }; | ||||
|  | ||||
|   std::vector<GLuint> indices = { | ||||
| @@ -159,48 +179,17 @@ int main() { | ||||
|     13, 15, 16 | ||||
|   }; | ||||
|  | ||||
|   GLuint vao = 0; | ||||
|   glGenVertexArrays(1, &vao); | ||||
|   glBindVertexArray(vao); | ||||
|   std::vector<Texture2D> textures = { | ||||
|     Texture2D("images/container2.png", GL_TEXTURE0, "material.diffuse"), | ||||
|     Texture2D("images/container2_specular.png", GL_TEXTURE1, "material.specular"), | ||||
|   }; | ||||
|  | ||||
|   GLuint ebo = 0; | ||||
|   glGenBuffers(1, &ebo); | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | ||||
|   glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); | ||||
|  | ||||
|   GLuint vbo = 0; | ||||
|   glGenBuffers(1, &vbo); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, vbo); | ||||
|   glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(GLfloat), vertices.data(), GL_STATIC_DRAW); | ||||
|  | ||||
|   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)0); | ||||
|   glEnableVertexAttribArray(0); | ||||
|   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(3 * sizeof(GLfloat))); | ||||
|   glEnableVertexAttribArray(1); | ||||
|   glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)(6 * sizeof(GLfloat))); | ||||
|   glEnableVertexAttribArray(2); | ||||
|  | ||||
|   GLuint light_vao = 0; | ||||
|   glGenVertexArrays(1, &light_vao); | ||||
|   glBindVertexArray(light_vao); | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, vbo); | ||||
|  | ||||
|   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (void *)0); | ||||
|   glEnableVertexAttribArray(0); | ||||
|  | ||||
|   glBindVertexArray(0); | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, 0); | ||||
|   Mesh container = {vertices, indices, textures}; | ||||
|   Mesh light     = {vertices, indices, {}}; | ||||
|  | ||||
|   Shader main_shader  {"shaders/vert.glsl", "shaders/frag.glsl"}; | ||||
|   Shader light_shader {"shaders/vert.glsl", "shaders/light_frag.glsl"}; | ||||
|  | ||||
|   Texture2D diffuse_map  = Texture2D("images/container2.png", GL_TEXTURE0); | ||||
|   Texture2D specular_map = Texture2D("images/container2_specular.png", GL_TEXTURE1); | ||||
|   main_shader.set_int("material.diffuse", 0); | ||||
|   main_shader.set_int("material.specular", 1); | ||||
|  | ||||
|   const float camera_speed   = 25.0f; | ||||
|   glm::vec3 camera_position  = glm::vec3(-2.0f, 0.0f, 6.0f); | ||||
|   glm::vec3 camera_forward   = glm::vec3(0.0f); | ||||
| @@ -382,10 +371,7 @@ int main() { | ||||
|       main_shader.activate(); | ||||
|       main_shader.set_mat4("model", model); | ||||
|       main_shader.set_mat3("normal_mat", normal_mat); | ||||
|       diffuse_map.activate(); | ||||
|       specular_map.activate(); | ||||
|       glBindVertexArray(vao); | ||||
|       glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||
|       container.draw(main_shader); | ||||
|     } | ||||
|  | ||||
|     // Draw light source | ||||
| @@ -395,8 +381,7 @@ int main() { | ||||
|       light_shader.activate(); | ||||
|       light_shader.set_mat4("model", model); | ||||
|       light_shader.set_vec3("light_diffuse", light_diffuse); | ||||
|       glBindVertexArray(light_vao); | ||||
|       glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||
|       light.draw(light_shader); | ||||
|     } | ||||
|  | ||||
|     SDL_GL_SwapWindow(window); | ||||
| @@ -546,7 +531,7 @@ const char *Shader::get_shader_type_string(GLenum shader_type) { | ||||
|   return output; | ||||
| } | ||||
|  | ||||
| Texture2D::Texture2D(const char *filename, GLint texture_unit) : texture_unit(texture_unit) { | ||||
| Texture2D::Texture2D(const char *filename, GLint texture_unit, const char *name) : texture_unit(texture_unit), name(name) { | ||||
|   uint8_t *image = stbi_load(filename, &width, &height, &channels, 0); | ||||
|   if (!image) { | ||||
|     return; | ||||
| @@ -572,7 +557,45 @@ Texture2D::Texture2D(const char *filename, GLint texture_unit) : texture_unit(te | ||||
|  | ||||
| Texture2D::~Texture2D() {} | ||||
|  | ||||
| void Texture2D::activate() { | ||||
| void Texture2D::activate() const { | ||||
|   glActiveTexture(texture_unit); | ||||
|   glBindTexture(GL_TEXTURE_2D, texture); | ||||
| } | ||||
|  | ||||
| Mesh::Mesh(std::vector<Vertex> vertices, std::vector<GLuint> indices, std::vector<Texture2D> textures) | ||||
|   : vertices(vertices), indices(indices), textures(textures) { | ||||
|     setup_mesh(); | ||||
| } | ||||
|  | ||||
| void Mesh::setup_mesh() { | ||||
|   glGenVertexArrays(1, &vao); | ||||
|   glGenBuffers(1, &ebo); | ||||
|   glGenBuffers(1, &vbo); | ||||
|  | ||||
|   glBindVertexArray(vao); | ||||
|  | ||||
|   glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); | ||||
|   glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size() * sizeof(GLuint), indices.data(), GL_STATIC_DRAW); | ||||
|  | ||||
|   glBindBuffer(GL_ARRAY_BUFFER, vbo); | ||||
|   glBufferData(GL_ARRAY_BUFFER, vertices.size() * sizeof(Vertex), vertices.data(), GL_STATIC_DRAW); | ||||
|  | ||||
|   glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)0); | ||||
|   glEnableVertexAttribArray(0); | ||||
|   glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)(offsetof(Vertex, normal))); | ||||
|   glEnableVertexAttribArray(1); | ||||
|   glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void *)(offsetof(Vertex, tex_coord))); | ||||
|   glEnableVertexAttribArray(2); | ||||
| } | ||||
|  | ||||
| void Mesh::draw(Shader &shader) { | ||||
|   for (int i = 0; i < textures.size(); ++i) { | ||||
|     const Texture2D &texture = textures[i]; | ||||
|     shader.set_int(texture.name.c_str(), texture.texture_unit - GL_TEXTURE0); | ||||
|     texture.activate(); | ||||
|   } | ||||
|  | ||||
|   glBindVertexArray(vao); | ||||
|   glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, (void *)0); | ||||
|   glBindVertexArray(0); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user