From f6ee4b9c2a635b1434502b669687628667fb9af5 Mon Sep 17 00:00:00 2001 From: InventorXtreme Date: Tue, 12 Mar 2024 21:32:45 -0400 Subject: [PATCH] tri2d now use integers when put on screen. Fixes missing pixels and overdraw --- Makefile | 2 +- c3d.c | 101 +++++++++++++++++++++++++++++++---------------------- c3dtypes.h | 2 +- 3 files changed, 61 insertions(+), 44 deletions(-) diff --git a/Makefile b/Makefile index 1e4112f..8a8a46a 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = clang #Set compiler -CFLAGS = -pg -g -Wall -O3 -pg #set compiler flags +CFLAGS = -pg -g -Wall -O2 -pg #set compiler flags LDFLAGS = -pg -g #set linker flags LDLIBS = -lraylib -lm #set libraries to use objects = c3d.o reader.o arrayfuncs.o vecfunc.o #list all object files diff --git a/c3d.c b/c3d.c index 3362327..71dc040 100644 --- a/c3d.c +++ b/c3d.c @@ -71,6 +71,11 @@ Vector2 BaryAndTritoPoint(Tri2D *t, Vector3 bary) { return retvec; } +void Vector2Integate(Vector2 * v) { + v->x = (int) v->x; + v->y = (int) v->y; +} + static inline float DepthAtBary(Tri2D *t, Vector3 bary) { float firstrepz = 1 / t->adepth; float secondrepz = 1 / t->bdepth; @@ -128,18 +133,18 @@ void DrawScanline(Zee *zee, Tri2D *trianglepointer, double start, double end, in float f1depth2 = DepthAtBary(trianglepointer, f1baryatpoint2); float dslope = f1depth2 - f1depth; - for (int i = floor(Max(start, 0)); i <= ceil(Min(end, RENDERWIDTH)); i++) { + + for (int i = (Max(start, 0)); i < (Min(end, RENDERWIDTH)); i++) { /* zee[IndexOfZBuff(i, scanline)].triangle = tp; */ /* Vector3 baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){i, scanline}); */ /* float depth = DepthAtBary(tp, baryatpoint); */ float aproxdepth = f1depth + (dslope * ((float)i - (float)(Max(start, 0)))); - if (aproxdepth > zee[IndexOfZBuff(i, scanline)].depth) { zee[IndexOfZBuff(i, scanline)].c = trianglepointer->color; zee[IndexOfZBuff(i, scanline)].depth = aproxdepth; - zee[IndexOfZBuff(i, scanline)].tri = trianglepointer; + //zee[IndexOfZBuff(i, scanline)].tri = trianglepointer; } } } @@ -154,9 +159,9 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { } // Becasue we are trying to get the x values in terms of the y values, we // need inverse slope - float atocslopeinv = + double atocslopeinv = (t->c.x - t->a.x) / (t->c.y - t->a.y); // dif in x from start to end with a and c - float btocslopinv = + double btocslopinv = (t->c.x - t->b.x) / (t->c.y - t->b.y); // dif in x from start to end with b and c // start at bottom of triangle (point c) so that we do not need to determine @@ -164,13 +169,13 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { double curx1 = t->c.x; double curx2 = t->c.x; - int scanbottom = t->c.y; - int scantop = Max(t->a.y, 0); + int scanbottom = (t->c.y); + int scantop = (Max(t->a.y, 0)); - for (float scanline = scanbottom; scanline >= scantop; scanline--) { + + for (int scanline = scanbottom; scanline >= scantop; scanline--) { if (0 <= scanline && scanline < RENDERHEIGHT) { - //tp->color = RED; DrawScanline(zee, tp, curx1, curx2, scanline); } curx1 -= atocslopeinv; // subtract because we are working backwards (reason @@ -194,9 +199,9 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { } // Becasue we are trying to get the x values in terms of the y values, we // need inverse slope - float atobslopeinv = + double atobslopeinv = (t->b.x - t->a.x) / (t->b.y - t->a.y); // dif in x from start to end with a and c - float atocslopeinv = + double atocslopeinv = (t->c.x - t->a.x) / (t->c.y - t->a.y); // dif in x from start to end with b and c // start at top of triangle (point c) so that we do not need to determine @@ -204,27 +209,36 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { double curx1 = t->a.x; double curx2 = t->a.x; - int scantop = t->a.y; // start must always be the true beging of the triangle, otherwise - // everything will be offset + int scantop = (t->a.y); // start must always be the true beging of the triangle, otherwise + // everything will be offset int scanbottom = - Min(t->c.y, RENDERHEIGHT-1); // we can stop rendering as soon as it goes off screen + (Min(t->c.y, RENDERHEIGHT)); // we can stop rendering as soon as it goes off screen - for (int scanline = scantop; scanline <= scanbottom; scanline++) { // TODO: Possibly more optimization possible here, use linear correspondance // for y, not just x to get depth - if (0 <= scanline && scanline < RENDERHEIGHT) { + if (0 <= scanline && scanline < RENDERHEIGHT ) { Tri2D nt = *tp; nt.color = RED; - DrawScanline(zee, &nt, curx1, curx2, scanline); + + DrawScanline(zee, tp, curx1, curx2, scanline); } curx1 += atobslopeinv; curx2 += atocslopeinv; } } -void DrawTriZuff(Zee *zbuf, Tri2D *t) { +void DrawTriZuff(Zee *zbuf, Tri2D *tex ) { + Tri2D tt = *tex; + Tri2D * t = &tt; Tri2DSortByY(t); + Vector2Integate(&t->a); + Vector2Integate(&t->b); + Vector2Integate(&t->c); + + if ( (t->a.y > RENDERHEIGHT && t->c.y > RENDERHEIGHT) || (t->a.y < 0 && t->c.y < 0)) { + return; + } if (t->b.y == t->c.y) { // if bottom of triangle is flat FillBottomFlatZbuffer(zbuf, t, t); @@ -246,11 +260,15 @@ void DrawTriZuff(Zee *zbuf, Tri2D *t) { bottomflattrires.a = t->a; bottomflattrires.b = t->b; bottomflattrires.c = v4; + + + bottomflattrires.color = t->color; Tri2D topflattrires; topflattrires.a = t->b; topflattrires.b = v4; topflattrires.c = t->c; + topflattrires.color = t->color; FillBottomFlatZbuffer(zbuf, &bottomflattrires, t); @@ -431,11 +449,11 @@ int main() { TriArray tarr; tarr.arr = internaltriarray; tarr.length = 0; - /* TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -1000}, (Vector3){0, 800, -1000}, */ - /* (Vector3){800, 800, -1000}, WHITE}); */ + TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -1000}, (Vector3){0, 800, -1000}, + (Vector3){800, 800, -1000}, WHITE}); - /* TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -2000}, (Vector3){0, 800, -2000}, */ - /* (Vector3){800, 800, -2000}, BLUE}); */ + TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -2000}, (Vector3){0, 800, -2000}, + (Vector3){800, 800, -2000}, BLUE}); static Tri internaltransformedtriarray[50000]; TriArray TransformedTris; @@ -454,7 +472,7 @@ int main() { memset(display, 0, sizeof(display)); Tri2D funners = - (Tri2D){(Vector2){0, 0}, (Vector2){500, 0}, (Vector2){500, 500}, -1000, -1000, -1000, GREEN}; + (Tri2D){(Vector2){0, 0}, (Vector2){500, 0}, (Vector2){500, 1}, -1000, -1000, -1000, GREEN}; Tri2D funners2 = (Tri2D){(Vector2){600, 0}, (Vector2){600, 500}, (Vector2){1000, 500}, 0, 0, 0, RED}; @@ -469,16 +487,14 @@ int main() { bool run3d = true; - if (true) { - Object3D t = ReadObjectFromFile("cube.obj"); - for (int i = 0; i < t.triangles->length; i++) { - // printf("t: %f\n", t.triangles->arr[i].a.x); - TriArrayAppend(&tarr, t.triangles->arr[i]); + if (true) { + Object3D t = ReadObjectFromFile("teapot.obj"); + for (int i = 0; i < t.triangles->length; i++) { + // printf("t: %f\n", t.triangles->arr[i].a.x); + TriArrayAppend(&tarr, t.triangles->arr[i]); + } } - } - - while (!WindowShouldClose() && run3d) { float frametime = GetFrameTime(); CtrlLocalCam(&camera, frametime); @@ -510,14 +526,14 @@ int main() { DrawTriZuff(ZBuff, &Tri2Darr.arr[i]); } - if (IsKeyDown(KEY_H)) { - if (ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2 )].tri != 0) { - //ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->color = RED; - printf("%f\n", ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->a.x); - } - } + /* if (IsKeyDown(KEY_H)) { */ + /* if (ZBuff[IndexOfZBuff(RENDERWIDTH / 2, RENDERHEIGHT / 2)].tri != 0) { */ + /* // ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->color = RED; */ + /* printf("%f\n", ZBuff[IndexOfZBuff(RENDERWIDTH / 2, RENDERHEIGHT / 2)].tri->a.x); */ + /* } */ + /* } */ - //FillTopFlatZbuffer(ZBuff, &funners, &funners); + // FillTopFlatZbuffer(ZBuff, &funners, &funners); // FillBottomFlatZbuffer(ZBuff,&funners2); // FillTopFlatZbuffer(ZBuff, &fullscreentritop); @@ -530,10 +546,11 @@ int main() { for (int y = 0; y < RENDERHEIGHT; y++) { for (int x = 0; x < RENDERWIDTH; x++) { - //REMOVE THE IF AND REPALCE THE VALUE THAT DISPLAY IS SET TO WITH DIRECT COLOR WHEN DONE DEBUGGING - if (ZBuff[IndexOfZBuff(x, y)].tri != 0) { - display[index] = ZBuff[IndexOfZBuff(x, y)].tri->color; - } + // REMOVE THE IF AND REPALCE THE VALUE THAT DISPLAY IS SET TO WITH DIRECT COLOR WHEN + // DONE DEBUGGING + //if (ZBuff[IndexOfZBuff(x, y)].tri != 0) { + display[index] = ZBuff[IndexOfZBuff(x, y)].c; + //} index = index + 1; } } diff --git a/c3dtypes.h b/c3dtypes.h index 7f1ac28..9299ad6 100644 --- a/c3dtypes.h +++ b/c3dtypes.h @@ -40,7 +40,7 @@ typedef struct Tri2D Tri2D; struct Zee { int depth; - Tri2D * tri; + //Tri2D * tri; Color c; }; typedef struct Zee Zee;