diff --git a/src/Main/CameraGroup.cxx b/src/Main/CameraGroup.cxx index ed95e6641..2aabd4a97 100644 --- a/src/Main/CameraGroup.cxx +++ b/src/Main/CameraGroup.cxx @@ -176,31 +176,6 @@ void makeNewProjMat(Matrixd& oldProj, double znear, 0.0, 0.0, center*ratio, 1.0)); } } - -void installCullVisitor(Camera* camera) -{ - osgViewer::Renderer* renderer - = static_cast(camera->getRenderer()); - for (int i = 0; i < 2; ++i) { - osgUtil::SceneView* sceneView = renderer->getSceneView(i); -#if SG_OSG_VERSION_LESS_THAN(3,0,0) - sceneView->setCullVisitor(new simgear::EffectCullVisitor); -#else - osg::ref_ptr identifier; - identifier = sceneView->getCullVisitor()->getIdentifier(); - sceneView->setCullVisitor(new simgear::EffectCullVisitor); - sceneView->getCullVisitor()->setIdentifier(identifier.get()); - - identifier = sceneView->getCullVisitorLeft()->getIdentifier(); - sceneView->setCullVisitorLeft(sceneView->getCullVisitor()->clone()); - sceneView->getCullVisitorLeft()->setIdentifier(identifier.get()); - - identifier = sceneView->getCullVisitorRight()->getIdentifier(); - sceneView->setCullVisitorRight(sceneView->getCullVisitor()->clone()); - sceneView->getCullVisitorRight()->setIdentifier(identifier.get()); -#endif - } -} } namespace flightgear @@ -213,55 +188,6 @@ void CameraInfo::updateCameras() farCamera->getViewport()->setViewport(x, y, width, height); } -CameraInfo* CameraGroup::addCamera(unsigned flags, Camera* camera, - const Matrix& view, - const Matrix& projection, - bool useMasterSceneData) -{ - CameraInfo* info = new CameraInfo(flags); - // The camera group will always update the camera - camera->setReferenceFrame(Transform::ABSOLUTE_RF); - - Camera* farCamera = 0; - if ((flags & (GUI | ORTHO)) == 0) { - farCamera = new Camera; - farCamera->setAllowEventFocus(camera->getAllowEventFocus()); - farCamera->setGraphicsContext(camera->getGraphicsContext()); - farCamera->setCullingMode(camera->getCullingMode()); - farCamera->setInheritanceMask(camera->getInheritanceMask()); - farCamera->setReferenceFrame(Transform::ABSOLUTE_RF); - // Each camera's viewport is written when the window is - // resized; if the the viewport isn't copied here, it gets updated - // twice and ends up with the wrong value. - farCamera->setViewport(simgear::clone(camera->getViewport())); - farCamera->setDrawBuffer(camera->getDrawBuffer()); - farCamera->setReadBuffer(camera->getReadBuffer()); - farCamera->setRenderTargetImplementation( - camera->getRenderTargetImplementation()); - const Camera::BufferAttachmentMap& bufferMap - = camera->getBufferAttachmentMap(); - if (bufferMap.count(Camera::COLOR_BUFFER) != 0) { - farCamera->attach( - Camera::COLOR_BUFFER, - bufferMap.find(Camera::COLOR_BUFFER)->second._texture.get()); - } - _viewer->addSlave(farCamera, projection, view, useMasterSceneData); - installCullVisitor(farCamera); - info->farCamera = farCamera; - info->farSlaveIndex = _viewer->getNumSlaves() - 1; - farCamera->setRenderOrder(Camera::POST_RENDER, info->farSlaveIndex); - camera->setCullMask(camera->getCullMask() & ~simgear::BACKGROUND_BIT); - camera->setClearMask(GL_DEPTH_BUFFER_BIT); - } - _viewer->addSlave(camera, projection, view, useMasterSceneData); - installCullVisitor(camera); - info->camera = camera; - info->slaveIndex = _viewer->getNumSlaves() - 1; - camera->setRenderOrder(Camera::POST_RENDER, info->slaveIndex); - _cameras.push_back(info); - return info; -} - void CameraGroup::update(const osg::Vec3d& position, const osg::Quat& orientation) { @@ -861,7 +787,7 @@ CameraInfo* CameraGroup::buildCamera(SGPropertyNode* cameraNode) } const SGPropertyNode* psNode = cameraNode->getNode("panoramic-spherical"); bool useMasterSceneGraph = !psNode; - CameraInfo* info = addCamera(cameraFlags, camera, vOff, pOff, + CameraInfo* info = globals->get_renderer()->buildRenderingPipeline(this, cameraFlags, camera, vOff, pOff, useMasterSceneGraph); info->name = cameraNode->getStringValue("name"); info->physicalWidth = physicalWidth; @@ -925,7 +851,7 @@ CameraInfo* CameraGroup::buildGUICamera(SGPropertyNode* cameraNode, camera->setProjectionResizePolicy(Camera::FIXED); camera->setReferenceFrame(Transform::ABSOLUTE_RF); const int cameraFlags = GUI | DO_INTERSECTION_TEST; - CameraInfo* result = addCamera(cameraFlags, camera, Matrixd::identity(), + CameraInfo* result = globals->get_renderer()->buildRenderingPipeline(this, cameraFlags, camera, Matrixd::identity(), Matrixd::identity(), false); SGPropertyNode* viewportNode = cameraNode->getNode("viewport", true); buildViewport(result, viewportNode, window->gc->getTraits()); diff --git a/src/Main/CameraGroup.hxx b/src/Main/CameraGroup.hxx index 76bb629bc..dd76c709a 100644 --- a/src/Main/CameraGroup.hxx +++ b/src/Main/CameraGroup.hxx @@ -134,19 +134,6 @@ public: * @return the viewer */ osgViewer::Viewer* getViewer() { return _viewer.get(); } - /** Add a camera to the group. The camera is added to the viewer - * as a slave. See osgViewer::Viewer::addSlave. - * @param flags properties of the camera; see CameraGroup::Flags - * @param projection slave projection matrix - * @param view slave view matrix - * @param useMasterSceneData whether the camera displays the - * viewer's scene data. - * @return a CameraInfo object for the camera. - */ - CameraInfo* addCamera(unsigned flags, osg::Camera* camera, - const osg::Matrix& projection, - const osg::Matrix& view, - bool useMasterSceneData = true); /** Create an osg::Camera from a property node and add it to the * camera group. * @param cameraNode the property node. @@ -197,6 +184,7 @@ public: CameraIterator camerasEnd() { return _cameras.end(); } ConstCameraIterator camerasBegin() const { return _cameras.begin(); } ConstCameraIterator camerasEnd() const { return _cameras.end(); } + void addCamera(CameraInfo* info) { _cameras.push_back(info); } /** Build a complete CameraGroup from a property node. * @param viewer the viewer associated with this camera group. * @param the camera group property node. diff --git a/src/Main/renderer.cxx b/src/Main/renderer.cxx index 864f0abab..25b4b9a66 100644 --- a/src/Main/renderer.cxx +++ b/src/Main/renderer.cxx @@ -62,9 +62,11 @@ #include #include +#include #include #include +#include #include #include #include @@ -500,6 +502,80 @@ FGRenderer::init( void ) _sky->texture_path( texture_path.str() ); } +void installCullVisitor(Camera* camera) +{ + osgViewer::Renderer* renderer + = static_cast(camera->getRenderer()); + for (int i = 0; i < 2; ++i) { + osgUtil::SceneView* sceneView = renderer->getSceneView(i); +#if SG_OSG_VERSION_LESS_THAN(3,0,0) + sceneView->setCullVisitor(new simgear::EffectCullVisitor); +#else + osg::ref_ptr identifier; + identifier = sceneView->getCullVisitor()->getIdentifier(); + sceneView->setCullVisitor(new simgear::EffectCullVisitor); + sceneView->getCullVisitor()->setIdentifier(identifier.get()); + + identifier = sceneView->getCullVisitorLeft()->getIdentifier(); + sceneView->setCullVisitorLeft(sceneView->getCullVisitor()->clone()); + sceneView->getCullVisitorLeft()->setIdentifier(identifier.get()); + + identifier = sceneView->getCullVisitorRight()->getIdentifier(); + sceneView->setCullVisitorRight(sceneView->getCullVisitor()->clone()); + sceneView->getCullVisitorRight()->setIdentifier(identifier.get()); +#endif + } +} + +flightgear::CameraInfo* FGRenderer::buildRenderingPipeline(flightgear::CameraGroup* cgroup, unsigned flags, Camera* camera, + const Matrix& view, + const Matrix& projection, + bool useMasterSceneData) +{ + CameraInfo* info = new CameraInfo(flags); + // The camera group will always update the camera + camera->setReferenceFrame(Transform::ABSOLUTE_RF); + + Camera* farCamera = 0; + if ((flags & (CameraGroup::GUI | CameraGroup::ORTHO)) == 0) { + farCamera = new Camera; + farCamera->setAllowEventFocus(camera->getAllowEventFocus()); + farCamera->setGraphicsContext(camera->getGraphicsContext()); + farCamera->setCullingMode(camera->getCullingMode()); + farCamera->setInheritanceMask(camera->getInheritanceMask()); + farCamera->setReferenceFrame(Transform::ABSOLUTE_RF); + // Each camera's viewport is written when the window is + // resized; if the the viewport isn't copied here, it gets updated + // twice and ends up with the wrong value. + farCamera->setViewport(simgear::clone(camera->getViewport())); + farCamera->setDrawBuffer(camera->getDrawBuffer()); + farCamera->setReadBuffer(camera->getReadBuffer()); + farCamera->setRenderTargetImplementation( + camera->getRenderTargetImplementation()); + const Camera::BufferAttachmentMap& bufferMap + = camera->getBufferAttachmentMap(); + if (bufferMap.count(Camera::COLOR_BUFFER) != 0) { + farCamera->attach( + Camera::COLOR_BUFFER, + bufferMap.find(Camera::COLOR_BUFFER)->second._texture.get()); + } + cgroup->getViewer()->addSlave(farCamera, projection, view, useMasterSceneData); + installCullVisitor(farCamera); + info->farCamera = farCamera; + info->farSlaveIndex = cgroup->getViewer()->getNumSlaves() - 1; + farCamera->setRenderOrder(Camera::POST_RENDER, info->farSlaveIndex); + camera->setCullMask(camera->getCullMask() & ~simgear::BACKGROUND_BIT); + camera->setClearMask(GL_DEPTH_BUFFER_BIT); + } + cgroup->getViewer()->addSlave(camera, projection, view, useMasterSceneData); + installCullVisitor(camera); + info->camera = camera; + info->slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; + camera->setRenderOrder(Camera::POST_RENDER, info->slaveIndex); + cgroup->addCamera(info); + return info; +} + void FGRenderer::setupView( void ) { diff --git a/src/Main/renderer.hxx b/src/Main/renderer.hxx index 29d9a6996..97c8e3697 100644 --- a/src/Main/renderer.hxx +++ b/src/Main/renderer.hxx @@ -7,6 +7,7 @@ #include #include +#include namespace osg { @@ -32,6 +33,8 @@ class Viewer; namespace flightgear { class FGEventHandler; +struct CameraInfo; +class CameraGroup; } class SGSky; @@ -69,9 +72,23 @@ public: void setEventHandler(flightgear::FGEventHandler* manipulator); /** Add a top level camera. - */ + */ void addCamera(osg::Camera* camera, bool useSceneData); + /** Add a camera to the group. The camera is added to the viewer + * as a slave. See osgViewer::Viewer::addSlave. + * @param flags properties of the camera; see CameraGroup::Flags + * @param projection slave projection matrix + * @param view slave view matrix + * @param useMasterSceneData whether the camera displays the + * viewer's scene data. + * @return a CameraInfo object for the camera. + */ + flightgear::CameraInfo* buildRenderingPipeline(flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera, + const osg::Matrix& view, + const osg::Matrix& projection, + bool useMasterSceneData); + SGSky* getSky() const { return _sky; } /**