further optomizations and unified scanline draw

This commit is contained in:
InventorXtreme 2024-03-12 12:55:07 -04:00
parent ef6fb628b5
commit 129c84d43e
3 changed files with 43 additions and 77 deletions

View file

@ -1,6 +1,8 @@
* TODOS * TODOS
** HIGH ** HIGH
*** TODO MAKE BOTH TRI RENDERERS SHARE A FUNCTION FOR ACTUALLY WRITING THE POINT, instead of having copy pasted code *** DONE MAKE BOTH TRI RENDERERS SHARE A FUNCTION FOR ACTUALLY WRITING THE POINT, instead of having copy pasted code
*** Have DrawScanline() draw directly to the output buffer, not just zbuffer (will speed up becaue no final copy)
** MED ** MED
*** TODO Cull tris outside of view range after they are transformed before considering the zbuffer *** TODO Cull tris outside of view range after they are transformed before considering the zbuffer
*** We might be able to do the slope optimization with both x and y
** LOW ** LOW

114
c3d.c
View file

@ -118,6 +118,36 @@ void Tri2DSortByY(Tri2D *t) {
} }
} }
void DrawScanline(Zee * zee, Tri2D * trianglepointer, double start, double end, int scanline) {
Vector3 f1baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0), scanline});
float f1depth = DepthAtBary(trianglepointer, f1baryatpoint);
Vector3 f1baryatpoint2 = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0) + 1, scanline});
float f1depth2 = DepthAtBary(trianglepointer, f1baryatpoint2);
float dslope = f1depth2 - f1depth;
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;
}
}
}
// Draws triangle with a flat top. Note A and B must be the top points with C // Draws triangle with a flat top. Note A and B must be the top points with C
// being the bottom "spike" // being the bottom "spike"
void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
@ -141,35 +171,16 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
for (int scanline = t->c.y; scanline >= t->a.y; scanline--) { for (int scanline = t->c.y; scanline >= t->a.y; scanline--) {
if (0 <= scanline && scanline < RENDERHEIGHT) { if (0 <= scanline && scanline < RENDERHEIGHT) {
Vector3 f1baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0), scanline}); DrawScanline(zee, tp, curx1, curx2, scanline);
float f1depth = DepthAtBary(tp, f1baryatpoint);
Vector3 f1baryatpoint2 = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0) + 1, scanline});
float f1depth2 = DepthAtBary(tp, f1baryatpoint2);
float dslope = f1depth2 - f1depth;
for (int i = Max(curx1, 0); i < Min(curx2, 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(curx1, 0))));
if (aproxdepth > zee[IndexOfZBuff(i, scanline)].depth) {
zee[IndexOfZBuff(i, scanline)].triangle = tp;
zee[IndexOfZBuff(i, scanline)].depth = aproxdepth;
// printf("here\n");
}
}
} }
curx1 -= atocslopeinv; // subtract because we are working backwards (reason curx1 -= atocslopeinv; // subtract because we are working backwards (reason
// why we start with point c in slope equtn) // why we start with point c in slope equtn)
curx2 -= btocslopinv; curx2 -= btocslopinv;
} }
} }
void PrintTri2D(Tri2D t) { void PrintTri2D(Tri2D t) {
printf("{(TRI2D) A: (%f, %f), B: (%f, %f), C:(%f,%f) }\n ", t.a.x, t.a.y, t.b.x, t.b.y, t.c.x, printf("{(TRI2D) A: (%f, %f), B: (%f, %f), C:(%f,%f) }\n ", t.a.x, t.a.y, t.b.x, t.b.y, t.c.x,
t.c.y); t.c.y);
@ -199,30 +210,8 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
scanline++) { // TODO: Possibly more optimization possible here, use linear correspondance scanline++) { // TODO: Possibly more optimization possible here, use linear correspondance
// for y, not just x to get depth // for y, not just x to get depth
if (0 <= scanline && scanline < RENDERHEIGHT) { if (0 <= scanline && scanline < RENDERHEIGHT) {
Vector3 f1baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0), scanline}); DrawScanline(zee, tp, curx1, curx2, scanline);
float f1depth = DepthAtBary(tp, f1baryatpoint); }
Vector3 f1baryatpoint2 = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0) + 1, scanline});
float f1depth2 = DepthAtBary(tp, f1baryatpoint2);
float dslope = f1depth2 - f1depth;
for (int i = Max(curx1, 0); i < Min(curx2, 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(curx1, 0))));
if (aproxdepth > zee[IndexOfZBuff(i, scanline)].depth) {
zee[IndexOfZBuff(i, scanline)].triangle = tp;
zee[IndexOfZBuff(i, scanline)].depth = aproxdepth;
// printf("here\n");
}
}
}
curx1 += atobslopeinv; curx1 += atobslopeinv;
curx2 += atocslopeinv; curx2 += atocslopeinv;
} }
@ -483,16 +472,6 @@ int main() {
float frametime = GetFrameTime(); float frametime = GetFrameTime();
CtrlLocalCam(&camera, frametime); CtrlLocalCam(&camera, frametime);
LocalCamApplyVelo(&camera, frametime); LocalCamApplyVelo(&camera, frametime);
// ClearBackground(BLACK);
/* Vector3 TransVector = TransformWithCam(point,&camera); */
/* if (TransVector.z < 0) { */
/* Vector2 MPos = Conv3Dto2D(TransVector); */
/* Vector2 FinPos = Conv2DCenteredToScreen(MPos); */
/* DrawCircleV(FinPos,100,BLACK); */
/* } */
/* EndTextureMode(); */
TransformedTris.length = 0; TransformedTris.length = 0;
Tri2Darr.length = 0; Tri2Darr.length = 0;
@ -515,21 +494,6 @@ int main() {
for (int i = 0; i < RENDERHEIGHT * RENDERWIDTH; i++) { for (int i = 0; i < RENDERHEIGHT * RENDERWIDTH; i++) {
ZBuff[i].depth = -10000000; ZBuff[i].depth = -10000000;
} }
/* for (int y = 0; y < RENDERHEIGHT; y++){ */
/* for (int x = 0; x<RENDERWIDTH; x++){ */
/* ZBuff[x][y].triangle = &blank; */
/* } */
/* } */
/* for (int i = 0; i < Tri2Darr.length; i++) { */
/* for (int y = 0; y < RENDERHEIGHT; y++) { */
/* for (int x = 0; x < RENDERWIDTH; x++) { */
/* if (IsInTri(Tri2Darr.arr[i], (Vector2){x, y})) { */
/* ZBuff[IndexOfZBuff(x, y)].triangle = &Tri2Darr.arr[i]; */
/* } */
/* } */
/* } */
/* } */
for (int i = 0; i < Tri2Darr.length; i++) { for (int i = 0; i < Tri2Darr.length; i++) {
DrawTriZuff(ZBuff, &Tri2Darr.arr[i]); DrawTriZuff(ZBuff, &Tri2Darr.arr[i]);
@ -555,13 +519,13 @@ int main() {
display[index+3] = c->a; display[index+3] = c->a;
*/ */
if (ZBuff[IndexOfZBuff(x, y)].triangle != 0) { // memset sets this to 0 //if (ZBuff[IndexOfZBuff(x, y)].triangle != 0 ) { // memset sets this to 0
// DrawPixel(x,y,ZBuff[x][y].triangle->color); // DrawPixel(x,y,ZBuff[x][y].triangle->color);
display[index] = ZBuff[IndexOfZBuff(x, y)].triangle->color; display[index] = ZBuff[IndexOfZBuff(x, y)].c;
// Zee test = ZBuff[IndexOfZBuff(x,y)]; // Zee test = ZBuff[IndexOfZBuff(x,y)];
// display[index] = test.triangle->color; // display[index] = test.triangle->color;
} //}
index = index + 1; index = index + 1;
} }
} }

View file

@ -40,7 +40,7 @@ typedef struct Tri2D Tri2D;
struct Zee { struct Zee {
int depth; int depth;
Tri2D *triangle; Color c;
}; };
typedef struct Zee Zee; typedef struct Zee Zee;