1
0
Fork 0

Move camera setup to the renderer

This commit is contained in:
Frederic Bouvier 2012-03-10 14:57:43 +01:00
parent bca4683d52
commit 1a3f69723b
4 changed files with 97 additions and 90 deletions

View file

@ -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<osgViewer::Renderer*>(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<osgUtil::CullVisitor::Identifier> 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());

View file

@ -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.

View file

@ -62,9 +62,11 @@
#include <osg/io_utils>
#include <osgDB/WriteFile>
#include <osgViewer/Renderer>
#include <simgear/math/SGMath.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/material/EffectCullVisitor.hxx>
#include <simgear/scene/model/animation.hxx>
#include <simgear/scene/model/placement.hxx>
#include <simgear/scene/sky/sky.hxx>
@ -500,6 +502,80 @@ FGRenderer::init( void )
_sky->texture_path( texture_path.str() );
}
void installCullVisitor(Camera* camera)
{
osgViewer::Renderer* renderer
= static_cast<osgViewer::Renderer*>(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<osgUtil::CullVisitor::Identifier> 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 )
{

View file

@ -7,6 +7,7 @@
#include <simgear/timing/timestamp.hxx>
#include <osg/ref_ptr>
#include <osg/Matrix>
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; }
/**