Files
fparkan/docs/specs/texture.md
Valentin Popov 0e19660eb5 Refactor documentation structure and add new specifications
- Updated MSH documentation to reflect changes in material, wear, and texture specifications.
- Introduced new `render.md` file detailing the render pipeline process.
- Removed outdated sections from `runtime-pipeline.md` and redirected to `render.md`.
- Added detailed specifications for `Texm` texture format and `WEAR` wear table.
- Updated navigation in `mkdocs.yml` to align with new documentation structure.
2026-02-19 04:46:23 +04:00

126 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Texture (`Texm`)
`Texm` — основной формат текстур движка.
Связанные страницы:
- [Material (`MAT0`)](material.md)
- [Wear table (`WEAR`)](wear.md)
- [Render pipeline](render.md)
## 1. Контейнер
- Тип ресурса: `0x6D786554` (`Texm`).
- Используется в `Textures.lib`, `LightMap.lib` и других `NRes` архивах.
## 2. Заголовок
```c
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)
- `565`
- `4444`
- `888`
- `8888`
Дополнительные ветки загрузки поддерживают также `556` и `88`.
## 4. Layout payload
1. `TexmHeader32` (32 байта)
2. palette `1024` байта, если `format == 0`
3. mip-chain пикселей
4. optional `Page` chunk
Расчёт ядра:
```c
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;
```
## 5. `Page` chunk
```c
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
1. Не нормализовать `flags4/flags5/unk6`.
2. Сохранять payload без лишних хвостовых байт.
3. Если есть `Page`, его размер должен быть ровно `8 + rectCount * 8`.
4. Проверять `width > 0`, `height > 0`, `mipCount > 0`.
## 10. Статус валидации
- Инварианты `Texm` реализованы в `tools/msh_doc_validator.py`.
- В текущем окружении нет полного игрового набора текстур в `testdata`, поэтому массовая перепроверка не запускалась.