Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use GL_HALF_FLOAT_OES typed textures in iOS?

I'm trying to create a float texture to store intermediate results of my rendering pipeline created by a fragment shader. I need the values of the fragments to be signed floats.

I understand that there is the OES_texture_float extension which should be supported by all new iOS devices (i.e. beginning from iPhone 3GS/iPod Touch 3/iPad according to the Apple guide).

However, when I create such a texture using

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

start my app and inspect it in Instruments, it tells me:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_HALF_FLOAT_OES, NULL) : (invalid enum=0x8d61): Invalid enum for argument 'type'

The curious thing is that it's nevertheless working on my iPhone 4S, but not on a iPhone 4 (which should be supported as well). The error message appears for both devices, though. But on the iPhone 4 OpenGL can't build a valid framebuffer object using this texture as a rendering target. On the 4S that works perfectly well.

Do you have any suggestions what I'm doing wrong?

Thanks!

like image 340
Frank Schlegel Avatar asked Dec 23 '11 22:12

Frank Schlegel


2 Answers

After a year I faced the problem again. I did some research and finally found the solution:

On almost all iOS devices it is possible to create and use float and half-float-typed textures. In fact all devices that support the OES_texture_float extension (or OES_texture_half_float, respectively) allow the creation of float-typed textures.

However, if you are trying to render into a float-typed texture using a Framebuffer Object, the device needs to support the EXT_color_buffer_half_float extension as well. As the name suggests this extension allows to bind half-float-typed textures to the render target of an FBO.

Now it turns out that this extension is only supported on devices that have a PowerVR SGX 543 or 554 graphics card, which are basically all devices released after (and including) the iPhone 4S. You can refere to Apple's OpenGL ES Hardware Platform Guide for iOS for a list of devices and their capabilities.

Summary:

If you want to render to a float-typed texture, you need to check if your device supports the EXT_color_buffer_half_float extension and you need to create your texture with

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

If your device does not support half-float color buffers, you can only bind unsigned-byte-typed textures to your FBO:

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

(Note that the format and internal format of the texture (GL_RGBA in this case) depends on the attachment point of the FBO.)

like image 59
Frank Schlegel Avatar answered Sep 28 '22 02:09

Frank Schlegel


I'm afraid you are doing nothing wrong, GL_HALF_FLOAT_OES is only supported on the iPhone4S and iPad2, despite there being no documentation to this effect. Float textures are a massive performance killer, even a basic variance shadow mapping implementation is completely unusable on an iPhone4S.

like image 42
Tark Avatar answered Sep 28 '22 03:09

Tark