Дошёл я до формата mmp, исследовал его и хочу поделиться опытом.
К сожалению, от автора MMP Studio я ответа не получил, поэтому пришлось реверсить самому.
Сомневаюсь, что кому-нибудь это понадобиться , но вот мне понадобилось (для текстурирования). Вдруг?
Итак, формат почти полностью раскрыт.
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.
Как выложу кодец на хостинг, сообщу отдельным сообщением.
К сожалению, от автора MMP Studio я ответа не получил, поэтому пришлось реверсить самому.
Сомневаюсь, что кому-нибудь это понадобиться , но вот мне понадобилось (для текстурирования). Вдруг?
Итак, формат почти полностью раскрыт.
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
Use Linux - open your mind