OpenWalnut
1.4.0
|
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 WGECamera(), 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( WGECamera::FRAME_BUFFER_OBJECT ); 00048 setRenderOrder( WGECamera::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 WGECamera(), 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( WGECamera::FRAME_BUFFER_OBJECT ); 00065 setRenderOrder( WGECamera::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 // allow mipmap generation, but set desired levels to 0. Allow the user to set this higher 00083 texture->setUseHardwareMipMapGeneration( true ); 00084 texture->setNumMipmapLevels( 0 ); 00085 00086 // attach 00087 WGECamera::attach( buffer, texture, 0, 0, true ); 00088 } 00089 00090 void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::Image > image ) 00091 { 00092 WGECamera::attach( buffer, image ); 00093 } 00094 00095 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::attach( BufferComponent buffer, GLint internalFormat ) 00096 { 00097 osg::ref_ptr< osg::Texture2D > tex; 00098 if( buffer == DEPTH_BUFFER ) // depth buffers need a special texture type (else: FBO status = 0x8cd6 (FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT)) 00099 { 00100 tex = createTexture( GL_DEPTH_COMPONENT ); 00101 } 00102 else 00103 { 00104 #if defined(__APPLE__) 00105 if( internalFormat != GL_RGBA ) 00106 { 00107 wlog::warn( "WGEOffscreenRenderPass::attach:" ) << 00108 "Changing internal format to GL_RGBA because the original format is not supported on Mac OSX."; 00109 } 00110 tex = createTexture( GL_RGBA ); // on MacOS X, only RGBA textures work as attachment for FBO's 00111 #else 00112 tex = createTexture( internalFormat ); 00113 #endif 00114 } 00115 attach( buffer, tex ); 00116 return tex; 00117 } 00118 00119 void WGEOffscreenRenderPass::detach( BufferComponent buffer ) 00120 { 00121 // remove the texture from HUD if existing 00122 if( m_hud && WGECamera::getBufferAttachmentMap().count( buffer ) ) 00123 { 00124 m_hud->removeTexture( WGECamera::getBufferAttachmentMap()[ buffer ]._texture ); 00125 } 00126 00127 m_fbo->setAttachment( buffer, osg::FrameBufferAttachment() ); 00128 00129 WGECamera::detach( buffer ); 00130 } 00131 00132 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::createTexture( GLint internalFormat ) 00133 { 00134 osg::ref_ptr< osg::Texture2D > tex = new osg::Texture2D; 00135 tex->setTextureSize( m_width, m_height ); 00136 tex->setInternalFormat( internalFormat ); 00137 00138 switch( internalFormat ) 00139 { 00140 case GL_R16F: 00141 tex->setSourceType( GL_HALF_FLOAT ); 00142 tex->setSourceFormat( GL_RED ); 00143 break; 00144 case GL_R32F: 00145 tex->setSourceType( GL_FLOAT ); 00146 tex->setSourceFormat( GL_RED ); 00147 break; 00148 00149 // Those ifdef's where introduced, as otherwise OW would not compile on older platforms where no newer OpenGL is available. 00150 #ifdef GL_RGB16F 00151 case GL_RGB16F: 00152 tex->setSourceType( GL_HALF_FLOAT ); 00153 tex->setSourceFormat( GL_RGB ); 00154 break; 00155 #endif 00156 #ifdef GL_RGBA16F 00157 case GL_RGBA16F: 00158 tex->setSourceType( GL_HALF_FLOAT ); 00159 tex->setSourceFormat( GL_RGBA ); 00160 break; 00161 #endif 00162 #ifdef GL_RGB32F 00163 case GL_RGB32F: 00164 tex->setSourceType( GL_FLOAT ); 00165 tex->setSourceFormat( GL_RGB ); 00166 break; 00167 #endif 00168 #ifdef GL_RGBA32F 00169 case GL_RGBA32F: 00170 tex->setSourceType( GL_FLOAT ); 00171 tex->setSourceFormat( GL_RGBA ); 00172 break; 00173 #endif 00174 00175 default: 00176 // keep default format and type 00177 break; 00178 } 00179 00180 // setup interpolation 00181 tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR ); 00182 tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR ); 00183 00184 // do repeat the texture 00185 tex->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT ); 00186 tex->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT ); 00187 00188 return tex; 00189 } 00190 00191 std::string WGEOffscreenRenderPass::getName() const 00192 { 00193 return m_name; 00194 } 00195 00196 size_t WGEOffscreenRenderPass::getTextureWidth() const 00197 { 00198 return m_width; 00199 } 00200 00201 size_t WGEOffscreenRenderPass::getTextureHeight() const 00202 { 00203 return m_height; 00204 } 00205 00206 void WGEOffscreenRenderPass::addUniform( osg::ref_ptr< osg::Uniform > uniform ) 00207 { 00208 this->getOrCreateStateSet()->addUniform( uniform ); 00209 } 00210 00211 std::string WGEOffscreenRenderPass::getBufferName( BufferComponent buffer ) 00212 { 00213 switch( buffer ) 00214 { 00215 case DEPTH_BUFFER: 00216 return "Depth"; 00217 case STENCIL_BUFFER: 00218 return "Stencil"; 00219 case PACKED_DEPTH_STENCIL_BUFFER: 00220 return "Depth+Stencil"; 00221 case COLOR_BUFFER: 00222 return "Color 0"; 00223 case COLOR_BUFFER0: 00224 return "Color 0"; 00225 case COLOR_BUFFER1: 00226 return "Color 1"; 00227 case COLOR_BUFFER2: 00228 return "Color 2"; 00229 case COLOR_BUFFER3: 00230 return "Color 3"; 00231 case COLOR_BUFFER4: 00232 return "Color 4"; 00233 case COLOR_BUFFER5: 00234 return "Color 5"; 00235 case COLOR_BUFFER6: 00236 return "Color 6"; 00237 case COLOR_BUFFER7: 00238 return "Color 7"; 00239 case COLOR_BUFFER8: 00240 return "Color 8"; 00241 case COLOR_BUFFER9: 00242 return "Color 9"; 00243 case COLOR_BUFFER10: 00244 return "Color 10"; 00245 case COLOR_BUFFER11: 00246 return "Color 11"; 00247 case COLOR_BUFFER12: 00248 return "Color 12"; 00249 case COLOR_BUFFER13: 00250 return "Color 13"; 00251 case COLOR_BUFFER14: 00252 return "Color 14"; 00253 case COLOR_BUFFER15: 00254 return "Color 15"; 00255 default: 00256 return "Unknown"; 00257 } 00258 } 00259