|
@@ -7,10 +7,15 @@
|
|
|
* Created by Manoël Trapier on 04/03/2021.
|
|
|
*/
|
|
|
|
|
|
+#include <stdint.h>
|
|
|
+#include <stdbool.h>
|
|
|
+
|
|
|
#include <display.h>
|
|
|
#include <triangle.h>
|
|
|
#include <math.h>
|
|
|
|
|
|
+bool doPerpectiveCorrection = true;
|
|
|
+
|
|
|
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);
|
|
@@ -132,10 +137,14 @@ static vec3_t barycentricWeights(vec2_t a, vec2_t b, vec2_t c, vec2_t p)
|
|
|
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)
|
|
|
+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 };
|
|
|
- vec3_t weights = barycentricWeights(a, b, c, pointP);
|
|
|
+ vec2_t a2 = vec2FromVec4(a);
|
|
|
+ vec2_t b2 = vec2FromVec4(b);
|
|
|
+ vec2_t c2 = vec2FromVec4(c);
|
|
|
+
|
|
|
+ vec3_t weights = barycentricWeights(a2, b2, c2, pointP);
|
|
|
|
|
|
double alpha = weights.x;
|
|
|
double beta = weights.y;
|
|
@@ -143,8 +152,22 @@ static void drawTexel(int32_t x, int32_t y, vec2_t a, vec2_t b, vec2_t c, tex2_t
|
|
|
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;
|
|
|
+ if (doPerpectiveCorrection)
|
|
|
+ {
|
|
|
+ double interpolatedReciprocalW;
|
|
|
+
|
|
|
+ interpolatedU = (ta.u / a.w) * alpha + (tb.u / b.w) * beta + (tc.u / c.w) * gamma;
|
|
|
+ interpolatedV = (ta.v / a.w) * alpha + (tb.v / b.w) * beta + (tc.v / c.w) * gamma;
|
|
|
+ interpolatedReciprocalW = (1 / a.w) * alpha + (1 / b.w) * beta + (1 / c.w) * gamma;
|
|
|
+
|
|
|
+ interpolatedU /= interpolatedReciprocalW;
|
|
|
+ interpolatedV /= interpolatedReciprocalW;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ 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));
|
|
@@ -163,25 +186,28 @@ void drawTextureTriangle(struct triangle_t *t)
|
|
|
if (t->points[0].y > t->points[1].y)
|
|
|
{
|
|
|
doubleSwap(&t->points[0].x, &t->points[1].x); doubleSwap(&t->points[0].y, &t->points[1].y);
|
|
|
+ doubleSwap(&t->points[0].z, &t->points[1].z); doubleSwap(&t->points[0].w, &t->points[1].w);
|
|
|
doubleSwap(&t->textureCoordinates[0].u, &t->textureCoordinates[1].u);
|
|
|
doubleSwap(&t->textureCoordinates[0].v, &t->textureCoordinates[1].v);
|
|
|
}
|
|
|
if (t->points[1].y > t->points[2].y)
|
|
|
{
|
|
|
doubleSwap(&t->points[1].x, &t->points[2].x); doubleSwap(&t->points[1].y, &t->points[2].y);
|
|
|
+ doubleSwap(&t->points[1].z, &t->points[2].z); doubleSwap(&t->points[1].w, &t->points[2].w);
|
|
|
doubleSwap(&t->textureCoordinates[1].u, &t->textureCoordinates[2].u);
|
|
|
doubleSwap(&t->textureCoordinates[1].v, &t->textureCoordinates[2].v);
|
|
|
}
|
|
|
if (t->points[0].y > t->points[1].y)
|
|
|
{
|
|
|
doubleSwap(&t->points[0].x, &t->points[1].x); doubleSwap(&t->points[0].y, &t->points[1].y);
|
|
|
+ doubleSwap(&t->points[0].z, &t->points[1].z); doubleSwap(&t->points[0].w, &t->points[1].w);
|
|
|
doubleSwap(&t->textureCoordinates[0].u, &t->textureCoordinates[1].u);
|
|
|
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];
|
|
|
+ vec4_t a = t->points[0];
|
|
|
+ vec4_t b = t->points[1];
|
|
|
+ vec4_t c = t->points[2];
|
|
|
|
|
|
/* Render the top part */
|
|
|
double inverseSlope1 = 0;
|