tri2d now use integers when put on screen. Fixes missing pixels and overdraw
This commit is contained in:
parent
8165a5c760
commit
f6ee4b9c2a
2
Makefile
2
Makefile
|
@ -1,5 +1,5 @@
|
||||||
CC = clang #Set compiler
|
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
|
LDFLAGS = -pg -g #set linker flags
|
||||||
LDLIBS = -lraylib -lm #set libraries to use
|
LDLIBS = -lraylib -lm #set libraries to use
|
||||||
objects = c3d.o reader.o arrayfuncs.o vecfunc.o #list all object files
|
objects = c3d.o reader.o arrayfuncs.o vecfunc.o #list all object files
|
||||||
|
|
101
c3d.c
101
c3d.c
|
@ -71,6 +71,11 @@ Vector2 BaryAndTritoPoint(Tri2D *t, Vector3 bary) {
|
||||||
return retvec;
|
return retvec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Vector2Integate(Vector2 * v) {
|
||||||
|
v->x = (int) v->x;
|
||||||
|
v->y = (int) v->y;
|
||||||
|
}
|
||||||
|
|
||||||
static inline float DepthAtBary(Tri2D *t, Vector3 bary) {
|
static inline float DepthAtBary(Tri2D *t, Vector3 bary) {
|
||||||
float firstrepz = 1 / t->adepth;
|
float firstrepz = 1 / t->adepth;
|
||||||
float secondrepz = 1 / t->bdepth;
|
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 f1depth2 = DepthAtBary(trianglepointer, f1baryatpoint2);
|
||||||
float dslope = f1depth2 - f1depth;
|
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; */
|
/* zee[IndexOfZBuff(i, scanline)].triangle = tp; */
|
||||||
|
|
||||||
/* Vector3 baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){i, scanline}); */
|
/* Vector3 baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){i, scanline}); */
|
||||||
/* float depth = DepthAtBary(tp, baryatpoint); */
|
/* float depth = DepthAtBary(tp, baryatpoint); */
|
||||||
|
|
||||||
float aproxdepth = f1depth + (dslope * ((float)i - (float)(Max(start, 0))));
|
float aproxdepth = f1depth + (dslope * ((float)i - (float)(Max(start, 0))));
|
||||||
|
|
||||||
if (aproxdepth > zee[IndexOfZBuff(i, scanline)].depth) {
|
if (aproxdepth > zee[IndexOfZBuff(i, scanline)].depth) {
|
||||||
zee[IndexOfZBuff(i, scanline)].c = trianglepointer->color;
|
zee[IndexOfZBuff(i, scanline)].c = trianglepointer->color;
|
||||||
zee[IndexOfZBuff(i, scanline)].depth = aproxdepth;
|
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
|
// Becasue we are trying to get the x values in terms of the y values, we
|
||||||
// need inverse slope
|
// 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
|
(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
|
(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
|
// 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 curx1 = t->c.x;
|
||||||
double curx2 = t->c.x;
|
double curx2 = t->c.x;
|
||||||
|
|
||||||
int scanbottom = t->c.y;
|
int scanbottom = (t->c.y);
|
||||||
int scantop = Max(t->a.y, 0);
|
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) {
|
if (0 <= scanline && scanline < RENDERHEIGHT) {
|
||||||
//tp->color = RED;
|
|
||||||
DrawScanline(zee, tp, curx1, curx2, scanline);
|
DrawScanline(zee, tp, curx1, curx2, scanline);
|
||||||
}
|
}
|
||||||
curx1 -= atocslopeinv; // subtract because we are working backwards (reason
|
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
|
// Becasue we are trying to get the x values in terms of the y values, we
|
||||||
// need inverse slope
|
// 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
|
(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
|
(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
|
// 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 curx1 = t->a.x;
|
||||||
double curx2 = t->a.x;
|
double curx2 = t->a.x;
|
||||||
|
|
||||||
int scantop = t->a.y; // start must always be the true beging of the triangle, otherwise
|
int scantop = (t->a.y); // start must always be the true beging of the triangle, otherwise
|
||||||
// everything will be offset
|
// everything will be offset
|
||||||
int scanbottom =
|
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;
|
for (int scanline = scantop; scanline <= scanbottom;
|
||||||
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 ) {
|
||||||
Tri2D nt = *tp;
|
Tri2D nt = *tp;
|
||||||
nt.color = RED;
|
nt.color = RED;
|
||||||
DrawScanline(zee, &nt, curx1, curx2, scanline);
|
|
||||||
|
DrawScanline(zee, tp, curx1, curx2, scanline);
|
||||||
}
|
}
|
||||||
curx1 += atobslopeinv;
|
curx1 += atobslopeinv;
|
||||||
curx2 += atocslopeinv;
|
curx2 += atocslopeinv;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTriZuff(Zee *zbuf, Tri2D *t) {
|
void DrawTriZuff(Zee *zbuf, Tri2D *tex ) {
|
||||||
|
Tri2D tt = *tex;
|
||||||
|
Tri2D * t = &tt;
|
||||||
Tri2DSortByY(t);
|
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
|
if (t->b.y == t->c.y) { // if bottom of triangle is flat
|
||||||
FillBottomFlatZbuffer(zbuf, t, t);
|
FillBottomFlatZbuffer(zbuf, t, t);
|
||||||
|
@ -246,11 +260,15 @@ void DrawTriZuff(Zee *zbuf, Tri2D *t) {
|
||||||
bottomflattrires.a = t->a;
|
bottomflattrires.a = t->a;
|
||||||
bottomflattrires.b = t->b;
|
bottomflattrires.b = t->b;
|
||||||
bottomflattrires.c = v4;
|
bottomflattrires.c = v4;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
bottomflattrires.color = t->color;
|
bottomflattrires.color = t->color;
|
||||||
Tri2D topflattrires;
|
Tri2D topflattrires;
|
||||||
topflattrires.a = t->b;
|
topflattrires.a = t->b;
|
||||||
topflattrires.b = v4;
|
topflattrires.b = v4;
|
||||||
topflattrires.c = t->c;
|
topflattrires.c = t->c;
|
||||||
|
|
||||||
topflattrires.color = t->color;
|
topflattrires.color = t->color;
|
||||||
|
|
||||||
FillBottomFlatZbuffer(zbuf, &bottomflattrires, t);
|
FillBottomFlatZbuffer(zbuf, &bottomflattrires, t);
|
||||||
|
@ -431,11 +449,11 @@ int main() {
|
||||||
TriArray tarr;
|
TriArray tarr;
|
||||||
tarr.arr = internaltriarray;
|
tarr.arr = internaltriarray;
|
||||||
tarr.length = 0;
|
tarr.length = 0;
|
||||||
/* TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -1000}, (Vector3){0, 800, -1000}, */
|
TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -1000}, (Vector3){0, 800, -1000},
|
||||||
/* (Vector3){800, 800, -1000}, WHITE}); */
|
(Vector3){800, 800, -1000}, WHITE});
|
||||||
|
|
||||||
/* TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -2000}, (Vector3){0, 800, -2000}, */
|
TriArrayAppend(&tarr, (Tri){(Vector3){0, 0, -2000}, (Vector3){0, 800, -2000},
|
||||||
/* (Vector3){800, 800, -2000}, BLUE}); */
|
(Vector3){800, 800, -2000}, BLUE});
|
||||||
|
|
||||||
static Tri internaltransformedtriarray[50000];
|
static Tri internaltransformedtriarray[50000];
|
||||||
TriArray TransformedTris;
|
TriArray TransformedTris;
|
||||||
|
@ -454,7 +472,7 @@ int main() {
|
||||||
memset(display, 0, sizeof(display));
|
memset(display, 0, sizeof(display));
|
||||||
|
|
||||||
Tri2D funners =
|
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 funners2 =
|
||||||
(Tri2D){(Vector2){600, 0}, (Vector2){600, 500}, (Vector2){1000, 500}, 0, 0, 0, RED};
|
(Tri2D){(Vector2){600, 0}, (Vector2){600, 500}, (Vector2){1000, 500}, 0, 0, 0, RED};
|
||||||
|
|
||||||
|
@ -469,16 +487,14 @@ int main() {
|
||||||
|
|
||||||
bool run3d = true;
|
bool run3d = true;
|
||||||
|
|
||||||
if (true) {
|
if (true) {
|
||||||
Object3D t = ReadObjectFromFile("cube.obj");
|
Object3D t = ReadObjectFromFile("teapot.obj");
|
||||||
for (int i = 0; i < t.triangles->length; i++) {
|
for (int i = 0; i < t.triangles->length; i++) {
|
||||||
// printf("t: %f\n", t.triangles->arr[i].a.x);
|
// printf("t: %f\n", t.triangles->arr[i].a.x);
|
||||||
TriArrayAppend(&tarr, t.triangles->arr[i]);
|
TriArrayAppend(&tarr, t.triangles->arr[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
while (!WindowShouldClose() && run3d) {
|
while (!WindowShouldClose() && run3d) {
|
||||||
float frametime = GetFrameTime();
|
float frametime = GetFrameTime();
|
||||||
CtrlLocalCam(&camera, frametime);
|
CtrlLocalCam(&camera, frametime);
|
||||||
|
@ -510,14 +526,14 @@ int main() {
|
||||||
DrawTriZuff(ZBuff, &Tri2Darr.arr[i]);
|
DrawTriZuff(ZBuff, &Tri2Darr.arr[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsKeyDown(KEY_H)) {
|
/* if (IsKeyDown(KEY_H)) { */
|
||||||
if (ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2 )].tri != 0) {
|
/* if (ZBuff[IndexOfZBuff(RENDERWIDTH / 2, RENDERHEIGHT / 2)].tri != 0) { */
|
||||||
//ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->color = RED;
|
/* // ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->color = RED; */
|
||||||
printf("%f\n", ZBuff[IndexOfZBuff(RENDERWIDTH/2, RENDERHEIGHT/2)].tri->a.x);
|
/* printf("%f\n", ZBuff[IndexOfZBuff(RENDERWIDTH / 2, RENDERHEIGHT / 2)].tri->a.x); */
|
||||||
}
|
/* } */
|
||||||
}
|
/* } */
|
||||||
|
|
||||||
//FillTopFlatZbuffer(ZBuff, &funners, &funners);
|
// FillTopFlatZbuffer(ZBuff, &funners, &funners);
|
||||||
// FillBottomFlatZbuffer(ZBuff,&funners2);
|
// FillBottomFlatZbuffer(ZBuff,&funners2);
|
||||||
|
|
||||||
// FillTopFlatZbuffer(ZBuff, &fullscreentritop);
|
// FillTopFlatZbuffer(ZBuff, &fullscreentritop);
|
||||||
|
@ -530,10 +546,11 @@ int main() {
|
||||||
for (int y = 0; y < RENDERHEIGHT; y++) {
|
for (int y = 0; y < RENDERHEIGHT; y++) {
|
||||||
for (int x = 0; x < RENDERWIDTH; x++) {
|
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
|
// REMOVE THE IF AND REPALCE THE VALUE THAT DISPLAY IS SET TO WITH DIRECT COLOR WHEN
|
||||||
if (ZBuff[IndexOfZBuff(x, y)].tri != 0) {
|
// DONE DEBUGGING
|
||||||
display[index] = ZBuff[IndexOfZBuff(x, y)].tri->color;
|
//if (ZBuff[IndexOfZBuff(x, y)].tri != 0) {
|
||||||
}
|
display[index] = ZBuff[IndexOfZBuff(x, y)].c;
|
||||||
|
//}
|
||||||
index = index + 1;
|
index = index + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ typedef struct Tri2D Tri2D;
|
||||||
|
|
||||||
struct Zee {
|
struct Zee {
|
||||||
int depth;
|
int depth;
|
||||||
Tri2D * tri;
|
//Tri2D * tri;
|
||||||
Color c;
|
Color c;
|
||||||
};
|
};
|
||||||
typedef struct Zee Zee;
|
typedef struct Zee Zee;
|
||||||
|
|
Loading…
Reference in a new issue