fixed dumb depth bug

This commit is contained in:
InventorXtreme 2024-08-05 23:41:57 -04:00
parent 89ab1281b5
commit 15f90efb1a
7 changed files with 292 additions and 99 deletions

253
c3d.c
View file

@ -1,5 +1,5 @@
#include "raylib.h"
#include "c3dtypes.h" #include "c3dtypes.h"
#include "raylib.h"
#include "raymath.h" #include "raymath.h"
#include "reader.h" #include "reader.h"
#include <math.h> #include <math.h>
@ -30,6 +30,28 @@ float proj; // HALFWIDTH / tan(half_fov) Inited later
bool printdebug; 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) { 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);
} }
@ -58,9 +80,9 @@ static inline Vector3 Tri2DBaryAtPoint(Tri2D *t, Vector2 p) {
float d20 = Vector2DotProduct(v2, v0); float d20 = Vector2DotProduct(v2, v0);
float d21 = Vector2DotProduct(v2, v1); float d21 = Vector2DotProduct(v2, v1);
float denom = d00 * d11 - d01 * d01; // cache float denom = d00 * d11 - d01 * d01; // cache
retvec.x = (d11 * d20 - d01 * d21) / denom; retvec.y = (d11 * d20 - d01 * d21) / denom; //fixed ordering,
retvec.y = (d00 * d21 - d01 * d20) / denom; retvec.z = (d00 * d21 - d01 * d20) / denom;
retvec.z = 1.0 - retvec.x - retvec.y; retvec.x = 1.0 - retvec.y - retvec.z;
return retvec; return retvec;
} }
@ -71,19 +93,19 @@ Vector2 BaryAndTritoPoint(Tri2D *t, Vector3 bary) {
return retvec; return retvec;
} }
void Vector2Integate(Vector2 * v) { void Vector2Integate(Vector2 *v) {
v->x = (int) v->x; v->x = (int)v->x;
v->y = (int) v->y; v->y = (int)v->y;
} }
static inline float DepthAtBary(Tri2D *t, Vector3 bary) { static inline float InvDepthAtBary(Tri2D *t, Vector3 bary) {
float firstrepz = 1 / t->adepth; float firstrepz = 1.0 / t->adepth;
float secondrepz = 1 / t->bdepth; float secondrepz = 1.0 / t->bdepth;
float thirdrepz = 1 / t->cdepth; 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) { double Min(double a, double b) {
@ -100,53 +122,121 @@ double Max(double a, double b) {
return a; 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 // sort triangle verts so that point A is the "highest" point (lowest y val) and
// point C is the "lowest" pont (highest y val) // point C is the "lowest" pont (highest y val)
void Tri2DSortByY(Tri2D *t) { void Tri2DSortByY(Tri2D *t) {
Vector2 temp; Vector2 temp;
Vector2 tempuv;
float tempdepth;
if (t->a.y > t->b.y) { if (t->a.y > t->b.y) {
temp = t->a; temp = t->a;
tempuv = t->auv;
tempdepth = t->adepth;
t->a = t->b; t->a = t->b;
t->auv = t->buv;
t->adepth = t->bdepth;
t->b = temp; t->b = temp;
t->buv = tempuv;
t->bdepth = tempdepth;
} }
if (t->b.y > t->c.y) { if (t->b.y > t->c.y) {
temp = t->b; temp = t->b;
tempuv = t->buv;
tempdepth = t->bdepth;
t->b = t->c; t->b = t->c;
t->buv = t->cuv;
t->bdepth = t->cdepth;
t->c = temp; t->c = temp;
t->cuv = tempuv;
t->cdepth = tempdepth;
} }
if (t->a.y > t->b.y) { if (t->a.y > t->b.y) {
temp = t->a; temp = t->a;
tempuv = t->auv;
tempdepth = t->adepth;
t->a = t->b; t->a = t->b;
t->auv = t->buv;
t->adepth = t->bdepth;
t->b = temp; t->b = temp;
t->buv = tempuv;
t->bdepth = tempdepth;
} }
} }
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) { void DrawScanline(Zee *zee, Tri2D *trianglepointer, double start, double end, int scanline) {
float depth = 0; float depth = 0;
Vector3 f1baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0), scanline}); Vector2 UVpos;
float f1depth = DepthAtBary(trianglepointer, f1baryatpoint); 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 = Vector3 f1baryatpoint2 =
Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0) + 1, scanline}); Tri2DBaryAtPoint(trianglepointer, (Vector2){Max(start, 0) + 1, scanline});
float f1depth2 = DepthAtBary(trianglepointer, f1baryatpoint2); Vector2 tex1point = BaryAndTritoPoint(&UVRangeTri, f1baryatpoint);
float dslope = f1depth2 - f1depth; 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++) { 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: //UNCOMMENT TO DO REAL UV CALC
/* Vector3 baryatpoint = Tri2DBaryAtPoint(trianglepointer, (Vector2){i, scanline}); */ //UVpos = BaryAndTritoPoint(&UVRangeTri, baryatpoint);
/* depth = DepthAtBary(trianglepointer, baryatpoint); */ //V2Print(UVpos);
depth = f1depth + (dslope * ((float)i - (float)(Max(start, 0)))); UVpos = Vector2Add(tex1point, Vector2Scale(UVSlope, ((float)i - (float)(Max(start, 0)))));
if (depth > zee[IndexOfZBuff(i, scanline)].depth) { depth = 1.0 / (f1invdepth + (dinvslope * ((float)i - (float)(Max(start, 0)))));
if (depth < zee[IndexOfZBuff(i, scanline)].depth) {
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)].c = trianglepointer->color;
}
zee[IndexOfZBuff(i, scanline)].depth = depth; 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 scanbottom = (t->c.y);
int scantop = (Max(t->a.y, 0)); int scantop = (Max(t->a.y, 0));
for (int scanline = scanbottom; scanline >= scantop; scanline--) { for (int scanline = scanbottom; scanline >= scantop; scanline--) {
if (0 <= scanline && scanline < RENDERHEIGHT) { if (0 <= scanline && scanline < RENDERHEIGHT) {
DrawScanline(zee, tp, curx1, curx2, scanline); 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 // Draws triangle with a flat bottomp. Note B and C must be the bottom points
// with A being the top "spike" // with A being the top "spike"
void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) { void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
@ -219,7 +302,7 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
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;
@ -230,23 +313,59 @@ void FillBottomFlatZbuffer(Zee *zee, Tri2D *t, Tri2D *tp) {
} }
} }
void DrawTriZuff(Zee *zbuf, Tri2D *tex ) { /* 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"); */
/* // } */
/* 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 tt = *tex;
Tri2D * t = &tt; Tri2D *t = &tt;
Tri2DSortByY(t); Tri2DSortByY(t);
Tri2D cpy = *t;
Vector2Integate(&t->a); Vector2Integate(&t->a);
Vector2Integate(&t->b); Vector2Integate(&t->b);
Vector2Integate(&t->c); Vector2Integate(&t->c);
if ( (t->a.y > RENDERHEIGHT && t->c.y > RENDERHEIGHT) || (t->a.y < 0 && t->c.y < 0)) { 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; 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, tex);
} else if (t->a.y == t->b.y) { // if top of triangle is flat } 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 } else { // funny split tri
Vector2 v4; // v4 is the vertex on the line between a and c. It is used 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.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;
@ -273,8 +390,8 @@ void DrawTriZuff(Zee *zbuf, Tri2D *tex ) {
topflattrires.color = t->color; topflattrires.color = t->color;
FillBottomFlatZbuffer(zbuf, &bottomflattrires, t); FillBottomFlatZbuffer(zbuf, &bottomflattrires, tex);
FillTopFlatZbuffer(zbuf, &topflattrires, t); FillTopFlatZbuffer(zbuf, &topflattrires, tex);
} }
} }
@ -361,12 +478,6 @@ Vector2 Conv3Dto2D(Vector3 v) {
return returnvector; 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) { static inline Vector3 TransformWithCam(Vector3 v, LocalCam *cam) {
Vector3 returnvector; Vector3 returnvector;
@ -374,7 +485,7 @@ static inline Vector3 TransformWithCam(Vector3 v, LocalCam *cam) {
returnvector.y = v.y - cam->position.y; returnvector.y = v.y - cam->position.y;
returnvector.z = v.z - cam->position.z; 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 = RotateAboutY(returnvector, -cam->angles.y);
returnvector = RotateAboutX(returnvector, -cam->angles.x); 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 TriTransformWithCam(Tri *t, LocalCam *cam) {
Tri rettri; Tri rettri = *t;
rettri.a = TransformWithCam(t->a, cam); rettri.a = TransformWithCam(t->a, cam);
rettri.b = TransformWithCam(t->b, cam); rettri.b = TransformWithCam(t->b, cam);
rettri.c = TransformWithCam(t->c, cam); rettri.c = TransformWithCam(t->c, cam);
@ -400,15 +511,21 @@ Tri2D ConvertTriToTri2D(Tri *t) {
rettri2d.b = Conv3Dto2D(t->b); rettri2d.b = Conv3Dto2D(t->b);
rettri2d.c = Conv3Dto2D(t->c); rettri2d.c = Conv3Dto2D(t->c);
rettri2d.a = Conv2DCenteredToScreen(rettri2d.a); rettri2d.a = Conv2DCenteredToScreen(rettri2d.a);
rettri2d.b = Conv2DCenteredToScreen(rettri2d.b); rettri2d.b = Conv2DCenteredToScreen(rettri2d.b);
rettri2d.c = Conv2DCenteredToScreen(rettri2d.c); rettri2d.c = Conv2DCenteredToScreen(rettri2d.c);
rettri2d.adepth = t->a.z; rettri2d.adepth = -t->a.z;
rettri2d.bdepth = t->b.z; rettri2d.bdepth = -t->b.z;
rettri2d.cdepth = t->c.z; rettri2d.cdepth = -t->c.z;
rettri2d.color = t->color; rettri2d.color = t->color;
rettri2d.material = t->material;
rettri2d.auv = t->auv;
rettri2d.buv = t->buv;
rettri2d.cuv = t->cuv;
return rettri2d; return rettri2d;
} }
@ -454,8 +571,8 @@ int main() {
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, -1010}, (Vector3){0, 800, -1010},
(Vector3){800, 800, -2000}, BLUE}); (Vector3){800, 800, -1010}, BLUE});
static Tri internaltransformedtriarray[50000]; static Tri internaltransformedtriarray[50000];
TriArray TransformedTris; TriArray TransformedTris;
@ -489,11 +606,12 @@ int main() {
bool run3d = true; bool run3d = true;
if (true) {
Object3D t = ReadObjectFromFile("mario.obj"); Object3D t = ReadObjectFromFile("mario.obj");
if (true) {
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]);
// 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) && if ((TransformedTris.arr[i].a.z < 0) && (TransformedTris.arr[i].b.z < 0) &&
(TransformedTris.arr[i].c.z < 0)) { (TransformedTris.arr[i].c.z < 0)) {
Tri2DArrayAppend(&Tri2Darr, ConvertTriToTri2D(&TransformedTris.arr[i])); Tri2DArrayAppend(&Tri2Darr, ConvertTriToTri2D(&TransformedTris.arr[i]));
//PrintTri2D(Tri2Darr.arr[Tri2Darr.length-1]);
} }
} }
@ -521,7 +640,7 @@ int main() {
memset(display, 0, sizeof(display)); memset(display, 0, sizeof(display));
memset(ZBuff, 0, sizeof(Zee) * 1920 * 1080); memset(ZBuff, 0, sizeof(Zee) * 1920 * 1080);
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 i = 0; i < Tri2Darr.length; i++) { for (int i = 0; i < Tri2Darr.length; i++) {
@ -531,7 +650,8 @@ int main() {
/* 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);
*/
/* } */ /* } */
/* } */ /* } */
@ -550,14 +670,24 @@ int main() {
// REMOVE THE IF AND REPALCE THE VALUE THAT DISPLAY IS SET TO WITH DIRECT COLOR WHEN // REMOVE THE IF AND REPALCE THE VALUE THAT DISPLAY IS SET TO WITH DIRECT COLOR WHEN
// DONE DEBUGGING // DONE DEBUGGING
//if (ZBuff[IndexOfZBuff(x, y)].tri != 0) { // if (ZBuff[IndexOfZBuff(x, y)].tri != 0) {
display[index] = ZBuff[IndexOfZBuff(x, y)].c; display[index] = ZBuff[index].c;
//} //}
index = index + 1; 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); BeginTextureMode(uiraylibtexture);
// gui stuff // gui stuff
EndTextureMode(); EndTextureMode();
@ -582,12 +712,11 @@ int main() {
char fpstext[40]; char fpstext[40];
sprintf(fpstext, "%d", GetFPS()); sprintf(fpstext, "%d", GetFPS());
DrawText(fpstext, 0, 0, 20, WHITE); DrawText(fpstext, 100, 0, 20, WHITE);
EndDrawing(); EndDrawing();
} }
CloseWindow(); CloseWindow();
return 0; return 0;
} }

View file

@ -20,6 +20,8 @@ struct CMaterial {
char * name; char * name;
char * texturefile; char * texturefile;
Color * tex; Color * tex;
int h;
int w;
}; };
typedef struct CMaterial CMaterial; typedef struct CMaterial CMaterial;
@ -30,7 +32,7 @@ struct Tri {
Color color; Color color;
CMaterial material; CMaterial * material;
Vector2 auv; Vector2 auv;
Vector2 buv; Vector2 buv;
@ -50,18 +52,21 @@ struct Tri2D {
float bdepth; float bdepth;
float cdepth; float cdepth;
Color color; Color color;
Vector2 auv; Vector2 auv;
Vector2 buv; Vector2 buv;
Vector2 cuv; Vector2 cuv;
CMaterial * material;
}; };
typedef struct Tri2D Tri2D; typedef struct Tri2D Tri2D;
struct Zee { struct Zee {
int depth; float depth;
//Tri2D * tri; //Tri2D tri;
Color c; Color c;
}; };
typedef struct Zee Zee; typedef struct Zee Zee;

View file

@ -1,4 +1,4 @@
newmtl texture newmtl Texture
Ka 0.0 0.0 0.0 Ka 0.0 0.0 0.0
Kd 0.5 0.5 0.5 Kd 0.5 0.5 0.5
Ks 0.0 0.0 0.0 Ks 0.0 0.0 0.0

View file

@ -30,7 +30,7 @@ vn 1.000000 0.000000 0.000000
vn -0.000000 0.000000 1.000000 vn -0.000000 0.000000 1.000000
vn -1.000000 -0.000000 -0.000000 vn -1.000000 -0.000000 -0.000000
vn 0.000000 0.000000 -1.000000 vn 0.000000 0.000000 -1.000000
usemtl Material usemtl Texture
s off s off
f 2/1/1 3/2/1 4/3/1 f 2/1/1 3/2/1 4/3/1
f 8/1/2 7/4/2 6/5/2 f 8/1/2 7/4/2 6/5/2

View file

@ -1,4 +1,5 @@
#include "arrayfuncs.h" #include "arrayfuncs.h"
#include "vecfunc.h"
#include "c3dtypes.h" #include "c3dtypes.h"
#include "raylib.h" #include "raylib.h"
#include <stdio.h> #include <stdio.h>
@ -26,8 +27,10 @@ CMaterial NewCmat(char *matname, char *fname) {
strncpy(cmat.name, matname, 15); strncpy(cmat.name, matname, 15);
strncpy(cmat.texturefile, fname, 15); strncpy(cmat.texturefile, fname, 15);
Image teximg = LoadImage(fname); Image teximg = LoadImage(fname);
cmat.h = teximg.height;
cmat.w = teximg.width;
cmat.tex = LoadImageColors(teximg); 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; return cmat;
} }
@ -74,10 +77,19 @@ void LoadMats(char *fname, CMaterialArray *cmats) {
strncpy(mtltex, v1, 50); strncpy(mtltex, v1, 50);
} }
} }
printf("Loaded Tex %s\n", fname); printf("Loaded MatFile %s\n", fname);
fclose(f); 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 ReadObjectFromFile(char *fname) {
Object3D out; Object3D out;
Vector3 *VertexArray = malloc(10000 * sizeof(Vector3)); Vector3 *VertexArray = malloc(10000 * sizeof(Vector3));
@ -86,20 +98,24 @@ Object3D ReadObjectFromFile(char *fname) {
Vector2 *UVArray = malloc(10000 * sizeof(Vector2)); Vector2 *UVArray = malloc(10000 * sizeof(Vector2));
int UVArrayLength = 0; int UVArrayLength = 0;
TriArray tarr; TriArray * tarr = malloc(sizeof(TriArray));
tarr.arr = malloc(10000 * sizeof(Tri)); tarr->arr = malloc(10000 * sizeof(Tri));
tarr.length = 0; tarr->length = 0;
CMaterialArray cmats; CMaterialArray * cmats = malloc(sizeof(CMaterialArray));
cmats.arr = malloc(50 * sizeof(CMaterial)); cmats->arr = malloc(50 * sizeof(CMaterial));
cmats.length = 0; cmats->length = 0;
out.triangles = &tarr; out.triangles = tarr;
out.mats = cmats;
strncpy(out.name, fname, 100); strncpy(out.name, fname, 100);
FILE *f = fopen(fname, "r"); FILE *f = fopen(fname, "r");
CMaterial * currentmat = NULL;
while (true) { while (true) {
char t[500]; char t[500];
char *fgetres = fgets(t, 500, f); char *fgetres = fgets(t, 500, f);
@ -107,14 +123,17 @@ Object3D ReadObjectFromFile(char *fname) {
break; break;
} }
char objtype[10]; char objtype[10];
char v1[100]; char v1[100];
char v2[100]; char v2[100];
char v3[100]; char v3[100];
sscanf(t, "%s %s %s %s", objtype, v1, v2, v3); sscanf(t, "%s %s %s %s", objtype, v1, v2, v3);
if (strcmp(objtype, "mtllib") == 0) { if (strcmp(objtype, "mtllib") == 0) {
LoadMats(v1, &cmats); LoadMats(v1, cmats);
} }
if (strcmp(objtype, "v") == 0) { if (strcmp(objtype, "v") == 0) {
VertexArray[VertexArrayLength].x = atof(v1) * 100; VertexArray[VertexArrayLength].x = atof(v1) * 100;
VertexArray[VertexArrayLength].y = atof(v2) * 100; VertexArray[VertexArrayLength].y = atof(v2) * 100;
@ -122,12 +141,39 @@ Object3D ReadObjectFromFile(char *fname) {
VertexArrayLength = VertexArrayLength + 1; VertexArrayLength = VertexArrayLength + 1;
} }
if (strcmp(objtype, "vt") == 0) { 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].x = atof(v1);
UVArray[UVArrayLength].y = atof(v2); UVArray[UVArrayLength].y = atof(v2);
//Vector2Print(UVArray[UVArrayLength]);
UVArrayLength = UVArrayLength + 1; 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) { 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 // TODO: append face to triarry
Tri temptri; Tri temptri;
@ -135,21 +181,30 @@ Object3D ReadObjectFromFile(char *fname) {
temptri.b = VertexArray[atoi(v2) - 1]; temptri.b = VertexArray[atoi(v2) - 1];
temptri.c = VertexArray[atoi(v3) - 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("OLINE: %s\n", t);
// printf("adding tri A: %d, B: %d, C: %d\n", atoi(v1), atoi(v2) , atoi(v3) ); // printf("adding tri A: %d, B: %d, C: %d\n", atoi(v1), atoi(v2) , atoi(v3) );
temptri.color = GREEN; temptri.color = GREEN;
TriArrayAppend(&tarr, temptri); TriArrayAppend(tarr, temptri);
} }
// need to bring in triarray functions into their own file // need to bring in triarray functions into their own file
} }
fclose(f); 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"); printf("Mats Loaded\n");
for (int i = 0; i < cmats.length; i++) { for (int i = 0; i < cmats->length; i++) {
printf("%s\n", cmats.arr[i].name); printf("%s\n", cmats->arr[i].name);
} }
return out; return out;

View file

@ -7,6 +7,9 @@ void Vector3Print(Vector3 v) {
printf("VX: %f, VY: %f, FZ: %f\n", v.x, v.y, v.z); 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 RotateAboutX(Vector3 v, double radians) {
Vector3 rotatedvector; Vector3 rotatedvector;
@ -28,5 +31,6 @@ Vector3 RotateAboutZ(Vector3 v, double radians) {
rotatedvector.x = cos(radians) * v.x + (-sin(radians) * v.y) + (0); rotatedvector.x = cos(radians) * v.x + (-sin(radians) * v.y) + (0);
rotatedvector.y = sin(radians) * v.x + cos(radians) * v.y + (0); rotatedvector.y = sin(radians) * v.x + cos(radians) * v.y + (0);
rotatedvector.z = 0 + 0 + 1 * v.z; rotatedvector.z = 0 + 0 + 1 * v.z;
//Vector3Print(rotatedvector);
return rotatedvector; return rotatedvector;
} }

View file

@ -3,7 +3,7 @@
void Vector3Print(Vector3 v); void Vector3Print(Vector3 v);
void Vector2Print(Vector2 v);
Vector3 RotateAboutX(Vector3 V, double radians); Vector3 RotateAboutX(Vector3 V, double radians);
Vector3 RotateAboutY(Vector3 V, double radians); Vector3 RotateAboutY(Vector3 V, double radians);