We no longer keep around geometry data after passing it on to opengl as it is not needed anymore resulting in some memory savings

dev
Shariq Shah 6 years ago
parent 33c2ea7ceb
commit 6546a95538
  1. 2
      src/common/version.h
  2. 221
      src/game/geometry.c
  3. 11
      src/game/geometry.h
  4. 2
      src/game/renderer.c
  5. 3
      todo.txt

@ -4,7 +4,7 @@
/* Auto generated version file. DO NOT MODIFY */ /* Auto generated version file. DO NOT MODIFY */
#define SYMMETRY_VERSION_MAJOR 0 #define SYMMETRY_VERSION_MAJOR 0
#define SYMMETRY_VERSION_MINOR 1 #define SYMMETRY_VERSION_MINOR 1
#define SYMMETRY_VERSION_REVISION 303 #define SYMMETRY_VERSION_REVISION 304
#define SYMMETRY_VERSION_BRANCH "dev" #define SYMMETRY_VERSION_BRANCH "dev"
#endif #endif

@ -17,9 +17,9 @@ GLenum* draw_modes = NULL;
static struct Geometry* geometry_list; static struct Geometry* geometry_list;
static int* empty_indices; static int* empty_indices;
static int load_from_file(struct Geometry* geometry, const char* filename); static void create_vao(struct Geometry* geometry, vec3* vertices, vec2* uvs, vec3* normals, vec3* vertex_colors, uint* indices);
static void create_vao(struct Geometry* geometry);
static struct Geometry* generate_new_index(int* out_new_index); static struct Geometry* generate_new_index(int* out_new_index);
static void geom_bounding_volume_generate(struct Geometry* geometry, vec3* vertices);
void geom_init(void) void geom_init(void)
{ {
@ -49,20 +49,19 @@ int geom_find(const char* filename)
return index; return index;
} }
void geom_bounding_volume_generate(int index) void geom_bounding_volume_generate(struct Geometry* geometry, vec3* vertices)
{ {
struct Geometry* geometry = &geometry_list[index]; struct Bounding_Box* box = &geometry->bounding_box;
struct Bounding_Box* box = &geometry->bounding_box; struct Bounding_Sphere* sphere = &geometry->bounding_sphere;
struct Bounding_Sphere* sphere = &geometry->bounding_sphere;
vec3_fill(&box->max, -FLT_MIN, -FLT_MIN, -FLT_MIN); vec3_fill(&box->max, -FLT_MIN, -FLT_MIN, -FLT_MIN);
vec3_fill(&box->min, FLT_MAX, FLT_MAX, FLT_MAX); vec3_fill(&box->min, FLT_MAX, FLT_MAX, FLT_MAX);
vec3_fill(&sphere->center, 0.f, 0.f, 0.f); vec3_fill(&sphere->center, 0.f, 0.f, 0.f);
sphere->radius = 0.f; sphere->radius = 0.f;
for(int i = 0; i < array_len(geometry->vertices); i++) for(int i = 0; i < array_len(vertices); i++)
{ {
vec3* vertex = &geometry->vertices[i]; vec3* vertex = &vertices[i];
if(vertex->x > box->max.x) box->max.x = vertex->x; if(vertex->x > box->max.x) box->max.x = vertex->x;
if(vertex->y > box->max.y) box->max.y = vertex->y; if(vertex->y > box->max.y) box->max.y = vertex->y;
if(vertex->z > box->max.z) box->max.z = vertex->z; if(vertex->z > box->max.z) box->max.z = vertex->z;
@ -85,13 +84,7 @@ void geom_bounding_volume_generate(int index)
} }
} }
void geom_bounding_volume_generate_all(void) struct Geometry* generate_new_index(int* out_new_index)
{
for(int i = 0; i < array_len(geometry_list); i++)
geom_bounding_volume_generate(i);
}
static struct Geometry* generate_new_index(int* out_new_index)
{ {
assert(out_new_index); assert(out_new_index);
int empty_len = array_len(empty_indices); int empty_len = array_len(empty_indices);
@ -122,10 +115,58 @@ int geom_create_from_file(const char* name)
new_geo = generate_new_index(&index); new_geo = generate_new_index(&index);
assert(new_geo); assert(new_geo);
if(load_from_file(new_geo, name)) char* full_path = str_new("models/%s", name);
FILE* file = io_file_open(DIRT_INSTALL, full_path, "rb");
free(full_path);
if(file)
{ {
create_vao(new_geo); const uint32 INDEX_SIZE = sizeof(uint32);
geom_bounding_volume_generate(index); const uint32 VEC3_SIZE = sizeof(vec3);
const uint32 VEC2_SIZE = sizeof(vec2);
uint32 header[4];
size_t bytes_read = 0;
if((bytes_read = fread(header, INDEX_SIZE, 4, file)) <= 0)
{
log_error("geometry:load_from_file", "Read failed");
/* TODO: Some error here, find it and fix it */
array_pop(geometry_list);
index = -1;
}
else
{
uint32 indices_count = header[0];
uint32 vertices_count = header[1];
uint32 normals_count = header[2];
uint32 uvs_count = header[3];
// Indices
uint* indices = array_new_cap(uint, indices_count);
fread(indices, INDEX_SIZE, indices_count, file);
array_match_len_cap(indices);
// Vertices
vec3* vertices = array_new_cap(vec3, vertices_count);
fread(vertices, VEC3_SIZE, vertices_count, file);
array_match_len_cap(vertices);
// Normals
vec3* normals = array_new_cap(vec3, normals_count);
fread(normals, VEC3_SIZE, normals_count, file);
array_match_len_cap(normals);
// Uvs
vec2* uvs = array_new_cap(vec2, uvs_count);
fread(uvs, VEC2_SIZE, uvs_count, file);
array_match_len_cap(uvs);
new_geo->filename = str_new(name);
new_geo->draw_indexed = 1;
new_geo->ref_count++;
create_vao(new_geo, vertices, uvs, normals, NULL, indices);
geom_bounding_volume_generate(new_geo, vertices);
if(vertices) array_free(vertices);
if(indices) array_free(indices);
if(uvs) array_free(uvs);
if(normals) array_free(normals);
}
fclose(file);
} }
else else
{ {
@ -151,29 +192,12 @@ int geom_create(const char* name,
assert(name && vertices && uvs && normals && indices); assert(name && vertices && uvs && normals && indices);
int index = -1; int index = -1;
/* add new geometry object or overwrite existing one */ /* add new geometry object or overwrite existing one */
struct Geometry* new_geo = NULL; struct Geometry* new_geometry = NULL;
new_geo = generate_new_index(&index); new_geometry = generate_new_index(&index);
assert(new_geo); assert(new_geometry);
new_geo->filename = str_new(name); new_geometry->filename = str_new(name);
new_geo->vertices = array_new_cap(vec3, array_len(vertices)); create_vao(new_geometry, vertices, uvs, normals, vertex_colors, indices);
array_copy(vertices, new_geo->vertices); geom_bounding_volume_generate(new_geometry, vertices);
new_geo->normals = array_new_cap(vec3, array_len(normals));
array_copy(normals, new_geo->normals);
new_geo->uvs = array_new_cap(vec2, array_len(uvs));
array_copy(uvs, new_geo->uvs);
new_geo->indices = array_new_cap(uint, array_len(indices));
array_copy(indices, new_geo->indices);
if(vertex_colors)
{
new_geo->vertex_colors = array_new_cap(vec3, array_len(vertex_colors));
array_copy(vertex_colors, new_geo->vertex_colors);
}
else
{
new_geo->vertex_colors = array_new(vec3);
}
create_vao(new_geo);
//generateBoundingBox(index);
return index; return index;
} }
@ -188,18 +212,8 @@ void geom_remove(int index)
geometry->ref_count--; geometry->ref_count--;
if(geometry->ref_count < 0) if(geometry->ref_count < 0)
{ {
if(geometry->indices) array_free(geometry->indices); if(geometry->filename) free(geometry->filename);
if(geometry->vertices) array_free(geometry->vertices); geometry->filename = NULL;
if(geometry->uvs) array_free(geometry->uvs);
if(geometry->normals) array_free(geometry->normals);
if(geometry->vertex_colors) array_free(geometry->vertex_colors);
if(geometry->filename) free(geometry->filename);
geometry->indices = NULL;
geometry->vertices = NULL;
geometry->uvs = NULL;
geometry->normals = NULL;
geometry->vertex_colors = NULL;
geometry->filename = NULL;
glDeleteBuffers(1, &geometry->vertex_vbo); glDeleteBuffers(1, &geometry->vertex_vbo);
glDeleteBuffers(1, &geometry->color_vbo); glDeleteBuffers(1, &geometry->color_vbo);
@ -231,64 +245,12 @@ void geom_cleanup(void)
array_free(draw_modes); array_free(draw_modes);
} }
static int load_from_file(struct Geometry* geometry, const char* filename) void create_vao(struct Geometry* geometry,
{ vec3* vertices,
assert(filename); vec2* uvs,
int success = 1; vec3* normals,
char* full_path = str_new("models/%s", filename); vec3* vertex_colors,
uint* indices)
FILE* file = io_file_open(DIRT_INSTALL, full_path, "rb");
free(full_path);
if(file)
{
const uint32 INDEX_SIZE = sizeof(uint32);
const uint32 VEC3_SIZE = sizeof(vec3);
const uint32 VEC2_SIZE = sizeof(vec2);
uint32 header[4];
size_t bytes_read = 0;
if((bytes_read = fread(header, INDEX_SIZE, 4, file)) <= 0)
{
log_error("geometry:load_from_file", "Read failed");
success = 0;
}
else
{
uint32 indices_count = header[0];
uint32 vertices_count = header[1];
uint32 normals_count = header[2];
uint32 uvs_count = header[3];
// Indices
geometry->indices = array_new_cap(uint, indices_count);
fread(geometry->indices, INDEX_SIZE, indices_count, file);
array_match_len_cap(geometry->indices);
// Vertices
geometry->vertices = array_new_cap(vec3, vertices_count);
fread(geometry->vertices, VEC3_SIZE, vertices_count, file);
array_match_len_cap(geometry->vertices);
// Normals
geometry->normals = array_new_cap(vec3, normals_count);
fread(geometry->normals, VEC3_SIZE, normals_count, file);
array_match_len_cap(geometry->normals);
// Uvs
geometry->uvs = array_new_cap(vec2, uvs_count);
fread(geometry->uvs, VEC2_SIZE, uvs_count, file);
array_match_len_cap(geometry->uvs);
geometry->vertex_colors = array_new(vec3);
}
fclose(file);
geometry->filename = str_new(filename);
geometry->draw_indexed = 1;
geometry->ref_count++;
}
else
{
success = 0;
}
return success;
}
static void create_vao(struct Geometry* geometry)
{ {
// TODO: Add support for different model formats and interleaving VBO // TODO: Add support for different model formats and interleaving VBO
assert(geometry); assert(geometry);
@ -298,59 +260,62 @@ static void create_vao(struct Geometry* geometry)
glGenBuffers(1, &geometry->vertex_vbo); glGenBuffers(1, &geometry->vertex_vbo);
glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_vbo); glBindBuffer(GL_ARRAY_BUFFER, geometry->vertex_vbo);
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
array_len(geometry->vertices) * sizeof(vec3), array_len(vertices) * sizeof(vec3),
geometry->vertices, vertices,
GL_STATIC_DRAW)); GL_STATIC_DRAW));
glEnableVertexAttribArray(0); glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
geometry->vertices_len = array_len(vertices);
if(array_len(geometry->normals) > 0) if(array_len(normals) > 0)
{ {
glGenBuffers(1, &geometry->normal_vbo); glGenBuffers(1, &geometry->normal_vbo);
glBindBuffer(GL_ARRAY_BUFFER, geometry->normal_vbo); glBindBuffer(GL_ARRAY_BUFFER, geometry->normal_vbo);
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
array_len(geometry->normals) * sizeof(vec3), array_len(normals) * sizeof(vec3),
geometry->normals, normals,
GL_STATIC_DRAW)); GL_STATIC_DRAW));
glEnableVertexAttribArray(1); glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, 0); glVertexAttribPointer(1, 3, GL_FLOAT, GL_TRUE, 0, 0);
} }
if(array_len(geometry->uvs) > 0) if(array_len(uvs) > 0)
{ {
glGenBuffers(1, &geometry->uv_vbo); glGenBuffers(1, &geometry->uv_vbo);
glBindBuffer(GL_ARRAY_BUFFER, geometry->uv_vbo); glBindBuffer(GL_ARRAY_BUFFER, geometry->uv_vbo);
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
array_len(geometry->uvs) * sizeof(vec2), array_len(uvs) * sizeof(vec2),
geometry->uvs, uvs,
GL_STATIC_DRAW)); GL_STATIC_DRAW));
glEnableVertexAttribArray(2); glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 0, 0);
} }
if(array_len(geometry->vertex_colors) > 0) if(vertex_colors && array_len(vertex_colors) > 0)
{ {
glGenBuffers(1, &geometry->color_vbo); glGenBuffers(1, &geometry->color_vbo);
glBindBuffer(GL_ARRAY_BUFFER, geometry->color_vbo); glBindBuffer(GL_ARRAY_BUFFER, geometry->color_vbo);
GL_CHECK(glBufferData(GL_ARRAY_BUFFER, GL_CHECK(glBufferData(GL_ARRAY_BUFFER,
array_len(geometry->vertex_colors) * sizeof(vec3), array_len(vertex_colors) * sizeof(vec3),
geometry->vertex_colors, vertex_colors,
GL_STATIC_DRAW)); GL_STATIC_DRAW));
glEnableVertexAttribArray(3); glEnableVertexAttribArray(3);
glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0); glVertexAttribPointer(3, 3, GL_FLOAT, GL_FALSE, 0, 0);
} }
if(array_len(geometry->indices) > 0) if(array_len(indices) > 0)
{ {
glGenBuffers(1, &geometry->index_vbo); glGenBuffers(1, &geometry->index_vbo);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_vbo); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, geometry->index_vbo);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, glBufferData(GL_ELEMENT_ARRAY_BUFFER,
array_len(geometry->indices) * sizeof(GLuint), array_len(indices) * sizeof(GLuint),
geometry->indices, indices,
GL_STATIC_DRAW); GL_STATIC_DRAW);
geometry->draw_indexed = 1; geometry->draw_indexed = 1;
geometry->indices_len = array_len(indices);
} }
glBindVertexArray(0); glBindVertexArray(0);
} }
void geom_render(int index, enum Geometry_Draw_Mode draw_mode) void geom_render(int index, enum Geometry_Draw_Mode draw_mode)
@ -359,9 +324,9 @@ void geom_render(int index, enum Geometry_Draw_Mode draw_mode)
struct Geometry* geo = &geometry_list[index]; struct Geometry* geo = &geometry_list[index];
glBindVertexArray(geo->vao); glBindVertexArray(geo->vao);
if(geo->draw_indexed) if(geo->draw_indexed)
glDrawElements(draw_modes[draw_mode], array_len(geo->indices), GL_UNSIGNED_INT, (void*)0); glDrawElements(draw_modes[draw_mode], geo->indices_len, GL_UNSIGNED_INT, (void*)0);
else else
glDrawArrays(draw_modes[draw_mode], 0, array_len(geo->vertices)); glDrawArrays(draw_modes[draw_mode], 0, geo->vertices_len);
glBindVertexArray(0); glBindVertexArray(0);
} }
@ -386,7 +351,7 @@ int geom_render_in_frustum(int index,
if(intersection == IT_INTERSECT || intersection == IT_INSIDE) if(intersection == IT_INTERSECT || intersection == IT_INSIDE)
{ {
geom_render(index, draw_mode); geom_render(index, draw_mode);
indices_rendered = array_len(geometry->indices); indices_rendered = array_len(geometry->indices_len);
} }
} }
return indices_rendered; return indices_rendered;

@ -31,12 +31,9 @@ struct Geometry
uint normal_vbo; uint normal_vbo;
uint color_vbo; uint color_vbo;
uint index_vbo; uint index_vbo;
uint vertices_len;
uint indices_len;
int ref_count; int ref_count;
vec3* vertices;
vec3* vertex_colors;
vec3* normals;
vec2* uvs;
uint* indices;
struct Bounding_Box bounding_box; struct Bounding_Box bounding_box;
struct Bounding_Sphere bounding_sphere; struct Bounding_Sphere bounding_sphere;
}; };
@ -47,8 +44,6 @@ int geom_find(const char* filename);
void geom_remove(int index); void geom_remove(int index);
void geom_cleanup(void); void geom_cleanup(void);
void geom_render(int index, enum Geometry_Draw_Mode draw_mode); void geom_render(int index, enum Geometry_Draw_Mode draw_mode);
void geom_bounding_volume_generate(int index);
void geom_bounding_volume_generate_all(void);
struct Geometry* geom_get(int index); struct Geometry* geom_get(int index);
int geom_render_in_frustum(int index, int geom_render_in_frustum(int index,
vec4* frustum, vec4* frustum,
@ -59,6 +54,6 @@ int geom_create(const char* name,
vec2* uvs, vec2* uvs,
vec3* normals, vec3* normals,
uint* indices, uint* indices,
vec3* vertex_colors); vec3* vertex_colors); // Note: caller responsible for freeing up the data passed in
#endif #endif

@ -189,7 +189,7 @@ void renderer_render(struct Renderer* renderer, struct Scene* scene)
int intersection = bv_intersect_frustum_box(&active_camera->frustum, &mesh->base.derived_bounding_box); int intersection = bv_intersect_frustum_box(&active_camera->frustum, &mesh->base.derived_bounding_box);
if(intersection == IT_INSIDE || intersection == IT_INTERSECT) if(intersection == IT_INSIDE || intersection == IT_INTERSECT)
{ {
renderer->num_indices += array_len(geometry->indices); renderer->num_indices += geometry->indices_len;
renderer->num_rendered++; renderer->num_rendered++;
} }
else else

@ -394,4 +394,5 @@ Done:
* Show version number in editor and console * Show version number in editor and console
* Save/Load base bounding boxes for entity types other than static mesh * Save/Load base bounding boxes for entity types other than static mesh
* Disabled picking when a tool is active in editor * Disabled picking when a tool is active in editor
* Simplified rendering further and removed unnecessary intermediate fbos * Simplified rendering further and removed unnecessary intermediate fbos
* We no longer keep geoemtry data loaded from files as it is not needed after data is passed on to opengl
Loading…
Cancel
Save