mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 16:15:43 +00:00
ObjLoading: Add implementation for loading iwis of version 27 (T6)
This commit is contained in:
parent
43fa845839
commit
76712328b2
@ -76,6 +76,11 @@ size_t ImageFormatBlockCompressed::GetSizeOfMipLevel(const unsigned mipLevel, co
|
||||
}
|
||||
|
||||
const ImageFormatUnsigned ImageFormat::FORMAT_R8G8B8(24, 0, 8, 8, 8, 16, 8, 0, 0, DXGI_FORMAT_UNKNOWN);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(4, 8, DXGI_FORMAT_BC1_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(4, 16, DXGI_FORMAT_BC2_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(4, 16, DXGI_FORMAT_BC3_UNORM);
|
||||
const ImageFormatUnsigned ImageFormat::FORMAT_R8G8B8A8(32, 0, 8, 8, 8, 16, 8, 24, 8, DXGI_FORMAT_R8G8B8A8_UNORM);
|
||||
const ImageFormatUnsigned ImageFormat::FORMAT_A8(8, 0, 0, 0, 0, 0, 0, 0, 8, DXGI_FORMAT_A8_UNORM);
|
||||
const ImageFormatUnsigned ImageFormat::FORMAT_R16G16B16A16_FLOAT(128, 0, 0, 0, 0, 0, 0, 0, 8, DXGI_FORMAT_R16G16B16A16_FLOAT);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC1(4, 64, DXGI_FORMAT_BC1_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC2(4, 128, DXGI_FORMAT_BC2_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC3(4, 128, DXGI_FORMAT_BC3_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC4(4, 64, DXGI_FORMAT_BC4_UNORM);
|
||||
const ImageFormatBlockCompressed ImageFormat::FORMAT_BC5(4, 128, DXGI_FORMAT_BC5_UNORM);
|
||||
|
@ -53,7 +53,12 @@ public:
|
||||
ImageFormat() = delete;
|
||||
|
||||
static const ImageFormatUnsigned FORMAT_R8G8B8;
|
||||
static const ImageFormatUnsigned FORMAT_R8G8B8A8;
|
||||
static const ImageFormatUnsigned FORMAT_A8;
|
||||
static const ImageFormatUnsigned FORMAT_R16G16B16A16_FLOAT; //TODO: Float not unsigned
|
||||
static const ImageFormatBlockCompressed FORMAT_BC1;
|
||||
static const ImageFormatBlockCompressed FORMAT_BC2;
|
||||
static const ImageFormatBlockCompressed FORMAT_BC3;
|
||||
static const ImageFormatBlockCompressed FORMAT_BC4;
|
||||
static const ImageFormatBlockCompressed FORMAT_BC5;
|
||||
};
|
||||
|
90
src/ObjCommon/Image/IwiTypes.h
Normal file
90
src/ObjCommon/Image/IwiTypes.h
Normal file
@ -0,0 +1,90 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
struct IwiVersion
|
||||
{
|
||||
char tag[3];
|
||||
char version;
|
||||
};
|
||||
|
||||
// IW4
|
||||
namespace iwi8
|
||||
{
|
||||
struct IwiHeader
|
||||
{
|
||||
uint32_t flags;
|
||||
int8_t format;
|
||||
int8_t unused;
|
||||
uint16_t dimensions[3];
|
||||
uint32_t fileSizeForPicmip[4];
|
||||
};
|
||||
}
|
||||
|
||||
// T5
|
||||
namespace iwi13
|
||||
{
|
||||
struct IwiHeader
|
||||
{
|
||||
int8_t format;
|
||||
int8_t flags;
|
||||
uint16_t dimensions[3];
|
||||
float gamma;
|
||||
uint32_t fileSizeForPicmip[8];
|
||||
};
|
||||
}
|
||||
|
||||
// T6
|
||||
namespace iwi27
|
||||
{
|
||||
struct IwiHeader
|
||||
{
|
||||
int8_t format;
|
||||
int8_t flags;
|
||||
uint16_t dimensions[3];
|
||||
float gamma;
|
||||
int8_t maxGlossForMip[16];
|
||||
uint32_t fileSizeForPicmip[8];
|
||||
};
|
||||
|
||||
enum class IwiFormat
|
||||
{
|
||||
IMG_FORMAT_INVALID = 0x0,
|
||||
IMG_FORMAT_BITMAP_RGBA = 0x1,
|
||||
IMG_FORMAT_BITMAP_RGB = 0x2,
|
||||
IMG_FORMAT_BITMAP_LUMINANCE_ALPHA = 0x3,
|
||||
IMG_FORMAT_BITMAP_LUMINANCE = 0x4,
|
||||
IMG_FORMAT_BITMAP_ALPHA = 0x5,
|
||||
IMG_FORMAT_WAVELET_RGBA = 0x6,
|
||||
IMG_FORMAT_WAVELET_RGB = 0x7,
|
||||
IMG_FORMAT_WAVELET_LUMINANCE_ALPHA = 0x8,
|
||||
IMG_FORMAT_WAVELET_LUMINANCE = 0x9,
|
||||
IMG_FORMAT_WAVELET_ALPHA = 0xA,
|
||||
IMG_FORMAT_DXT1 = 0xB,
|
||||
IMG_FORMAT_DXT3 = 0xC,
|
||||
IMG_FORMAT_DXT5 = 0xD,
|
||||
IMG_FORMAT_DXN = 0xE,
|
||||
IMG_FORMAT_BITMAP_RGB565 = 0xF,
|
||||
IMG_FORMAT_BITMAP_RGB5A3 = 0x10,
|
||||
IMG_FORMAT_BITMAP_C8 = 0x11,
|
||||
IMG_FORMAT_BITMAP_RGBA8 = 0x12,
|
||||
IMG_FORMAT_A16B16G16R16F = 0x13,
|
||||
IMG_FORMAT_COUNT,
|
||||
};
|
||||
|
||||
enum IwiFlags
|
||||
{
|
||||
IMG_FLAG_NOPICMIP = 1 << 0,
|
||||
IMG_FLAG_NOMIPMAPS = 1 << 1,
|
||||
IMG_FLAG_CUBEMAP = 1 << 2,
|
||||
IMG_FLAG_VOLMAP = 1 << 3,
|
||||
IMG_FLAG_STREAMING = 1 << 4,
|
||||
IMG_FLAG_CLAMP_U = 1 << 6,
|
||||
IMG_FLAG_CLAMP_V = 1 << 7,
|
||||
IMG_FLAG_FORCE_SYSTEM = 1 << 8,
|
||||
IMG_FLAG_DYNAMIC = 1 << 16,
|
||||
IMG_FLAG_RENDER_TARGET = 1 << 17,
|
||||
IMG_FLAG_MULTISAMPLE = 1 << 18,
|
||||
};
|
||||
|
||||
}
|
@ -1,24 +1,137 @@
|
||||
#include "IwiLoader.h"
|
||||
#include "Image/IwiTypes.h"
|
||||
#include <cassert>
|
||||
|
||||
IwiLoader::IwiLoader(MemoryManager* memoryManager)
|
||||
{
|
||||
m_memory_manager = memoryManager;
|
||||
}
|
||||
|
||||
Texture* IwiLoader::LoadIwi(FileAPI::IFile* file)
|
||||
const IImageFormat* IwiLoader::GetFormat27(int8_t format)
|
||||
{
|
||||
struct
|
||||
switch (static_cast<iwi27::IwiFormat>(format))
|
||||
{
|
||||
char tag[3];
|
||||
char version;
|
||||
} iwiHeaderMeta{};
|
||||
|
||||
if (file->Read(&iwiHeaderMeta, sizeof iwiHeaderMeta, 1) != 1)
|
||||
return nullptr;
|
||||
|
||||
printf("Read IWI with version %i\n", iwiHeaderMeta.version);
|
||||
|
||||
// TODO: Read iwi based on version
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGBA:
|
||||
return &ImageFormat::FORMAT_R8G8B8A8;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_ALPHA:
|
||||
return &ImageFormat::FORMAT_A8;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_DXT1:
|
||||
return &ImageFormat::FORMAT_BC1;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_DXT3:
|
||||
return &ImageFormat::FORMAT_BC2;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_DXT5:
|
||||
return &ImageFormat::FORMAT_BC3;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_DXN:
|
||||
return &ImageFormat::FORMAT_BC5;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_A16B16G16R16F:
|
||||
assert(false); // Unsupported yet
|
||||
return &ImageFormat::FORMAT_R16G16B16A16_FLOAT;
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGB:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE_ALPHA:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_LUMINANCE:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_WAVELET_RGBA:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_WAVELET_RGB:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE_ALPHA:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_WAVELET_LUMINANCE:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_WAVELET_ALPHA:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGB565:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGB5A3:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_C8:
|
||||
case iwi27::IwiFormat::IMG_FORMAT_BITMAP_RGBA8:
|
||||
printf("Unsupported IWI format: %i\n", format);
|
||||
break;
|
||||
default:
|
||||
printf("Unknown IWI format: %i\n", format);
|
||||
break;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Texture* IwiLoader::LoadIwi27(FileAPI::IFile* file)
|
||||
{
|
||||
iwi27::IwiHeader header{};
|
||||
|
||||
if (file->Read(&header, sizeof header, 1) != 1)
|
||||
return nullptr;
|
||||
|
||||
const IImageFormat* format = GetFormat27(header.format);
|
||||
if (format == nullptr)
|
||||
return nullptr;
|
||||
|
||||
uint16_t width = header.dimensions[0];
|
||||
uint16_t height = header.dimensions[1];
|
||||
uint16_t depth = header.dimensions[2];
|
||||
bool hasMipMaps = !(header.flags & iwi27::IwiFlags::IMG_FLAG_NOMIPMAPS);
|
||||
|
||||
Texture* texture;
|
||||
if(header.flags & iwi27::IwiFlags::IMG_FLAG_CUBEMAP)
|
||||
{
|
||||
texture = m_memory_manager->Create<TextureCube>(format, width, height, hasMipMaps);
|
||||
}
|
||||
else if(header.flags & iwi27::IwiFlags::IMG_FLAG_VOLMAP)
|
||||
{
|
||||
texture = m_memory_manager->Create<Texture3D>(format, width, height, depth, hasMipMaps);
|
||||
}
|
||||
else
|
||||
{
|
||||
texture = m_memory_manager->Create<Texture2D>(format, width, height, hasMipMaps);
|
||||
}
|
||||
|
||||
texture->Allocate();
|
||||
|
||||
size_t currentFileSize = sizeof iwi27::IwiHeader + sizeof IwiVersion;
|
||||
const int mipMapCount = hasMipMaps ? texture->GetMipMapCount() : 1;
|
||||
|
||||
for (int currentMipLevel = mipMapCount - 1; currentMipLevel >= 0; currentMipLevel--)
|
||||
{
|
||||
const size_t sizeOfMipLevel = texture->GetSizeOfMipLevel(currentMipLevel);
|
||||
currentFileSize += sizeOfMipLevel;
|
||||
|
||||
if (currentMipLevel < static_cast<int>(_countof(iwi27::IwiHeader::fileSizeForPicmip))
|
||||
&& currentFileSize != header.fileSizeForPicmip[currentMipLevel])
|
||||
{
|
||||
printf("Iwi has invalid file size for picmip %i\n", currentMipLevel);
|
||||
|
||||
m_memory_manager->Delete(texture);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (file->Read(texture->GetBufferForMipLevel(currentMipLevel), 1, sizeOfMipLevel) != sizeOfMipLevel)
|
||||
{
|
||||
printf("Unexpected eof of iwi in mip level %i\n", currentMipLevel);
|
||||
|
||||
m_memory_manager->Delete(texture);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
Texture* IwiLoader::LoadIwi(FileAPI::IFile* file)
|
||||
{
|
||||
IwiVersion iwiVersion{};
|
||||
|
||||
if (file->Read(&iwiVersion, sizeof iwiVersion, 1) != 1)
|
||||
return nullptr;
|
||||
|
||||
if (iwiVersion.tag[0] != 'I'
|
||||
|| iwiVersion.tag[1] != 'W'
|
||||
|| iwiVersion.tag[2] != 'i')
|
||||
{
|
||||
printf("Invalid IWI magic\n");
|
||||
}
|
||||
|
||||
switch (iwiVersion.version)
|
||||
{
|
||||
case 27:
|
||||
return LoadIwi27(file);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Unknown IWI version %i\n", iwiVersion.version);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ class IwiLoader
|
||||
{
|
||||
MemoryManager* m_memory_manager;
|
||||
|
||||
const IImageFormat* GetFormat27(int8_t format);
|
||||
Texture* LoadIwi27(FileAPI::IFile* file);
|
||||
|
||||
public:
|
||||
explicit IwiLoader(MemoryManager* memoryManager);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user