8 int nelem; /* num elements per attribute [1, 4] */
9 float *data; /* dynarr */
11 int vbo_valid, data_valid;
17 unsigned int nverts, nfaces;
19 /* current value for each attribute for the immediate mode interface */
20 cgm_vec4 cur_val[CMESH_NUM_ATTR];
22 unsigned int buffer_objects[CMESH_NUM_ATTR + 1];
23 struct cmesh_vattrib vattr[CMESH_NUM_ATTR];
25 unsigned int *idata; /* dynarr */
27 int ibo_valid, idata_valid;
29 /* index buffer for wireframe rendering (constructed on demand) */
30 unsigned int wire_ibo;
33 /* axis-aligned bounding box */
34 cgm_vec3 aabb_min, aabb_max;
42 static int sdr_loc[CMESH_NUM_ATTR] = {0, 1, 2, 3, 4, 5, 6, 7};
46 void cmesh_set_attrib_sdrloc(int attr, int loc)
51 int cmesh_get_attrib_sdrloc(int attr)
56 void cmesh_clear_attrib_sdrloc(void)
59 for(i=0; i<CMESH_NUM_ATTR; i++) {
65 struct cmesh *cmesh_alloc(void)
69 if(!(cm = malloc(sizeof *cm))) {
72 if(cmesh_init(cm) == -1) {
79 void cmesh_free(struct cmesh *cm)
85 int cmesh_init(struct cmesh *cm)
90 glGenBuffers(CMESH_NUM_ATTR + 1, cm->buffer_objects);
92 for(i=0; i<CMESH_NUM_ATTR; i++) {
93 if(!(cm->vattr[i].data = dynarr_alloc(0, sizeof(float)))) {
97 cm->vattr[i].vbo = buffer_objects[i];
100 cm->ibo = buffer_objects[CMESH_NUM_ATTR];
101 if(!(cm->idata = dynarr_alloc(0, sizeof *cm->idata))) {
108 void cmesh_destroy(struct cmesh *cm)
112 for(i=0; i<CMESH_NUM_ATTR; i++) {
113 dynarr_free(cm->vattr[i].data);
115 dynarr_free(cm->idata);
117 glDeleteBuffers(CMESH_NUM_ATTR + 1, cm->buffer_objects);
119 glDeleteBuffers(1, &cm->wire_ibo);
123 void cmesh_clear(struct cmesh *cm)
125 memset(cm, 0, sizeof *cm);
127 cgm_wcons(cm->cur_val + CMESH_ATTR_COLOR, 1, 1, 1, 1);
131 void cmesh_copy(struct cmesh *cmdest, struct cmesh *cmsrc);
133 void cmesh_set_name(struct cmesh *cm, const char *name);
134 const char *cmesh_name(struct cmesh *cm);
136 int cmesh_has_attrib(struct cmesh *cm, int attr);
137 int cmesh_indexed(struct cmesh *cm);
139 /* vdata can be 0, in which case only memory is allocated
140 * returns pointer to the attribute array
142 float *cmesh_set_attrib(struct cmesh *cm, int attr, int nelem, unsigned int num,
144 float *cmesh_attrib(struct cmesh *cm, int attr); /* invalidates VBO */
145 const float *cmesh_attrib_ro(struct cmesh *cm, int attr); /* doesn't invalidate */
146 int cmesh_attrib_count(struct cmesh *cm, int attr);
148 /* indices can be 0, in which case only memory is allocated
149 * returns pointer to the index array
151 unsigned int *cmesh_set_index(struct cmesh *cm, int num, const unsigned int *indices);
152 unsigned int *cmesh_index(struct cmesh *cm); /* invalidates IBO */
153 const unsigned int *cmesh_index_ro(struct cmesh *cm); /* doesn't invalidate */
154 int cmesh_index_count(struct cmesh *cm);
156 int get_poly_count(struct cmesh *cm);
158 /* attr can be -1 to invalidate all attributes */
159 void cmesh_invalidate_attrib(struct cmesh *cm, int attr);
160 void cmesh_invalidate_index(struct cmesh *cm);
162 int cmesh_append(struct cmesh *cmdest, struct cmesh *cmsrc);
164 /* immediate-mode style mesh construction interface */
165 int cmesh_vertex(struct cmesh *cm, float x, float y, float z);
166 int cmesh_normal(struct cmesh *cm, float nx, float ny, float nz);
167 int cmesh_tangent(struct cmesh *cm, float tx, float ty, float tz);
168 int cmesh_texcoord(struct cmesh *cm, float u, float v, float w);
169 int cmesh_boneweights(struct cmesh *cm, float w1, float w2, float w3, float w4);
170 int cmesh_boneidx(struct cmesh *cm, int idx1, int idx2, int idx3, int idx4);
172 /* dir_xform can be null, in which case it's calculated from xform */
173 void cmesh_apply_xform(struct cmesh *cm, float *xform, float *dir_xform);
175 void cmesh_flip(struct cmesh *cm); /* flip faces (winding) and normals */
176 void cmesh_flip_faces(struct cmesh *cm);
177 void cmesh_flip_normals(struct cmesh *cm);
179 void cmesh_explode(struct cmesh *cm); /* undo all vertex sharing */
181 /* this is only guaranteed to work on an exploded mesh */
182 void cmesh_calc_face_normals(struct cmesh *cm);
184 void cmesh_draw(struct cmesh *cm);
185 void cmesh_draw_wire(struct cmesh *cm, float linesz);
186 void cmesh_draw_vertices(struct cmesh *cm, float ptsz);
187 void cmesh_draw_normals(struct cmesh *cm, float len);
188 void cmesh_draw_tangents(struct cmesh *cm, float len);
190 /* get the bounding box in local space. The result will be cached and subsequent
191 * calls will return the same box. The cache gets invalidated by any functions that
192 * can affect the vertex data
194 void cmesh_aabbox(struct cmesh *cm, cgm_vec3 *vmin, cgm_vec3 *vmax);
196 /* get the bounding sphere in local space. The result will be cached ... see above */
197 float cmesh_bsphere(struct cmesh *cm, cgm_vec3 *center, float *rad);
199 /* texture coordinate manipulation */
200 void cmesh_texcoord_apply_xform(struct cmesh *cm, float *xform);
201 void cmesh_texcoord_gen_plane(struct cmesh *cm, cgm_vec3 *norm, cgm_vec3 *tang);
202 void cmesh_texcoord_gen_box(struct cmesh *cm);
203 void cmesh_texcoord_gen_cylinder(struct cmesh *cm);
205 int cmesh_dump(struct cmesh *cm, const char *fname);
206 int cmesh_dump_file(struct cmesh *cm, FILE *fp);
207 int cmesh_dump_obj(struct cmesh *cm, const char *fname);
208 int cmesh_dump_obj_file(struct cmesh *cm, FILE *fp, int voffs);