ObjWriting: Add dumper for GfxImage iwi files of version 27

This commit is contained in:
Jan 2020-02-11 23:47:04 +01:00
parent 6b59fcb5fe
commit f3779bac03
6 changed files with 214 additions and 1 deletions

View File

@ -0,0 +1,20 @@
#include "AssetDumperGfxImage.h"
#include "Image/IwiWriter27.h"
using namespace T6;
bool AssetDumperGfxImage::ShouldDump(GfxImage* asset)
{
return asset->loadedSize > 0;
}
std::string AssetDumperGfxImage::GetFileNameForAsset(Zone* zone, GfxImage* asset)
{
return "images/" + std::string(asset->name) + ".iwi";
}
void AssetDumperGfxImage::DumpAsset(Zone* zone, GfxImage* asset, FileAPI::File* out)
{
IwiWriter27 writer;
writer.DumpImage(out, asset->texture.texture);
}

View File

@ -0,0 +1,12 @@
#pragma once
#include "Dumping/AbstractAssetDumper.h"
#include "Game/T6/T6.h"
class AssetDumperGfxImage final : public AbstractAssetDumper<T6::GfxImage>
{
protected:
bool ShouldDump(T6::GfxImage* asset) override;
std::string GetFileNameForAsset(Zone* zone, T6::GfxImage* asset) override;
void DumpAsset(Zone* zone, T6::GfxImage* asset, FileAPI::File* out) override;
};

View File

@ -8,6 +8,7 @@
#include "AssetDumpers/AssetDumperScriptParseTree.h" #include "AssetDumpers/AssetDumperScriptParseTree.h"
#include "AssetDumpers/AssetDumperStringTable.h" #include "AssetDumpers/AssetDumperStringTable.h"
#include "AssetDumpers/AssetDumperLocalizeEntry.h" #include "AssetDumpers/AssetDumperLocalizeEntry.h"
#include "AssetDumpers/AssetDumperGfxImage.h"
bool ZoneDumperT6::CanHandleZone(Zone* zone) bool ZoneDumperT6::CanHandleZone(Zone* zone)
{ {
@ -32,7 +33,7 @@ bool ZoneDumperT6::DumpZone(Zone* zone, const std::string& basePath)
// DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel); // DUMP_ASSET_POOL(AssetDumperXModel, m_xmodel);
// DUMP_ASSET_POOL(AssetDumperMaterial, m_material); // DUMP_ASSET_POOL(AssetDumperMaterial, m_material);
// DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set); // DUMP_ASSET_POOL(AssetDumperTechniqueSet, m_technique_set);
// DUMP_ASSET_POOL(AssetDumperGfxImage, m_image); DUMP_ASSET_POOL(AssetDumperGfxImage, m_image);
// DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank); // DUMP_ASSET_POOL(AssetDumperSndBank, m_sound_bank);
// DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch); // DUMP_ASSET_POOL(AssetDumperSndPatch, m_sound_patch);
// DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map); // DUMP_ASSET_POOL(AssetDumperClipMap, m_clip_map);

View File

@ -0,0 +1,15 @@
#pragma once
#include "Image/Texture.h"
#include "Utils/FileAPI.h"
#include <string>
class IImageWriter
{
public:
virtual ~IImageWriter() = default;
virtual bool SupportsImageFormat(const ImageFormat* imageFormat) = 0;
virtual std::string GetFileExtension() = 0;
virtual void DumpImage(FileAPI::IFile* file, Texture* texture) = 0;
};

View File

@ -0,0 +1,138 @@
#include "IwiWriter27.h"
#include <cassert>
IwiWriter27::IwiWriter27()
= default;
IwiWriter27::~IwiWriter27()
= default;
iwi27::IwiFormat IwiWriter27::GetIwiFormatForImageFormat(const ImageFormat* imageFormat)
{
switch (imageFormat->GetId())
{
case ImageFormatId::R8_G8_B8:
return iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGB;
case ImageFormatId::R8_G8_B8_A8:
return iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGBA;
case ImageFormatId::A8:
return iwi27::IwiFormat::IMG_FORMAT_BITMAP_ALPHA;
case ImageFormatId::R16_G16_B16_A16_FLOAT:
return iwi27::IwiFormat::IMG_FORMAT_A16B16G16R16F;
case ImageFormatId::BC1:
return iwi27::IwiFormat::IMG_FORMAT_DXT1;
case ImageFormatId::BC2:
return iwi27::IwiFormat::IMG_FORMAT_DXT3;
case ImageFormatId::BC3:
return iwi27::IwiFormat::IMG_FORMAT_DXT5;
case ImageFormatId::BC5:
return iwi27::IwiFormat::IMG_FORMAT_DXN;
default:
return iwi27::IwiFormat::IMG_FORMAT_INVALID;
}
}
bool IwiWriter27::SupportsImageFormat(const ImageFormat* imageFormat)
{
return GetIwiFormatForImageFormat(imageFormat) != iwi27::IwiFormat::IMG_FORMAT_INVALID;
}
std::string IwiWriter27::GetFileExtension()
{
return ".iwi";
}
void IwiWriter27::WriteVersion(FileAPI::IFile* file)
{
IwiVersion version{};
version.tag[0] = 'I';
version.tag[1] = 'W';
version.tag[2] = 'i';
version.version = 27;
file->Write(&version, sizeof IwiVersion, 1);
}
void IwiWriter27::FillHeader2D(iwi27::IwiHeader* header, Texture2D* texture)
{
header->dimensions[0] = texture->GetWidth();
header->dimensions[1] = texture->GetHeight();
header->dimensions[2] = 1;
}
void IwiWriter27::FillHeaderCube(iwi27::IwiHeader* header, TextureCube* texture)
{
header->dimensions[0] = texture->GetWidth();
header->dimensions[1] = texture->GetHeight();
header->dimensions[2] = 1;
header->flags |= iwi27::IwiFlags::IMG_FLAG_CUBEMAP;
}
void IwiWriter27::FillHeader3D(iwi27::IwiHeader* header, Texture3D* texture)
{
header->dimensions[0] = texture->GetWidth();
header->dimensions[1] = texture->GetHeight();
header->dimensions[2] = texture->GetDepth();
header->flags |= iwi27::IwiFlags::IMG_FLAG_VOLMAP;
}
void IwiWriter27::DumpImage(FileAPI::IFile* file, Texture* texture)
{
assert(file != nullptr);
assert(texture != nullptr);
WriteVersion(file);
iwi27::IwiHeader header{};
header.flags = 0;
header.gamma = 0.0f;
header.format = static_cast<int8_t>(GetIwiFormatForImageFormat(texture->GetFormat()));
if (!texture->HasMipMaps())
header.flags |= iwi27::IwiFlags::IMG_FLAG_NOMIPMAPS;
for (signed char& i : header.maxGlossForMip)
i = 0;
size_t currentFileSize = sizeof IwiVersion + sizeof iwi27::IwiHeader;
const int textureMipCount = texture->HasMipMaps() ? texture->GetMipMapCount() : 1;
for (int currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
{
const size_t mipLevelSize = texture->GetSizeOfMipLevel(currentMipLevel);
currentFileSize += mipLevelSize;
if(currentMipLevel < static_cast<int>(_countof(iwi27::IwiHeader::fileSizeForPicmip)))
header.fileSizeForPicmip[currentMipLevel] = currentFileSize;
}
if(auto* texture2D = dynamic_cast<Texture2D*>(texture))
{
FillHeader2D(&header, texture2D);
}
else if(auto* textureCube = dynamic_cast<TextureCube*>(texture))
{
FillHeaderCube(&header, textureCube);
}
else if(auto* texture3D = dynamic_cast<Texture3D*>(texture))
{
FillHeader3D(&header, texture3D);
}
file->Write(&header, sizeof iwi27::IwiHeader, 1);
for (int currentMipLevel = textureMipCount - 1; currentMipLevel >= 0; currentMipLevel--)
{
const size_t mipLevelSize = texture->GetSizeOfMipLevel(currentMipLevel);
file->Write(texture->GetBufferForMipLevel(currentMipLevel), 1, mipLevelSize);
}
}

View File

@ -0,0 +1,27 @@
#pragma once
#include "IImageWriter.h"
#include "Image/IwiTypes.h"
class IwiWriter27 final : public IImageWriter
{
static iwi27::IwiFormat GetIwiFormatForImageFormat(const ImageFormat* imageFormat);
static void WriteVersion(FileAPI::IFile* file);
static void FillHeader2D(iwi27::IwiHeader* header, Texture2D* texture);
static void FillHeaderCube(iwi27::IwiHeader* header, TextureCube* texture);
static void FillHeader3D(iwi27::IwiHeader* header, Texture3D* texture);
public:
IwiWriter27();
IwiWriter27(const IwiWriter27& other) = delete;
IwiWriter27(IwiWriter27&& other) noexcept = delete;
~IwiWriter27() override;
IwiWriter27& operator=(const IwiWriter27& other) = delete;
IwiWriter27& operator=(IwiWriter27&& other) noexcept = delete;
bool SupportsImageFormat(const ImageFormat* imageFormat) override;
std::string GetFileExtension() override;
void DumpImage(FileAPI::IFile* file, Texture* texture) override;
};