OpenWalnut  1.4.0
WGEOffscreenTexturePass.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 "../WGETextureHud.h"
00028 #include "../WGEGeodeUtils.h"
00029 
00030 #include "WGEOffscreenTexturePass.h"
00031 
00032 WGEOffscreenTexturePass::WGEOffscreenTexturePass( size_t textureWidth, size_t textureHeight, int num ):
00033     WGEOffscreenRenderPass( textureWidth, textureHeight, num )
00034 {
00035     // initialize members
00036     setup();
00037 }
00038 
00039 WGEOffscreenTexturePass::WGEOffscreenTexturePass( size_t textureWidth, size_t textureHeight, osg::ref_ptr< WGETextureHud > hud, std::string name,
00040                                                   int num ):
00041     WGEOffscreenRenderPass( textureWidth, textureHeight, hud, name, num )
00042 {
00043     // initialize members
00044     setup();
00045 }
00046 
00047 WGEOffscreenTexturePass::~WGEOffscreenTexturePass()
00048 {
00049     // cleanup
00050 }
00051 
00052 void WGEOffscreenTexturePass::setup()
00053 {
00054     // we need to create a nice quad for texture processing spanning the whole texture space
00055     osg::ref_ptr< osg::Geode > geode = wge::genFinitePlane( osg::Vec3( 0.0, 0.0, 0.0 ),
00056                                                             osg::Vec3( 1.0, 0.0, 0.0 ),
00057                                                             osg::Vec3( 0.0, 1.0, 0.0 ) );
00058     // setup the texture matrix scaler to the geode
00059     geode->addUpdateCallback( new TextureMatrixUpdateCallback( this ) );
00060 
00061     // add the slice to the geode
00062     this->addChild( geode );
00063 
00064     // disable all annoying states as blending, lighting and so on is done via shaders
00065     osg::StateSet* state = this->getOrCreateStateSet();
00066     state->setMode( GL_DEPTH_TEST, osg::StateAttribute::OFF );
00067     state->setMode( GL_LIGHTING, osg::StateAttribute::PROTECTED );
00068     state->setMode( GL_LIGHTING, osg::StateAttribute::OFF );
00069     state->setMode( GL_BLEND, osg::StateAttribute::PROTECTED );
00070     state->setMode( GL_BLEND, osg::StateAttribute::OFF );
00071 
00072     // avoid culling
00073     setCullingActive( false );
00074 
00075     // setup 2D projection
00076     this->setReferenceFrame( osg::Transform::ABSOLUTE_RF );
00077     this->setProjectionMatrixAsOrtho2D( 0.0, 1.0, 0.0, 1.0 );
00078     this->setViewMatrix( osg::Matrixd::identity() );
00079 
00080     // enable texture coordinate manipulation via texture matrices
00081     m_texMat = new osg::TexMat;
00082     m_texMat->setMatrix( osg::Matrixd::identity() );
00083     state->setTextureAttributeAndModes( 0, m_texMat, osg::StateAttribute::ON );
00084 }
00085 
00086 void WGEOffscreenTexturePass::TextureMatrixUpdateCallback::operator()( osg::Node* node, osg::NodeVisitor* nv )
00087 {
00088     osg::ref_ptr< osg::TexMat > texMat = m_pass->m_texMat;
00089 
00090     // we need all this to scale the texture coordinates to match the viewport of the camera as the whole texture might be larger than the
00091     // viewport.
00092     unsigned int screenWidth = m_pass->getViewport()->width();
00093     unsigned int screenHeight = m_pass->getViewport()->height();
00094 
00095     texMat->setMatrix( osg::Matrixd::scale( static_cast< float >( screenWidth ) / static_cast< float >( m_pass->getTextureWidth() ),
00096                                             static_cast< float >( screenHeight )/ static_cast< float >( m_pass->getTextureHeight() ), 1.0 ) );
00097 
00098     // call nested callbacks
00099     traverse( node, nv );
00100 }
00101