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 "util.h"
#include "render_object.h"
//#include "render_object.h"
struct render_object;
struct node_animation
{
render_object* ro;

13
include/entity.h

@ -7,25 +7,16 @@
#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
{
// 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;
// TODO: should be a pointer into a global array of mesh_info(s) or
// mesh_groups stored on the render_state object
meMeshGroup mesh_group;
render_objects render_objs;
render_object* render_objs;
uint ro_count;
};
bool entInit(entity& e, const char* model_path);

8
include/mesh.h

@ -15,10 +15,11 @@
struct meMeshInfo
{
glm::mat4 model_transform;
// NOTE: vertices, normals, and tex_coords have the same count
uint num_vertices;
glm::vec3* vertices;
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* indices;
util_image diffuse_texture;
@ -27,9 +28,10 @@ struct meMeshInfo
struct meMeshGroup
{
bool use_normals;
uint num_meshes;
// TODO: this should be one big allocation since the mesh doesn't change
// while running
meMeshInfo** meshes;
uint num_meshes;
};

8
include/render_object.h

@ -4,6 +4,8 @@
#include <GL/glew.h>
#include <glm/glm.hpp>
#include "mesh.h"
struct render_object
{
@ -16,8 +18,10 @@ struct render_object
GLuint index_buffer_id;
};
bool roInit(meMeshInfo* mi_in, render_object& ro_out);
// TODO: make use of glIsBuffer/glDeleteBuffers
void roFree(render_object* ro);
void roFree(render_object& ro);
// 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 "dumbLog.h"
#include "entity.h"
#include "util.h"
// forward declarations
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
@ -23,22 +22,14 @@ entInit(entity& e, const char* model_path)
entScale(e, glm::vec3(1.0));
entSetWorldPosition(e, glm::vec3(0, 0, 0));
if (meLoadFromFile(e.mesh_group, model_path)
&& loadMeshIntoGL(e))
if (meLoadFromFile(e.mesh_group, model_path))
{
#if 0
initEntityRG(e, shader, e.mesh_group.use_normals);
if (!initEntityROs(e))
goto cleanup;
#endif
} else {
goto cleanup;
e.ro_count = e.mesh_group.num_meshes;
e.render_objs = UTIL_ALLOC(e.ro_count, render_object);
if (loadMeshIntoGL(e))
return true;
}
return true;
cleanup:
entFree(e);
return false;
}
@ -48,8 +39,12 @@ entFree(entity& e)
{
meFreeMeshGroup(e.mesh_group);
for (uint i = 0; i < e.render_objs.count; i++)
roFree(&e.render_objs.objs[i]);
for (uint i = 0; i < e.ro_count; i++)
roFree(e.render_objs[i]);
utilSafeFree(e.render_objs);
e.render_objs = nullptr;
e.ro_count = 0;
}
void
@ -78,125 +73,19 @@ entScale(entity& e, glm::vec3 v)
bool
loadMeshIntoGL(entity& e)
{
LOG(Error) << "TODO: redo GL init for new render_object\n";
return false;
}
#if 0
void
initEntityRG(entity& e, rg_shader_program& shader, bool use_normals)
{
render_group* rg = UTIL_ALLOC(1, render_group);
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);
for (uint i = 0; i < e.mesh_group.num_meshes; i++) {
assert(e.render_objs != nullptr);
render_object ro = e.render_objs[i];
meMeshInfo* mi = e.mesh_group.meshes[i];
assert(mi != nullptr);
if (!roInit(mi, ro)) {
LOG(Error) << "Error initializing render objects\n";
entFree(e);
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;
}
#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);
meMeshInfo* copyMeshInfo(const aiScene* scene, aiMesh* mesh);
bool loadDiffuseTexture(const aiScene* scene, aiMesh* mesh, meMeshInfo* mi);
bool validateScene(const aiScene* scene, const char* filepath);
// interface
@ -40,19 +41,11 @@ meLoadFromFile(meMeshGroup& mesh_group, const char* filepath)
LOG(Info) << "Loading file: " << filepath << "\n";
const aiScene* scene = aiImportFile(filepath, aiProcessPreset_TargetRealtime_MaxQuality);
if (!scene) {
LOG(Error) << "Error loading file: " << filepath << "\n";
if (!validateScene(scene, filepath))
return false;
}
if (scene->mNumMeshes < 1) {
LOG(Error) << "Scene contains no meshes\n";
return false;
}
mesh_group.num_meshes = scene->mNumMeshes;
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++) {
aiMesh* mesh = scene->mMeshes[i];
@ -81,6 +74,8 @@ meFreeMeshGroup(meMeshGroup& mesh_group)
freeMesh(mesh_group.meshes[i]);
utilSafeFree(mesh_group.meshes);
mesh_group.num_meshes = 0;
mesh_group.meshes = nullptr;
}
void
@ -198,3 +193,24 @@ copyMeshInfo(const aiScene* scene, aiMesh* mesh)
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"
// 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
roFree(render_object* ro)
roFree(render_object& ro)
{
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