Browse Source

Lesson 25.1

Godzil 3 years ago
parent
commit
89dc628004

+ 1 - 0
source/clipping.c

@@ -12,6 +12,7 @@
 #include <math.h>
 #include <assert.h>
 
+#include <display.h>
 #include <clipping.h>
 
 static plane_t frustum[TOTAL_PLANES];

+ 173 - 23
source/display.c

@@ -13,21 +13,20 @@
 #include <SDL.h>
 #include <SDL_ttf.h>
 
+#include <3dengine.h>
 #include <log.h>
 #include <display.h>
 
 /***********************************************************************************************************************
- * Global variables
+ * Variables
  **********************************************************************************************************************/
-
-SDL_Window *window = NULL;
-SDL_Renderer *renderer = NULL;
-colour_t *frameBuffer = NULL;
-double *zBuffer = NULL;
-SDL_Texture *frameBufferTexture = NULL;
-int32_t windowWidth = 1024;
-int32_t windowHeight = 768;
-
+static SDL_Window *window = NULL;
+static SDL_Renderer *renderer = NULL;
+static colour_t *frameBuffer = NULL;
+static double *zBuffer = NULL;
+static SDL_Texture *frameBufferTexture = NULL;
+static int32_t windowWidth = 1024;
+static int32_t windowHeight = 768;
 static TTF_Font *font = NULL;
 
 /***********************************************************************************************************************
@@ -36,7 +35,7 @@ static TTF_Font *font = NULL;
 #define MAX(_a, _b) ((_a) < (_b)) ? (_b) : (_a)
 #define MIN(_a, _b) ((_a) > (_b)) ? (_b) : (_a)
 
-bool initialiseWindow(bool fullScreen)
+bool initialiseWindow(int32_t width, int32_t height, bool fullScreen)
 {
     bool ret = false;
     int windowFlags = 0;
@@ -56,6 +55,9 @@ bool initialiseWindow(bool fullScreen)
         goto exit;
     }
 
+    windowWidth = width;
+    windowHeight = height;
+
     if (fullScreen)
     {
         Log(TLOG_DEBUG, NULL, "Will go fullscreen! Fasten your seatbelts!");
@@ -92,6 +94,28 @@ bool initialiseWindow(bool fullScreen)
         goto exit;
     }
 
+    frameBuffer = (uint32_t *)calloc(windowWidth * windowHeight, sizeof(uint32_t));
+    if (!frameBuffer)
+    {
+        Log(TLOG_PANIC, NULL, "Memory allocation error.");
+        goto exit;
+    }
+
+    zBuffer = (double *)calloc(windowWidth * windowHeight, sizeof(double));
+    if (!frameBuffer)
+    {
+        Log(TLOG_PANIC, NULL, "Memory allocation error.");
+        goto exit;
+    }
+
+    frameBufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, windowWidth,
+                                           windowHeight);
+    if (frameBufferTexture == NULL)
+    {
+        Log(TLOG_PANIC, NULL, "SDL Texture creation error: %s", SDL_GetError());
+        goto exit;
+    }
+
     if (fullScreen)
     {
         SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN);
@@ -103,6 +127,12 @@ exit:
     return ret;
 }
 
+void getWindowSize(int32_t *width, int32_t *height)
+{
+    *width = windowWidth;
+    *height = windowHeight;
+}
+
 void destroyWindow()
 {
     if (font != NULL)
@@ -122,6 +152,17 @@ void destroyWindow()
     SDL_Quit();
 }
 
+void displayWindowClear()
+{
+    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
+    SDL_RenderClear(renderer);
+}
+
+void displayWindowRender()
+{
+    SDL_RenderPresent(renderer);
+}
+
 void renderFrameBuffer()
 {
     SDL_UpdateTexture(frameBufferTexture, NULL, frameBuffer, (uint32_t)(windowWidth * sizeof(uint32_t)));
@@ -216,27 +257,21 @@ void drawHLine(int32_t x0, int32_t y, int32_t x1, colour_t colour)
 
 void clearFrameBuffer(colour_t colour)
 {
-    int32_t x, y;
-    for (y = 0 ; y < windowHeight ; y++)
+    int32_t x;
+    for (x = 0 ; x < windowWidth * windowHeight ; x++)
     {
-        for (x = 0 ; x < windowWidth ; x++)
-        {
-            frameBuffer[x + (y * windowWidth)] = colour;
-        }
+        frameBuffer[x] = colour;
     }
 }
 
 void clearZBuffer()
 {
-    int32_t x, y;
+    int32_t x;
     if (doZBuffer)
     {
-        for (y = 0 ; y < windowHeight ; y++)
+        for (x = 0 ; x < windowWidth * windowHeight ; x++)
         {
-            for (x = 0 ; x < windowWidth ; x++)
-            {
-                zBuffer[x + (y * windowWidth)] = 1.0;
-            }
+                zBuffer[x] = 1.0;
         }
     }
 }
@@ -299,3 +334,118 @@ void drawLine(int32_t x0, int32_t y0, int32_t x1, int32_t y1, colour_t colour)
         }
     }
 }
+
+static vec3_t barycentricWeights(vec2_t a, vec2_t b, vec2_t c, vec2_t p)
+{
+    vec2_t ab = vec2SubVectors(b, a);
+    vec2_t bc = vec2SubVectors(c, b);
+    vec2_t ac = vec2SubVectors(c, a);
+    vec2_t ap = vec2SubVectors(p, a);
+    vec2_t bp = vec2SubVectors(p, b);
+    vec3_t ret;
+
+    double areaTriangleABC = (ab.x * ac.y) - (ab.y * ac.x);
+
+    double alpha = ((bc.x * bp.y) - (bp.x * bc.y)) / areaTriangleABC;
+    double beta = ((ap.x * ac.y) - (ac.x * ap.y)) / areaTriangleABC;
+    double gamma = 1 - alpha - beta;
+
+    ret.x = alpha;
+    ret.y = beta;
+    ret.z = gamma;
+
+    return ret;
+}
+
+void drawZPixel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, colour_t colour)
+{
+    vec2_t pointP = { x, y };
+    vec2_t a2 = vec2FromVec4(a);
+    vec2_t b2 = vec2FromVec4(b);
+    vec2_t c2 = vec2FromVec4(c);
+
+    if ((x < 0) || (y < 0) || (x > windowWidth) ||(y > windowHeight))
+    {
+        return;
+    }
+
+    vec3_t weights = barycentricWeights(a2, b2, c2, pointP);
+
+    double alpha = weights.x;
+    double beta = weights.y;
+    double gamma = weights.z;
+    double interpolatedReciprocalW;
+
+    interpolatedReciprocalW = (1 / a.w) * alpha + (1 / b.w) * beta + (1 / c.w) * gamma;
+
+    /* Inverse to get logical W invrementing going further to us */
+    interpolatedReciprocalW = 1 - interpolatedReciprocalW;
+    if (interpolatedReciprocalW < zBuffer[(windowWidth * y) + x])
+    {
+        drawPixel(x, y, colour);
+
+        /* Update Z Buffer */
+        zBuffer[(windowWidth * y) + x] = interpolatedReciprocalW;
+    }
+}
+
+void drawTexel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, tex2_t ta, tex2_t tb, tex2_t tc, texture_t *texture)
+{
+    vec2_t pointP = { x, y };
+    vec2_t a2 = vec2FromVec4(a);
+    vec2_t b2 = vec2FromVec4(b);
+    vec2_t c2 = vec2FromVec4(c);
+
+    if ((x < 0) || (y < 0) || (x > windowWidth) ||(y > windowHeight))
+    {
+        return;
+    }
+
+    vec3_t weights = barycentricWeights(a2, b2, c2, pointP);
+
+    double alpha = weights.x;
+    double beta = weights.y;
+    double gamma = weights.z;
+    double interpolatedU, interpolatedV, interpolatedReciprocalW;
+    int32_t texX, texY;
+
+    interpolatedReciprocalW = (1 / a.w) * alpha + (1 / b.w) * beta + (1 / c.w) * gamma;
+
+    if (doPerspectiveCorrection)
+    {
+        interpolatedU = (ta.u / a.w) * alpha + (tb.u / b.w) * beta + (tc.u / c.w) * gamma;
+        interpolatedV = ((1 - ta.v) / a.w) * alpha + ((1 - tb.v) / b.w) * beta + ((1 - tc.v) / c.w) * gamma;
+
+
+        interpolatedU /= interpolatedReciprocalW;
+        interpolatedV /= interpolatedReciprocalW;
+    }
+    else
+    {
+        interpolatedU = ta.u * alpha + tb.u * beta + tc.u * gamma;
+        interpolatedV = (1 - ta.v) * alpha + (1 - tb.v) * beta + (1 - tc.v) * gamma;
+    }
+
+    texX = abs((int32_t)(interpolatedU * texture->width));
+    texY = abs((int32_t)(interpolatedV * texture->height));
+
+    texX = texX % texture->width;
+    texY = texY % texture->height;
+
+    if (doZBuffer)
+    {
+        /* Inverse to get logical W invrementing going further to us */
+        interpolatedReciprocalW = 1 - interpolatedReciprocalW;
+        if (interpolatedReciprocalW < zBuffer[(windowWidth * y) + x])
+        {
+            drawPixel(x, y, texture->data[(texY * texture->width) + texX]);
+
+            /* Update Z Buffer */
+            zBuffer[(windowWidth * y) + x] = interpolatedReciprocalW;
+        }
+    }
+    else
+    {
+        drawPixel(x, y, texture->data[(texY * texture->width) + texX]);
+    }
+}

+ 19 - 0
source/include/3dengine.h

@@ -0,0 +1,19 @@
+/*
+ * 3D Engine 
+ * 3dengine.h: 
+ * Based on pikuma.com 3D software renderer in C
+ * Copyright (c) 2021 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 15/03/2021.
+ */
+
+#ifndef THREEDENGINE_SOURCE_INCLUDE_3DENGINE_H
+#define THREEDENGINE_SOURCE_INCLUDE_3DENGINE_H
+
+/***********************************************************************************************************************
+ * Global variables
+ **********************************************************************************************************************/
+extern bool doPerspectiveCorrection;
+extern bool doZBuffer;
+
+#endif /* THREEDENGINE_SOURCE_INCLUDE_3DENGINE_H */

+ 17 - 35
source/include/colour.h

@@ -1,42 +1,24 @@
 /*
- * C Fancy Logger
- * colour.h:
- * Copyright (c) 2009-2021 986-Studio. All rights reserved.
+ * 3D Engine 
+ * colour.h: 
+ * Based on pikuma.com 3D software renderer in C
+ * Copyright (c) 2021 986-Studio. All rights reserved.
  *
- * Created by Manoël Trapier on 20/01/2009.
+ * Created by Manoël Trapier on 15/03/2021.
  */
 
-#ifndef LOG_COLOUR_H
-#define	LOG_COLOUR_H
+#ifndef THREEDENGINE_SOURCE_INCLUDE_COLOUR_H
+#define THREEDENGINE_SOURCE_INCLUDE_COLOUR_H
 
-#define ALLOW_COLORS
+/***********************************************************************************************************************
+ * Data types
+ **********************************************************************************************************************/
+typedef uint32_t colour_t;
 
-#ifdef ALLOW_COLORS
-#define __C(c) "\x1B[" c "m"
-#else
-#define __C(c) ""
-#endif
-
-#define ANSI_COLOR __C
-#define FBLACK ANSI_COLOR("30")
-#define FRED ANSI_COLOR("31")
-#define FGREEN ANSI_COLOR("32")
-#define FYELLOW ANSI_COLOR("33")
-#define FBLUE ANSI_COLOR("34")
-#define FMAGENTA ANSI_COLOR("35")
-#define FCYAN ANSI_COLOR("36")
-#define FWHITE ANSI_COLOR("37")
-
-#define BBLACK ANSI_COLOR("40")
-#define BRED ANSI_COLOR("41")
-#define BGREEN ANSI_COLOR("42")
-#define BYELLOW ANSI_COLOR("43")
-#define BBLUE ANSI_COLOR("44")
-#define BMAGENTA ANSI_COLOR("45")
-#define BCYAN ANSI_COLOR("46")
-#define BWHITE ANSI_COLOR("47")
-
-#define CNORMAL ANSI_COLOR("0")
-
-#endif	/* LOG_COLOUR_H */
+/***********************************************************************************************************************
+ * Prototypes
+ **********************************************************************************************************************/
+#define MAKE_RGB(_r, _g, _b) ((0xFF000000) | ((_b & 0xFF) << 16) | ((_g & 0xFF) << 8) | ((_r & 0xFF)))
+#define MAKE_ARGB(_a, _r, _g, _b) (((_a & 0xFF) << 24) | ((_g & 0xFF) << 16) | ((_g & 0xFF) << 8) | ((_r & 0xFF)))
 
+#endif /* THREEDENGINE_SOURCE_INCLUDE_COLOUR_H */

+ 16 - 16
source/include/display.h

@@ -13,10 +13,17 @@
 #include <stdbool.h>
 #include <SDL.h>
 
+#include <vector.h>
+#include <texture.h>
+#include <colour.h>
+
 /***********************************************************************************************************************
  * Data types
  **********************************************************************************************************************/
-typedef uint32_t colour_t;
+typedef struct window_t
+{
+    int32_t height, width;
+} window_t;
 
 /***********************************************************************************************************************
  * Constants
@@ -24,25 +31,17 @@ typedef uint32_t colour_t;
 #define FPS (60)
 #define FRAME_TARGET_TIME (1000 / FPS)
 
-/***********************************************************************************************************************
- * Global variables
- **********************************************************************************************************************/
-extern SDL_Window *window;
-extern SDL_Renderer *renderer;
-extern colour_t *frameBuffer;
-extern double *zBuffer;
-extern SDL_Texture *frameBufferTexture;
-extern int32_t windowWidth;
-extern int32_t windowHeight;
-extern bool doZBuffer;
-
 /***********************************************************************************************************************
  * Prototypes
  **********************************************************************************************************************/
 /* --- Window functions --- */
-bool initialiseWindow(bool fullScreen);
+bool initialiseWindow(int32_t screenWidth, int32_t screenHeight, bool fullScreen);
 void destroyWindow();
 void renderFrameBuffer();
+void getWindowSize(int32_t *width, int32_t *height);
+void displayWindowClear();
+void displayWindowRender();
+
 
 /* --- Drawing functions --- */
 void clearZBuffer();
@@ -71,7 +70,8 @@ static inline void doubleSwap(double *a, double *b)
     *b = tmp;
 }
 
-#define MAKE_RGB(_r, _g, _b) ((0xFF000000) | ((_b & 0xFF) << 16) | ((_g & 0xFF) << 8) | ((_r & 0xFF)))
-#define MAKE_ARGB(_a, _r, _g, _b) (((_a & 0xFF) << 24) | ((_g & 0xFF) << 16) | ((_g & 0xFF) << 8) | ((_r & 0xFF)))
+/* Other */
+void drawZPixel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, colour_t colour);
+void drawTexel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, tex2_t ta, tex2_t tb, tex2_t tc, texture_t *texture);
 
 #endif /* THREEDENGINE_SOURCE_INCLUDE_DISPLAY_H */

+ 6 - 9
source/include/mesh.h

@@ -12,6 +12,7 @@
 
 #include <vector.h>
 #include <triangle.h>
+#include <texture.h>
 
 /***********************************************************************************************************************
  * Data types
@@ -26,20 +27,16 @@ typedef struct mesh_t
     vec3_t rotation;         /**< Rotation of the object */
     vec3_t scale;            /**< Scaling of the object */
     vec3_t translation;      /**< Translation of the object */
-} mesh_t;
-
 
-/***********************************************************************************************************************
- * Global variables
- **********************************************************************************************************************/
-extern mesh_t mesh;
+    texture_t texture;       /**< Texture to apply to the object */
+} mesh_t;
 
 /***********************************************************************************************************************
  * Prototypes
  **********************************************************************************************************************/
-void loadCubeMeshData();
-void meshFree();
+void loadCubeMeshData(mesh_t *mesh);
+void loadOBJFile(mesh_t *mesh, const char *filepath);
 
-void loadOBJFile(const char *filepath);
+void meshFree(mesh_t *mesh);
 
 #endif /* THREEDENGINE_SOURCE_INCLUDE_MESH_H */

+ 42 - 0
source/include/termcolour.h

@@ -0,0 +1,42 @@
+/*
+ * C Fancy Logger
+ * colour.h:
+ * Copyright (c) 2009-2021 986-Studio. All rights reserved.
+ *
+ * Created by Manoël Trapier on 20/01/2009.
+ */
+
+#ifndef LOG_COLOUR_H
+#define	LOG_COLOUR_H
+
+#define ALLOW_COLORS
+
+#ifdef ALLOW_COLORS
+#define __C(c) "\x1B[" c "m"
+#else
+#define __C(c) ""
+#endif
+
+#define ANSI_COLOR __C
+#define FBLACK ANSI_COLOR("30")
+#define FRED ANSI_COLOR("31")
+#define FGREEN ANSI_COLOR("32")
+#define FYELLOW ANSI_COLOR("33")
+#define FBLUE ANSI_COLOR("34")
+#define FMAGENTA ANSI_COLOR("35")
+#define FCYAN ANSI_COLOR("36")
+#define FWHITE ANSI_COLOR("37")
+
+#define BBLACK ANSI_COLOR("40")
+#define BRED ANSI_COLOR("41")
+#define BGREEN ANSI_COLOR("42")
+#define BYELLOW ANSI_COLOR("43")
+#define BBLUE ANSI_COLOR("44")
+#define BMAGENTA ANSI_COLOR("45")
+#define BCYAN ANSI_COLOR("46")
+#define BWHITE ANSI_COLOR("47")
+
+#define CNORMAL ANSI_COLOR("0")
+
+#endif	/* LOG_COLOUR_H */
+

+ 10 - 14
source/include/texture.h

@@ -11,10 +11,9 @@
 #define THREEDENGINE_SOURCE_INCLUDE_TEXTURE_H
 
 #include <stdint.h>
-
 #include <upng.h>
 
-#include <display.h>
+#include <colour.h>
 
 /***********************************************************************************************************************
  * Data types
@@ -24,21 +23,18 @@ typedef struct tex2_t
     double u, v;
 } tex2_t;
 
-/***********************************************************************************************************************
- * Global variables
- **********************************************************************************************************************/
-extern int textureWidth;
-extern int textureHeight;
-
-extern const uint8_t REDBRICK_TEXTURE[];
-
-colour_t *meshTexture;
-extern upng_t *pngTexture;
+typedef struct texture_t
+{
+    upng_t *png;
+    colour_t *data;
+    int width;
+    int height;
+} texture_t;
 
 /***********************************************************************************************************************
  * Prototypes
  **********************************************************************************************************************/
-void loadTextureDateFromPng(const char *filepath);
-void textureCleanup();
+void loadTextureDateFromPng(texture_t *texture, const char *filepath);
+void textureCleanup(texture_t *texture);
 
 #endif /* THREEDENGINE_SOURCE_INCLUDE_TEXTURE_H */

+ 2 - 2
source/include/triangle.h

@@ -36,13 +36,13 @@ typedef struct triangle_t
     colour_t colour;
     double averageDepth;
 
-    uint32_t *texture;
+    texture_t *texture;
 } triangle_t;
 
 /***********************************************************************************************************************
  * Global variables
  **********************************************************************************************************************/
-extern bool doPerpectiveCorrection;
+extern bool doPerspectiveCorrection;
 
 /***********************************************************************************************************************
  * Prototypes

+ 1 - 1
source/log.c

@@ -10,7 +10,7 @@
 
 #include <stdlib.h>
 #include <stdio.h>
-#include <colour.h>
+#include <termcolour.h>
 #include <string.h>
 #include <stdarg.h>
 #include <log.h>

+ 97 - 158
source/main.c

@@ -16,6 +16,7 @@
 
 #include <log.h>
 
+#include <3dengine.h>
 #include <array.h>
 #include <matrix.h>
 #include <triangle.h>
@@ -44,13 +45,19 @@ bool displayVertex = false;
 bool doNotCull = false;
 bool doZBuffer = true;
 bool doClipping = true;
-enum displayMode_t currentDisplayMode = DISPLAY_MODE_WIREFRAME;
-matrix4_t projectionMatrix;
-matrix4_t viewMatrix;
-light_t globalLight;
-double updateTime, renderTime, waitTime;
-int trianglesCount, trianglesTotal;
-triangle_t *projectedTriangles = NULL;
+bool doPerspectiveCorrection = true;
+
+static mesh_t mesh;
+static int windowHeight;
+static int windowWidth;
+
+static enum displayMode_t currentDisplayMode = DISPLAY_MODE_WIREFRAME;
+static matrix4_t projectionMatrix;
+static matrix4_t viewMatrix;
+static light_t globalLight;
+static double updateTime, renderTime, waitTime;
+static int trianglesCount, trianglesTotal;
+static triangle_t *projectedTriangles = NULL;
 static const vec3_t origin = {0, 0, 0 };
 
 void setup()
@@ -61,28 +68,6 @@ void setup()
     double zNear = 1;
     double zFar = 20;
 
-    frameBuffer = (uint32_t *)calloc(windowWidth * windowHeight, sizeof(uint32_t));
-    if (!frameBuffer)
-    {
-        Log(TLOG_PANIC, NULL, "Memory allocation error.");
-        goto exit;
-    }
-
-    zBuffer = (double *)calloc(windowWidth * windowHeight, sizeof(double));
-    if (!frameBuffer)
-    {
-        Log(TLOG_PANIC, NULL, "Memory allocation error.");
-        goto exit;
-    }
-
-    frameBufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, windowWidth,
-                                           windowHeight);
-    if (frameBufferTexture == NULL)
-    {
-        Log(TLOG_PANIC, NULL, "SDL Texture creation error: %s", SDL_GetError());
-        goto exit;
-    }
-
     projectionMatrix = mat4Perspective(aspectRatioY, FOV, zNear, zFar);
 
     initFrustumPlanes(FOV, aspectRatioX, zNear, zFar);
@@ -92,132 +77,90 @@ void setup()
     globalLight.direction.z = 1;
     vec3Normalize(&globalLight.direction);
 
-    /* Load texture */
-    //meshTexture = (colour_t *)REDBRICK_TEXTURE;
-    loadTextureDateFromPng("assets/f117.png");
-
-
     /* Load object */
-    loadOBJFile("assets/f117.obj");
-    //loadCubeMeshData();
+    loadOBJFile(&mesh,"assets/f117.obj");
+    //loadCubeMeshData(&mesh);
 
-    trianglesTotal = arrayGetSize(mesh.faces);
+    /* Load texture */
+    loadTextureDateFromPng(&mesh.texture, "assets/f117.png");
 
-exit:
-    return;
+    trianglesTotal = arrayGetSize(mesh.faces);
 }
 
 void processInput()
 {
     SDL_Event event;
-    SDL_PollEvent(&event);
-
-    switch (event.type)
+    while(SDL_PollEvent(&event))
     {
-    case SDL_QUIT:isRunning = false;
-        break;
-
-    case SDL_KEYDOWN:
-        switch(event.key.keysym.sym)
+        switch (event.type)
         {
-        case SDLK_ESCAPE:
-            isRunning = false;
-            break;
-
-        case SDLK_1:
-            displayVertex = true;
-            currentDisplayMode = DISPLAY_MODE_WIREFRAME;
-            break;
-
-        case SDLK_2:
-            displayVertex = false;
-            currentDisplayMode = DISPLAY_MODE_WIREFRAME;
-            break;
-
-        case SDLK_3:
-            displayVertex = false;
-            currentDisplayMode = DISPLAY_MODE_SOLID;
-            break;
-
-        case SDLK_4:
-            displayVertex = false;
-            currentDisplayMode = DISPLAY_MODE_SOLID_WIRE;
-            break;
-
-        case SDLK_5:
-            displayVertex = false;
-            currentDisplayMode = DISPLAY_MODE_TEXTURED;
-            break;
-
-        case SDLK_6:
-            displayVertex = false;
-            currentDisplayMode = DISPLAY_MODE_TEXTURED_WIRE;
-            break;
-
-        case SDLK_u:
-            doNotCull = false;
-            break;
-
-        case SDLK_j:
-            doNotCull = true;
-            break;
-
-        case SDLK_i:
-            doPerpectiveCorrection = false;
+        case SDL_QUIT:isRunning = false;
             break;
 
-        case SDLK_k:
-            doPerpectiveCorrection = true;
-            break;
-
-        case SDLK_o:
-            doZBuffer = true;
-            break;
-
-        case SDLK_l:
-            doZBuffer = false;
-            break;
-
-        case SDLK_y:
-            doClipping = true;
-            break;
-
-        case SDLK_h:
-            doClipping = false;
-            break;
-
-        case SDLK_w:
-            camera.forwardVelocity = vec3ScalarMult(camera.direction, 5 * deltaTime);
-            camera.position = vec3AddVectors(camera.position, camera.forwardVelocity);
-            break;
-
-        case SDLK_d:
-            camera.yawAngle += 1.0 * deltaTime;
-            break;
-
-        case SDLK_s:
-            camera.forwardVelocity = vec3ScalarMult(camera.direction, 5 * deltaTime);
-            camera.position = vec3SubVectors(camera.position, camera.forwardVelocity);
-            break;
-
-        case SDLK_a:
-            camera.yawAngle -= 1.0 * deltaTime;
-            break;
-
-        case SDLK_UP:
-            camera.position.y += 3.0 * deltaTime;
+        case SDL_KEYDOWN:
+            switch (event.key.keysym.sym)
+            {
+            case SDLK_1:
+                displayVertex = true;
+                currentDisplayMode = DISPLAY_MODE_WIREFRAME;
+                break;
+
+            case SDLK_2:
+                displayVertex = false;
+                currentDisplayMode = DISPLAY_MODE_WIREFRAME;
+                break;
+
+            case SDLK_3:
+                displayVertex = false;
+                currentDisplayMode = DISPLAY_MODE_SOLID;
+                break;
+
+            case SDLK_4:
+                displayVertex = false;
+                currentDisplayMode = DISPLAY_MODE_SOLID_WIRE;
+                break;
+
+            case SDLK_5:
+                displayVertex = false;
+                currentDisplayMode = DISPLAY_MODE_TEXTURED;
+                break;
+
+            case SDLK_6:
+                displayVertex = false;
+                currentDisplayMode = DISPLAY_MODE_TEXTURED_WIRE;
+                break;
+
+            case SDLK_ESCAPE: isRunning = false; break;
+            case SDLK_u: doNotCull = false; break;
+            case SDLK_j: doNotCull = true; break;
+            case SDLK_i: doPerspectiveCorrection = false; break;
+            case SDLK_k: doPerspectiveCorrection = true; break;
+            case SDLK_o: doZBuffer = true; break;
+            case SDLK_l: doZBuffer = false; break;
+            case SDLK_y: doClipping = true; break;
+            case SDLK_h: doClipping = false; break;
+
+            case SDLK_w:
+                camera.forwardVelocity = vec3ScalarMult(camera.direction, 5 * deltaTime);
+                camera.position = vec3AddVectors(camera.position, camera.forwardVelocity);
+                break;
+
+            case SDLK_d: camera.yawAngle += 1.0 * deltaTime; break;
+            case SDLK_s:
+                camera.forwardVelocity = vec3ScalarMult(camera.direction, 5 * deltaTime);
+                camera.position = vec3SubVectors(camera.position, camera.forwardVelocity);
+                break;
+
+            case SDLK_a: camera.yawAngle -= 1.0 * deltaTime; break;
+            case SDLK_UP: camera.position.y += 3.0 * deltaTime; break;
+            case SDLK_DOWN: camera.position.y -= 3.0 * deltaTime; break;
+            }
             break;
 
-        case SDLK_DOWN:
-            camera.position.y -= 3.0 * deltaTime;
+        default:
             break;
         }
-        break;
-
-    default:
-        break;
     }
-
 }
 
 uint32_t getMicroSecTime()
@@ -227,7 +170,7 @@ uint32_t getMicroSecTime()
     return ((curTime.tv_sec) * 1000 * 1000) + (curTime.tv_usec);
 }
 
-static void projectTriangle(triangle_t *workTriangle, vec3_t *triangleNormal, colour_t colour)
+static void projectTriangle(triangle_t *workTriangle, vec3_t *triangleNormal, texture_t *texture, colour_t colour)
 {
     int j;
     struct triangle_t currentTriangle = *workTriangle;
@@ -236,7 +179,6 @@ static void projectTriangle(triangle_t *workTriangle, vec3_t *triangleNormal, co
     {
         vec4_t projected = mat4ProdVec4Project(projectionMatrix, workTriangle->points[j]);
 
-
         projected.x *= windowWidth / 2.;
         projected.y *= windowHeight / 2.;
 
@@ -265,7 +207,7 @@ static void projectTriangle(triangle_t *workTriangle, vec3_t *triangleNormal, co
                                     workTriangle->points[1].z +
                                     workTriangle->points[2].z) / 3.0;
 
-    currentTriangle.texture = meshTexture;
+    currentTriangle.texture = texture;
     arrayAdd(projectedTriangles, currentTriangle);
 }
 
@@ -304,8 +246,7 @@ void update()
     worldMatrix = mat4ProdMat4(mat4RotationY(mesh.rotation.y), worldMatrix);
     worldMatrix = mat4ProdMat4(mat4RotationX(mesh.rotation.x), worldMatrix);
     worldMatrix = mat4ProdMat4(mat4Translate(mesh.translation.x, mesh.translation.y, mesh.translation.z), worldMatrix);
-
-    /* Not sure for now */
+    /* Last apply the view matrix */
     worldMatrix = mat4ProdMat4(viewMatrix, worldMatrix);
 
     arrayEmpty(projectedTriangles);
@@ -327,10 +268,7 @@ void update()
         for(j = 0; j < 3; j++)
         {
             transformedVertices[j] = vec4FromVec3(vertices[j]);
-
             transformedVertices[j] = mat4ProdVec4(worldMatrix, transformedVertices[j]);
-
-            //transformedVertices[j] = mat4ProdVec4(viewMatrix, transformedVertices[j]);
         }
 
         vec3_t vectorBA = vec3SubVectors(vec3FromVec4(transformedVertices[1]), vec3FromVec4(transformedVertices[0]));
@@ -366,7 +304,7 @@ void update()
             createTriangleFromPolygon(&polygon, trianglesAfterClipping, &numberOfClippedTriangles);
             for(j = 0; j < numberOfClippedTriangles; j++)
             {
-                projectTriangle(&trianglesAfterClipping[j], &triangleNormal, mesh.faces[i].colour);
+                projectTriangle(&trianglesAfterClipping[j], &triangleNormal, &mesh.texture, mesh.faces[i].colour);
             }
         }
         else
@@ -387,7 +325,7 @@ void update()
                 }
             };
 
-            projectTriangle(&workTriangle, &triangleNormal, mesh.faces[i].colour);
+            projectTriangle(&workTriangle, &triangleNormal, &mesh.texture, mesh.faces[i].colour);
         };
     }
 
@@ -406,8 +344,8 @@ void render()
     int i;
     uint32_t ticks = getMicroSecTime();
 
-    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
-    SDL_RenderClear(renderer);
+    clearFrameBuffer(MAKE_RGB(0, 0, 0));
+    clearZBuffer();
 
     int triangleCount = arrayGetSize(projectedTriangles);
 
@@ -454,12 +392,9 @@ void render()
                               MAKE_RGB(255, 0, 0));
             }
         }
-
     }
 
     renderFrameBuffer();
-    clearFrameBuffer(MAKE_RGB(0, 0, 0));
-    clearZBuffer();
 
     renderTime = (renderTime + (getMicroSecTime() - ticks) / 1000.) / 2.0;
 
@@ -469,8 +404,9 @@ void render()
     drawText(5, 41, 0x11FF22, "FPS: %.1f | dT: %.3f", 1000 / (waitTime + updateTime + renderTime), deltaTime);
     drawText(5, 53, 0x11FF22, "Triangles: %d / %d", triangleCount, trianglesTotal);
     drawText(5, 65, 0x11FF22, "Cull: %c | PeCo: %c | ZB: %c, | CP: %c",
-             doNotCull?'N':'Y', doPerpectiveCorrection?'Y':'N', doZBuffer?'Y':'N', doClipping?'Y':'N');
-    SDL_RenderPresent(renderer);
+             doNotCull?'N':'Y', doPerspectiveCorrection ? 'Y' : 'N', doZBuffer ? 'Y' : 'N', doClipping ? 'Y' : 'N');
+
+    displayWindowRender();
 }
 
 int main(int argc, char *argv[])
@@ -481,6 +417,9 @@ int main(int argc, char *argv[])
 
     Log(TLOG_ALWAYS, NULL, "Booting 3D Engine (version %s)!", VERSION);
 
+    windowWidth = 1024;
+    windowHeight = 768;
+
     for (param_i = 1 ; (param_i < argc) && (argv[param_i][0] == '-') ; param_i++)
     {
         switch (argv[param_i][1])
@@ -497,7 +436,7 @@ int main(int argc, char *argv[])
     }
 no_more_params:
 
-    isRunning = initialiseWindow(fullScreen);
+    isRunning = initialiseWindow(windowWidth, windowHeight, fullScreen);
 
     setup();
 
@@ -509,8 +448,8 @@ no_more_params:
     }
 
     arrayFree(projectedTriangles);
-    textureCleanup();
-    meshFree();
+    textureCleanup(&mesh.texture);
+    meshFree(&mesh);
     destroyWindow();
 
     return 0;

+ 48 - 54
source/mesh.c

@@ -19,9 +19,7 @@
 #include <mesh.h>
 
 #define N_CUBE_VERTICES (8)
-extern vec3_t cubeVertices[N_CUBE_VERTICES];
 #define N_CUBE_FACES (6 * 2)
-extern face_t cubeFaces[N_CUBE_FACES];
 
 vec3_t cubeVertices[N_CUBE_VERTICES] =
 {
@@ -57,41 +55,32 @@ face_t cubeFaces[N_CUBE_FACES] =
     { .a = 6, .b = 1, .c = 4, .a_uv = { 0, 1 }, .b_uv = { 1, 0 }, .c_uv = { 1, 1 }, .colour = 0xFFFFFFFF }
 };
 
-mesh_t mesh =
-{
-    .vertices = NULL,
-    .faces = NULL,
-    .rotation = { 0, 0, 0 },
-    .scale = { 1, 1, 1 },
-    .translation = { 0, 0, 0 },
-};
-
-void loadCubeMeshData()
+void loadCubeMeshData(mesh_t *mesh)
 {
     int i;
 
-    meshFree();
+    meshFree(mesh);
 
     for(i = 0; i < N_CUBE_VERTICES; i++)
     {
-        arrayAdd(mesh.vertices, cubeVertices[i]);
+        arrayAdd(mesh->vertices, cubeVertices[i]);
     }
     for(i = 0; i < N_CUBE_FACES; i++)
     {
-        arrayAdd(mesh.faces, cubeFaces[i]);
+        arrayAdd(mesh->faces, cubeFaces[i]);
     }
 
-    mesh.rotation.x = 0;
-    mesh.rotation.y = 0;
-    mesh.rotation.z = 0;
+    mesh->rotation.x = 0;
+    mesh->rotation.y = 0;
+    mesh->rotation.z = 0;
 }
 
-void meshFree()
+void meshFree(mesh_t *mesh)
 {
-    arrayEmpty(mesh.normalVertices);
-    arrayEmpty(mesh.textureVertices);
-    arrayFree(mesh.faces);
-    arrayFree(mesh.vertices);
+    arrayEmpty(mesh->normalVertices);
+    arrayEmpty(mesh->textureVertices);
+    arrayFree(mesh->faces);
+    arrayFree(mesh->vertices);
 }
 
 /***********************************************************************************************************************
@@ -99,10 +88,10 @@ void meshFree()
  **********************************************************************************************************************/
 
 /* Function used to load OBJ files */
-static int objFileLoaderParser(const char *content);
-static void objFileLoaderLineParser(char *line, uint32_t currentLine);
-static int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine);
-static void updateFaceUVValues();
+static int objFileLoaderParser(mesh_t *mesh, const char *content);
+static void objFileLoaderLineParser(mesh_t *mesh, char *line, uint32_t currentLine);
+static int objFileLoaderExecuteLine(mesh_t *mesh, int argc, char *argv[], uint32_t currentLine);
+static void updateFaceUVValues(mesh_t *mesh);
 
 static uint32_t objFileLoaderIgnoredLines = 0;
 static uint32_t objFileLoaderLoadedVertices = 0;
@@ -111,28 +100,28 @@ static uint32_t objFileLoaderLoadedVerticesTexture = 0;
 static uint32_t objFileLoaderLoadedFaces = 0;
 static uint32_t objFileLoaderTotalTri = 0;
 
-static void updateFaceUVValues()
+static void updateFaceUVValues(mesh_t *mesh)
 {
     uint32_t i;
-    uint32_t faceCount = arrayGetSize(mesh.faces);
+    uint32_t faceCount = arrayGetSize(mesh->faces);
 
-    if (arrayGetSize(mesh.textureVertices) > 0)
+    if (arrayGetSize(mesh->textureVertices) > 0)
     {
         for (i = 0 ; i < faceCount ; i++)
         {
-            face_t *face = &mesh.faces[i];
-
-            face->a_uv.u = mesh.textureVertices[face->at].u;
-            face->a_uv.v = mesh.textureVertices[face->at].v;
-            face->b_uv.u = mesh.textureVertices[face->bt].u;
-            face->b_uv.v = mesh.textureVertices[face->bt].v;
-            face->c_uv.u = mesh.textureVertices[face->ct].u;
-            face->c_uv.v = mesh.textureVertices[face->ct].v;
+            face_t *face = &mesh->faces[i];
+
+            face->a_uv.u = mesh->textureVertices[face->at].u;
+            face->a_uv.v = mesh->textureVertices[face->at].v;
+            face->b_uv.u = mesh->textureVertices[face->bt].u;
+            face->b_uv.v = mesh->textureVertices[face->bt].v;
+            face->c_uv.u = mesh->textureVertices[face->ct].u;
+            face->c_uv.v = mesh->textureVertices[face->ct].v;
         }
     }
 }
 
-void loadOBJFile(const char *filepath)
+void loadOBJFile(mesh_t *mesh, const char *filepath)
 {
     FILE *fp;
     size_t fileSize;
@@ -155,9 +144,14 @@ void loadOBJFile(const char *filepath)
         objFileLoaderLoadedFaces = 0;
         objFileLoaderTotalTri = 0;
 
-        meshFree();
+        meshFree(mesh);
+
+        /* Set some default values */
+        mesh->rotation = vec3(0, 0, 0 );
+        mesh->scale = vec3(1, 1, 1 );
+        mesh->translation = vec3(0, 0, 0 );
 
-        if (objFileLoaderParser(fileBuff))
+        if (objFileLoaderParser(mesh, fileBuff))
         {
             Log(TLOG_ERROR, "OBJLoader", "Errors occurred while opening the file '%s'.", filepath);
         }
@@ -172,7 +166,7 @@ void loadOBJFile(const char *filepath)
 
         free(fileBuff);
 
-        updateFaceUVValues();
+        updateFaceUVValues(mesh);
     }
     else
     {
@@ -182,7 +176,7 @@ void loadOBJFile(const char *filepath)
 
 #define MAX_LINE_LENGTH (512)
 /* Here start the fun! */
-static int objFileLoaderParser(const char *content)
+static int objFileLoaderParser(mesh_t *mesh, const char *content)
 {
     /* I don't think we will handle lines of more than 512 characters... */
     char lineBuff[MAX_LINE_LENGTH];
@@ -212,7 +206,7 @@ static int objFileLoaderParser(const char *content)
         memset(lineBuff, 0, MAX_LINE_LENGTH);
         strncpy(lineBuff, bufferPos, lineLength);
 
-        objFileLoaderLineParser(lineBuff, currentLineNum);
+        objFileLoaderLineParser(mesh, lineBuff, currentLineNum);
 
         bufferPos += lineLength + 1;
 
@@ -228,7 +222,7 @@ static int objFileLoaderParser(const char *content)
 
 #define MAX_ARGS (15)
 /* Parse the line into a couple ofr argc/argv using space as argument separator */
-static void objFileLoaderLineParser(char *line, uint32_t currentLine)
+static void objFileLoaderLineParser(mesh_t *mesh, char *line, uint32_t currentLine)
 {
     char *argv[MAX_ARGS];
     uint32_t argc = 0;
@@ -260,13 +254,13 @@ static void objFileLoaderLineParser(char *line, uint32_t currentLine)
         }
     }
 
-    if (objFileLoaderExecuteLine(argc, argv, currentLine))
+    if (objFileLoaderExecuteLine(mesh, argc, argv, currentLine))
     {
         objFileLoaderIgnoredLines++;
     }
 }
 
-static int objFileLoaderParseFaceVertex(char *buf, uint32_t *v, uint32_t  *vt, uint32_t  *vn)
+static int objFileLoaderParseFaceVertex(mesh_t *mesh, char *buf, uint32_t *v, uint32_t  *vt, uint32_t  *vn)
 {
     uint32_t bufPos = 0;
     uint32_t lineLength = strlen(buf);
@@ -309,7 +303,7 @@ static int objFileLoaderParseFaceVertex(char *buf, uint32_t *v, uint32_t  *vt, u
 }
 
 /* Actually execute the line */
-int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
+int objFileLoaderExecuteLine(mesh_t *mesh, int argc, char *argv[], uint32_t currentLine)
 {
     int ret = 1;
     if (strncmp(argv[0], "v", 2) == 0)
@@ -322,7 +316,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
         else
         {
             vec3_t vertex = { atof(argv[1]), atof(argv[2]), atof(argv[3]) };
-            arrayAdd(mesh.vertices, vertex);
+            arrayAdd(mesh->vertices, vertex);
             objFileLoaderLoadedVertices++;
             ret = 0;
         }
@@ -337,7 +331,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
         else
         {
             vec3_t vertex = { atof(argv[1]), atof(argv[2]), atof(argv[3]) };
-            arrayAdd(mesh.normalVertices, vertex);
+            arrayAdd(mesh->normalVertices, vertex);
             objFileLoaderLoadedVerticesNormal++;
             ret = 0;
         }
@@ -352,7 +346,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
         else
         {
             tex2_t vertex = { atof(argv[1]), atof(argv[2]) };
-            arrayAdd(mesh.textureVertices, vertex);
+            arrayAdd(mesh->textureVertices, vertex);
             objFileLoaderLoadedVerticesTexture++;
             ret = 0;
         }
@@ -364,7 +358,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
         uint32_t v[MAX_ARGS], vt[MAX_ARGS], vn[MAX_ARGS];
         for(i = 1; i < argc; i++)
         {
-            objFileLoaderParseFaceVertex(argv[i], &v[i], &vt[i], &vn[i]);
+            objFileLoaderParseFaceVertex(mesh, argv[i], &v[i], &vt[i], &vn[i]);
         }
 
         if (argc == 4)
@@ -378,7 +372,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
                 .at = vt[1] - 1 , .bt = vt[2] - 1, .ct = vt[3] - 1,
                 .colour = MAKE_RGB(45, 170, 10)
             };
-            arrayAdd(mesh.faces, face);
+            arrayAdd(mesh->faces, face);
             ret = 0;
         }
         else if (argc > 4)
@@ -391,7 +385,7 @@ int objFileLoaderExecuteLine(int argc, char *argv[], uint32_t currentLine)
                     .a = v[1] - 1, .b = v[i] - 1, .c = v[i + 1] - 1,
                     .at = vt[1] - 1, .bt = vt[i] - 1, .ct = vt[i + 1] - 1,
                     .colour = MAKE_RGB(45, 170, 10) };
-                arrayAdd(mesh.faces, face);
+                arrayAdd(mesh->faces, face);
 
                 objFileLoaderTotalTri++;
             }

+ 16 - 26
source/texture.c

@@ -12,51 +12,41 @@
 #include <texture.h>
 #include <display.h>
 
-/***********************************************************************************************************************
- * Global variables
- **********************************************************************************************************************/
-
-colour_t *meshTexture = NULL;
-upng_t *pngTexture = NULL;
-
-int textureWidth = 64;
-int textureHeight = 64;
-
 /***********************************************************************************************************************
  * Public functions
  **********************************************************************************************************************/
 
-void loadTextureDateFromPng(const char *filepath)
+void loadTextureDateFromPng(texture_t *tex, const char *filepath)
 {
-    if (pngTexture != NULL)
+    if (tex->png != NULL)
     {
-        upng_free(pngTexture);
-        pngTexture = NULL;
+        upng_free(tex->png);
+        tex->png = NULL;
     }
 
-    pngTexture = upng_new_from_file(filepath);
-    if (pngTexture != NULL)
+    tex->png = upng_new_from_file(filepath);
+    if (tex->png != NULL)
     {
-        upng_decode(pngTexture);
-        if (upng_get_error(pngTexture)  == UPNG_EOK)
+        upng_decode(tex->png);
+        if (upng_get_error(tex->png)  == UPNG_EOK)
         {
-            meshTexture = (colour_t *)upng_get_buffer(pngTexture);
-            textureWidth = upng_get_width(pngTexture);
-            textureHeight = upng_get_height(pngTexture);
+            tex->data = (colour_t *)upng_get_buffer(tex->png);
+            tex->width = upng_get_width(tex->png);
+            tex->height = upng_get_height(tex->png);
         }
     }
 }
 
-void textureCleanup(v)
+void textureCleanup(texture_t *tex)
 {
-    if (pngTexture != NULL)
+    if (tex->png != NULL)
     {
-        upng_free(pngTexture);
-        pngTexture = NULL;
+        upng_free(tex->png);
+        tex->png = NULL;
     }
 
     /* uPNG do free the buffer for us. */
-    meshTexture = NULL;
+    tex->data = NULL;
 }
 
 /***********************************************************************************************************************

+ 1 - 118
source/triangle.c

@@ -10,34 +10,11 @@
 #include <stdint.h>
 #include <stdbool.h>
 
+#include <3dengine.h>
 #include <display.h>
 #include <triangle.h>
 #include <math.h>
 
-bool doPerpectiveCorrection = true;
-
-static vec3_t barycentricWeights(vec2_t a, vec2_t b, vec2_t c, vec2_t p)
-{
-    vec2_t ab = vec2SubVectors(b, a);
-    vec2_t bc = vec2SubVectors(c, b);
-    vec2_t ac = vec2SubVectors(c, a);
-    vec2_t ap = vec2SubVectors(p, a);
-    vec2_t bp = vec2SubVectors(p, b);
-    vec3_t ret;
-
-    double areaTriangleABC = (ab.x * ac.y) - (ab.y * ac.x);
-
-    double alpha = ((bc.x * bp.y) - (bp.x * bc.y)) / areaTriangleABC;
-    double beta = ((ap.x * ac.y) - (ac.x * ap.y)) / areaTriangleABC;
-    double gamma = 1 - alpha - beta;
-
-    ret.x = alpha;
-    ret.y = beta;
-    ret.z = gamma;
-
-    return ret;
-}
-
 void drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, colour_t colour)
 {
     drawLine(x0, y0, x1, y1, colour);
@@ -46,38 +23,6 @@ void drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, in
 }
 
 /* ----------------------------------- Filled triangles ----------------------------------- */
-static void drawZPixel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, colour_t colour)
-{
-    vec2_t pointP = { x, y };
-    vec2_t a2 = vec2FromVec4(a);
-    vec2_t b2 = vec2FromVec4(b);
-    vec2_t c2 = vec2FromVec4(c);
-
-    if ((x < 0) || (y < 0) || (x > windowWidth) ||(y > windowHeight))
-    {
-        return;
-    }
-
-    vec3_t weights = barycentricWeights(a2, b2, c2, pointP);
-
-    double alpha = weights.x;
-    double beta = weights.y;
-    double gamma = weights.z;
-    double interpolatedReciprocalW;
-
-    interpolatedReciprocalW = (1 / a.w) * alpha + (1 / b.w) * beta + (1 / c.w) * gamma;
-
-    /* Inverse to get logical W invrementing going further to us */
-    interpolatedReciprocalW = 1 - interpolatedReciprocalW;
-    if (interpolatedReciprocalW < zBuffer[(windowWidth * y) + x])
-    {
-        drawPixel(x, y, colour);
-
-        /* Update Z Buffer */
-        zBuffer[(windowWidth * y) + x] = interpolatedReciprocalW;
-    }
-}
-
 void drawFilledTriangle(struct triangle_t *t)
 {
     int32_t x, y;
@@ -169,68 +114,6 @@ void drawFilledTriangle(struct triangle_t *t)
 }
 
 /* ----------------------------------- Textured triangles ----------------------------------- */
-static void drawTexel(int32_t x, int32_t y, vec4_t a, vec4_t b, vec4_t c, tex2_t ta, tex2_t tb, tex2_t tc, colour_t *texture)
-{
-    vec2_t pointP = { x, y };
-    vec2_t a2 = vec2FromVec4(a);
-    vec2_t b2 = vec2FromVec4(b);
-    vec2_t c2 = vec2FromVec4(c);
-
-    if ((x < 0) || (y < 0) || (x > windowWidth) ||(y > windowHeight))
-    {
-        return;
-    }
-
-    vec3_t weights = barycentricWeights(a2, b2, c2, pointP);
-
-    double alpha = weights.x;
-    double beta = weights.y;
-    double gamma = weights.z;
-    double interpolatedU, interpolatedV, interpolatedReciprocalW;
-    int32_t texX, texY;
-
-    interpolatedReciprocalW = (1 / a.w) * alpha + (1 / b.w) * beta + (1 / c.w) * gamma;
-
-    if (doPerpectiveCorrection)
-    {
-        interpolatedU = (ta.u / a.w) * alpha + (tb.u / b.w) * beta + (tc.u / c.w) * gamma;
-        interpolatedV = ((1 - ta.v) / a.w) * alpha + ((1 - tb.v) / b.w) * beta + ((1 - tc.v) / c.w) * gamma;
-
-
-        interpolatedU /= interpolatedReciprocalW;
-        interpolatedV /= interpolatedReciprocalW;
-    }
-    else
-    {
-        interpolatedU = ta.u * alpha + tb.u * beta + tc.u * gamma;
-        interpolatedV = (1 - ta.v) * alpha + (1 - tb.v) * beta + (1 - tc.v) * gamma;
-    }
-
-    texX = abs((int32_t)(interpolatedU * textureWidth));
-    texY = abs((int32_t)(interpolatedV * textureHeight));
-
-    texX = texX % textureWidth;
-    texY = texY % textureWidth;
-
-    if (doZBuffer)
-    {
-        /* Inverse to get logical W invrementing going further to us */
-        interpolatedReciprocalW = 1 - interpolatedReciprocalW;
-        if (interpolatedReciprocalW < zBuffer[(windowWidth * y) + x])
-        {
-            drawPixel(x, y, texture[(texY * textureWidth) + texX]);
-
-            /* Update Z Buffer */
-            zBuffer[(windowWidth * y) + x] = interpolatedReciprocalW;
-        }
-    }
-    else
-    {
-        drawPixel(x, y, texture[(texY * textureWidth) + texX]);
-    }
-}
-
-
 void drawTextureTriangle(struct triangle_t *t)
 {
     int32_t x, y;