OpenWalnut  1.4.0
WGEOffscreenRenderNode.cpp
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 #include <string>
00026 
00027 #include <osg/Geode>
00028 
00029 #include "../../common/WAssert.h"
00030 #include "../WGEUtils.h"
00031 
00032 #include "WGEOffscreenRenderNode.h"
00033 
00034 bool isPowerOfTwo( size_t x )
00035 {
00036     return ( (x != 0 ) && ( (x & ( ~x + 1 ) ) == x ) );
00037 }
00038 
00039 bool checkTextureSize( size_t size )
00040 {
00041     return !( ( size > 8192 ) || ( size < 8 ) );
00042 }
00043 
00044 WGEOffscreenRenderNode::WGEOffscreenRenderNode( osg::ref_ptr< WGECamera > reference, size_t width, size_t height, bool noHud ):
00045     WGEGroupNode(),
00046     m_referenceCamera( reference ),
00047     m_hud(),
00048     m_textureWidth( width ),
00049     m_textureHeight( height ),
00050     m_nextPassNum( 0 ),
00051     m_forceViewportTextureSize( false )
00052 {
00053     WAssert( checkTextureSize( width ) && checkTextureSize( height ), "Invalid offscreen texture size. Must be power of two and in [8,4096]." );
00054 
00055     // initialize members
00056     m_hud = new WGETextureHud();
00057     if( !noHud )
00058     {
00059         m_hud->addUpdateCallback( new WGEViewportCallback< WGETextureHud >( m_referenceCamera ) );
00060         m_hud->coupleViewportWithTextureViewport();
00061         insert( m_hud );
00062     }
00063 }
00064 
00065 WGEOffscreenRenderNode::~WGEOffscreenRenderNode()
00066 {
00067     // cleanup
00068 }
00069 
00070 osg::ref_ptr< WGEOffscreenRenderPass > WGEOffscreenRenderNode::addGeometryRenderPass( osg::ref_ptr< osg::Node > node, std::string name )
00071 {
00072     // create a plain render pass and add some geometry
00073     osg::ref_ptr< WGEOffscreenRenderPass > pass = addRenderPass< WGEOffscreenRenderPass >( name );
00074     pass->addChild( node );
00075 
00076     // add proxy to ensure proper clipping/culling even when the node changes its size in the shader. The programmer of the node has to take
00077     // care, that the getBounds methods of the node returns the right size (use a ComputeBoundingSpereCallback or overwrite computeBounds in
00078     // your node)
00079     //
00080     // It is important to add this proxy into the goup as the passes disable near/far recalculation. They inherit the near/far planes from the
00081     // camera of this group node. To ensure that OSG sets it properly, we use these proxies.
00082     insert( wge::generateDynamicCullProxy( node ) );
00083 
00084     return pass;
00085 }
00086 
00087 osg::ref_ptr< WGEOffscreenRenderPass > WGEOffscreenRenderNode::addGeometryRenderPass( osg::ref_ptr< osg::Node > node,
00088                                                                                       osg::ref_ptr< WGEShader > shader,
00089                                                                                       std::string name )
00090 {
00091     // create a plain render pass and add some geometry
00092     osg::ref_ptr< WGEOffscreenRenderPass > pass = addRenderPass< WGEOffscreenRenderPass >( name );
00093     pass->addChild( node );
00094     shader->apply( pass );
00095 
00096     // add proxy to ensure proper clipping/culling even when the node changes its size in the shader. The programmer of the node has to take
00097     // care, that the getBounds methods of the node returns the right size (use a ComputeBoundingSpereCallback or overwrite computeBounds in
00098     // your node)
00099     //
00100     // It is important to add this proxy into the goup as the passes disable near/far recalculation. They inherit the near/far planes from the
00101     // camera of this group node. To ensure that OSG sets it properly, we use these proxies.    insert( wge::generateDynamicCullProxy( node ) );
00102 
00103     return pass;
00104 }
00105 
00106 osg::ref_ptr< WGEOffscreenTexturePass > WGEOffscreenRenderNode::addTextureProcessingPass( std::string name )
00107 {
00108     osg::ref_ptr< WGEOffscreenTexturePass > pass = addRenderPass< WGEOffscreenTexturePass >( name );
00109     return pass;
00110 }
00111 
00112 osg::ref_ptr< WGEOffscreenTexturePass > WGEOffscreenRenderNode::addTextureProcessingPass( osg::ref_ptr< WGEShader > shader, std::string name )
00113 {
00114     osg::ref_ptr< WGEOffscreenTexturePass > pass = addRenderPass< WGEOffscreenTexturePass >( name );
00115     shader->apply( pass );
00116     return pass;
00117 }
00118 
00119 osg::ref_ptr< WGEOffscreenFinalPass > WGEOffscreenRenderNode::addFinalOnScreenPass( std::string name )
00120 {
00121     osg::ref_ptr< WGEOffscreenFinalPass > pass = addRenderPass< WGEOffscreenFinalPass >( name );
00122     return pass;
00123 }
00124 
00125 osg::ref_ptr< WGEOffscreenFinalPass > WGEOffscreenRenderNode::addFinalOnScreenPass( osg::ref_ptr< WGEShader > shader, std::string name )
00126 {
00127     osg::ref_ptr< WGEOffscreenFinalPass > pass = addRenderPass< WGEOffscreenFinalPass >( name );
00128     shader->apply( pass );
00129     return pass;
00130 }
00131 
00132 osg::ref_ptr< WGETextureHud > WGEOffscreenRenderNode::getTextureHUD() const
00133 {
00134     return m_hud;
00135 }
00136 
00137 size_t WGEOffscreenRenderNode::getTextureWidth() const
00138 {
00139     return m_textureWidth;
00140 }
00141 
00142 size_t WGEOffscreenRenderNode::getTextureHeight() const
00143 {
00144     return m_textureHeight;
00145 }
00146 
00147 void WGEOffscreenRenderNode::setLinkViewportToTextureSize( bool vp )
00148 {
00149     m_forceViewportTextureSize = vp;
00150 }
00151 
00152 bool WGEOffscreenRenderNode::getLinkViewportToTextureSize() const
00153 {
00154     return m_forceViewportTextureSize;
00155 }
00156