OpenWalnut  1.4.0
WGEViewerEffectImageOverlay.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/Texture2D>
00028 #include <osgDB/ReadFile>
00029 
00030 #include "../common/WPathHelper.h"
00031 #include "../common/WProperties.h"
00032 #include "../common/WLogger.h"
00033 
00034 #include "WGEViewer.h"
00035 
00036 #include "callbacks/WGEFunctorCallback.h"
00037 #include "shaders/WGEShader.h"
00038 #include "shaders/WGEPropertyUniform.h"
00039 
00040 #include "WGEViewerEffectImageOverlay.h"
00041 
00042 WGEViewerEffectImageOverlay::WGEViewerEffectImageOverlay():
00043     WGEViewerEffect( "Image Overlay", "Blend in some arbitrary image." )
00044 {
00045     m_image = m_properties->addProperty( "Image", "The Image to use.", WPathHelper::getSharePath() / "GE" / "overlay.png" );
00046     WPropDouble scale = m_properties->addProperty( "Scale", "Scale the image in percent.", 50.0 );
00047     scale->setMin( 0.0 );
00048     scale->setMax( 200.0 );
00049 
00050     WPropBool moveToTop = m_properties->addProperty( "Move to Top", "Move the image to the top.", false );
00051     WPropBool moveToRight = m_properties->addProperty( "Move to Right", "Move the image to the right.", true );
00052 
00053     WPropDouble opacity = m_properties->addProperty( "Opacity",
00054         "Make the overlay transparent. Please be aware that the image itself might be transparent already.", 1.0 );
00055     opacity->setMin( 0.0 );
00056     opacity->setMax( 3.0 );
00057 
00058     osg::ref_ptr< WGEShader > overlayShader = new WGEShader( "WGECameraOverlayTexture" );
00059     overlayShader->apply( m_geode );
00060 
00061     m_forceReload = true;
00062 
00063     // texture setup, Loading is done later in the update callback.
00064     m_logoTexture = new osg::Texture2D;
00065     m_logoTexture->setDataVariance( osg::Object::DYNAMIC );
00066     // no wrapping
00067     m_logoTexture->setWrap( osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER );
00068     m_logoTexture->setWrap( osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER );
00069 
00070     // texture width and height (gets set by the update callback)
00071     m_overlayWidth = new osg::Uniform( "u_overlayWidth", static_cast< float >( 1 ) );
00072     m_overlayHeight = new osg::Uniform( "u_overlayHeight", static_cast< float >( 1 ) );
00073     m_state->addUniform( m_overlayWidth );
00074     m_state->addUniform( m_overlayHeight );
00075     // NOTE: the values of these uniforms get updated by the updateViewport callback, so these values are only placeholders
00076     m_viewportWidth = new osg::Uniform( "u_viewportWidth", static_cast< float >( 1024 ) );
00077     m_viewportHeight = new osg::Uniform( "u_viewportHeight", static_cast< float >( 768 ) );
00078     m_state->addUniform( m_viewportWidth );
00079     m_state->addUniform( m_viewportHeight );
00080 
00081     m_state->addUniform( new WGEPropertyUniform< WPropDouble >( "u_overlayScalePerc", scale ) );
00082     m_state->addUniform( new WGEPropertyUniform< WPropBool >( "u_toTop", moveToTop ) );
00083     m_state->addUniform( new WGEPropertyUniform< WPropBool >( "u_toRight", moveToRight ) );
00084 
00085     m_state->addUniform( new WGEPropertyUniform< WPropDouble >( "u_overlayOpacity", opacity ) );
00086 
00087     // add a callback which handles changes in viewport size
00088     m_updater = new Updater();
00089     addUpdateCallback( m_updater );
00090 
00091     // bind
00092     m_state->setTextureAttributeAndModes( 0, m_logoTexture, osg::StateAttribute::ON );
00093 }
00094 
00095 WGEViewerEffectImageOverlay::~WGEViewerEffectImageOverlay()
00096 {
00097     // cleanup
00098 }
00099 
00100 void WGEViewerEffectImageOverlay::setReferenceViewer( WGEViewer::SPtr viewer )
00101 {
00102     m_viewer = viewer;
00103 }
00104 
00105 const boost::shared_ptr< WGEViewer > WGEViewerEffectImageOverlay::getReferenceViewer() const
00106 {
00107     return m_viewer;
00108 }
00109 
00110 void WGEViewerEffectImageOverlay::Updater::operator() ( osg::Node* node, osg::NodeVisitor* nv )
00111 {
00112     WGEViewerEffectImageOverlay* effect = dynamic_cast< WGEViewerEffectImageOverlay* >( node );
00113     if( effect )
00114     {
00115         // viewer set?
00116         if( effect->m_viewer )
00117         {
00118             // valid camera? -> update viewport
00119             WGECamera* cam = effect->m_viewer->getCamera();
00120             if( cam )
00121             {
00122                 // valid viewport?
00123                 if( cam->getViewport() )
00124                 {
00125                     effect->m_viewportWidth->set( static_cast< float >( cam->getViewport()->width() ) );
00126                     effect->m_viewportHeight->set( static_cast< float >( cam->getViewport()->height() ) );
00127                 }
00128             }
00129 
00130             // update image if needed
00131             if( effect->m_forceReload || effect->m_image->changed() )
00132             {
00133                 effect->m_forceReload = false;
00134                 osg::Image* logoImage = osgDB::readImageFile( effect->m_image->get( true ).string() );
00135                 if( logoImage )
00136                 {
00137                     effect->m_logoTexture->setImage( logoImage );
00138                     effect->m_overlayWidth->set( static_cast< float >( logoImage->s() ) );
00139                     effect->m_overlayHeight->set( static_cast< float >( logoImage->t() ) );
00140                 }
00141             }
00142         }
00143     }
00144 
00145     // call nested callbacks
00146     traverse( node, nv );
00147     return;
00148 }
00149