Browse Source

update asset cache and loading interface

main
cinnaboot 5 years ago
parent
commit
8370a69ed4
  1. 182
      src/asset.cpp
  2. 10
      src/asset.h
  3. 5
      src/main.cpp
  4. 17
      src/shader.cpp
  5. 1
      src/shader.h

182
src/asset.cpp

@ -10,26 +10,105 @@
// forward declarations // forward declarations
// TODO: move to GLDebug.h?
void dumpNodes(tinygltf::Model t_mdl); 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, bool parseMeshNode(mesh* m,
MemoryArena* arena, MemoryArena* arena,
const tinygltf::Node& node, const tinygltf::Node& node,
const tinygltf::Model& t_mdl); 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 // interface
model* model*
assetLoadFromFile(Assets* assets, getModelByPath(Assets* assets, const char* filepath)
MemoryArena* arena, {
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) 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::Model t_mdl;
tinygltf::TinyGLTF gltf_ctx; tinygltf::TinyGLTF gltf_ctx;
@ -48,8 +127,8 @@ assetLoadFromFile(Assets* assets,
#endif #endif
// NOTE: assume we're working with a single buffer // NOTE: assume we're working with a single buffer
assert(t_mdl.buffers.size() == 1); assert(t_mdl.buffers.size() == 1);
model* mdl = initModel(assets, arena, t_mdl, filename); model* mdl = initModel(assets, t_mdl, filename);
mdl->diffuse_texture = copyDiffuseTexture(assets, arena, t_mdl); mdl->diffuse_texture = copyDiffuseTexture(assets, t_mdl);
if (mdl->diffuse_texture == nullptr) { if (mdl->diffuse_texture == nullptr) {
LOG(Error) << "Error Loading diffuse texture\n"; LOG(Error) << "Error Loading diffuse texture\n";
@ -61,7 +140,11 @@ assetLoadFromFile(Assets* assets,
for (tinygltf::Node node : t_mdl.nodes) { for (tinygltf::Node node : t_mdl.nodes) {
if (node.mesh >= 0) { 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"; LOG(Error) << "Error parsing node\n";
return nullptr; return nullptr;
} }
@ -72,38 +155,33 @@ assetLoadFromFile(Assets* assets,
} }
model* 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) if (assets->models[i].filepath_hash == path_hash)
return &assets->models[i]; return &assets->models[i];
} }
LOG(Debug) << "asset not cached: " << path_hash << "\n"; LOG(Debug) << "asset not cached, hash: " << path_hash << "\n";
return nullptr; return nullptr;
} }
util_image*
// internal loadTextureFile(Assets* assets, const char* filename)
model*
initModel(Assets* assets,
MemoryArena* arena,
tinygltf::Model t_mdl,
const char* filename)
{ {
// TODO: re-alloc array when out of space return nullptr;
assert(assets->num_models < assets->max_models && arena != nullptr); }
model* mdl = &assets->models[assets->num_models];
assets->num_models++;
uint buf_count = t_mdl.bufferViews.size(); util_image*
mdl->meshes = ARENA_ALLOC(arena, mesh, buf_count); getCachedTexture(Assets* assets, u64 path_hash)
mdl->num_meshes = t_mdl.meshes.size(); {
mdl->filepath = arenaCopyCStr(arena, filename, MAX_PATH_SIZE); for (u32 i = 0; i < assets->num_textures; i++) {
mdl->filepath_hash = utilFNV64a_str(mdl->filepath); 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 bool
@ -215,44 +293,6 @@ parseMeshNode(mesh* m,
return false; 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* const char*
getTargetStr(int target) getTargetStr(int target)
{ {

10
src/asset.h

@ -9,6 +9,7 @@
// NOTE: wrapper for stb_image // NOTE: wrapper for stb_image
// TODO: better name would be AssetTexture
struct util_image struct util_image
{ {
i32 w; i32 w;
@ -23,7 +24,7 @@ struct util_image
// NOTE: wrapper for tinygltf https://github.com/syoyo/tinygltf // NOTE: wrapper for tinygltf https://github.com/syoyo/tinygltf
// https://github.com/KhronosGroup/glTF // https://github.com/KhronosGroup/glTF
// TODO: rename to Mesh or MeshAsset?
struct mesh struct mesh
{ {
u32 num_vertices; u32 num_vertices;
@ -36,6 +37,7 @@ struct mesh
glm::mat4* xform; glm::mat4* xform;
}; };
// TODO: rename to Model or ModelAsset
#define MAX_PATH_SIZE 256 #define MAX_PATH_SIZE 256
struct model struct model
{ {
@ -59,9 +61,7 @@ struct Assets
}; };
model* model* getModelByPath(Assets* assets, const char* filepath);
assetLoadFromFile(Assets* assets, MemoryArena* arena, const char* filename);
model* util_image* getTextureByPath(Assets* assets, const char* filepath);
assetGetCachedModel(Assets* assets, u64 path_hash);

5
src/main.cpp

@ -249,8 +249,8 @@ loadScene(RenderState* rs)
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 = getModelByPath(rs, "../data/textured_cube.gltf"); model* tex_cube = getModelByPath(&rs->assets, "../data/textured_cube.gltf");
assert(tex_cube != nullptr && tex_cube->num_meshes > 0); assert(tex_cube != nullptr);
const mesh& texmesh = tex_cube->meshes[0]; const mesh& texmesh = tex_cube->meshes[0];
GLVertexAttrib* pos_attrib = getVertexAttribByName(s_debug, "position"); GLVertexAttrib* pos_attrib = getVertexAttribByName(s_debug, "position");
@ -279,6 +279,7 @@ loadScene(RenderState* rs)
Entity* e = getFreeEntity(orange_cubes); Entity* e = getFreeEntity(orange_cubes);
assert(e != nullptr); assert(e != nullptr);
// FIXME: check if mesh texture is cached here?
if (!initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings, if (!initEntity(e, rs->rg_arena, tex_cube, 2, attrib_mappings,
"debug_box")) "debug_box"))
{ {

17
src/shader.cpp

@ -211,6 +211,23 @@ initGLAttribBuffer(gl_buffer* buf, GLenum target, GLVertexAttrib* attrib)
buf->name = utilAllocateCStr(attrib->name); 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 // 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 // going to use this, can void copying GLmesh twice that way
GLmesh GLmesh

1
src/shader.h

@ -79,6 +79,7 @@ struct GLTexture
GLenum pixel_format; // NOTE: GL_RGB or GL_RGBA GLenum pixel_format; // NOTE: GL_RGB or GL_RGBA
u32 width; u32 width;
u32 height; u32 height;
u64 filepath_hash;
}; };
struct GLContext struct GLContext

Loading…
Cancel
Save