static void subdivide(glb_data *d, const GLfloat * v1, GLuint vi1, const GLfloat * v2, GLuint vi2, const GLfloat * v3, GLuint vi3, int depth) { int i; if (depth == 0) { save_triangle(d, vi1, vi2, vi3); } else { GLuint vi12, vi23, vi31; GLfloat v12[3], v23[3], v31[3]; for (i = 0; i < 3; ++i) { v12[i] = v1[i] + v2[i]; v23[i] = v2[i] + v3[i]; v31[i] = v3[i] + v1[i]; } normalize(v12); vi12 = save_vertex(d, v12); normalize(v23); vi23 = save_vertex(d, v23); normalize(v31); vi31 = save_vertex(d, v31); subdivide(d, v1, vi1, v12, vi12, v31, vi31, depth - 1); subdivide(d, v2, vi2, v23, vi23, v12, vi12, depth - 1); subdivide(d, v3, vi3, v31, vi31, v23, vi23, depth - 1); subdivide(d, v12, vi12, v23, vi23, v31, vi31, depth - 1); } }
/* Public interface: Create the sphere. */ glb_data * glb_sphere_init(void) { glb_data *d = (glb_data *) calloc (1, sizeof (*d)); int i; for (i = 0; i < 20; ++i) { subdivide(d, vdata[tindices[i][0]], save_vertex(d, vdata[tindices[i][0]]), vdata[tindices[i][1]], save_vertex(d, vdata[tindices[i][1]]), vdata[tindices[i][2]], save_vertex(d, vdata[tindices[i][2]]), glb_config.subdivision_depth); } return d; }
static void render_tri(struct draw_stage *stage, struct prim_header *prim) { struct render_stage *rs = render_stage(stage); struct cell_context *cell = rs->cell; struct cell_prim_buffer *buf = &cell->prim_buffer; uint i; if (buf->num_verts + 3 > CELL_MAX_VERTS) { cell_flush_prim_buffer(cell); } i = buf->num_verts; assert(i+2 <= CELL_MAX_VERTS); save_vertex(buf, i+0, prim->v[0]); save_vertex(buf, i+1, prim->v[1]); save_vertex(buf, i+2, prim->v[2]); buf->num_verts += 3; }