Основные форматы хранения графики в GC\Wii

Автор TTEMMA, 12 мая 2015, 23:49

« назад - далее »

TTEMMA

Так уж сложилось, что продержавшись на NES мало времени и не сделав ни одного публичного перевода я переехал на более молодые консоли. Почему то я выбрал именно GC и Wii, может из-за того, что там почти нет русских игр? Может и из-за этого. Но суть не в этом.
 
Основной формат хранения графики у GC и Wii одинаков, связано это с тем, что архитектура Wii - это просто улучшенная версия GC. Так что эти 2 консоли можно считать почти одинаковыми по файлам. Правда, в Wii добавили n-ое количество новых форматов, но их, пока, обсуждать не будем.
 
Перейдём к самой сути данной темы, способы хранения графики на Wii и GC во многих играх одинаковы, и чаще графика скрывается под TPL файлами. Но это не говорит о том, что так в каждой игре. Так же, на GC, как я знаю, в играх серии The Legend of Zelda используется BTI, а на Wii в BRRES файлах используется ещё одна разновидность файла с текстурами TEX0. Так же, в BRFNT файлах(шрифты Wii) используются тот же способ хранения графики, как и в выше описанных файлах.
 
Почитав о способах хранения графики, я и решил написать эту статью.
Сделаем маленькую табличку, в которой и будут описаны все наши форматы хранения графики.
 

 
Для начала, мы попытаемся разобрать все форматы хранения графики. А уже позже разберём 3 типа контейнеров:

  • TPL
  • BTI
  • TEX0
И немного о самой архитектуре GC и Wii:
Что GC, что Wii работают на процессоре от фирмы IBM - PowerPC. В данных консолях эти процессоры работают в Big-Endian. То бишь, если смотреть файлы в HEX редакторе, то указатели и другие значения не надо переворачивать, как это делается у Little-Endian.
К примеру, число 8307 в Big-Endian будет выглядеть как 0x2073, а у Little-Endian 0x7320. Думаю, разницу вы поняли.
 
Ссылки на посты с описанием форматов:
I4 - Оттенки серого
I8 - Оттенки серого
IA4 - Оттенки серого с прозрачностью

SPOT

Извиняюсь за наглость, когда ждать продолжение?

TTEMMA

Цитата: SPOT от 14 мая 2015, 12:37Извиняюсь за наглость, когда ждать продолжение?
Скоро будет, я хочу с каждым типом изображения поставлять исходный код программы, которая сможет открывать тот тип, про который будет рассказываться. Но у меня, пока что, не получается написать программу:(

SPOT

Цитата: TTEMMA от 14 мая 2015, 14:47Но у меня, пока что, не получается написать программу :(
И в чём именно трудность? Или попросту не хватает времени?

TTEMMA

Изображение поделено на блоки - это не проблема. Когда я его "декодирую", то надо создать цикл сначала от 0 до Высота, в этом цикле от 0 до Ширина, а в этом цикле пробежаться по блокам.
Проблема в том, что у меня программа вообще не пробегается по циклу Высота, по циклу с шириной пробежался и остановился.
Пишу на Delphi, использую циклы While, ибо в For к числу, которое задается началом, нельзя прибавлять числа. А мне надо в каждом цикле по высота и ширине прибавлять по 8.
Не знаю, что уже делать.

SPOT

Цитата: TTEMMA от 15 мая 2015, 10:18Изображение поделено на блоки - это не проблема. Когда я его "декодирую", то надо создать цикл сначала от 0 до Высота, в этом цикле от 0 до Ширина, а в этом цикле пробежаться по блокам.
Проблема в том, что у меня программа вообще не пробегается по циклу Высота, по циклу с шириной пробежался и остановился.
Возможно где-то ошибка в коде. Попробуй отдельно пройти "по циклу Высота".
 

Цитата: TTEMMA от 15 мая 2015, 10:18Пишу на Delphi, использую циклы While, ибо в For к числу, которое задается началом, нельзя прибавлять числа. А мне надо в каждом цикле по высота и ширине прибавлять по 8.
Не знаю, что уже делать.
Так с for () можно сделать всё что угодно.

for (int a = i; a<b; a++){} //стандарт
for (int a = i; a<b; ){
a+=8;
}

for (;;){
a+=8;
if (a>=b)break;
}
Способов куча.

TTEMMA

Это в C можно так, но не в delphi.
 
Я совершил самую глупейшую ошибку - не обнулял счётчик по ширине. Поэтому цикл по высоте и ширине проходил 1 раз, а дальше шёл цикл только по высоте, от которого смысла 0. Разобрался, скоро опишу I4.
'Изображение'

TTEMMA

I4 - Оттенки серого
Как можно понять по названия формата хранения графики, изображение у нас 4 битное. То есть, на 1 пиксель выделяется 4 бита, следственно 1 байт - 2 пикселя.
 
Для данного урока я подготовил изображение размером 256х256, оно будет прикреплено к данному посту.
Выглядит оно таким вот образом:
 
Так, начнём, как я уже говорил, один пиксель занимает 4 бита. 4 бита - это половина 1 байта.
Все изображения в GC\Wii делятся на блоки, в нашем случае каждый блок имеет размер 8*8. 
Так как у нас в одном байте аж 2 пикселя, то мы ширину блока(8) можем смело поделить на 2. Правда, если писать программу, то мы будем не делить данное значение, а в цикле к счётчику прибавлять 2:

//Наглядный пример на C++
for (int x1 = x;x1<Width+8;x+=2)
{
//здесь читаем 2 пикселя и бла бла бла
}
Давайте подробно разберём хранение пикселей. К примеру, возьмём байт 0xF3.
Для начала, надо разбить байт по 4 бита. Следовательно, значение первого пикселя = F(15), а значение второго пикселя = 3.
Но это не всё, полученные значения надо умножить на 17 и мы получим
1 пиксель : F*17 = 255
2 пиксель : 3*17 = 51
 
Дальше всё просто, значение RGB 1-го пикселя будет:
R = 255
G = 255
B = 255

 
Следовательно, 2-го пикселя:
R = 51
G = 51
B = 51
 
Впрочем, это всё. Надеюсь, всё было понятно.
 
P.S. Пока программ не будет, если сможем разобрать все форматы хранения, то напишу подобие библиотеки для работы с этими изображениями и тогда будем клепать просмотрищики BTI, TPL.
Так же, если было написано мало или что-то не понятно, пишите, попытаюсь разжевать ещё больше.

SPOT

Цитата: TTEMMA от 16 мая 2015, 21:41Но это не всё, полученные значения надо умножить на 17 и мы получим
Почему на 17?

TTEMMA

Цитата: SPOT от 18 мая 2015, 10:12 

Цитата: TTEMMA от 16 мая 2015, 21:41Но это не всё, полученные значения надо умножить на 17 и мы получим
Почему на 17?
 
Вообще, надо умножить на 255(общее кол-во цветов в 8 битной кодировке) и полученное число поделить на 15(максимальное кол-во цветов в 4 битной кодировке). Так мы сможем получить 1 байт(8 битный) отвечающий за все 3 цвета в оттенках серого.
Но вместо (Value*255)/15 можно использовать 17.

SPOT


TTEMMA

Цитата: SPOT от 29 мая 2015, 21:56TTEMMA, Стоит ждать продолжение?
Стоит, просто, пока что, времени нет.

Greengh0st

Давай пости нужные темы, как все будет готово, надо полностью собрать в один пост и перевезти все в "Как умеем".

TTEMMA

I8 - Оттенки серого
Различий у данного формата от I4 лишь в том, что на цвет выделяется 8 бит - 1 байт.
 
Я взял тоже изображения, что брали и у I4, выглядит оно так:
 
В данном типе изображения, 1 пиксель занимает 8 байт. Один блок имеет размер 8х4.
Примерно, если писать программу, то считываются пиксели в каждом блоке так:

//Наглядный пример на C++
for (int y1 = y;y1<y+4;y++)
{
for (int x1 = x;x1<x+8;x++)
{
//здесь читаем 1 пиксель и бла бла бла
}
}
Так как у нас на каждый пиксель используется один байт, то мы спокойной считываем один байт и задаём его как RGB.
К примеру, FF:
R = 255
G = 255
B = 255

Вот так прост данный формат хранения графики.

Alon

Цитата: TTEMMA от 03 июня 2015, 19:18К примеру, FF:
R = 255
G = 255
B = 255

Вот так прост данный формат хранения графики.
 
 
Можно на примере другого цвета объяснить как мы получили RGB?

TTEMMA

Цитата: Alon от 04 июня 2015, 11:04 

Цитата: TTEMMA от 03 июня 2015, 19:18К примеру, FF:
R = 255
G = 255
B = 255

Вот так прост данный формат хранения графики.
 
 
Можно на примере другого цвета объяснить как мы получили RGB?
 
Да, конечно. К примеру, байт 0х44, в десятичной это будет 68, следовательно
R = 68
G = 68
B = 68

TTEMMA

IA4 - Оттенки серого с прозрачностью
Как понятно по названию, данный тип хранения графики предоставляет из себя оттенки серого с прозрачностью.
Один цвет занимает 1 байт - 8 бит: 4 бита - прозрачность, 4 бита - цвет.
Размер блока имеет 8х4.
Для примера возьмём нашу старую картинку:

Выглядит, как-то, хреново, но да ладно.
 
Итак, в HEX редакторе изображение выглядит так:

 
Как мы помним, 1 пиксель = 1 байт.
Для примера, возьмём байт 0x57
Первые 4 бита выступают за байт прозрачности, то есть биты 0101 выступают за прозрачность. Но ещё не всё, надо это значение умножить на 255 и поделить на 15:
Alpha = 5 * 255 / 15 = 85 (0101 = 5 в десятичной)
Умножаем на общее кол-во цветов и делим на возможное кол-во цветов.
По тому же способу получаем и RGB, только берём теперь последние 4 байта - 0111. С этим значением надо сделать тоже самое, что и со значением Alpha:
RGB = 7 * 255 / 15 = 119 (0111 = 7 в десятичной)
 
Следовательно, в байте 0x57:
  Альфа канал равен 85
  Красный цвет равен 119
  Зелёный цвет равен 119
  И синий цвет равен 119
 

 
Вот, собственно, и всё. Как видите, очень простой формат.

zetper

Спасибо за статью,  будет ли пример файла "IA4 - Оттенки серого с прозрачностью" ?  ждать ли продолжение по форматам GC\Wii ?