diff --git a/headers/Essentials.h b/headers/Essentials.h index 2861e43..88dc6ea 100644 --- a/headers/Essentials.h +++ b/headers/Essentials.h @@ -23,6 +23,7 @@ int Clamp(int, int, int); template void Swap(T &xp, T &yp); +float distance(const float& x1, const float& y1, const float& x2, const float& y2); unsigned int interPolate(const float& input1, const float& input2, const float& position, const unsigned int& val1, const unsigned int& val2); float interPolate(const float& input1, const float& input2, const float& position, const float& val1, const float& val2); float interPolate(const float& fraction, const float& val1, const float& val2); @@ -403,6 +404,7 @@ inline void DrawPixel(int x, int y, Color color); void DrawImage(Image, Vect2 = { 0,0,1 }); void SortByY(Vec3[max_Vertex], int = 3); void SortByYTextures(Vec3[max_Vertex], Vec2[max_Vertex], int = 3); +void SortByYIntensity(Vec3[max_Vertex], float[max_Vertex], int = 3); void DrawDDALine(Vect2, Vect2, Color); void DrawDDALine(float, float, float, float); void DrawDDALine(float, float, float, float, Color); @@ -415,10 +417,12 @@ void DrawBresLine(float, float, float, float); void DrawBresLine(float, float, float, float, unsigned); void DrawHorizLine(int, int, int, Color, Vec3 = { 0, 0, 0 }); +void DrawHorizLineShaded(int, int, int, unsigned char, unsigned char, Vec3 = { 0, 0, 0 }); void DrawHorizTexture(float, float, float, float&, float&, float, float, float, float, Texture*); void DrawTriangle(Triangle&, Color = 0xffffff); void ColorTriangle(Triangle&, Color, Vec3 = { 0.0f,0.0f,0.0f }); +void ShadeTriangle(Triangle&, Vec3 = { 0.0f,0.0f,0.0f }); void TextureTriangle(Triangle&, Texture*); int getMidX(); diff --git a/headers/Shape3D.h b/headers/Shape3D.h index 868e9ae..ff612f5 100644 --- a/headers/Shape3D.h +++ b/headers/Shape3D.h @@ -362,7 +362,7 @@ struct Controller { lUp = 0, lDown = 0, lLeft = 0, lRight = 0, lForward = 0, lBackward = 0, forward = 0, backward = 0, - yawL = 0, yawR = 0, colored = 1, wireframe = 0; + yawL = 0, yawR = 0, colored = 1, wireframe = 0, shaded=1; void reset() { up = 0; down = 0; left = 0; right = 0; @@ -377,9 +377,16 @@ class Shape3D { Mat4x4 matProj; Texture* texture; - Vec3 camera{ 0.0f, 0.0f, 0.0f }; + //Vec3 camera{ 0.0f, 0.0f, 0.0f }; + Vec3 camera{ 0.0f, 10.0f, 30.0f }; + + //Lighting Parameters Vec3 lightDirection = { 1.0f, 1.0f, 1.0f }; - Vec3 lightPosition = { 20.0f,20.0f,20.0f }; + //Vec3 lightPosition = { 5.0f, 5.0f,5.0f }; + Vec3 lightPosition = { 5.0f, 20.0f, 40.0f }; + float Ka = 0.75f, Kd = 0.75f, Ks = 0.5f, + Ia = 5.0f, Il = 7.0f; + int n = 10; float speed = 50.0f; Vec3 lookDir= { 0,0,1 }; @@ -387,11 +394,11 @@ class Shape3D { float fTheta=0; - bool wireframe = 0, colored = 1; + bool wireframe = 0, colored = 1, shaded=1; public: Shape3D() { //Loading Light - //mesh.LoadFromObjectFile("../Assets/cubeSmall.obj"); + mesh.LoadFromObjectFile("../Assets/cubeSmall.obj"); //The Cube //mesh.triangles = { @@ -422,16 +429,15 @@ class Shape3D { //Loading obj //mesh.LoadFromObjectFile("../Assets/Church.obj"); - //mesh.LoadFromObjectFile("../Assets/Cube2.obj"); + mesh.LoadFromObjectFile("../Assets/Cube2.obj"); //mesh.LoadFromObjectFile("../Assets/Teapot.obj"); //mesh.LoadFromObjectFile("../Assets/Axis.obj"); - //mesh.LoadFromObjectFile("../Assets/Mountain.obj"); //mesh.LoadFromObjectFile("../Assets/Mountain2.obj"); //mesh.LoadFromObjectFile("../Assets/Sample.obj"); //For Release - mesh.LoadFromObjectFile("Light.obj"); - mesh.LoadFromObjectFile("Object.obj"); + //mesh.LoadFromObjectFile("Light.obj"); + //mesh.LoadFromObjectFile("Object.obj"); //Load Texture texture = NULL; @@ -489,19 +495,11 @@ class Shape3D { yaw += change * 10.0f; wireframe = c.wireframe; colored = c.colored; + shaded = c.shaded; } void draw() { Mesh toRaster; - - // Rotation Z - //Mat4x4 matRotZ; - //matRotZ = Mat4x4::MakeRotationZ(fTheta*0.5f); - // Rotation Y - //Mat4x4 matRotY; - //matRotY = Mat4x4::MakeRotationY(fTheta); - // Rotation X - //Mat4x4 matRotX; - //matRotX = Mat4x4::MakeRotationX(0); + //Tranlation Mat4x4 matTrans; matTrans = Mat4x4::MakeTranslate(0.0f, 0.0f, 3.0f); @@ -509,14 +507,12 @@ class Shape3D { matLightTrans = Mat4x4::MakeTranslate(lightPosition); //World Transformations Mat4x4 matWorld; - Mat4x4 matWorld2; + Mat4x4 matLighting; matWorld = Mat4x4::MakeIdentity(); - matWorld2 = Mat4x4::MakeIdentity(); - //matWorld.MultiplyMatrix(matRotZ); - //matWorld.MultiplyMatrix(matRotY); + matLighting = Mat4x4::MakeIdentity(); matWorld.MultiplyMatrix(matTrans); - matWorld2.MultiplyMatrix(matLightTrans); - matWorld2.MultiplyMatrix(matTrans); + matLighting.MultiplyMatrix(matLightTrans); + matLighting.MultiplyMatrix(matTrans); //camera Vec3 up = { 0,1,0 }; @@ -534,13 +530,12 @@ class Shape3D { //Draw Triangles for (int index=0; index < sizee; index++) { - //for (auto tri : mesh.triangles) { Triangle tri = mesh.triangles[index]; Triangle triProjected, triTransformed, triViewed; //Apply Transformations if(index<12) - matWorld2.MultiplyTriangle(triTransformed, tri); + matLighting.MultiplyTriangle(triTransformed, tri); else matWorld.MultiplyTriangle(triTransformed, tri); @@ -549,36 +544,24 @@ class Shape3D { Vec3 CameraRay = triTransformed.vertex[0] - camera; if (Vec3::dot(normal,CameraRay.normalize()) < 0.0f) { - if (index < 12) + if (index < 12) { triTransformed.color - = Color(0xff, 0xff, 0xff, 0xff); + = Color(0xff, 0xff, 0xff, 0xff); + for (int k = 0; k < 3; k++) + triTransformed.intensities[k] = 12.5f; + } else { - //Illumination - /*float light = normal.dot(lightDirection.normalize()); - - unsigned char col = interPolate(-1.0f, 1.0f, light, (unsigned int)0, (unsigned int)0xff); - triTransformed.color - = Color(col, col, col, 0xff);*/ - - float Ka = 0.75f, Kd = 0.75f, Ks = 0.5f, - Ia = 5.0f, Il = 7.0f; - int n = 10; - //camera - Vec3 Normals[] = { triTransformed.normals[0], triTransformed.normals[1], triTransformed.normals[2] }; - Vec3 Positions[] = { triTransformed.vertex[0], triTransformed.vertex[1], triTransformed.vertex[2] }; - + //Illumination for (int k = 0; k < 3; k++) { - Vec3 L = (lightPosition - Positions[k]).normalize(); - Vec3 V = (camera - Positions[k]).normalize(); - Vec3 N = Normals[k]; - - float I1 = Ka * Ia; - float I2 = Kd * Il * Vec3::dot(N, L); - float I3 = Ks * Il * pow(Vec3::dot(N, (L + V).normalize()), n); + Vec3 L = (lightPosition - triTransformed.vertex[k]).normalize(); + Vec3 V = (camera - triTransformed.vertex[k]).normalize(); + Vec3 N = triTransformed.normals[k]; - triTransformed.intensities[k] = I1 + I2 + I3; + triTransformed.intensities[k] = Ka * Ia + Kd * Il * Vec3::dot(N, L) + Ks * Il * pow(Vec3::dot(N, (L + V).normalize()), n); } + + if(!shaded){ float inten = (triTransformed.intensities[0] + triTransformed.intensities[1] + triTransformed.intensities[2]) / 3; inten = (inten < 0) ? 0 : inten; float minIp = 0, maxIp = 12.5f; @@ -586,12 +569,8 @@ class Shape3D { unsigned char col = interPolate(minIp, maxIp, inten, minCol, maxCol); triTransformed.color = Color(col, col, col, 0xff); - //Illumination end - } - /* char output[100]; - sprintf_s(output, 100, "%d. Intensity: %f %f %f\n", - index, triTransformed.intensities[0], triTransformed.intensities[1], triTransformed.intensities[2]); - OutputDebugStringA(output);*/ + } + } //Convert World Space to View Space matView.MultiplyTriangle(triViewed, triTransformed); @@ -673,7 +652,11 @@ class Shape3D { tri.vertex[i].x = (float)globalBuffer.width - tri.vertex[i].x; } //TextureTriangle(tri, texture); - if (colored) ColorTriangle(tri, tri.color); + if (colored) { + if(shaded) ShadeTriangle(tri); + else ColorTriangle(tri, tri.color); + } + //if (wireframe) DrawTriangle(tri, 0xffffffff - tri.color.color); if (wireframe) DrawTriangle(tri, 0xffffffff - tri.color.color); } } diff --git a/ourBetterGraphics_eyy_/Assets/CubeTingie.bmp b/ourBetterGraphics_eyy_/Assets/CubeTingie.bmp deleted file mode 100644 index 38d413f..0000000 Binary files a/ourBetterGraphics_eyy_/Assets/CubeTingie.bmp and /dev/null differ diff --git a/src/Essentials.cpp b/src/Essentials.cpp index b4c689e..a4793dc 100644 --- a/src/Essentials.cpp +++ b/src/Essentials.cpp @@ -25,6 +25,10 @@ void Swap(T &xp, T &yp){ xp = yp; yp = temp; } +float distance(const float& x1, const float& y1, const float& x2, const float& y2) { + return sqrtf((x2 - x1)*(x2-x1) + (y2 - y1)*(y2-y1)); + //return abs(x2 - x1) + abs(y2 - y1); +} unsigned int interPolate(const float& input1, const float& input2, const float& position, const unsigned int& val1, const unsigned int& val2) { if (input1 == input2) return val1; else return val1 + (position - input1) / (input2 - input1) * (val2 - val1); @@ -117,8 +121,19 @@ void SortByY(Vec3 arr[max_Vertex], int n) { for (i = 0; i < n - 1; i++) // Last i elements are already in place for (j = 0; j < n - 1 - i; j++) - if (arr[j].y > arr[j + 1].y) + if (arr[j].y > arr[j + 1].y) { + Swap(arr[j], arr[j + 1]); + } +} +void SortByYIntensity(Vec3 arr[max_Vertex],float intensities[max_Vertex], int n) { + int i, j; + for (i = 0; i < n - 1; i++) + // Last i elements are already in place + for (j = 0; j < n - 1 - i; j++) + if (arr[j].y > arr[j + 1].y) { Swap(arr[j], arr[j + 1]); + Swap(intensities[j], intensities[j + 1]); + } } void SortByYTextures(Vec3 arr[max_Vertex], Vec2 tex[max_Vertex], int n) { int i, j; @@ -254,9 +269,26 @@ void DrawBresLine(float x1, float y1, float x2, float y2, Color color) { } void DrawHorizLine(int x1, int x2, int y, Color color, Vec3 off) { - if (x2 < x1) Swap(x1, x2); - for (int i = x1; i <= x2; i++) + if (x2 < x1) { + Swap(x1, x2); + }; + for (int i = x1; i <= x2; i++) { DrawPixel(i + off.x, y + off.y, color); + } +} +void DrawHorizLineShaded(int x1, int x2, int y, Triangle tri, Vec3 off) { + if (x2 < x1) + Swap(x1, x2); + for (int i = x1; i <= x2; i++) { + //Barycentric coordinates + float W1 = ( (tri.vertex[1].y - tri.vertex[2].y)*( i - tri.vertex[2].x ) + ( tri.vertex[2].x - tri.vertex[1].x) * (y - tri.vertex[2].y) ) / + ((tri.vertex[1].y - tri.vertex[2].y) * (tri.vertex[0].x - tri.vertex[2].x) + (tri.vertex[2].x - tri.vertex[1].x) * (tri.vertex[0].y - tri.vertex[2].y)); + float W2 = ((tri.vertex[2].y - tri.vertex[0].y) * (i - tri.vertex[2].x) + (tri.vertex[0].x - tri.vertex[2].x) * (y - tri.vertex[2].y)) / + ((tri.vertex[1].y - tri.vertex[2].y) * (tri.vertex[0].x - tri.vertex[2].x) + (tri.vertex[2].x - tri.vertex[1].x) * (tri.vertex[0].y - tri.vertex[2].y)); + float W3 = 1 - W1 - W2; + unsigned char col = (W1*tri.intensities[0]+ W2 * tri.intensities[1]+ W3 * tri.intensities[2]) / 12.5f * 0xff; + DrawPixel(i + off.x, y + off.y, Color(col, col, col, 0xff)); + } } void DrawHorizTexture(float ax, float bx, float y, float& texU, float& texV, float& texW, float texStartU, float texEndU, float texStartV, float texEndV, @@ -307,6 +339,35 @@ void ColorTriangle(Triangle& tri, Color color, Vec3 off) { DrawHorizLine(Source.x, End.x, Source.y, color, off); } } +void ShadeTriangle(Triangle& tri, Vec3 off) { + float dx1, dx2, dx3; + Vec3 array[] = { tri.vertex[0], tri.vertex[1], tri.vertex[2] }; + SortByY(array); + Vec3 A = array[0]; + Vec3 B = array[1]; + Vec3 C = array[2]; + + Vec3 Source, End; + if (B.y - A.y > 0) dx1 = (B.x - A.x) / (B.y - A.y); else dx1 = 0; + if (C.y - A.y > 0) dx2 = (C.x - A.x) / (C.y - A.y); else dx2 = 0; + if (C.y - B.y > 0) dx3 = (C.x - B.x) / (C.y - B.y); else dx3 = 0; + + Source = End = A; + if (dx1 > dx2) { + for (; Source.y <= B.y; Source.y++, End.y++, Source.x += dx2, End.x += dx1) + DrawHorizLineShaded(Source.x, End.x, Source.y, tri, off); + End = B; + for (; Source.y <= C.y; Source.y++, End.y++, Source.x += dx2, End.x += dx3) + DrawHorizLineShaded(Source.x, End.x, Source.y, tri, off); + } + else { + for (; Source.y <= B.y; Source.y++, End.y++, Source.x += dx1, End.x += dx2) + DrawHorizLineShaded(Source.x, End.x, Source.y, tri, off); + Source = B; + for (; Source.y <= C.y; Source.y++, End.y++, Source.x += dx3, End.x += dx2) + DrawHorizLineShaded(Source.x, End.x, Source.y, tri, off); + } +} void TextureTriangle(Triangle& tri, Texture* texture) { //Sort Vertices by y value Vec3 array[] = { tri.vertex[0], tri.vertex[1], tri.vertex[2] }; diff --git a/src/main.cpp b/src/main.cpp index 9cc0f4b..26b8181 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -130,6 +130,7 @@ int CALLBACK WinMain( if (vkCode == 'C') { p += multiplier; + controller.shaded = !controller.shaded; } if (vkCode == 'J')