Re: [osg-users] render depth buffer to image for one time

326 views
Skip to first unread message

aaron wetzler

unread,
Jun 27, 2011, 12:11:33 PM6/27/11
to osg-...@lists.openscenegraph.org
SOLUTION


For anyone who struggled with this here is my solution.
I really have no idea how "correct" it is but it works for me


Code:
//Setup of the viewer and scenedata here

osg::ref_ptr<osg::Camera> osgCam = viewer.getCamera();

osg::ref_ptr<osg::Image> colorImage= new osg::Image;
osg::ref_ptr<osg::Image> zImage = new osg::Image;

colorImage->allocateImage(1024, 768, 1, GL_RGBA, GL_UNSIGNED_BYTE);
zImage->allocateImage(1024, 768, 1, GL_DEPTH_COMPONENT , GL_UNSIGNED_BYTE);

osgCam->attach(osg::Camera::COLOR_BUFFER, colorImage.get());
osgCam->attach(osg::Camera::DEPTH_BUFFER, zImage.get()); /* */

viewer.frame();

Sleep(100);
osgDB::writeImageFile(*colorImage.get(),"color.bmp");
osgDB::writeImageFile(*zImage.get(),"depth.bmp");

Cheers,
aaron

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=40935#40935

_______________________________________________
osg-users mailing list
osg-...@lists.openscenegraph.org
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Sergey Polischuk

unread,
Jun 27, 2011, 5:21:44 PM6/27/11
to osg-...@lists.openscenegraph.org
Hi, Aaron

If you set singlethreaded mode and stop threading on viewer you can skip Sleep() step.
Used same thing couple of times :)

Cheers, Sergey.

27.06.2011, 20:11, "aaron wetzler" <aaronw...@gmail.com>:

Robert Osfield

unread,
Jun 27, 2011, 5:24:50 PM6/27/11
to osg-...@lists.openscenegraph.org
Hi Aaron,

Is there any reason why an osg::Camera FinalDrawCallback wouldn't work
fine for handling the writes when required? This would work fine for
multi-threaded usage and any length of time the the rendering would
take.

Robert.

aaron wetzler

unread,
Jun 27, 2011, 5:55:00 PM6/27/11
to osg-...@lists.openscenegraph.org
Thanks hybr and robertosfield for your comments. Both useful and I will use those tips.

Although my solution does work its not enough and Im now stuck on a couple of things. If you could point me in the right direction or to the right links that would be great

1)How do I render the depth image to the screen instead of rendering the color buffer?
Whats the name of the function that lets me define which buffer I want rendered to the screen (or FBO for that matter)

2) I actually want to invert my depth image and edit its values. How do I do that before writing the image?

3) The dimensions I put in the allocateImage call i.e. (1024, 768) have no effect on the size of the written image. How can I change that?


Looking forward to hearing from you

Aaron

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=40958#40958

Sergey Polischuk

unread,
Jun 27, 2011, 6:08:57 PM6/27/11
to osg-...@lists.openscenegraph.org
Hi, Aaron.

1) You can render scene depth to texture(using additional camera), then render screen aligned quad with this texture on screen. Or you can use osgPPU nodekit to do this, in this case you will need to make pipeline of two units: UnitDepthBufferBypass and UnitOut (iirc)

2) You have two options: first you can work with raw data in your image before writing (there are interfaces to pointer to raw data), second - you can preprocess it with shaders (again, using osgPPU (add one UnitInOut with correct shader between two mentioned earlier) or add shader that will process data when drawing screen aligned quad mentioned earlier)

3) iirc image will resize if it is not large enough to capture entire window(with framebuffer rendering) or viewport (with fbo rendering) so you may need to setup your window correctly or create camera that render to fbo with correct dimensions and use it for image capture.

Cheers,
Sergey.

28.06.2011, 01:55, "aaron wetzler" <aaronw...@gmail.com>:

aaron wetzler

unread,
Jul 1, 2011, 11:49:28 AM7/1/11
to osg-...@lists.openscenegraph.org
Hi Sergey

I would like to understand exactly how the graphics pipeline works and am struggling to figure this out by digging through the code (are there free books that deal with OSG and its implementation details in-depth? I dont mean the QSG by Paul Martz...). Also, my understanding of OpenGL is lacking in some places especially in implementation details so perhaps this will help clear things up for me.

In the prerender example we have something like this:

0: camera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
1: camera->attach(osg::Camera::BufferComponent(osg::Camera::COLOR_BUFFER0), image);
2: camera->setPostDrawCallback(new MyCameraPostDrawCallback(image));
3: textureRect[tex_to_get]->setImage(0, image);

As far as I understand this works as follows

0: This generates an FBO which has no data storage until I attach data storage to it (next step) ? Is this true? What happens then when I attach a color attachment but dont attach a depth buffer attachment? Does OSG automatically generate one for me? I ask because in regular OpenGL when you dont attach a depth attachment to an FBO then rendering to the FBO using glEnable(GL_DEPTH_TEST) produces incorrect results...

1: The image attached to the camera is the data storage for the FBO created in step 0. If this is the case then it means the FBO sits in RAM and not on the GPU. Is that true?

2:Here we set a post render callback using the image as our input. As far as I understand this means that the image (which is sitting in RAM) is edited in place. That means that as long as we dont need the data for actual rendering then we are being efficient because we dont copy to the GPU. Which brings up the next line...

3: We specify that a texture has the image as its image. I dont entirely understand what this means. When we create the original texture then OpenGL allocates space on the GPU for that texture. By using setImage(0,image) then does that mean that whatever is in that image (which sits on RAM) must always be copied to the GPU texture before the texture can be used at render time?

All in all I feel quite confused and would like to understand how to do the above process efficiently.
Ideally I would like to : pass dynamic geometry to the GPU every frame and have that rendered to textures inside the GPU. Occassionally I would like to ask the GPU to send the RTT textures back to the CPU, update them on the CPU and then send them back to the GPU.
How should I be doing that in the most efficient way possible?

Thank you!

Cheers,
aaron

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=41103#41103

Sergey Polischuk

unread,
Jul 1, 2011, 2:39:06 PM7/1/11
to osg-...@lists.openscenegraph.org
Hi aaron

0: osg can manage missing attachments for you if they are needed. This behaviour is configurable with env variables and in code. I dont actually remember default behaviour, but i think it will attach color and\or depth renderbuffers if they needed and missing, not sure about stencil.

1: as far as i remember this works by creating renderbuffer and then using glReadPixels from fbo to ram (image data storage). You can use image with pbo to make use of asynchronous dma transfers. Render to texture works faster, but you dont get your data on cpu side.

2: cant say much because didnt looked at example sources

3: texture->setImage(...) works like initializing gl texture with data stored in osg image with glTexImage(...), it will be copied in gpu memory and updated by osg if image changes. In this step you could also benefit from using image with pbo to get asynchronous copy.

> How should I be doing that in the most efficient way possible?

Depends on data size, frequency of gpu<->ram transfers and image processing speed on cpu. If you can process your image on gpu i'd stick with that and skip cpu processing altogether. Transfers gpu<->ram not so fast in any case, though pbo usage can help hide latency.

Cheers,
Sergey.

01.07.2011, 19:49, "aaron wetzler" <aaronw...@gmail.com>:

aaron wetzler

unread,
Jul 2, 2011, 8:52:20 AM7/2/11
to osg-...@lists.openscenegraph.org
Sergey, thank you so much for your help. Its been very useful
and has helped me focus my attention on the right things. I have almost finished what I needed to do.

I have one last question:

I now have an RTT camera which I take its depth and color attachments from. The RTT camera is a slave to the master scene camera and takes its data from there also.

My problem is that when I just leave the natural settings of the master camera then it seems that the depth range changes according to the bounding box of the scene data.

[Image: http://forum.openscenegraph.org/files/capture2_125.png ]

The range in the above image it gives me is great but I dont want it to change. I want to fix that depth range and also be in control of it.


In the next image I have set
viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);

I assumed this had to do with the near and far culling planes but it seems to affect the depth range also.

[Image: http://forum.openscenegraph.org/files/capture1_105.png ]

So now my question is how do I set and fix the depth range to what I choose?


...

Thank you!

Cheers,
aaron[img][/img]

------------------
Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=41117#41117


Attachments:
http://forum.openscenegraph.org//files/capture1_105.png
http://forum.openscenegraph.org//files/capture2_125.png

aaron wetzler

unread,
Jul 2, 2011, 9:27:46 AM7/2/11
to osg-...@lists.openscenegraph.org
I was being silly. I simply didnt pick the right values for the near and far planes.
This was my solution:


Code:
viewer.getCamera()->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
double left,right,bottom,top,fovy,aspectratio,near,far;
viewer.getCamera()->getProjectionMatrixAsPerspective(fovy,aspectratio,near,far);
viewer.getCamera()->setProjectionMatrixAsPerspective(fovy,aspectratio,20,25);

...

Thank you!

Cheers,
aaron

------------------


Read this topic online here:

http://forum.openscenegraph.org/viewtopic.php?p=41118#41118

Reply all
Reply to author
Forward
0 new messages