From 64e3e98069fb2310311687b9f099b338b8b375a5 Mon Sep 17 00:00:00 2001 From: Frederic Bouvier Date: Tue, 1 May 2012 16:44:59 +0200 Subject: [PATCH] More work on configurable rendering pipeline implementation --- src/Viewer/renderer.cxx | 142 +++++++++++++++++++++++++------ src/Viewer/renderer.hxx | 12 ++- src/Viewer/renderingpipeline.cxx | 103 ++++++---------------- src/Viewer/renderingpipeline.hxx | 34 +++----- 4 files changed, 161 insertions(+), 130 deletions(-) diff --git a/src/Viewer/renderer.cxx b/src/Viewer/renderer.cxx index 97aec0d3c..158fb4066 100644 --- a/src/Viewer/renderer.cxx +++ b/src/Viewer/renderer.cxx @@ -35,6 +35,8 @@ #include #include +#include + #include #include #include @@ -103,7 +105,6 @@ #include "viewer.hxx" #include "viewmgr.hxx" #include "splash.hxx" -#include "renderingpipeline.hxx" #include "renderer.hxx" #include "CameraGroup.hxx" #include "FGEventHandler.hxx" @@ -757,7 +758,7 @@ private: CameraInfo* info; }; -osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, GLenum sourceType, osg::Texture::WrapMode wrapMode, bool shadowComparison = false) +osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, GLenum sourceType, GLenum wrapMode, bool shadowComparison = false) { osg::Texture2D* tex = new osg::Texture2D; tex->setResizeNonPowerOfTwoHint( false ); @@ -771,8 +772,8 @@ osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, G tex->setSourceType(sourceType); tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR ); tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR ); - tex->setWrap( osg::Texture::WRAP_S, wrapMode ); - tex->setWrap( osg::Texture::WRAP_T, wrapMode ); + tex->setWrap( osg::Texture::WRAP_S, (osg::Texture::WrapMode)wrapMode ); + tex->setWrap( osg::Texture::WRAP_T, (osg::Texture::WrapMode)wrapMode ); return tex; } @@ -799,7 +800,22 @@ void attachBufferToCamera( flightgear::CameraInfo* info, osg::Camera* camera, os info->getRenderStageInfo(ck).buffers.insert( std::make_pair( c, bk ) ); } -osg::Camera* FGRenderer::buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +osg::Camera* FGRenderer::buildDefaultDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +{ + std::vector > attachments; + if (_useColorForDepth) { + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::DEPTH_BUFFER, "real-depth") ); + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::COLOR_BUFFER3, "depth") ); + } else { + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::DEPTH_BUFFER, "depth") ); + } + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::COLOR_BUFFER0, "normal") ); + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::COLOR_BUFFER1, "diffuse") ); + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::COLOR_BUFFER2, "spec-emis") ); + return buildDeferredGeometryCamera(info, gc, attachments); +} + +osg::Camera* FGRenderer::buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ) { osg::Camera* camera = new osg::Camera; info->addCamera(flightgear::GEOMETRY_CAMERA, camera ); @@ -813,14 +829,8 @@ osg::Camera* FGRenderer::buildDeferredGeometryCamera( flightgear::CameraInfo* in camera->setClearDepth( 1.0 ); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setViewport( new osg::Viewport ); - attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER0, flightgear::GEOMETRY_CAMERA, "normal" ); - attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER1, flightgear::GEOMETRY_CAMERA, "diffuse" ); - attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER2, flightgear::GEOMETRY_CAMERA, "spec-emis" ); - if (_useColorForDepth) { - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, "real-depth" ); - attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER3, flightgear::GEOMETRY_CAMERA, "depth" ); - } else { - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, "depth" ); + BOOST_FOREACH(ref_ptr attachment, attachments) { + attachBufferToCamera( info, camera, attachment->component, flightgear::GEOMETRY_CAMERA, attachment->buffer ); } camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); @@ -871,7 +881,14 @@ static osg::Camera* createShadowCascadeCamera( int no, int cascadeSize ) { return cascadeCam; } -osg::Camera* FGRenderer::buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +osg::Camera* FGRenderer::buildDefaultDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +{ + std::vector > attachments; + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::DEPTH_BUFFER, "shadow") ); + return buildDeferredShadowCamera(info, gc, attachments); +} + +osg::Camera* FGRenderer::buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ) { osg::Camera* mainShadowCamera = new osg::Camera; info->addCamera(flightgear::SHADOW_CAMERA, mainShadowCamera, 0.0f ); @@ -882,7 +899,9 @@ osg::Camera* FGRenderer::buildDeferredShadowCamera( flightgear::CameraInfo* info mainShadowCamera->setAllowEventFocus(false); mainShadowCamera->setGraphicsContext(gc); mainShadowCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); - attachBufferToCamera( info, mainShadowCamera, osg::Camera::DEPTH_BUFFER, flightgear::SHADOW_CAMERA, "shadow" ); + BOOST_FOREACH(ref_ptr attachment, attachments) { + attachBufferToCamera( info, mainShadowCamera, attachment->component, flightgear::SHADOW_CAMERA, attachment->buffer ); + } mainShadowCamera->setComputeNearFarMode(osg::Camera::DO_NOT_COMPUTE_NEAR_FAR); mainShadowCamera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); mainShadowCamera->setProjectionMatrix(osg::Matrix::identity()); @@ -1077,7 +1096,19 @@ void FGRenderer::updateCascadeNumber(size_t num) _shadowNumber->set( (int)_numCascades ); } -osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +osg::Camera* FGRenderer::buildDefaultDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ) +{ + std::vector > attachments; + if (_useColorForDepth) { + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::DEPTH_BUFFER, "real-depth") ); + } else { + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::DEPTH_BUFFER, "depth") ); + } + attachments.push_back(new FGRenderingPipeline::Attachment(osg::Camera::COLOR_BUFFER0, "lighting") ); + return buildDeferredLightingCamera( info, gc, attachments ); +} + +osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ) { osg::Camera* camera = new osg::Camera; info->addCamera(flightgear::LIGHTING_CAMERA, camera ); @@ -1091,11 +1122,8 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in camera->setRenderOrder(osg::Camera::POST_RENDER, 50); camera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); camera->setViewport( new osg::Viewport ); - attachBufferToCamera( info, camera, osg::Camera::COLOR_BUFFER, flightgear::LIGHTING_CAMERA, "lighting" ); - if (_useColorForDepth) { - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, "real-depth" ); - } else { - attachBufferToCamera( info, camera, osg::Camera::DEPTH_BUFFER, flightgear::GEOMETRY_CAMERA, "depth" ); + BOOST_FOREACH(ref_ptr attachment, attachments) { + attachBufferToCamera( info, camera, attachment->component, flightgear::LIGHTING_CAMERA, attachment->buffer ); } camera->setDrawBuffer(GL_FRONT); camera->setReadBuffer(GL_FRONT); @@ -1222,15 +1250,20 @@ osg::Camera* FGRenderer::buildDeferredLightingCamera( flightgear::CameraInfo* in return camera; } +namespace flightgear { +flightgear::CameraInfo* buildCameraFromRenderingPipeline(FGRenderingPipeline* rpipe, CameraGroup* cgroup, unsigned flags, osg::Camera* camera, + const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc); +} + flightgear::CameraInfo* -FGRenderer::buildDeferredPipeline(flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera, +FGRenderer::buildDeferredPipeline(CameraGroup* cgroup, unsigned flags, osg::Camera* camera, const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc) { if (_renderer.empty() || !_pipeline.valid()) return buildDefaultDeferredPipeline(cgroup, flags, camera, view, projection, gc); - return _pipeline->buildCamera(cgroup, flags, camera, view, projection, gc); + return buildCameraFromRenderingPipeline(_pipeline, cgroup, flags, camera, view, projection, gc); } flightgear::CameraInfo* @@ -1242,19 +1275,19 @@ FGRenderer::buildDefaultDeferredPipeline(flightgear::CameraGroup* cgroup, unsign CameraInfo* info = new CameraInfo(flags); buildDeferredBuffers(info, _shadowMapSize, _useColorForDepth); - osg::Camera* geometryCamera = buildDeferredGeometryCamera( info, gc ); + osg::Camera* geometryCamera = buildDefaultDeferredGeometryCamera( info, gc ); cgroup->getViewer()->addSlave(geometryCamera, false); installCullVisitor(geometryCamera); int slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; info->getRenderStageInfo(GEOMETRY_CAMERA).slaveIndex = slaveIndex; - Camera* shadowCamera = buildDeferredShadowCamera( info, gc ); + Camera* shadowCamera = buildDefaultDeferredShadowCamera( info, gc ); cgroup->getViewer()->addSlave(shadowCamera, false); installCullVisitor(shadowCamera); slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; info->getRenderStageInfo(SHADOW_CAMERA).slaveIndex = slaveIndex; - osg::Camera* lightingCamera = buildDeferredLightingCamera( info, gc ); + osg::Camera* lightingCamera = buildDefaultDeferredLightingCamera( info, gc ); cgroup->getViewer()->addSlave(lightingCamera, false); installCullVisitor(lightingCamera); slaveIndex = cgroup->getViewer()->getNumSlaves() - 1; @@ -1958,6 +1991,63 @@ bool printVisibleSceneInfo(FGRenderer* renderer) return true; } +void buildBuffers(FGRenderingPipeline* rpipe, flightgear::CameraInfo* info) +{ + for (size_t i = 0; i < rpipe->buffers.size(); ++i) { + osg::ref_ptr buffer = rpipe->buffers[i]; + info->addBuffer(buffer->name, buildDeferredBuffer( buffer->internalFormat, + buffer->sourceFormat, + buffer->sourceType, + buffer->wrapMode, + buffer->shadowComparison) ); + } +} + +void buildStage(FGRenderingPipeline* rpipe, flightgear::CameraInfo* info, + FGRenderingPipeline::Stage* stage, + flightgear::CameraGroup* cgroup, + osg::Camera* camera, + const osg::Matrix& view, + const osg::Matrix& projection, + osg::GraphicsContext* gc) +{ + osg::ref_ptr stageCamera; + if (stage->type == "main-camera") + stageCamera = camera; + else + stageCamera = new osg::Camera; + + stageCamera->setName(stage->name); + stageCamera->setGraphicsContext(gc); + //stageCamera->setCullCallback(new FGStageCameraCullCallback(stage, info)); + if (stage->type != "main-camera") + stageCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); +} + +void buildMainCamera(FGRenderingPipeline* rpipe, flightgear::CameraInfo* info, + FGRenderingPipeline::Stage* stage, + flightgear::CameraGroup* cgroup, + osg::Camera* camera, + const osg::Matrix& view, + const osg::Matrix& projection, + osg::GraphicsContext* gc) +{ +} + +flightgear::CameraInfo* buildCameraFromRenderingPipeline(FGRenderingPipeline* rpipe, flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera, + const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc) +{ + flightgear::CameraInfo* info = new flightgear::CameraInfo(flags); + buildBuffers(rpipe, info); + + for (size_t i = 0; i < rpipe->stages.size(); ++i) { + osg::ref_ptr stage = rpipe->stages[i]; + buildStage(rpipe, info, stage, cgroup, camera, view, projection, gc); + } + + return 0; +} + } // end of renderer.cxx diff --git a/src/Viewer/renderer.hxx b/src/Viewer/renderer.hxx index 4c7d6636c..9f8a8159b 100644 --- a/src/Viewer/renderer.hxx +++ b/src/Viewer/renderer.hxx @@ -10,6 +10,8 @@ #include #include +#include "renderingpipeline.hxx" + namespace osg { class Camera; @@ -40,7 +42,6 @@ class CameraGroup; } class SGSky; -class FGRenderingPipeline; class FGRenderer { @@ -146,9 +147,12 @@ protected: float _cascadeFar[4]; bool _useColorForDepth; - osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); - osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); - osg::Camera* buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); + osg::Camera* buildDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ); + osg::Camera* buildDefaultDeferredGeometryCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); + osg::Camera* buildDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ); + osg::Camera* buildDefaultDeferredShadowCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); + osg::Camera* buildDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc, const std::vector > &attachments ); + osg::Camera* buildDefaultDeferredLightingCamera( flightgear::CameraInfo* info, osg::GraphicsContext* gc ); void updateShadowCascade(const flightgear::CameraInfo* info, osg::Camera* camera, osg::Group* grp, int idx, double left, double right, double bottom, double top, double zNear, double f1, double f2); osg::Vec3 getSunDirection() const; osg::ref_ptr _ambientFactor; diff --git a/src/Viewer/renderingpipeline.cxx b/src/Viewer/renderingpipeline.cxx index dfdcf3388..52133981c 100644 --- a/src/Viewer/renderingpipeline.cxx +++ b/src/Viewer/renderingpipeline.cxx @@ -173,6 +173,18 @@ FGRenderingPipeline::Buffer::Buffer(SGPropertyNode* prop) shadowComparison = prop->getBoolValue("shadow-comparison", false); } +simgear::effect::EffectNameValue componentsInit[] = +{ + {"depth", osg::Camera::DEPTH_BUFFER}, + {"stencil", osg::Camera::STENCIL_BUFFER}, + {"packed-depth-stencil", osg::Camera::PACKED_DEPTH_STENCIL_BUFFER}, + {"color0", osg::Camera::COLOR_BUFFER0}, + {"color1", osg::Camera::COLOR_BUFFER1}, + {"color2", osg::Camera::COLOR_BUFFER2}, + {"color3", osg::Camera::COLOR_BUFFER3} +}; +simgear::effect::EffectPropertyMap components(componentsInit); + FGRenderingPipeline::Stage::Stage(SGPropertyNode* prop) { SGPropertyNode_ptr nameProp = prop->getChild("name"); @@ -185,57 +197,27 @@ FGRenderingPipeline::Stage::Stage(SGPropertyNode* prop) throw sg_exception("Stage type is mandatory"); } type = typeProp->getStringValue(); + + std::vector attachments = prop->getChildren("attachment"); + for (int i = 0; i < (int)attachments.size(); ++i) { + this->attachments.push_back(new FGRenderingPipeline::Attachment(attachments[i])); + } +} + +FGRenderingPipeline::Attachment::Attachment(SGPropertyNode* prop) +{ + simgear::findAttr(components, prop->getChild("component"), component); + SGPropertyNode_ptr bufferProp = prop->getChild("buffer"); + if (!bufferProp.valid()) { + throw sg_exception("Attachment buffer is mandatory"); + } + buffer = bufferProp->getStringValue(); } FGRenderingPipeline::FGRenderingPipeline() { } -flightgear::CameraInfo* FGRenderingPipeline::buildCamera(flightgear::CameraGroup* cgroup, unsigned flags, osg::Camera* camera, - const osg::Matrix& view, const osg::Matrix& projection, osg::GraphicsContext* gc) -{ - flightgear::CameraInfo* info = new flightgear::CameraInfo(flags); - buildBuffers( info ); - - for (size_t i = 0; i < stages.size(); ++i) { - osg::ref_ptr stage = stages[i]; - buildStage(info, stage, cgroup, camera, view, projection, gc); - } - - return 0; -} - -osg::Texture2D* buildDeferredBuffer(GLint internalFormat, GLenum sourceFormat, GLenum sourceType, GLenum wrapMode, bool shadowComparison) -{ - osg::Texture2D* tex = new osg::Texture2D; - tex->setResizeNonPowerOfTwoHint( false ); - tex->setInternalFormat( internalFormat ); - tex->setShadowComparison(shadowComparison); - if (shadowComparison) { - tex->setShadowTextureMode(osg::Texture2D::LUMINANCE); - tex->setBorderColor(osg::Vec4(1.0f,1.0f,1.0f,1.0f)); - } - tex->setSourceFormat(sourceFormat); - tex->setSourceType(sourceType); - tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR ); - tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR ); - tex->setWrap( osg::Texture::WRAP_S, (osg::Texture::WrapMode)wrapMode ); - tex->setWrap( osg::Texture::WRAP_T, (osg::Texture::WrapMode)wrapMode ); - return tex; -} - -void FGRenderingPipeline::buildBuffers( flightgear::CameraInfo* info ) -{ - for (size_t i = 0; i < buffers.size(); ++i) { - osg::ref_ptr buffer = buffers[i]; - info->addBuffer(buffer->name, buildDeferredBuffer( buffer->internalFormat, - buffer->sourceFormat, - buffer->sourceType, - buffer->wrapMode, - buffer->shadowComparison) ); - } -} - class FGStageCameraCullCallback : public osg::NodeCallback { public: FGStageCameraCullCallback(FGRenderingPipeline::Stage* s, flightgear::CameraInfo* i) : stage(s), info(i) {} @@ -258,34 +240,3 @@ private: osg::ref_ptr stage; flightgear::CameraInfo* info; }; - -void FGRenderingPipeline::buildStage(flightgear::CameraInfo* info, - Stage* stage, - flightgear::CameraGroup* cgroup, - osg::Camera* camera, - const osg::Matrix& view, - const osg::Matrix& projection, - osg::GraphicsContext* gc) -{ - osg::ref_ptr stageCamera; - if (stage->type == "main-camera") - stageCamera = camera; - else - stageCamera = new osg::Camera; - - stageCamera->setName(stage->name); - stageCamera->setGraphicsContext(gc); - stageCamera->setCullCallback(new FGStageCameraCullCallback(stage, info)); - if (stage->type != "main-camera") - stageCamera->setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT ); -} - -void FGRenderingPipeline::buildMainCamera(flightgear::CameraInfo* info, - Stage* stage, - flightgear::CameraGroup* cgroup, - osg::Camera* camera, - const osg::Matrix& view, - const osg::Matrix& projection, - osg::GraphicsContext* gc) -{ -} diff --git a/src/Viewer/renderingpipeline.hxx b/src/Viewer/renderingpipeline.hxx index 875294faf..293e627b0 100644 --- a/src/Viewer/renderingpipeline.hxx +++ b/src/Viewer/renderingpipeline.hxx @@ -3,6 +3,7 @@ #define __FG_RENDERINGPIPELINE_HXX 1 #include +#include #include namespace simgear @@ -46,6 +47,14 @@ public: std::string type; }; + struct Attachment : public osg::Referenced { + Attachment(SGPropertyNode* prop); + Attachment(osg::Camera::BufferComponent c, const std::string& b ) : component(c), buffer(b) {} + + osg::Camera::BufferComponent component; + std::string buffer; + }; + struct Stage : public osg::Referenced { Stage(SGPropertyNode* prop); @@ -53,36 +62,13 @@ public: std::string type; std::vector > passes; + std::vector > attachments; }; FGRenderingPipeline(); - flightgear::CameraInfo* buildCamera(flightgear::CameraGroup* cgroup, - unsigned flags, - osg::Camera* camera, - const osg::Matrix& view, - const osg::Matrix& projection, - osg::GraphicsContext* gc); - -private: std::vector > buffers; std::vector > stages; - void buildBuffers(flightgear::CameraInfo* info); - void buildStage(flightgear::CameraInfo* info, - Stage* stage, - flightgear::CameraGroup* cgroup, - osg::Camera* camera, - const osg::Matrix& view, - const osg::Matrix& projection, - osg::GraphicsContext* gc); - void buildMainCamera(flightgear::CameraInfo* info, - Stage* stage, - flightgear::CameraGroup* cgroup, - osg::Camera* camera, - const osg::Matrix& view, - const osg::Matrix& projection, - osg::GraphicsContext* gc); - friend FGRenderingPipeline* flightgear::makeRenderingPipeline(const std::string& name, const simgear::SGReaderWriterOptions* options); };