X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fmesh.c;h=88c6edc6221fa97a08882d82e1e55d83bc13b398;hp=c4c8a87f207e612b353cdf66fbf7ee883fab2400;hb=ae96c724e905181ca10441a63b1dfe9c2fc5d2ea;hpb=8001fafbf699a4048046d4393377e3ec83480b95 diff --git a/src/mesh.c b/src/mesh.c index c4c8a87..88c6edc 100644 --- a/src/mesh.c +++ b/src/mesh.c @@ -5,49 +5,59 @@ #include "mesh.h" #include "3dgfx.h" +void free_mesh(struct g3d_mesh *mesh) +{ + destroy_mesh(mesh); + free(mesh); +} + +void destroy_mesh(struct g3d_mesh *mesh) +{ + free(mesh->varr); + free(mesh->iarr); +} + static struct { + int prim; struct g3d_vertex *varr; const float *xform; } zsort_cls; static int zsort_cmp(const void *aptr, const void *bptr) { + int i; + float za = 0.0f; + float zb = 0.0f; const float *m = zsort_cls.xform; - const struct g3d_vertex *va = (const struct g3d_vertex*)aptr; const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr; - 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; - ++vb; - - 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]; - + for(i=0; ix + 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]; + ++va; + ++vb; + } return za - zb; } static int zsort_indexed_cmp(const void *aptr, const void *bptr) { - const int16_t *a = (const int16_t*)aptr; - const int16_t *b = (const int16_t*)bptr; + int i; + float za = 0.0f; + float zb = 0.0f; + const uint16_t *a = (const uint16_t*)aptr; + const uint16_t *b = (const uint16_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]; + for(i=0; ix + 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; } @@ -56,6 +66,7 @@ void zsort_mesh(struct g3d_mesh *m) { zsort_cls.varr = m->varr; zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0); + zsort_cls.prim = m->prim; if(m->iarr) { int nfaces = m->icount / m->prim; @@ -100,7 +111,7 @@ int append_mesh(struct g3d_mesh *ma, struct g3d_mesh *mb) { int i, new_vcount, new_icount; void *tmp; - int16_t *iptr; + uint16_t *iptr; if(ma->prim != mb->prim) { fprintf(stderr, "append_mesh failed, primitive mismatch\n"); @@ -173,7 +184,7 @@ int indexify_mesh(struct g3d_mesh *mesh) int i, j, nfaces, max_icount, idx; int out_vcount = 0; struct g3d_vertex *vin, *vout; - int16_t *iout; + uint16_t *iout; if(mesh->iarr) { fprintf(stderr, "indexify_mesh failed: already indexed\n"); @@ -209,13 +220,101 @@ int indexify_mesh(struct g3d_mesh *mesh) return 0; } +void normalize_mesh_normals(struct g3d_mesh *mesh) +{ + int i; + struct g3d_vertex *v = mesh->varr; + + for(i=0; ivcount; i++) { + float mag = sqrt(v->nx * v->nx + v->ny * v->ny + v->nz * v->nz); + float s = (mag == 0.0f) ? 1.0f : 1.0f / mag; + v->nx *= s; + v->ny *= s; + v->nz *= s; + ++v; + } +} + + +static void sphvec(float *res, float theta, float phi, float rad) +{ + theta = -theta; + res[0] = sin(theta) * sin(phi); + res[1] = cos(phi); + res[2] = cos(theta) * sin(phi); +} + +int gen_sphere_mesh(struct g3d_mesh *mesh, float rad, int usub, int vsub) +{ + int i, j; + int nfaces, uverts, vverts; + struct g3d_vertex *vptr; + uint16_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))) { + fprintf(stderr, "gen_sphere_mesh: failed to allocate vertex buffer (%d vertices)\n", mesh->vcount); + return -1; + } + if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) { + fprintf(stderr, "gen_sphere_mesh: failed to allocate index buffer (%d indices)\n", mesh->icount); + return -1; + } + vptr = mesh->varr; + iptr = mesh->iarr; + + for(i=0; ix, theta, phi, rad); + vptr->w = 1.0f; + + vptr->nx = vptr->x / rad; + vptr->ny = vptr->y / rad; + vptr->nz = vptr->z / rad; + 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; +} + int gen_plane_mesh(struct g3d_mesh *m, float width, float height, int usub, int vsub) { int i, j; int nfaces, nverts, nidx, uverts, vverts; float x, y, u, v, du, dv; struct g3d_vertex *vptr; - int16_t *iptr; + uint16_t *iptr; if(usub < 1) usub = 1; if(vsub < 1) vsub = 1; @@ -289,7 +388,6 @@ int gen_cube_mesh(struct g3d_mesh *mesh, float sz, int sub) int i; struct g3d_mesh *m; struct g3d_mesh tmpmesh; - float xform[16]; static float rotface[][4] = { {0, 0, 1, 0}, {90, 0, 1, 0}, @@ -309,8 +407,7 @@ int gen_cube_mesh(struct g3d_mesh *mesh, float sz, int sub) g3d_load_identity(); g3d_rotate(rotface[i][0], rotface[i][1], rotface[i][2], rotface[i][3]); g3d_translate(0, 0, sz / 2.0f); - g3d_get_matrix(G3D_MODELVIEW, xform); - apply_mesh_xform(m, xform); + apply_mesh_xform(m, g3d_get_matrix(G3D_MODELVIEW, 0)); if(i > 0) { if(append_mesh(mesh, m) == -1) { return -1; @@ -341,7 +438,7 @@ int gen_torus_mesh(struct g3d_mesh *mesh, float rad, float ringrad, int usub, in int i, j; int nfaces, uverts, vverts; struct g3d_vertex *vptr; - int16_t *iptr; + uint16_t *iptr; mesh->prim = G3D_QUADS; @@ -379,6 +476,7 @@ int gen_torus_mesh(struct g3d_mesh *mesh, float rad, float ringrad, int usub, in int chess = (i & 1) == (j & 1); torusvec(&vptr->x, theta, phi, rad, ringrad); + vptr->w = 1.0f; vptr->nx = (vptr->x - rcent[0]) / ringrad; vptr->ny = (vptr->y - rcent[1]) / ringrad;