diff --git a/src/asset.cpp b/src/asset.cpp index 0cb9d67..99b986d 100644 --- a/src/asset.cpp +++ b/src/asset.cpp @@ -10,26 +10,105 @@ // forward declarations + +// TODO: move to GLDebug.h? void dumpNodes(tinygltf::Model t_mdl); -model* initModel(Assets* assets, - MemoryArena* arena, - tinygltf::Model t_mdl, - const char* filename); -util_image* copyDiffuseTexture(Assets* assets, - MemoryArena* arena, - const tinygltf::Model& t_mdl); bool parseMeshNode(mesh* m, MemoryArena* arena, const tinygltf::Node& node, const tinygltf::Model& t_mdl); +model* getCachedModel(Assets* assets, u64 path_hash); +model* loadModelFile(Assets* assets, const char* filename); +util_image* getCachedTexture(Assets* assets, u64 path_hash); +util_image* loadTextureFile(Assets* assets, const char* filename); + // interface model* -assetLoadFromFile(Assets* assets, - MemoryArena* arena, +getModelByPath(Assets* assets, const char* filepath) +{ + model* mdl = getCachedModel(assets, utilFNV64a_str(filepath)); + + if (!mdl) + mdl = loadModelFile(assets, filepath); + + return mdl; +} + +util_image* +getTextureByPath(Assets* assets, const char* filepath) +{ + util_image* texture = + getCachedTexture(assets, utilFNV64a_str(filepath)); + + if (!texture) + texture = loadTextureFile(assets, filepath); + + return texture; +} + + +// internal + +model* +initModel(Assets* assets, + tinygltf::Model t_mdl, const char* filename) +{ + // TODO: re-alloc array when out of space + assert(assets->num_models < assets->max_models && assets->arena != nullptr); + model* mdl = &assets->models[assets->num_models]; + assets->num_models++; + + uint buf_count = t_mdl.bufferViews.size(); + mdl->meshes = ARENA_ALLOC(assets->arena, mesh, buf_count); + mdl->num_meshes = t_mdl.meshes.size(); + mdl->filepath = arenaCopyCStr(assets->arena, filename, MAX_PATH_SIZE); + mdl->filepath_hash = utilFNV64a_str(mdl->filepath); + + return mdl; +} + +util_image* +getFreeTexture(Assets* assets) +{ + if (assets->num_textures < assets->max_textures) + return &assets->textures[assets->num_textures++]; + + printf("%s(), no free textures\n", __FUNCTION__); + return nullptr; +} + +util_image* +copyDiffuseTexture(Assets* assets, 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]; + + util_image* dtex = getFreeTexture(assets); + if (!dtex) return nullptr; + + 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 = ARENA_ALLOC(assets->arena, u8, dtex->data_len); + std::strncpy(dtex->file_path, t_img.uri.c_str(), sizeof(dtex->file_path)); + dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); + std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); + + return dtex; +} + +model* +loadModelFile(Assets* assets, const char* filename) { tinygltf::Model t_mdl; tinygltf::TinyGLTF gltf_ctx; @@ -48,8 +127,8 @@ assetLoadFromFile(Assets* assets, #endif // NOTE: assume we're working with a single buffer assert(t_mdl.buffers.size() == 1); - model* mdl = initModel(assets, arena, t_mdl, filename); - mdl->diffuse_texture = copyDiffuseTexture(assets, arena, t_mdl); + model* mdl = initModel(assets, t_mdl, filename); + mdl->diffuse_texture = copyDiffuseTexture(assets, t_mdl); if (mdl->diffuse_texture == nullptr) { LOG(Error) << "Error Loading diffuse texture\n"; @@ -61,7 +140,11 @@ assetLoadFromFile(Assets* assets, 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++], + assets->arena, + node, + t_mdl)) + { LOG(Error) << "Error parsing node\n"; return nullptr; } @@ -72,38 +155,33 @@ assetLoadFromFile(Assets* assets, } model* -assetGetCachedModel(Assets* assets, uint64_t path_hash) +getCachedModel(Assets* assets, u64 path_hash) { - for (uint i = 0; i < assets->num_models; i++) { + for (u32 i = 0; i < assets->num_models; i++) { if (assets->models[i].filepath_hash == path_hash) return &assets->models[i]; } - LOG(Debug) << "asset not cached: " << path_hash << "\n"; + LOG(Debug) << "asset not cached, hash: " << path_hash << "\n"; return nullptr; } - -// internal - -model* -initModel(Assets* assets, - MemoryArena* arena, - tinygltf::Model t_mdl, - const char* filename) +util_image* +loadTextureFile(Assets* assets, const char* filename) { - // TODO: re-alloc array when out of space - assert(assets->num_models < assets->max_models && arena != nullptr); - model* mdl = &assets->models[assets->num_models]; - assets->num_models++; + return nullptr; +} - uint buf_count = t_mdl.bufferViews.size(); - mdl->meshes = ARENA_ALLOC(arena, mesh, buf_count); - mdl->num_meshes = t_mdl.meshes.size(); - mdl->filepath = arenaCopyCStr(arena, filename, MAX_PATH_SIZE); - mdl->filepath_hash = utilFNV64a_str(mdl->filepath); +util_image* +getCachedTexture(Assets* assets, u64 path_hash) +{ + for (u32 i = 0; i < assets->num_textures; i++) { + if (assets->textures[i].filepath_hash == path_hash) + return &assets->textures[i]; + } - return mdl; + LOG(Debug) << "asset not cached, hash: " << path_hash << "\n"; + return nullptr; } bool @@ -215,44 +293,6 @@ parseMeshNode(mesh* m, return false; } -util_image* -getFreeTexture(Assets* assets) -{ - if (assets->num_textures < assets->max_textures) - return &assets->textures[assets->num_textures++]; - - printf("%s(), no free textures\n", __FUNCTION__); - return nullptr; -} - -util_image* -copyDiffuseTexture(Assets* assets, - MemoryArena* 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]; - - util_image* dtex = getFreeTexture(assets); - if (!dtex) return nullptr; - - 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 = ARENA_ALLOC(arena, u8, dtex->data_len); - std::strncpy(dtex->file_path, t_img.uri.c_str(), sizeof(dtex->file_path)); - dtex->filepath_hash = utilFNV64a_str(t_img.uri.c_str()); - std::memcpy(dtex->pixels, t_img.image.data(), dtex->data_len); - - return dtex; -} - const char* getTargetStr(int target) { diff --git a/src/asset.h b/src/asset.h index 4eac966..e5d744e 100644 --- a/src/asset.h +++ b/src/asset.h @@ -9,6 +9,7 @@ // NOTE: wrapper for stb_image +// TODO: better name would be AssetTexture struct util_image { i32 w; @@ -23,7 +24,7 @@ struct util_image // NOTE: wrapper for tinygltf https://github.com/syoyo/tinygltf // https://github.com/KhronosGroup/glTF - +// TODO: rename to Mesh or MeshAsset? struct mesh { u32 num_vertices; @@ -36,6 +37,7 @@ struct mesh glm::mat4* xform; }; +// TODO: rename to Model or ModelAsset #define MAX_PATH_SIZE 256 struct model { @@ -59,9 +61,7 @@ struct Assets }; -model* -assetLoadFromFile(Assets* assets, MemoryArena* arena, const char* filename); +model* getModelByPath(Assets* assets, const char* filepath); -model* -assetGetCachedModel(Assets* assets, u64 path_hash); +util_image* getTextureByPath(Assets* assets, const char* filepath); diff --git a/src/main.cpp b/src/main.cpp index b162909..f2b75d6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -249,8 +249,8 @@ loadScene(RenderState* rs) if (!s_default || !s_debug) return false; // TODO: full lighting model - model* tex_cube = getModelByPath(rs, "../data/textured_cube.gltf"); - assert(tex_cube != nullptr && tex_cube->num_meshes > 0); + model* tex_cube = getModelByPath(&rs->assets, "../data/textured_cube.gltf"); + assert(tex_cube != nullptr); const mesh& texmesh = tex_cube->meshes[0]; GLVertexAttrib* pos_attrib = getVertexAttribByName(s_debug, "position"); @@ -279,6 +279,7 @@ loadScene(RenderState* rs) Entity* e = getFreeEntity(orange_cubes); assert(e != nullptr); + // FIXME: check if mesh texture is cached here? if (!initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings, "debug_box")) { diff --git a/src/shader.cpp b/src/shader.cpp index 96169ed..a54fdd7 100644 --- a/src/shader.cpp +++ b/src/shader.cpp @@ -211,6 +211,23 @@ initGLAttribBuffer(gl_buffer* buf, GLenum target, GLVertexAttrib* attrib) buf->name = utilAllocateCStr(attrib->name); } +// FIXME: WIP +bool +initGLTexture(const util_image image, GLuint& tex_id) +{ + glGenTextures(1, &tex_id); + glBindTexture(GL_TEXTURE_2D, tex_id); + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + GLenum pixel_format = (image.num_channels == 3) ? GL_RGB : GL_RGBA; + glTexImage2D(GL_TEXTURE_2D, 0, pixel_format, image.w, image.h, 0, + pixel_format, GL_UNSIGNED_BYTE, image.pixels); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + + return (glGetError() == GL_NO_ERROR); +} +// FIXME: WIP + // FIXME: might as well pass in pointer to GLmesh, since that's how we're // going to use this, can void copying GLmesh twice that way GLmesh diff --git a/src/shader.h b/src/shader.h index 18e2dd1..f615f62 100644 --- a/src/shader.h +++ b/src/shader.h @@ -79,6 +79,7 @@ struct GLTexture GLenum pixel_format; // NOTE: GL_RGB or GL_RGBA u32 width; u32 height; + u64 filepath_hash; }; struct GLContext