If you ever have a need for both colour buffer and depth buffer, than this might interest you. In the simplest way, you could render all your objects to screen and simply use glReadPixels: GLint viewport[4]; glGetIntegerv(GL_VIEWPORT, viewport); int imgsize = viewport[2] * viewport[3]; unsigned char *pixmap = (unsigned char*)malloc(sizeof(unsigned char) * imgsize * 4); glReadPixels(0, 0, viewport[2], viewport[3], GL_RGBA, GL_UNSIGNED_BYTE, pixmap); ... unsigned char *depthmap = (unsigned char*)malloc(sizeof(unsigned char) * imgsize * 1); glReadPixels(0, 0, viewport[2], viewport[3], GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, depthmap); Then operate on the memory of pixmap and depthmap at your leisure. If you find that you could do most operations on the GPU, then it is worth using textures to avoid heavy read back operations. Frame buffer objects are the best way to approach this. For most purposes, the depth buffer is unimportant for read back, this is where a RenderBuffer object is defined and used to store the depth without letting the programmer deal with it. GLuint rboId[1]; GLuint fboId[1]; GLuint textureId[1]; // texture created here glGenTextures(1, textureId); ...
// create a renderbuffer object to store depth info glGenRenderbuffersEXT(1, rboId); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rboId[0]); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height);
// create a framebuffer object glGenFramebuffersEXT(1, fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[0]);
// attach the texture to FBO color attachment point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId[0], 0);
// attach the renderbuffer to depth attachment point glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, rboId[0]);
check_fbo_status(); // see if everything is ok glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind To obtain both the colour and the depth, simply create two textures with the appropriate parameters (as in glReadPixels read back) and skip the render buffer construction. Instead of attaching the render buffer object to the FBO for depth, use the texture name instead. GLuint rboId[1]; GLuint fboId[1]; GLuint textureId[2]; // texture created here glGenTextures(2, textureId); ... // parameters for color buffer texture glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); ... // parameters for depth texture glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT16, width, height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, 0);
// create a framebuffer object glGenFramebuffersEXT(1, fboId); glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[0]);
// attach the texture to FBO color attachment point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, textureId[0], 0);
// Attach the texture to FBO depth attachment point glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, textureId[1], 0);
check_fbo_status(); // see if everything is ok glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind To use it all, swap the framebuffer to FBO, and restore it (0) when done. glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboId[0]); // bind
render();
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // Unbind
|