- Introduced `LoadedModel` and `LoadedTexture` structs for better encapsulation of model and texture data. - Added functions to load models and textures from archives, including support for resolving textures based on materials and wear entries. - Implemented error handling for missing textures, materials, and wear entries. - Updated the rendering pipeline to support texture loading and binding, including command-line arguments for texture customization. - Enhanced the `texm` crate with new decoding capabilities for various pixel formats, including indexed textures. - Added tests for texture decoding and loading to ensure reliability and correctness. - Updated documentation to reflect changes in the material and texture resolution process.
4.3 KiB
4.3 KiB
Texture (Texm)
Texm — основной формат текстур движка.
Связанные страницы:
1. Контейнер
- Тип ресурса:
0x6D786554(Texm). - Используется в
Textures.lib,LightMap.libи другихNResархивах.
2. Заголовок
struct TexmHeader32 {
uint32_t magic; // 'Texm'
uint32_t width;
uint32_t height;
uint32_t mipCount;
uint32_t flags4;
uint32_t flags5;
uint32_t unk6;
uint32_t format;
};
3. Поддерживаемые форматы
Базовые форматы:
0(8-bit indexed + palette)56544448888888
Дополнительные ветки загрузки поддерживают также 556 и 88.
4. Layout payload
TexmHeader32(32 байта)- palette
1024байта, еслиformat == 0 - mip-chain пикселей
- optional
Pagechunk
Расчёт ядра:
bytesPerPixel =
(format == 0) ? 1 :
(format == 565 || format == 556 || format == 4444 || format == 88) ? 2 :
4;
pixelCount = sum(max(1, width>>i) * max(1, height>>i), i=0..mipCount-1);
sizeCore = 32 + (format==0 ? 1024 : 0) + bytesPerPixel * pixelCount;
4.1. Декодирование в RGBA8 (runtime/инструменты)
Для CPU-пути (preview, валидация, оффлайн-конвертация) используется декодирование:
0(Indexed8):index -> palette[index](RGBAиз палитры 256×4).565:R5 G6 B5,A=255.556:R5 G5 B6,A=255.4444:A4 R4 G4 B4(с расширением 4-битных каналов в 8-битные).88:L8 A8(R=G=B=L).888:R8 G8 B8+ padding/служебный байт,A=255.8888:A8 R8 G8 B8.
Это декодирование соответствует текущему test/demo pipeline проекта.
5. Page chunk
struct PageChunk {
uint32_t magic; // 'Page'
uint32_t rectCount;
Rect16 rects[rectCount];
};
struct Rect16 {
int16_t x;
int16_t w;
int16_t y;
int16_t h;
};
Page задаёт atlas-прямоугольники для выборки под-областей текстуры.
6. Mip-skip политика
Загрузчик может пропускать первые mip-уровни в зависимости от:
flags5,- размеров текстуры,
- количества mip.
После mipSkip:
- уменьшаются
width/height/mipCount; - сдвигается начало пиксельных данных;
Page-координаты пересчитываются в соответствии с новым базовым уровнем.
7. Палитры
Для части текстур движок связывает палитру по суффиксу имени.
Практический формат:
- буква
A..Z+ вариант""или0..9 - всего
26 * 11 = 286возможных слотов палитр.
Невалидные суффиксы нужно считать ошибкой входных данных в инструментах.
8. Кэширование
Движок ведёт отдельные кэши:
- общий texture cache;
- lightmap cache.
Для обычных текстур используется отложенный сбор неиспользуемых слотов (по времени нулевого refcount).
9. Правила writer/editor
- Не нормализовать
flags4/flags5/unk6. - Сохранять payload без лишних хвостовых байт.
- Если есть
Page, его размер должен быть ровно8 + rectCount * 8. - Проверять
width > 0,height > 0,mipCount > 0.
10. Статус валидации
- Инварианты
Texmреализованы вtools/msh_doc_validator.py. - В текущем окружении нет полного игрового набора текстур в
testdata, поэтому массовая перепроверка не запускалась.