frameBufferObject.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "frameBufferObject.h"
00020
00021 #ifdef WIN32
00022 # define bzero( ptr, size ) memset( ptr, 0, size );
00023 #endif
00024
00025 namespace eq
00026 {
00027
00028 FrameBufferObject::FrameBufferObject( GLEWContext* glewContext )
00029 : _fboID( 0 )
00030 , _width( 0 )
00031 , _height( 0 )
00032 , _depth( glewContext )
00033 , _stencil( glewContext )
00034 , _glewContext( glewContext )
00035 , _valid( false )
00036 {
00037 EQASSERT( GLEW_EXT_framebuffer_object );
00038
00039 _colors.push_back( new Texture( glewContext ));
00040
00041 _colors[0]->setFormat( GL_RGBA );
00042 _depth.setFormat( GL_DEPTH_COMPONENT );
00043 _stencil.setFormat( GL_STENCIL_INDEX );
00044 }
00045
00046 FrameBufferObject::~FrameBufferObject()
00047 {
00048 exit();
00049 for( size_t i = 0; i < _colors.size(); ++i )
00050 {
00051 delete _colors[i];
00052 _colors[i] = 0;
00053 }
00054 }
00055
00056 void FrameBufferObject::exit()
00057 {
00058 CHECK_THREAD( _thread );
00059 if( _fboID )
00060 {
00061 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00062 glDeleteFramebuffersEXT( 1, &_fboID );
00063 _fboID = 0;
00064 }
00065
00066 for( size_t i = 0; i < _colors.size(); ++i )
00067 _colors[i]->flush();
00068 _depth.flush();
00069 _stencil.flush();
00070 }
00071
00072 void FrameBufferObject::setColorFormat( const GLuint format )
00073 {
00074 for( size_t i = 0; i < _colors.size(); ++i )
00075 _colors[ i ]->setFormat( format );
00076 }
00077
00078 bool FrameBufferObject::addColorTexture( )
00079 {
00080 if( _colors.size() >= 16 )
00081 {
00082 EQERROR << "Too many color textures, can't add another one";
00083 return false;
00084 }
00085
00086 _colors.push_back( new Texture( _glewContext ));
00087 _colors.back()->setFormat( _colors.front()->getFormat( ));
00088
00089 _valid = false;
00090 return true;
00091 }
00092
00093 bool FrameBufferObject::init( const int width , const int height,
00094 const int depthSize, const int stencilSize )
00095 {
00096 CHECK_THREAD( _thread );
00097
00098 if( _fboID )
00099 {
00100 _error = "FBO already initialized";
00101 EQWARN << _error << std::endl;
00102 return false;
00103 }
00104
00105
00106 glGenFramebuffersEXT( 1, &_fboID );
00107 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID );
00108
00109
00110 for( size_t i = 0; i < _colors.size(); ++i )
00111 _colors[i]->bindToFBO( GL_COLOR_ATTACHMENT0 + i, width, height );
00112
00113 if ( depthSize > 0 )
00114 _depth.bindToFBO( GL_DEPTH_ATTACHMENT, width, height );
00115
00116
00117
00118
00119 _width = width;
00120 _height = height;
00121 _valid = true;
00122 return _checkFBOStatus();
00123 }
00124
00125 bool FrameBufferObject::_checkFBOStatus()
00126 {
00127 switch( glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ))
00128 {
00129 case GL_FRAMEBUFFER_COMPLETE_EXT:
00130 EQVERB << "FBO supported and complete" << std::endl;
00131 return true;
00132
00133 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
00134 _error = "Unsupported framebuffer format";
00135 break;
00136 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
00137 _error = "Framebuffer incomplete, missing attachment";
00138 break;
00139 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
00140 _error = "Framebuffer incomplete, incomplete attachment";
00141 break;
00142 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
00143 _error = "Framebuffer incomplete, \
00144 attached images must have same dimensions";
00145 break;
00146 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
00147 _error = "Framebuffer incomplete, \
00148 attached images must have same format";
00149 break;
00150 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
00151 _error = "Framebuffer incomplete, missing draw buffer";
00152 break;
00153 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
00154 _error = "Framebuffer incomplete, missing read buffer";
00155 break;
00156 default:
00157 break;
00158 }
00159
00160 EQERROR << _error << std::endl;
00161 return false;
00162 }
00163
00164 void FrameBufferObject::bind()
00165 {
00166 CHECK_THREAD( _thread );
00167 EQASSERT( _fboID );
00168 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID );
00169 }
00170
00171 void FrameBufferObject::unbind()
00172 {
00173 glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
00174 }
00175
00176 bool FrameBufferObject::resize( const int width, const int height )
00177 {
00178 CHECK_THREAD( _thread );
00179 EQASSERT( width > 0 && height > 0 );
00180
00181 if( _width == width && _height == height && _valid )
00182 return true;
00183
00184 for( size_t i = 0; i < _colors.size(); ++i )
00185 _colors[i]->resize( width, height );
00186
00187 if ( _depth.isValid( ))
00188 _depth.resize( width, height );
00189
00190 if ( _stencil.isValid( ))
00191 _stencil.resize( width, height );
00192
00193 _width = width;
00194 _height = height;
00195 _valid = true;
00196
00197 return _checkFBOStatus();
00198 }
00199
00200 PixelViewport FrameBufferObject::getPixelViewport() const
00201 {
00202 return PixelViewport( 0, 0, _width, _height );
00203 }
00204
00205 }
00206