7 int load_mesh(struct g3d_mesh *mesh, const char *fname)
13 struct g3d_vertex *varr;
17 static int zsort_cmp(const void *aptr, const void *bptr)
19 const float *m = zsort_cls.xform;
21 const struct g3d_vertex *va = (const struct g3d_vertex*)aptr;
22 const struct g3d_vertex *vb = (const struct g3d_vertex*)bptr;
24 float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
25 float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
30 za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
31 zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
36 static int zsort_indexed_cmp(const void *aptr, const void *bptr)
38 const int16_t *a = (const int16_t*)aptr;
39 const int16_t *b = (const int16_t*)bptr;
41 const float *m = zsort_cls.xform;
43 const struct g3d_vertex *va = zsort_cls.varr + a[0];
44 const struct g3d_vertex *vb = zsort_cls.varr + b[0];
46 float za = m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
47 float zb = m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
49 va = zsort_cls.varr + a[2];
50 vb = zsort_cls.varr + b[2];
52 za += m[2] * va->x + m[6] * va->y + m[10] * va->z + m[14];
53 zb += m[2] * vb->x + m[6] * vb->y + m[10] * vb->z + m[14];
59 void zsort_mesh(struct g3d_mesh *m)
61 zsort_cls.varr = m->varr;
62 zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
65 int nfaces = m->icount / m->prim;
66 qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_indexed_cmp);
68 int nfaces = m->vcount / m->prim;
69 qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
74 void draw_mesh(struct g3d_mesh *mesh)
77 g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
79 g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
84 #define NORMAL(vp, x, y, z) do { vp->nx = x; vp->ny = y; vp->nz = z; } while(0)
85 #define COLOR(vp, cr, cg, cb) do { vp->r = cr; vp->g = cg; vp->b = cb; } while(0)
86 #define TEXCOORD(vp, tu, tv) do { vp->u = tu; vp->v = tv; } while(0)
87 #define VERTEX(vp, vx, vy, vz) \
89 vp->x = vx; vp->y = vy; vp->z = vz; vp->w = 1.0f; \
93 int gen_cube(struct g3d_mesh *mesh, float sz, int sub)
95 struct g3d_vertex *vptr;
98 mesh->prim = G3D_QUADS;
103 if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
109 NORMAL(vptr, 0, 0, -1);
110 COLOR(vptr, 255, 0, 255);
111 VERTEX(vptr, hsz, -hsz, -hsz);
112 VERTEX(vptr, -hsz, -hsz, -hsz);
113 VERTEX(vptr, -hsz, hsz, -hsz);
114 VERTEX(vptr, hsz, hsz, -hsz);
116 NORMAL(vptr, 0, -1, 0);
117 COLOR(vptr, 0, 255, 255);
118 VERTEX(vptr, -hsz, -hsz, -hsz);
119 VERTEX(vptr, hsz, -hsz, -hsz);
120 VERTEX(vptr, hsz, -hsz, hsz);
121 VERTEX(vptr, -hsz, -hsz, hsz);
123 NORMAL(vptr, -1, 0, 0);
124 COLOR(vptr, 255, 255, 0);
125 VERTEX(vptr, -hsz, -hsz, -hsz);
126 VERTEX(vptr, -hsz, -hsz, hsz);
127 VERTEX(vptr, -hsz, hsz, hsz);
128 VERTEX(vptr, -hsz, hsz, -hsz);
130 NORMAL(vptr, 1, 0, 0);
131 COLOR(vptr, 255, 0, 0);
132 VERTEX(vptr, hsz, -hsz, hsz);
133 VERTEX(vptr, hsz, -hsz, -hsz);
134 VERTEX(vptr, hsz, hsz, -hsz);
135 VERTEX(vptr, hsz, hsz, hsz);
137 NORMAL(vptr, 0, 1, 0);
138 COLOR(vptr, 0, 255, 0);
139 VERTEX(vptr, -hsz, hsz, hsz);
140 VERTEX(vptr, hsz, hsz, hsz);
141 VERTEX(vptr, hsz, hsz, -hsz);
142 VERTEX(vptr, -hsz, hsz, -hsz);
144 NORMAL(vptr, 0, 0, 1);
145 COLOR(vptr, 0, 0, 255);
146 VERTEX(vptr, -hsz, -hsz, hsz);
147 VERTEX(vptr, hsz, -hsz, hsz);
148 VERTEX(vptr, hsz, hsz, hsz);
149 VERTEX(vptr, -hsz, hsz, hsz);
154 static void torusvec(float *res, float theta, float phi, float mr, float rr)
159 rx = -cos(phi) * rr + mr;
163 res[0] = rx * sin(theta) + rz * cos(theta);
165 res[2] = -rx * cos(theta) + rz * sin(theta);
168 int gen_torus(struct g3d_mesh *mesh, float rad, float ringrad, int usub, int vsub)
171 int nfaces, uverts, vverts;
172 struct g3d_vertex *vptr;
175 mesh->prim = G3D_QUADS;
177 if(usub < 4) usub = 4;
178 if(vsub < 2) vsub = 2;
183 mesh->vcount = uverts * vverts;
184 nfaces = usub * vsub;
185 mesh->icount = nfaces * 4;
187 printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount);
189 if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
192 if(!(mesh->iarr = malloc(mesh->icount * sizeof *mesh->iarr))) {
198 for(i=0; i<uverts; i++) {
199 float u = (float)i / (float)(uverts - 1);
200 float theta = u * 2.0 * M_PI;
203 torusvec(rcent, theta, 0, rad, 0);
205 for(j=0; j<vverts; j++) {
206 float v = (float)j / (float)(vverts - 1);
207 float phi = v * 2.0 * M_PI;
208 int chess = (i & 1) == (j & 1);
210 torusvec(&vptr->x, theta, phi, rad, ringrad);
212 vptr->nx = (vptr->x - rcent[0]) / ringrad;
213 vptr->ny = (vptr->y - rcent[1]) / ringrad;
214 vptr->nz = (vptr->z - rcent[2]) / ringrad;
217 vptr->r = chess ? 255 : 64;
219 vptr->b = chess ? 64 : 255;
222 if(i < usub && j < vsub) {
223 int idx = i * vverts + j;
226 *iptr++ = idx + vverts + 1;
227 *iptr++ = idx + vverts;