[osg-users] GL_DEPTH_COMPONENT data not clamped to [0, 1] when doing osg::Image::readPixels(...)
danielh at cm-labs.com
Tue Mar 3 13:27:33 PST 2009
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
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;
// 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
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.
// 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
// 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
The Code for the callback is as follows:
struct FilterImageCallback : osg::Camera::DrawCallback
FilterImageCallback(osg::Image* pImage, int width, int height)
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());
// 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".
I can't find the mistake.
Any help is much appreciated!
Cheers and Thank you
More information about the osg-users