четверг, 3 ноября 2011 г.

9 байт которые едва не свели меня с ума

Подня убил на решение простейшей задачки - вывести в OpenGL фоновую картинку. Картинка выводилась, но имела странные цвета.

 

Надо сказать что за долгую жизнь OpenGL давно пора было сделать к нему дополнительную либу для работы с популярными графическими форматами и сделать ее стандартом, однако ж типичная ситуация в этой отрасли: те кто может - не хотят, те кто хочет - не могут. Иными словами решений масса, но единого нет. И масса усилий начинающих разбираться с OpenGL тратится на изобретение многочисленных велосипедов или попытки прикрутить чей-то велосипед к своему проекту.

 

В конце концов, перепробовав все и вся я взялся за GIMP и нарисовал простую картинку с тремя базовыми цветами - черный, белый, красный, синий и зеленый, чтобы точно понять - что же происходит с этими цветами. Результат меня шокировал - черный остался черным, а вот белый - тоже стал черным! остальные превратились в непонятно что. То есть ни инверсия цвета, ни перестановка компонент (RGB или BGR) не могут привести к такому эффекту. При этом все элементы картинки остаются на своих местах, т.е. вариант что я подсовываю 32битное представление цвета вместо 24битного и т.п. тоже отпадает.

 

Тогда я попробовал сам сформировать массив пикселей и обнаружил что максимальные значения цветовых компонент - 127,127,127 - старший бит игнорируется. Преобразовав значения исходной картинки из диапазона 0-255 в 0-127 я впервый раз за день получил нормальные цвета и задумался. С одной стороны задача решилась, но как-тот убого, что-то тут не так.... И тут наконец забрезжил свет в конце тоннеля.

Найдите отличие:

gl.glDrawPixels(imgWidth, imgHeight, 
GL2.GL_RGBA, GL2.GL_UNSIGNED_BYTE,imgRGBA);

gl.glDrawPixels(imgWidth, imgHeight,
GL2.GL_RGBA, GL2.GL_BYTE,imgRGBA);

Черт меня дери...  Непонятно, кому и зачем это вообще может понадобится - представлять цвет 7ми битными компонентами, однако OpenGL любезно предоставляет такую возможность. Я ожидал что GL2.GL_RGBA задает цветовую модель, а единственное назначение следующей константы задавать размер элементов массива. Для данной модели  это либо 1 байт - каждый элемент представляет отдельный цвет , либо 4 байта (int) - каждый элемент представляет цвет целиком, включая прозрачность. То что учитывается знак - полный сюрприз.

 

Разница - 9 байт. Ровно столько занимает добавка "_UNSIGNED". Потрачено полдня, перерыта масса документации и примеров. Как выяснилось - рыл совсем не там и не то.

Комментариев нет:

Отправить комментарий