diff --git a/.clang-format b/.clang-format index e5ab5c1..1bfafbc 100644 --- a/.clang-format +++ b/.clang-format @@ -1,2 +1,2 @@ IndentWidth: 4 -ColumnLimit: 80 +ColumnLimit: 100 diff --git a/Makefile b/Makefile index 50b5ef8..8a8a46a 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ CC = clang #Set compiler 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.c #list all object files +objects = c3d.o reader.o arrayfuncs.o vecfunc.o #list all object files c3d: $(objects) #State that to make the c3d executeable, we need all objects diff --git a/arrayfuncs.h b/arrayfuncs.h index 4e92079..645172a 100644 --- a/arrayfuncs.h +++ b/arrayfuncs.h @@ -1,3 +1,5 @@ +#include "c3dtypes.h" + #ifndef ARRAYFUNCS_HEADER #define ARRAYFUNCS_HEADER diff --git a/c3d.c b/c3d.c index 5c857a6..711435c 100644 --- a/c3d.c +++ b/c3d.c @@ -1,15 +1,15 @@ #include "raylib.h" +#include "raymath.h" #include "reader.h" #include #include #include #include -#include "c3dtypes.h" #include "arrayfuncs.h" +#include "c3dtypes.h" #include "vecfunc.h" - const int RENDERWIDTH = 1920; const int RENDERHEIGHT = 1080; @@ -27,6 +27,41 @@ const float half_fov = fov / 2; float proj; // HALFWIDTH / tan(half_fov) Inited later +bool printdebug; + +static inline Vector3 Tri2DBaryAtPoint(Tri2D *t, Vector2 p) { + Vector3 retvec; + Vector2 v0 = Vector2Subtract(t->b, t->a); // cachable + Vector2 v1 = Vector2Subtract(t->c, t->a); // cacheable + Vector2 v2 = Vector2Subtract(p, t->a); + float d00 = Vector2DotProduct(v0, v0); // cacheable + float d01 = Vector2DotProduct(v0, v1); // cacheable + float d11 = Vector2DotProduct(v1, v1); // cahceable + float d20 = Vector2DotProduct(v2, v0); + float d21 = Vector2DotProduct(v2, v1); + float denom = d00 * d11 - d01 * d01; // cache + retvec.x = (d11 * d20 - d01 * d21) / denom; + retvec.y = (d00 * d21 - d01 * d20) / denom; + retvec.z = 1.0 - retvec.x - retvec.y; + return retvec; +} + +Vector2 BaryAndTritoPoint(Tri2D *t, Vector3 bary) { + Vector2 retvec; + retvec.x = bary.x * t->a.x + bary.y * t->b.x + bary.z * t->c.x; + retvec.y = bary.y * t->a.y + bary.y * t->b.y + bary.z * t->c.y; + return retvec; +} + +static inline float DepthAtBary(Tri2D *t, Vector3 bary) { + float firstrepz = 1 / t->adepth; + float secondrepz = 1 / t->bdepth; + float thirdrepz = 1 / t->cdepth; + + float finrepz = firstrepz * bary.x + secondrepz * bary.y + thirdrepz * bary.z; + + return 1 / finrepz; +} double Min(double a, double b) { if (a > b) { @@ -42,9 +77,7 @@ double Max(double a, double b) { return a; } -static inline int IndexOfZBuff(int row, int col) { - return row + RENDERWIDTH * col; -} +static inline int IndexOfZBuff(int row, int col) { return row + RENDERWIDTH * col; } // sort triangle verts so that point A is the "highest" point (lowest y val) and // point C is the "lowest" pont (highest y val) @@ -78,11 +111,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 = - (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 = - (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 // which vertex is on which side and increment it with its proper slope @@ -92,18 +123,25 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { for (int scanline = t->c.y; scanline >= t->a.y; scanline--) { if (0 <= scanline && scanline < RENDERHEIGHT) { for (int i = Max(curx1, 0); i < Min(curx2, RENDERWIDTH); i++) { - zee[IndexOfZBuff(i, scanline)].triangle = tp; + /* zee[IndexOfZBuff(i, scanline)].triangle = tp; */ + + Vector3 baryatpoint = Tri2DBaryAtPoint(tp, (Vector2){i, scanline}); + float depth = DepthAtBary(tp, baryatpoint); + if (depth > zee[IndexOfZBuff(i, scanline)].depth) { + zee[IndexOfZBuff(i, scanline)].triangle = tp; + zee[IndexOfZBuff(i, scanline)].depth = depth; + // printf("here\n"); + } } } - curx1 -= - atocslopeinv; // subtract because we are working backwards (reason - // why we start with point c in slope equtn) + 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); + 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); } // Draws triangle with a flat bottomp. Note B and C must be the bottom points @@ -117,21 +155,39 @@ 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 = - (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 = - (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 // which vertex is on which side and increment it with its proper slope double curx1 = t->a.x; double curx2 = t->a.x; - for (int scanline = t->a.y; scanline < t->c.y; scanline++) { + for (int scanline = t->a.y; scanline < t->c.y; + 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; + /* 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; @@ -152,9 +208,9 @@ void DrawTriZuff(Zee *zbuf, Tri2D *t) { Vector2 v4; // v4 is the vertex on the line between a and c. It is used // to split the triangle into a top and bottom v4.y = t->b.y; - float slope = (float)((t->c.x) - (t->a.x)) / - ((float)(t->c.y - t->a.y)); // get slope in run over rise - // becasue we need to find x + float slope = + (float)((t->c.x) - (t->a.x)) / ((float)(t->c.y - t->a.y)); // get slope in run over rise + // becasue we need to find x float changeiny = (float)(t->b.y - t->a.y); float officalxpos = t->a.x + (slope * changeiny); v4.x = officalxpos; @@ -175,8 +231,7 @@ void DrawTriZuff(Zee *zbuf, Tri2D *t) { } float Sign(Vector2 *v1, Vector2 *v2, Vector2 *v3) { - return (v1->x - v3->x) * (v2->y - v3->y) - - (v2->x - v3->x) * (v1->y - v3->y); + return (v1->x - v3->x) * (v2->y - v3->y) - (v2->x - v3->x) * (v1->y - v3->y); } static inline bool IsInTri(Tri2D tri, Vector2 p) { @@ -193,8 +248,6 @@ static inline bool IsInTri(Tri2D tri, Vector2 p) { return !(has_neg && has_pos); } - - void CtrlLocalCam(LocalCam *cam, float time) { cam->velocity.x = 0; cam->velocity.y = 0; @@ -208,7 +261,7 @@ void CtrlLocalCam(LocalCam *cam, float time) { Vector3 rotatedforce = RotateAboutY(forceForward, cam->angles.y); // printf("%f", cam->angles.y); // Vector3Print(rotatedforce); - cam->velocity = Vector3Sum(cam->velocity, rotatedforce); + cam->velocity = Vector3Add(cam->velocity, rotatedforce); // cam->velocity.z = cam->velocity.z + 50000*time*sin(cam->angles.y); // cam->velocity.x = cam->velocity.x + 500*time*cos(cam->angles.y); @@ -216,7 +269,7 @@ void CtrlLocalCam(LocalCam *cam, float time) { if (IsKeyDown(KEY_S)) { Vector3 forceForward = (Vector3){0, 0, 500}; Vector3 rotatedforce = RotateAboutY(forceForward, cam->angles.y); - cam->velocity = Vector3Sum(cam->velocity, rotatedforce); + cam->velocity = Vector3Add(cam->velocity, rotatedforce); // cam->velocity.z = cam->velocity.z + 50000*time*sin(cam->angles.y); // cam->velocity.x = cam->velocity.x + 500*time*cos(cam->angles.y); @@ -225,7 +278,7 @@ void CtrlLocalCam(LocalCam *cam, float time) { if (IsKeyDown(KEY_A)) { Vector3 forceForward = (Vector3){-500, 0, 0}; Vector3 rotatedforce = RotateAboutY(forceForward, cam->angles.y); - cam->velocity = Vector3Sum(cam->velocity, rotatedforce); + cam->velocity = Vector3Add(cam->velocity, rotatedforce); // cam->velocity.z = cam->velocity.z + 50000*time*sin(cam->angles.y); // cam->velocity.x = cam->velocity.x + 500*time*cos(cam->angles.y); @@ -233,7 +286,7 @@ void CtrlLocalCam(LocalCam *cam, float time) { if (IsKeyDown(KEY_D)) { Vector3 forceForward = (Vector3){500, 0, 0}; Vector3 rotatedforce = RotateAboutY(forceForward, cam->angles.y); - cam->velocity = Vector3Sum(cam->velocity, rotatedforce); + cam->velocity = Vector3Add(cam->velocity, rotatedforce); // cam->velocity.z = cam->velocity.z + 50000*time*sin(cam->angles.y); // cam->velocity.x = cam->velocity.x + 500*time*cos(cam->angles.y); @@ -248,17 +301,15 @@ void CtrlLocalCam(LocalCam *cam, float time) { } if (IsKeyDown(KEY_Q)) { - cam->angleVelocity.y = cam->angleVelocity.y + time * 10; + cam->angleVelocity.y = cam->angleVelocity.y + time * 30; } if (IsKeyDown(KEY_E)) { - cam->angleVelocity.y = cam->angleVelocity.y - time * 10; + cam->angleVelocity.y = cam->angleVelocity.y - time * 30; } if (IsKeyDown(KEY_G)) { - printf("PosX: %f PosY: %f PosZ: %f\n", cam->position.x, cam->position.y, - cam->position.z); - printf("RotX; %f RotY: %f RotZ: %f\n", cam->angles.x, cam->angles.y, - cam->angles.z); + printf("PosX: %f PosY: %f PosZ: %f\n", cam->position.x, cam->position.y, cam->position.z); + printf("RotX; %f RotY: %f RotZ: %f\n", cam->angles.x, cam->angles.y, cam->angles.z); } } @@ -323,6 +374,10 @@ Tri2D ConvertTriToTri2D(Tri *t) { rettri2d.b = Conv2DCenteredToScreen(rettri2d.b); rettri2d.c = Conv2DCenteredToScreen(rettri2d.c); + rettri2d.adepth = t->a.z; + rettri2d.bdepth = t->b.z; + rettri2d.cdepth = t->c.z; + rettri2d.color = t->color; return rettri2d; } @@ -332,8 +387,7 @@ int main() { proj = HALFWIDTH / tan(half_fov); SetConfigFlags(FLAG_WINDOW_UNDECORATED); - InitWindow(SCREENWIDTH, SCREENHEIGHT, - "raylib [core] example - basic window"); + InitWindow(SCREENWIDTH, SCREENHEIGHT, "raylib [core] example - basic window"); // SetWindowPosition(0,1080); Vector2 a = GetMonitorPosition(0); @@ -344,11 +398,9 @@ int main() { printf("mh:%d mw:%d w:%d h:%d\n", mh, mw, w, h); SetWindowPosition(a.x + (0.5 * mw) - (w / 2), a.y + (0.5 * mh) - (0.5 * h)); - RenderTexture2D uiraylibtexture = - LoadRenderTexture(RENDERWIDTH, RENDERHEIGHT); + RenderTexture2D uiraylibtexture = LoadRenderTexture(RENDERWIDTH, RENDERHEIGHT); - RenderTexture2D render3dtexture = - LoadRenderTexture(RENDERWIDTH, RENDERHEIGHT); + RenderTexture2D render3dtexture = LoadRenderTexture(RENDERWIDTH, RENDERHEIGHT); Texture2D directaccesstex; @@ -369,9 +421,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}); Tri internaltransformedtriarray[50]; TriArray TransformedTris; @@ -389,26 +443,21 @@ int main() { static Color display[1920 * 1080 * 4]; memset(display, 0, sizeof(display)); - Tri2D funners = (Tri2D){(Vector2){50, 50}, (Vector2){500, 50}, - (Vector2){500, 500}, GREEN}; - Tri2D funners2 = (Tri2D){(Vector2){600, 0}, (Vector2){600, 500}, - (Vector2){1000, 500}, RED}; + Tri2D funners = + (Tri2D){(Vector2){50, 50}, (Vector2){500, 50}, (Vector2){500, 500}, 0, 0, 0, GREEN}; + Tri2D funners2 = + (Tri2D){(Vector2){600, 0}, (Vector2){600, 500}, (Vector2){1000, 500}, 0, 0, 0, RED}; - Tri2D fullscreentritop = (Tri2D){(Vector2){0, 0}, (Vector2){1920, 0}, - (Vector2){1920, 1080}, BLUE}; - Tri2D fullscreentribottom = (Tri2D){(Vector2){0, 0}, (Vector2){0, 1080}, - (Vector2){1920, 1080}, RED}; + Tri2D fullscreentritop = + (Tri2D){(Vector2){0, 0}, (Vector2){1920, 0}, (Vector2){1920, 1080}, 0, 0, 0, BLUE}; + Tri2D fullscreentribottom = + (Tri2D){(Vector2){0, 0}, (Vector2){0, 1080}, (Vector2){1920, 1080}, 0, 0, 0, RED}; - Tri2D blank = - (Tri2D){(Vector2){-10, -10}, (Vector2){-10, -10}, (Vector2){-10, -10}}; + Tri2D blank = (Tri2D){(Vector2){-10, -10}, (Vector2){-10, -10}, (Vector2){-10, -10}}; - Tri2D norm = (Tri2D){(Vector2){500, 50}, (Vector2){0, 0}, - (Vector2){250, 500}, GREEN}; + Tri2D norm = (Tri2D){(Vector2){500, 50}, (Vector2){0, 0}, (Vector2){250, 500}, 0, 0, 0, GREEN}; - - - - bool run3d = false; + bool run3d = true; while (!WindowShouldClose() && run3d) { float frametime = GetFrameTime(); CtrlLocalCam(&camera, frametime); @@ -427,16 +476,13 @@ int main() { Tri2Darr.length = 0; for (int i = 0; i < tarr.length; i++) { - TriArrayAppend(&TransformedTris, - TriTransformWithCam(&tarr.arr[i], &camera)); + TriArrayAppend(&TransformedTris, TriTransformWithCam(&tarr.arr[i], &camera)); } for (int i = 0; i < TransformedTris.length; i++) { - if ((TransformedTris.arr[i].a.z < 0) && - (TransformedTris.arr[i].b.z < 0) && + if ((TransformedTris.arr[i].a.z < 0) && (TransformedTris.arr[i].b.z < 0) && (TransformedTris.arr[i].c.z < 0)) { - Tri2DArrayAppend(&Tri2Darr, - ConvertTriToTri2D(&TransformedTris.arr[i])); + Tri2DArrayAppend(&Tri2Darr, ConvertTriToTri2D(&TransformedTris.arr[i])); } } @@ -445,20 +491,27 @@ int main() { /* } */ memset(display, 0, sizeof(display)); memset(ZBuff, 0, sizeof(Zee) * 1920 * 1080); + for (int i = 0; i < RENDERHEIGHT * RENDERWIDTH; i++) { + ZBuff[i].depth = -10000000; + } /* for (int y = 0; y < RENDERHEIGHT; y++){ */ /* for (int x = 0; xa; */ - 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; @@ -504,19 +556,17 @@ int main() { UpdateTexture(render3dtexture.texture, display); // Copies render3dtexture to screen - DrawTexturePro(render3dtexture.texture, - (Rectangle){0, 0, render3dtexture.texture.width, - render3dtexture.texture.height}, - (Rectangle){0, 0, SCREENWIDTH, SCREENHEIGHT}, - (Vector2){0, 0}, 0, WHITE); + DrawTexturePro( + render3dtexture.texture, + (Rectangle){0, 0, render3dtexture.texture.width, render3dtexture.texture.height}, + (Rectangle){0, 0, SCREENWIDTH, SCREENHEIGHT}, (Vector2){0, 0}, 0, WHITE); // Copies uiraylibtexture to screen (not this is not the texture used // for 3d stuff - DrawTexturePro(uiraylibtexture.texture, - (Rectangle){0, 0, uiraylibtexture.texture.width, - -uiraylibtexture.texture.height}, - (Rectangle){0, 0, SCREENWIDTH, SCREENHEIGHT}, - (Vector2){0, 0}, 0, WHITE); + DrawTexturePro( + uiraylibtexture.texture, + (Rectangle){0, 0, uiraylibtexture.texture.width, -uiraylibtexture.texture.height}, + (Rectangle){0, 0, SCREENWIDTH, SCREENHEIGHT}, (Vector2){0, 0}, 0, WHITE); char fpstext[40]; sprintf(fpstext, "%d", GetFPS()); diff --git a/c3dtypes.h b/c3dtypes.h index 0211d84..c192de0 100644 --- a/c3dtypes.h +++ b/c3dtypes.h @@ -5,6 +5,7 @@ + struct LocalCam { Vector3 position; Vector3 velocity; @@ -29,6 +30,10 @@ struct Tri2D { Vector2 b; Vector2 c; + float adepth; + float bdepth; + float cdepth; + Color color; }; typedef struct Tri2D Tri2D; diff --git a/vecfunc.c b/vecfunc.c index 95f36ab..9159319 100644 --- a/vecfunc.c +++ b/vecfunc.c @@ -2,25 +2,11 @@ #include #include -Vector3 Vector3Sum(Vector3 v1, Vector3 v2) { - Vector3 retvec; - retvec.x = v1.x + v2.x; - retvec.y = v1.y + v2.y; - retvec.z = v1.z + v2.z; - return retvec; -} void Vector3Print(Vector3 v) { printf("VX: %f, VY: %f, FZ: %f\n", v.x, v.y, v.z); } -Vector3 Vector3Scale(Vector3 v1, float scale) { - Vector3 retvec; - retvec.x = v1.x * scale; - retvec.y = v1.y * scale; - retvec.z = v1.z * scale; - return retvec; -} Vector3 RotateAboutX(Vector3 v, double radians) { Vector3 rotatedvector; diff --git a/vecfunc.h b/vecfunc.h index e367e89..f68bc77 100644 --- a/vecfunc.h +++ b/vecfunc.h @@ -1,11 +1,9 @@ #ifndef VECFUNC_HEADER #define VECFUNC_HEADER -Vector3 Vector3Sum(Vector3 v1, Vector3 v2); void Vector3Print(Vector3 v); -Vector3 Vector3Scale(Vector3 v1, float scale); Vector3 RotateAboutX(Vector3 V, double radians); Vector3 RotateAboutY(Vector3 V, double radians);