Browse Source

Implemented Bump Mapping shader.

angel 7 years ago
parent
commit
4264c4fca7
11 changed files with 165 additions and 92 deletions
  1. 1 1
      include/geometry.h
  2. 2 2
      include/model.h
  3. 36 52
      include/shader.h
  4. 7 3
      include/texture.h
  5. 1 1
      src/engine.cpp
  6. 1 0
      src/matrix.cpp
  7. 60 6
      src/mesh.cpp
  8. 1 0
      src/objParser.cpp
  9. 21 17
      src/rasterizer.cpp
  10. 6 7
      src/softwareRenderer.cpp
  11. 29 3
      src/texture.cpp

+ 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.01), far(1000), AR(ratio){};
+        Frustrum(float ratio): fov(35), near(0.01), far(1000), AR(ratio){};
         Plane pl[6];
         Plane pl[6];
 
 
         void setCamInternals();
         void setCamInternals();

+ 2 - 2
include/model.h

@@ -22,8 +22,8 @@ class Model{
         //Prints the mesh vertices for debugging
         //Prints the mesh vertices for debugging
         void describeMesh();
         void describeMesh();
     private:
     private:
-        Texture mAlbedo{"../models/fire_hydrant_Base_Color.png"};
-        Texture mNormal{"../models/fire_hydrant_Normal_OpenGL.png"};
+        Texture mAlbedo{"../models/fire_hydrant_Base_Color.png", "RGB"};
+        Texture mNormal{"../models/fire_hydrant_Normal_OpenGL.png", "XYZ"};
         Mesh mMesh;
         Mesh mMesh;
         AABox mBounds;
         AABox mBounds;
         Matrix4 mModelMatrix;
         Matrix4 mModelMatrix;

+ 36 - 52
include/shader.h

@@ -9,7 +9,7 @@
 //Shader Interface for a class that emulates modern GPU fragment and vertex shaders
 //Shader Interface for a class that emulates modern GPU fragment and vertex shaders
 struct IShader {
 struct IShader {
     virtual ~IShader() {};
     virtual ~IShader() {};
-    virtual Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals, const Vector3f &tangent, const Vector3f &biTangent, const Vector3f &light, int index) = 0;
+    virtual Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) = 0;
     virtual Vector3f fragment(float u, float v) = 0;
     virtual Vector3f fragment(float u, float v) = 0;
 };
 };
 
 
@@ -19,7 +19,7 @@ struct FlatShader : public IShader {
     float varIntensity;
     float varIntensity;
     Vector3f rgb{255,255,255};
     Vector3f rgb{255,255,255};
 
 
-    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
+    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) override{
         varIntensity = std::max(0.0f,normal.dotProduct(light));
         varIntensity = std::max(0.0f,normal.dotProduct(light));
         return MVP.matMultVec(vertex); //Transforms verts into projected space
         return MVP.matMultVec(vertex); //Transforms verts into projected space
     }
     }
@@ -40,7 +40,7 @@ struct GouraudShader : public IShader {
     Vector3f varying_diffuse, varying_specular, reflectDir, viewDir, light2, normal2;
     Vector3f varying_diffuse, varying_specular, reflectDir, viewDir, light2, normal2;
     Vector3f rgb{255,255,255};
     Vector3f rgb{255,255,255};
 
 
-    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
+    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) override{
         normal2 = N.matMultDir(normal).normalized();
         normal2 = N.matMultDir(normal).normalized();
         light2 = V.matMultDir(light).normalized();
         light2 = V.matMultDir(light).normalized();
         reflectDir = Vector3f::reflect(-light2, normal);
         reflectDir = Vector3f::reflect(-light2, normal);
@@ -75,7 +75,7 @@ struct PhongShader : public IShader {
     Vector3f varying_diffuse, varying_specular, reflectDir, light2;
     Vector3f varying_diffuse, varying_specular, reflectDir, light2;
     Vector3f rgb{255,255,255};
     Vector3f rgb{255,255,255};
 
 
-    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
+    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) override{
         normals[index] = N.matMultDir(normal).normalized();
         normals[index] = N.matMultDir(normal).normalized();
         viewDir[index] = MV.matMultVec(vertex).normalized();
         viewDir[index] = MV.matMultVec(vertex).normalized();
         light2 = V.matMultDir(light).normalized();
         light2 = V.matMultDir(light).normalized();
@@ -116,7 +116,7 @@ struct BlinnPhongShader : public IShader {
     Vector3f halfwayDir, lightDir;
     Vector3f halfwayDir, lightDir;
     Vector3f interpCol, white{255,255,255};
     Vector3f interpCol, white{255,255,255};
 
 
-    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal, const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
+    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) override{
         normals[index] = N.matMultDir(normal).normalized();
         normals[index] = N.matMultDir(normal).normalized();
         UV[index] = textureVals;
         UV[index] = textureVals;
         viewDir[index] = MV.matMultVec(vertex).normalized();
         viewDir[index] = MV.matMultVec(vertex).normalized();
@@ -131,13 +131,6 @@ struct BlinnPhongShader : public IShader {
         interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
         interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
         //Albedo
         //Albedo
         interpCol = albedoT->getPixelVal(interpUV.x, interpUV.y);
         interpCol = albedoT->getPixelVal(interpUV.x, interpUV.y);
-        //interpNormal = normalT->getPixelVal(interpUV.x, interpUV.y);
-        // interpNormal.x = (interpNormal.x*2/256.0f) -1;
-        // interpNormal.y = (interpNormal.y*2/256.0f) -1;
-        // interpNormal.z = 1 - interpNormal.z*1/256.0f;
-        // interpNormal = interpNormal.normalized();
-
-        //rgb.print();
 
 
         //Ambient 
         //Ambient 
         ambient = lightColor * ambientStrength;
         ambient = lightColor * ambientStrength;
@@ -165,73 +158,64 @@ struct NormalMapShader : public IShader {
 
 
     //Light Variables
     //Light Variables
     Vector3f lightColor{1,1,1}, white{1,1,1};
     Vector3f lightColor{1,1,1}, white{1,1,1};
-    float ambientStrength = 0.05, diffStrength = 1, specularStrength = 0.5;
+    float ambientStrength = 0.05, diffStrength = 0.9, specularStrength = 0.8;
     float diff, spec, shininess = 128;
     float diff, spec, shininess = 128;
+    Vector3f lightDir[3];
 
 
     //Variables set per vertex
     //Variables set per vertex
-    Vector3f normals[3], viewDir[3], UV[3], tangentFragPos[3], viewPos[3];
-    Vector3f lightDir, vertexPos[3],vertTangent[3], vertBiTangent[3] ;
+    Vector3f viewDir[3], texCoords[3], tangentFragPos[3];
+    Vector3f normal_WS, tangent_WS, biTangent_WS;
+    Matrix4 TBN;
     
     
     //Interpolated variables
     //Interpolated variables
-    Vector3f interpUV, interpNormal, interpViewPos, interpCol, interpTangentFragPos;
+    Vector3f interpCoords, interpLightDir, interpNormal,
+             interpViewDir, interpCol;
 
 
     //Per fragment
     //Per fragment
     Vector3f ambient, diffuse, specular ;
     Vector3f ambient, diffuse, specular ;
     Vector3f halfwayDir;
     Vector3f halfwayDir;
 
 
-    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent,const Vector3f &biTangent,const Vector3f &light, int index) override{
+    Vector3f vertex(const Vector3f &vertex, const Vector3f &normal,const Vector3f &textureVals,const Vector3f &tangent, const Vector3f &light, int index) override{
         //Creating TBN matrix
         //Creating TBN matrix
-        normals[index]           = N.matMultDir(normal).normalized();
-        vertTangent[index]       = N.matMultDir(tangent).normalized();
-        vertBiTangent[index]     = N.matMultDir(biTangent).normalized();
-        vertexPos[index]         = M.matMultVec(vertex);
-        // Matrix4 TBN = Matrix4::TBNMatrix(vertTangent[index], vertBiTangent[index], normals[index]);
-
+        normal_WS     = N.matMultDir(normal).normalized();
+        tangent_WS    = N.matMultDir(tangent).normalized();
+        biTangent_WS  = normal_WS.crossProduct(tangent_WS);
+        TBN = Matrix4::TBNMatrix(tangent_WS, biTangent_WS, normal_WS);
+        
         //Getting UV coordinates for use in both albedo and normal textures
         //Getting UV coordinates for use in both albedo and normal textures
-        UV[index] = textureVals;
+        texCoords[index] = textureVals;
 
 
         //Passing all lighting related data to tangent space
         //Passing all lighting related data to tangent space
-        // tangentFragPos[index] = TBN.matMultVec(N.matMultVec(vertex));
-        // viewPos[index]        = TBN.matMultVec(cameraPos); 
-        // lightDir              = TBN.matMultVec(light);
-
+        lightDir[index]       = TBN.matMultVec(light);
+        viewDir[index]        = TBN.matMultVec(cameraPos - M.matMultVec(vertex));
+        
         return MVP.matMultVec(vertex);
         return MVP.matMultVec(vertex);
     }
     }
 
 
     Vector3f fragment(float u, float v) override{
     Vector3f fragment(float u, float v) override{
         //Interpolated stuff
         //Interpolated stuff
-        // interpTangentFragPos = tangentFragPos[0] + (tangentFragPos[1] - tangentFragPos[0])* u + (tangentFragPos[2] - tangentFragPos[0]) * v;
-        // interpViewPos = viewPos[0] + (viewPos[1] - viewPos[0])* u + (viewPos[2] - viewPos[0]) * v;
-        //interpUV = UV[0] + (UV[1] - UV[0])* u + (UV[2] - UV[0]) * v;
-        Vector3f interpPos =  vertexPos[0] + (vertexPos[1] - vertexPos[0])* u + (vertexPos[2] - vertexPos[0]) * v;
-        Vector3f interpTan =  vertTangent[0] + (vertTangent[1] - vertTangent[0])* u + (vertTangent[2] - vertTangent[0]) * v;
-        Vector3f interpBiTan =  vertBiTangent[0] + (vertBiTangent[1] - vertBiTangent[0])* u + (vertBiTangent[2] - vertBiTangent[0]) * v;
-        Vector3f interpNorm =  normals[0] + (normals[1] - normals[0])* u + (normals[2] - normals[0]) * v;
-
-        //Albedo
-        // interpCol    = albedoT->getPixelVal(interpUV.x, interpUV.y);
-        // interpNormal = normalT->getPixelVal(interpUV.x, interpUV.y);
-        // interpNormal.x = (interpNormal.x * 2/256.0f) - 1;
-        // interpNormal.y = (interpNormal.y * 2/256.0f) - 1;
-        // interpNormal.z = (interpNormal.z * 2/256.0f) - 1;
-        // interpNormal = interpNormal.normalized();
+        interpCoords   = texCoords[0] + (texCoords[1] - texCoords[0])* u + (texCoords[2] - texCoords[0]) * v;
+        interpLightDir = lightDir[0] + (lightDir[1] - lightDir[0])* u + (lightDir[2] - lightDir[0]) * v;
+        interpViewDir  = viewDir[0] + (viewDir[1] - viewDir[0])* u + (viewDir[2] - viewDir[0]) * v;
 
 
+        //Reading albedo and normal data from textures
+        interpCol    = albedoT->getPixelVal(interpCoords.x, interpCoords.y);
+        interpNormal = normalT->getPixelVal(interpCoords.x, interpCoords.y);
+        interpNormal = interpNormal.normalized();
 
 
         //Ambient 
         //Ambient 
-        // ambient = lightColor * ambientStrength;
+        ambient = lightColor * ambientStrength;
 
 
         //Diffuse
         //Diffuse
-        //lightDir = (interpTangentFragPos - lightDir).normalized();
-        // diff = std::max(0.0f, interpNormal.dotProduct(lightDir));
-        // diffuse = lightColor * diff * diffStrength;
+        diff = std::max(0.0f, interpNormal.dotProduct(interpLightDir));
+        diffuse = lightColor * diff * diffStrength;
         
         
         //Specular
         //Specular
-        // halfwayDir = (lightDir - interpViewDir).normalized();
-        // spec = std::pow(std::max(0.0f, interpNormal.dotProduct(halfwayDir)), shininess);
-        // specular = lightColor * spec * specularStrength;
+        halfwayDir = (interpLightDir + interpViewDir).normalized();
+        spec = std::pow(std::max(0.0f, interpNormal.dotProduct(halfwayDir)), shininess);
+        specular = lightColor * spec * specularStrength;
 
 
-        //return (ambient + diffuse) * interpCol + specular * white;
-        return  interpPos;
+        return (ambient + diffuse) * interpCol + specular * white;
     }
     }
 
 
 };
 };

+ 7 - 3
include/texture.h

@@ -4,15 +4,19 @@
 #include <string>
 #include <string>
 #include "vector3D.h"
 #include "vector3D.h"
 
 
+
+
 class Texture{
 class Texture{
     public:
     public:
-        Texture(std::string path); 
+        Texture(std::string path, std::string type); 
+
+        ~Texture();
 
 
         Vector3f getPixelVal(float u, float v);
         Vector3f getPixelVal(float u, float v);
 
 
     private:
     private:
-        unsigned char *pixelData;
-        int width, height, channels, origin;
+        float *pixelData;
+        int width, height, channels;
 };
 };
 
 
 #endif
 #endif

+ 1 - 1
src/engine.cpp

@@ -98,7 +98,7 @@ void Engine::run(){
         //if (count == 500) break;
         //if (count == 500) break;
     }
     }
 
 
-    printf("Closing down engine:\n");
+    printf("Closing down engine.\n");
     printf("Average frame time over %2.1d frames: %f\n", count,total/(float)count);
     printf("Average frame time over %2.1d frames: %f\n", count,total/(float)count);
     
     
 }
 }

+ 1 - 0
src/matrix.cpp

@@ -402,6 +402,7 @@ Matrix4 Matrix4::TBNMatrix(const Vector3f &tangent, const Vector3f &biTangent, c
     tangentMat(2,2) = normal.z;
     tangentMat(2,2) = normal.z;
 
 
     return tangentMat.transpose();
     return tangentMat.transpose();
+
 }
 }
 
 
 void Matrix4::print(){
 void Matrix4::print(){

+ 60 - 6
src/mesh.cpp

@@ -27,13 +27,17 @@ void Mesh::buildTangentSpace(){
         Vector3i vIndices = vertexIndices[i];
         Vector3i vIndices = vertexIndices[i];
         Vector3i tIndices = textureIndices[i];
         Vector3i tIndices = textureIndices[i];
 
 
-        Vector3f edge1 = vertices[vIndices.data[1]] - vertices[vIndices.data[0]];
-        Vector3f edge2 = vertices[vIndices.data[2]] - vertices[vIndices.data[0]];
+        Vector3f v0 = vertices[vIndices.data[0]];
+        Vector3f v1 = vertices[vIndices.data[1]];
+        Vector3f v2 = vertices[vIndices.data[2]];
+
+        Vector3f edge1 = v1 - v0;
+        Vector3f edge2 = v2 - v0;
 
 
         Vector3f deltaUV1 = texels[tIndices.data[1]] - texels[tIndices.data[0]];
         Vector3f deltaUV1 = texels[tIndices.data[1]] - texels[tIndices.data[0]];
         Vector3f deltaUV2 = texels[tIndices.data[2]] - texels[tIndices.data[0]];
         Vector3f deltaUV2 = texels[tIndices.data[2]] - texels[tIndices.data[0]];
 
 
-        float f = 1 / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
+        float f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);
 
 
         tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
         tangent.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
         tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
         tangent.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
@@ -52,20 +56,24 @@ void Mesh::buildTangentSpace(){
         tempBiTangents[vIndices.data[0]].push_back(biTangent);
         tempBiTangents[vIndices.data[0]].push_back(biTangent);
         tempBiTangents[vIndices.data[1]].push_back(biTangent);
         tempBiTangents[vIndices.data[1]].push_back(biTangent);
         tempBiTangents[vIndices.data[2]].push_back(biTangent);
         tempBiTangents[vIndices.data[2]].push_back(biTangent);
+
     }
     }
 
 
-    //Take average of tangents and bitangents at that vertex
+    //Take average of tangents and bitangents at that vertex and populate the array in the 
+    //correct order
     for(int j = 0; j < numVertices; ++j){
     for(int j = 0; j < numVertices; ++j){
         int count1 = 0, count2 = 0;
         int count1 = 0, count2 = 0;
+
         Vector3f temp1{0};
         Vector3f temp1{0};
         while(!tempTangents[j].empty()){
         while(!tempTangents[j].empty()){
             ++count1;
             ++count1;
             temp1 += tempTangents[j].back();
             temp1 += tempTangents[j].back();
             if (temp1.x == 0 && temp1.y == 0 && temp1.z == 0){
             if (temp1.x == 0 && temp1.y == 0 && temp1.z == 0){
-                temp1 += tempTangents[j].back();
+                temp1 = tempTangents[j].back();
             }
             }
             tempTangents[j].pop_back();
             tempTangents[j].pop_back();
         }
         }
+
         temp1 = temp1 * (1.0f/count1);
         temp1 = temp1 * (1.0f/count1);
         tangents.push_back(temp1);
         tangents.push_back(temp1);
 
 
@@ -74,11 +82,57 @@ void Mesh::buildTangentSpace(){
             ++count2;
             ++count2;
             temp2 += tempBiTangents[j].back();
             temp2 += tempBiTangents[j].back();
              if (temp2.x == 0 && temp2.y == 0 && temp2.z == 0){
              if (temp2.x == 0 && temp2.y == 0 && temp2.z == 0){
-                temp2 += tempBiTangents[j].back();
+                temp2 = tempBiTangents[j].back();
             }
             }
             tempBiTangents[j].pop_back();
             tempBiTangents[j].pop_back();
         }
         }
         temp2 = temp2 * (1.0f/count2);
         temp2 = temp2 * (1.0f/count2);
         biTangents.push_back(temp2);
         biTangents.push_back(temp2);
     }
     }
+
+    //Renormalize and correct handedness of tangent/bitangent vectors
+    for(int k = 0; k < numFaces; ++k){
+        Vector3i vIndices = vertexIndices[k];
+        Vector3i nIndices = normalsIndices[k];
+
+        //Per vertex
+        Vector3f tangentV0 = tangents[vIndices.data[0]]; 
+        Vector3f tangentV1 = tangents[vIndices.data[1]];
+        Vector3f tangentV2 = tangents[vIndices.data[2]];
+
+        Vector3f normalV0 = normals[nIndices.data[0]]; 
+        Vector3f normalV1 = normals[nIndices.data[1]];
+        Vector3f normalV2 = normals[nIndices.data[2]];
+
+        Vector3f biTangentV0 = biTangents[vIndices.data[0]]; 
+        Vector3f biTangentV1 = biTangents[vIndices.data[1]];
+        Vector3f biTangentV2 = biTangents[vIndices.data[2]];
+
+        tangentV0  = (tangentV0 - (normalV0*tangentV0.dotProduct(normalV0))).normalized();
+        tangentV1  = (tangentV1 - (normalV1*tangentV1.dotProduct(normalV1))).normalized();
+        tangentV2  = (tangentV2 - (normalV2*tangentV2.dotProduct(normalV2))).normalized();
+
+
+        if (biTangentV0.dotProduct(normalV0.crossProduct(tangentV0)) < 0.0f){
+            //printf("here0!\n");
+            tangentV0 = tangentV0  * -1.0f;
+        }
+
+        if (biTangentV1.dotProduct(normalV1.crossProduct(tangentV1)) < 0.0f){
+            //printf("here1!\n");
+            tangentV1 = tangentV1  * -1.0f;
+        }
+
+        if (biTangentV2.dotProduct(normalV2.crossProduct(tangentV2)) < 0.0f){
+            //printf("here2!\n");
+            tangentV2 = tangentV2  * -1.0f;
+        }
+
+        tangents[vIndices.data[0]]  = tangentV0;
+        tangents[vIndices.data[1]]  = tangentV1; 
+        tangents[vIndices.data[2]]  = tangentV2; 
+
+    }
+
+
 }
 }

+ 1 - 0
src/objParser.cpp

@@ -43,6 +43,7 @@ void OBJ::loadFileData(Mesh &mesh, std::ifstream &file){
             tempU = std::modf(std::stof(x), &intpart);
             tempU = std::modf(std::stof(x), &intpart);
             tempV = std::modf(std::stof(y), &intpart);
             tempV = std::modf(std::stof(y), &intpart);
             Vector3f tex(tempU, tempV, 0);
             Vector3f tex(tempU, tempV, 0);
+            //Vector3f tex(std::stof(x), std::stof(y), 0);
             mesh.texels.push_back(tex);
             mesh.texels.push_back(tex);
         }
         }
         else if(key == "f"){ //index data
         else if(key == "f"){ //index data

+ 21 - 17
src/rasterizer.cpp

@@ -86,7 +86,7 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
     Vector3f hW{1/vertices[0].w, 1/vertices[1].w, 1/vertices[2].w};
     Vector3f hW{1/vertices[0].w, 1/vertices[1].w, 1/vertices[2].w};
 
 
     //Per fragment variables
     //Per fragment variables
-    float depth, uPers, vPers, areaPers; //u, v, are perspective corrected
+    float depth, uPers, vPers, areaPers, count = 0; //u, v, are perspective corrected
     Vector3f e, e_row, e_init, f;
     Vector3f e, e_row, e_init, f;
     Vector3f rgbVals{255,255,255};
     Vector3f rgbVals{255,255,255};
     
     
@@ -122,7 +122,11 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
         e.z = e_row.z;
         e.z = e_row.z;
 
 
         for(int x = xMin; x <= xMax; ++x){
         for(int x = xMin; x <= xMax; ++x){
-
+            // if(x == 640){
+            //     (*pixelBuffer)(x,y) = SDL_MapRGB(mappingFormat, 0xFF, 0xFF, 0xFF);
+            //     printf("here! %d, %d\n", x,y);
+            //     continue;
+            // }
             //Only draw if inside pixel and following top left rule
             //Only draw if inside pixel and following top left rule
             if(inside(e.x, A01, B01) && inside(e.y, A12, B12) && inside(e.z, A20, B20) ){
             if(inside(e.x, A01, B01) && inside(e.y, A12, B12) && inside(e.z, A20, B20) ){
 
 
@@ -139,12 +143,12 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
 
 
                     //Run fragment shader
                     //Run fragment shader
                     rgbVals = shader.fragment(uPers , vPers);
                     rgbVals = shader.fragment(uPers , vPers);
-
                     //Update pixel buffer with clamped values 
                     //Update pixel buffer with clamped values 
                     (*pixelBuffer)(x,y) = SDL_MapRGB(mappingFormat,
                     (*pixelBuffer)(x,y) = SDL_MapRGB(mappingFormat,
-                    clamp(gammaAdjust(rgbVals.data[0], 2.2), 0, 255.0f),
-                    clamp(gammaAdjust(rgbVals.data[1], 2.2), 0, 255.0f),
-                    clamp(gammaAdjust(rgbVals.data[2], 2.2), 0, 255.0f));
+                    clamp(gammaAdjust(rgbVals.data[0], 1), 0, 255.0f), //
+                    clamp(gammaAdjust(rgbVals.data[1], 1), 0, 255.0f),//
+                    clamp(gammaAdjust(rgbVals.data[2], 1), 0, 255.0f));//
+                    //(*pixelBuffer)(x,y) = SDL_MapRGB(mappingFormat,0xFF, 0xFF, 0xFF);
                 }   
                 }   
             }
             }
 
 
@@ -163,22 +167,22 @@ void Rasterizer::drawTriangles(Vector3f *vertices, IShader &shader, Buffer<Uint3
 
 
 void Rasterizer::viewportTransform(Buffer<Uint32> *pixelBuffer, Vector3f *vertices){
 void Rasterizer::viewportTransform(Buffer<Uint32> *pixelBuffer, Vector3f *vertices){
     for(int i = 0; i < 3; ++i){
     for(int i = 0; i < 3; ++i){
-        vertices[i].x = ((vertices[i].x + 1 ) * pixelBuffer->mWidth * 0.5);
-        vertices[i].y = ((vertices[i].y + 1 ) * pixelBuffer->mHeight * 0.5);
+        vertices[i].x = ((vertices[i].x + 1 ) * pixelBuffer->mWidth * 0.5)  + 0.5;
+        vertices[i].y = ((vertices[i].y + 1 ) * pixelBuffer->mHeight * 0.5) + 0.5;
     }
     }
 }
 }
 
 
 
 
 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::max({vertices[0].x, vertices[1].x, vertices[2].x});
-    //xMin = 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});
+    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::max({vertices[0].y, vertices[1].y, vertices[2].y});
-    //yMin = 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});
+    yMin = std::min({vertices[0].y, vertices[1].y, vertices[2].y});
 
 
     //Clip against screen
     //Clip against screen
     xMax = std::min(xMax, pixelBuffer->mWidth -1);
     xMax = std::min(xMax, pixelBuffer->mWidth -1);
@@ -209,5 +213,5 @@ float Rasterizer::clamp(float n, float lower, float upper) {
 
 
 
 
 float Rasterizer::gammaAdjust(float n, float gamma) {
 float Rasterizer::gammaAdjust(float n, float gamma) {
-  return std::pow(n, 1.0/(float)gamma)*255.0f;
+  return std::pow(n, 1.0/gamma)*256.0f;
 }
 }

+ 6 - 7
src/softwareRenderer.cpp

@@ -35,12 +35,11 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
     std::vector<Vector3f> * texels     = &triMesh->texels;
     std::vector<Vector3f> * texels     = &triMesh->texels;
     std::vector<Vector3f> * normals    = &triMesh->normals;
     std::vector<Vector3f> * normals    = &triMesh->normals;
     std::vector<Vector3f> * tangents   = &triMesh->tangents;
     std::vector<Vector3f> * tangents   = &triMesh->tangents;
-    std::vector<Vector3f> * biTangents = &triMesh->biTangents;
     int numFaces = triMesh->numFaces;
     int numFaces = triMesh->numFaces;
 
 
     //Array grouping vertices together into triangle
     //Array grouping vertices together into triangle
     Vector3f trianglePrimitive[3], normalPrim[3], uvPrim[3],
     Vector3f trianglePrimitive[3], normalPrim[3], uvPrim[3],
-             tangentPrim[3], biTangentPrim[3];
+             tangentPrim[3];
 
 
     //Initializing shader 
     //Initializing shader 
     NormalMapShader shader;
     NormalMapShader shader;
@@ -67,7 +66,7 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
     // Iterate through every triangle
     // Iterate through every triangle
     int count = 0;
     int count = 0;
 
 
-    #pragma omp parallel for private(trianglePrimitive, normalPrim, uvPrim, tangentPrim, biTangentPrim) firstprivate(shader)
+   #pragma omp parallel for private(trianglePrimitive, normalPrim, uvPrim, tangentPrim) firstprivate(shader)
     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];
@@ -79,16 +78,16 @@ void SoftwareRenderer::drawTriangularMesh(Model * currentModel){
         buildTri(n, normalPrim, *normals);
         buildTri(n, normalPrim, *normals);
         buildTri(u, uvPrim, *texels);
         buildTri(u, uvPrim, *texels);
         buildTri(f, tangentPrim, *tangents);
         buildTri(f, tangentPrim, *tangents);
-        buildTri(f, biTangentPrim, *biTangents);
 
 
         //Early quit if 
         //Early quit if 
         if (backFaceCulling((*fNormals)[j], trianglePrimitive[0], worldToObject)) continue;
         if (backFaceCulling((*fNormals)[j], trianglePrimitive[0], worldToObject)) continue;
         ++count;
         ++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], normalPrim[i],
-                                                uvPrim[i], tangentPrim[i], 
-                                                biTangentPrim[i], lightDir, i);
+            trianglePrimitive[i] = shader.vertex(
+                trianglePrimitive[i], normalPrim[i],
+                uvPrim[i], tangentPrim[i], 
+                lightDir, i);
         }
         }
 
 
         //Skip triangles that are outside viewing frustrum
         //Skip triangles that are outside viewing frustrum

+ 29 - 3
src/texture.cpp

@@ -2,14 +2,40 @@
 #define STB_IMAGE_IMPLEMENTATION
 #define STB_IMAGE_IMPLEMENTATION
 #include "stb_image.h"
 #include "stb_image.h"
 
 
-Texture::Texture(std::string path){
+Texture::Texture(std::string path, std::string type){
     stbi_set_flip_vertically_on_load(true);  
     stbi_set_flip_vertically_on_load(true);  
-    pixelData = stbi_load(path.c_str(), &width, &height, &channels, 0);
+    unsigned char * data = stbi_load(path.c_str(), &width, &height, &channels, 0);
+
+    if (data){
+        if(type == "RGB"){
+            pixelData = new float[width*height*channels];
+            for(int i = 0; i < width*height*channels; ++i){
+                pixelData[i] = (float)data[i] * (1/256.0f);
+            }
+        }
+        else if (type == "XYZ"){
+            pixelData = new float[width*height*channels];
+            for(int i = 0; i < width*height*channels; ++i){
+                pixelData[i] = (float)data[i] * (2/256.0f) - 1.0f;
+            }
+        }
+        else{
+            printf("Error unrecognized texture format type.\n");
+        }
+    }
+    else{
+        printf("Failed to load texture at: %s\n",path.c_str());
+    }
+    stbi_image_free(data);
+}
+
+Texture::~Texture(){
+    delete [] pixelData;
 }
 }
 
 
 Vector3f Texture::getPixelVal(float u, float v){
 Vector3f Texture::getPixelVal(float u, float v){
     int uInt = u * (width-1); 
     int uInt = u * (width-1); 
     int vInt = v * (height-1);
     int vInt = v * (height-1);
     int index = (vInt*width + uInt)*3;
     int index = (vInt*width + uInt)*3;
-    return Vector3f{(float)pixelData[index], (float)pixelData[index+1], (float)pixelData[index+2]};
+    return Vector3f{pixelData[index], pixelData[index+1], pixelData[index+2]};
 }
 }