polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

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