Browse Source

use RenderGroups and Entities to store groups of meshes

main
cinnaboot 5 years ago
parent
commit
62539c777f
  1. 216
      src/main.cpp
  2. 7
      src/shader.cpp
  3. 25
      src/shader.h

216
src/main.cpp

@ -22,42 +22,121 @@ struct SDLHandles
SDL_DisplayMode display_mode; SDL_DisplayMode display_mode;
}; };
// TODO: node/tree structure for entities
struct Node;
struct Entity
{
u32 num_meshes;
GLmesh* meshes;
glm::mat4* xform;
char* name;
};
struct RenderGroup
{
shader_program* shader;
u32 num_entites;
u32 max_entities;
Entity* entities;
char* name;
};
struct RenderState struct RenderState
{ {
memory_arena* asset_arena;
transforms* xforms; // NOTE: would be part of camera in libTangerine transforms* xforms; // NOTE: would be part of camera in libTangerine
SDLHandles* handles; SDLHandles* handles;
GLContext* gl_ctx; GLContext* gl_ctx;
memory_arena* asset_arena;
Assets* assets; Assets* assets;
// FIXME: WIP
// TODO: need to initialize groups
memory_arena* rg_arena; memory_arena* rg_arena;
u32 num_render_groups; u32 num_render_groups;
u32 max_render_groups; u32 max_render_groups;
RenderGroup* render_groups; RenderGroup* render_groups;
// TODO: need to initialize mappings
u32 num_mappings;
u32 max_mappings;
ShaderToRenderGroupMapping* mappings;
///
// TODO: can remove these after implementing render groups
u32 num_gl_meshes;
u32 max_gl_meshes;
GLmesh* gl_meshes;
u32 num_lights; u32 num_lights;
u32 max_lights; u32 max_lights;
PointLight* lights; PointLight* lights;
}; };
#define DEFAULT_ENTITY_COUNT 256
void
initRenderGroup(RenderGroup* rg,
memory_arena* arena,
shader_program* shader,
u32 num_entities = DEFAULT_ENTITY_COUNT,
const char* name = "")
{
rg->max_entities = num_entities;
rg->shader = shader;
rg->name = arenaCopyCStr(arena, name);
rg->entities = ARENA_ALLOC(arena, Entity, num_entities);
}
void
freeRenderGroup(RenderGroup* rg, memory_arena* arena)
{
printf("%s(), should probably look into freeing arena memory?\n",
__FUNCTION__);
assert(0);
}
Entity*
getFreeEntity(RenderGroup* rg)
{
if (rg->num_entites < rg->max_entities)
return &rg->entities[rg->num_entites++];
printf("%s(), render group full\n", __FUNCTION__);
return nullptr;
}
bool
initEntity(Entity* e,
memory_arena* arena,
model* mdl,
u32 num_attrib_mappings,
GLBufferToAttribMapping* attrib_mappings,
const char* name = "")
{
e->num_meshes = mdl->num_meshes;
e->meshes = ARENA_ALLOC(arena, GLmesh, e->num_meshes);
e->xform = ARENA_ALLOC(arena, glm::mat4, 1);
*e->xform = glm::mat4(1.f);
e->name = arenaCopyCStr(arena, name);
for (u32 i = 0; i< e->num_meshes; i++) {
GLmesh* glm = &e->meshes[i];
*glm = loadGLMesh(mdl->meshes[i], GL_TRIANGLES, glm::vec3(0, 0, 0),
num_attrib_mappings, attrib_mappings);
if (glm->vao_id == 0) {
printf("%s(), error initializing entity\n", __FUNCTION__);
return false;
}
}
return true;
}
void
setEntityPosition(Entity* e, glm::vec3 pos)
{
*e->xform = glm::translate(*e->xform, pos);
}
void
rotateEntity(Entity* e, glm::vec3 axis, float radians)
{
*e->xform = glm::rotate(*e->xform, radians, axis);
}
// NOTE: equivalent to rgAppend() in libTangerine // NOTE: equivalent to rgAppend() in libTangerine
model* model*
getModel(RenderState* rs, const char* filepath) getModelByPath(RenderState* rs, const char* filepath)
{ {
model* mdl = assetGetCached(rs->assets, utilFNV64a_str(filepath)); model* mdl = assetGetCached(rs->assets, utilFNV64a_str(filepath));
@ -67,13 +146,13 @@ getModel(RenderState* rs, const char* filepath)
return mdl; return mdl;
} }
GLmesh* RenderGroup*
getFreeGLMesh(RenderState* rs) getFreeRenderGroup(RenderState* rs)
{ {
if (rs->num_gl_meshes < rs->max_gl_meshes) if (rs->num_render_groups < rs->max_render_groups)
return &rs->gl_meshes[rs->num_gl_meshes++]; return &rs->render_groups[rs->num_render_groups++];
printf("%s(), Error, rs->gl_meshes is full\n", __FUNCTION__); printf("%s(), no free render group\n", __FUNCTION__);
return nullptr; return nullptr;
} }
@ -109,7 +188,7 @@ initAssets(memory_arena* arena,
return assets; return assets;
} }
#define MAX_GL_MESHES 256 #define DEFAULT_RENDER_GROUP_COUNT 256
RenderState* RenderState*
initRenderState() initRenderState()
{ {
@ -117,13 +196,16 @@ initRenderState()
if (rs) { if (rs) {
rs->asset_arena = arenaInit(DEFAULT_ARENA_SIZE); rs->asset_arena = arenaInit(DEFAULT_ARENA_SIZE);
rs->rg_arena = arenaInit(DEFAULT_ARENA_SIZE);
rs->assets = initAssets(rs->asset_arena); rs->assets = initAssets(rs->asset_arena);
rs->rg_arena = arenaInit(DEFAULT_ARENA_SIZE);
rs->max_render_groups = DEFAULT_RENDER_GROUP_COUNT;
rs->render_groups = ARENA_ALLOC(rs->rg_arena, RenderGroup,
DEFAULT_RENDER_GROUP_COUNT);
rs->gl_ctx = initGLContext(rs->asset_arena); rs->gl_ctx = initGLContext(rs->asset_arena);
rs->xforms = ARENA_ALLOC(rs->asset_arena, transforms, 1); rs->xforms = ARENA_ALLOC(rs->asset_arena, transforms, 1);
rs->handles = UTIL_ALLOC(1, SDLHandles); rs->handles = UTIL_ALLOC(1, SDLHandles);
rs->max_gl_meshes = MAX_GL_MESHES;
rs->gl_meshes = ARENA_ALLOC(rs->rg_arena, GLmesh, MAX_GL_MESHES);
} }
return rs; return rs;
@ -233,20 +315,12 @@ addShaders(RenderState* rs)
bool bool
loadScene(RenderState* rs) loadScene(RenderState* rs)
{ {
const u32 NUM_CUBES = 4;
glm::vec3 cube_locs[NUM_CUBES] = {
glm::vec3(-10, 10, 0),
glm::vec3(-10, -10, 0),
glm::vec3( 10, 10, 0),
glm::vec3( 10, -10, 0),
};
shader_program* s_default = getShaderByName("default", rs->gl_ctx); shader_program* s_default = getShaderByName("default", rs->gl_ctx);
shader_program* s_debug = getShaderByName("debug", rs->gl_ctx); shader_program* s_debug = getShaderByName("debug", rs->gl_ctx);
if (!s_default || !s_debug) return false; if (!s_default || !s_debug) return false;
// TODO: full lighting model // TODO: full lighting model
model* tex_cube = getModel(rs, "../data/textured_cube.gltf"); model* tex_cube = getModelByPath(rs, "../data/textured_cube.gltf");
assert(tex_cube != nullptr && tex_cube->num_meshes > 0); assert(tex_cube != nullptr && tex_cube->num_meshes > 0);
const mesh& texmesh = tex_cube->meshes[0]; const mesh& texmesh = tex_cube->meshes[0];
@ -259,30 +333,42 @@ loadScene(RenderState* rs)
{ "normal", nullptr, normal_attrib, texmesh.normals } { "normal", nullptr, normal_attrib, texmesh.normals }
}; };
// NOTE: load meshes const u32 NUM_CUBES = 4;
GLmesh* gl_texmesh = getFreeGLMesh(rs); glm::vec3 cube_locs[NUM_CUBES] = {
if (!gl_texmesh) return false; glm::vec3(-10, 10, 0),
glm::vec3(-10, -10, 0),
*gl_texmesh = loadGLMesh(texmesh, GL_TRIANGLES, glm::vec3(-5, -5, 0), 2, glm::vec3( 10, 10, 0),
attrib_mappings); glm::vec3( 10, -10, 0),
if (gl_texmesh->vao_id == 0) return false; };
gl_texmesh = getFreeGLMesh(rs);
if (!gl_texmesh) return false;
*gl_texmesh = loadGLMesh(texmesh, GL_TRIANGLES, glm::vec3(5, 5, 0), 2, RenderGroup* orange_cubes = getFreeRenderGroup(rs);
attrib_mappings); assert(orange_cubes != nullptr);
if (gl_texmesh->vao_id == 0) return false; initRenderGroup(orange_cubes, rs->rg_arena, s_debug, NUM_CUBES,
"debug_cubes");
for (u32 i = 0; i < NUM_CUBES; i++) { for (u32 i = 0; i < NUM_CUBES; i++) {
GLmesh* gmesh = getFreeGLMesh(rs); Entity* e = getFreeEntity(orange_cubes);
if (!gmesh) return false; assert(e != nullptr);
*gmesh = loadGLMesh(texmesh, GL_TRIANGLES, cube_locs[i], 2, if (!initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings,
attrib_mappings); "debug_box"))
if (gmesh->vao_id == 0) return false; {
// FIXME: this doesn't actually do anything
freeRenderGroup(orange_cubes, rs->rg_arena);
return false;
} }
setEntityPosition(e, cube_locs[i]);
}
RenderGroup* debug_cube_group = getFreeRenderGroup(rs);
assert(debug_cube_group != nullptr);
initRenderGroup(debug_cube_group, rs->rg_arena, s_default, 1,
"orange_cubes");
Entity* e = getFreeEntity(debug_cube_group);
assert(e != nullptr);
initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings, "orange_box");
return true; return true;
} }
@ -294,9 +380,6 @@ loop(RenderState* rs)
bool running = true; bool running = true;
SDL_Event e; SDL_Event e;
shader_program* s_default = getShaderByName("default", rs->gl_ctx);
shader_program* s_debug = getShaderByName("debug", rs->gl_ctx);
while (running) { while (running) {
frame_start = SDL_GetTicks(); frame_start = SDL_GetTicks();
@ -312,14 +395,18 @@ loop(RenderState* rs)
glClearColor(0.2, 0.2, 0.2, 1); glClearColor(0.2, 0.2, 0.2, 1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
for (u32 i = 0; i < rs->num_gl_meshes; i++) { for (u32 i = 0; i < rs->num_render_groups; i++) {
GLmesh& glm = rs->gl_meshes[i]; RenderGroup& rg = rs->render_groups[i];
*glm.model_xform = glm::rotate(
*glm.model_xform, (float) M_PI / 60, glm::vec3(0, 1, 0)); for (u32 j = 0; j < rg.num_entites; j++) {
// FIXME: need a shader to gl_mesh mapping Entity& e = rg.entities[j];
//shader_program* s = (glm.shader) ? glm.shader : s_debug; rotateEntity(&e, glm::vec3(0, 1, 0), (float) M_PI / 60);
shader_program* s = s_debug;
renderVAO(&glm, s); for (u32 k = 0; k < e.num_meshes; k++) {
GLmesh& glm = e.meshes[k];
renderVAO(&glm, e.xform, rg.shader);
}
}
} }
SDL_GL_SwapWindow(rs->handles->window); SDL_GL_SwapWindow(rs->handles->window);
@ -359,11 +446,6 @@ main()
return 1; return 1;
} }
#if 0
shader_program* s_debug = getShaderByName("debug", rs->gl_ctx);
dumpShader(s_debug->prog_id);
#endif
if (!loadScene(rs)) { if (!loadScene(rs)) {
LOG(Error) << "error loading scene\n"; LOG(Error) << "error loading scene\n";
return 1; return 1;

7
src/shader.cpp

@ -131,12 +131,12 @@ getShaderByID(GLContext* gl_ctx, GLuint prog_id)
} }
void void
renderVAO(GLmesh* glmesh, shader_program* shader) renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader)
{ {
glUseProgram(shader->prog_id); glUseProgram(shader->prog_id);
glBindVertexArray(glmesh->vao_id); glBindVertexArray(glmesh->vao_id);
glUniformMatrix4fv(shader->model_xform_id, 1, GL_FALSE, glUniformMatrix4fv(shader->model_xform_id, 1, GL_FALSE,
(float*) glmesh->model_xform); (float*) model_xform);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glmesh->element_buf->id); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, glmesh->element_buf->id);
glDrawElements( glDrawElements(
glmesh->draw_mode, glmesh->num_indices, GL_UNSIGNED_SHORT, 0); glmesh->draw_mode, glmesh->num_indices, GL_UNSIGNED_SHORT, 0);
@ -212,7 +212,7 @@ initGLAttribBuffer(gl_buffer* buf, GLenum target, GLVertexAttrib* attrib)
} }
// FIXME: might as well pass in pointer to GLmesh, since that's how we're // FIXME: might as well pass in pointer to GLmesh, since that's how we're
// going to use this, can void copying GLmesh twich that way // going to use this, can void copying GLmesh twice that way
GLmesh GLmesh
loadGLMesh(const mesh& m, loadGLMesh(const mesh& m,
GLenum draw_mode, GLenum draw_mode,
@ -273,6 +273,7 @@ freeGLMesh(GLmesh* glm)
} }
} }
// NOTE: internal // NOTE: internal
bool bool

25
src/shader.h

@ -112,29 +112,6 @@ struct GLmesh
gl_buffer* element_buf; gl_buffer* element_buf;
}; };
// TODO: node/tree structure for entities
struct Node;
struct Entity
{
u32 num_meshes;
GLmesh* meshes;
};
struct RenderGroup
{
u32 num_entites;
u32 max_entities;
Entity* entities;
char* name;
};
struct ShaderToRenderGroupMapping
{
shader_program* shader;
RenderGroup* render_group;
};
struct Animation; struct Animation;
struct PointLight struct PointLight
@ -171,7 +148,7 @@ shader_program* getShaderByName(const char* name, GLContext* gl_ctx);
shader_program* getShaderByID(GLContext* gl_ctx, GLuint prog_id); shader_program* getShaderByID(GLContext* gl_ctx, GLuint prog_id);
shader_program* getShaderByHash(GLContext* gl_ctx, u64 hash); shader_program* getShaderByHash(GLContext* gl_ctx, u64 hash);
shader_program* getFreeShader(GLContext* gl_ctx); shader_program* getFreeShader(GLContext* gl_ctx);
void renderVAO(GLmesh* glmesh, shader_program* shader); void renderVAO(GLmesh* glmesh, glm::mat4* model_xform, shader_program* shader);
GLVertexAttrib* getVertexAttribByName(shader_program* shader, const char* name); GLVertexAttrib* getVertexAttribByName(shader_program* shader, const char* name);
GLmesh loadGLMesh(const mesh& m, GLmesh loadGLMesh(const mesh& m,
GLenum draw_mode, GLenum draw_mode,

Loading…
Cancel
Save