- separated mesh algorithms in mesh.h/mesh.c
authorJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 14 Feb 2018 05:35:58 +0000 (07:35 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Wed, 14 Feb 2018 05:35:58 +0000 (07:35 +0200)
- fixed backface culling precision issue
- fixed leftover old prototypes for g3d_color* functions
- added debug breakpoint in util and made the demo break when pressing
  delete.
- fugly textured cube in infcubes part

src/3dgfx.c
src/3dgfx.h
src/demo.c
src/infcubes.c
src/mesh.c [new file with mode: 0644]
src/mesh.h [new file with mode: 0644]
src/metaball.c
src/polytest.c
src/util.h

index 17ddd93..673122d 100644 (file)
@@ -470,7 +470,7 @@ void g3d_draw_indexed(int prim, const struct g3d_vertex *varr, int varr_size,
                        int32_t ay = pv[1].y - pv[0].y;
                        int32_t bx = pv[2].x - pv[0].x;
                        int32_t by = pv[2].y - pv[0].y;
-                       int32_t cross_z = ax * (by >> 8) - ay * (bx >> 8);
+                       int32_t cross_z = (ax >> 4) * (by >> 4) - (ay >> 4) * (bx >> 4);
                        int sign = (cross_z >> 31) & 1;
 
                        if(!(sign ^ st->frontface)) {
index 7710459..94884ca 100644 (file)
@@ -102,8 +102,10 @@ void g3d_begin(int prim);
 void g3d_end(void);
 void g3d_vertex(float x, float y, float z);
 void g3d_normal(float x, float y, float z);
-void g3d_color(float r, float g, float b);
-void g3d_color4(float r, float g, float b, float a);
+void g3d_color3b(unsigned char r, unsigned char g, unsigned char b);
+void g3d_color4b(unsigned char r, unsigned char g, unsigned char b, unsigned char a);
+void g3d_color3f(float r, float g, float b);
+void g3d_color4f(float r, float g, float b, float a);
 void g3d_texcoord(float u, float v);
 
 #endif /* THREEDGFX_H_ */
index 6abcf67..b2a03e0 100644 (file)
@@ -11,6 +11,7 @@
 #include "music.h"
 #include "cfgopt.h"
 #include "tinyfps.h"
+#include "util.h"
 
 int fb_width = 320;
 int fb_height = 240;
@@ -121,6 +122,10 @@ void demo_keyboard(int key, int press)
                        demo_quit();
                        break;
 
+               case 127:
+                       debug_break();
+                       break;
+
                case '\n':
                case '\r':
                        dptr = inp;
index 5fe7df9..cfa665b 100644 (file)
@@ -1,15 +1,19 @@
 #include <stdio.h>
+#include <string.h>
 #include <math.h>
 #include "demo.h"
 #include "3dgfx.h"
 #include "screen.h"
 #include "cfgopt.h"
+#include "polyfill.h"
+#include "imago2.h"
+#include "gfxutil.h"
 
 static int init(void);
 static void destroy(void);
 static void start(long trans_time);
 static void draw(void);
-static void draw_cube(void);
+static void draw_cube(float sz);
 
 static struct screen scr = {
        "infcubes",
@@ -19,8 +23,9 @@ static struct screen scr = {
        draw
 };
 
-static float cam_theta, cam_phi;
+static float cam_theta = -29, cam_phi = 35;
 static float cam_dist = 5;
+static struct pimage tex_crate;
 
 struct screen *infcubes_screen(void)
 {
@@ -30,11 +35,31 @@ struct screen *infcubes_screen(void)
 
 static int init(void)
 {
+       int i, npixels;
+       unsigned char *src;
+       uint16_t *dst;
+
+       if(!(tex_crate.pixels = img_load_pixels("data/crate.jpg", &tex_crate.width,
+                                       &tex_crate.height, IMG_FMT_RGB24))) {
+               fprintf(stderr, "infcubes: failed to load crate texture\n");
+               return -1;
+       }
+
+       npixels = tex_crate.width * tex_crate.height;
+       src = (unsigned char*)tex_crate.pixels;
+       dst = tex_crate.pixels;
+       for(i=0; i<npixels; i++) {
+               int r = *src++;
+               int g = *src++;
+               int b = *src++;
+               *dst++ = PACK_RGB16(r, g, b);
+       }
        return 0;
 }
 
 static void destroy(void)
 {
+       img_free_pixels(tex_crate.pixels);
 }
 
 static void start(long trans_time)
@@ -43,8 +68,11 @@ static void start(long trans_time)
        g3d_load_identity();
        g3d_perspective(50.0, 1.3333333, 0.5, 100.0);
 
-       g3d_enable(G3D_LIGHTING);
+       g3d_enable(G3D_CULL_FACE);
+       g3d_disable(G3D_LIGHTING);
        g3d_enable(G3D_LIGHT0);
+
+       g3d_set_texture(tex_crate.width, tex_crate.height, tex_crate.pixels);
 }
 
 static void update(void)
@@ -67,43 +95,54 @@ static void draw(void)
 
        memset(fb_pixels, 0, fb_width * fb_height * 2);
 
-       draw_cube();
+       g3d_polygon_mode(G3D_FLAT);
+       draw_cube(-6);
+
+       g3d_polygon_mode(G3D_TEX);
+       draw_cube(1);
 
        swap_buffers(fb_pixels);
 }
 
-static void draw_cube(void)
+static void draw_cube(float sz)
 {
+       float hsz = sz * 0.5f;
        g3d_begin(G3D_QUADS);
+       g3d_color3b(255, 0, 0);
        g3d_normal(0, 0, 1);
-       g3d_vertex(-1, -1, 1);
-       g3d_vertex(1, -1, 1);
-       g3d_vertex(1, 1, 1);
-       g3d_vertex(-1, 1, 1);
+       g3d_texcoord(0, 0); g3d_vertex(-hsz, -hsz, hsz);
+       g3d_texcoord(1, 0); g3d_vertex(hsz, -hsz, hsz);
+       g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, hsz);
+       g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, hsz);
+       g3d_color3b(0, 255, 0);
        g3d_normal(1, 0, 0);
-       g3d_vertex(1, -1, 1);
-       g3d_vertex(1, -1, -1);
-       g3d_vertex(1, 1, -1);
-       g3d_vertex(1, 1, 1);
+       g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, hsz);
+       g3d_texcoord(1, 0); g3d_vertex(hsz, -hsz, -hsz);
+       g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, -hsz);
+       g3d_texcoord(0, 1); g3d_vertex(hsz, hsz, hsz);
+       g3d_color3b(0, 0, 255);
        g3d_normal(0, 0, -1);
-       g3d_vertex(1, -1, -1);
-       g3d_vertex(-1, -1, -1);
-       g3d_vertex(-1, 1, -1);
-       g3d_vertex(1, 1, -1);
+       g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, -hsz);
+       g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, -hsz);
+       g3d_texcoord(1, 1); g3d_vertex(-hsz, hsz, -hsz);
+       g3d_texcoord(0, 1); g3d_vertex(hsz, hsz, -hsz);
+       g3d_color3b(255, 0, 255);
        g3d_normal(-1, 0, 0);
-       g3d_vertex(-1, -1, -1);
-       g3d_vertex(-1, -1, 1);
-       g3d_vertex(-1, 1, 1);
-       g3d_vertex(-1, 1, -1);
+       g3d_texcoord(0, 0); g3d_vertex(-hsz, -hsz, -hsz);
+       g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, hsz);
+       g3d_texcoord(1, 1); g3d_vertex(-hsz, hsz, hsz);
+       g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, -hsz);
+       g3d_color3b(255, 255, 0);
        g3d_normal(0, 1, 0);
-       g3d_vertex(-1, 1, 1);
-       g3d_vertex(1, 1, 1);
-       g3d_vertex(1, 1, -1);
-       g3d_vertex(-1, 1, -1);
+       g3d_texcoord(0, 0); g3d_vertex(-hsz, hsz, hsz);
+       g3d_texcoord(1, 0); g3d_vertex(hsz, hsz, hsz);
+       g3d_texcoord(1, 1); g3d_vertex(hsz, hsz, -hsz);
+       g3d_texcoord(0, 1); g3d_vertex(-hsz, hsz, -hsz);
+       g3d_color3b(0, 255, 255);
        g3d_normal(0, -1, 0);
-       g3d_vertex(1, -1, 1);
-       g3d_vertex(-1, -1, 1);
-       g3d_vertex(-1, -1, -1);
-       g3d_vertex(1, -1, -1);
+       g3d_texcoord(0, 0); g3d_vertex(hsz, -hsz, hsz);
+       g3d_texcoord(1, 0); g3d_vertex(-hsz, -hsz, hsz);
+       g3d_texcoord(1, 1); g3d_vertex(-hsz, -hsz, -hsz);
+       g3d_texcoord(0, 1); g3d_vertex(hsz, -hsz, -hsz);
        g3d_end();
 }
diff --git a/src/mesh.c b/src/mesh.c
new file mode 100644 (file)
index 0000000..0027ccf
--- /dev/null
@@ -0,0 +1,233 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include "mesh.h"
+#include "3dgfx.h"
+
+int load_mesh(struct g3d_mesh *mesh, const char *fname)
+{
+       return -1;      /* TODO */
+}
+
+static struct {
+       struct g3d_vertex *varr;
+       const float *xform;
+} zsort_cls;
+
+static int zsort_cmp(const void *aptr, const void *bptr)
+{
+       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];
+
+       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;
+
+       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;
+}
+
+
+void zsort_mesh(struct g3d_mesh *m)
+{
+       zsort_cls.varr = m->varr;
+       zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
+
+       if(m->iarr) {
+               int nfaces = m->icount / m->prim;
+               qsort(m->iarr, nfaces, m->prim * sizeof *m->iarr, zsort_indexed_cmp);
+       } else {
+               int nfaces = m->vcount / m->prim;
+               qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
+       }
+}
+
+
+void draw_mesh(struct g3d_mesh *mesh)
+{
+       if(mesh->iarr) {
+               g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
+       } else {
+               g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
+       }
+}
+
+
+#define NORMAL(vp, x, y, z) do { vp->nx = x; vp->ny = y; vp->nz = z; } while(0)
+#define COLOR(vp, cr, cg, cb) do { vp->r = cr; vp->g = cg; vp->b = cb; } while(0)
+#define TEXCOORD(vp, tu, tv) do { vp->u = tu; vp->v = tv; } while(0)
+#define VERTEX(vp, vx, vy, vz) \
+       do { \
+               vp->x = vx; vp->y = vy; vp->z = vz; vp->w = 1.0f; \
+               ++vp; \
+       } while(0)
+
+int gen_cube(struct g3d_mesh *mesh, float sz, int sub)
+{
+       struct g3d_vertex *vptr;
+       float hsz = sz / 2.0;
+
+       mesh->prim = G3D_QUADS;
+       mesh->iarr = 0;
+       mesh->icount = 0;
+
+       mesh->vcount = 24;
+       if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
+               return -1;
+       }
+       vptr = mesh->varr;
+
+       /* -Z */
+       NORMAL(vptr, 0, 0, -1);
+       COLOR(vptr, 255, 0, 255);
+       VERTEX(vptr, hsz, -hsz, -hsz);
+       VERTEX(vptr, -hsz, -hsz, -hsz);
+       VERTEX(vptr, -hsz, hsz, -hsz);
+       VERTEX(vptr, hsz, hsz, -hsz);
+       /* -Y */
+       NORMAL(vptr, 0, -1, 0);
+       COLOR(vptr, 0, 255, 255);
+       VERTEX(vptr, -hsz, -hsz, -hsz);
+       VERTEX(vptr, hsz, -hsz, -hsz);
+       VERTEX(vptr, hsz, -hsz, hsz);
+       VERTEX(vptr, -hsz, -hsz, hsz);
+       /* -X */
+       NORMAL(vptr, -1, 0, 0);
+       COLOR(vptr, 255, 255, 0);
+       VERTEX(vptr, -hsz, -hsz, -hsz);
+       VERTEX(vptr, -hsz, -hsz, hsz);
+       VERTEX(vptr, -hsz, hsz, hsz);
+       VERTEX(vptr, -hsz, hsz, -hsz);
+       /* +X */
+       NORMAL(vptr, 1, 0, 0);
+       COLOR(vptr, 255, 0, 0);
+       VERTEX(vptr, hsz, -hsz, hsz);
+       VERTEX(vptr, hsz, -hsz, -hsz);
+       VERTEX(vptr, hsz, hsz, -hsz);
+       VERTEX(vptr, hsz, hsz, hsz);
+       /* +Y */
+       NORMAL(vptr, 0, 1, 0);
+       COLOR(vptr, 0, 255, 0);
+       VERTEX(vptr, -hsz, hsz, hsz);
+       VERTEX(vptr, hsz, hsz, hsz);
+       VERTEX(vptr, hsz, hsz, -hsz);
+       VERTEX(vptr, -hsz, hsz, -hsz);
+       /* +Z */
+       NORMAL(vptr, 0, 0, 1);
+       COLOR(vptr, 0, 0, 255);
+       VERTEX(vptr, -hsz, -hsz, hsz);
+       VERTEX(vptr, hsz, -hsz, hsz);
+       VERTEX(vptr, hsz, hsz, hsz);
+       VERTEX(vptr, -hsz, hsz, hsz);
+
+       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);
+}
+
+int gen_torus(struct g3d_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;
+
+       printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount);
+
+       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; i<uverts; i++) {
+               float u = (float)i / (float)(uverts - 1);
+               float theta = u * 2.0 * M_PI;
+               float rcent[3];
+
+               torusvec(rcent, theta, 0, rad, 0);
+
+               for(j=0; j<vverts; j++) {
+                       float v = (float)j / (float)(vverts - 1);
+                       float phi = v * 2.0 * M_PI;
+                       int chess = (i & 1) == (j & 1);
+
+                       torusvec(&vptr->x, 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;
+}
+
diff --git a/src/mesh.h b/src/mesh.h
new file mode 100644 (file)
index 0000000..92cc240
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef MESH_H_
+#define MESH_H_
+
+struct g3d_mesh {
+       int prim;
+       struct g3d_vertex *varr;
+       int16_t *iarr;
+       int vcount, icount;
+};
+
+int load_mesh(struct g3d_mesh *mesh, const char *fname);
+
+void zsort_mesh(struct g3d_mesh *mesh);
+void draw_mesh(struct g3d_mesh *mesh);
+
+int gen_cube(struct g3d_mesh *mesh, float sz, int sub);
+int gen_torus(struct g3d_mesh *mesh, float rad, float ringrad, int usub, int vsub);
+
+#endif /* MESH_H_ */
index f9bc61c..9404912 100644 (file)
@@ -9,13 +9,7 @@
 #include "gfxutil.h"
 #include "util.h"
 #include "metasurf.h"
-
-struct mesh {
-       int prim;
-       struct g3d_vertex *varr;
-       int16_t *iarr;
-       int vcount, icount;
-};
+#include "mesh.h"
 
 struct metaball {
        float energy;
@@ -26,8 +20,6 @@ static int init(void);
 static void destroy(void);
 static void start(long trans_time);
 static void draw(void);
-static void draw_mesh(struct mesh *mesh);
-static void zsort(struct mesh *m);
 
 static void calc_voxel_field(void);
 
@@ -41,7 +33,7 @@ static struct screen scr = {
 
 static float cam_theta, cam_phi = 25;
 static float cam_dist = 10;
-static struct mesh mmesh;
+static struct g3d_mesh mmesh;
 
 static struct metasurface *msurf;
 
@@ -104,49 +96,21 @@ static void start(long trans_time)
 
 static void update(void)
 {
-       static int prev_mx, prev_my;
-       static unsigned int prev_bmask;
+       int i, j;
+       float tsec = time_msec / 1000.0f;
+       static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8};
+       static float speed[] = {0.8, 1.4, 1.0};
+       static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}};
+       static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}};
 
-       if(mouse_bmask) {
-               if((mouse_bmask ^ prev_bmask) == 0) {
-                       int dx = mouse_x - prev_mx;
-                       int dy = mouse_y - prev_my;
+       mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
 
-                       if(dx || dy) {
-                               if(mouse_bmask & 1) {
-                                       cam_theta += dx * 1.0;
-                                       cam_phi += dy * 1.0;
+       for(i=0; i<NUM_MBALLS; i++) {
+               float t = (tsec + phase[i]) * speed[i];
 
-                                       if(cam_phi < -90) cam_phi = -90;
-                                       if(cam_phi > 90) cam_phi = 90;
-                               }
-                               if(mouse_bmask & 4) {
-                                       cam_dist += dy * 0.5;
-
-                                       if(cam_dist < 0) cam_dist = 0;
-                               }
-                       }
-               }
-       }
-       prev_mx = mouse_x;
-       prev_my = mouse_y;
-       prev_bmask = mouse_bmask;
-
-       {
-               int i, j;
-               float tsec = time_msec / 1000.0f;
-               static float phase[] = {0.0, M_PI / 3.0, M_PI * 0.8};
-               static float speed[] = {0.8, 1.4, 1.0};
-               static float scale[][3] = {{1, 2, 0.8}, {0.5, 1.6, 0.6}, {1.5, 0.7, 0.5}};
-               static float offset[][3] = {{0, 0, 0}, {0.25, 0, 0}, {-0.2, 0.15, 0.2}};
-
-               for(i=0; i<NUM_MBALLS; i++) {
-                       float t = (tsec + phase[i]) * speed[i];
-
-                       for(j=0; j<3; j++) {
-                               float x = sin(t + j * M_PI / 2.0);
-                               mball[i].pos[j] = offset[i][j] + x * scale[i][j];
-                       }
+               for(j=0; j<3; j++) {
+                       float x = sin(t + j * M_PI / 2.0);
+                       mball[i].pos[j] = offset[i][j] + x * scale[i][j];
                }
        }
 
@@ -180,7 +144,7 @@ static void draw(void)
 
        g3d_light_pos(0, -10, 10, 20);
 
-       zsort(&mmesh);
+       zsort_mesh(&mmesh);
 
        g3d_mtl_diffuse(0.6, 0.6, 0.6);
 
@@ -191,49 +155,6 @@ static void draw(void)
        swap_buffers(fb_pixels);
 }
 
-static void draw_mesh(struct mesh *mesh)
-{
-       if(mesh->iarr) {
-               g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
-       } else {
-               g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
-       }
-}
-
-static struct {
-       struct g3d_vertex *varr;
-       const float *xform;
-} zsort_cls;
-
-static int zsort_cmp(const void *aptr, const void *bptr)
-{
-       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];
-
-       return za - zb;
-}
-
-static void zsort(struct mesh *m)
-{
-       int nfaces = m->vcount / m->prim;
-
-       zsort_cls.varr = m->varr;
-       zsort_cls.xform = g3d_get_matrix(G3D_MODELVIEW, 0);
-
-       qsort(m->varr, nfaces, m->prim * sizeof *m->varr, zsort_cmp);
-}
-
 static void calc_voxel_field(void)
 {
        int i, j, k, b;
index 1815bb9..207fb31 100644 (file)
@@ -8,22 +8,12 @@
 #include "gfxutil.h"
 #include "polyfill.h"  /* just for struct pimage */
 #include "cfgopt.h"
-
-struct mesh {
-       int prim;
-       struct g3d_vertex *varr;
-       int16_t *iarr;
-       int vcount, icount;
-};
+#include "mesh.h"
 
 static int init(void);
 static void destroy(void);
 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 void zsort(struct mesh *m);
 static void draw_lowres_raster(void);
 static int gen_texture(struct pimage *img, int xsz, int ysz);
 
@@ -37,7 +27,7 @@ static struct screen scr = {
 
 static float cam_theta, cam_phi = 25;
 static float cam_dist = 3;
-static struct mesh cube, torus;
+static struct g3d_mesh cube, torus;
 
 static struct pimage tex;
 
@@ -54,7 +44,7 @@ static int init(void)
 {
        int i;
 
-       gen_cube(&cube, 1.0);
+       gen_cube(&cube, 1.0, 0);
        gen_torus(&torus, 1.0, 0.25, 24, 12);
        /* scale texcoords */
        for(i=0; i<torus.vcount; i++) {
@@ -97,33 +87,7 @@ static void start(long trans_time)
 
 static void update(void)
 {
-       static int prev_mx, prev_my;
-       static unsigned int prev_bmask;
-
-       if(mouse_bmask) {
-               if((mouse_bmask ^ prev_bmask) == 0) {
-                       int dx = mouse_x - prev_mx;
-                       int dy = mouse_y - prev_my;
-
-                       if(dx || dy) {
-                               if(mouse_bmask & 1) {
-                                       cam_theta += dx * 1.0;
-                                       cam_phi += dy * 1.0;
-
-                                       if(cam_phi < -90) cam_phi = -90;
-                                       if(cam_phi > 90) cam_phi = 90;
-                               }
-                               if(mouse_bmask & 4) {
-                                       cam_dist += dy * 0.5;
-
-                                       if(cam_dist < 0) cam_dist = 0;
-                               }
-                       }
-               }
-       }
-       prev_mx = mouse_x;
-       prev_my = mouse_y;
-       prev_bmask = mouse_bmask;
+       mouse_orbit_update(&cam_theta, &cam_phi, &cam_dist);
 }
 
 
@@ -145,7 +109,7 @@ static void draw(void)
 
        g3d_light_pos(0, -10, 10, 20);
 
-       zsort(&torus);
+       zsort_mesh(&torus);
 
        g3d_mtl_diffuse(0.4, 0.7, 1.0);
        g3d_set_texture(tex.width, tex.height, tex.pixels);
@@ -184,202 +148,6 @@ static void draw_debug(void)
        swap_buffers(fb_pixels);
 }
 
-static void draw_mesh(struct mesh *mesh)
-{
-       if(mesh->iarr) {
-               g3d_draw_indexed(mesh->prim, mesh->varr, mesh->vcount, mesh->iarr, mesh->icount);
-       } else {
-               g3d_draw(mesh->prim, mesh->varr, mesh->vcount);
-       }
-}
-
-#define NORMAL(vp, x, y, z) do { vp->nx = x; vp->ny = y; vp->nz = z; } while(0)
-#define COLOR(vp, cr, cg, cb) do { vp->r = cr; vp->g = cg; vp->b = cb; } while(0)
-#define TEXCOORD(vp, tu, tv) do { vp->u = tu; vp->v = tv; } while(0)
-#define VERTEX(vp, vx, vy, vz) \
-       do { \
-               vp->x = vx; vp->y = vy; vp->z = vz; vp->w = 1.0f; \
-               ++vp; \
-       } while(0)
-
-static int gen_cube(struct mesh *mesh, float sz)
-{
-       struct g3d_vertex *vptr;
-       float hsz = sz / 2.0;
-
-       mesh->prim = G3D_QUADS;
-       mesh->iarr = 0;
-       mesh->icount = 0;
-
-       mesh->vcount = 24;
-       if(!(mesh->varr = malloc(mesh->vcount * sizeof *mesh->varr))) {
-               return -1;
-       }
-       vptr = mesh->varr;
-
-       /* -Z */
-       NORMAL(vptr, 0, 0, -1);
-       COLOR(vptr, 255, 0, 255);
-       VERTEX(vptr, hsz, -hsz, -hsz);
-       VERTEX(vptr, -hsz, -hsz, -hsz);
-       VERTEX(vptr, -hsz, hsz, -hsz);
-       VERTEX(vptr, hsz, hsz, -hsz);
-       /* -Y */
-       NORMAL(vptr, 0, -1, 0);
-       COLOR(vptr, 0, 255, 255);
-       VERTEX(vptr, -hsz, -hsz, -hsz);
-       VERTEX(vptr, hsz, -hsz, -hsz);
-       VERTEX(vptr, hsz, -hsz, hsz);
-       VERTEX(vptr, -hsz, -hsz, hsz);
-       /* -X */
-       NORMAL(vptr, -1, 0, 0);
-       COLOR(vptr, 255, 255, 0);
-       VERTEX(vptr, -hsz, -hsz, -hsz);
-       VERTEX(vptr, -hsz, -hsz, hsz);
-       VERTEX(vptr, -hsz, hsz, hsz);
-       VERTEX(vptr, -hsz, hsz, -hsz);
-       /* +X */
-       NORMAL(vptr, 1, 0, 0);
-       COLOR(vptr, 255, 0, 0);
-       VERTEX(vptr, hsz, -hsz, hsz);
-       VERTEX(vptr, hsz, -hsz, -hsz);
-       VERTEX(vptr, hsz, hsz, -hsz);
-       VERTEX(vptr, hsz, hsz, hsz);
-       /* +Y */
-       NORMAL(vptr, 0, 1, 0);
-       COLOR(vptr, 0, 255, 0);
-       VERTEX(vptr, -hsz, hsz, hsz);
-       VERTEX(vptr, hsz, hsz, hsz);
-       VERTEX(vptr, hsz, hsz, -hsz);
-       VERTEX(vptr, -hsz, hsz, -hsz);
-       /* +Z */
-       NORMAL(vptr, 0, 0, 1);
-       COLOR(vptr, 0, 0, 255);
-       VERTEX(vptr, -hsz, -hsz, hsz);
-       VERTEX(vptr, hsz, -hsz, hsz);
-       VERTEX(vptr, hsz, hsz, hsz);
-       VERTEX(vptr, -hsz, hsz, hsz);
-
-       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;
-
-       printf("generating torus with %d faces (%d vertices)\n", nfaces, mesh->vcount);
-
-       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; i<uverts; i++) {
-               float u = (float)i / (float)(uverts - 1);
-               float theta = u * 2.0 * M_PI;
-               float rcent[3];
-
-               torusvec(rcent, theta, 0, rad, 0);
-
-               for(j=0; j<vverts; j++) {
-                       float v = (float)j / (float)(vverts - 1);
-                       float phi = v * 2.0 * M_PI;
-                       int chess = (i & 1) == (j & 1);
-
-                       torusvec(&vptr->x, 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 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);
-}
 
 static void draw_huge_pixel(uint16_t *dest, int dest_width, uint16_t color)
 {
index 6d200b7..76dd044 100644 (file)
@@ -43,6 +43,9 @@ void perf_end(void);
        "sub eax, [perf_start_count]" \
        "mov [perf_interval_count], eax" \
        modify [eax ebx ecx edx];
+
+void debug_break(void);
+#pragma aux debug_break = "int 3";
 #endif
 
 #ifdef __GNUC__
@@ -63,6 +66,9 @@ void perf_end(void);
        : "=m"(perf_interval_count) \
        : "m"(perf_start_count) \
        : "%eax", "%ebx", "%ecx", "%edx")
+
+#define debug_break() \
+       asm volatile ("int $3")
 #endif
 
 #ifdef _MSC_VER
@@ -86,6 +92,11 @@ void perf_end(void);
                        mov [perf_interval_count], eax \
                } \
        } while(0)
+
+#define debug_break() \
+       do { \
+               __asm { int 3 } \
+       } while(0)
 #endif
 
 #endif /* UTIL_H_ */