From 18c00bd9f4e58b644600e3f5526d9a929a7cfdd4 Mon Sep 17 00:00:00 2001 From: outfrost Date: Tue, 29 Jan 2019 04:30:17 +0100 Subject: [PATCH] Rework asset import, add texture import --- assimp_types.h | 1 + level.c | 94 ++++++++++++++++++++++++++++++++++++++++++++------ level.h | 23 ++++++++++-- render.c | 2 +- tga.c | 4 +-- 5 files changed, 108 insertions(+), 16 deletions(-) diff --git a/assimp_types.h b/assimp_types.h index 5900963..5230272 100644 --- a/assimp_types.h +++ b/assimp_types.h @@ -7,5 +7,6 @@ typedef struct aiScene AiScene; typedef struct aiNode AiNode; typedef struct aiMesh AiMesh; typedef struct aiFace AiFace; +typedef struct aiString AiString; #endif diff --git a/level.c b/level.c index 3469736..8c3b59d 100644 --- a/level.c +++ b/level.c @@ -1,32 +1,106 @@ #include #include +#include #include "level.h" #include "logger.h" -const AiScene* levelScene = NULL; +BlockGrid levelGrid; -static const Block BLOCK_EMPTY = 0; -static const Block BLOCK_WALL01 = 0xFF0000FF; // red +static Block blockEmpty = { .type = BLOCKTYPE_SPACE, + .sceneData = NULL, + .textureIds = NULL }; +static Block blockWall01 = { .type = BLOCKTYPE_OBSTACLE, + .sceneData = NULL, + .textureIds = NULL }; -static const AiScene* blockWall01 = NULL; +//static TgaImage* levelImage = NULL; -static TgaImage* levelImage = NULL; +static const char* replaceFileExtension(const AiString path, const char* ext); void initLevel() { - blockWall01 = importScene("out/assets/wall01.3ds"); - levelScene = blockWall01; + const AiScene* sceneData = importScene("out/assets/wall01.3ds"); + blockWall01.sceneData = sceneData; + if (sceneData != NULL) { + const unsigned int numTextures = sceneData->mNumMeshes; + + blockWall01.textureIds = malloc(numTextures * sizeof(GLuint)); + glGenTextures(numTextures, blockWall01.textureIds); + + for (unsigned int i = 0; i < numTextures; ++i) { + glBindTexture(GL_TEXTURE_2D, blockWall01.textureIds[i]); + + AiString originalTexturePath; + if (aiGetMaterialTexture(sceneData->mMaterials[sceneData->mMeshes[i]->mMaterialIndex], + aiTextureType_DIFFUSE, + 0, + &originalTexturePath, + NULL, NULL, NULL, NULL, NULL, NULL) == AI_SUCCESS) { + const char* textureFile = replaceFileExtension(originalTexturePath, ".tga"); + size_t textureFileLength = strlen(textureFile); + char* texturePath = malloc(strlen("out/assets/") + textureFileLength + 1); + strcpy(texturePath, "out/assets/"); + strncat(texturePath, textureFile, textureFileLength); + TgaImage* textureImage = readTga(texturePath); + if (textureImage == NULL) { + logError("Asset texture file not found: %s", texturePath); + } + else { + glTexImage2D(GL_TEXTURE_2D, + 0, + textureImage->imageComponents, + textureImage->header.imageWidth, + textureImage->header.imageHeight, + 0, + textureImage->imageFormat, + GL_UNSIGNED_BYTE, + textureImage->bytes); + free(textureImage->bytes); + } + } + } + + glBindTexture(GL_TEXTURE_2D, 0); + } } -void setImage(TgaImage* image) { - levelImage = image; +void buildLevelFromImage(TgaImage* image) { + if (image->header.imageBpp != 32) { + logError("Invalid level image format (%d bpp)", image->header.imageBpp); + return; + } } const AiScene* importScene(const char* path) { const AiScene* scene = aiImportFile(path, 0u); if (scene == NULL) { - logError("Asset import failed (file: %s)", path); + logError("Failed to import asset from %s", path); + } + else if ((scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE) == AI_SCENE_FLAGS_INCOMPLETE) { + logError("Incomplete scene imported from %s", path); } return scene; // TODO aiReleaseImport(scene); } + +/** BUGS + * The following function will not work properly with texture + * file names (excluding directory part) beginning with '.' + */ +static const char* replaceFileExtension(const AiString path, const char* ext) { + size_t lengthToCopy = path.length; + + char* lastDotSubstr = strrchr(path.data, '.'); + if (lastDotSubstr != NULL) { + if (strpbrk(lastDotSubstr, "\\/") == NULL) { + lengthToCopy = lastDotSubstr - path.data; + } + } + + size_t extLength = strlen(ext) + 1; + char* newPath = malloc(lengthToCopy + extLength); + strncpy(newPath, path.data, lengthToCopy); + strncpy(newPath + lengthToCopy, ext, extLength); + + return newPath; +} diff --git a/level.h b/level.h index b36c2bb..539ab37 100644 --- a/level.h +++ b/level.h @@ -7,12 +7,29 @@ #include "tga.h" -typedef uint32_t Block; +typedef enum { + BLOCKTYPE_SPACE, + BLOCKTYPE_OBSTACLE_X, + BLOCKTYPE_OBSTACLE_Z, + BLOCKTYPE_OBSTACLE +} BlockType; -const AiScene* levelScene; +typedef struct { + const BlockType type; + const AiScene* sceneData; + GLuint* textureIds; +} Block; + +typedef struct { + int width; + int height; + Block* blocks; +} BlockGrid; + +BlockGrid levelGrid; void initLevel(); -void setImage(TgaImage* image); +void buildLevelFromImage(TgaImage* image); const AiScene* importScene(const char* path); #endif diff --git a/render.c b/render.c index 18f0827..2ef2668 100644 --- a/render.c +++ b/render.c @@ -37,7 +37,7 @@ void renderScene() { glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); - drawSceneRecursive(levelScene, levelScene->mRootNode); +// drawSceneRecursive(levelScene, levelScene->mRootNode); glDisable(GL_LIGHT0); glFlush(); diff --git a/tga.c b/tga.c index 7e13d90..551039c 100644 --- a/tga.c +++ b/tga.c @@ -21,11 +21,11 @@ TgaImage* readTga(const char* path) { switch (header.imageBpp) { case 32: - imageFormat = GL_BGRA_EXT; + imageFormat = GL_BGRA; imageComponents = GL_RGBA8; break; case 24: - imageFormat = GL_BGR_EXT; + imageFormat = GL_BGR; imageComponents = GL_RGB8; break; case 8: -- 2.44.0