Как использовать типизированные текстуры GL_HALF_FLOAT_OES в iOS?

Я пытаюсь создать текстуру float для хранения промежуточных результатов моего конвейера рендеринга, созданного шейдером фрагментов. Мне нужны значения фрагментов, которые должны быть подписаны.

Я понимаю, что существует расширение OES_texture_float, которое должно поддерживаться всеми новыми устройствами iOS (т.е. начиная с iPhone 3GS/iPod Touch 3/iPad в соответствии с Apple guide).

Однако, когда я создаю такую ​​текстуру, используя

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_HALF_FLOAT_OES, NULL);

запустите мое приложение и осмотрите его в "Инструменты", он говорит мне:

glTexImage2D (GL_TEXTURE_2D, 0, GL_RGB, ширина, высота, 0, GL_RGB, GL_HALF_FLOAT_OES, NULL): (invalid enum = 0x8d61): Недопустимое перечисление для аргумента 'type'

Любопытно, что он все же работает на моем iPhone 4S, но не на iPhone 4 (который также должен поддерживаться). Однако сообщение об ошибке появляется для обоих устройств. Но на iPhone 4 OpenGL не может создать действительный объект framebuffer, используя эту текстуру как цель рендеринга. На 4S работает отлично.

Есть ли у вас предложения, что я делаю неправильно?

Спасибо!

Ответ 1

Через год я снова столкнулся с проблемой. Я провел некоторое исследование и, наконец, нашел решение:

На почти всех устройствах iOS можно создавать и использовать текстуры с плавающей точкой и полу-флоат-типом. Фактически все устройства, поддерживающие расширение OES_texture_float (или OES_texture_half_float, соответственно), позволяют создавать текстуры с плавающей запятой.

Однако, если вы пытаетесь отобразить текстуру с плавающей запятой, используя объект Framebuffer, устройству также необходимо поддерживать расширение EXT_color_buffer_half_float. Как видно из названия, это расширение позволяет связывать текстуры с полуполяцией с объектом рендеринга FBO.

Теперь выясняется, что это расширение поддерживается только на устройствах с графической картой PowerVR SGX 543 или 554, которые в основном являются устройствами, выпущенными после (и включая) iPhone 4S. Вы можете ссылаться на Apple OpenGL ES Hardware Platform Guide для iOS для списка устройств и их возможностей.

Резюме:

Если вы хотите отобразить текстуру с поплавком, вам нужно проверить, поддерживает ли ваше устройство расширение EXT_color_buffer_half_float, и вам нужно создать свою текстуру с помощью

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_HALF_FLOAT_OES, NULL);

Если ваше устройство не поддерживает буферы с половинным поплавком, вы можете привязывать только текстуры без знака к вашему FBO:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);

(Обратите внимание, что формат и внутренний формат текстуры (GL_RGBA в этом случае) зависит от точки привязки FBO.)

Ответ 2

Я боюсь, что вы ничего не делаете, GL_HALF_FLOAT_OES поддерживается только на iPhone4S и iPad2, несмотря на отсутствие документации по этому вопросу. Плавающие текстуры являются мощным убийцей производительности, даже базовая реализация привязки к теневому отображению полностью непригодна для использования на iPhone4S.