|
@@ -9,6 +9,7 @@
|
|
|
|
|
|
#include <display.h>
|
|
|
#include <triangle.h>
|
|
|
+#include <math.h>
|
|
|
|
|
|
void drawTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t x2, int32_t y2, colour_t colour)
|
|
|
{
|
|
@@ -109,6 +110,51 @@ void drawFilledTriangle(int32_t x0, int32_t y0, int32_t x1, int32_t y1, int32_t
|
|
|
}
|
|
|
|
|
|
/* ----------------------------------- Textured triangles ----------------------------------- */
|
|
|
+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;
|
|
|
+}
|
|
|
+
|
|
|
+static void drawTexel(int32_t x, int32_t y, vec2_t a, vec2_t b, vec2_t c, tex2_t ta, tex2_t tb, tex2_t tc, uint32_t *texture)
|
|
|
+{
|
|
|
+ vec2_t pointP = { x, y };
|
|
|
+ vec3_t weights = barycentricWeights(a, b, c, pointP);
|
|
|
+
|
|
|
+ double alpha = weights.x;
|
|
|
+ double beta = weights.y;
|
|
|
+ double gamma = weights.z;
|
|
|
+ double interpolatedU, interpolatedV;
|
|
|
+ int32_t texX, texY;
|
|
|
+
|
|
|
+ interpolatedU = ta.u * alpha + tb.u * beta + tc.u * gamma;
|
|
|
+ interpolatedV = ta.v * alpha + tb.v * beta + tc.v * gamma;
|
|
|
+
|
|
|
+ texX = abs((int32_t)(interpolatedU * textureWidth));
|
|
|
+ texY = abs((int32_t)(interpolatedV * textureHeight));
|
|
|
+
|
|
|
+ texX = texX % textureWidth;
|
|
|
+ texY = texY % textureWidth;
|
|
|
+
|
|
|
+ drawPixel(x, y, texture[(texY * textureWidth) + texX]);
|
|
|
+}
|
|
|
+
|
|
|
|
|
|
void drawTextureTriangle(struct triangle_t *t)
|
|
|
{
|
|
@@ -133,12 +179,16 @@ void drawTextureTriangle(struct triangle_t *t)
|
|
|
doubleSwap(&t->textureCoordinates[0].v, &t->textureCoordinates[1].v);
|
|
|
}
|
|
|
|
|
|
+ vec2_t a = t->points[0];
|
|
|
+ vec2_t b = t->points[1];
|
|
|
+ vec2_t c = t->points[2];
|
|
|
+
|
|
|
/* Render the top part */
|
|
|
double inverseSlope1 = 0;
|
|
|
double inverseSlope2 = 0;
|
|
|
- int32_t x0 = t->points[0].x, y0 = t->points[0].y;
|
|
|
- int32_t x1 = t->points[1].x, y1 = t->points[1].y;
|
|
|
- int32_t x2 = t->points[2].x, y2 = t->points[2].y;
|
|
|
+ int32_t x0 = a.x, y0 = a.y;
|
|
|
+ int32_t x1 = b.x, y1 = b.y;
|
|
|
+ int32_t x2 = c.x, y2 = c.y;
|
|
|
|
|
|
if ((y1 - y0) != 0) { inverseSlope1 = (double)(x1 - x0) / abs(y1 - y0); }
|
|
|
if ((y2 - y0) != 0) { inverseSlope2 = (double)(x2 - x0) / abs(y2 - y0); }
|
|
@@ -157,7 +207,11 @@ void drawTextureTriangle(struct triangle_t *t)
|
|
|
|
|
|
for (x = xStart ; x <= xEnd ; x++)
|
|
|
{
|
|
|
- drawPixel(x, y, (x%2 == 0)?0xFFFF00FF:0xFF000000);
|
|
|
+ drawTexel(x, y, a, b, c,
|
|
|
+ t->textureCoordinates[0],
|
|
|
+ t->textureCoordinates[1],
|
|
|
+ t->textureCoordinates[2],
|
|
|
+ t->texture);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -180,7 +234,11 @@ void drawTextureTriangle(struct triangle_t *t)
|
|
|
|
|
|
for (x = xStart ; x <= xEnd ; x++)
|
|
|
{
|
|
|
- drawPixel(x, y, (x%2 == 0)?0xFFFF00FF:0xFF000000);
|
|
|
+ drawTexel(x, y, a, b, c,
|
|
|
+ t->textureCoordinates[0],
|
|
|
+ t->textureCoordinates[1],
|
|
|
+ t->textureCoordinates[2],
|
|
|
+ t->texture);
|
|
|
}
|
|
|
}
|
|
|
}
|