Browse Source

Refactored rendering to occur in a more logical fashion.

angel 7 years ago
parent
commit
5d7ab200ae
8 changed files with 111 additions and 117 deletions
  1. 3 1
      include/engine.h
  2. 2 1
      include/matrix.h
  3. 6 1
      include/rasterizer.h
  4. 14 10
      include/renderManager.h
  5. 14 11
      src/engine.cpp
  6. 1 0
      src/matrix.cpp
  7. 39 90
      src/rasterizer.cpp
  8. 32 3
      src/renderManager.cpp

+ 3 - 1
include/engine.h

@@ -22,13 +22,15 @@ class Engine{
 
         void loadModels();
 
-        void moveModels(int dt);
+        //Will not be here forever
+        void updateCamera();
 
     private:
         WindowManager FEWindowManager;
         RenderManager FERenderManager;
         InputManager  FEInputManager;
         Model        *sceneModels;
+        Matrix4      viewMatrix;
 };
 
 #endif

+ 2 - 1
include/matrix.h

@@ -37,9 +37,10 @@ class Matrix4{
         //2D to 3D projection matrix
         Matrix4 static makeProjectionMatrix(float fov, float AR, float near, float far);
 
+        Matrix4(){};
 
     private:
-        Matrix4(){};
+        
         std::array<float, 16> mMatrix{};
 };
 

+ 6 - 1
include/rasterizer.h

@@ -10,7 +10,7 @@ class Rasterizer{
     public:
         Rasterizer(Canvas *canvas) :mCanvas(canvas){}
 
-        void drawModels(Model * models);
+        void drawModels(Vector3 &v1, Vector3 &v2, Vector3 &v3);
 
         void testPattern();
 
@@ -31,6 +31,11 @@ class Rasterizer{
 
         Canvas * mCanvas;
 
+        Uint32 white = SDL_MapRGBA(mappingFormat, 0xFF,0xFF,0xFF,0xFF);
+        Uint32 red = SDL_MapRGBA(mappingFormat, 0xFF,0x00,0x00,0xFF);
+        Uint32 green = SDL_MapRGBA(mappingFormat, 0x00,0xFF,0x00,0xFF);
+        Uint32 blue = SDL_MapRGBA(mappingFormat, 0x00,0x00,0xFF,0xFF);
+
 };
 
 #endif

+ 14 - 10
include/renderManager.h

@@ -15,28 +15,32 @@ class RenderManager {
 
         ~RenderManager();
 
-        bool startUp(WindowManager windowManager);
+        bool startUp(WindowManager windowManager);        
 
-        bool createRenderer(SDL_Window * mainWindow);
+        void render(Model *models, Matrix4 &mat);
+
+        void shutDown();
 
+    private:
+        //Init methods
+        bool createRenderer(SDL_Window * mainWindow);
+        bool createCanvas();
         bool createScreenTexture();
+        void createProjectionMatrix();
 
+        //Rendering pipeline stuff
         void clearScreen();
-
         void updateScreen();
 
-        bool createCanvas();
-
-        void render(Model *models);
-
-        void shutDown();
+        //Per vertex stuff
+        
 
-    private:
         SDL_Renderer *mainRenderer;
         Texture screenTexture;
         Canvas *mainCanvas;
         Rasterizer *raster;
-    
+        Matrix4 projectionMatrix;
+
 };
 
 #endif

+ 14 - 11
src/engine.cpp

@@ -58,11 +58,10 @@ void Engine::mainLoop(){
         //Update entities here in the future
         //Right now only does simple demo stuff
         //Maybe physics based in the future??
-        int dt = start - end;
-        moveModels(dt);
+        updateCamera();
 
         //Perform all render calculations and update screen
-        FERenderManager.render(sceneModels);
+        FERenderManager.render(sceneModels, viewMatrix);
         end = SDL_GetTicks();
         //SDL_Delay(100);
         printf("%2.1d: Loop elapsed time (ms):%d\n",count,end - start);
@@ -87,12 +86,16 @@ void Engine::loadModels(){
     //sceneModels->describeMesh();
 }
 
-//Engine class moves stuff, for now
-//Some kind of physics module should be responsible of this in the future
-//Actually it should probably be moved by user input
-void Engine::moveModels(int dt){
 
-    //I freed the engine from moving stuff!
-    //Now it's technically the camera that moves and everything else follows
-
-}
+//This should be its own class in the future
+void Engine::updateCamera(){
+    float t = static_cast<float>(SDL_GetTicks());
+    float radius = 7;
+    float camX   = std::sin(t/4000) * radius;
+    float camZ   = std::cos(t/4000) * radius;
+    Vector3 pos(camX, 0, camZ);
+    Vector3 tar;
+    Vector3 v(0,1,0);
+    viewMatrix = Matrix4::lookAt(pos,tar,v);
+    viewMatrix = (Matrix4::makeTranslateMat(0,camX*0.25,0)*viewMatrix);
+}

+ 1 - 0
src/matrix.cpp

@@ -197,6 +197,7 @@ Matrix4 Matrix4::lookAt(Vector3& position, Vector3& target, Vector3& temp){
     Vector3 forward = (position - target).normalized();
     Vector3 side    = forward.crossProduct(temp.normalized());
     Vector3 up      = forward.crossProduct(side);
+    //Vector3 up      = side.crossProduct(forward);
 
     //We will now build the inverse transform from the world position to the camera
     //The idea is that we don't care where the camera is, we only care about what

+ 39 - 90
src/rasterizer.cpp

@@ -29,104 +29,53 @@ void Rasterizer::testPattern(){
 
 }
 
-void Rasterizer::drawModels(Model * models){
-    Uint32 white = SDL_MapRGBA(mappingFormat, 0xFF,0xFF,0xFF,0xFF);
-    Uint32 red = SDL_MapRGBA(mappingFormat, 0xFF,0x00,0x00,0xFF);
-    Uint32 green = SDL_MapRGBA(mappingFormat, 0x00,0xFF,0x00,0xFF);
-    Uint32 blue = SDL_MapRGBA(mappingFormat, 0x00,0x00,0xFF,0xFF);
-    Mesh * modelMesh = models->getMesh();
-    std::vector<Vector3> * faces = &modelMesh->faces;
-    std::vector<Vector3> * vertices = &modelMesh->vertices;
-
-    //View Matrix stuff, to be moved elsewhere
-    //Represents a camera rotating around the origin
-    float t = static_cast<float>(SDL_GetTicks());
-    float radius = 8;
-    float camX   = std::sin(t/5000) * radius;
-    float camZ   = std::cos(t/5000) * radius;
-    Vector3 pos(camX, 0, camZ);
-    Vector3 tar;
-    Vector3 v(0,1,0);
-    Matrix4 viewMatrix = Matrix4::lookAt(pos,tar,v);
-    viewMatrix = Matrix4::makeTranslateMat(0,camX,0)*viewMatrix;
-
-    //Creating perspective matrix
-    //No need to build it each frame since fov and near far clipping is normally
-    //Not something that changes every frame
-    float fov = 90;
-    float aspectRatio = mCanvas->mWidth / (float)mCanvas->mHeight;
-    float near = 0.1;
-    float far  = 100;
-    Matrix4 perspectiveMatrix = Matrix4::makeProjectionMatrix(fov, aspectRatio, near,far);
-
-    //perspectiveMatrix.printMat();
-    //SDL_Delay(1000);
-
-    Matrix4 viewProjectionMatrix = perspectiveMatrix*viewMatrix;
-
-    //viewProjectionMatrix.printMat();
-
-    //SDL_Delay(1000);
-
-    for (Vector3 f : *faces ){
-        //(*vertices)[f.x-1].print();
-        Vector3 v1 = viewProjectionMatrix.matMultVec((*vertices)[f.x-1]); //-1 because .obj file starts face count
-        //Vector3 v2 = viewProjectionMatrix.matMultVec((*vertices)[f.y-1]); // from 1. Should probably fix this 
-        //Vector3 v3 = viewProjectionMatrix.matMultVec((*vertices)[f.z-1]); // At some point
-       // v1.print();
-        if(v1.x < -1 || v1.x > 1 || v1.y < -1 || v1.y > 1 || v1.z > 1 || v1.z < -1) continue;
-        //if(v2.x < -1 || v2.x > 1 || v2.y < -1 || v2.y > 1) continue;
-        //v1.print();
-        //SDL_Delay(1000);
-        drawLine(v1, v1, red);
-        //drawLine(v2, v3, green);
-        //drawLine(v1, v3, blue);
-    }
-
+//Should probably do something fancier in the future
+void Rasterizer::drawModels(Vector3 &v1, Vector3 &v2, Vector3 &v3 ){
+    drawLine(v1, v2, red);
+    drawLine(v2, v3, green);
+    drawLine(v1, v3, blue);
 }   
 
 void Rasterizer::drawLine(Vector3 vertex1, Vector3 vertex2, Uint32 color){
 
         int x1 = (vertex1.x + 1 ) * mCanvas->mWidth * 0.5;
         int y1 = (-vertex1.y + 1 ) * mCanvas->mHeight * 0.5;
-        //int x2 = (vertex2.x +1 ) * mCanvas->mWidth  * 0.5;
-        //int y2 = (-vertex2.y +1 ) * mCanvas->mHeight * 0.5;
-
-        setPixelColor(color, x1, y1);
-
-        // //transpose line if it is too steep
-        // bool steep = false;
-        // if (std::abs(x1-x2) < std::abs(y1-y2) ){
-        //     std::swap(x1,y1);
-        //     std::swap(x2,y2);
-        //     steep = true;
-        // }
-
-        // //Redefine line so that it is left to right
-        // if ( x1  > x2 ){
-        //     std::swap(x1,x2);
-        //     std::swap(y1,y2);
-        // }
-        // int dx = x2 - x1;
-        // int dy = y2 - y1;
-        // int derror2 = std::abs(dy)*2;
-        // int error2 = 0;
-        // int y = y1;
+        int x2 = (vertex2.x +1 ) * mCanvas->mWidth  * 0.5;
+        int y2 = (-vertex2.y +1 ) * mCanvas->mHeight * 0.5;
+
+        //transpose line if it is too steep
+        bool steep = false;
+        if (std::abs(x1-x2) < std::abs(y1-y2) ){
+            std::swap(x1,y1);
+            std::swap(x2,y2);
+            steep = true;
+        }
 
-        // for(int x=x1; x <= x2 ; x++){
-        //     if(steep){
-        //             setPixelColor(color, y, x);
-        //         }
-        //         else{
-        //             setPixelColor(color, x, y);
-        //         }
-        //     error2 += derror2;
-        //     if (error2 > dx){
-        //         y += (y2 > y1  ? 1 : -1);
-        //         error2 -= dx*2;
-        //     }
+        //Redefine line so that it is left to right
+        if ( x1  > x2 ){
+            std::swap(x1,x2);
+            std::swap(y1,y2);
+        }
+        int dx = x2 - x1;
+        int dy = y2 - y1;
+        int derror2 = std::abs(dy)*2;
+        int error2 = 0;
+        int y = y1;
+
+        for(int x=x1; x <= x2 ; x++){
+            if(steep){
+                    setPixelColor(color, y, x);
+                }
+                else{
+                    setPixelColor(color, x, y);
+                }
+            error2 += derror2;
+            if (error2 > dx){
+                y += (y2 > y1  ? 1 : -1);
+                error2 -= dx*2;
+            }
 
-        // }
+        }
         
 }
 

+ 32 - 3
src/renderManager.cpp

@@ -25,11 +25,20 @@ bool RenderManager::startUp(WindowManager WindowManager){
             }
             //Create rasterizer to begin drawing
             raster = new Rasterizer(mainCanvas);
+            createProjectionMatrix();
             return true;
         }
     }
 }
 
+void RenderManager::createProjectionMatrix(){
+    float fov = 75;
+    float aspectRatio = mainCanvas->mWidth / (float)mainCanvas->mHeight;
+    float near = 0.1;
+    float far  = 100;
+    projectionMatrix = Matrix4::makeProjectionMatrix(fov, aspectRatio, near,far);
+}
+
 bool RenderManager::createScreenTexture(){
     if(! screenTexture.createBlank(mainRenderer, WindowManager::SCREEN_WIDTH, WindowManager::SCREEN_HEIGHT)){
         printf("Could not create texture. Error: %s\n", SDL_GetError());
@@ -67,13 +76,33 @@ void RenderManager::shutDown(){
     mainRenderer = nullptr;
 }
 
-void RenderManager::render(Model *models){
+void RenderManager::render(Model *models, Matrix4 &viewMatrix){
 
     //Clear Screen back to black
     clearScreen();
+
+    //Combination of both matrices
+    Matrix4 viewProjectionMatrix = projectionMatrix*viewMatrix;
+
+    //Getting the meshes and faces 
+    Mesh * modelMesh = models->getMesh();
+    std::vector<Vector3> * faces = &modelMesh->faces;
+    std::vector<Vector3> * vertices = &modelMesh->vertices;
+
+    for (Vector3 f : *faces ){
+        Vector3 v1 = viewProjectionMatrix.matMultVec((*vertices)[f.x-1]); //-1 because .obj file starts face count
+        Vector3 v2 = viewProjectionMatrix.matMultVec((*vertices)[f.y-1]); // from 1. Should probably fix this 
+        Vector3 v3 = viewProjectionMatrix.matMultVec((*vertices)[f.z-1]); // At some point
+        if(v1.x < -1 || v1.x > 1 || v1.y < -1 || v1.y > 1 || v1.z > 1 || v1.z < -1) continue;
+        if(v2.x < -1 || v2.x > 1 || v2.y < -1 || v2.y > 1 || v2.z > 1 || v2.z < -1) continue;
+        if(v3.x < -1 || v3.x > 1 || v3.y < -1 || v3.y > 1 || v3.z > 1 || v3.z < -1) continue;
+
+        raster->drawModels(v1,v2,v3);
+    }
+
+
+    //Rasterizing
     
-    //Perform any modifications we want on the pixels
-    raster->drawModels(models);
 
     //Apply the pixel changes and redraw
     updateScreen();