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!
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.
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.)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With