瀏覽代碼

Rewrote parser for OBJ files.

angel 7 年之前
父節點
當前提交
d15b268500
共有 15 個文件被更改,包括 175 次插入132 次删除
  1. 14 15
      include/camera.h
  2. 5 1
      include/mesh.h
  3. 1 6
      include/model.h
  4. 20 0
      include/objParser.h
  5. 5 1
      include/scene.h
  6. 1 0
      include/softwareRenderer.h
  7. 二進制
      models/.teapot.obj.swp
  8. 4 4
      src/engine.cpp
  9. 10 0
      src/mesh.cpp
  10. 2 86
      src/model.cpp
  11. 73 0
      src/objParser.cpp
  12. 29 12
      src/scene.cpp
  13. 1 2
      src/sceneManager.cpp
  14. 9 4
      src/softwareRenderer.cpp
  15. 1 1
      src/vector.cpp

+ 14 - 15
include/camera.h

@@ -6,24 +6,23 @@
 
 
 
 
 struct Camera{
 struct Camera{
-    public:
-        Camera();
+    Camera();
 
 
-        void update();
+    void update();
 
 
-        //Position and direction of camera
-        Vector3 position{0,0,8};
-        Vector3 target{0,0,0};
-        Vector3 up{0,1,0};
+    //Position and direction of camera
+    Vector3 position{0,0,8};
+    Vector3 target{0,0,0};
+    Vector3 up{0,1,0};
 
 
-        //Matrices and frustrum stuff
-        Matrix4 viewMatrix;
-        Matrix4 projectionMatrix;
-        float fov{90};
-        //Given in positive values but changed to negative in the matrix
-        float near{0.1};
-        float far{100};
-        float aspectRatio{1.0};
+    //Matrices and frustrum stuff
+    Matrix4 viewMatrix;
+    Matrix4 projectionMatrix;
+    float fov{90};
+    //Given in positive values but changed to negative in the matrix
+    float near{0.1};
+    float far{100};
+    float aspectRatio{1.0};
 };
 };
 
 
 #endif
 #endif

+ 5 - 1
include/mesh.h

@@ -11,7 +11,11 @@ struct Mesh{
     std::vector<Vector3> normals;
     std::vector<Vector3> normals;
 
 
     int numFaces = 0;
     int numFaces = 0;
-    std::vector<Vector3> faces;
+    std::vector<Vector3> vertexIndices;
+    std::vector<Vector3> textureIndices;
+    std::vector<Vector3> normalsIndices;
+
+    void describeMesh();
 };
 };
 
 
 #endif
 #endif

+ 1 - 6
include/model.h

@@ -5,9 +5,9 @@
 #include "string"
 #include "string"
 #include "bound3.h"
 #include "bound3.h"
 #include "matrix.h"
 #include "matrix.h"
+#include "objParser.h"
 
 
 class Model{
 class Model{
-
     public:
     public:
         Model(std::string path); 
         Model(std::string path); 
         void describeMesh();
         void describeMesh();
@@ -18,12 +18,7 @@ class Model{
         void update();
         void update();
 
 
     private:
     private:
-        
         void buildBoundaryBox();
         void buildBoundaryBox();
-        void buildMesh(std::string path);
-        void loadVertices(std::ifstream &fileHandle);
-        void loadNormals(std::ifstream &fileHandle);
-        void loadFaces(std::ifstream &fileHandle);
         Mesh mMesh;
         Mesh mMesh;
         Bound3 mBounds;
         Bound3 mBounds;
 };
 };

+ 20 - 0
include/objParser.h

@@ -0,0 +1,20 @@
+#ifndef OBJPARSER_H
+#define OBJPARSER_H
+
+#include <fstream>
+#include <sstream>
+#include "mesh.h"
+
+namespace OBJ{
+    Mesh& buildMeshFromFile(Mesh &mesh, std::string &path);
+
+    bool fileExists(std::string &path);
+
+    //Get vertices and Normal data
+    void loadFileData(Mesh &mesh, std::ifstream &file);
+
+    std::vector<std::string> split(std::string &str, char delim);
+
+}
+
+#endif

+ 5 - 1
include/scene.h

@@ -18,16 +18,20 @@ class Scene{
         std::vector<Model*>* getVisiblemodels();
         std::vector<Model*>* getVisiblemodels();
 
 
         Camera * getCurrentCamera();
         Camera * getCurrentCamera();
+
+        bool checkIfEmpty();
     private:
     private:
         Camera mainCamera;
         Camera mainCamera;
 
 
+        bool emptyScene;
+
         std::vector<Model*> modelsInScene;
         std::vector<Model*> modelsInScene;
 
 
         //Contains the models that remain after frustrum culling
         //Contains the models that remain after frustrum culling
         std::vector<Model*> visibleModels;
         std::vector<Model*> visibleModels;
         
         
         //Initializes all modelsin the scene
         //Initializes all modelsin the scene
-        void loadSceneModels(std::string path);
+        bool loadSceneModels(std::string &path);
 
 
         //Cull objects that should not be visible and add the visible to the 
         //Cull objects that should not be visible and add the visible to the 
         //visibleModels list for rendering TO DO 
         //visibleModels list for rendering TO DO 

+ 1 - 0
include/softwareRenderer.h

@@ -40,6 +40,7 @@ class SoftwareRenderer {
         
         
         //Pointer to the scene's target camera
         //Pointer to the scene's target camera
         Camera * mCamera;
         Camera * mCamera;
+        bool startUpComplete = false;
 
 
         Buffer<float> * zBuffer;
         Buffer<float> * zBuffer;
         Buffer<Uint32> * pixelBuffer;
         Buffer<Uint32> * pixelBuffer;

二進制
models/.teapot.obj.swp


+ 4 - 4
src/engine.cpp

@@ -41,17 +41,17 @@ bool Engine::startUp(){
 
 
 //Closing in opposite order to avoid dangling pointers
 //Closing in opposite order to avoid dangling pointers
 void Engine::shutDown(){
 void Engine::shutDown(){
-    printf("Closing input manager.\n");
     gInputManager.shutDown();
     gInputManager.shutDown();
+    printf("Closed input manager.\n");
 
 
-    printf("Closing renderer manager.\n");
     gRenderManager.shutDown();
     gRenderManager.shutDown();
+    printf("Closed renderer manager.\n");
     
     
-    printf("Closing Scene manager.\n");
     gSceneManager.shutDown();
     gSceneManager.shutDown();
+    printf("Closed Scene manager.\n");
     
     
-    printf("Closing display manager.\n");
     gDisplayManager.shutDown();
     gDisplayManager.shutDown();
+    printf("Closed display manager.\n");
 }
 }
 
 
 //Runs main application loop and allows for scene changes
 //Runs main application loop and allows for scene changes

+ 10 - 0
src/mesh.cpp

@@ -0,0 +1,10 @@
+#include "mesh.h"
+
+void Mesh::describeMesh(){
+    int meshSize = numVertices;
+    for(int i = 0; i < meshSize; ++i){
+        Vector3 vertex = vertices[i];
+        printf("Vertex  %2.1d: %f, %f, %f \n",i,vertex.x, vertex.y, vertex.z);
+    }
+    printf("Meshsize is: %d \n", meshSize);
+}

+ 2 - 86
src/model.cpp

@@ -1,101 +1,17 @@
 #include "model.h"
 #include "model.h"
-#include <stdio.h>
-#include <iostream>
-#include <fstream>
-#include <sstream>
 #include "vector3.h"
 #include "vector3.h"
-#include "matrix.h"
 #include <limits>
 #include <limits>
 
 
 Model::Model(std::string path){
 Model::Model(std::string path){
-    buildMesh(path);
+    OBJ::buildMeshFromFile(mMesh, path);
     buildBoundaryBox();
     buildBoundaryBox();
+    
 }
 }
 
 
 Mesh * Model::getMesh(){
 Mesh * Model::getMesh(){
     return &mMesh;
     return &mMesh;
 }
 }
 
 
-void Model::describeMesh(){
-    int meshSize = mMesh.numVertices;
-    for(int i = 0; i < meshSize; ++i){
-        Vector3 vertex = mMesh.vertices[i];
-        printf("Vertex  %2.1d: %f, %f, %f \n",i,vertex.x, vertex.y, vertex.z);
-    }
-    printf("Meshsize is: %d \n", meshSize);
-}
-
-void Model::buildMesh(std::string path){
-    printf("Loading models...\n");
-
-    //Open file containing vertex data
-    std::ifstream file;
-    file.open(path.c_str());
-
-    //Get vertices into mesh
-    loadVertices(file);
-
-    //Get faces
-    loadFaces(file);
-
-    //Get normals
-    loadNormals(file);
-
-    //Close file after reading
-    file.close();
-}
-
-void Model::loadFaces(std::ifstream &file){
-    std::string line, f, x ,y ,z;
-    while(!file.eof()){
-        
-        std::getline(file,line);
-        std::istringstream iss(line);
-        iss >> f;
-        if(f == "f"){
-            iss >> x >> y >> z;
-            Vector3 face(std::stof(x)-1,std::stof(y)-1,std::stof(z)-1);
-            mMesh.faces.push_back(face);
-        }
-    }
-    mMesh.numFaces = mMesh.faces.size();
-    file.clear();
-    file.seekg(0, file.beg);
-}
-
-void Model::loadVertices(std::ifstream &file){
-    std::string line, v, x ,y ,z;
-    while(!file.eof()){
-        std::getline(file,line);
-        std::istringstream iss(line);
-        iss >> v;
-        if(v == "v"){
-            iss >> x >> y >> z;
-            Vector3 vertex(std::stof(x),std::stof(y),std::stof(z));
-            mMesh.vertices.push_back(vertex);
-        }
-    }
-    mMesh.numVertices = mMesh.vertices.size();
-    file.clear();
-    file.seekg(0, file.beg);
-}
-
-void Model::loadNormals(std::ifstream &file){
-    std::string line, v, x ,y ,z;
-    while(!file.eof()){
-        std::getline(file,line);
-        std::istringstream iss(line);
-        iss >> v;
-        if(v == "vn"){
-            iss >> x >> y >> z;
-            Vector3 normal(std::stof(x),std::stof(y),std::stof(z));
-            mMesh.normals.push_back(normal);
-        }
-    }
-    file.clear();
-    file.seekg(0, file.beg);
-}
-
 void Model::initPosition(TransformParameters initVals){
 void Model::initPosition(TransformParameters initVals){
     Matrix4 modelMatrix = Matrix4::transformMatrix(initVals);
     Matrix4 modelMatrix = Matrix4::transformMatrix(initVals);
     int size = mMesh.numVertices;
     int size = mMesh.numVertices;

+ 73 - 0
src/objParser.cpp

@@ -0,0 +1,73 @@
+#include "objParser.h"
+
+Mesh& OBJ::buildMeshFromFile(Mesh &mesh, std::string &path){
+
+    //Open file containing vertex data
+    std::ifstream file;
+    file.open(path.c_str());
+    
+    //Get vertices and normal data &
+    //Get face, normal and texture indices
+    loadFileData(mesh, file);
+
+    file.close(); 
+}
+
+bool OBJ::fileExists(std::string &path){
+    std::ifstream file(path.c_str());
+    return file.good();
+}
+
+void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
+    std::string line, key, x ,y ,z;
+    Vector3 indices[3];
+    char delimeter = '/';
+    while(!file.eof()){
+        std::getline(file,line);
+        std::istringstream iss(line);
+        iss >> key;
+        if(key == "v"){ //Vertex data
+            iss >> x >> y >> z;
+            Vector3 vertex(std::stof(x),std::stof(y),std::stof(z));
+            mesh.vertices.push_back(vertex);
+        }
+        else if(key == "vn"){ //Normal data
+            iss >> x >> y >> z;
+            Vector3 normal(std::stof(x),std::stof(y),std::stof(z));
+            mesh.normals.push_back(normal);
+        }
+        else if(key == "f"){ //
+            iss >> x >> y >> z;
+            std::vector<std::string> splitX = split(x,delimeter); 
+            std::vector<std::string> splitY = split(y,delimeter);
+            std::vector<std::string> splitZ = split(z,delimeter);
+            for(int i = 0; i < splitX.size(); ++i){
+                indices[i] = Vector3(std::stof(splitX[i])-1,std::stof(splitY[i])-1,std::stof(splitZ[i])-1);
+            }
+            mesh.vertexIndices.push_back(indices[0]);
+            mesh.textureIndices.push_back(indices[1]);
+            mesh.normalsIndices.push_back(indices[2]);
+        }
+    }
+    mesh.numVertices = mesh.vertices.size();
+    mesh.numFaces = mesh.vertexIndices.size();
+    file.clear();
+    file.seekg(0, file.beg);
+}
+
+std::vector<std::string> OBJ::split(std::string &str, char delim){
+    std::stringstream ss(str);
+    std::string token;
+    std::vector<std::string> splitString;
+    while(std::getline(ss,token,delim)){
+        if(token == ""){
+            //If token is empty just write -1
+            //Since you cannot have an idnex of that size anyway
+            splitString.push_back("-1"); 
+        }
+        else{
+            splitString.push_back(token);
+        }
+    }
+    return splitString;
+}

+ 29 - 12
src/scene.cpp

@@ -1,12 +1,17 @@
 #include <scene.h>
 #include <scene.h>
+#include "objParser.h"
 
 
 Scene::Scene(std::string path){
 Scene::Scene(std::string path){
-    loadSceneModels(path);
+    emptyScene = loadSceneModels(path);
+
 }
 }
 
 
 Scene::~Scene(){
 Scene::~Scene(){
-    for(Model *models : modelsInScene){
-        delete models;
+
+    if (!emptyScene){
+        for(Model *models : modelsInScene){
+            delete models;
+        }
     }
     }
 }
 }
 
 
@@ -19,22 +24,30 @@ void Scene::update(){
     frustrumCulling();
     frustrumCulling();
 }
 }
 
 
-void Scene::loadSceneModels(std::string path){
+bool Scene::loadSceneModels(std::string &path){
     //In the future I want to read all o the models in the model folder
     //In the future I want to read all o the models in the model folder
     //And build them here.  For now only one
     //And build them here.  For now only one
     std::string fullPath = "../models/";
     std::string fullPath = "../models/";
     fullPath = fullPath + path;
     fullPath = fullPath + path;
-    modelsInScene.push_back(new Model(fullPath));
 
 
-    //We also initialize the model position here position here
-    TransformParameters initParameters;
-    //initParameters.scaling = Vector3(1, 60, 60);
-    //initParameters.rotation = Vector3(0,0,0);
-    initParameters.translation = Vector3(0, -3, 0);
+    if(!OBJ::fileExists(fullPath)){
+        printf("Error! File:%s does not exist.\n",path.c_str());
+        return true;
+    }
+    else{
+        modelsInScene.push_back(new Model(fullPath));
 
 
-    modelsInScene[0]->initPosition(initParameters);
+        //We also initialize the model position here position here
+        TransformParameters initParameters;
+        //initParameters.scaling = Vector3(1, 60, 60);
+        //initParameters.rotation = Vector3(0,0,0);
+        initParameters.translation = Vector3(0, -3, 0);
+        modelsInScene[0]->initPosition(initParameters);
 
 
-    //sceneModel->describeMesh();
+        //sceneModel->describeMesh();
+        return false;
+    }
+    
 }
 }
 
 
 void Scene::frustrumCulling(){
 void Scene::frustrumCulling(){
@@ -57,6 +70,10 @@ Camera* Scene::getCurrentCamera(){
     return &mainCamera;
     return &mainCamera;
 }
 }
 
 
+bool Scene::checkIfEmpty(){
+    return emptyScene;
+}
+
 // //If the frustrum culling returns true it means the model has been culled
 // //If the frustrum culling returns true it means the model has been culled
     // //Because no other models are in the scene we return
     // //Because no other models are in the scene we return
     // // if (frustrumCulling(models, viewMatrix)){
     // // if (frustrumCulling(models, viewMatrix)){

+ 1 - 2
src/sceneManager.cpp

@@ -27,9 +27,8 @@ bool SceneManager::switchScene(){
 
 
 //for now just loads the teapot.obj
 //for now just loads the teapot.obj
 bool SceneManager::loadScene(){
 bool SceneManager::loadScene(){
-    bool success = true;
     currentScene = new Scene("teapot.obj");
     currentScene = new Scene("teapot.obj");
-    return success;
+    return  !currentScene->checkIfEmpty();
 }
 }
 
 
 void SceneManager::update(){
 void SceneManager::update(){

+ 9 - 4
src/softwareRenderer.cpp

@@ -13,13 +13,18 @@ bool SoftwareRenderer::startUp(int w, int h){
     if( !createBuffers(w, h) ){
     if( !createBuffers(w, h) ){
         return false;
         return false;
     }
     }
+    startUpComplete = true;
     return true;
     return true;
 }
 }
 
 
 void SoftwareRenderer::shutDown(){
 void SoftwareRenderer::shutDown(){
+
     mCamera = nullptr;
     mCamera = nullptr;
-    delete zBuffer;
-    delete pixelBuffer;
+    if (startUpComplete){
+        delete zBuffer;
+        delete pixelBuffer;
+    }
+
 }
 }
 
 
 void SoftwareRenderer::clearBuffers(){
 void SoftwareRenderer::clearBuffers(){
@@ -49,7 +54,7 @@ bool SoftwareRenderer::createBuffers(int w, int h){
 void SoftwareRenderer::drawTriangularMesh(Mesh* triMesh){
 void SoftwareRenderer::drawTriangularMesh(Mesh* triMesh){
 
 
     //Getting the vertices, faces 
     //Getting the vertices, faces 
-    std::vector<Vector3> * faces = &triMesh->faces;
+    std::vector<Vector3> * vIndices = &triMesh->vertexIndices;
     std::vector<Vector3> * vertices = &triMesh->vertices;
     std::vector<Vector3> * vertices = &triMesh->vertices;
     std::vector<Vector3> * normals = &triMesh->normals;
     std::vector<Vector3> * normals = &triMesh->normals;
 
 
@@ -63,7 +68,7 @@ void SoftwareRenderer::drawTriangularMesh(Mesh* triMesh){
     Matrix4 MVP = (mCamera->projectionMatrix)*(mCamera->viewMatrix);
     Matrix4 MVP = (mCamera->projectionMatrix)*(mCamera->viewMatrix);
 
 
     float intensity = 0;
     float intensity = 0;
-    for (Vector3 &f : *faces ){
+    for (Vector3 &f : *vIndices){
 
 
         //Pack vertices together into an array
         //Pack vertices together into an array
         buildTri(f,trianglePrimitive, *vertices);
         buildTri(f,trianglePrimitive, *vertices);

+ 1 - 1
src/vector.cpp

@@ -40,7 +40,7 @@ Vector3& Vector3::normalized(){
     }
     }
     else{
     else{
         //Deal with this at some point!
         //Deal with this at some point!
-        printf("Your vector is all zeros!!\n");
+        //printf("Your vector is all zeros!!\n");
     }
     }
     return *this;
     return *this;
 }     
 }