X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;f=src%2Fcmesh.c;h=993fa2cc0d8554a06deb6771c3332da445e8ac86;hb=a6bd42c022f3b1c12a54444e5e469215f2ecbe27;hp=4d7425182bcd080250745f0d5188db6060bda0fc;hpb=1b62e1cf0e1cf019b42ee232ba838d06c55b8cda;p=vrtris diff --git a/src/cmesh.c b/src/cmesh.c index 4d74251..993fa2c 100644 --- a/src/cmesh.c +++ b/src/cmesh.c @@ -4,6 +4,7 @@ #include #include "opengl.h" #include "cmesh.h" +#include "logger.h" struct cmesh_vattrib { @@ -49,6 +50,7 @@ static void update_wire_ibo(struct cmesh *cm); static void calc_aabb(struct cmesh *cm); static void calc_bsph(struct cmesh *cm); +static int def_nelem[CMESH_NUM_ATTR] = {3, 3, 3, 2, 4, 4, 4, 2}; static int sdr_loc[CMESH_NUM_ATTR] = {0, 1, 2, 3, 4, 5, 6, 7}; static int use_custom_sdr_attr; @@ -366,6 +368,74 @@ int cmesh_attrib_count(struct cmesh *cm, int attr) return cmesh_has_attrib(cm, attr) ? cm->nverts : 0; } +int cmesh_push_attrib(struct cmesh *cm, int attr, float *v) +{ + float *vptr; + int i, cursz, newsz; + + if(!cm->vattr[attr].nelem) { + cm->vattr[attr].nelem = def_nelem[attr]; + } + + cursz = dynarr_size(cm->vattr[attr].data); + newsz = cursz + cm->vattr[attr].nelem; + if(!(vptr = dynarr_resize(cm->vattr[attr].data, newsz))) { + return -1; + } + cm->vattr[attr].data = vptr; + vptr += cursz; + + for(i=0; ivattr[attr].nelem; i++) { + *vptr++ = *v++; + } + cm->vattr[attr].data_valid = 1; + cm->vattr[attr].vbo_valid = 0; + + if(attr == CMESH_ATTR_VERTEX) { + cm->nverts = newsz / cm->vattr[attr].nelem; + } + return 0; +} + +int cmesh_push_attrib1f(struct cmesh *cm, int attr, float x) +{ + float v[4]; + v[0] = x; + v[1] = v[2] = 0.0f; + v[3] = 1.0f; + return cmesh_push_attrib(cm, attr, v); +} + +int cmesh_push_attrib2f(struct cmesh *cm, int attr, float x, float y) +{ + float v[4]; + v[0] = x; + v[1] = y; + v[2] = 0.0f; + v[3] = 1.0f; + return cmesh_push_attrib(cm, attr, v); +} + +int cmesh_push_attrib3f(struct cmesh *cm, int attr, float x, float y, float z) +{ + float v[4]; + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = 1.0f; + return cmesh_push_attrib(cm, attr, v); +} + +int cmesh_push_attrib4f(struct cmesh *cm, int attr, float x, float y, float z, float w) +{ + float v[4]; + v[0] = x; + v[1] = y; + v[2] = z; + v[3] = w; + return cmesh_push_attrib(cm, attr, v); +} + /* indices can be 0, in which case only memory is allocated * returns pointer to the index array */ @@ -435,6 +505,20 @@ int cmesh_index_count(struct cmesh *cm) return cm->nfaces * 3; } +int cmesh_push_index(struct cmesh *cm, unsigned int idx) +{ + unsigned int *iptr; + if(!(iptr = dynarr_push(cm->idata, &idx))) { + return -1; + } + cm->idata = iptr; + cm->idata_valid = 1; + cm->ibo_valid = 0; + + cm->nfaces = dynarr_size(cm->idata) / 3; + return 0; +} + int cmesh_poly_count(struct cmesh *cm) { if(cm->nfaces) { @@ -1149,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; inverts; i++) { + fprintf(fp, "%5u:", i); + for(j=0; jvattr[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; ivattr[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; inverts; 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; inverts; 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; inverts; 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; inverts / 3; + unsigned int idx = 1 + voffs; + for(i=0; i