X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fpolytest.c;h=a2985dd99a7c8a4198f187b083fa110cee8d0410;hp=5b43eeaadbe5099deb9b96f60e39f2692422204d;hb=90a1ba8903eed9e3d4b17f4b56cd02ed801dd8b6;hpb=633743214adddf6ec20f8b1bee1782e6966023af diff --git a/src/polytest.c b/src/polytest.c index 5b43eea..a2985dd 100644 --- a/src/polytest.c +++ b/src/polytest.c @@ -1,6 +1,7 @@ #include #include #include +#include #include "screen.h" #include "demo.h" #include "3dgfx.h" @@ -8,7 +9,7 @@ struct mesh { int prim; struct g3d_vertex *varr; - unsigned int *iarr; + int16_t *iarr; int vcount, icount; }; @@ -18,6 +19,9 @@ static void start(long trans_time); static void draw(void); static void draw_mesh(struct mesh *mesh); static int gen_cube(struct mesh *mesh, float sz); +static int gen_torus(struct mesh *mesh, float rad, float ringrad, int usub, int vsub); +static int dump_obj(const char *fname, struct mesh *m); +static void zsort(struct mesh *m); static struct screen scr = { "polytest", @@ -27,7 +31,7 @@ static struct screen scr = { draw }; -static struct mesh cube; +static struct mesh cube, torus; struct screen *polytest_screen(void) { @@ -37,6 +41,8 @@ struct screen *polytest_screen(void) static int init(void) { gen_cube(&cube, 1.0); + gen_torus(&torus, 1.0, 0.25, 24, 12); + dump_obj("torus.obj", &torus); return 0; } @@ -82,13 +88,14 @@ static void draw(void) g3d_rotate(phi, 1, 0, 0); g3d_rotate(theta, 0, 1, 0); - draw_mesh(&cube); + zsort(&torus); + draw_mesh(&torus); } static void draw_mesh(struct mesh *mesh) { if(mesh->iarr) { - /*g3d_draw_indexed(mesh->prim, mesh->iarr, mesh->icount, mesh->varr);*/ + g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount); } else { g3d_draw(mesh->prim, mesh->varr, mesh->vcount); } @@ -163,3 +170,163 @@ static int gen_cube(struct mesh *mesh, float sz) return 0; } + +static void torusvec(float *res, float theta, float phi, float mr, float rr) +{ + float rx, ry, rz; + theta = -theta; + + rx = -cos(phi) * rr + mr; + ry = sin(phi) * rr; + rz = 0.0f; + + res[0] = rx * sin(theta) + rz * cos(theta); + res[1] = ry; + res[2] = -rx * cos(theta) + rz * sin(theta); +} + +static int gen_torus(struct mesh *mesh, float rad, float ringrad, int usub, int vsub) +{ + int i, j; + int nfaces, uverts, vverts; + struct g3d_vertex *vptr; + int16_t *iptr; + + mesh->prim = G3D_QUADS; + + if(usub < 4) usub = 4; + if(vsub < 2) vsub = 2; + + uverts = usub + 1; + vverts = vsub + 1; + + mesh->vcount = uverts * vverts; + nfaces = usub * vsub; + mesh->icount = nfaces * 4; + + if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) { + return -1; + } + if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) { + return -1; + } + vptr = mesh->varr; + iptr = mesh->iarr; + + for(i=0; ix, theta, phi, rad, ringrad); + + vptr->nx = (vptr->x - rcent[0]) / ringrad; + vptr->ny = (vptr->y - rcent[1]) / ringrad; + vptr->nz = (vptr->z - rcent[2]) / ringrad; + vptr->u = u; + vptr->v = v; + vptr->r = chess ? 255 : 64; + vptr->g = 128; + vptr->b = chess ? 64 : 255; + ++vptr; + + if(i < usub && j < vsub) { + int idx = i * vverts + j; + *iptr++ = idx; + *iptr++ = idx + 1; + *iptr++ = idx + vverts + 1; + *iptr++ = idx + vverts; + } + } + } + return 0; +} + +static int dump_obj(const char *fname, struct mesh *m) +{ + int i, j, nfaces; + FILE *fp; + struct g3d_vertex *vptr; + int16_t *iptr; + + if(!(fp = fopen(fname, "wb"))) { + return -1; + } + + nfaces = m->icount / m->prim; + printf("dumping obj: %s - %d vertices / %d faces (%d indices)\n", fname, + m->vcount, nfaces, m->icount); + + vptr = m->varr; + for(i=0; ivcount; i++) { + fprintf(fp, "v %f %f %f\n", vptr->x, vptr->y, vptr->z); + ++vptr; + } + vptr = m->varr; + for(i=0; ivcount; i++) { + fprintf(fp, "vn %f %f %f\n", vptr->nx, vptr->ny, vptr->nz); + ++vptr; + } + vptr = m->varr; + for(i=0; ivcount; i++) { + fprintf(fp, "vt %f %f\n", vptr->u, vptr->v); + ++vptr; + } + + iptr = m->iarr; + for(i=0; iicount; i += m->prim) { + fputc('f', fp); + for(j=0; jprim; j++) { + int idx = *iptr++ + 1; + fprintf(fp, " %d/%d/%d", idx, idx, idx); + } + fputc('\n', fp); + } + + fclose(fp); + return 0; +} + +static struct { + struct g3d_vertex *varr; + const float *xform; +} zsort_cls; + +static int zsort_cmp(const void *aptr, const void *bptr) +{ + const int16_t *a = (const int16_t*)aptr; + const int16_t *b = (const int16_t*)bptr; + + const float *m = zsort_cls.xform; + + const struct g3d_vertex *va = zsort_cls.varr + a[0]; + const struct g3d_vertex *vb = zsort_cls.varr + b[0]; + + float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; + float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; + + va = zsort_cls.varr + a[2]; + vb = zsort_cls.varr + b[2]; + + za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14]; + zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14]; + + return za - zb; +} + +static void zsort(struct mesh *m) +{ + int nfaces = m->icount / m->prim; + + zsort_cls.varr = m->varr; + zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0); + + qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_cmp); +}