OpenWalnut 1.3.1
WGEOffscreenRenderNode.h
00001 //---------------------------------------------------------------------------
00002 //
00003 // Project: OpenWalnut ( http://www.openwalnut.org )
00004 //
00005 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
00006 // For more information see http://www.openwalnut.org/copying
00007 //
00008 // This file is part of OpenWalnut.
00009 //
00010 // OpenWalnut is free software: you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as published by
00012 // the Free Software Foundation, either version 3 of the License, or
00013 // (at your option) any later version.
00014 //
00015 // OpenWalnut is distributed in the hope that it will be useful,
00016 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018 // GNU Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public License
00021 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
00022 //
00023 //---------------------------------------------------------------------------
00024 
00025 #ifndef WGEOFFSCREENRENDERNODE_H
00026 #define WGEOFFSCREENRENDERNODE_H
00027 
00028 #include <string>
00029 
00030 #include <osg/Camera>
00031 
00032 #include "../WGEGroupNode.h"
00033 #include "WGEOffscreenRenderPass.h"
00034 #include "WGEOffscreenTexturePass.h"
00035 #include "WGEOffscreenFinalPass.h"
00036 #include "../WGETextureHud.h"
00037 #include "../shaders/WGEShader.h"
00038 #include "../callbacks/WGEViewportCallback.h"
00039 
00040 
00041 /**
00042  * This type of node basically is a convenience class for managing and creating offscreen renderings. The children of this node should be of type
00043  * \ref WGEOffscreenRenderPass. This class provides factories to create offscreen-render-pass instances with proper sizes with a coupling to a
00044  * reference camera. This is useful to provide automatic viewport scaling etc. to each render-pass. You do not explicitly need this class to
00045  * create offscreen-renderings at all. You can manually manage multiple WGEOffscreenRenderPass instances.
00046  *
00047  * It is important to understand, that the graph (your scene) must not be a children of this node. This node can be placed somewhere in your
00048  * scene. The OSG collects all the cameras (and offscreen-cameras) and render then independently from their position in the graph (except for
00049  * transformations inherited from others).
00050  *
00051  * \note Please not that you should not modify the whole wiring and offscreen configuration if the this node has been added as it is not
00052  * thread-safe.
00053  */
00054 class WGEOffscreenRenderNode: public WGEGroupNode // NOLINT
00055 {
00056 public:
00057     /**
00058      * Convenience typedef for an osg::ref_ptr
00059      */
00060     typedef osg::ref_ptr< WGEOffscreenRenderNode > RefPtr;
00061 
00062     /**
00063      * Convenience typedef for an osg::ref_ptr; const
00064      */
00065     typedef osg::ref_ptr< const WGEOffscreenRenderNode > ConstRefPtr;
00066 
00067     /**
00068      * Create a new managing instance. It uses the specified camera as reference to all created offscreen-render-pass instances. Especially
00069      * viewport, clear-mask and clear-color get used. The default texture resolution is 2048x2048 which is more than full-HD resolution. So it
00070      * should be enough.
00071      *
00072      * \note The width and hight define the offscreen texture size. The viewport if each rendering is automatically set to the one of the
00073      * reference camera. This means, width and height only define the maximal supported resolution without upscaling of your offscreen renderer.
00074      *
00075      * \param reference camera used as reference
00076      * \param width the width of the textures used in this rendering. Must be in [8,4096] and a power of two.
00077      * \param height the height of the textures used in this rendering. Must be in [8,4096] and a power of two.
00078      *
00079      * \param noHud If true, no hud gets displayed showing the created and used textures.
00080      */
00081     WGEOffscreenRenderNode( osg::ref_ptr< osg::Camera > reference, size_t width = 2048, size_t height = 2048, bool noHud = false );
00082 
00083     /**
00084      * Destructor.
00085      */
00086     virtual ~WGEOffscreenRenderNode();
00087 
00088     /**
00089      * Returns the instance of the texture HUD.
00090      *
00091      * \return the HUD
00092      */
00093     osg::ref_ptr< WGETextureHud > getTextureHUD() const;
00094 
00095     /**
00096      * Creates a new offscreen-render-pass coupled with the reference camera which renders a specified OSG graph to a texture.
00097      *
00098      * \param node the node which represents the subgraph.
00099      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00100      *
00101      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00102      *
00103      * \return the geometry render pass.
00104      */
00105     virtual osg::ref_ptr< WGEOffscreenRenderPass > addGeometryRenderPass( osg::ref_ptr< osg::Node > node, std::string name = "Unnamed" );
00106 
00107     /**
00108      * Creates a new offscreen-render-pass coupled with the reference camera which renders a specified OSG graph to a texture.
00109      *
00110      * \param node the node which represents the subgraph.
00111      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00112      * \param shader the shader to add.
00113      *
00114      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00115      *
00116      * \return the geometry render pass.
00117      */
00118     virtual osg::ref_ptr< WGEOffscreenRenderPass > addGeometryRenderPass( osg::ref_ptr< osg::Node > node, osg::ref_ptr< WGEShader > shader,
00119                                                                           std::string name = "Unnamed" );
00120 
00121     /**
00122      * Creates a new offscreen-render-pass coupled with the reference camera which simply processes textures. All the in- and output textures
00123      * have to be specified manually.
00124      *
00125      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00126      *
00127      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00128      *
00129      * \return the texture processing pass created.
00130      */
00131     virtual osg::ref_ptr< WGEOffscreenTexturePass > addTextureProcessingPass( std::string name = "Unnamed" );
00132 
00133     /**
00134      * Creates a new offscreen-render-pass coupled with the reference camera which simply processes textures. All the in- and output textures
00135      * have to be specified manually.
00136      *
00137      * \note never forget to remove the returned node if not used anymore or use WGEGroup::clean.
00138      *
00139      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00140      * \param shader the shader to add.
00141      *
00142      * \return the texture processing pass created.
00143      */
00144     virtual osg::ref_ptr< WGEOffscreenTexturePass > addTextureProcessingPass( osg::ref_ptr< WGEShader > shader, std::string name = "Unnamed" );
00145 
00146     /**
00147      * Creates a new render pass which can be seen as put-textures-back-on-screen-pass. It renders a full-screen quad to the on-screen
00148      * frame-buffer. An optional shader can be used for final processing (most commonly clipping, blending, color-mapping and so on).
00149      *
00150      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00151      *
00152      * \return the on-screen render pass which draws processed textures back on screen.
00153      */
00154     virtual osg::ref_ptr< WGEOffscreenFinalPass > addFinalOnScreenPass( std::string name = "Unnamed" );
00155 
00156     /**
00157      * Creates a new render pass which can be seen as put-textures-back-on-screen-pass. It renders a full-screen quad to the on-screen
00158      * frame-buffer. An optional shader can be used for final processing (most commonly clipping, blending, color-mapping and so on).
00159      *
00160      * \param shader the shader to add
00161      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00162      *
00163      * \return the on-screen render pass which draws processed textures back on screen.
00164      */
00165     virtual osg::ref_ptr< WGEOffscreenFinalPass > addFinalOnScreenPass( osg::ref_ptr< WGEShader > shader, std::string name = "Unnamed" );
00166 
00167     /**
00168      * Creates a new offscreen-render-pass coupled with the reference camera. This pass actually does nothing. The method is useful for custom
00169      * variants of WGEOffscreenRenderPass.
00170      *
00171      * \param name the name of the render pass. You should specify it to enable the nice debugging feature of WGETextureHud.
00172      *
00173      * \return new instance of a plain render pass
00174      *
00175      * \tparam T the type of pass to create.
00176      */
00177     template < typename T >
00178     osg::ref_ptr< T >  addRenderPass( std::string name = "Unnamed" );
00179 
00180 protected:
00181 private:
00182     /**
00183      * The camera to which is used for setting this camera up.
00184      */
00185     osg::ref_ptr< osg::Camera > m_referenceCamera;
00186 
00187     /**
00188      * The pointer to the hud used to render all used texture buffers. This can be NULL. It gets distributed to all created render-pass
00189      * instances.
00190      */
00191     osg::ref_ptr< WGETextureHud > m_hud;
00192 
00193     /**
00194      * The width of each texture in this offscreen rendering.
00195      */
00196     size_t m_textureWidth;
00197 
00198     /**
00199      * The height of each texture in this offscreen rendering.
00200      */
00201     size_t m_textureHeight;
00202 
00203     /**
00204      * The number of the next pass getting added.
00205      */
00206     size_t m_nextPassNum;
00207 };
00208 
00209 template < typename T >
00210 osg::ref_ptr< T > WGEOffscreenRenderNode::addRenderPass( std::string name )
00211 {
00212     // create a new pass
00213     osg::ref_ptr< T > pass = new T( m_textureWidth, m_textureHeight, m_hud, name, m_nextPassNum );
00214     m_nextPassNum++;
00215 
00216     // this node needs to keep all the pass instances. Only this way, the OSG traverses and renders these nodes in the order specified by
00217     // m_nextPassNum.
00218     insert( pass );   // insert into this group
00219 
00220     // ensure proper propagation of viewport changes
00221     pass->addUpdateCallback( new WGEViewportCallback< T >( m_referenceCamera ) );
00222 
00223     // set clear mask and color according to reference cam
00224     pass->setClearMask( m_referenceCamera->getClearMask() );
00225     pass->setClearColor( m_referenceCamera->getClearColor() );
00226 
00227     return pass;
00228 }
00229 
00230 #endif  // WGEOFFSCREENRENDERNODE_H
00231