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
// 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)
{

10
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);

5
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"))
{

17
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

1
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

Loading…
Cancel
Save