OpenWalnut 1.3.1
WGEOffscreenRenderPass.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 
00028 #include <osg/Texture>
00029 #include <osg/Texture2D>
00030 
00031 #include "core/common/WLogger.h"
00032 #include "../WGETextureHud.h"
00033 
00034 #include "WGEOffscreenRenderPass.h"
00035 
00036 WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t textureHeight, int num ):
00037     osg::Camera(),
00038     m_width( textureWidth ),
00039     m_height( textureHeight ),
00040     m_fbo( new osg::FrameBufferObject() ),
00041     m_hud( NULL )
00042 {
00043     // initialize members
00044     setClearColor( osg::Vec4( 0.0, 0.0, 0.0, 0.0 ) );
00045     setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00046     setReferenceFrame( osg::Transform::RELATIVE_RF );
00047     setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
00048     setRenderOrder( osg::Camera::PRE_RENDER, num );
00049 }
00050 
00051 WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t textureHeight, osg::ref_ptr< WGETextureHud > hud, std::string name,
00052                                                 int num ):
00053     osg::Camera(),
00054     m_width( textureWidth ),
00055     m_height( textureHeight ),
00056     m_fbo( new osg::FrameBufferObject() ),
00057     m_hud( hud ),
00058     m_name( name )
00059 {
00060     // initialize members
00061     setClearColor( osg::Vec4( 0.0, 0.0, 0.0, 0.0 ) );
00062     setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
00063     setReferenceFrame( osg::Transform::RELATIVE_RF );
00064     setRenderTargetImplementation( osg::Camera::FRAME_BUFFER_OBJECT );
00065     setRenderOrder( osg::Camera::PRE_RENDER, num );
00066 }
00067 
00068 WGEOffscreenRenderPass::~WGEOffscreenRenderPass()
00069 {
00070     // cleanup
00071 }
00072 
00073 void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::Texture2D > texture )
00074 {
00075     m_fbo->setAttachment( buffer, osg::FrameBufferAttachment( texture ) );
00076 
00077     if( m_hud )
00078     {
00079         m_hud->addTexture( new WGETextureHud::WGETextureHudEntry( texture, m_name + " - " + getBufferName( buffer ) ) );
00080     }
00081 
00082     osg::Camera::attach( buffer, texture );
00083 }
00084 
00085 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::attach( BufferComponent buffer, GLint internalFormat )
00086 {
00087     osg::ref_ptr< osg::Texture2D > tex;
00088     if( buffer == DEPTH_BUFFER )   // depth buffers need a special texture type (else: FBO status = 0x8cd6 (FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT))
00089     {
00090         tex = createTexture( GL_DEPTH_COMPONENT );
00091     }
00092     else
00093     {
00094 #if defined(__APPLE__)
00095         if( internalFormat != GL_RGBA )
00096         {
00097             wlog::warn( "WGEOffscreenRenderPass::attach:" ) <<
00098                 "Changing internal format to GL_RGBA because the original format is not supported on Mac OSX.";
00099         }
00100         tex = createTexture( GL_RGBA );           // on MacOS X, only RGBA textures work as attachment for FBO's
00101 #else
00102         tex = createTexture( internalFormat );
00103 #endif
00104     }
00105     attach( buffer, tex );
00106     return tex;
00107 }
00108 
00109 void WGEOffscreenRenderPass::detach( BufferComponent buffer )
00110 {
00111     // remove the texture from HUD if existing
00112     if( m_hud && osg::Camera::getBufferAttachmentMap().count( buffer ) )
00113     {
00114         m_hud->removeTexture( osg::Camera::getBufferAttachmentMap()[ buffer ]._texture );
00115     }
00116 
00117     m_fbo->setAttachment( buffer, osg::FrameBufferAttachment() );
00118 
00119     osg::Camera::detach( buffer );
00120 }
00121 
00122 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::createTexture( GLint internalFormat )
00123 {
00124     osg::ref_ptr< osg::Texture2D > tex = new osg::Texture2D;
00125     tex->setTextureSize( m_width, m_height );
00126     tex->setInternalFormat( internalFormat );
00127 
00128     // setup interpolation
00129     tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
00130     tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
00131 
00132     // do repeat the texture
00133     tex->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
00134     tex->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
00135 
00136     return tex;
00137 }
00138 
00139 std::string WGEOffscreenRenderPass::getName() const
00140 {
00141     return m_name;
00142 }
00143 
00144 size_t WGEOffscreenRenderPass::getTextureWidth() const
00145 {
00146     return m_width;
00147 }
00148 
00149 size_t WGEOffscreenRenderPass::getTextureHeight() const
00150 {
00151     return m_height;
00152 }
00153 
00154 void WGEOffscreenRenderPass::addUniform( osg::ref_ptr< osg::Uniform > uniform )
00155 {
00156     this->getOrCreateStateSet()->addUniform( uniform );
00157 }
00158 
00159 std::string WGEOffscreenRenderPass::getBufferName( BufferComponent buffer )
00160 {
00161     switch( buffer )
00162     {
00163         case DEPTH_BUFFER:
00164             return "Depth";
00165         case STENCIL_BUFFER:
00166             return "Stencil";
00167         case PACKED_DEPTH_STENCIL_BUFFER:
00168             return "Depth+Stencil";
00169         case COLOR_BUFFER:
00170             return "Color 0";
00171         case COLOR_BUFFER0:
00172             return "Color 0";
00173         case COLOR_BUFFER1:
00174             return "Color 1";
00175         case COLOR_BUFFER2:
00176             return "Color 2";
00177         case COLOR_BUFFER3:
00178             return "Color 3";
00179         case COLOR_BUFFER4:
00180             return "Color 4";
00181         case COLOR_BUFFER5:
00182             return "Color 5";
00183         case COLOR_BUFFER6:
00184             return "Color 6";
00185         case COLOR_BUFFER7:
00186             return "Color 7";
00187         case COLOR_BUFFER8:
00188             return "Color 8";
00189         case COLOR_BUFFER9:
00190             return "Color 9";
00191         case COLOR_BUFFER10:
00192             return "Color 10";
00193         case COLOR_BUFFER11:
00194             return "Color 11";
00195         case COLOR_BUFFER12:
00196             return "Color 12";
00197         case COLOR_BUFFER13:
00198             return "Color 13";
00199         case COLOR_BUFFER14:
00200             return "Color 14";
00201         case COLOR_BUFFER15:
00202             return "Color 15";
00203         default:
00204             return "Unknown";
00205     }
00206 }
00207