diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index f5f0143..6252973 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -67,11 +67,11 @@ int main(int argc, char *argv[]) { terrain->translate(0.f, -5.f, -15.f); game.add_event(terrain); */ - se::gfx::Texture stall_texture("examples/dev_testing/resources/stallTextureb.png"); + /* se::gfx::Texture stall_texture("examples/dev_testing/resources/stallTextureb.png"); auto stall = std::make_shared(game.get_window(), core_shader, stall_texture, "examples/dev_testing/resources/stall.obj"); stall->translate(10.f, -5.f, 0.f); stall->rotate_y(90.f); - game.add_event(stall); + game.add_event(stall); */ /* std::vector square_vertices = { { se::Vectorf(0.5f, 0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right @@ -107,7 +107,7 @@ int main(int argc, char *argv[]) { tri->scale(.75f); game.add_event(tri); */ - /* std::vector cube_vertices = { + std::vector cube_vertices = { { se::Vectorf(-1.f, -1.f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, { se::Vectorf(1.f, -1.f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, { se::Vectorf(1.f, 1.f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 0.f) }, @@ -137,8 +137,9 @@ int main(int argc, char *argv[]) { }; auto cube = std::make_shared(game.get_window(), core_shader, cube_vertices, cube_indicies); - cube->translate(3.f, 0.f, 0.f); - game.add_event(cube); */ + cube->calculate_normals(); + cube->translate(3.5f, 0.f, 0.f); + game.add_event(cube); auto camera = std::make_shared(game.get_window(), core_shader, 70, glm::vec3(0, 0, 0)); game.add_event(camera); diff --git a/include/simpleengine/gfx/model.h b/include/simpleengine/gfx/model.h index 0cc7bc2..68097fc 100644 --- a/include/simpleengine/gfx/model.h +++ b/include/simpleengine/gfx/model.h @@ -12,7 +12,7 @@ namespace simpleengine::gfx { class Model : public simpleengine::Renderable, public simpleengine::Transformable { public: - std::vector vertices; + std::vector vertices; std::vector indicies; gfx::VBO ebo; gfx::VBO vbo; @@ -20,14 +20,25 @@ namespace simpleengine::gfx { gfx::Shader shader; - Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies = std::vector()); - Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, + Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies = std::vector()); + Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, std::vector indicies = std::vector()); protected: virtual void setup_vertices(); public: - virtual void update(const float& delta_time) override; virtual void render(GLFWwindow* target) override; + + private: + glm::vec3 compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3); + + public: + /** + * @brief Calculate the normals of the model. + * + * @note This **will** overwrite the existing normals. + * + */ + void calculate_normals(); }; } \ No newline at end of file diff --git a/include/simpleengine/gfx/textured_model.h b/include/simpleengine/gfx/textured_model.h index 8bbea41..13d7fdc 100644 --- a/include/simpleengine/gfx/textured_model.h +++ b/include/simpleengine/gfx/textured_model.h @@ -21,14 +21,14 @@ namespace simpleengine::gfx { public: std::vector textures; - TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, + TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, std::vector indicies = std::vector()); - TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector vertices, + TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, std::vector vertices, std::vector indicies = std::vector()); - TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, + TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, std::vector indicies = std::vector()); - TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector textures, std::vector vertices, + TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector textures, std::vector vertices, std::vector indicies = std::vector()); virtual void update(const float& delta_time) override; diff --git a/include/simpleengine/gfx/vao.h b/include/simpleengine/gfx/vao.h index ee1644d..377466a 100644 --- a/include/simpleengine/gfx/vao.h +++ b/include/simpleengine/gfx/vao.h @@ -65,5 +65,20 @@ namespace simpleengine::gfx { // don't unbind VAOs (nor VBOs) when it's not directly necessary. glBindVertexArray(0); } + + void disable_attrib(const VBO& vbo, GLuint index) const { + bind(); + vbo.bind(); + + glDisableVertexAttribArray(index); + //glDisableVertexArrayAttrib(index); + } + + void set_attrib_value(const VBO& vbo, GLuint index, float f) const { + bind(); + vbo.bind(); + + glVertexAttrib1f(index, f); + } }; } \ No newline at end of file diff --git a/include/simpleengine/objects/3d/terrain.h b/include/simpleengine/objects/3d/terrain.h index 3dcb664..19e1721 100644 --- a/include/simpleengine/objects/3d/terrain.h +++ b/include/simpleengine/objects/3d/terrain.h @@ -26,7 +26,7 @@ namespace simpleengine::objects_3d { gfx::Texture texture; Terrain(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, int grid_x, int grid_y, float size = 800.f, int vertex_count = 128) : - simpleengine::gfx::TexturedModel(window, shader, { texture }, std::vector()), x(grid_x * size), y(grid_y * size), + simpleengine::gfx::TexturedModel(window, shader, { texture }, std::vector()), x(grid_x * size), y(grid_y * size), texture(texture), size(size), vertex_count(vertex_count) { generate_terrain(); diff --git a/include/simpleengine/vertex.h b/include/simpleengine/vertex.h index 652dc15..ccbccd7 100644 --- a/include/simpleengine/vertex.h +++ b/include/simpleengine/vertex.h @@ -14,20 +14,7 @@ #include "vector.h" namespace simpleengine { - class Vertex { - public: - simpleengine::Vectorf position; - glm::vec3 color; - glm::vec2 tex_coord; - float texture_id = 0.f; - - Vertex() = default; - - Vertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, int texture_id = 0) : - position(position), color(color), tex_coord(tex_coord), texture_id((float) texture_id) { - - } - }; + /** * @brief A `Vertex` that can be lit up. @@ -39,16 +26,21 @@ namespace simpleengine { glm::vec3 color; glm::vec2 tex_coord; glm::vec3 normal; - float texture_id = 0.f; + float texture_id = -1.f; LitVertex() = default; - LitVertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = 0) : + LitVertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, int texture_id = -1.f) : + position(position), color(color), tex_coord(tex_coord), normal(glm::vec3(0.f)), texture_id((float) texture_id) { + + } + + LitVertex(simpleengine::Vectorf position, glm::vec3 color, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = -1.f) : position(position), color(color), tex_coord(tex_coord), normal(normal), texture_id((float) texture_id) { } - LitVertex(simpleengine::Vectorf position, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = 0) : + LitVertex(simpleengine::Vectorf position, glm::vec2 tex_coord, glm::vec3 normal, int texture_id = -1.f) : position(position), color(glm::vec3(1.f)), tex_coord(tex_coord), normal(normal), texture_id((float) texture_id) { } diff --git a/resources/shaders/core/3d/fragment_core.glsl b/resources/shaders/core/3d/fragment_core.glsl index 3d09bb5..d134fa1 100644 --- a/resources/shaders/core/3d/fragment_core.glsl +++ b/resources/shaders/core/3d/fragment_core.glsl @@ -36,10 +36,10 @@ void main() { float reflectivity = u_texture_reflectivity[id]; vec3 final_specular = calculate_specular(unit_normal, shine_damper, reflectivity); - fs_color = vec4(diffuse, 1.f) * texture(u_textures[1], vs_texcoord) + vec4(final_specular, 1.f); + fs_color = vec4(diffuse, 1.f) * texture(u_textures[id], vs_texcoord) + vec4(final_specular, 1.f); //fs_color = texture(u_textures[1], vs_texcoord); } else { - fs_color = vec4(diffuse, 1.f) * vec4(vs_color, 1.f); // We don't add any reflectivity to solid colored vectors. + fs_color = vec4(vs_color, 1.f); // We don't add any reflectivity to solid colored vectors. } } diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index 0298773..d53f425 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -1,31 +1,36 @@ #include "gfx/model.h" namespace simpleengine::gfx { - Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies) : + Model::Model(GLFWwindow* window, gfx::Shader shader, std::vector vertices, std::vector indicies) : simpleengine::Renderable(window), shader(shader), vertices(vertices), indicies(indicies), vbo(gfx::VBO(GL_ARRAY_BUFFER, false)), ebo(gfx::VBO(GL_ELEMENT_ARRAY_BUFFER, false)) { setup_vertices(); } - Model::Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, std::vector indicies) : + Model::Model(GLFWwindow* window, GLuint shader_program, std::vector vertices, std::vector indicies) : Model(window, gfx::Shader(shader_program), vertices, indicies) { } void Model::setup_vertices() { vao.bind(); - vbo.buffer(vertices.data(), 0, sizeof(Vertex) * vertices.size()); + vbo.buffer(vertices.data(), 0, sizeof(LitVertex) * vertices.size()); if (!indicies.empty()) { ebo.buffer(indicies.data(), 0, indicies.size() * sizeof(GLuint)); } // Enable VAO attributes - vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, position)); - vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, color)); + vao.enable_attrib(vbo, 0, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, position)); + vao.enable_attrib(vbo, 1, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, color)); + vao.enable_attrib(vbo, 2, 3, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, normal)); // Attribute 2 is used for normals - vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, tex_coord)); - vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(Vertex), offsetof(Vertex, texture_id)); + vao.enable_attrib(vbo, 3, 2, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, tex_coord)); + vao.enable_attrib(vbo, 4, 1, GL_FLOAT, sizeof(LitVertex), offsetof(LitVertex, texture_id)); + + /* vao.disable_attrib(vbo, 2); + vao.disable_attrib(vbo, 4); + vao.set_attrib_value(vbo, 4, -1.f); */ glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); @@ -49,4 +54,34 @@ namespace simpleengine::gfx { glDrawElements(GL_TRIANGLES, indicies.size(), GL_UNSIGNED_INT, 0); } } + + glm::vec3 Model::compute_face_normal(const glm::vec3& p1, const glm::vec3& p2, const glm::vec3& p3) { + // Uses p2 as a new origin for p1,p3 + auto a = p3 - p2; + auto b = p1 - p2; + + // Compute the cross product a X b to get the face normal + return glm::normalize(glm::cross(a, b)); + } + + void Model::calculate_normals() { + std::vector normals = std::vector(vertices.size()); + + for (int i = 0; i < indicies.size(); i+=3) { + const glm::vec3& a = vertices[indicies[i]].position; + const glm::vec3& b = vertices[indicies[i + 1]].position; + const glm::vec3& c = vertices[indicies[i + 2]].position; + glm::vec3 normal = compute_face_normal(a, b, c); + + normals[indicies[i]] += normal; + normals[indicies[i + 1]] += normal; + normals[indicies[i + 2]] += normal; + } + + for (int i = 0; i < normals.size(); i++) { + normals[i] = glm::normalize(normals[i]); + + vertices[i].normal = normals[i]; + } + } } \ No newline at end of file diff --git a/src/gfx/textured_model.cpp b/src/gfx/textured_model.cpp index cd4cef3..3945a36 100644 --- a/src/gfx/textured_model.cpp +++ b/src/gfx/textured_model.cpp @@ -2,24 +2,24 @@ #include "gfx/ssbo.h" namespace simpleengine::gfx { - TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, + TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, gfx::Texture texture, std::vector vertices, std::vector indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies), textures(std::vector{texture}) { } TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, gfx::Texture texture, - std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), + std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), std::vector{texture}, vertices, indicies) { } - TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, + TexturedModel::TexturedModel(GLFWwindow* window, gfx::Shader shader, std::vector textures, std::vector vertices, std::vector indicies) : simpleengine::gfx::Model(window, shader, vertices, indicies), textures(textures) { } TexturedModel::TexturedModel(GLFWwindow* window, GLuint shader_program, std::vector textures, - std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), + std::vector vertices, std::vector indicies) : TexturedModel(window, gfx::Shader(shader_program), textures, vertices, indicies) { } diff --git a/src/objects/3d/mesh.cpp b/src/objects/3d/mesh.cpp index d9bc2f7..f4037e0 100644 --- a/src/objects/3d/mesh.cpp +++ b/src/objects/3d/mesh.cpp @@ -41,7 +41,7 @@ namespace simpleengine::objects_3d { } Mesh::Mesh(GLFWwindow *window, gfx::Shader shader, gfx::Texture texture, std::ifstream file_stream) : - simpleengine::gfx::TexturedModel(window, shader, std::vector{texture}, std::vector()) { + simpleengine::gfx::TexturedModel(window, shader, std::vector{texture}, std::vector()) { if (!file_stream.is_open()) { std::cerr << "File stream that was given to ObjModel::ObjModel is not open!" << std::endl;