qtopengl-esqt-quickdepth-buffergoogle-angle

glReadPixels on DEPTH_COMPONENT throws GL_INVALID_OPERATION


I'm having a problem reading the depth buffer of a offscreen framebuffer rendering pass. When using OpenGL 4.5 it works as intended, but on OpenGL ES 2.0 (Angle) I get an error on my glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depthBuffer) call. The error is 0x502, which is a GL_INVALID_OPERATION error code.

Some more background. I'm working in a Qt environment, which has a main rendering routine and now I'm doing some offscreen rendering. Usually we use the opengl desktop implementation, but on some machine, we are experiencing some problems with bad opengl versions. Therefore I'm current working on making the whole setup more robust. One thing I did is to use angle instead. So I'm just trying to get angle to work, which SHOULD correspond to using OpenGL ES 2.0.

Well here the framebuffer creation:

glGenFramebuffers(1, &fboId);
glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glGenRenderbuffers(1, &cboId);
glBindRenderbuffer(GL_RENDERBUFFER, cboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, width, height);    
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, cboId);    
glGenRenderbuffers(1, &dboId);
glBindRenderbuffer(GL_RENDERBUFFER, dboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, width, height);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, dboId);

The framebuffer is complete and no error is thrown. The code between the previous and the following final piece does not throw any errors aswell.

glBindFramebuffer(GL_FRAMEBUFFER, fboId);
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, colorData);
//No error up to this point
glReadPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT, depthData));
//This call throws 0x502 (GL_INVALID_OPERATION)

Usually I use GL_DEPTH_COMPONENT24, which is not working for some reason. So I used GL_DEPTH_COMPONENT16 instead. Maybe that's a hint what is wrong. FYI the main framebuffer is using a 24bit Depth and 8bit stencil. (I tried using the GL_DEPTH24_STENCIL8 format aswell with no success on the glReadPixels call).

Using a texture instead or a pbuffer is not working, because the needed functions for this workaround (glGetTexImage(...), glMapBuffer(...)) are not implemented in the GL version I'm stuck with.


Solution

  • According to Khronos specification:

    format Specifies the format of the pixel data. The following symbolic values are accepted: GL_ALPHA, GL_RGB, and GL_RGBA.

    type Specifies the data type of the pixel data. Must be one of GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT_5_6_5, GL_UNSIGNED_SHORT_4_4_4_4, or GL_UNSIGNED_SHORT_5_5_5_1.

    GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_SHORT_5_6_5 and format is not GL_RGB.

    GL_INVALID_OPERATION is generated if type is GL_UNSIGNED_SHORT_4_4_4_4 or GL_UNSIGNED_SHORT_5_5_5_1 and format is not GL_RGBA.

    GL_INVALID_OPERATION is generated if format and type are neither GL_RGBA and GL_UNSIGNED_BYTE, respectively, nor the format/type pair returned by querying GL_IMPLEMENTATION_COLOR_READ_FORMAT and GL_IMPLEMENTATION_COLOR_READ_TYPE.

    Neither format nor type in your code qualify for this requirements.