Search code examples
opengl-es-3.0pbo

why glReadPixel GL_RGB from PBO got error 0x502 INVALD OPTION


I saw

format specifies the format of the returned pixel values; accepted values are:

GL_ALPHA GL_RGB GL_RGBA RGBA color components are read from the color buffer. Each color component is converted to floating point such that zero intensity maps to 0.0 and full intensity maps to 1.0.

Unneeded data is then discarded. For example, GL_ALPHA discards the red, green, and blue components, while GL_RGB discards only the alpha component. GL_LUMINANCE computes a single-component value as the sum of the red, green, and blue components, and GL_LUMINANCE_ALPHA does the same, while keeping alpha as a second value. The final values are clamped to the range [0, 1]."

at https://www.khronos.org/opengles/sdk/1.1/docs/man/glReadPixels.xml

It's work well if use GL_RGBA. But if I change

glReadPixelsPBOJNI(0, 0, width, height, GLES30.GL_RGBA, GLES30.GL_UNSIGNED_BYTE, 0);

to

glReadPixelsPBOJNI(0, 0, width, height, GLES30.GL_RGB, GLES30.GL_UNSIGNED_BYTE, 0);

0x502 is got. What's wrong with this?

My code is here: https://stackoverflow.com/questions/34347835/how-can-i-implement-pbopixel-buffer-object-in-android-grafika-project


Solution

  • GL_RGB is not generally supported as a format for glReadPixels() in OpenGL ES. From the ES 3.0 spec:

    Only two combinations of format and type are accepted in most cases. The first varies depending on the format of the currently bound rendering surface. For normalized fixed-point rendering surfaces, the combination format RGBA and type UNSIGNED_BYTE is accepted. [..]

    The second is an implementation-chosen format from among those defined in table 3.2, excluding formats DEPTH_COMPONENT and DEPTH_STENCIL. The values of format and type for this format may be determined by calling GetIntegerv with the symbolic constants IMPLEMENTATION_COLOR_READ_FORMAT and IMPLEMENTATION_COLOR_READ_TYPE, respectively.

    So unless you query the implementation-chosen format, and it comes back as GL_RGB, you cannot use GL_RGB. The only format you can use everywhere is GL_RGBA.

    The quote from the man page you found looks like a simple mistake. If you look at the top where the arguments are listed, it does not list GL_RGB as valid under format. So the information on that page is clearly inconsistent. Errors in the man pages are common. In case of doubt, you have to check the spec documents for more conclusive information.