OpenWalnut  1.3.1
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  osg::Camera(),
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( osg::Camera::FRAME_BUFFER_OBJECT );
48  setRenderOrder( osg::Camera::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  osg::Camera(),
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( osg::Camera::FRAME_BUFFER_OBJECT );
65  setRenderOrder( osg::Camera::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  osg::Camera::attach( buffer, texture );
83 }
84 
85 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::attach( BufferComponent buffer, GLint internalFormat )
86 {
87  osg::ref_ptr< osg::Texture2D > tex;
88  if( buffer == DEPTH_BUFFER ) // depth buffers need a special texture type (else: FBO status = 0x8cd6 (FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT))
89  {
90  tex = createTexture( GL_DEPTH_COMPONENT );
91  }
92  else
93  {
94 #if defined(__APPLE__)
95  if( internalFormat != GL_RGBA )
96  {
97  wlog::warn( "WGEOffscreenRenderPass::attach:" ) <<
98  "Changing internal format to GL_RGBA because the original format is not supported on Mac OSX.";
99  }
100  tex = createTexture( GL_RGBA ); // on MacOS X, only RGBA textures work as attachment for FBO's
101 #else
102  tex = createTexture( internalFormat );
103 #endif
104  }
105  attach( buffer, tex );
106  return tex;
107 }
108 
109 void WGEOffscreenRenderPass::detach( BufferComponent buffer )
110 {
111  // remove the texture from HUD if existing
112  if( m_hud && osg::Camera::getBufferAttachmentMap().count( buffer ) )
113  {
114  m_hud->removeTexture( osg::Camera::getBufferAttachmentMap()[ buffer ]._texture );
115  }
116 
117  m_fbo->setAttachment( buffer, osg::FrameBufferAttachment() );
118 
119  osg::Camera::detach( buffer );
120 }
121 
122 osg::ref_ptr< osg::Texture2D > WGEOffscreenRenderPass::createTexture( GLint internalFormat )
123 {
124  osg::ref_ptr< osg::Texture2D > tex = new osg::Texture2D;
125  tex->setTextureSize( m_width, m_height );
126  tex->setInternalFormat( internalFormat );
127 
128  // setup interpolation
129  tex->setFilter( osg::Texture::MIN_FILTER, osg::Texture::LINEAR );
130  tex->setFilter( osg::Texture::MAG_FILTER, osg::Texture::LINEAR );
131 
132  // do repeat the texture
133  tex->setWrap( osg::Texture::WRAP_S, osg::Texture::REPEAT );
134  tex->setWrap( osg::Texture::WRAP_T, osg::Texture::REPEAT );
135 
136  return tex;
137 }
138 
140 {
141  return m_name;
142 }
143 
145 {
146  return m_width;
147 }
148 
150 {
151  return m_height;
152 }
153 
154 void WGEOffscreenRenderPass::addUniform( osg::ref_ptr< osg::Uniform > uniform )
155 {
156  this->getOrCreateStateSet()->addUniform( uniform );
157 }
158 
159 std::string WGEOffscreenRenderPass::getBufferName( BufferComponent buffer )
160 {
161  switch( buffer )
162  {
163  case DEPTH_BUFFER:
164  return "Depth";
165  case STENCIL_BUFFER:
166  return "Stencil";
167  case PACKED_DEPTH_STENCIL_BUFFER:
168  return "Depth+Stencil";
169  case COLOR_BUFFER:
170  return "Color 0";
171  case COLOR_BUFFER0:
172  return "Color 0";
173  case COLOR_BUFFER1:
174  return "Color 1";
175  case COLOR_BUFFER2:
176  return "Color 2";
177  case COLOR_BUFFER3:
178  return "Color 3";
179  case COLOR_BUFFER4:
180  return "Color 4";
181  case COLOR_BUFFER5:
182  return "Color 5";
183  case COLOR_BUFFER6:
184  return "Color 6";
185  case COLOR_BUFFER7:
186  return "Color 7";
187  case COLOR_BUFFER8:
188  return "Color 8";
189  case COLOR_BUFFER9:
190  return "Color 9";
191  case COLOR_BUFFER10:
192  return "Color 10";
193  case COLOR_BUFFER11:
194  return "Color 11";
195  case COLOR_BUFFER12:
196  return "Color 12";
197  case COLOR_BUFFER13:
198  return "Color 13";
199  case COLOR_BUFFER14:
200  return "Color 14";
201  case COLOR_BUFFER15:
202  return "Color 15";
203  default:
204  return "Unknown";
205  }
206 }
207