From 15f90efb1aad6d3cc69807d79371e0105b6573b9 Mon Sep 17 00:00:00 2001 From: InventorXtreme Date: Mon, 5 Aug 2024 23:41:57 -0400 Subject: [PATCH] fixed dumb depth bug --- c3d.c | 283 ++++++++++++++++++++++++++++++++++++++--------------- c3dtypes.h | 11 ++- cube.mtl | 2 +- cube.obj | 4 +- reader.c | 85 +++++++++++++--- vecfunc.c | 4 + vecfunc.h | 2 +- 7 files changed, 292 insertions(+), 99 deletions(-) diff --git a/c3d.c b/c3d.c index 23494d2..d006cc1 100644 --- a/c3d.c +++ b/c3d.c @@ -1,5 +1,5 @@ -#include "raylib.h" #include "c3dtypes.h" +#include "raylib.h" #include "raymath.h" #include "reader.h" #include @@ -30,6 +30,28 @@ float proj; // HALFWIDTH / tan(half_fov) Inited later bool printdebug; +void PrintTri2D(Tri2D t) { + printf("{(TRI2D) (Color: %d %d %d) A: (%f, %f, d:%f), B: (%f, %f, d:%f), C:(%f,%f, d:%f) }\n ", + t.color.r, t.color.g, t.color.b, t.a.x, t.a.y, t.adepth, t.b.x, t.b.y, t.bdepth, t.c.x, + t.c.y, t.cdepth); +} + +Vector2 Conv2DCenteredToScreen(Vector2 v) { + Vector2 returnvector; + returnvector.x = v.x + HALFWIDTH; + returnvector.y = v.y + HALFHEIGHT; + return returnvector; +} + + +static inline Vector2 ConvScreenToCentered(Vector2 v) { + Vector2 returnvector; + returnvector.x = v.x - HALFWIDTH; + returnvector.y = v.y - HALFHEIGHT; + return returnvector; +} + + 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); } @@ -58,9 +80,9 @@ static inline Vector3 Tri2DBaryAtPoint(Tri2D *t, Vector2 p) { 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; + retvec.y = (d11 * d20 - d01 * d21) / denom; //fixed ordering, + retvec.z = (d00 * d21 - d01 * d20) / denom; + retvec.x = 1.0 - retvec.y - retvec.z; return retvec; } @@ -71,19 +93,19 @@ Vector2 BaryAndTritoPoint(Tri2D *t, Vector3 bary) { return retvec; } -void Vector2Integate(Vector2 * v) { - v->x = (int) v->x; - v->y = (int) v->y; +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; - float thirdrepz = 1 / t->cdepth; +static inline float InvDepthAtBary(Tri2D *t, Vector3 bary) { + float firstrepz = 1.0 / t->adepth; + float secondrepz = 1.0 / t->bdepth; + float thirdrepz = 1.0 / t->cdepth; - float finrepz = firstrepz * bary.x + secondrepz * bary.y + thirdrepz * bary.z; + float finrepz = (firstrepz * bary.x) + (secondrepz * bary.y) + (thirdrepz * bary.z); - return 1 / finrepz; + return finrepz; } double Min(double a, double b) { @@ -100,53 +122,121 @@ 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) { + // asfd + 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) void Tri2DSortByY(Tri2D *t) { Vector2 temp; + Vector2 tempuv; + float tempdepth; if (t->a.y > t->b.y) { temp = t->a; + tempuv = t->auv; + tempdepth = t->adepth; + t->a = t->b; + t->auv = t->buv; + t->adepth = t->bdepth; + t->b = temp; + t->buv = tempuv; + t->bdepth = tempdepth; } if (t->b.y > t->c.y) { temp = t->b; + tempuv = t->buv; + tempdepth = t->bdepth; + t->b = t->c; + t->buv = t->cuv; + t->bdepth = t->cdepth; + t->c = temp; + t->cuv = tempuv; + t->cdepth = tempdepth; } if (t->a.y > t->b.y) { temp = t->a; + tempuv = t->auv; + tempdepth = t->adepth; + t->a = t->b; + t->auv = t->buv; + t->adepth = t->bdepth; + t->b = temp; + t->buv = tempuv; + t->bdepth = tempdepth; } } -void DrawScanline(Zee *zee, Tri2D *trianglepointer, double start, double end, int scanline) { - float depth = 0; - Vector3 f1baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0), scanline}); - float f1depth = DepthAtBary(trianglepointer, f1baryatpoint); +void V2Print(Vector2 v) { + // ra + printf("%f, %f\n", v.x, v.y); +} +void DrawScanline(Zee *zee, Tri2D *trianglepointer, double start, double end, int scanline) { + float depth = 0; + Vector2 UVpos; + UVpos.x = 0; + UVpos.y = 0; + Tri2D UVRangeTri; + UVRangeTri.a = trianglepointer->auv; + UVRangeTri.b = trianglepointer->buv; + UVRangeTri.c = trianglepointer->cuv; + /* V2Print(UVRangeTri.a); */ + /* V2Print(UVRangeTri.b); */ + /* V2Print(UVRangeTri.c); */ + + + Vector3 f1baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0), scanline}); Vector3 f1baryatpoint2 = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0) + 1, scanline}); - float f1depth2 = DepthAtBary(trianglepointer, f1baryatpoint2); - float dslope = f1depth2 - f1depth; + Vector2 tex1point = BaryAndTritoPoint(&UVRangeTri, f1baryatpoint); + Vector2 tex2point = BaryAndTritoPoint(&UVRangeTri, f1baryatpoint2); + + double f1invdepth = InvDepthAtBary(trianglepointer, f1baryatpoint); + double f1invdepth2 = InvDepthAtBary(trianglepointer, f1baryatpoint2); + + double dinvslope = f1invdepth2 - f1invdepth; // change in store_depth per pixel + + Vector2 UVSlope = Vector2Subtract(tex2point, tex1point); + // printf("UVSLOPE: X%f: Y:%f\n", UVSlope.x, UVSlope.y); for (int i = (Max(start, 0)); i < (Min(end, RENDERWIDTH)); i++) { - /* zee[IndexOfZBuff(i, scanline)].triangle = tp; */ + // UNCOMMENT TO DO TRUE NON SLOPE BASED DEPTH CALC: + //Vector3 baryatpoint = Tri2DBaryAtPoint(trianglepointer, ( (Vector2){i, scanline})); + //depth = 1.0 / InvDepthAtBary(trianglepointer, baryatpoint); - //UNCOMMENT TO DO TRUE NON SLOPE BASED DEPTH CALC: - /* Vector3 baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){i, scanline}); */ - /* depth = DepthAtBary(trianglepointer, baryatpoint); */ + + //UNCOMMENT TO DO REAL UV CALC + //UVpos = BaryAndTritoPoint(&UVRangeTri, baryatpoint); + //V2Print(UVpos); + + UVpos = Vector2Add(tex1point, Vector2Scale(UVSlope, ((float)i - (float)(Max(start, 0))))); + depth = 1.0 / (f1invdepth + (dinvslope * ((float)i - (float)(Max(start, 0))))); + if (depth < zee[IndexOfZBuff(i, scanline)].depth) { - depth = f1depth + (dslope * ((float)i - (float)(Max(start, 0)))); - if (depth > zee[IndexOfZBuff(i, scanline)].depth) { - zee[IndexOfZBuff(i, scanline)].c = trianglepointer->color; + CMaterial *mat = trianglepointer->material; + + if (mat != NULL) { + + int y = (int)(UVpos.y * (float)mat->h) % mat->h ; // keep within range because of bug + int x = (int)(UVpos.x * (float)mat->w) % mat->w; + // printf("plotting point x: %f, y: %d\n", UVpos.x,y); + // int pitch = + zee[IndexOfZBuff(i, scanline)].c = trianglepointer->material->tex[(y * mat->w) + x]; + } else { + zee[IndexOfZBuff(i, scanline)].c = trianglepointer->color; + } zee[IndexOfZBuff(i, scanline)].depth = depth; - //zee[IndexOfZBuff(i, scanline)].tri = trianglepointer; + //zee[IndexOfZBuff(i, scanline)].tri = *trianglepointer; } } } @@ -174,8 +264,6 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { int scanbottom = (t->c.y); int scantop = (Max(t->a.y, 0)); - - for (int scanline = scanbottom; scanline >= scantop; scanline--) { if (0 <= scanline && scanline < RENDERHEIGHT) { DrawScanline(zee, tp, curx1, curx2, scanline); @@ -186,11 +274,6 @@ void FillTopFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { } } -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); -} - // Draws triangle with a flat bottomp. Note B and C must be the bottom points // with A being the top "spike" void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { @@ -212,17 +295,17 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { 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 + // everything will be offset int scanbottom = (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 ) { - Tri2D nt = *tp; - nt.color = RED; - + if (0 <= scanline && scanline < RENDERHEIGHT) { + Tri2D nt = *tp; + nt.color = RED; + DrawScanline(zee, tp, curx1, curx2, scanline); } curx1 += atobslopeinv; @@ -230,23 +313,59 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { } } -void DrawTriZuff(Zee *zbuf, Tri2D *tex ) { - Tri2D tt = *tex; - Tri2D * t = &tt; - Tri2DSortByY(t); - Vector2Integate(&t->a); - Vector2Integate(&t->b); - Vector2Integate(&t->c); +/* void DrawTriZuff2simple(Zee *zbuf, Tri2D *tex){ */ +/* for (int y = 0; y < RENDERHEIGHT; y++){ */ +/* for (int x = 0; x < RENDERWIDTH; x++){ */ +/* if (IsInTri(*tex, (Vector2){x,y})) { */ +/* Vector2 p = (Vector2) {x,y}; */ +/* Vector3 baryatpoint = Tri2DBaryAtPoint(tex, ( (Vector2){x, y})); */ +/* Vector2 bp = BaryAndTritoPoint(tex, baryatpoint); */ +/* //if (bp.x != p.x || bp.y != p.y) { */ +/* // printf("Gotcha:\n"); */ +/* // Vector2Print(p); */ +/* // Vector2Print(bp); */ +/* // printf("GotchaEND:\n"); */ - if ( (t->a.y > RENDERHEIGHT && t->c.y > RENDERHEIGHT) || (t->a.y < 0 && t->c.y < 0)) { - return; - } +/* // } */ +/* float depth = InvDepthAtBary(tex, baryatpoint); */ + +/* if (depth < zbuf[IndexOfZBuff(x, y)].depth) { */ +/* zbuf[IndexOfZBuff(x, y)].depth = depth; */ +/* zbuf[IndexOfZBuff(x, y)].c = tex->color; */ + +/* } */ +/* } */ +/* } */ +/* } */ +/* } */ + + +//the issues is the tt pointer changes, so the thing does not reference properly for debugging +void DrawTriZuff(Zee *zbuf, Tri2D *tex) { + Tri2D tt = *tex; + Tri2D *t = &tt; + + Tri2DSortByY(t); + + Tri2D cpy = *t; + + Vector2Integate(&t->a); + Vector2Integate(&t->b); + Vector2Integate(&t->c); + + CMaterial *mat = tex->material; + /* int y = (int) UVpos.y % mat->h; // keep within range because of bug */ + /* int x = (int) UVpos.x % mat->w; */ + // printf("%s\n", mat->name); + 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); + FillBottomFlatZbuffer(zbuf, t, tex); } else if (t->a.y == t->b.y) { // if top of triangle is flat - FillTopFlatZbuffer(zbuf, t, t); + FillTopFlatZbuffer(zbuf, t, tex); } else { // funny split tri Vector2 v4; // v4 is the vertex on the line between a and c. It is used @@ -263,8 +382,6 @@ void DrawTriZuff(Zee *zbuf, Tri2D *tex ) { bottomflattrires.b = t->b; bottomflattrires.c = v4; - - bottomflattrires.color = t->color; Tri2D topflattrires; topflattrires.a = t->b; @@ -273,8 +390,8 @@ void DrawTriZuff(Zee *zbuf, Tri2D *tex ) { topflattrires.color = t->color; - FillBottomFlatZbuffer(zbuf, &bottomflattrires, t); - FillTopFlatZbuffer(zbuf, &topflattrires, t); + FillBottomFlatZbuffer(zbuf, &bottomflattrires, tex); + FillTopFlatZbuffer(zbuf, &topflattrires, tex); } } @@ -361,12 +478,6 @@ Vector2 Conv3Dto2D(Vector3 v) { return returnvector; } -Vector2 Conv2DCenteredToScreen(Vector2 v) { - Vector2 returnvector; - returnvector.x = v.x + HALFWIDTH; - returnvector.y = v.y + HALFHEIGHT; - return returnvector; -} static inline Vector3 TransformWithCam(Vector3 v, LocalCam *cam) { Vector3 returnvector; @@ -374,7 +485,7 @@ static inline Vector3 TransformWithCam(Vector3 v, LocalCam *cam) { returnvector.y = v.y - cam->position.y; returnvector.z = v.z - cam->position.z; - returnvector = RotateAboutZ(returnvector, cam->angles.z); + returnvector = RotateAboutZ(returnvector, -cam->angles.z); returnvector = RotateAboutY(returnvector, -cam->angles.y); returnvector = RotateAboutX(returnvector, -cam->angles.x); @@ -384,7 +495,7 @@ static inline Vector3 TransformWithCam(Vector3 v, LocalCam *cam) { } Tri TriTransformWithCam(Tri *t, LocalCam *cam) { - Tri rettri; + Tri rettri = *t; rettri.a = TransformWithCam(t->a, cam); rettri.b = TransformWithCam(t->b, cam); rettri.c = TransformWithCam(t->c, cam); @@ -400,15 +511,21 @@ Tri2D ConvertTriToTri2D(Tri *t) { rettri2d.b = Conv3Dto2D(t->b); rettri2d.c = Conv3Dto2D(t->c); + rettri2d.a = Conv2DCenteredToScreen(rettri2d.a); 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.adepth = -t->a.z; + rettri2d.bdepth = -t->b.z; + rettri2d.cdepth = -t->c.z; rettri2d.color = t->color; + rettri2d.material = t->material; + + rettri2d.auv = t->auv; + rettri2d.buv = t->buv; + rettri2d.cuv = t->cuv; return rettri2d; } @@ -454,8 +571,8 @@ int main() { 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, -1010}, (Vector3){0, 800, -1010}, + (Vector3){800, 800, -1010}, BLUE}); static Tri internaltransformedtriarray[50000]; TriArray TransformedTris; @@ -489,11 +606,12 @@ int main() { bool run3d = true; + Object3D t = ReadObjectFromFile("mario.obj"); if (true) { - Object3D t = ReadObjectFromFile("mario.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]); + // printf("%s\n",tarr.arr[i].material->name); } } @@ -512,6 +630,7 @@ int main() { 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])); + //PrintTri2D(Tri2Darr.arr[Tri2Darr.length-1]); } } @@ -521,7 +640,7 @@ 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; + ZBuff[i].depth = 10000000; } for (int i = 0; i < Tri2Darr.length; i++) { @@ -531,7 +650,8 @@ int main() { /* 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); */ + /* printf("%f\n", ZBuff[IndexOfZBuff(RENDERWIDTH / 2, RENDERHEIGHT / 2)].tri->a.x); + */ /* } */ /* } */ @@ -550,14 +670,24 @@ int main() { // 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; - //} + // if (ZBuff[IndexOfZBuff(x, y)].tri != 0) { + display[index] = ZBuff[index].c; + //} index = index + 1; } } + // printf("%d\n",t.mats->length); + // printf("%d\n",t.mats->arr[t.mats->length -1].h); + /* index = 0; */ + /* for (int y = 0; y < t.mats->arr[0].h; y++) { */ + /* for (int x = 0; x < t.mats->arr[0].w; x++) { */ + /* display[(y * RENDERWIDTH) + x] = t.mats->arr[0].tex[index]; */ + /* index = index + 1; */ + /* } */ + /* } */ BeginTextureMode(uiraylibtexture); + // gui stuff EndTextureMode(); @@ -582,12 +712,11 @@ int main() { char fpstext[40]; sprintf(fpstext, "%d", GetFPS()); - DrawText(fpstext, 0, 0, 20, WHITE); + DrawText(fpstext, 100, 0, 20, WHITE); EndDrawing(); } CloseWindow(); - return 0; } diff --git a/c3dtypes.h b/c3dtypes.h index a8e9056..dc9c4c6 100644 --- a/c3dtypes.h +++ b/c3dtypes.h @@ -20,6 +20,8 @@ struct CMaterial { char * name; char * texturefile; Color * tex; + int h; + int w; }; typedef struct CMaterial CMaterial; @@ -30,7 +32,7 @@ struct Tri { Color color; - CMaterial material; + CMaterial * material; Vector2 auv; Vector2 buv; @@ -50,18 +52,21 @@ struct Tri2D { float bdepth; float cdepth; + Color color; Vector2 auv; Vector2 buv; Vector2 cuv; + + CMaterial * material; }; typedef struct Tri2D Tri2D; struct Zee { - int depth; - //Tri2D * tri; + float depth; + //Tri2D tri; Color c; }; typedef struct Zee Zee; diff --git a/cube.mtl b/cube.mtl index dcd20c5..2fce944 100644 --- a/cube.mtl +++ b/cube.mtl @@ -1,4 +1,4 @@ -newmtl texture +newmtl Texture Ka 0.0 0.0 0.0 Kd 0.5 0.5 0.5 Ks 0.0 0.0 0.0 diff --git a/cube.obj b/cube.obj index c786c1e..1460f61 100644 --- a/cube.obj +++ b/cube.obj @@ -30,7 +30,7 @@ vn 1.000000 0.000000 0.000000 vn -0.000000 0.000000 1.000000 vn -1.000000 -0.000000 -0.000000 vn 0.000000 0.000000 -1.000000 -usemtl Material +usemtl Texture s off f 2/1/1 3/2/1 4/3/1 f 8/1/2 7/4/2 6/5/2 @@ -43,4 +43,4 @@ f 5/14/2 8/1/2 6/5/2 f 1/12/3 5/6/3 2/8/3 f 2/12/4 6/8/4 3/4/4 f 4/13/5 3/9/5 8/11/5 -f 5/6/6 1/12/6 8/11/6 \ No newline at end of file +f 5/6/6 1/12/6 8/11/6 diff --git a/reader.c b/reader.c index 6bd51a7..3dc189d 100644 --- a/reader.c +++ b/reader.c @@ -1,4 +1,5 @@ #include "arrayfuncs.h" +#include "vecfunc.h" #include "c3dtypes.h" #include "raylib.h" #include @@ -26,8 +27,10 @@ CMaterial NewCmat(char *matname, char *fname) { strncpy(cmat.name, matname, 15); strncpy(cmat.texturefile, fname, 15); Image teximg = LoadImage(fname); + cmat.h = teximg.height; + cmat.w = teximg.width; cmat.tex = LoadImageColors(teximg); - printf("Loaded Tex %s\n", matname); + printf("Loaded SingleTex %s with h:%d and w:%d\n", matname,cmat.h,cmat.w); return cmat; } @@ -74,10 +77,19 @@ void LoadMats(char *fname, CMaterialArray *cmats) { strncpy(mtltex, v1, 50); } } - printf("Loaded Tex %s\n", fname); + printf("Loaded MatFile %s\n", fname); fclose(f); } +CMaterial * FindCmat(CMaterialArray * cmats, char * name){ + for (int i = 0; i < cmats->length; i++) { + if (strcmp(cmats->arr[i].name, name) == 0){ + return &cmats->arr[i]; + } + } + return NULL; +} + Object3D ReadObjectFromFile(char *fname) { Object3D out; Vector3 *VertexArray = malloc(10000 * sizeof(Vector3)); @@ -86,20 +98,24 @@ Object3D ReadObjectFromFile(char *fname) { Vector2 *UVArray = malloc(10000 * sizeof(Vector2)); int UVArrayLength = 0; - TriArray tarr; - tarr.arr = malloc(10000 * sizeof(Tri)); - tarr.length = 0; + TriArray * tarr = malloc(sizeof(TriArray)); + tarr->arr = malloc(10000 * sizeof(Tri)); + tarr->length = 0; - CMaterialArray cmats; - cmats.arr = malloc(50 * sizeof(CMaterial)); - cmats.length = 0; + CMaterialArray * cmats = malloc(sizeof(CMaterialArray)); + cmats->arr = malloc(50 * sizeof(CMaterial)); + cmats->length = 0; - out.triangles = &tarr; + out.triangles = tarr; + out.mats = cmats; strncpy(out.name, fname, 100); FILE *f = fopen(fname, "r"); + + CMaterial * currentmat = NULL; + while (true) { char t[500]; char *fgetres = fgets(t, 500, f); @@ -107,14 +123,17 @@ Object3D ReadObjectFromFile(char *fname) { break; } + char objtype[10]; char v1[100]; char v2[100]; char v3[100]; sscanf(t, "%s %s %s %s", objtype, v1, v2, v3); + if (strcmp(objtype, "mtllib") == 0) { - LoadMats(v1, &cmats); + LoadMats(v1, cmats); } + if (strcmp(objtype, "v") == 0) { VertexArray[VertexArrayLength].x = atof(v1) * 100; VertexArray[VertexArrayLength].y = atof(v2) * 100; @@ -122,12 +141,39 @@ Object3D ReadObjectFromFile(char *fname) { VertexArrayLength = VertexArrayLength + 1; } if (strcmp(objtype, "vt") == 0) { - // printf("vt: (%s,%s)\n", v1, v2); + //printf("vt: (%s,%s)\n", v1, v2); UVArray[UVArrayLength].x = atof(v1); UVArray[UVArrayLength].y = atof(v2); + //Vector2Print(UVArray[UVArrayLength]); UVArrayLength = UVArrayLength + 1; } + if (strcmp(objtype, "usemtl") == 0) { + currentmat = FindCmat(cmats, v1); + printf("CHANGED MAT TO: %s %s\n", currentmat->name, currentmat->texturefile); + } if (strcmp(objtype, "f") == 0) { + int slashCount = 0; + for (int i = 0; i < strlen(t); i++) { + if (t[i] == '/') { + slashCount = slashCount + 1; + } + } + + char blank[100]; + char v1t[100]; + char v2t[100]; + char v3t[100]; + + if (slashCount > 2) { + sscanf(v1, "%[^/]%s", blank, v1t); + sscanf(v2, "%[^/]%s", blank, v2t); + sscanf(v3, "%[^/]%s", blank, v3t); + } + if (slashCount > 5) { + sscanf(v1, "%[^/]/%[^/]%s", blank, v1t, blank); + sscanf(v2, "%[^/]/%[^/]%s", blank, v2t, blank); + sscanf(v3, "%[^/]/%[^/]%s", blank, v3t, blank); + } // TODO: append face to triarry Tri temptri; @@ -135,21 +181,30 @@ Object3D ReadObjectFromFile(char *fname) { temptri.b = VertexArray[atoi(v2) - 1]; temptri.c = VertexArray[atoi(v3) - 1]; + temptri.auv = UVArray[atoi(v1t)-1]; + temptri.buv = UVArray[atoi(v2t)-1]; + temptri.cuv = UVArray[atoi(v3t)-1]; + //printf("%s\n",v1t); + + //Vector2Print(temptri.cuv); + + temptri.material = currentmat; + // printf("OLINE: %s\n", t); // printf("adding tri A: %d, B: %d, C: %d\n", atoi(v1), atoi(v2) , atoi(v3) ); temptri.color = GREEN; - TriArrayAppend(&tarr, temptri); + TriArrayAppend(tarr, temptri); } // need to bring in triarray functions into their own file } fclose(f); - printf("Loaded model %s with %d tris\n", fname, tarr.length); + printf("Loaded model %s with %d tris\n", fname, tarr->length); printf("Mats Loaded\n"); - for (int i = 0; i < cmats.length; i++) { - printf("%s\n", cmats.arr[i].name); + for (int i = 0; i < cmats->length; i++) { + printf("%s\n", cmats->arr[i].name); } return out; diff --git a/vecfunc.c b/vecfunc.c index 9159319..8e0ee9a 100644 --- a/vecfunc.c +++ b/vecfunc.c @@ -7,6 +7,9 @@ void Vector3Print(Vector3 v) { printf("VX: %f, VY: %f, FZ: %f\n", v.x, v.y, v.z); } +void Vector2Print(Vector2 v) { + printf("VX: %f, VY: %f\n", v.x,v.y); +} Vector3 RotateAboutX(Vector3 v, double radians) { Vector3 rotatedvector; @@ -28,5 +31,6 @@ Vector3 RotateAboutZ(Vector3 v, double radians) { rotatedvector.x = cos(radians) * v.x + (-sin(radians) * v.y) + (0); rotatedvector.y = sin(radians) * v.x + cos(radians) * v.y + (0); rotatedvector.z = 0 + 0 + 1 * v.z; + //Vector3Print(rotatedvector); return rotatedvector; } diff --git a/vecfunc.h b/vecfunc.h index f68bc77..13e8697 100644 --- a/vecfunc.h +++ b/vecfunc.h @@ -3,7 +3,7 @@ void Vector3Print(Vector3 v); - +void Vector2Print(Vector2 v); Vector3 RotateAboutX(Vector3 V, double radians); Vector3 RotateAboutY(Vector3 V, double radians);