From: John Tsiombikas Date: Fri, 9 Sep 2016 04:19:21 +0000 (+0300) Subject: torus with crude zsorting X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=commitdiff_plain;h=90a1ba8903eed9e3d4b17f4b56cd02ed801dd8b6 torus with crude zsorting --- diff --git a/src/3dgfx.c b/src/3dgfx.c index 49b4c2c..31e649d 100644 --- a/src/3dgfx.c +++ b/src/3dgfx.c @@ -251,16 +251,25 @@ void g3d_perspective(float vfov_deg, float aspect, float znear, float zfar) g3d_mult_matrix(m); } -#define CROSS(res, a, b) \ - do { \ - (res)[0] = (a)[1] * (b)[2] - (a)[2] * (b)[1]; \ - (res)[1] = (a)[2] * (b)[0] - (a)[0] * (b)[2]; \ - (res)[2] = (a)[0] * (b)[1] - (a)[1] * (b)[0]; \ - } while(0) +const float *g3d_get_matrix(int which, float *m) +{ + int top = st->mtop[which]; + + if(m) { + memcpy(m, st->mat[which][top], 16 * sizeof(float)); + } + return st->mat[which][top]; +} void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size) { - int i; + g3d_draw_indexed(prim, varr, varr_size, 0, 0); +} + +void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, + const int16_t *iarr, int iarr_size) +{ + int i, j, nfaces; struct pvertex pv[4]; struct g3d_vertex v[4]; int vnum = prim; /* primitive vertex counts correspond to enum values */ @@ -271,11 +280,12 @@ void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size) memcpy(st->norm_mat, st->mat[G3D_MODELVIEW][mvtop], 16 * sizeof(float)); st->norm_mat[12] = st->norm_mat[13] = st->norm_mat[14] = 0.0f; - while(varr_size >= vnum) { - varr_size -= vnum; + nfaces = (iarr ? iarr_size : varr_size) / vnum; + + for(j=0; jmat[G3D_MODELVIEW][mvtop], &v[i].x); xform3_vec3(st->norm_mat, &v[i].nx); diff --git a/src/3dgfx.h b/src/3dgfx.h index 9e4b140..68d0783 100644 --- a/src/3dgfx.h +++ b/src/3dgfx.h @@ -63,6 +63,10 @@ void g3d_ortho(float left, float right, float bottom, float top, float znear, fl void g3d_frustum(float left, float right, float bottom, float top, float znear, float zfar); void g3d_perspective(float vfov, float aspect, float znear, float zfar); +const float *g3d_get_matrix(int which, float *m); + void g3d_draw(int prim, const struct g3d_vertex *varr, int varr_size); +void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size, + const int16_t *iarr, int iarr_size); #endif /* THREEDGFX_H_ */ diff --git a/src/demo.c b/src/demo.c index fbcc4be..64bb965 100644 --- a/src/demo.c +++ b/src/demo.c @@ -23,6 +23,7 @@ int demo_init(int argc, char **argv) { struct screen *scr; + start_scr_name = getenv("START_SCR"); if(argv[1]) { start_scr_name = argv[1]; } 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); +}