[osg-users] GL_DEPTH_COMPONENT data not clamped to [0, 1] when doing osg::Image::readPixels(...)

Daniel Holz danielh at cm-labs.com
Tue Mar 3 13:27:33 PST 2009

Hi everyone,

I am trying to store the Z-Buffer of a subgraph of my scene in an 
osg::Image for later processing,
but the values I obtain are not as expected in the range [0,1] but 
appear to be integer values starting at 0 and going up to about 200.
I am writing the depth buffer to the osg::Image by using 
image->readPixels(0, 0, width, height, GL_DEPTH_COMPONENT, GL_FLOAT);
The osg code which is executed is:

    void Image::readPixels(int x,int y,int width,int height,GLenum 
format,GLenum type)



And according to the OpenGL reference manual 
(http://www.opengl.org/sdk/docs/man/xhtml/glReadPixels.xml) the values 
written to the buffer "_data" should be of type float and in the range 
[0,1] which they are not for me.

I am wondering if I am doing something wrong.
In the following I posted a short version of my implementation, which is 
based on the osgprerender example.

First I set up a render to texture pass:
    // texture to render to
    osg::Texture* texture = 0;
    osg::Texture2D* texture2D = new osg::Texture2D;
    texture2D->setTextureSize(tex_width, tex_height);
    // set up texture for z-buffer values
    texture = texture2D;

    // attach an image to the texture.
    // this allows us to modify the image data before it is being 
rendered to the quad
    osg::Image* image = new osg::Image;

Then I create a second camera as copy of the main camera which renders 
to the above texture.

    // obtain main camera
    osg::Camera* pCamera = ...
    osg::Camera* pCamCopy = new osg::Camera;
    // set update callback to update the copied camera's view and 
projection matrix
    pCamCopy->setPreDrawCallback(new UpdateCamCallback(pCamera)); // 
just keeps the copied and the main camera aligned
    // set the clear mask. -> just the depth buffer is cleared.
    // set the color mask. -> since we do not want any color information 
to be written we can set all bits to zero.
    pCamCopy->setColorMask(new osg::ColorMask(0,0,0,0));
    // set up projection.
    // set view
    // set viewport

    // set the camera to render before the main camera.
    // tell the camera to use OpenGL frame buffer object where supported.
    // attach the texture and use it as the depth buffer
    pCamCopy->attach(osg::Camera::DEPTH_BUFFER, texture);

    // add sub graph to camera for rendering
    // add camera to scene

Finally I set a post draw callback to the copied camera, where the post 
processing of the depth buffer should be performed.
There I call osg::Image::readPixels(...) to copy the depth buffer data 
from the gpu to the image but the obtained data does not seem to be correct.
    // set post processing callback
    pCamCopy->setPostDrawCallback(new FilterImageCallback(image, 
tex_width, tex_height));

The Code for the callback is as follows:

struct FilterImageCallback : osg::Camera::DrawCallback
    FilterImageCallback(osg::Image* pImage, int width, int height)
        :   m_pImage(pImage),
    void operator () (osg::RenderInfo& renderInfo) const
        m_pImage->readPixels(0, 0, m_width, m_height, 

        // apply post processing here:

        // test: obtain first pixel's z value and convert to float.
        float z = (float) (m_pImage->data())[0];
        // Problem: z-value is not in range [0, 1] but appears to be 
0,1,2, etc. It is 0 for areas where the z-buffer is clear, i.e. z-value 
corresponds to "infinity".

    osg::Image* m_pImage;
    int m_width;
    int m_height;

I can't find the mistake.
Any help is much appreciated!

Cheers and Thank you

More information about the osg-users mailing list