Browse Source

get data buffering into GL again

testing
cinnaboot 6 years ago
parent
commit
4028c86c14
  1. 4
      include/animation.h
  2. 13
      include/entity.h
  3. 8
      include/mesh.h
  4. 8
      include/render_object.h
  5. 157
      src/entity.cpp
  6. 34
      src/mesh.cpp
  7. 65
      src/render_object.cpp

4
include/animation.h

@ -4,9 +4,11 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "util.h" #include "util.h"
#include "render_object.h" //#include "render_object.h"
struct render_object;
struct node_animation struct node_animation
{ {
render_object* ro; render_object* ro;

13
include/entity.h

@ -7,25 +7,16 @@
#include "render_object.h" #include "render_object.h"
struct render_objects
{
render_object* objs;
uint count;
};
// NOTE: an entity is the basic unit of the high level renderer interface
struct entity struct entity
{ {
// NOTE: glm::mat4 combines translation, scale, and rotation in a 4x4
// transform matrix. This is the equivalent of the 'model' matrix in
// the model, view, projection matrix composition
glm::mat4 world_transform; glm::mat4 world_transform;
// TODO: should be a pointer into a global array of mesh_info(s) or // TODO: should be a pointer into a global array of mesh_info(s) or
// mesh_groups stored on the render_state object // mesh_groups stored on the render_state object
meMeshGroup mesh_group; meMeshGroup mesh_group;
render_objects render_objs; render_object* render_objs;
uint ro_count;
}; };
bool entInit(entity& e, const char* model_path); bool entInit(entity& e, const char* model_path);

8
include/mesh.h

@ -15,10 +15,11 @@
struct meMeshInfo struct meMeshInfo
{ {
glm::mat4 model_transform; glm::mat4 model_transform;
// NOTE: vertices, normals, and tex_coords have the same count
uint num_vertices; uint num_vertices;
glm::vec3* vertices; glm::vec3* vertices;
glm::vec3* normals; glm::vec3* normals;
glm::vec3* texture_coords; // NOTE: using vec3 to stay aligned with other props glm::vec3* texture_coords; // NOTE: stay aligned with other buffers
uint num_indices; uint num_indices;
uint* indices; uint* indices;
util_image diffuse_texture; util_image diffuse_texture;
@ -27,9 +28,10 @@ struct meMeshInfo
struct meMeshGroup struct meMeshGroup
{ {
bool use_normals; // TODO: this should be one big allocation since the mesh doesn't change
uint num_meshes; // while running
meMeshInfo** meshes; meMeshInfo** meshes;
uint num_meshes;
}; };

8
include/render_object.h

@ -4,6 +4,8 @@
#include <GL/glew.h> #include <GL/glew.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include "mesh.h"
struct render_object struct render_object
{ {
@ -16,8 +18,10 @@ struct render_object
GLuint index_buffer_id; GLuint index_buffer_id;
}; };
bool roInit(meMeshInfo* mi_in, render_object& ro_out);
// TODO: make use of glIsBuffer/glDeleteBuffers // TODO: make use of glIsBuffer/glDeleteBuffers
void roFree(render_object* ro); void roFree(render_object& ro);
// TODO: implement me! // TODO: implement me!
void roDraw(render_object* ro); void roDraw(render_object& ro);

157
src/entity.cpp

@ -1,17 +1,16 @@
#include <cassert>
#include <glm/gtc/matrix_transform.hpp> #include <glm/gtc/matrix_transform.hpp>
#include "dumbLog.h" #include "dumbLog.h"
#include "entity.h" #include "entity.h"
#include "util.h"
// forward declarations // forward declarations
bool loadMeshIntoGL(entity& e); bool loadMeshIntoGL(entity& e);
#if 0
bool initEntityROs(entity& e);
bool convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture);
#endif
// interface // interface
@ -23,22 +22,14 @@ entInit(entity& e, const char* model_path)
entScale(e, glm::vec3(1.0)); entScale(e, glm::vec3(1.0));
entSetWorldPosition(e, glm::vec3(0, 0, 0)); entSetWorldPosition(e, glm::vec3(0, 0, 0));
if (meLoadFromFile(e.mesh_group, model_path) if (meLoadFromFile(e.mesh_group, model_path))
&& loadMeshIntoGL(e))
{ {
#if 0 e.ro_count = e.mesh_group.num_meshes;
initEntityRG(e, shader, e.mesh_group.use_normals); e.render_objs = UTIL_ALLOC(e.ro_count, render_object);
if (loadMeshIntoGL(e))
if (!initEntityROs(e)) return true;
goto cleanup;
#endif
} else {
goto cleanup;
} }
return true;
cleanup:
entFree(e); entFree(e);
return false; return false;
} }
@ -48,8 +39,12 @@ entFree(entity& e)
{ {
meFreeMeshGroup(e.mesh_group); meFreeMeshGroup(e.mesh_group);
for (uint i = 0; i < e.render_objs.count; i++) for (uint i = 0; i < e.ro_count; i++)
roFree(&e.render_objs.objs[i]); roFree(e.render_objs[i]);
utilSafeFree(e.render_objs);
e.render_objs = nullptr;
e.ro_count = 0;
} }
void void
@ -78,125 +73,19 @@ entScale(entity& e, glm::vec3 v)
bool bool
loadMeshIntoGL(entity& e) loadMeshIntoGL(entity& e)
{ {
LOG(Error) << "TODO: redo GL init for new render_object\n"; for (uint i = 0; i < e.mesh_group.num_meshes; i++) {
return false; assert(e.render_objs != nullptr);
} render_object ro = e.render_objs[i];
meMeshInfo* mi = e.mesh_group.meshes[i];
#if 0 assert(mi != nullptr);
void
initEntityRG(entity& e, rg_shader_program& shader, bool use_normals) if (!roInit(mi, ro)) {
{ LOG(Error) << "Error initializing render objects\n";
render_group* rg = UTIL_ALLOC(1, render_group); entFree(e);
e.ren_group = rg;
e.ren_group->shader = shader;
rg->draw_indexed = true;
rg->draw_mode = GL_TRIANGLES;
rg->use_normals = use_normals;
uint num_meshes = rg->num_objects = e.mesh_group.num_meshes;
rg->render_objects = UTIL_ALLOC(num_meshes, render_object*);
}
#endif
#if 0
bool
initEntityROs(entity& e)
{
render_group* rg = e.ren_group;
for (uint i = 0; i < e.mesh_group.num_meshes; i++)
{
meMeshInfo* mesh = e.mesh_group.meshes[i];
uint buffer_len = mesh->num_vertices * 3;
uint index_len = mesh->num_indices;
render_object* ro = rgAllocateRenderObject(buffer_len, index_len);
rg->render_objects[i] = ro;
if (ro == nullptr)
return false;
if (!convertMeshInfo(mesh, ro, rg->use_normals, mesh->use_texture)) {
rgFree(rg);
return false; return false;
} }
if (mesh->use_texture) {
ro->use_texture = true;
if (!rgInitGLTexture(ro->tex_id, mesh->diffuse_texture)) {
LOG(Error) << "Error initializing GL texture\n";
return false;
}
}
} }
return true; return true;
} }
#endif
#if 0
bool
convertMeshInfo(meMeshInfo* mesh, render_object* ro, bool use_normals, bool use_texture)
{
uint vertex_buf_len = mesh->num_vertices * 3;
GLfloat* vertex_buf = ro->vertex_buffer.buffer;
GLfloat* normal_buf = ro->normal_buffer.buffer;
GLfloat* uv_buf = ro->uv_buffer.buffer;
uint* index_buf = ro->index_buffer.buffer;
if (!vertex_buf || !normal_buf || !index_buf)
return false;
// dump vertices, colors, normals, and texture coords into render_group buffers
uint vertex_index = 0;
uint vertex_prop_index = 0;
for (uint i = 0; i < vertex_buf_len; i++) {
const glm::vec3& vertex = mesh->vertices[vertex_index];
switch (vertex_prop_index) {
case 0: vertex_buf[i] = vertex.x; break;
case 1: vertex_buf[i] = vertex.y; break;
case 2: vertex_buf[i] = vertex.z; break;
}
if (use_normals) {
const glm::vec3& normal = mesh->normals[vertex_index];
switch (vertex_prop_index) {
case 0: normal_buf[i] = normal.x; break;
case 1: normal_buf[i] = normal.y; break;
case 2: normal_buf[i] = normal.z; break;
}
}
if (use_texture) {
const glm::vec3& uv = mesh->texture_coords[vertex_index];
switch (vertex_prop_index) {
case 0: uv_buf[i] = uv.x; break;
case 1: uv_buf[i] = uv.y; break;
case 2: uv_buf[i] = uv.z; break;
}
}
vertex_prop_index++;
if (vertex_prop_index == 3) {
vertex_prop_index = 0;
vertex_index++;
}
}
// dump indices
for (uint i = 0; i < mesh->num_indices; i++)
index_buf[i] = mesh->indices[i];
rgInitGLFloatBuffer(&ro->vertex_buffer, GL_DYNAMIC_DRAW, GL_ARRAY_BUFFER);
if (use_normals)
rgInitGLFloatBuffer(&ro->normal_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
if (use_texture)
rgInitGLFloatBuffer(&ro->uv_buffer, GL_STATIC_DRAW, GL_ARRAY_BUFFER);
rgInitGLIndexBuffer(&ro->index_buffer, GL_STATIC_DRAW, GL_ELEMENT_ARRAY_BUFFER);
return true;
}
#endif

34
src/mesh.cpp

@ -20,6 +20,7 @@ void freeMesh(meMeshInfo* mesh);
inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out); inline glm::vec3 copyVector(aiVector3D v_in, glm::vec3& v_out);
meMeshInfo* copyMeshInfo(const aiScene* scene, aiMesh* mesh); meMeshInfo* copyMeshInfo(const aiScene* scene, aiMesh* mesh);
bool loadDiffuseTexture(const aiScene* scene, aiMesh* mesh, meMeshInfo* mi); bool loadDiffuseTexture(const aiScene* scene, aiMesh* mesh, meMeshInfo* mi);
bool validateScene(const aiScene* scene, const char* filepath);
// interface // interface
@ -40,19 +41,11 @@ meLoadFromFile(meMeshGroup& mesh_group, const char* filepath)
LOG(Info) << "Loading file: " << filepath << "\n"; LOG(Info) << "Loading file: " << filepath << "\n";
const aiScene* scene = aiImportFile(filepath, aiProcessPreset_TargetRealtime_MaxQuality); const aiScene* scene = aiImportFile(filepath, aiProcessPreset_TargetRealtime_MaxQuality);
if (!scene) { if (!validateScene(scene, filepath))
LOG(Error) << "Error loading file: " << filepath << "\n";
return false; return false;
}
if (scene->mNumMeshes < 1) {
LOG(Error) << "Scene contains no meshes\n";
return false;
}
mesh_group.num_meshes = scene->mNumMeshes; mesh_group.num_meshes = scene->mNumMeshes;
mesh_group.meshes = UTIL_ALLOC(mesh_group.num_meshes, meMeshInfo*); mesh_group.meshes = UTIL_ALLOC(mesh_group.num_meshes, meMeshInfo*);
mesh_group.use_normals = scene->mMeshes[0]->HasNormals();
for (uint i = 0; i < scene->mNumMeshes; i++) { for (uint i = 0; i < scene->mNumMeshes; i++) {
aiMesh* mesh = scene->mMeshes[i]; aiMesh* mesh = scene->mMeshes[i];
@ -81,6 +74,8 @@ meFreeMeshGroup(meMeshGroup& mesh_group)
freeMesh(mesh_group.meshes[i]); freeMesh(mesh_group.meshes[i]);
utilSafeFree(mesh_group.meshes); utilSafeFree(mesh_group.meshes);
mesh_group.num_meshes = 0;
mesh_group.meshes = nullptr;
} }
void void
@ -198,3 +193,24 @@ copyMeshInfo(const aiScene* scene, aiMesh* mesh)
return mi; return mi;
} }
bool
validateScene(const aiScene* scene, const char* filepath)
{
if (!scene) {
LOG(Error) << "Error loading file: " << filepath << "\n";
return false;
}
if (scene->mNumMeshes < 1) {
LOG(Error) << "Scene contains no meshes\n";
return false;
}
if (!scene->mMeshes[0]->HasNormals()) {
LOG(Error) << "Mesh doesn't have normals\n";
return false;
}
return true;
}

65
src/render_object.cpp

@ -3,8 +3,71 @@
#include "render_object.h" #include "render_object.h"
// forward declarations
bool initGLFloatBuffer(glm::vec3* buffer, uint count, GLuint& buffer_id);
bool initGLIndexBuffer(uint* buffer, uint num_indices, GLuint& buffer_id);
// interface
bool
roInit(meMeshInfo* mi_in, render_object& ro_out)
{
if (initGLFloatBuffer(mi_in->vertices,
mi_in->num_vertices,
ro_out.vertex_buffer_id) &&
initGLFloatBuffer(mi_in->normals,
mi_in->num_vertices,
ro_out.normal_buffer_id) &&
initGLFloatBuffer(mi_in->texture_coords,
mi_in->num_vertices,
ro_out.uv_buffer_id) &&
initGLIndexBuffer(mi_in->indices,
mi_in->num_indices,
ro_out.index_buffer_id))
{
return true;
}
LOG(Error) << "Failed to initialize render_object\n";
roFree(ro_out);
return false;
}
void void
roFree(render_object* ro) roFree(render_object& ro)
{ {
LOG(Debug) << "TODO: release GL buffers from render_object\n"; LOG(Debug) << "TODO: release GL buffers from render_object\n";
} }
// internal
bool
initGLFloatBuffer(glm::vec3* buffer, uint count, GLuint& buffer_id)
{
glGenBuffers(1, &buffer_id);
glBindBuffer(GL_ARRAY_BUFFER, buffer_id);
glBufferData(GL_ARRAY_BUFFER,
count * sizeof(GLfloat),
buffer,
GL_STATIC_DRAW);
// TODO: check for errors after buffering
return true;
}
bool
initGLIndexBuffer(uint* buffer, uint num_indices, GLuint& buffer_id)
{
glGenBuffers(1, &buffer_id);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_id);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
num_indices * sizeof(uint),
buffer,
GL_STATIC_DRAW);
// TODO: check for errors after buffering
return true;
}

Loading…
Cancel
Save