geometry.c (4705B)
1 2 #include "geometry.h" 3 #include "util.h" 4 #include "resource.h" 5 #include "debug.h" 6 #include <assert.h> 7 8 struct resource_manager geom_manager; 9 10 void 11 destroy_buffer_geometry(struct geometry_id *geom_id) { 12 struct geometry *geom = get_geometry(geom_id); 13 gpu_addr buffers[MAX_VERTEX_ATTRS]; 14 15 for (int i = 0; i < MAX_VERTEX_ATTRS; i++) 16 buffers[i] = geom->vbos[i].handle; 17 /* void glDeleteVertexArrays(GLsizei n, const GLuint *arrays); */ 18 /* glDisableVertexAttribArray(geom->buffer.vertex_buffer.handle); */ 19 /* check_gl(); */ 20 /* glDisableVertexAttribArray(geom->buffer.normal_buffer.handle); */ 21 /* check_gl(); */ 22 /* glDisableVertexAttribArray(geom->buffer.index_buffer.handle); */ 23 /* check_gl(); */ 24 check_gl(); 25 glDeleteBuffers(ARRAY_SIZE(buffers), buffers); 26 check_gl(); 27 28 29 geom->has_vbos = 0; 30 } 31 32 void bind_geometry(struct geometry *geom, struct gpu_program *program) { 33 struct vbo *vbo; 34 for (int i = 0; i < MAX_VERTEX_ATTRS; i++) { 35 if (i != va_index && !(program->active_attributes & (1 << i))) { 36 continue; 37 } 38 vbo = &geom->vbos[i]; 39 assert(program->vertex_attrs[i] != 0xFFFFFFFF); 40 if (vbo->handle) { 41 bind_vbo(vbo, program->vertex_attrs[i], 42 vbo->component_type); 43 check_gl(); 44 } else { 45 printf("%s: %s attribute not bound\n", 46 program->name, 47 vertex_attr_str(i)); 48 assert(0); 49 } 50 } 51 } 52 53 54 void render_geometry(struct geometry *geom, struct gpu_program *program) 55 { 56 int type = GL_TRIANGLES; 57 bind_geometry(geom, program); 58 if (geom->num_indices) { 59 glDrawElements(type, 60 geom->num_indices, /* count */ 61 GL_UNSIGNED_INT, /* type */ 62 (void*)0 /* element array buffer offset */ 63 ); 64 //printf("render_geometry %d %s\n", geom->num_indices, program->name); 65 check_gl(); 66 } 67 else { 68 /* printf("nverts %d\n", geom->num_verts); */ 69 glDrawArrays(type, 0, geom->num_verts); 70 check_gl(); 71 } 72 } 73 74 void init_geometry(struct geometry *geom) { 75 geom->has_vbos = 0; 76 77 for (int i = 0; i < MAX_VERTEX_ATTRS; i++) 78 init_vbo(&geom->vbos[i]); 79 80 geom->num_uv_components = 2; 81 } 82 83 void make_buffer_geometry(struct make_geometry *mkgeom, struct geometry *geom) 84 { 85 init_geometry(geom); 86 87 // VBOs 88 geom->num_uv_components = mkgeom->num_uv_components; 89 geom->num_verts = mkgeom->num_verts; 90 geom->num_indices = mkgeom->num_indices; 91 92 assert(mkgeom->num_verts); 93 assert(mkgeom->vertices); 94 /* assert(geom->normals); */ 95 /* assert(geom->indices); */ 96 /* assert(geom->num_indices >= 1); */ 97 98 /* printf("making vertex buffer\n"); */ 99 make_float_vertex_buffer(&geom->vbos[va_position], 100 mkgeom->vertices, 101 mk_num_elements(mkgeom->num_verts), 102 mk_components(3)); 103 104 /* printf("making normal buffer\n"); */ 105 // cube normals 106 if (mkgeom->normals) { 107 make_float_vertex_buffer(&geom->vbos[va_normal], 108 mkgeom->normals, 109 mk_num_elements(mkgeom->num_verts), 110 mk_components(3)); 111 } 112 if (mkgeom->joint_ids) { 113 assert(0); 114 make_int_vertex_buffer(&geom->vbos[va_joint_ids], 115 mkgeom->joint_ids, 116 mk_num_elements(mkgeom->num_verts), 117 mk_components(3)); 118 } 119 120 // vertex colors 121 if (mkgeom->colors) { 122 make_float_vertex_buffer(&geom->vbos[va_color], 123 mkgeom->colors, 124 mk_num_elements(mkgeom->num_verts), 125 mk_components(3)); 126 } 127 128 if (mkgeom->tex_coords != NULL) { 129 assert(geom->num_uv_components); 130 131 make_uv_buffer(&geom->vbos[va_tex_coord], 132 mkgeom->tex_coords, 133 mk_num_elements(geom->num_verts), 134 mk_components(geom->num_uv_components) 135 ); 136 } 137 138 /* printf("making index buffer\n"); */ 139 // cube indices 140 if (mkgeom->indices) 141 make_index_buffer(&geom->vbos[va_index], 142 mkgeom->indices, 143 mk_num_elements(mkgeom->num_indices) 144 ); 145 146 geom->has_vbos = 1; 147 } 148 149 150 void geometry_centroid(struct geometry *geom, float *dest) { 151 vec3_subtract(geom->max, geom->min, dest); 152 vec3_scale(dest, 0.5, dest); 153 }; 154 155 156 void init_geometry_manager() { 157 init_resource_manager(&geom_manager, sizeof(struct geometry), 158 DEF_NUM_GEOMETRY, MAX_GEOMETRY, "geometry"); 159 } 160 161 struct geometry *get_geometry(struct geometry_id *geom_id) { 162 return get_resource(&geom_manager, &geom_id->id); 163 } 164 165 166 struct geometry *new_geometry(struct geometry_id *geom_id) { 167 struct geometry *geom = new_resource(&geom_manager, &geom_id->id); 168 /* debug("new geometry %llu\n", geom_id->uuid); */ 169 return geom; 170 } 171 172 struct geometry *get_all_geometry(u32 *count, struct geometry_id **ids) { 173 return get_all_resources(&geom_manager, count, (struct resource_id**)ids); 174 } 175 176 void destroy_geometry(struct geometry_id *geom_id) 177 { 178 struct geometry *geom = get_geometry(geom_id); assert(geom); 179 struct vbo *vbo; 180 181 for (int i = 0; i < MAX_VERTEX_ATTRS; i++) { 182 vbo = &geom->vbos[i]; 183 if (vbo->handle) 184 glDeleteBuffers(1, &vbo->handle); 185 } 186 187 destroy_resource(&geom_manager, &geom_id->id); 188 } 189