From 1d09bdfa2007bb0747b5d09b5511646f7106d79f Mon Sep 17 00:00:00 2001 From: Doyle Thai Date: Sat, 27 Aug 2016 04:15:13 +1000 Subject: [PATCH] Draft implementation of hash tabled textures --- src/AssetManager.c | 56 +++++++++++++++++++++------- src/Renderer.c | 2 +- src/Texture.c | 12 +++--- src/WorldTraveller.c | 27 ++++---------- src/include/Dengine/AssetManager.h | 11 ++++-- src/include/Dengine/Assets.h | 12 ------ src/include/Dengine/Texture.h | 8 ++++ src/include/Dengine/WorldTraveller.h | 2 - 8 files changed, 72 insertions(+), 58 deletions(-) diff --git a/src/AssetManager.c b/src/AssetManager.c index 0f38b3b..5841c67 100644 --- a/src/AssetManager.c +++ b/src/AssetManager.c @@ -106,17 +106,17 @@ AudioVorbis *asset_getVorbis(AssetManager *assetManager, return NULL; } -Texture *asset_getTexture(AssetManager *const assetManager, - const enum TexList type) +Texture *asset_getTex(AssetManager *const assetManager, const char *const key) { - if (type < texlist_count) - return &assetManager->textures[type]; + u32 hashIndex = common_getHashIndex(key, ARRAY_COUNT(assetManager->textures)); + Texture *result = &assetManager->textures[hashIndex]; + if (result->key) + { + while (result && common_strcmp(result->key, key) != 0) + result = result->next; + } -#ifdef DENGINE_DEBUG - ASSERT(INVALID_CODE_PATH); -#endif - - return NULL; + return result; } TexAtlas *asset_makeTexAtlas(AssetManager *const assetManager, @@ -211,8 +211,35 @@ const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, return 0; } -const i32 asset_loadTextureImage(AssetManager *assetManager, - const char *const path, const enum TexList type) +// TODO(doyle): Revise passing in the assetmanager +Texture *asset_getAndAllocFreeTexSlot(AssetManager *assetManager, + MemoryArena *arena, const char *const key) +{ + i32 texListSize = ARRAY_COUNT(assetManager->textures); + u32 hashIndex = common_getHashIndex(key, ARRAY_COUNT(assetManager->textures)); + Texture *result = &assetManager->textures[hashIndex]; + if (result->key) + { + while (result->next) + { + if (common_strcmp(result->key, key) == 0) + { + // TODO(doyle): Error correction whereby if a tex atlas already + // exists + ASSERT(INVALID_CODE_PATH); + } + result = result->next; + } + + result->next = PLATFORM_MEM_ALLOC(arena, 1, Texture); + result = result->next; + } + + return result; +} + +const i32 asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, + const char *const path, const char *const key) { /* Open the texture image */ i32 imgWidth, imgHeight, bytesPerPixel; @@ -235,12 +262,13 @@ const i32 asset_loadTextureImage(AssetManager *assetManager, return -1; } - Texture tex = texture_gen(CAST(GLuint)(imgWidth), CAST(GLuint)(imgHeight), - CAST(GLint)(bytesPerPixel), image); + Texture *tex = asset_getAndAllocFreeTexSlot(assetManager, arena, key); + *tex = texture_gen(CAST(GLuint)(imgWidth), CAST(GLuint)(imgHeight), + CAST(GLint)(bytesPerPixel), image); + GL_CHECK_ERROR(); stbi_image_free(image); - assetManager->textures[type] = tex; return 0; } diff --git a/src/Renderer.c b/src/Renderer.c index a7813c0..f6fc9b2 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -154,7 +154,7 @@ INTERNAL v2 mapWorldToCameraSpace(v2 worldPos, v4 cameraBounds) RenderTex renderer_createNullRenderTex(AssetManager *const assetManager) { - Texture *emptyTex = asset_getTexture(assetManager, texlist_empty); + Texture *emptyTex = asset_getTex(assetManager, "nullTex"); RenderTex result = {emptyTex, V4(0, 1, 1, 0)}; return result; } diff --git a/src/Texture.c b/src/Texture.c index 06378d9..0bc5992 100644 --- a/src/Texture.c +++ b/src/Texture.c @@ -34,12 +34,12 @@ Texture texture_gen(const GLuint width, const GLuint height, // TODO(doyle): Let us set the parameters gl params as well GL_CHECK_ERROR(); Texture tex = {0}; - tex.width = width; - tex.height = height; - tex.internalFormat = GL_RGBA; - tex.wrapS = GL_REPEAT; - tex.wrapT = GL_REPEAT; - tex.filterMinification = GL_NEAREST; + tex.width = width; + tex.height = height; + tex.internalFormat = GL_RGBA; + tex.wrapS = GL_REPEAT; + tex.wrapT = GL_REPEAT; + tex.filterMinification = GL_NEAREST; tex.filterMagnification = GL_NEAREST; glGenTextures(1, &tex.id); diff --git a/src/WorldTraveller.c b/src/WorldTraveller.c index 98a08ec..87fef8d 100644 --- a/src/WorldTraveller.c +++ b/src/WorldTraveller.c @@ -53,7 +53,7 @@ INTERNAL void addGenericMob(MemoryArena *arena, AssetManager *assetManager, v2 size = V2(58.0f, 98.0f); enum EntityType type = entitytype_mob; enum Direction dir = direction_west; - Texture *tex = asset_getTexture(assetManager, texlist_claude); + Texture *tex = asset_getTex(assetManager, "ClaudeSprite.png"); b32 collides = TRUE; Entity *mob = entity_add(arena, world, pos, size, type, dir, tex, collides); @@ -458,25 +458,15 @@ INTERNAL void parseXmlTreeToGame(AssetManager *assetManager, MemoryArena *arena, common_strncat(imagePath, dataDir, common_strlen(dataDir)); common_strncat(imagePath, imageName, common_strlen(imageName)); - // TODO(doyle): Fixme proper loading of texture into right slot - if (common_strcmp(imageName, "ClaudeSprite.png") == 0) - { - asset_loadTextureImage(assetManager, imagePath, - texlist_claude); - } - else - { - asset_loadTextureImage(assetManager, imagePath, - texlist_terrain); - } + asset_loadTextureImage(assetManager, arena, imagePath, + imageName); atlasEntry->key = PLATFORM_MEM_ALLOC( arena, common_strlen(imageName) + 1, char); common_strncpy(atlasEntry->key, imageName, common_strlen(imageName)); - atlasEntry->tex = - asset_getTexture(assetManager, texlist_claude); + atlasEntry->tex = asset_getTex(assetManager, imageName); XmlNode *atlasChildNode = atlasXmlNode->child; while (atlasChildNode) @@ -663,8 +653,8 @@ INTERNAL void assetInit(GameState *state) /* Create empty 1x1 4bpp black texture */ u32 bitmap = (0xFF << 24) | (0xFF << 16) | (0xFF << 8) | (0xFF << 0); - Texture emptyTex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap)); - assetManager->textures[texlist_empty] = emptyTex; + Texture *tex = asset_getAndAllocFreeTexSlot(assetManager, arena, "nullTex"); + *tex = texture_gen(1, 1, 4, CAST(u8 *)(&bitmap)); PlatformFileRead terrainXml = {0}; i32 result = platform_readFileToBuffer( @@ -833,7 +823,6 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) world->entityIdInBattle = PLATFORM_MEM_ALLOC(arena, world->maxEntities, i32); world->numEntitiesInBattle = 0; - world->texType = texlist_terrain; world->bounds = math_getRect(V2(0, 0), v2_scale(worldDimensionInTiles, CAST(f32) state->tileSize)); @@ -856,7 +845,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) V2(CAST(f32) state->tileSize, CAST(f32) state->tileSize); enum EntityType type = entitytype_tile; enum Direction dir = direction_null; - Texture *tex = asset_getTexture(assetManager, world->texType); + Texture *tex = asset_getTex(assetManager, "terrain.png"); b32 collides = FALSE; Entity *tile = entity_add(arena, world, pos, size, type, dir, tex, collides); @@ -891,7 +880,7 @@ INTERNAL void entityInit(GameState *state, v2 windowSize) pos = V2(size.x, CAST(f32) state->tileSize); type = entitytype_hero; dir = direction_east; - tex = asset_getTexture(assetManager, texlist_claude); + tex = asset_getTex(assetManager, "ClaudeSprite.png"); collides = TRUE; Entity *hero = entity_add(arena, world, pos, size, type, dir, tex, collides); diff --git a/src/include/Dengine/AssetManager.h b/src/include/Dengine/AssetManager.h index d324cbd..68f6072 100644 --- a/src/include/Dengine/AssetManager.h +++ b/src/include/Dengine/AssetManager.h @@ -26,8 +26,7 @@ Rect asset_getAtlasSubTexRect(TexAtlas *atlas, char *key); AudioVorbis *asset_getVorbis(AssetManager *assetManager, const enum AudioList type); -Texture *asset_getTexture(AssetManager *const assetManager, - const enum TexList type); +Texture *asset_getTex(AssetManager *const assetManager, const char *const key); TexAtlas *asset_makeTexAtlas(AssetManager *const assetManager, MemoryArena *arena, const char *const key); @@ -37,13 +36,17 @@ Shader *asset_getShader(AssetManager *assetManager, const enum ShaderList type); TexAtlas *asset_getTexAtlas(AssetManager *const assetManager, const char *const key); +Texture *asset_getAndAllocFreeTexSlot(AssetManager *assetManager, + MemoryArena *arena, + const char *const key); + Animation *asset_getAnim(AssetManager *assetManager, char *key); const i32 asset_loadVorbis(AssetManager *assetManager, MemoryArena *arena, const char *const path, const enum AudioList type); -const i32 asset_loadTextureImage(AssetManager *assetManager, +const i32 asset_loadTextureImage(AssetManager *assetManager, MemoryArena *arena, const char *const path, - const enum TexList type); + const char *const key); const i32 asset_loadShaderFiles(AssetManager *assetManager, MemoryArena *arena, const char *const vertexPath, diff --git a/src/include/Dengine/Assets.h b/src/include/Dengine/Assets.h index e538b18..9d37359 100644 --- a/src/include/Dengine/Assets.h +++ b/src/include/Dengine/Assets.h @@ -32,18 +32,6 @@ enum TerrainRects terrainrects_count, }; -enum AnimList -{ - animlist_hero_idle, - animlist_hero_walk, - animlist_hero_wave, - animlist_hero_battlePose, - animlist_hero_tackle, - animlist_terrain, - animlist_count, - animlist_invalid, -}; - enum AudioList { audiolist_battle, diff --git a/src/include/Dengine/Texture.h b/src/include/Dengine/Texture.h index 0b09fbf..5571ca8 100644 --- a/src/include/Dengine/Texture.h +++ b/src/include/Dengine/Texture.h @@ -10,6 +10,12 @@ // TODO(doyle): Look into merging into assets.h file .. typedef struct Texture { + union + { + char *key; + char *name; + }; + // Holds the ID of the texture object, used for all texture operations to // reference to this particlar texture GLuint id; @@ -30,6 +36,8 @@ typedef struct Texture GLuint filterMinification; // Filtering mode if texture pixels > screen pixels GLuint filterMagnification; + + struct Texture *next; } Texture; // Generates texture from image data diff --git a/src/include/Dengine/WorldTraveller.h b/src/include/Dengine/WorldTraveller.h index bd56828..2eb6fb3 100644 --- a/src/include/Dengine/WorldTraveller.h +++ b/src/include/Dengine/WorldTraveller.h @@ -45,8 +45,6 @@ typedef struct World b32 *entityIdInBattle; i32 numEntitiesInBattle; - enum TexList texType; - i32 cameraFollowingId; v2 cameraPos; // In pixels v4 bounds; // In pixels