# HG changeset patch # User John Tsiombikas # Date 1327112064 -7200 # Node ID b30f83409769ca2fcbc5733f599bd9dd0e79fb4a # Parent c15992cedec97d286f07903ef18173807c3cac48 foo diff -r c15992cedec9 -r b30f83409769 scnviewgl/scnviewgl.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scnviewgl/scnviewgl.c Sat Jan 21 04:14:24 2012 +0200 @@ -0,0 +1,262 @@ +#include +#include + +#ifndef __APPLE__ +#include +#else +#include +#endif + +#include "scene.h" + +void disp(void); +void render_scene(struct scenefile *scn); +void render_mesh(struct mesh *m); +void reshape(int x, int y); +void keyb(unsigned char key, int x, int y); +void mouse(int bn, int state, int x, int y); +void motion(int x, int y); +void sball_motion(int x, int y, int z); +void sball_rotate(int x, int y, int z); +void sball_button(int bn, int state); +int parse_args(int argc, char **argv); + +struct scenefile *scn; +float cam_theta, cam_phi, cam_dist = 10; + +int main(int argc, char **argv) +{ + float ldir[] = {-1, 1, 1, 0}; + + glutInitWindowSize(800, 600); + glutInit(&argc, argv); + + if(parse_args(argc, argv) == -1) { + return 1; + } + + glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE); + glutCreateWindow("OpenGL Scene Viewer"); + + glutDisplayFunc(disp); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + glutMotionFunc(motion); + glutSpaceballMotionFunc(sball_motion); + glutSpaceballRotateFunc(sball_rotate); + glutSpaceballButtonFunc(sball_button); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_CULL_FACE); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glLightfv(GL_LIGHT0, GL_POSITION, ldir); + + glutMainLoop(); + return 0; +} + + +void disp(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glRotatef(cam_theta, 0, 1, 0); + glRotatef(cam_phi, 1, 0, 0); + glTranslatef(0, 0, -cam_dist); + + render_scene(scn); + + glutSwapBuffers(); +} + +void render_scene(struct scenefile *scn) +{ + int i, num = scnfile_count(scn); + + for(i=0; i= 0) { + ptr = mesh_attrib_elem(m, nloc, *nidx++); + assert(ptr); + glNormal3fv(ptr); + } + if(tloc >= 0) { + ptr = mesh_attrib_elem(m, tloc, *tidx++); + assert(ptr); + glTexCoord2fv(ptr); + } + ptr = mesh_attrib_elem(m, vloc, *vidx++); + assert(ptr); + glVertex3fv(ptr); + } + } + glEnd(); +} + + +void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(45.0, (float)x / (float)y, 0.5, 1000.0); +} + +void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + case 'q': + exit(0); + + case 'c': + { + static int flip; + if(++flip & 1) { + glFrontFace(GL_CW); + } else { + glFrontFace(GL_CCW); + } + } + break; + + case 'l': + { + static int lton = 1; + if(++lton & 1) { + glEnable(GL_LIGHTING); + } else { + glDisable(GL_LIGHTING); + } + } + break; + + case 'w': + { + static int wire; + if(++wire & 1) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } else { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } + } + break; + + default: + break; + } +} + +int prev_x, prev_y; +int bnstate[32]; + +void mouse(int bn, int state, int x, int y) +{ + bnstate[bn] = state == GLUT_DOWN ? 1 : 0; + prev_x = x; + prev_y = y; +} + +void motion(int x, int y) +{ + int dx = x - prev_x; + int dy = y - prev_y; + prev_x = x; + prev_y = y; + + if(bnstate[1]) { + cam_theta += (float)dx; + cam_phi += (float)dy; + + if(cam_phi < -90) + cam_phi = -90; + if(cam_phi > 90) + cam_phi = 90; + } + if(bnstate[3]) { + cam_dist += (float)dy * 0.1; + + if(cam_dist < 0) + cam_dist = 0; + } +} + +void sball_motion(int x, int y, int z) +{ +} + +void sball_rotate(int x, int y, int z) +{ +} + +void sball_button(int bn, int state) +{ +} + +int parse_args(int argc, char **argv) +{ + int i, loaded_something = 0; + + for(i=0; i +#include +#include "scene.h" + +#ifdef __GNUC__ +#define PACKED __attribute__((packed)) +#endif + + +struct header { + char magic[10]; + int fmt_ver; +} PACKED; + +struct vertex { + char flags; + float pos[3]; + char bone_id; /* -1 means no bone */ + char ref_count; +} PACKED; + +struct triangle { + uint16_t flags; + uint16_t v[3]; + float vnorm[3][3]; + float s[3]; + float t[3]; + unsigned char smoothing_group; + unsigned char group_idx; +} PACKED; + + diff -r c15992cedec9 -r b30f83409769 src/mesh.c --- a/src/mesh.c Sun Jan 15 08:32:19 2012 +0200 +++ b/src/mesh.c Sat Jan 21 04:14:24 2012 +0200 @@ -94,6 +94,14 @@ return ma->elem_sz; } +void *vattr_elem(struct mesh_vertattr *ma, int elem) +{ + int count = dynarr_size(ma->data); + if(elem >= count) { + return 0; + } + return (char*)ma->data + elem * ma->elem_sz; +} /* -------- mesh -------- */ @@ -116,7 +124,7 @@ void mesh_destroy(struct mesh *m) { - int i, nattr = mesh_attr_count(m); + int i, nattr = mesh_num_attribs(m); for(i=0; iattr + i); @@ -148,6 +156,11 @@ return m->name ? m->name : ""; } +int mesh_poly_type(struct mesh *m) +{ + return m->poly_nverts; +} + int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr) { struct mesh_polyidx pidx; @@ -171,9 +184,14 @@ return 0; } +int mesh_num_attribs(struct mesh *m) +{ + return dynarr_size(m->attr); +} + int mesh_find_attrib(struct mesh *m, const char *name) { - int i, nattr = mesh_attr_count(m); + int i, nattr = mesh_num_attribs(m); for(i=0; iattr[i].name && strcmp(m->attr[i].name, name) == 0) { @@ -183,14 +201,30 @@ return -1; } -int mesh_attr_count(struct mesh *m) +struct mesh_vertattr *mesh_attrib(struct mesh *m, int loc) { - return dynarr_size(m->attr); + return loc >= 0 ? m->attr + loc : 0; +} + +void *mesh_attrib_data(struct mesh *m, int loc) +{ + return loc >= 0 ? m->attr[loc].data : 0; +} + +int *mesh_poly_data(struct mesh *m, int loc) +{ + return loc >= 0 ? m->polyidx[loc].data : 0; +} + + +int mesh_attrib_count(struct mesh *m, int loc) +{ + return loc >= 0 ? vattr_count(m->attr + loc) : 0; } int mesh_poly_count(struct mesh *m) { - int i, nattr = mesh_attr_count(m); + int i, nattr = mesh_num_attribs(m); for(i=0; ipolyidx[i].data); @@ -201,9 +235,19 @@ return 0; } +void *mesh_attrib_elem(struct mesh *m, int loc, int elem) +{ + return loc >= 0 ? vattr_elem(m->attr + loc, elem) : 0; +} + +int mesh_attrib_elem_size(struct mesh *m, int loc) +{ + return loc >= 0 ? m->attr[loc].elem_sz : 0; +} + int mesh_add_polyref(struct mesh *m, int attr_loc, ...) { - int i, nattr = mesh_attr_count(m); + int i, nattr = mesh_num_attribs(m); int *poly = alloca(m->poly_nverts * sizeof *poly); va_list ap; void *tmp; diff -r c15992cedec9 -r b30f83409769 src/mesh.h --- a/src/mesh.h Sun Jan 15 08:32:19 2012 +0200 +++ b/src/mesh.h Sat Jan 21 04:14:24 2012 +0200 @@ -22,6 +22,7 @@ void *vattr_pointer(struct mesh_vertattr *ma); int vattr_count(struct mesh_vertattr *ma); int vattr_elem_size(struct mesh_vertattr *ma); +void *vattr_elem(struct mesh_vertattr *ma, int elem); /* --- mesh --- */ @@ -31,12 +32,23 @@ int mesh_set_name(struct mesh *m, const char *name); const char *mesh_get_name(struct mesh *m); +/* 1 - points, 2 - lines, 3 - triangles, 4 - quads */ +int mesh_poly_type(struct mesh *m); + int mesh_add_attrib(struct mesh *m, struct mesh_vertattr *attr); +int mesh_num_attribs(struct mesh *m); int mesh_find_attrib(struct mesh *m, const char *name); -int mesh_attr_count(struct mesh *m); +struct mesh_vertattr *mesh_attrib(struct mesh *m, int loc); +void *mesh_attrib_data(struct mesh *m, int loc); +int *mesh_poly_data(struct mesh *m, int loc); + +int mesh_attrib_count(struct mesh *m, int loc); int mesh_poly_count(struct mesh *m); +void *mesh_attrib_elem(struct mesh *m, int loc, int elem); +int mesh_attrib_elem_size(struct mesh *m, int loc); + /* the variable arguments correspond to the N indices of the N-gon * for this particular vertex attribute (attr_loc, retrieved by * mesh_find_attrib) diff -r c15992cedec9 -r b30f83409769 src/scene.c --- a/src/scene.c Sun Jan 15 08:32:19 2012 +0200 +++ b/src/scene.c Sat Jan 21 04:14:24 2012 +0200 @@ -1,5 +1,7 @@ +#include #include #include +#include #include "scene.h" #include "dynarr.h" @@ -7,6 +9,19 @@ struct mesh **mesh; }; +struct scnfile_io { + void *uptr; /* user-data */ + + size_t (*read)(void *buf, size_t bytes, void *uptr); + size_t (*write)(void *buf, size_t bytes, void *uptr); + long (*seek)(long offs, int whence, void *uptr); +}; + +static size_t def_read(void *buf, size_t bytes, void *uptr); +static size_t def_write(void *buf, size_t bytes, void *uptr); +static long def_seek(long offset, int whence, void *uptr); + + int scnfile_init(struct scenefile *scn) { if(!(scn->mesh = dynarr_alloc(0, sizeof *scn->mesh))) { @@ -59,6 +74,27 @@ int scnfile_load(struct scenefile *scn, const char *fname) { + FILE *fp; + int res; + + if(!(fp = fopen(fname, "rb"))) { + fprintf(stderr, "scenefile: failed to load: %s: %s\n", fname, strerror(errno)); + return -1; + } + res = scnfile_read_file(scn, fp); + fclose(fp); + return res; +} + +int scnfile_read_file(struct scenefile *scn, FILE *fp) +{ + struct scnfile_io io = {0, def_read, def_write, def_seek}; + io.uptr = fp; + return scnfile_read(scn, &io); +} + +int scnfile_read(struct scenefile *scn, struct scnfile_io *io) +{ return -1; /* TODO */ } @@ -86,3 +122,44 @@ { return dynarr_size(scn->mesh); } + + +void scnfile_io_user_data(struct scnfile_io *io, void *uptr) +{ + io->uptr = uptr; +} + +void scnfile_io_read_func(struct scnfile_io *io, size_t (*read)(void*, size_t, void*)) +{ + io->read = read; +} + +void scnfile_io_write_func(struct scnfile_io *io, size_t (*write)(void*, size_t, void*)) +{ + io->write = write; +} + +void scnfile_io_seek_func(struct scnfile_io *io, long (*seek)(long, int, void*)) +{ + io->seek = seek; +} + + +static size_t def_read(void *buf, size_t bytes, void *uptr) +{ + return uptr ? fread(buf, 1, bytes, uptr) : 0; +} + +static size_t def_write(void *buf, size_t bytes, void *uptr) +{ + return uptr ? fwrite(buf, 1, bytes, uptr) : 0; +} + +static long def_seek(long offset, int whence, void *uptr) +{ + if(!uptr || fseek(uptr, offset, whence) == -1) { + return -1; + } + return ftell(uptr); +} + diff -r c15992cedec9 -r b30f83409769 src/scene.h --- a/src/scene.h Sun Jan 15 08:32:19 2012 +0200 +++ b/src/scene.h Sat Jan 21 04:14:24 2012 +0200 @@ -4,6 +4,7 @@ #include "mesh.h" struct scenefile; +struct scnfile_io; #ifdef __cplusplus extern "C" { @@ -20,11 +21,49 @@ int scnfile_load(struct scenefile *scn, const char *fname); +int scnfile_read_file(struct scenefile *scn, FILE *fp); +int scnfile_read(struct scenefile *scn, struct scnfile_io *io); int scnfile_find_mesh(struct scenefile *scn, const char *fname); struct mesh *scnfile_mesh(struct scenefile *scn, int idx); int scnfile_count(struct scenefile *scn); + +/* These functions can be used to fill an scnfile_io struct before it's passed to + * one of the user-defined i/o image reading/writing functions (scnfile_read/scnfile_write). + * + * User-defined i/o functions: + * + * - size_t read_func(void *buffer, size_t bytes, void *user_ptr) + * Must try to fill the buffer with the specified number of bytes, and return + * the number of bytes actually read. + * + * - size_t write_func(void *buffer, size_t bytes, void *user_ptr) + * Must write the specified number of bytes from the supplied buffer and return + * the number of bytes actually written. + * + * - long seek_func(long offset, int whence, void *user_ptr) + * Must seek offset bytes from: the beginning of the file if whence is SEEK_SET, + * the current position if whence is SEEK_CUR, or the end of the file if whence is + * SEEK_END, and return the resulting file offset from the beginning of the file. + * (i.e. seek_func(0, SEEK_CUR, user_ptr); must be equivalent to an ftell). + * + * All three functions get the user-data pointer set through scnfile_io_set_user_data + * as their last argument. + * + * Note: obviously you don't need to set a write function if you're only going + * to call scnfile_read, or the read and seek function if you're only going to call + * scnfile_write. + * + * Note: if the user-supplied write function is buffered, make sure to flush + * (or close the file) after scnfile_write returns. + */ +void scnfile_io_user_data(struct scnfile_io *io, void *uptr); +void scnfile_io_read_func(struct scnfile_io *io, size_t (*read)(void*, size_t, void*)); +void scnfile_io_write_func(struct scnfile_io *io, size_t (*write)(void*, size_t, void*)); +void scnfile_io_seek_func(struct scnfile_io *io, long (*seek)(long, int, void*)); + + #ifdef __cplusplus } #endif