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
** 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
*** 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

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
// being the bottom "spike"
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--) {
if (0 <= scanline && scanline < RENDERHEIGHT) {
Vector3 f1baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0), 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");
}
}
DrawScanline(zee, tp, curx1, curx2, scanline);
}
curx1 -= atocslopeinv; // subtract because we are working backwards (reason
// why we start with point c in slope equtn)
curx2 -= btocslopinv;
}
}
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,
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
// for y, not just x to get depth
if (0 <= scanline && scanline < RENDERHEIGHT) {
Vector3 f1baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){Max(curx1, 0), 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");
}
}
}
DrawScanline(zee, tp, curx1, curx2, scanline);
}
curx1 += atobslopeinv;
curx2 += atocslopeinv;
}
@ -483,16 +472,6 @@ int main() {
float frametime = GetFrameTime();
CtrlLocalCam(&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;
Tri2Darr.length = 0;
@ -515,21 +494,6 @@ int main() {
for (int i = 0; i < RENDERHEIGHT * RENDERWIDTH; i++) {
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++) {
DrawTriZuff(ZBuff, &Tri2Darr.arr[i]);
@ -555,13 +519,13 @@ int main() {
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);
display[index] = ZBuff[IndexOfZBuff(x, y)].triangle->color;
display[index] = ZBuff[IndexOfZBuff(x, y)].c;
// Zee test = ZBuff[IndexOfZBuff(x,y)];
// display[index] = test.triangle->color;
}
//}
index = index + 1;
}
}

View file

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