OpenWalnut  1.5.0dev
WGEOffscreenRenderPass.cpp
1 //---------------------------------------------------------------------------
2 //
3 // Project: OpenWalnut ( http://www.openwalnut.org )
4 //
5 // Copyright 2009 OpenWalnut Community, BSV@Uni-Leipzig and CNCF@MPI-CBS
6 // For more information see http://www.openwalnut.org/copying
7 //
8 // This file is part of OpenWalnut.
9 //
10 // OpenWalnut is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 3 of the License, or
13 // (at your option) any later version.
14 //
15 // OpenWalnut is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
22 //
23 //---------------------------------------------------------------------------
24 
25 #include <string>
26 
27 
28 #include <osg/Texture>
29 #include <osg/Texture2D>
30 
31 #include "core/common/WLogger.h"
32 #include "../WGETextureHud.h"
33 
34 #include "WGEOffscreenRenderPass.h"
35 
36 WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t textureHeight, int num ):
37  WGECamera(),
38  m_width( textureWidth ),
39  m_height( textureHeight ),
40  m_fbo( new osg::FrameBufferObject() ),
41  m_hud( NULL )
42 {
43  // initialize members
44  setClearColor( osg::Vec4( 0.0, 0.0, 0.0, 0.0 ) );
45  setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
46  setReferenceFrame( osg::Transform::RELATIVE_RF );
47  setRenderTargetImplementation( WGECamera::FRAME_BUFFER_OBJECT );
48  setRenderOrder( WGECamera::PRE_RENDER, num );
49 }
50 
51 WGEOffscreenRenderPass::WGEOffscreenRenderPass( size_t textureWidth, size_t textureHeight, osg::ref_ptr< WGETextureHud > hud, std::string name,
52  int num ):
53  WGECamera(),
54  m_width( textureWidth ),
55  m_height( textureHeight ),
56  m_fbo( new osg::FrameBufferObject() ),
57  m_hud( hud ),
58  m_name( name )
59 {
60  // initialize members
61  setClearColor( osg::Vec4( 0.0, 0.0, 0.0, 0.0 ) );
62  setClearMask( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
63  setReferenceFrame( osg::Transform::RELATIVE_RF );
64  setRenderTargetImplementation( WGECamera::FRAME_BUFFER_OBJECT );
65  setRenderOrder( WGECamera::PRE_RENDER, num );
66 }
67 
69 {
70  // cleanup
71 }
72 
73 void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::Texture2D > texture )
74 {
75  m_fbo->setAttachment( buffer, osg::FrameBufferAttachment( texture ) );
76 
77  if( m_hud )
78  {
79  m_hud->addTexture( new WGETextureHud::WGETextureHudEntry( texture, m_name + " - " + getBufferName( buffer ) ) );
80  }
81 
82  // allow mipmap generation, but set desired levels to 0. Allow the user to set this higher
83  texture->setUseHardwareMipMapGeneration( true );
84  texture->setNumMipmapLevels( 0 );
85 
86  // attach
87  WGECamera::attach( buffer, texture, 0, 0, true );
88 }
89 
90 void WGEOffscreenRenderPass::attach( BufferComponent buffer, osg::ref_ptr< osg::Image > image )
91 {
92  WGECamera::attach( buffer, image );
93 }
94 
95 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::attach( BufferComponent buffer, GLint internalFormat )
96 {
97  osg::ref_ptr< osg::Texture2D > tex;
98  if( buffer == DEPTH_BUFFER ) // depth buffers need a special texture type (else: FBO status = 0x8cd6 (FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT))
99  {
100  tex = createTexture( GL_DEPTH_COMPONENT );
101  }
102  else
103  {
104 #if defined( __APPLE__ )
105  if( internalFormat != GL_RGBA )
106  {
107  wlog::warn( "WGEOffscreenRenderPass::attach:" ) <<
108  "Changing internal format to GL_RGBA because the original format is not supported on Mac OSX.";
109  }
110  tex = createTexture( GL_RGBA ); // on MacOS X, only RGBA textures work as attachment for FBO's
111 #else
112  tex = createTexture( internalFormat );
113 #endif
114  }
115  attach( buffer, tex );
116  return tex;
117 }
118 
119 void WGEOffscreenRenderPass::detach( BufferComponent buffer )
120 {
121  // remove the texture from HUD if existing
122  if( m_hud && WGECamera::getBufferAttachmentMap().count( buffer ) )
123  {
124  m_hud->removeTexture( WGECamera::getBufferAttachmentMap()[ buffer ]._texture );
125  }
126 
127  m_fbo->setAttachment( buffer, osg::FrameBufferAttachment() );
128 
129  WGECamera::detach( buffer );
130 }
131 
132 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::createTexture( GLint internalFormat )
133 {
134  osg::ref_ptr< osg::Texture2D > tex = new osg::Texture2D;
135  tex->setTextureSize( m_width, m_height );
136  tex->setInternalFormat( internalFormat );
137 
138  switch( internalFormat )
139  {
140  case GL_R16F:
141  tex->setSourceType( GL_HALF_FLOAT );
142  tex->setSourceFormat( GL_RED );
143  break;
144  case GL_R32F:
145  tex->setSourceType( GL_FLOAT );
146  tex->setSourceFormat( GL_RED );
147  break;
148 
149 // Those ifdef's where introduced, as otherwise OW would not compile on older platforms where no newer OpenGL is available.
150 #ifdef GL_RGB16F
151  case GL_RGB16F:
152  tex->setSourceType( GL_HALF_FLOAT );
153  tex->setSourceFormat( GL_RGB );
154  break;
155 #endif
156 #ifdef GL_RGBA16F
157  case GL_RGBA16F:
158  tex->setSourceType( GL_HALF_FLOAT );
159  tex->setSourceFormat( GL_RGBA );
160  break;
161 #endif
162 #ifdef GL_RGB32F
163  case GL_RGB32F:
164  tex->setSourceType( GL_FLOAT );
165  tex->setSourceFormat( GL_RGB );
166  break;
167 #endif
168 #ifdef GL_RGBA32F
169  case GL_RGBA32F:
170  tex->setSourceType( GL_FLOAT );
171  tex->setSourceFormat( GL_RGBA );
172  break;
173 #endif
174 
175  default:
176  // keep default format and type
177  break;
178  }
179 
180  // setup interpolation
181  tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
182  tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
183 
184  // do repeat the texture
185  tex->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
186  tex->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
187 
188  return tex;
189 }
190 
192 {
193  return m_name;
194 }
195 
197 {
198  return m_width;
199 }
200 
202 {
203  return m_height;
204 }
205 
206 void WGEOffscreenRenderPass::addUniform( osg::ref_ptr< osg::Uniform > uniform )
207 {
208  this->getOrCreateStateSet()->addUniform( uniform );
209 }
210 
211 std::string WGEOffscreenRenderPass::getBufferName( BufferComponent buffer )
212 {
213  switch( buffer )
214  {
215  case DEPTH_BUFFER:
216  return "Depth";
217  case STENCIL_BUFFER:
218  return "Stencil";
219  case PACKED_DEPTH_STENCIL_BUFFER:
220  return "Depth+Stencil";
221  case COLOR_BUFFER:
222  return "Color 0";
223  case COLOR_BUFFER0:
224  return "Color 0";
225  case COLOR_BUFFER1:
226  return "Color 1";
227  case COLOR_BUFFER2:
228  return "Color 2";
229  case COLOR_BUFFER3:
230  return "Color 3";
231  case COLOR_BUFFER4:
232  return "Color 4";
233  case COLOR_BUFFER5:
234  return "Color 5";
235  case COLOR_BUFFER6:
236  return "Color 6";
237  case COLOR_BUFFER7:
238  return "Color 7";
239  case COLOR_BUFFER8:
240  return "Color 8";
241  case COLOR_BUFFER9:
242  return "Color 9";
243  case COLOR_BUFFER10:
244  return "Color 10";
245  case COLOR_BUFFER11:
246  return "Color 11";
247  case COLOR_BUFFER12:
248  return "Color 12";
249  case COLOR_BUFFER13:
250  return "Color 13";
251  case COLOR_BUFFER14:
252  return "Color 14";
253  case COLOR_BUFFER15:
254  return "Color 15";
255  default:
256  return "Unknown";
257  }
258 }
259 
Class for wrapping around the OSG Camera class.
Definition: WGECamera.h:36
std::string m_name
The name if the rendering pass.
osg::ref_ptr< WGETextureHud > m_hud
Gets notified about any added and removed attachment.
osg::ref_ptr< osg::Texture2D > createTexture(GLint internalFormat=GL_RGBA)
Creates a new texture suitable for this offscreen rendering instance.
osg::ref_ptr< osg::FrameBufferObject > m_fbo
The framebuffer object to use for this camera.
size_t m_height
The height of the textures used for this pass.
WGEOffscreenRenderPass(size_t textureWidth, size_t textureHeight, int num=0)
Creates a new offscreen rendering instance.
void attach(BufferComponent buffer, osg::ref_ptr< osg::Texture2D > texture)
Attach a given texture to a buffer.
void detach(BufferComponent buffer)
Detaches the texture currently bound to the specified buffer.
size_t m_width
The width of the textures used for this pass.
size_t getTextureWidth() const
Get the size of the underlying texture.
virtual void addUniform(osg::ref_ptr< osg::Uniform > uniform)
The uniform to add.
size_t getTextureHeight() const
Get the size of the underlying texture.
static std::string getBufferName(BufferComponent buffer)
Returns the buffer name.
virtual ~WGEOffscreenRenderPass()
Destructor.
std::string getName() const
Returns the name of this render pass.
Class implementing one texture HUD entry representing a texture in the HUD.
Definition: WGETextureHud.h:63
WStreamedLogger warn(const std::string &source)
Logging a warning message.
Definition: WLogger.h:309