9 static int update_mesh_vbo(struct mesh *m);
10 static int update_meshgroup_vbo(struct meshgroup *mg);
12 void init_mesh(struct mesh *m)
14 memset(m, 0, sizeof *m);
17 void destroy_mesh(struct mesh *m)
23 glDeleteBuffers(1, &m->vbo);
26 glDeleteBuffers(1, &m->ibo);
30 void clear_mesh(struct mesh *m)
37 m->num_verts = m->max_verts = m->num_idx = m->max_idx = 0;
39 m->bbvalid = m->vbovalid = 0;
42 int copy_mesh(struct mesh *dest, struct mesh *src)
46 if(src->max_verts && !(dest->varr = malloc(src->max_verts * sizeof *dest->varr))) {
49 if(src->max_idx && !(dest->iarr = malloc(src->max_idx * sizeof *dest->iarr))) {
55 dest->num_verts = src->num_verts;
56 dest->max_verts = src->max_verts;
58 memcpy(dest->varr, src->varr, src->num_verts * sizeof *dest->varr);
61 dest->num_idx = src->num_idx;
62 dest->max_idx = src->max_idx;
64 memcpy(dest->iarr, src->iarr, src->num_idx * sizeof *dest->iarr);
70 void init_meshgroup(struct meshgroup *mg)
72 memset(mg, 0, sizeof *mg);
75 void destroy_meshgroup(struct meshgroup *mg)
80 glDeleteBuffers(1, &mg->vbo);
83 glDeleteBuffers(1, &mg->ibo);
87 void clear_meshgroup(struct meshgroup *mg)
93 mg->num_verts = mg->num_idx = 0;
95 mg->bbvalid = mg->vbovalid = 0;
98 void calc_mesh_bounds(struct mesh *m)
101 struct vertex *vptr = m->varr;
103 m->bb.vmin.x = m->bb.vmin.y = m->bb.vmin.z = FLT_MAX;
104 m->bb.vmax.x = m->bb.vmax.y = m->bb.vmax.z = -FLT_MAX;
106 for(i=0; i<m->num_verts; i++) {
107 if(vptr->pos.x < m->bb.vmin.x) m->bb.vmin.x = vptr->pos.x;
108 if(vptr->pos.y < m->bb.vmin.y) m->bb.vmin.y = vptr->pos.y;
109 if(vptr->pos.z < m->bb.vmin.z) m->bb.vmin.z = vptr->pos.z;
110 if(vptr->pos.x > m->bb.vmax.x) m->bb.vmax.x = vptr->pos.x;
111 if(vptr->pos.y > m->bb.vmax.y) m->bb.vmax.y = vptr->pos.y;
112 if(vptr->pos.z > m->bb.vmax.z) m->bb.vmax.z = vptr->pos.z;
119 void calc_meshgroup_bounds(struct meshgroup *mg)
124 mg->bb.vmin.x = mg->bb.vmin.y = mg->bb.vmin.z = FLT_MAX;
125 mg->bb.vmax.x = mg->bb.vmax.y = mg->bb.vmax.z = -FLT_MAX;
127 for(i=0; i<mg->num_meshes; i++) {
133 if(m->bb.vmin.x < mg->bb.vmin.x) mg->bb.vmin.x = m->bb.vmin.x;
134 if(m->bb.vmin.y < mg->bb.vmin.y) mg->bb.vmin.y = m->bb.vmin.y;
135 if(m->bb.vmin.z < mg->bb.vmin.z) mg->bb.vmin.z = m->bb.vmin.z;
136 if(m->bb.vmax.x > mg->bb.vmax.x) mg->bb.vmax.x = m->bb.vmax.x;
137 if(m->bb.vmax.y > mg->bb.vmax.y) mg->bb.vmax.y = m->bb.vmax.y;
138 if(m->bb.vmax.z > mg->bb.vmax.z) mg->bb.vmax.z = m->bb.vmax.z;
144 int add_mesh_vertex(struct mesh *m, struct vertex *v)
149 if(m->num_verts >= m->max_verts) {
150 newmax = m->max_verts ? m->max_verts * 2 : 16;
151 if(!(tmp = realloc(m->varr, newmax * sizeof *m->varr))) {
155 m->max_verts = newmax;
158 m->varr[m->num_verts++] = *v;
162 int add_mesh_index(struct mesh *m, int idx)
167 if(m->num_idx >= m->max_idx) {
168 newmax = m->max_idx ? m->max_idx * 2 : 16;
169 if(!(tmp = realloc(m->iarr, newmax * sizeof *m->iarr))) {
176 m->iarr[m->num_idx++] = idx;
180 int add_mesh_face(struct mesh *m, int va, int vb, int vc)
182 if(add_mesh_index(m, va) == -1) return -1;
183 if(add_mesh_index(m, vb) == -1) {
187 if(add_mesh_index(m, vc) == -1) {
194 int add_meshgroup_mesh(struct meshgroup *mg, struct mesh *m)
199 if(mg->num_meshes >= mg->max_meshes) {
200 newmax = mg->max_meshes ? mg->max_meshes * 2 : 16;
201 if(!(tmp = realloc(mg->meshes, newmax * sizeof *mg->meshes))) {
205 mg->max_meshes = newmax;
208 mg->meshes[mg->num_meshes++] = m;
212 void draw_mesh(struct mesh *m)
215 if(update_mesh_vbo(m) == -1) {
220 glEnableVertexAttribArray(MESH_ATTR_VERTEX);
221 glEnableVertexAttribArray(MESH_ATTR_NORMAL);
222 glEnableVertexAttribArray(MESH_ATTR_TANGENT);
223 glEnableVertexAttribArray(MESH_ATTR_TEXCOORD);
225 glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
226 glVertexAttribPointer(MESH_ATTR_VERTEX, 3, GL_FLOAT, 0, sizeof *m->varr, 0);
227 glVertexAttribPointer(MESH_ATTR_NORMAL, 3, GL_FLOAT, 0, sizeof *m->varr, (void*)offsetof(struct vertex, norm));
228 glVertexAttribPointer(MESH_ATTR_TANGENT, 3, GL_FLOAT, 0, sizeof *m->varr, (void*)offsetof(struct vertex, tang));
229 glVertexAttribPointer(MESH_ATTR_TEXCOORD, 2, GL_FLOAT, 0, sizeof *m->varr, (void*)offsetof(struct vertex, tex));
230 glBindBuffer(GL_ARRAY_BUFFER, 0);
233 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo);
234 glDrawElements(GL_TRIANGLES, m->num_idx, GL_UNSIGNED_INT, 0);
235 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
237 glDrawArrays(GL_TRIANGLES, 0, m->num_verts);
240 glDisableVertexAttribArray(MESH_ATTR_VERTEX);
241 glDisableVertexAttribArray(MESH_ATTR_NORMAL);
242 glDisableVertexAttribArray(MESH_ATTR_TANGENT);
243 glDisableVertexAttribArray(MESH_ATTR_TEXCOORD);
246 void draw_meshgroup(struct meshgroup *mg)
249 if(update_meshgroup_vbo(mg) == -1) {
254 glEnableVertexAttribArray(MESH_ATTR_VERTEX);
255 glEnableVertexAttribArray(MESH_ATTR_NORMAL);
256 glEnableVertexAttribArray(MESH_ATTR_TANGENT);
257 glEnableVertexAttribArray(MESH_ATTR_TEXCOORD);
259 glBindBuffer(GL_ARRAY_BUFFER, mg->vbo);
260 glVertexAttribPointer(MESH_ATTR_VERTEX, 3, GL_FLOAT, 0, sizeof(struct vertex), 0);
261 glVertexAttribPointer(MESH_ATTR_NORMAL, 3, GL_FLOAT, 0, sizeof(struct vertex), (void*)offsetof(struct vertex, norm));
262 glVertexAttribPointer(MESH_ATTR_TANGENT, 3, GL_FLOAT, 0, sizeof(struct vertex), (void*)offsetof(struct vertex, tang));
263 glVertexAttribPointer(MESH_ATTR_TEXCOORD, 2, GL_FLOAT, 0, sizeof(struct vertex), (void*)offsetof(struct vertex, tex));
264 glBindBuffer(GL_ARRAY_BUFFER, 0);
267 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mg->ibo);
268 glDrawElements(GL_TRIANGLES, mg->num_idx, GL_UNSIGNED_INT, 0);
269 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
271 glDrawArrays(GL_TRIANGLES, 0, mg->num_verts);
274 glDisableVertexAttribArray(MESH_ATTR_VERTEX);
275 glDisableVertexAttribArray(MESH_ATTR_NORMAL);
276 glDisableVertexAttribArray(MESH_ATTR_TANGENT);
277 glDisableVertexAttribArray(MESH_ATTR_TEXCOORD);
280 static int update_mesh_vbo(struct mesh *m)
282 if(m->num_verts <= 0) return -1;
285 glGenBuffers(1, &m->vbo);
287 glBindBuffer(GL_ARRAY_BUFFER, m->vbo);
288 glBufferData(GL_ARRAY_BUFFER, m->num_verts * sizeof *m->varr, m->varr, GL_STATIC_DRAW);
289 glBindBuffer(GL_ARRAY_BUFFER, 0);
293 glGenBuffers(1, &m->ibo);
295 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m->ibo);
296 glBufferData(GL_ELEMENT_ARRAY_BUFFER, m->num_idx * sizeof *m->iarr,
297 m->iarr, GL_STATIC_DRAW);
298 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
303 static int update_meshgroup_vbo(struct meshgroup *mg)
306 struct vertex *varr, *vptr;
307 unsigned int *iarr = 0, *iptr;
310 mg->num_verts = mg->num_idx = 0;
312 for(i=0; i<mg->num_meshes; i++) {
313 mg->num_verts += mg->meshes[i]->num_verts;
314 mg->num_idx += mg->meshes[i]->num_idx;
317 if(mg->num_verts <= 0) return -1;
319 if(!(varr = malloc(mg->num_verts * sizeof *varr))) {
320 fprintf(stderr, "update_meshgroup_vbo: failed to allocate vertex array with %d vertices\n", mg->num_verts);
323 if(mg->num_idx > 0) {
324 if(!(iarr = malloc(mg->num_idx * sizeof *iarr))) {
325 fprintf(stderr, "update_meshgroup_vbo: failed to allocate index array with %d indices\n", mg->num_idx);
334 for(i=0; i<mg->num_meshes; i++) {
336 memcpy(vptr, m->varr, m->num_verts * sizeof *vptr);
337 vptr += m->num_verts;
340 memcpy(iptr, m->iarr, m->num_idx * sizeof *iptr);
346 glGenBuffers(1, &mg->vbo);
348 glBindBuffer(GL_ARRAY_BUFFER, mg->vbo);
349 glBufferData(GL_ARRAY_BUFFER, mg->num_verts * sizeof *varr, varr, GL_STATIC_DRAW);
350 glBindBuffer(GL_ARRAY_BUFFER, 0);
353 glGenBuffers(1, &mg->ibo);
355 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mg->ibo);
356 glBufferData(GL_ELEMENT_ARRAY_BUFFER, mg->num_idx * sizeof *iarr, iarr, GL_STATIC_DRAW);
357 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
365 void xform_mesh(struct mesh *mesh, float *mat)
372 for(i=0; i<mesh->num_verts; i++) {
373 cgm_vmul_v3m4(&mesh->varr[i].pos, mat);
374 cgm_vmul_v3m3(&mesh->varr[i].norm, mat);
375 cgm_vmul_v3m3(&mesh->varr[i].tang, mat);