LCOV - code coverage report
Current view: top level - eq/util - frameBufferObject.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 49 87 56.3 %
Date: 2014-06-18 Functions: 8 11 72.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2008-2009, Cedric Stalder <cedric.stalder@gmail.com>
       3             :  *               2009-2013, Stefan Eilemann <eile@equalizergraphics.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "frameBufferObject.h"
      20             : 
      21             : #include <eq/client/gl.h>
      22             : #include <eq/fabric/pixelViewport.h>
      23             : 
      24             : #ifdef _WIN32
      25             : #  define bzero( ptr, size ) memset( ptr, 0, size );
      26             : #endif
      27             : 
      28             : namespace eq
      29             : {
      30             : namespace util
      31             : {
      32             : 
      33          13 : FrameBufferObject::FrameBufferObject( const GLEWContext* glewContext,
      34             :                                       const GLenum textureTarget )
      35             :     : _fboID( 0 )
      36             :     , _depth( textureTarget, glewContext )
      37             :     , _glewContext( glewContext )
      38          13 :     , _valid( false )
      39             : {
      40          13 :     LBASSERT( GLEW_EXT_framebuffer_object );
      41          13 :     _colors.push_back( new Texture( textureTarget, glewContext ));
      42          13 : }
      43             : 
      44          26 : FrameBufferObject::~FrameBufferObject()
      45             : {
      46          13 :     exit();
      47          26 :     for( size_t i = 0; i < _colors.size(); ++i )
      48             :     {
      49          13 :         delete _colors[i];
      50          13 :         _colors[i] = 0;
      51             :     }
      52          13 : }
      53             : 
      54           0 : bool FrameBufferObject::addColorTexture()
      55             : {
      56           0 :     if( _colors.size() >= 16 )
      57             :     {
      58           0 :         LBWARN << "Too many color textures, can't add another one" << std::endl;
      59           0 :         return false;
      60             :     }
      61             : 
      62           0 :     _colors.push_back( new Texture(_colors.front()->getTarget(), _glewContext));
      63           0 :     _valid = false;
      64           0 :     return true;
      65             : }
      66             : 
      67          20 : Error FrameBufferObject::init( const int32_t width, const int32_t height,
      68             :                                const GLuint colorFormat,
      69             :                                const int32_t depthSize,
      70             :                                const int32_t stencilSize )
      71             : {
      72          20 :     LB_TS_THREAD( _thread );
      73             : 
      74          20 :     if( _fboID )
      75           7 :         return Error( ERROR_FRAMEBUFFER_INITIALIZED );
      76             : 
      77             :     // generate and bind the framebuffer
      78          13 :     glGenFramebuffersEXT( 1, &_fboID );
      79          13 :     glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID );
      80             : 
      81             :     // create and bind textures
      82          26 :     for( unsigned i = 0; i < _colors.size(); ++i )
      83             :     {
      84          13 :         _colors[i]->init( colorFormat, width, height );
      85          13 :         _colors[i]->bindToFBO( GL_COLOR_ATTACHMENT0 + i, width, height );
      86             :     }
      87          13 :     if( stencilSize > 0 && GLEW_EXT_packed_depth_stencil )
      88             :     {
      89          13 :         _depth.init( GL_DEPTH24_STENCIL8, width, height );
      90          13 :         _depth.bindToFBO( GL_DEPTH_STENCIL_ATTACHMENT, width, height );
      91             :     }
      92           0 :     else if( depthSize > 0 )
      93             :     {
      94           0 :         _depth.init( GL_DEPTH_COMPONENT, width, height );
      95           0 :         _depth.bindToFBO( GL_DEPTH_ATTACHMENT, width, height );
      96             :     }
      97             : 
      98          13 :     const Error error = _checkStatus();
      99          13 :     if( error )
     100           0 :         exit();
     101          13 :     return error;
     102             : }
     103             : 
     104          20 : void FrameBufferObject::exit()
     105             : {
     106          20 :     LB_TS_THREAD( _thread );
     107          20 :     if( _fboID )
     108             :     {
     109          13 :         glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 );
     110          13 :         glDeleteFramebuffersEXT( 1, &_fboID );
     111          13 :         _fboID = 0;
     112             :     }
     113             : 
     114          40 :     for( size_t i = 0; i < _colors.size(); ++i )
     115          20 :         _colors[i]->flush();
     116          20 :     _depth.flush();
     117             : 
     118          20 :     _valid = false;
     119          20 : }
     120             : 
     121          13 : Error FrameBufferObject::_checkStatus()
     122             : {
     123          13 :     _valid = false;
     124             : 
     125          13 :     const GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
     126          13 :     switch( status )
     127             :     {
     128             :     case GL_FRAMEBUFFER_COMPLETE_EXT:
     129          13 :         _valid = true;
     130          13 :         return Error( ERROR_NONE );
     131             : 
     132             :     case 0: // error?!
     133           0 :         EQ_GL_ERROR( "glCheckFramebufferStatusEXT" );
     134           0 :         return Error( ERROR_FRAMEBUFFER_STATUS );
     135             : 
     136             :     case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
     137           0 :         return Error( ERROR_FRAMEBUFFER_UNSUPPORTED );
     138             : 
     139             :     case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
     140           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT );
     141             : 
     142             :     case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
     143           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_ATTACHMENT );
     144             : 
     145             :     case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
     146           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_DIMENSIONS );
     147             : 
     148             :     case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
     149           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_FORMATS );
     150             : 
     151             :     case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
     152           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER );
     153             : 
     154             :     case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
     155           0 :         return Error( ERROR_FRAMEBUFFER_INCOMPLETE_READ_BUFFER );
     156             : 
     157             :     default:
     158           0 :         LBWARN << "Unhandled frame buffer status 0x" << std::hex
     159           0 :                << status << std::dec << std::endl;
     160           0 :         return Error( ERROR_FRAMEBUFFER_STATUS );
     161             :     }
     162             : }
     163             : 
     164           8 : void FrameBufferObject::bind()
     165             : {
     166           8 :     LB_TS_THREAD( _thread );
     167           8 :     LBASSERT( _fboID );
     168           8 :     EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, _fboID ));
     169           8 : }
     170             : 
     171           0 : void FrameBufferObject::unbind()
     172             : {
     173           0 :     EQ_GL_CALL( glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ));
     174           0 : }
     175             : 
     176           0 : Error FrameBufferObject::resize( const int32_t width, const int32_t height )
     177             : {
     178           0 :     LB_TS_THREAD( _thread );
     179           0 :     LBASSERT( width > 0 && height > 0 );
     180             : 
     181           0 :     LBASSERT( !_colors.empty( ));
     182           0 :     Texture* color = _colors.front();
     183             : 
     184           0 :     if( color->getWidth() == width && color->getHeight() == height && _valid )
     185           0 :         return Error( ERROR_NONE );
     186             : 
     187           0 :     for( size_t i = 0; i < _colors.size(); ++i )
     188           0 :         _colors[i]->resize( width, height );
     189             : 
     190           0 :     if ( _depth.isValid( ))
     191           0 :         _depth.resize( width, height );
     192             : 
     193           0 :     return _checkStatus();
     194             : }
     195             : 
     196             : }
     197          36 : }

Generated by: LCOV version 1.10