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)
{
allocateImage(width,height,1,format,type);
glPixelStorei(GL_PACK_ALIGNMENT,_packing);
glReadPixels(x,y,width,height,format,type,_data);
}
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);
texture2D->setFilter(osg::Texture2D::MIN_FILTER,osg::Texture2D::LINEAR);
texture2D->setFilter(osg::Texture2D::MAG_FILTER,osg::Texture2D::LINEAR);
// set up texture for z-buffer values
texture2D->setInternalFormat(GL_DEPTH_COMPONENT);
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;
texture2D->setImage(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.
pCamCopy->setClearMask(GL_DEPTH_BUFFER_BIT);
// 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.
pCamCopy->setProjectionMatrix(pCamera->getProjectionMatrix());
// set view
pCamCopy->setReferenceFrame(osg::Transform::ABSOLUTE_RF);
pCamCopy->setViewMatrix(pCamera->getViewMatrix());
// set viewport
pCamCopy->setViewport(0,0,tex_width,tex_height);
// set the camera to render before the main camera.
pCamCopy->setRenderOrder(osg::Camera::PRE_RENDER);
// tell the camera to use OpenGL frame buffer object where supported.
pCamCopy->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
// attach the texture and use it as the depth buffer
pCamCopy->attach(osg::Camera::DEPTH_BUFFER, texture);
// add sub graph to camera for rendering
pCamCopy->addChild(subGraph);
// add camera to scene
pRoot->addChild(pCamCopy)
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),
m_width(width),
m_height(height)
{}
void operator () (osg::RenderInfo& renderInfo) const
{
m_pImage->readPixels(0, 0, m_width, m_height,
GL_DEPTH_COMPONENT, GL_FLOAT);
// 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".
}
private:
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
Daniel
_______________________________________________
osg-users mailing list
osg-users@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org