Формат MMP
#1
Дошёл я до формата mmp, исследовал его и хочу поделиться опытом.

К сожалению, от автора MMP Studio я ответа не получил, поэтому пришлось реверсить самому.
Сомневаюсь, что кому-нибудь это понадобиться Smile, но вот мне понадобилось (для текстурирования). Вдруг?

Итак, формат почти полностью раскрыт.
MMP есть не что иное, как обёртка над DDS.

Заголовок (76 байт):
signature: uint32;
width: uint32;
height: uint32;
size (PNT3) or mipmap count (other): uint32;
format: uint32;
rgb_bit_count: uint32;
a_bit_mask: uint32;
unknown: uint32;
unknown: uint32;
r_bit_mask: uint32;
unknown: uint32;
unknown: uint32;
g_bit_mask: uint32;
unknown: uint32;
unknown: uint32;
b_bit_mask: uint32;
unknown: uint32;
unknown: uint32;
unknown: uint32;

Поля rgb_bit_count, a_bit_mask, r_bit_mask, g_bit_mask, b_bit_mask можно проигнорировать, т.к. подформат данных мы знаем по полю format.

Существует 7 подформатов MMP:
DD, DXT1, DXT3, PNT3, PV, QU, XX

Не по порядку:
* DD - несжатые данные в формате ARGB4.
* PV - несжатые данные в формате R5G6B5.
* QU - несжатые данные в формате ARG5B1.
* XX - несжатые данные в формате ARGB8.

* DXT1/3 - название говорит само за себя. Чтобы распаковать (если карточка не поддерживает), можно обратиться, например, к GIMP DDS Plugin. Там очень хорошая реализация. Есть также библиотечка SOIL, там тоже есть поддержка DXT. Ну и наконец в моём коде (когда выложу) можно посмотреть.

* PNT3 - сжатые или несжатые данные в формате ARGB8. Больше всего трудностей у меня возникло с PNT3, о нём особо. Размер несжатых данных определяется стандартно: width * height * 4. Если полученное число совпадает с полем size в заголовке, сразу отправляем данные в API. Иначе этот файл сжат. Алгоритм оказался следующим. В файлах PNT3 большие куски текстуры просто белые (0 в бинарном представлении). Как раз эти большие участки и сжаты. Файл гарантированно выровнен по границе uint32. Если его читать по 4 байта, то данные цвета гарантированно будут больше некоторого большого числа, например, 1000000.
В случае же меньшего значения (но большего нуля) - это количество нулей, которые нужно распаковать. После распаковки размеры сойдутся.

Теперь пару слов, как залить данные в OpenGL (в виде GLenum data_format, GLenum data_type).
* DD - напрямую GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV.
* PV - напрямую GL_RGB, GL_UNSIGNED_SHORT_5_6_5.
* QU - напрямую GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV.
* XX - напрямую GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV.
* PNT3 - напрямую GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV.
* DXT1/3 - если есть расширение GL_EXT_texture_compression_s3tc, то напрямую GL_COMPRESSED_RGB_S3TC_DXT1_EXT/GL_COMPRESSED_RGBA_S3TC_DXT3_EXT! Иначе придётся распаковать и что-нибудь типа GL_RGBA, GL_UNSIGNED_BYTE.

Как выложу кодец на хостинг, сообщу отдельным сообщением.
Windows - аналог плохо понятых механизмов Unix
Use Linux - open your mind
Ответ
#2
Спасибо за описание! :up: Оно непременно кому-нибудь пригодится :-[ Особенно если этот кто-то подучит GL как полагается...
Ответ
#3
Код:
// signature
#define MMP_SIGNATURE   ((DWORD)0x00504D4D)
// formats
#define MMP_FORMAT_5650    ((DWORD)0x5650)
#define MMP_FORMAT_5550    ((DWORD)0x5550)
#define MMP_FORMAT_5551    ((DWORD)0x5551)
#define MMP_FORMAT_4444    ((DWORD)0x4444)
#define MMP_FORMAT_8888    ((DWORD)0x8888)
#define MMP_FORMAT_DXT1    ((DWORD)0x31545844)
#define MMP_FORMAT_DXT2    ((DWORD)0x32545844)
#define MMP_FORMAT_DXT3    ((DWORD)0x33545844)
#define MMP_FORMAT_DXT4    ((DWORD)0x34545844)
#define MMP_FORMAT_DXT5    ((DWORD)0x35545844)
#define MMP_FORMAT_DXTN    ((DWORD)0x00545844)
#define MMP_FORMAT_PAINT   ((DWORD)0x00544E50)
#define MMP_FORMAT_PAINT32 ((DWORD)0x32544E50)
#define MMP_FORMAT_PNT3    ((DWORD)0x33544E50)
// bit depthes for appropriate formats
#define MMP_BIT_DEPTH_5650    ((DWORD)16)
#define MMP_BIT_DEPTH_5551    ((DWORD)16)
#define MMP_BIT_DEPTH_4444    ((DWORD)16)
#define MMP_BIT_DEPTH_8888    ((DWORD)32)
#define MMP_BIT_DEPTH_DXT1    ((DWORD)4)
#define MMP_BIT_DEPTH_DXT2    ((DWORD)8)
#define MMP_BIT_DEPTH_DXT3    ((DWORD)8)
#define MMP_BIT_DEPTH_DXT4    ((DWORD)8)
#define MMP_BIT_DEPTH_DXT5    ((DWORD)8)
#define MMP_BIT_DEPTH_PAINT   ((DWORD)24)
#define MMP_BIT_DEPTH_PAINT32 ((DWORD)32)
#define MMP_BIT_DEPTH_PNT3    ((DWORD)32)

struct SMMPFileHeader
{
public :
    // general header information
    DWORD dwSignature;          // see signature constant above
    DWORD dwDimentionX;          // x-dimention of the top-level mip object
    DWORD dwDimentionY;          // y-dimention of the top-level mip object
    union
    {
 DWORD dwMipMapLevel;        // number of mip-map levels
 DWORD dwLinearSize;            // linear size of compresed PNT3 format
    };
    // format info
    // general format info
    DWORD dwFormat;            // format type (see format constants above)
    DWORD dwBitDepth;              // bit depth (see bit depth constants above)
    // masks (for RGBA formats it can be applied to each pixel, for FOURCC formats if can be applied for color_0...color_1)
    // alpha mask info
    DWORD dwAMask;            // mask
    DWORD dwAShift;                       // shift
    DWORD dwABits;                        // bits
    // red mask info
    DWORD dwRMask;            // mask
    DWORD dwRShift;                       // shift
    DWORD dwRBits;                        // bits
    // green mask info
    DWORD dwGMask;            // mask
    DWORD dwGShift;                       // shift
    DWORD dwGBits;                        // bits
    // blue mask info
    DWORD dwBMask;            // mask
    DWORD dwBShift;                       // shift
    DWORD dwBBits;                        // bits
    //
    DWORD dwUserDataShift;        // number of bytes to shift from the header to get to mmp data
};

Добавил: Robin [mergetime]1261963327[/mergetime]
Сто раз уже это обмусоливали.
Ответ
#4
Robin,Monday, 28 December 2009, 04:22 Написал:Добавил: Robin [mergetime]1261963327[/mergetime]
Сто раз уже это обмусоливали.
[right][snapback]39849[/snapback][/right]

Ну уж извините, я не из сообщества гипат.ру. Открытой информации не нашёл (или плохо искал?). Из вашего описания видно, что действительно нужно минимальное количество полей для нормальной загрузки (если брать в расчёт оригинальные ресурсы).
Windows - аналог плохо понятых механизмов Unix
Use Linux - open your mind
Ответ
#5
Код готов. Если ещё кому-то понадобится mmp, то смотрите сюда. Поиск по *mmp* и *texture*.

Весь проект здесь.
Windows - аналог плохо понятых механизмов Unix
Use Linux - open your mind
Ответ
#6
Mosida,Tuesday, 02 February 2010, 09:49 Написал:Очень рад, что и в России есть авторы, кто выкладывает свои работы в сети. Жаль только, что выбранный формат не очень удобен. Я, к сожалению, не всегда имею возможность использовать продукцию Microsoft в частности Microsoft Equation мне не доступен, и для меня более привычен TeX. Планируете ли Вы перевести материалы во что-нибудь более универсальное, например, в формат PDF?
[right][snapback]39979[/snapback][/right]
Вообще таких планов нет. Мне нужно только загрузить mmp в память для игры и всё. Документация тоже не планируется. Однако, если что-то будет нужно, пишите, рассмотрим этот вопрос.
Windows - аналог плохо понятых механизмов Unix
Use Linux - open your mind
Ответ


Перейти к форуму:


Пользователи, просматривающие эту тему: 3 Гость(ей)