4

I am doing off-screen processing using opengl es2.0 on Android.

I created a renderbuffer, and attached it to a framebuffer FBO, after rendering to the FBO, I try to get the pixels from that FBO by getReadPixels() method. But I got nothing.

The code is shown below:

GLuint resultFBO;// FBO
    GLuint rboId;  //render buffer id
glGenRenderbuffers(1, &rboId);
glBindRenderbuffer(GL_RENDERBUFFER, rboId);
glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, image_width, image_height);
glBindRenderbuffer(GL_RENDERBUFFER, 0);

glGenFramebuffers(1, &resultFBO);
glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
        GL_RENDERBUFFER, rboId);
glBindFramebuffer(GL_FRAMEBUFFER, 0);

GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status == GL_FRAMEBUFFER_COMPLETE) {
    //LOGH("Single FBO setup successfully.");
} else {
    LOGH("Problem in setup FBO texture: %d .", status);
}

//After render to the FBO 
glBindFramebuffer(GL_FRAMEBUFFER, resultFBO);
glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, imageSetData);
John
  • 697
  • 1
  • 10
  • 33
  • Is there any reason why you read the 16-bit depth buffer into a ubyte array? – Christian Rau Sep 13 '13 at 09:08
  • @ChristianRau I tried with GL_DEPTH_COMPONENT when call glRenderbufferStorage, but that will failed with errors. – John Sep 13 '13 at 09:10
  • Well yeah, so what? `GL_DEPTH_COMPONENT16` is probably a good idea, but why read it into a ubyte array? – Christian Rau Sep 13 '13 at 09:19
  • And by the way, what is *"nothing"* at all? How do you check the contents of `imageSetData` and what does it actually contain (since it cannot contain *"nothing"*)? – Christian Rau Sep 13 '13 at 09:21
  • @ChristianRau actually after I transfer the data to imageSetData, I will show it on screen. Previously I render to texture, and use getReadPixels(), I can get and see the image. now I am going to render to renderbuffer, getReadPixels() method doesn't transfer any data to my imageSetData. – John Sep 13 '13 at 09:29
  • *"actually after I transfer the data to imageSetData, I will show it on screen."* - **so does it show black, or what?** – Christian Rau Sep 13 '13 at 09:31
  • @ChristianRau imageSetData has original data, the original data not changed at all. if work properly, i can see a new image. – John Sep 13 '13 at 09:41

1 Answers1

3

You can not glReadPixels() from GL_DEPTH_COMPONENT in OpenGL ES 2.0. Only from the color buffer. See API Reference here.


void glReadPixels(  GLint x,
    GLint y,
    GLsizei width,
    GLsizei height,
    GLenum format,
    GLenum type,
    GLvoid * data);

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


Workaround1: If precision is not that important, you can write depth to one of the 8bit color channels instead.

Workaround2: You can write depth into the RGBA channels by packing the float into a vec4: See for example this SO thread.

Workaround3: You can try the OES_depth_texture extension and, if supported, render to a depth texture instead.

Community
  • 1
  • 1
umlum
  • 1,107
  • 6
  • 11
  • But when I need render to render buffer through FBO, when I allocate memory for the render buffer, I use `glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, image_width, image_height); ` here I am using `GL_DEPTH_COMMPNET16`, so I think I cannot use GL_RGB to read pixels. What do you think? – John Sep 15 '13 at 04:26
  • I linked to a thread that explains how you can pack a depth float into a RGBA vec4. – umlum Sep 15 '13 at 08:02
  • Hi, thanks for your replay, Can I ask you another question? regarding the precision in shaders, my code works well on desktop version of openg GL, but when I port to Android, I found there are some artifacts in the result image, the white color becomes green, I used RGB32 format on desktop, but I used RGB format (each channel 8 bits) on Android, is this the problem? – John Sep 16 '13 at 06:36