From 528b608bc0c703eb0db484cfec03e268db8525fe Mon Sep 17 00:00:00 2001 From: Jay Robson Date: Mon, 22 Jan 2024 23:53:10 +1100 Subject: [PATCH] added normals --- src/graphics/arrays.cpp | 3 ++ src/graphics/arrays.hpp | 1 + src/graphics/camera.cpp | 29 +++---------- src/graphics/camera.hpp | 3 +- src/graphics/mesh.cpp | 62 ++++++++++++++++++++++++++++ src/graphics/mesh.hpp | 25 +++++++++++ src/graphics/model.cpp | 91 +++++++++++------------------------------ src/graphics/model.hpp | 15 +++---- src/graphics/shader.cpp | 9 +++- src/graphics/window.cpp | 7 ++-- 10 files changed, 140 insertions(+), 105 deletions(-) create mode 100644 src/graphics/mesh.cpp create mode 100644 src/graphics/mesh.hpp diff --git a/src/graphics/arrays.cpp b/src/graphics/arrays.cpp index ced4c60..9d1bfbb 100644 --- a/src/graphics/arrays.cpp +++ b/src/graphics/arrays.cpp @@ -29,5 +29,8 @@ void arrays::vertex_attrib_pointers() glVertexAttribPointer(2, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.pos, &v)); glEnableVertexAttribArray(2); + + glVertexAttribPointer(3, 3, GL_FLOAT, false, sizeof(v), ptr_diff(&v.normal, &v)); + glEnableVertexAttribArray(3); } diff --git a/src/graphics/arrays.hpp b/src/graphics/arrays.hpp index 2f8bc26..b158d3c 100644 --- a/src/graphics/arrays.hpp +++ b/src/graphics/arrays.hpp @@ -12,6 +12,7 @@ struct vertex unsigned long texid = 0; glm::vec2 texpos = {0, 0}; glm::vec3 pos = {0, 0, 0}; + glm::vec3 normal = {0, 0, 0}; vertex() { } vertex(unsigned long texid, glm::vec2 texpos, glm::vec3 pos) : texid(texid), texpos(texpos), pos(pos) { } diff --git a/src/graphics/camera.cpp b/src/graphics/camera.cpp index 473e200..9a87165 100644 --- a/src/graphics/camera.cpp +++ b/src/graphics/camera.cpp @@ -16,8 +16,8 @@ static double x = 0, y = 0, z = 0; void camera::rotate(double y, double p) { - yaw += y * 0.1; - pitch += p * 0.1; + yaw += y * 0.05; + pitch += p * 0.05; if(pitch < -90) pitch = -90; if(pitch > 90) pitch = 90; @@ -37,34 +37,17 @@ void camera::update() glm::vec<3, double> off(0, 0, 0); if(keyboard::is_pressed(GLFW_KEY_SPACE)) - { off.y -= 1; - } - if(keyboard::is_pressed(GLFW_KEY_LEFT_SHIFT)) - { off.y += 1; - } - if(keyboard::is_pressed(GLFW_KEY_W)) - { off.z += 1; - } - if(keyboard::is_pressed(GLFW_KEY_S)) - { off.z -= 1; - } - if(keyboard::is_pressed(GLFW_KEY_A)) - { off.x += 1; - } - if(keyboard::is_pressed(GLFW_KEY_D)) - { off.x -= 1; - } double angle = -glm::radians(yaw); @@ -75,12 +58,12 @@ void camera::update() glm::vec<2, double> rotated = glm::vec<2, double>(off.x, off.z) * mat; - y += off.y * 0.1; - x += rotated.x * 0.1; - z += rotated.y * 0.1; + y += off.y * 0.05; + x += rotated.x * 0.05; + z += rotated.y * 0.05; } -glm::mat4 camera::get() +glm::mat4 camera::get_model_matrix() { glm::mat4 mat(1); diff --git a/src/graphics/camera.hpp b/src/graphics/camera.hpp index 1f81ccb..37ac263 100644 --- a/src/graphics/camera.hpp +++ b/src/graphics/camera.hpp @@ -2,11 +2,12 @@ #pragma once #include +#include namespace sim::graphics::camera { -glm::mat4 get(); +glm::mat4 get_model_matrix(); void rotate(double pitch, double yaw); void move(double x, double y, double z); void update(); diff --git a/src/graphics/mesh.cpp b/src/graphics/mesh.cpp new file mode 100644 index 0000000..f561e96 --- /dev/null +++ b/src/graphics/mesh.cpp @@ -0,0 +1,62 @@ + +#include +#include + +#include "mesh.hpp" +#include "arrays.hpp" +#include + +using namespace sim::graphics; + +mesh::mesh() +{ + glGenVertexArrays(1, &vao); + glGenBuffers(1, &vbo); + glGenBuffers(1, &ebo); + + glBindVertexArray(vao); + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); + + arrays::vertex_attrib_pointers(); +} + +mesh::mesh(mesh&& o) +{ + vbo = o.vbo; + ebo = o.ebo; + vao = o.vao; + size = o.size; + o.vbo = 0; + o.ebo = 0; + o.vao = 0; +} + +mesh::~mesh() +{ + if(vbo) glDeleteBuffers(1, &vbo); + if(ebo) glDeleteBuffers(1, &ebo); + if(vao) glDeleteVertexArrays(1, &vao); +} + +void mesh::set_vertices(const arrays::vertex* data, size_t size, int mode) +{ + glBufferData(GL_ARRAY_BUFFER, size * sizeof(data[0]), data, mode); +} + +void mesh::set_indices(const unsigned int* data, size_t size, int mode) +{ + glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(data[0]), data, mode); + this->size = size; +} + +void mesh::bind() const +{ + glBindVertexArray(vao); +} + +void mesh::render() const +{ + glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0); +} + diff --git a/src/graphics/mesh.hpp b/src/graphics/mesh.hpp new file mode 100644 index 0000000..b5f9b2a --- /dev/null +++ b/src/graphics/mesh.hpp @@ -0,0 +1,25 @@ + +#pragma once + +#include "arrays.hpp" + +namespace sim::graphics +{ + +struct mesh +{ + unsigned int vao = 0, vbo = 0, ebo = 0, size = 0; + + mesh(); + mesh(mesh&& o); + mesh(const mesh& o) = delete; + ~mesh(); + + void bind() const; + void set_vertices(const arrays::vertex* data, size_t size, int mode); + void set_indices(const unsigned int* data, size_t size, int mode); + void render() const; +}; + +}; + diff --git a/src/graphics/model.cpp b/src/graphics/model.cpp index c8349dd..6139305 100644 --- a/src/graphics/model.cpp +++ b/src/graphics/model.cpp @@ -8,115 +8,74 @@ #include +#include "mesh.hpp" #include "model.hpp" #include "arrays.hpp" using namespace sim::graphics; -model::model() +static void proc_mesh(std::vector& meshes, aiMesh* mesh, const aiScene* scene) { - -} - -model::~model() -{ - if(vbo) glDeleteBuffers(1, &vbo); - if(ebo) glDeleteBuffers(1, &ebo); - if(vao) glDeleteVertexArrays(1, &vao); -} - -void model::alloc() -{ - glGenVertexArrays(1, &vao); - glGenBuffers(1, &vbo); - glGenBuffers(1, &ebo); - - glBindVertexArray(vao); - glBindBuffer(GL_ARRAY_BUFFER, vbo); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ebo); - - arrays::vertex_attrib_pointers(); -} - -void model::load_vbo(const arrays::vertex* data, size_t size, int mode) -{ - glBufferData(GL_ARRAY_BUFFER, size * sizeof(data[0]), data, mode); -} - -void model::load_ebo(const unsigned int* data, size_t size, int mode) -{ - glBufferData(GL_ELEMENT_ARRAY_BUFFER, size * sizeof(data[0]), data, mode); - this->size = size; -} - -struct proc_state -{ - size_t at = 0; std::vector vertices; std::vector indices; -}; - -static void proc_mesh(proc_state& state, aiMesh* mesh, const aiScene* scene) -{ + for(unsigned int i = 0; i < mesh->mNumVertices; i++) { arrays::vertex vertex; vertex.pos = {mesh->mVertices[i].x, mesh->mVertices[i].y, mesh->mVertices[i].z}; - state.vertices.push_back(vertex); - } + if(mesh->HasNormals()) + { + vertex.normal = {mesh->mNormals[i].x, mesh->mNormals[i].y, mesh->mNormals[i].z}; + } - unsigned int at = state.at; + vertices.push_back(vertex); + } for(unsigned int i = 0; i < mesh->mNumFaces; i++) { aiFace face = mesh->mFaces[i]; - unsigned int j; - for(j = 0; j < face.mNumIndices; j++) + for(unsigned int j = 0; j < face.mNumIndices; j++) { - state.indices.push_back(face.mIndices[j] + state.at); + indices.push_back(face.mIndices[j]); } - - at += j; } - state.at = at; + sim::graphics::mesh m; + m.set_vertices(&vertices[0], vertices.size(), GL_STATIC_DRAW); + m.set_indices(&indices[0], indices.size(), GL_STATIC_DRAW); + meshes.push_back(std::move(m)); } -static void proc_node(proc_state& state, aiNode* node, const aiScene* scene) +static void proc_node(std::vector& meshes, aiNode* node, const aiScene* scene) { for(size_t i = 0; i < node->mNumMeshes; i++) { aiMesh* mesh = scene->mMeshes[node->mMeshes[i]]; - proc_mesh(state, mesh, scene); + proc_mesh(meshes, mesh, scene); } for(size_t i = 0; i < node->mNumChildren; i++) { - proc_node(state, node->mChildren[i], scene); + proc_node(meshes, node->mChildren[i], scene); } } void model::load(const char* path) { - proc_state state; Assimp::Importer importer; const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); - proc_node(state, scene->mRootNode, scene); - - load_vbo(&state.vertices[0], state.vertices.size(), GL_STATIC_DRAW); - load_ebo(&state.indices[0], state.indices.size(), GL_STATIC_DRAW); + proc_node(meshes, scene->mRootNode, scene); } -void model::bind() +void model::render() const { - glBindVertexArray(vao); -} - -void model::render() -{ - glDrawElements(GL_TRIANGLES, size, GL_UNSIGNED_INT, 0); + for(const mesh& m : meshes) + { + m.bind(); + m.render(); + } } diff --git a/src/graphics/model.hpp b/src/graphics/model.hpp index c181f3f..8a15c52 100644 --- a/src/graphics/model.hpp +++ b/src/graphics/model.hpp @@ -1,24 +1,19 @@ #pragma once -#include "arrays.hpp" +#include "mesh.hpp" + +#include namespace sim::graphics { struct model { - unsigned int vao = 0, vbo = 0, ebo = 0, size = 0; + std::vector meshes; - model(); - ~model(); - - void bind(); - void alloc(); void load(const char* path); - void load_vbo(const arrays::vertex* data, size_t size, int mode); - void load_ebo(const unsigned int* data, size_t size, int mode); - void render(); + void render() const; }; }; diff --git a/src/graphics/shader.cpp b/src/graphics/shader.cpp index e6a6fce..f0bba1f 100644 --- a/src/graphics/shader.cpp +++ b/src/graphics/shader.cpp @@ -16,6 +16,7 @@ static const char* VERTEX_SHADER = R"( layout (location = 0) in sampler2D aTex; layout (location = 1) in vec2 aTexPos; layout (location = 2) in vec3 aPos; +layout (location = 3) in vec3 aNormal; uniform mat4 model; uniform mat4 projection; @@ -27,10 +28,16 @@ out float zVal; void main() { vec4 pos = model * vec4(aPos, 1.0); + + mat3 model_norm = mat3(model); + vec3 normal = aNormal; + vec3 cNormal = vec3(0.f, 0.f, 1.f) * model_norm; + + zVal = dot(normal, cNormal);// / (length(aNormal) * length(cNormal)); + gl_Position = projection * pos; texPos = aTexPos; tex = aTex; - zVal = 8.0f / (pos.z * pos.z); } )"; diff --git a/src/graphics/window.cpp b/src/graphics/window.cpp index fe0447d..01d267c 100644 --- a/src/graphics/window.cpp +++ b/src/graphics/window.cpp @@ -66,8 +66,7 @@ void window::create() shader::init_program(); - Model.alloc(); - Model.load("monkey.obj"); + Model.load("teapot.obj"); glViewport(0, 0, 800, 600); } @@ -86,13 +85,14 @@ void window::loop() camera::update(); - glm::mat4 mat_model = camera::get(); + glm::mat4 mat_model = camera::get_model_matrix(); double mouse_x, mouse_y; mouse::get(mouse_x, mouse_y); mat_model = glm::translate(mat_model, glm::vec3(0.0f, 0.0f, -5.0f)); mat_model = glm::rotate(mat_model, float(M_PI * 0.125), glm::vec3(1, 1, 1)); + mat_model = glm::scale(mat_model, glm::vec3(1, 1, 1) * 0.2f); glm::mat4 mat_projection = glm::perspective(float(M_PI * 0.25), (float)resize::get_aspect(), 0.1f, 100.f); @@ -101,7 +101,6 @@ void window::loop() glUniformMatrix4fv(shader::gl_model, 1, false, &mat_model[0][0]); glUniform1i(shader::gl_do_tex, 0); - Model.bind(); Model.render(); glfwSwapBuffers(win);