From 692fbf8196c46d35b99e515c69e2b93ed63329ec Mon Sep 17 00:00:00 2001 From: k Date: Wed, 28 May 2025 23:56:20 -0400 Subject: [PATCH] loading obj files working. --- headers/camera.hpp | 1 + headers/mesh.hpp | 1 + headers/obj.hpp | 4 +++ src/camera.cpp | 2 ++ src/main.cpp | 33 ++++++++--------------- src/mesh.cpp | 42 ++++++++++++++++++++++++++--- src/obj.cpp | 66 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 124 insertions(+), 25 deletions(-) create mode 100644 headers/obj.hpp create mode 100644 src/obj.cpp diff --git a/headers/camera.hpp b/headers/camera.hpp index 186a073..9e39e14 100644 --- a/headers/camera.hpp +++ b/headers/camera.hpp @@ -11,6 +11,7 @@ public: void addFPos(glm::vec3 pos); void setRotate(float yaw, float pitch); void addRotate(float yaw, float pitch); + glm::vec3 getPos(); glm::mat4 getView(); glm::mat4 getProjection(); float aspect; diff --git a/headers/mesh.hpp b/headers/mesh.hpp index bbe3b80..0f5a619 100644 --- a/headers/mesh.hpp +++ b/headers/mesh.hpp @@ -8,6 +8,7 @@ class Mesh { public: Mesh(Shader *s, unsigned int VAO, int count); + Mesh(Shader *s, std::string path); ~Mesh(); void draw(Camera *c); void setPosition(glm::vec3 p); diff --git a/headers/obj.hpp b/headers/obj.hpp new file mode 100644 index 0000000..151d83c --- /dev/null +++ b/headers/obj.hpp @@ -0,0 +1,4 @@ +#include +#include + +unsigned int loadOBJ(const char *path, std::vector *out_vertices); diff --git a/src/camera.cpp b/src/camera.cpp index ed568e9..8ea6c20 100644 --- a/src/camera.cpp +++ b/src/camera.cpp @@ -52,6 +52,8 @@ glm::mat4 Camera::getView() { return view; } +glm::vec3 Camera::getPos() { return pos; } + glm::mat4 Camera::getProjection() { return glm::perspective(glm::radians(fov), aspect, 0.1f, 100.0f); } diff --git a/src/main.cpp b/src/main.cpp index efc0045..12af3a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,11 +1,10 @@ #include "camera.hpp" -#include /*Must be before GLFW*/ +#include "glad/glad.h" #include #include #include #include #include -#include #include #define UNUSED(x) (void)(x) @@ -37,21 +36,11 @@ GLFWwindow *init() { return window; } -unsigned int meshInit() { - unsigned int VBO, VAO; - glGenVertexArrays(1, &VAO); - glBindVertexArray(VAO); - - glGenBuffers(1, &VBO); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, sizeof(uvcube), uvcube, GL_STATIC_DRAW); - - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), (void *)0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(float), - (void *)(3 * sizeof(float))); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - return VAO; +void showFPS(GLFWwindow *window, double delta) { + char title[22]; + title[21] = '\0'; + snprintf(title, 20, "OpenGl FPS: [%3.2f]", (1 / delta)); + glfwSetWindowTitle(window, title); } int main(void) { @@ -67,9 +56,8 @@ int main(void) { Shader *lightShader = new Shader("./shaders/lighting/Vert.glsl", "./shaders/lighting/LightFrag.glsl"); - uint VAO = meshInit(); - Mesh *cube = new Mesh(cubeShader, VAO, 36); - Mesh *light = new Mesh(lightShader, VAO, 36); + Mesh *cube = new Mesh(cubeShader, "./cube.obj"); + Mesh *light = new Mesh(lightShader, "./cube.obj"); cube->setOwnedShader(true); light->setOwnedShader(true); @@ -79,9 +67,10 @@ int main(void) { glEnable(GL_DEPTH_TEST); float lastFrame = 0; while (!glfwWindowShouldClose(window)) { - float currentFrame = static_cast(glfwGetTime()); + float currentFrame = (float)glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; + showFPS(window, deltaTime); glClearColor(0.2f, 0.3f, 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); @@ -91,7 +80,7 @@ int main(void) { s->setVec3("lightColor", lightColor); s->setVec3("ourColor", glm::vec3(0.24725, 0.1995, 0.0745)); s->setVec3("lightPos", lightPos); - s->setVec3("viewPos", glm::vec3(0.0, 0.0, 5.0)); + s->setVec3("viewPos", cam->getPos()); s->setVec3("light.ambient", glm::vec3(0.2)); s->setVec3("light.diffuse", glm::vec3(0.5)); diff --git a/src/mesh.cpp b/src/mesh.cpp index 3aeba9d..0924474 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1,16 +1,28 @@ #include "camera.hpp" +#include "obj.hpp" #include "shader.hpp" #include +#include + +unsigned int meshInit(std::string path, std::vector &data); Mesh::Mesh(Shader *s, unsigned int VAO, int count) : buffersOwned(false), shaderOwned(false), count(count), VAO(VAO), shader(s), position(glm::vec3(0)), scale(glm::vec3(1)), rotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)) {} +Mesh::Mesh(Shader *s, std::string path) + : buffersOwned(true), shaderOwned(false), shader(s), position(glm::vec3(0)), + scale(glm::vec3(1)), rotation(glm::quat(1.0f, 0.0f, 0.0f, 0.0f)) { + std::vector data; + VAO = meshInit(path, data); + count = data.size() / 8; +} + Mesh::~Mesh() { if (shaderOwned) delete shader; - if (buffersOwned){ + if (buffersOwned) { glDeleteVertexArrays(1, &VAO); // TODO vbo, ibo } @@ -18,7 +30,7 @@ Mesh::~Mesh() { void Mesh::draw(Camera *c) { glm::mat4 model = glm::mat4(1); - + glBindVertexArray(VAO); shader->use(); shader->setMat4("view", c->getView()); shader->setMat4("projection", c->getProjection()); @@ -26,7 +38,7 @@ void Mesh::draw(Camera *c) { model = glm::scale(model, scale); model = model * glm::mat4_cast(rotation); shader->setMat4("model", model); - glDrawArrays(GL_TRIANGLES, 0, 36); + glDrawArrays(GL_TRIANGLES, 0, count); } void Mesh::setPosition(glm::vec3 p) { position = p; } @@ -40,3 +52,27 @@ void Mesh::setOwnedBuffers(bool o) { buffersOwned = o; } void Mesh::setOwnedShader(bool o) { shaderOwned = o; } Shader *Mesh::getShader() { return shader; } + +unsigned int meshInit(std::string path, std::vector &data) { + unsigned int VBO, VAO; + glGenVertexArrays(1, &VAO); + glBindVertexArray(VAO); + + glGenBuffers(1, &VBO); + glBindBuffer(GL_ARRAY_BUFFER, VBO); + + loadOBJ(path.c_str(), &data); + glBufferData(GL_ARRAY_BUFFER, data.size() * sizeof(float), data.data(), + GL_STATIC_DRAW); + glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void *)0); + glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), + (void *)(3 * sizeof(float))); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), + (void *)(6 * sizeof(float))); + + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); + glEnableVertexAttribArray(2); // not in use + glBindVertexArray(0); + return VAO; +} diff --git a/src/obj.cpp b/src/obj.cpp new file mode 100644 index 0000000..fdea71d --- /dev/null +++ b/src/obj.cpp @@ -0,0 +1,66 @@ +#include "obj.hpp" +#include +#include +#include +#include + +/*this is ugly but works*/ +unsigned int loadOBJ(const char *path, std::vector *out_vertices) { + std::vector verts, norms; + std::vector uvs; + + FILE *file = fopen(path, "r"); + assert(file && "file not found"); + + int tmp = 0; + while (1) { + char lineHeader[128]; + int res = fscanf(file, "%s", lineHeader); + if (res == EOF) + break; + if (strcmp(lineHeader, "v") == 0) { + glm::vec3 vert; + tmp = fscanf(file, "%f %f %f\n", &vert.x, &vert.y, &vert.z); + assert(tmp == 3 && "bad vert"); + verts.push_back(vert); + } else if (strcmp(lineHeader, "vt") == 0) { + glm::vec2 uv; + tmp = fscanf(file, "%f %f\n", &uv.x, &uv.y); + assert(tmp == 2 && "bad uv"); + uvs.push_back(uv); + } else if (strcmp(lineHeader, "vn") == 0) { + glm::vec3 norm; + tmp = fscanf(file, "%f %f %f\n", &norm.x, &norm.y, &norm.z); + assert(tmp == 3 && "bad norm"); + norms.push_back(norm); + } else if (strcmp(lineHeader, "f") == 0) { + unsigned int vIndex[3], uvIndex[3], nIndex[3]; + tmp = fscanf(file, "%d/%d/%d %d/%d/%d %d/%d/%d\n", &vIndex[0], + &uvIndex[0], &nIndex[0], &vIndex[1], &uvIndex[1], &nIndex[1], + &vIndex[2], &uvIndex[2], &nIndex[2]); + assert(tmp == 9 && "bad face"); + + for (size_t i = 0; i < 3; ++i) { + size_t vi, ni, ui; + vi = (vIndex[i] - 1); + ni = (nIndex[i] - 1); + ui = (uvIndex[i] - 1); + assert(verts.size() > vi); + assert(norms.size() > ni); + assert(uvs.size() > ui); + auto vert = verts[vi]; + auto norm = norms[ni]; + auto uv = uvs[ui]; + out_vertices->push_back(vert.x); + out_vertices->push_back(vert.y); + out_vertices->push_back(vert.z); + out_vertices->push_back(norm.x); + out_vertices->push_back(norm.y); + out_vertices->push_back(norm.z); + out_vertices->push_back(uv.x); + out_vertices->push_back(uv.y); + } + } + } + return verts.size(); +}