Показать сообщение отдельно
Старый 22.01.2015, 18:44   #4
Кирпи4
Социал-сычевист
 
Аватар для Кирпи4
 
Регистрация: 24.06.2011
Сообщений: 611
Написано 342 полезных сообщений
(для 1,359 пользователей)
Ответ: OpenVice, или садо-мазо реверс-инженеринг

Texture Dictionary

Текстуры в вайсе упакованы в формате движка игры - RenderWare. Формат сам по себе чанковый, и на первый взгляд немного неудобный.

Базовая структура каждого чанка:
int section - тип чанка
int size - размер чанка, включая все дочерние
int version - версия RenderWare
Корневой чанк файла - 0x0016. Первым в нём идёт чанк содержит в себе следующие данные:
chunk struct - чанк, содержащий базовую информацию об архиве текстур.
chunk[texCount] textures - чанки каждой текстуры. Описаны ниже.
chunk extension - пустой чанк, можно смело обрывать чтение файла на предыдущем пункте.
Struct-чанк, описанный выше, имеет ID 0x0001, внутри два инта:
int texCount - количество текстур.
int device - колдунственное число, обозначает DX8 или DX9, зачем - загадка.
Подчанки текстур имею заголовок 0x0015, являются контейнером для одной текстуры.
chunk struct - собственно одна текстура. Имеет самую толстую спеку из всех чанков.
chunk extension - опять же пустой чанк. В PS2-версии формата содержит какие-то данные, но в PC остаётся пустым.
Текстурный struct-чанк, так же имеет ID 0x0001, держит в себе данные и параметры текстуры:
int platform - для вайса должно быть равно 8, иначе алярм.
int addressing - оче хитро сжатая информация об сглаживании и адресации текстур. Как разжать описано ниже.
chr[32] name - имя текстуры. Null-terminated, неиспользованные байты заполнены "\0".
chr[32] mask - название маски текстуры. Я не использую, назначение сомнительное. Хранится так же, как и имя.
int raster - формат растра. Список ниже.
int alpha - аж целый инт для простого флажка, есть ли альфа или нет...
short width - ширина.
short height - высота.
byte depth - глубина цвета в битах.
byte mipcount - количество mip-уровней текстуры.
byte type - всегда равно 4.
byte compression - какое сжатие текстур использовано. 0 - никакого, 1 - DXT1, 3 - DXT3.
Дальше, если raster содержит битовый флаг 0x2000, дальше следует палитра:
int[256] palette - цвета палитры для каждого индекса в формате RGBA.
Следом, для каждого из mip-уровней повторяется следующее:
int size - размер в байтах. В зависимости от формата и фазы луны, может равняться нулю. Это необходимо проверять и пересчитывать вручную размер.
byte[size] data - данные картинки.
Как раскодировать сглаживание и адресацию.
Хранится всё в одном инте, но используются по сути два первых байта. Первый байт - это режим фильтрации, список режимов прилагается. Следующий байт надо разбить на два блока по 4 бита, первый блок - адресация по U, второй - по V. Типы адресации тоже прилагаются.

Типы растра:
FORMAT_DEFAULT         0x0000
FORMAT_1555            0x0100 (однобитная альфа, RGB 5 бит на канал; этот же формат используется для DXT1 с альфой)
FORMAT_565             0x0200 (5 бит красного, 6 бит зелёного, 5 бит синего; используется DXT1 без альфы)
FORMAT_4444            0x0300 (RGBA 4 бита на канал; также используется для DXT3)
FORMAT_LUM8            0x0400 (gray scale)
FORMAT_8888            0x0500 (RGBA 8 бит на канал)
FORMAT_888             0x0600 (RGB 8 бит на канал без альфы)
FORMAT_555             0x0A00 (RGB 5 бит на канал - очень редкий формат)

FORMAT_EXT_AUTO_MIPMAP 0x1000 (движок должен сгенерировать мипмапы)
FORMAT_EXT_PAL8        0x2000 (2^8 = 256 цветов в палитре)
FORMAT_EXT_PAL4        0x4000 (2^4 = 16 цветов в палитре)
FORMAT_EXT_MIPMAP      0x8000 (мипмапы прилагаются)
Типы фильтрации:
FILTER_NONE                0x00
FILTER_NEAREST             0x01
FILTER_LINEAR              0x02
FILTER_MIP_NEAREST         0x03
FILTER_MIP_LINEAR          0x04
FILTER_LINEAR_MIP_NEAREST  0x05
FILTER_LINEAR_MIP_LINEAR   0x06
Типы адресации текстурных координат:
WRAP_NONE     0x00
WRAP_WRAP     0x01
WRAP_MIRROR   0x02
WRAP_CLAMP    0x03
Как говорится, первый блин комом, поэтому первые попытки прочитать текстуры были, мягко говоря, неудачными:

Однако, спустя некоторое время я понял, что неправильно читал размер для каждого мип-уровня. Вместо int я читал short, два байта терялись и ломали остальные данные. После поправки, всё встало на свои места:
__________________


(Offline)
 
Ответить с цитированием
Эти 4 пользователя(ей) сказали Спасибо Кирпи4 за это полезное сообщение:
Arton (22.01.2015), Gector (22.01.2015), Igor (23.01.2015), St_AnGer (23.01.2015)