#include "AssetLoaderGfxImage.h" #include #include #include "Game/IW3/IW3.h" #include "Image/DdsLoader.h" #include "Pool/GlobalAssetPool.h" #include "Image/IwiTypes.h" using namespace IW3; void* AssetLoaderGfxImage::CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) { auto* image = memory->Create(); memset(image, 0, sizeof(GfxImage)); image->name = memory->Dup(assetName.c_str()); return image; } bool AssetLoaderGfxImage::CanLoadFromRaw() const { return true; } bool AssetLoaderGfxImage::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { // Do not load any GfxImages from raw for now that are not loaded // TODO: Load iwis and add streaming info to asset if (assetName.empty() || assetName[0] != '*') return false; std::string safeAssetName = assetName; for (auto& c : safeAssetName) { switch (c) { case '*': c = '_'; break; default: break; } } const auto file = searchPath->Open("images/" + safeAssetName + ".dds"); if (!file.IsOpen()) return false; const DdsLoader ddsLoader(zone->GetMemory()); auto* texture = ddsLoader.LoadDds(*file.m_stream); if (texture == nullptr) { std::cout << "Failed to load dds file for image asset \"" << assetName << "\"" << std::endl; return false; } auto* image = memory->Create(); image->name = memory->Dup(assetName.c_str()); image->picmip.platform[0] = 0; image->picmip.platform[1] = 0; image->noPicmip = !texture->HasMipMaps(); image->semantic = TS_FUNCTION; image->track = 0; image->cardMemory.platform[0] = 0; image->cardMemory.platform[1] = 0; image->width = static_cast(texture->GetWidth()); image->height = static_cast(texture->GetHeight()); image->depth = static_cast(texture->GetDepth()); image->category = IMG_CATEGORY_AUTO_GENERATED; image->delayLoadPixels = false; switch (texture->GetTextureType()) { case TextureType::T_2D: image->mapType = MAPTYPE_2D; break; case TextureType::T_3D: image->mapType = MAPTYPE_3D; break; case TextureType::T_CUBE: image->mapType = MAPTYPE_CUBE; break; default: image->mapType = MAPTYPE_NONE; break; } const auto mipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1; const auto faceCount = texture->GetFaceCount(); size_t dataSize = 0; for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) dataSize += texture->GetSizeOfMipLevel(mipLevel) * faceCount; auto* loadDef = static_cast(zone->GetMemory()->Alloc(offsetof(GfxImageLoadDef, data) + dataSize)); image->texture.loadDef = loadDef; loadDef->levelCount = static_cast(mipCount); loadDef->flags = 0; if (!texture->HasMipMaps()) loadDef->flags |= iwi6::IMG_FLAG_NOMIPMAPS; if (texture->GetTextureType() == TextureType::T_CUBE) loadDef->flags |= iwi6::IMG_FLAG_CUBEMAP; if (texture->GetTextureType() == TextureType::T_3D) loadDef->flags |= iwi6::IMG_FLAG_VOLMAP; loadDef->dimensions[0] = image->width; loadDef->dimensions[1] = image->height; loadDef->dimensions[2] = image->depth; loadDef->format = static_cast(texture->GetFormat()->GetD3DFormat()); loadDef->resourceSize = dataSize; char* currentDataBuffer = loadDef->data; for (auto mipLevel = 0; mipLevel < mipCount; mipLevel++) { const auto mipSize = texture->GetSizeOfMipLevel(mipLevel); for (auto face = 0; face < faceCount; face++) { memcpy(currentDataBuffer, texture->GetBufferForMipLevel(mipLevel, face), mipSize); currentDataBuffer += mipSize; } } manager->AddAsset(ASSET_TYPE_IMAGE, assetName, image); return true; }