diff --git a/examples/render_groups/main.cpp b/examples/render_groups/main.cpp index a3664bd..633cff9 100644 --- a/examples/render_groups/main.cpp +++ b/examples/render_groups/main.cpp @@ -195,15 +195,6 @@ main() renDoRenderLoop(rs, 60, doFrameCallbackPre); #endif // NOTE: testing entity system with new asset structures - // FIXME: remove mesh.h, mesh.cpp - // FIXME: remove platform_wait_for_vblank - // FIXME: clean up examples with new asset system - // FIXME: merger render_group_fix branch back into master - // FIXME: make a test case for overflowing default array sizes, rg->assets - // rg_info->groups, render_group->enitities - // FIXME: look for glm::mat4 in structs, and replace with pointers - // FIXME: better shader abstraction so we can store a list of shaders on - // render_state cameraInitPerspective( rs->cam, @@ -217,12 +208,14 @@ main() #if 1 entity* e = - rgAppend(rg, rs->assets, rs->arena, "../data/blender/spaceship.gltf"); + rgAppend(rg, rs->assets, rs->textures, rs->arena, + "../data/blender/spaceship.gltf"); uint scale = 4; //entRotate(e, -1 * M_PI_2, glm::vec3(1, 0, 0)); #else entity* e = - rgAppend(rg, rs->assets, rs->arena, "../data/blender/icosphere.gltf"); + rgAppend(rg, rs->assets, rs->textures, rs->arena, + "../data/blender/icosphere.gltf"); uint scale = 20; #endif if (e != nullptr) { diff --git a/include/asset.h b/include/asset.h index a690cd3..d0b1ba6 100644 --- a/include/asset.h +++ b/include/asset.h @@ -50,11 +50,24 @@ struct model_assets uint max; }; +struct texture_assets +{ + util_image* images; + uint count; + uint max; +}; + + +// TODO: would be nice to make these init functions generic model_assets* -assetInitBlock(memory_arena* arena, uint asset_count); +assetInitModelBlock(memory_arena* arena, uint asset_count); + +texture_assets* +assetInitTextureBlock(memory_arena* arena, uint asset_count); model* assetLoadFromFile(model_assets* assets, + texture_assets* textures, memory_arena* arena, const char* filename); diff --git a/include/renderer.h b/include/renderer.h index 6b44798..af37a02 100644 --- a/include/renderer.h +++ b/include/renderer.h @@ -60,6 +60,7 @@ rgAlloc(rg_info* rgi, uint num_entites, shader_wrapper shader); entity* rgAppend(render_group* rg, model_assets* assets, + texture_assets* textures, memory_arena* arena, const char* model_path); @@ -81,12 +82,9 @@ struct render_state rg_info* render_groups; - // WIP - model_assets* assets; memory_arena* arena; - // FIXME: should be a hashmap for textures loaded from assets - // ie) pallete textures - util_image* textures; + model_assets* assets; + texture_assets* textures; // TODO: hide shaders behind a better abstraction than 'shader_wrapper' default_shader_program* default_shader; diff --git a/include/util_image.h b/include/util_image.h index db9e8af..1d27d34 100644 --- a/include/util_image.h +++ b/include/util_image.h @@ -13,6 +13,7 @@ struct util_image int32 num_channels; uint data_len; uint8* pixels; + uint64_t filepath_hash; // FIXME: should use a pointer here, and just add the length of file_path // onto the allocation for util_image char file_path[256]; diff --git a/src/asset.cpp b/src/asset.cpp index bbfed86..3a2bcf9 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -15,7 +15,8 @@ model* initModel(model_assets* assets, memory_arena* arena, tinygltf::Model t_mdl, const char* filename); -bool parseMeshNode(mesh& m, +bool parseMeshNode(mesh* m, + texture_assets* textures, memory_arena* arena, const tinygltf::Node& node, const tinygltf::Model& t_mdl); @@ -24,7 +25,7 @@ bool parseMeshNode(mesh& m, // interface model_assets* -assetInitBlock(memory_arena* arena, uint asset_count) +assetInitModelBlock(memory_arena* arena, uint asset_count) { model_assets* assets = (model_assets*) arenaAllocateBlock(arena, sizeof(model_assets)); @@ -35,8 +36,52 @@ assetInitBlock(memory_arena* arena, uint asset_count) return assets; } +texture_assets* +assetInitTextureBlock(memory_arena* arena, uint asset_count) +{ + texture_assets* assets = + (texture_assets*) arenaAllocateBlock(arena, sizeof(texture_assets)); + assets->images = (util_image*) arenaAllocateBlock( + arena, asset_count * sizeof(util_image)); + assets->max = asset_count; + + return assets; +} + +// FIXME: move to internal when finished +util_image* +copyDiffuseTexture(texture_assets* textures, + memory_arena* arena, + const tinygltf::Model& t_mdl) +{ + // NOTE: assuming material[0] since we're using pallete texture + assert(t_mdl.materials.size() == 1 + && t_mdl.textures.size() == 1 + && t_mdl.images.size() == 1 + && t_mdl.images[0].image.size() > 0); + tinygltf::Image t_img = t_mdl.images[0]; + + // TODO: re-alloc array when out of space + assert(textures->count < textures->max && arena != nullptr); + util_image* dtex = &textures->images[textures->count]; + textures->count++; + + dtex->w = t_img.width; + dtex->h = t_img.height; + dtex->bits_per_channel = t_img.bits; + dtex->num_channels = t_img.component; + dtex->data_len = t_img.image.size(); + dtex->pixels = (uint8*) arenaAllocateBlock(arena, dtex->data_len); + std::strncpy(dtex->file_path, t_img.uri.c_str(), t_img.uri.size()); + dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); + std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); + + return dtex; +} + model* assetLoadFromFile(model_assets* assets, + texture_assets* textures, memory_arena* arena, const char* filename) { @@ -52,19 +97,28 @@ assetLoadFromFile(model_assets* assets, << " , msg: " << err << "\n"; return nullptr; } - +#if 0 + dumpNodes(t_mdl); +#endif // NOTE: assume we're working with a single buffer assert(t_mdl.buffers.size() == 1); model* mdl = initModel(assets, arena, t_mdl, filename); - // FIXME: also need to dump textures/materials -#if 0 - dumpNodes(t_mdl); + mdl->diffuse_texture = copyDiffuseTexture(textures, arena, t_mdl); +#if 1 + if (mdl->diffuse_texture == nullptr) { + LOG(Error) << "Error Loading diffuse texture\n"; + // TODO: reclaim arena memory + return nullptr; + } #endif + uint mesh_idx = 0; for (tinygltf::Node node : t_mdl.nodes) { if (node.mesh >= 0) { - if (!parseMeshNode(mdl->meshes[mesh_idx++], arena, node, t_mdl)) { + if (!parseMeshNode(&mdl->meshes[mesh_idx++], + textures, arena, node, t_mdl)) + { LOG(Error) << "Error parsing node\n"; return nullptr; } @@ -122,6 +176,7 @@ copyBuffer(uint8_t*& buffer_ref, const tinygltf::BufferView& bv = t_mdl.bufferViews[acc.bufferView]; const tinygltf::Buffer& t_buf = t_mdl.buffers[bv.buffer]; + // TODO: clean up validation if (bv.target == TINYGLTF_TARGET_ARRAY_BUFFER) { assert(acc.componentType == TINYGLTF_COMPONENT_TYPE_FLOAT && (acc.type == TINYGLTF_TYPE_VEC3 @@ -176,7 +231,8 @@ parseNodeTransform(memory_arena* arena, const tinygltf::Node* node) } bool -parseMeshNode(mesh& m, +parseMeshNode(mesh* m, + texture_assets* textures, memory_arena* arena, const tinygltf::Node& node, const tinygltf::Model& t_mdl) @@ -195,26 +251,26 @@ parseMeshNode(mesh& m, const tinygltf::Accessor& vert_acc = t_mdl.accessors[prim.attributes["POSITION"]]; const tinygltf::Accessor& index_acc = t_mdl.accessors[prim.indices]; - m.num_vertices = vert_acc.count; - m.num_indices = index_acc.count; - m.draw_mode = prim.mode; - m.usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes + m->num_vertices = vert_acc.count; + m->num_indices = index_acc.count; + m->draw_mode = prim.mode; + m->usage = GL_STATIC_DRAW; // TODO: logic for updating dynamic meshes // FIXME: the node transforms from blender only work as part of a node tree #if 1 - m.xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); - *m.xform = glm::mat4(1.0f); + m->xform = (glm::mat4*) arenaAllocateBlock(arena, sizeof(glm::mat4)); + *m->xform = glm::mat4(1.0f); #else - m.xform = parseNodeTransform(arena, &node); + m->xform = parseNodeTransform(arena, &node); #endif - if (m.xform != nullptr - && copyBuffer((uint8_t*&) m.vertices, arena, + if (m->xform != nullptr + && copyBuffer((uint8_t*&) m->vertices, arena, prim.attributes["POSITION"], t_mdl) - && copyBuffer((uint8_t*&) m.normals, arena, + && copyBuffer((uint8_t*&) m->normals, arena, prim.attributes["NORMAL"], t_mdl) - && copyBuffer((uint8_t*&) m.texture_coords, arena, + && copyBuffer((uint8_t*&) m->texture_coords, arena, prim.attributes["TEXCOORD_0"], t_mdl) - && copyBuffer((uint8_t*&) m.indices, arena, + && copyBuffer((uint8_t*&) m->indices, arena, prim.indices, t_mdl)) { return true; diff --git a/src/renderer.cpp b/src/renderer.cpp index 8695e33..2d28e9b 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -56,6 +56,7 @@ rgAlloc(rg_info* rgi, uint num_entites, shader_wrapper shader) entity* rgAppend(render_group* rg, model_assets* assets, + texture_assets* textures, memory_arena* arena, const char* model_path) { @@ -65,7 +66,7 @@ rgAppend(render_group* rg, // NOTE: not cached if (mdl == nullptr) { - mdl = assetLoadFromFile(assets, arena, model_path); + mdl = assetLoadFromFile(assets, textures, arena, model_path); if (mdl == nullptr) { LOG(Error) << "Error loading model: " << model_path << "\n"; @@ -101,7 +102,8 @@ renInit(const char* title, rs->render_groups->groups = UTIL_ALLOC(DEFAULT_RG_COUNT, render_group); rs->render_groups->max_size = DEFAULT_RG_COUNT; rs->arena = arenaInit(arena_size); - rs->assets = assetInitBlock(rs->arena, asset_size); + rs->assets = assetInitModelBlock(rs->arena, asset_size); + rs->textures = assetInitTextureBlock(rs->arena, asset_size); rs->lights = lightsInit(); setDefaults(rs, viewport_dims);