mesh dump routines
authorJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 1 Mar 2019 12:50:34 +0000 (14:50 +0200)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Fri, 1 Mar 2019 12:50:34 +0000 (14:50 +0200)
src/cmesh.c
src/game.c
src/gamescr.c

index 115f778..993fa2c 100644 (file)
@@ -4,6 +4,7 @@
 #include <assert.h>
 #include "opengl.h"
 #include "cmesh.h"
+#include "logger.h"
 
 
 struct cmesh_vattrib {
@@ -1232,7 +1233,134 @@ void cmesh_texcoord_gen_plane(struct cmesh *cm, cgm_vec3 *norm, cgm_vec3 *tang);
 void cmesh_texcoord_gen_box(struct cmesh *cm);
 void cmesh_texcoord_gen_cylinder(struct cmesh *cm);
 
-int cmesh_dump(struct cmesh *cm, const char *fname);
-int cmesh_dump_file(struct cmesh *cm, FILE *fp);
-int cmesh_dump_obj(struct cmesh *cm, const char *fname);
-int cmesh_dump_obj_file(struct cmesh *cm, FILE *fp, int voffs);
+int cmesh_dump(struct cmesh *cm, const char *fname)
+{
+       FILE *fp = fopen(fname, "wb");
+       if(fp) {
+               int res = cmesh_dump_file(cm, fp);
+               fclose(fp);
+               return res;
+       }
+       return -1;
+}
+
+int cmesh_dump_file(struct cmesh *cm, FILE *fp)
+{
+       static const char *label[] = { "pos", "nor", "tan", "tex", "col", "bw", "bid", "tex2" };
+       static const char *elemfmt[] = { 0, " %s(%g)", " %s(%g, %g)", " %s(%g, %g, %g)", " %s(%g, %g, %g, %g)", 0 };
+       int i, j;
+
+       if(!cmesh_has_attrib(cm, CMESH_ATTR_VERTEX)) {
+               return -1;
+       }
+
+       fprintf(fp, "VERTEX ATTRIBUTES\n");
+
+       for(i=0; i<cm->nverts; i++) {
+               fprintf(fp, "%5u:", i);
+               for(j=0; j<CMESH_NUM_ATTR; j++) {
+                       if(cmesh_has_attrib(cm, j)) {
+                               const float *v = cmesh_attrib_at_ro(cm, j, i);
+                               int nelem = cm->vattr[j].nelem;
+                               fprintf(fp, elemfmt[nelem], label[j], v[0], nelem > 1 ? v[1] : 0.0f,
+                                               nelem > 2 ? v[2] : 0.0f, nelem > 3 ? v[3] : 0.0f);
+                       }
+               }
+               fputc('\n', fp);
+       }
+
+       if(cmesh_indexed(cm)) {
+               const unsigned int *idx = cmesh_index_ro(cm);
+               int numidx = cmesh_index_count(cm);
+               int numtri = numidx / 3;
+               assert(numidx % 3 == 0);
+
+               fprintf(fp, "FACES\n");
+
+               for(i=0; i<numtri; i++) {
+                       fprintf(fp, "%5d: %d %d %d\n", i, idx[0], idx[1], idx[2]);
+                       idx += 3;
+               }
+       }
+       return 0;
+}
+
+int cmesh_dump_obj(struct cmesh *cm, const char *fname)
+{
+       FILE *fp = fopen(fname, "wb");
+       if(fp) {
+               int res = cmesh_dump_obj_file(cm, fp, 0);
+               fclose(fp);
+               return res;
+       }
+       return -1;
+}
+
+int cmesh_dump_obj_file(struct cmesh *cm, FILE *fp, int voffs)
+{
+       int i, j, num, nelem;
+
+       if(!cmesh_has_attrib(cm, CMESH_ATTR_VERTEX)) {
+               return -1;
+       }
+
+
+       nelem = cm->vattr[CMESH_ATTR_VERTEX].nelem;
+       if((num = dynarr_size(cm->vattr[CMESH_ATTR_VERTEX].data)) != cm->nverts * nelem) {
+               warning_log("vertex array size (%d) != nverts (%d)\n", num, cm->nverts);
+       }
+       for(i=0; i<cm->nverts; i++) {
+               const float *v = cmesh_attrib_at_ro(cm, CMESH_ATTR_VERTEX, i);
+               fprintf(fp, "v %f %f %f\n", v[0], nelem > 1 ? v[1] : 0.0f, nelem > 2 ? v[2] : 0.0f);
+       }
+
+       if(cmesh_has_attrib(cm, CMESH_ATTR_NORMAL)) {
+               nelem = cm->vattr[CMESH_ATTR_NORMAL].nelem;
+               if((num = dynarr_size(cm->vattr[CMESH_ATTR_NORMAL].data)) != cm->nverts * nelem) {
+                       warning_log("normal array size (%d) != nverts (%d)\n", num, cm->nverts);
+               }
+               for(i=0; i<cm->nverts; i++) {
+                       const float *v = cmesh_attrib_at_ro(cm, CMESH_ATTR_NORMAL, i);
+                       fprintf(fp, "vn %f %f %f\n", v[0], nelem > 1 ? v[1] : 0.0f, nelem > 2 ? v[2] : 0.0f);
+               }
+       }
+
+       if(cmesh_has_attrib(cm, CMESH_ATTR_TEXCOORD)) {
+               nelem = cm->vattr[CMESH_ATTR_TEXCOORD].nelem;
+               if((num = dynarr_size(cm->vattr[CMESH_ATTR_TEXCOORD].data)) != cm->nverts * nelem) {
+                       warning_log("texcoord array size (%d) != nverts (%d)\n", num, cm->nverts);
+               }
+               for(i=0; i<cm->nverts; i++) {
+                       const float *v = cmesh_attrib_at_ro(cm, CMESH_ATTR_TEXCOORD, i);
+                       fprintf(fp, "vt %f %f\n", v[0], nelem > 1 ? v[1] : 0.0f);
+               }
+       }
+
+       if(cmesh_indexed(cm)) {
+               const unsigned int *idxptr = cmesh_index_ro(cm);
+               int numidx = cmesh_index_count(cm);
+               int numtri = numidx / 3;
+               assert(numidx % 3 == 0);
+
+               for(i=0; i<numtri; i++) {
+                       fputc('f', fp);
+                       for(j=0; j<3; j++) {
+                               unsigned int idx = *idxptr++ + 1 + voffs;
+                               fprintf(fp, " %u/%u/%u", idx, idx, idx);
+                       }
+                       fputc('\n', fp);
+               }
+       } else {
+               int numtri = cm->nverts / 3;
+               unsigned int idx = 1 + voffs;
+               for(i=0; i<numtri; i++) {
+                       fputc('f', fp);
+                       for(j=0; j<3; j++) {
+                               fprintf(fp, " %u/%u/%u", idx, idx, idx);
+                               ++idx;
+                       }
+                       fputc('\n', fp);
+               }
+       }
+       return 0;
+}
index a729996..f2d888a 100644 (file)
@@ -12,7 +12,6 @@
 static void calc_framerate(void);
 static void print_framerate(void);
 
-float view_matrix[16], proj_matrix[16];
 static int should_swap;
 static unsigned long framerate;
 
@@ -40,6 +39,11 @@ int game_init(int argc, char **argv)
                should_swap = goatvr_should_swap();
        }
 
+       glEnable(GL_DEPTH_TEST);
+       glEnable(GL_CULL_FACE);
+       glEnable(GL_LIGHTING);
+       glEnable(GL_LIGHT0);
+
        return 0;
 }
 
index 0bd7f70..cc1a837 100644 (file)
@@ -32,6 +32,9 @@ struct game_screen game_screen = {
 };
 
 static struct cmesh *blkmesh;
+static float cam_theta, cam_phi, cam_dist = 6;
+static int bnstate[16];
+static int prev_mx, prev_my;
 
 static int init(void)
 {
@@ -42,6 +45,7 @@ static int init(void)
                fprintf(stderr, "failed to load block model\n");
                return -1;
        }
+       cmesh_dump_obj(blkmesh, "dump.obj");
        return 0;
 }
 
@@ -64,7 +68,9 @@ static void update(float dt)
 
 static void draw(void)
 {
-       glTranslatef(0, 0, 6);
+       glTranslatef(0, 0, -cam_dist);
+       glRotatef(cam_phi, 1, 0, 0);
+       glRotatef(cam_theta, 0, 1, 0);
 
        cmesh_draw(blkmesh);
 }
@@ -79,10 +85,29 @@ static void keyboard(int key, int pressed)
 
 static void mouse(int bn, int pressed, int x, int y)
 {
+       bnstate[bn] = pressed;
+       prev_mx = x;
+       prev_my = y;
 }
 
 static void motion(int x, int y)
 {
+       float dx = x - prev_mx;
+       float dy = y - prev_my;
+       prev_mx = x;
+       prev_my = y;
+
+       if(bnstate[0]) {
+               cam_theta += dx * 0.5;
+               cam_phi += dy * 0.5;
+
+               if(cam_phi < -90) cam_phi = -90;
+               if(cam_phi > 90) cam_phi = 90;
+       }
+       if(bnstate[2]) {
+               cam_dist += dy * 0.1;
+               if(cam_dist < 0) cam_dist = 0;
+       }
 }
 
 static void wheel(int dir)