j00hi
j00hi

Reputation: 5931

How to use OpenGL ES extensions on Android

I am developing a OpenGL ES 3.0 application on Android, mainly in Java and I need to use floating point render textures.

GLES30.glGetString(GLES30.GL_EXTENSIONS)

returns a string containing GL_EXT_color_buffer_half_float, and GL_EXT_color_buffer_float among others => my device supports floating point textures, obviously.

However, I am a bit lost right now how to use those extensions. Calling

GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA16F, 512, 512, 0, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, null);

results in an glError 1282. Everything works when I use GL_RGBA instead of GL_RGBA16F. I wanted to try GL_RGBA16F_EXT, but that's not contained in GLES30. So, I tried to pass the value 0x881A which is how GL_RGBA16F_EXT is defined, I think. But, same error: glError 1282.

There is that function eglGetProcAddress which is sometimes needed to use OpenGL ES extensions, but since I don't need the address of a function, I suspect that won't help me either. I don't really know what to try next. How can i create floating point FBOs?

Upvotes: 2

Views: 1439

Answers (1)

Reto Koradi
Reto Koradi

Reputation: 54592

GL_UNSIGNED_BYTE is not a valid value for the type argument of glTexImage2D() in combination with the GL_RGBA16F value for the internalFormat argument.

Based on table 3.2 in the spec, the only valid type values for GL_RGBA16F are GL_HALF_FLOAT and GL_FLOAT. This call should work:

GLES30.glTexImage2D(GLES30.GL_TEXTURE_2D, 0, GLES30.GL_RGBA16F, 512, 512, 0,
                    GLES30.GL_RGBA, GLES30.GL_HALF_FLOAT, null);

Unlike full OpenGL, OpenGL ES has a fairly limited set of valid format/type/internalFormat combinations for glTexImage2D(). It does not support automatic conversion of data types as part of this call beyond the value combinations listed in table 3.2 of the spec.

These type and internalFormat values still have to form a valid combination, even if no data is specified in the call. Mainly because... it's defined that way. In my personal opinion, this whole glTexImage2D() was never a good API design, and it partly also suffers from they way it evolved over time. The newer glTexStorage2D() is much cleaner.

For example, in this specific case, the internalFormat does indeed completely specify the storage format of the texture, because GL_RGBA16F is a sized format. So the type seems redundant. But the older unsized formats are still supported as well for backwards compatibility. Say if you specify GL_RGB for internalFormat, the texture will use a GL_RGB8 internal format if you combine that with GL_UNSIGNED_BYTE for the type, but it will be a GL_RGB565 if the type is GL_UNSIGNED_SHORT_5_6_5.

Upvotes: 1

Related Questions