From bfbdbf75f3f63ad0853e4597e7b5e7213b879ca8 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Wed, 25 Dec 2024 21:22:48 +0000 Subject: [PATCH] Create mesh abstraction --- src/main.cc | 171 +++++++++++++++++++++++++++++----------------------- 1 file changed, 97 insertions(+), 74 deletions(-) diff --git a/src/main.cc b/src/main.cc index edf01fb..0d9226f 100644 --- a/src/main.cc +++ b/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 vertices; + std::vector indices; + std::vector textures; + + Mesh(std::vector vertices, std::vector indices, std::vector 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 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 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 indices = { @@ -159,48 +179,17 @@ int main() { 13, 15, 16 }; - GLuint vao = 0; - glGenVertexArrays(1, &vao); - glBindVertexArray(vao); + std::vector 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 vertices, std::vector indices, std::vector 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); +}