void RenderingManager::screenshot(osg::Image *image, int w, int h) { osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera); rttCamera->setNodeMask(Mask_RenderToTexture); rttCamera->attach(osg::Camera::COLOR_BUFFER, image); rttCamera->setRenderOrder(osg::Camera::PRE_RENDER); rttCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); rttCamera->setProjectionMatrixAsPerspective(mFieldOfView, w/float(h), mNearClip, mViewDistance); rttCamera->setViewMatrix(mViewer->getCamera()->getViewMatrix()); rttCamera->setViewport(0, 0, w, h); osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setInternalFormat(GL_RGB); texture->setTextureSize(w, h); texture->setResizeNonPowerOfTwoHint(false); texture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); texture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); rttCamera->attach(osg::Camera::COLOR_BUFFER, texture); image->setDataType(GL_UNSIGNED_BYTE); image->setPixelFormat(texture->getInternalFormat()); rttCamera->setUpdateCallback(new NoTraverseCallback); rttCamera->addChild(mLightRoot); rttCamera->setCullMask(mViewer->getCamera()->getCullMask() & (~Mask_GUI)); mRootNode->addChild(rttCamera); // The draw needs to complete before we can copy back our image. osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback); rttCamera->setFinalDrawCallback(callback); // at the time this function is called we are in the middle of a frame, // so out of order calls are necessary to get a correct frameNumber for the next frame. // refer to the advance() and frame() order in Engine::go() mViewer->eventTraversal(); mViewer->updateTraversal(); mViewer->renderingTraversals(); callback->waitTillDone(); // now that we've "used up" the current frame, get a fresh framenumber for the next frame() following after the screenshot is completed mViewer->advance(mViewer->getFrameStamp()->getSimulationTime()); rttCamera->removeChildren(0, rttCamera->getNumChildren()); rttCamera->setGraphicsContext(NULL); mRootNode->removeChild(rttCamera); }
void RenderingManager::screenshot(osg::Image *image, int w, int h) { osg::ref_ptr<osg::Camera> rttCamera (new osg::Camera); rttCamera->setNodeMask(Mask_RenderToTexture); rttCamera->attach(osg::Camera::COLOR_BUFFER, image); rttCamera->setRenderOrder(osg::Camera::PRE_RENDER); rttCamera->setReferenceFrame(osg::Camera::ABSOLUTE_RF); rttCamera->setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT, osg::Camera::PIXEL_BUFFER_RTT); rttCamera->setClearColor(mViewer->getCamera()->getClearColor()); rttCamera->setClearMask(mViewer->getCamera()->getClearMask()); rttCamera->setProjectionMatrixAsPerspective(mFieldOfView, w/float(h), mNearClip, mViewDistance); rttCamera->setViewMatrix(mViewer->getCamera()->getViewMatrix()); rttCamera->setViewport(0, 0, w, h); rttCamera->setGraphicsContext(mViewer->getCamera()->getGraphicsContext()); osg::ref_ptr<osg::Texture2D> texture (new osg::Texture2D); texture->setInternalFormat(GL_RGB); texture->setTextureSize(w, h); texture->setResizeNonPowerOfTwoHint(false); rttCamera->attach(osg::Camera::COLOR_BUFFER, texture); image->setDataType(GL_UNSIGNED_BYTE); image->setPixelFormat(texture->getInternalFormat()); rttCamera->addChild(mLightRoot); rttCamera->setCullMask(mViewer->getCamera()->getCullMask() & (~Mask_GUI)); mRootNode->addChild(rttCamera); // The draw needs to complete before we can copy back our image. osg::ref_ptr<NotifyDrawCompletedCallback> callback (new NotifyDrawCompletedCallback); rttCamera->setFinalDrawCallback(callback); mViewer->frame(mViewer->getFrameStamp()->getSimulationTime()); callback->waitTillDone(); rttCamera->removeChildren(0, rttCamera->getNumChildren()); rttCamera->setGraphicsContext(NULL); mRootNode->removeChild(rttCamera); }