Browse Source

Revert point before refactor.

angel 7 years ago
parent
commit
26ed6488ad

+ 1 - 1
CMakeLists.txt

@@ -10,7 +10,7 @@ include_directories(${SDL2_INCLUDE_DIR} include libs)
 file(GLOB source_files "*.h" "*.cpp" "src/*.cpp" "include/*.h" "libs/*.h")
 file(GLOB source_files "*.h" "*.cpp" "src/*.cpp" "include/*.h" "libs/*.h")
 message(STATUS $ENV{source_files})
 message(STATUS $ENV{source_files})
 add_executable(softwareRenderer ${source_files})
 add_executable(softwareRenderer ${source_files})
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 ")
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ")
 set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ")
 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ")
 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ")
 target_link_libraries(softwareRenderer ${SDL2_LIBRARY})
 target_link_libraries(softwareRenderer ${SDL2_LIBRARY})

+ 2 - 8
include/displayManager.h

@@ -35,16 +35,10 @@ class DisplayManager{
         //Wrappers for SDL init functions
         //Wrappers for SDL init functions
         bool startSDL();
         bool startSDL();
         bool createWindow();
         bool createWindow();
-        bool createSDLRenderer();
-        bool createScreenTexture();
+        bool createScreenSurface();
 
 
-        SDL_Texture  *mTexture;
-        SDL_Renderer *mSDLRenderer;
+        SDL_Surface  *mSurface;
         SDL_Window   *mWindow;
         SDL_Window   *mWindow;
-
-        //These are only really needed for the texture copying operation
-        int           mTexturePitch;
-        void         *mTexturePixels;
 };
 };
 
 
 #endif
 #endif

+ 1 - 1
include/geometry.h

@@ -33,7 +33,7 @@ class Frustrum{
         };
         };
     public:
     public:
         float  fov, AR, near, far , nearH, nearW, farH, farW;
         float  fov, AR, near, far , nearH, nearW, farH, farW;
-        Frustrum(float ratio): fov(90), near(0.1), far(10000), AR(ratio){};
+        Frustrum(float ratio): fov(90), near(0.01), far(1000), AR(ratio){};
         Plane pl[6];
         Plane pl[6];
 
 
         void setCamInternals();
         void setCamInternals();

+ 4 - 0
include/mesh.h

@@ -10,6 +10,7 @@ struct Mesh{
     int numVertices = 0;
     int numVertices = 0;
     std::vector<Vector3f> vertices;
     std::vector<Vector3f> vertices;
     std::vector<Vector3f> normals;
     std::vector<Vector3f> normals;
+    std::vector<Vector3f> fNormals; //Normals for the whole face
     std::vector<Vector3f> texels;
     std::vector<Vector3f> texels;
 
 
     int numFaces = 0;
     int numFaces = 0;
@@ -19,6 +20,9 @@ struct Mesh{
 
 
     //Simple mesh description for debugging.
     //Simple mesh description for debugging.
     void describeMesh();
     void describeMesh();
+
+    //Builds facet normals for early back face culling
+    void buildFacetNormals();
 };
 };
 
 
 #endif
 #endif

+ 1 - 1
include/rasterizer.h

@@ -40,7 +40,7 @@ class Rasterizer{
         Rasterizer(){}; //Ensuring an object can never be instanced accidentally
         Rasterizer(){}; //Ensuring an object can never be instanced accidentally
 
 
         //Setting this equal to the same pixel format our screen texture is in
         //Setting this equal to the same pixel format our screen texture is in
-        static const Uint32 PIXEL_FORMAT = SDL_PIXELFORMAT_RGBA8888;
+        static const Uint32 PIXEL_FORMAT = SDL_PIXELFORMAT_RGB888;
         static const SDL_PixelFormat* mappingFormat;
         static const SDL_PixelFormat* mappingFormat;
 
 
         //Some basic colors
         //Some basic colors

+ 1 - 1
include/softwareRenderer.h

@@ -51,7 +51,7 @@ class SoftwareRenderer {
         void perspectiveDivide(Vector3f *clippedVertices);
         void perspectiveDivide(Vector3f *clippedVertices);
 
 
         //Culling and clipping methods
         //Culling and clipping methods
-        bool backFaceCulling(Vector3f *trianglePrim, Vector3f &viewDir);
+        bool backFaceCulling(Vector3f &facetNormal, Vector3f &vertex, Matrix4 &worldToObject);
         bool clipTriangles(Vector3f *clipSpaceVertices);
         bool clipTriangles(Vector3f *clipSpaceVertices);
 
 
         //Pointer to the scene's target camera
         //Pointer to the scene's target camera

+ 16 - 44
src/displayManager.cpp

@@ -14,28 +14,15 @@ bool DisplayManager::startUp(){
             success = false;
             success = false;
         }
         }
         else{
         else{
-            if( !createSDLRenderer() ){
+            if( !createScreenSurface() ){
                 success = false;
                 success = false;
             }
             }
-            else{
-                if( !createScreenTexture() ){
-                    success = false;
-                }
-            }
-
         }
         }
     }
     }
     return success;
     return success;
 }
 }
 
 
 void DisplayManager::shutDown(){
 void DisplayManager::shutDown(){
-    mTexturePixels = nullptr;
-  
-    SDL_DestroyTexture(mTexture);
-    mTexture = nullptr;
-
-    SDL_DestroyRenderer(mSDLRenderer);
-    mSDLRenderer = nullptr;
 
 
     SDL_DestroyWindow(mWindow);
     SDL_DestroyWindow(mWindow);
     mWindow = nullptr;
     mWindow = nullptr;
@@ -60,46 +47,31 @@ bool DisplayManager::createWindow(){
     return true;
     return true;
 }
 }
 
 
-bool DisplayManager::createSDLRenderer(){
-    mSDLRenderer = SDL_CreateRenderer(mWindow, -1, SDL_RENDERER_PRESENTVSYNC);
-    if(mSDLRenderer == nullptr){
-        printf("Could not create renderer context. Error: %s\n", SDL_GetError());
-        return false;
-    }
-    return true;
-}
-
-bool DisplayManager::createScreenTexture(){
-    mTexture = SDL_CreateTexture(mSDLRenderer, SDL_PIXELFORMAT_RGBA8888,
-        SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT);
-    if(mTexture == NULL){
-        printf("Could not create texture. Error: %s\n", SDL_GetError());
+bool DisplayManager::createScreenSurface(){
+    mSurface = SDL_GetWindowSurface(mWindow);
+    if(mSurface == NULL){
+        printf("Could not create window surface. Error: %s\n", SDL_GetError());
         return false;
         return false;
     }
     }
     return true;
     return true;
 }
 }
 
 
 void DisplayManager::clear(){
 void DisplayManager::clear(){
-    SDL_SetRenderDrawColor(mSDLRenderer, 0x00, 0x00, 0x00, 0xFF);
-    SDL_RenderClear(mSDLRenderer);
+    //Clear to black
+    SDL_LockSurface(mSurface);
+    SDL_memset(mSurface->pixels,0 ,mSurface->h * mSurface->pitch);
+    SDL_UnlockSurface(mSurface);
 }
 }
 
 
 void DisplayManager::swapBuffers(Buffer<Uint32> *pixels){
 void DisplayManager::swapBuffers(Buffer<Uint32> *pixels){
-    
-    //Lock texture for manipulation
-    SDL_LockTexture(mTexture, NULL, &mTexturePixels, &mTexturePitch );
-    
-    //Copy pixels to texture memory PRETTY SLOW. FIX?
-    memcpy(mTexturePixels, pixels->buffer, SCREEN_HEIGHT*mTexturePitch);
+    //Allows surface editing 
+    SDL_LockSurface(mSurface);
 
 
-    //Unlocking texture to apply pixel changes
-    SDL_UnlockTexture(mTexture);
-    mTexturePixels = nullptr;
+    //Copy pixels buffer resuls to screen surface
+    memcpy(mSurface->pixels, pixels->buffer, pixels->mHeight*pixels->mPitch);
+    SDL_UnlockSurface(mSurface);
 
 
-    //Setting blendmode for copy operation to renderer backbuffer
-    SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND);
-    SDL_RenderCopy(mSDLRenderer, mTexture, NULL , NULL);
+    //Update surface to window
+    SDL_UpdateWindowSurface(mWindow);
 
 
-    //Update screen to window
-    SDL_RenderPresent( mSDLRenderer );
 }
 }

+ 1 - 0
src/engine.cpp

@@ -82,6 +82,7 @@ void Engine::run(){
 
 
         //Handle all user input
         //Handle all user input
         done = gInputManager.processInput();
         done = gInputManager.processInput();
+        
 
 
         //Update all models, camera and lighting in the current scene
         //Update all models, camera and lighting in the current scene
         gSceneManager.update();
         gSceneManager.update();

+ 8 - 0
src/mesh.cpp

@@ -7,3 +7,11 @@ void Mesh::describeMesh(){
     printf("Meshsize is: %d \n", numVertices);
     printf("Meshsize is: %d \n", numVertices);
 }
 }
     
     
+void Mesh::buildFacetNormals(){
+    for(int i = 0; i < numFaces; ++i){
+        Vector3i indices = vertexIndices[i];
+        Vector3f N1 = vertices[indices.data[1]] - vertices[indices.data[0]];
+        Vector3f N2 = vertices[indices.data[2]] - vertices[indices.data[0]];
+        fNormals.push_back((N1.crossProduct(N2)).normalized());
+    }
+}

+ 1 - 0
src/model.cpp

@@ -4,6 +4,7 @@
 Model::Model(std::string path, TransformParameters &initParameters){
 Model::Model(std::string path, TransformParameters &initParameters){
     OBJ::buildMeshFromFile(mMesh, path);
     OBJ::buildMeshFromFile(mMesh, path);
     mBounds.buildAABB(mMesh);
     mBounds.buildAABB(mMesh);
+    mMesh.buildFacetNormals();
     mModelMatrix = Matrix4::transformMatrix(initParameters);
     mModelMatrix = Matrix4::transformMatrix(initParameters);
 }
 }
 
 

+ 5 - 2
src/objParser.cpp

@@ -21,6 +21,7 @@ bool OBJ::fileExists(std::string &path){
 //Main OBJ parsing function
 //Main OBJ parsing function
 void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
 void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
     std::string line, key, x ,y ,z;
     std::string line, key, x ,y ,z;
+    float tempU, tempV, intpart;
     Vector3i indices[3];
     Vector3i indices[3];
     char delimeter = '/';
     char delimeter = '/';
     while(!file.eof()){
     while(!file.eof()){
@@ -37,9 +38,11 @@ void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
             Vector3f normal(std::stof(x),std::stof(y),std::stof(z));
             Vector3f normal(std::stof(x),std::stof(y),std::stof(z));
             mesh.normals.push_back(normal);
             mesh.normals.push_back(normal);
         }
         }
-        else if(key == "vt"){ //Normal data
+        else if(key == "vt"){ //Texture data
             iss >> x >> y;
             iss >> x >> y;
-            Vector3f tex(std::stof(x),std::stof(y),0);
+            tempU = std::modf(std::stof(x), &intpart);
+            tempV = std::modf(std::stof(y), &intpart);
+            Vector3f tex(tempU, tempV, 0);
             mesh.texels.push_back(tex);
             mesh.texels.push_back(tex);
         }
         }
         else if(key == "f"){ //index data
         else if(key == "f"){ //index data

+ 7 - 7
src/rasterizer.cpp

@@ -114,6 +114,7 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
     e_row.z = edge(vertices[0], vertices[1], point);
     e_row.z = edge(vertices[0], vertices[1], point);
 
 
 
 
+
     //Iterating through each pixel in triangle bounding box
     //Iterating through each pixel in triangle bounding box
     for(point.y = yMin; point.y <= yMax; ++point.y){
     for(point.y = yMin; point.y <= yMax; ++point.y){
         //Bary coordinates at start of row
         //Bary coordinates at start of row
@@ -141,11 +142,10 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
                     rgbVals = shader.fragment(uPers , vPers);
                     rgbVals = shader.fragment(uPers , vPers);
 
 
                     //Update pixel buffer with clamped values 
                     //Update pixel buffer with clamped values 
-                    (*pixelBuffer)(point.x,point.y) = SDL_MapRGBA(mappingFormat,
+                    (*pixelBuffer)(point.x,point.y) = SDL_MapRGB(mappingFormat,
                     std::min(rgbVals.data[0],255.0f),
                     std::min(rgbVals.data[0],255.0f),
                     std::min(rgbVals.data[1],255.0f),
                     std::min(rgbVals.data[1],255.0f),
-                    std::min(rgbVals.data[2],255.0f),
-                    0xFF);
+                    std::min(rgbVals.data[2],255.0f));
                 }   
                 }   
             }
             }
 
 
@@ -171,13 +171,13 @@ void Rasterizer::viewportTransform(Buffer<Uint32> *pixelBuffer, Vector3f *vertic
 
 
 
 
 void Rasterizer::triBoundBox(int &xMax, int &xMin, int &yMax, int &yMin,Vector3f *vertices, Buffer<Uint32> *pixelBuffer){
 void Rasterizer::triBoundBox(int &xMax, int &xMin, int &yMax, int &yMin,Vector3f *vertices, Buffer<Uint32> *pixelBuffer){
-    xMax = std::ceil(std::max({vertices[0].x, vertices[1].x, vertices[2].x,}));
-    xMin = std::ceil(std::min({vertices[0].x, vertices[1].x, vertices[2].x,}));
+    xMax = std::ceil(std::max({vertices[0].x, vertices[1].x, vertices[2].x}));
+    xMin = std::ceil(std::min({vertices[0].x, vertices[1].x, vertices[2].x}));
     //xMax = std::max({vertices[0].x, vertices[1].x, vertices[2].x});
     //xMax = std::max({vertices[0].x, vertices[1].x, vertices[2].x});
     //xMin = std::min({vertices[0].x, vertices[1].x, vertices[2].x});
     //xMin = std::min({vertices[0].x, vertices[1].x, vertices[2].x});
 
 
-    yMax = std::ceil(std::max({vertices[0].y, vertices[1].y, vertices[2].y,}));
-    yMin = std::ceil(std::min({vertices[0].y, vertices[1].y, vertices[2].y,}));
+    yMax = std::ceil(std::max({vertices[0].y, vertices[1].y, vertices[2].y}));
+    yMin = std::ceil(std::min({vertices[0].y, vertices[1].y, vertices[2].y}));
     //yMax = std::max({vertices[0].y, vertices[1].y, vertices[2].y});
     //yMax = std::max({vertices[0].y, vertices[1].y, vertices[2].y});
     //yMin = std::min({vertices[0].y, vertices[1].y, vertices[2].y});
     //yMin = std::min({vertices[0].y, vertices[1].y, vertices[2].y});
 
 

+ 14 - 11
src/softwareRenderer.cpp

@@ -23,14 +23,16 @@ void SoftwareRenderer::shutDown(){
 
 
 void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
 void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
     //Getting the vertices, faces, texture data 
     //Getting the vertices, faces, texture data 
+
     Mesh *triMesh = currentModel->getMesh();
     Mesh *triMesh = currentModel->getMesh();
     std::vector<Vector3i> * vIndices = &triMesh->vertexIndices;
     std::vector<Vector3i> * vIndices = &triMesh->vertexIndices;
     std::vector<Vector3i> * tIndices = &triMesh->textureIndices;
     std::vector<Vector3i> * tIndices = &triMesh->textureIndices;
     std::vector<Vector3i> * nIndices = &triMesh->normalsIndices;
     std::vector<Vector3i> * nIndices = &triMesh->normalsIndices;
 
 
     std::vector<Vector3f> * vertices = &triMesh->vertices;
     std::vector<Vector3f> * vertices = &triMesh->vertices;
-    std::vector<Vector3f> * normals = &triMesh->normals;
-    std::vector<Vector3f> * texels = &triMesh->texels;
+    std::vector<Vector3f> * normals  = &triMesh->normals;
+    std::vector<Vector3f> * fNormals = &triMesh->fNormals;
+    std::vector<Vector3f> * texels   = &triMesh->texels;
     int numFaces = triMesh->numFaces;
     int numFaces = triMesh->numFaces;
 
 
     //Array grouping vertices together into triangle
     //Array grouping vertices together into triangle
@@ -51,12 +53,14 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
     lightDir = lightDir.normalized();
     lightDir = lightDir.normalized();
 
 
     //Building ModelViewProjection matrix
     //Building ModelViewProjection matrix
+    Matrix4 worldToObject = (*(currentModel->getModelMatrix())).inverse();
     shader.MV  = (mCamera->viewMatrix)*(*(currentModel->getModelMatrix()));
     shader.MV  = (mCamera->viewMatrix)*(*(currentModel->getModelMatrix()));
     shader.MVP = (mCamera->projectionMatrix)*shader.MV;
     shader.MVP = (mCamera->projectionMatrix)*shader.MV;
     shader.V   = (mCamera->viewMatrix);
     shader.V   = (mCamera->viewMatrix);
     shader.N   = (shader.MV.inverse()).transpose(); 
     shader.N   = (shader.MV.inverse()).transpose(); 
 
 
     //Iterate through every triangle
     //Iterate through every triangle
+    int count = 0;
     for (int j = 0; j < numFaces; ++j){
     for (int j = 0; j < numFaces; ++j){
         //Current vertex and normal indices
         //Current vertex and normal indices
         Vector3i f = (*vIndices)[j];
         Vector3i f = (*vIndices)[j];
@@ -68,6 +72,9 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
         buildTri(n,normalPrim, *normals);
         buildTri(n,normalPrim, *normals);
         buildTri(u,uvPrim, *texels);
         buildTri(u,uvPrim, *texels);
 
 
+        //Early quit if 
+        if (backFaceCulling((*fNormals)[j], trianglePrimitive[0], worldToObject)) continue;
+        ++count;
         //Apply vertex shader
         //Apply vertex shader
         for(int i = 0; i < 3; ++i){
         for(int i = 0; i < 3; ++i){
             trianglePrimitive[i] = shader.vertex(trianglePrimitive[i],
             trianglePrimitive[i] = shader.vertex(trianglePrimitive[i],
@@ -85,7 +92,9 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
         //Send to rasterizer which will also call the fragment shader and write to the 
         //Send to rasterizer which will also call the fragment shader and write to the 
         //zbuffer and pixel buffer.
         //zbuffer and pixel buffer.
         Rasterizer::drawTriangles(trianglePrimitive, shader, pixelBuffer, zBuffer);
         Rasterizer::drawTriangles(trianglePrimitive, shader, pixelBuffer, zBuffer);
+        
     }
     }
+    printf("%d faces drawn.\n", count);
 }
 }
 
 
 void SoftwareRenderer::clearBuffers(){
 void SoftwareRenderer::clearBuffers(){
@@ -126,18 +135,12 @@ void SoftwareRenderer::buildTri(Vector3i &index, Vector3f *primitive, std::vecto
     }
     }
 }
 }
 
 
-bool SoftwareRenderer::backFaceCulling(Vector3f *trianglePrim, Vector3f &viewDir){
-        //Triangle surface normal 
-        //Should probably be calculated on load next time
-        Vector3f N1 = trianglePrim[1] - trianglePrim[0];
-        Vector3f N2 = trianglePrim[2] - trianglePrim[0];
-        Vector3f N  = (N1.crossProduct(N2)).normalized();
-
-        viewDir =  mCamera->position -  trianglePrim[0];
+bool SoftwareRenderer::backFaceCulling(Vector3f &facetNormal, Vector3f &vert,  Matrix4 &worldToObject){
+        Vector3f viewDir =  worldToObject.matMultVec(mCamera->position) -  vert;
         viewDir.normalized();
         viewDir.normalized();
 
 
         //Returns false if the triangle cannot see the camera
         //Returns false if the triangle cannot see the camera
-        float intensity =  N.dotProduct(viewDir);
+        float intensity =  facetNormal.dotProduct(viewDir);
         return intensity <= 0.0;
         return intensity <= 0.0;
 }
 }
 
 

+ 3 - 5
src/texture.cpp

@@ -8,10 +8,8 @@ Texture::Texture(std::string path){
 }
 }
 
 
 Vector3f Texture::getPixelVal(float u, float v){
 Vector3f Texture::getPixelVal(float u, float v){
-    float intpart;
-    int uInt = std::modf(u, &intpart) * (width-1); 
-    int vInt = std::modf(v, &intpart) * (height-1);
+    int uInt = u * (width-1); 
+    int vInt = v * (height-1);
     int index = (vInt*width + uInt)*3;
     int index = (vInt*width + uInt)*3;
-    //printf("%d, %d, %d, %x, %x, %x\n",vInt, uInt, index ,pixelData[index],pixelData[index+1],pixelData[index+2]);
-    return Vector3f{pixelData[index], pixelData[index+1], pixelData[index+2]};
+    return Vector3f{(float)pixelData[index], (float)pixelData[index+1], (float)pixelData[index+2]};
 }
 }