accum.cpp

00001 
00002 /* Copyright (c) 2009-2010, Stefan Eilemann <eile@equalizergraphics.com>
00003  *               2009, Sarah Amsellem <sarah.amsellem@gmail.com>
00004  *
00005  * This library is free software; you can redistribute it and/or modify it under
00006  * the terms of the GNU Lesser General Public License version 2.1 as published
00007  * by the Free Software Foundation.
00008  *  
00009  * This library is distributed in the hope that it will be useful, but WITHOUT
00010  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00011  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00012  * details.
00013  * 
00014  * You should have received a copy of the GNU Lesser General Public License
00015  * along with this library; if not, write to the Free Software Foundation, Inc.,
00016  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00017  */
00018 
00019 #include "accumBufferObject.h"
00020 #include "accum.h"
00021 
00022 namespace eq
00023 {
00024 namespace util
00025 {
00026 
00027 Accum::Accum( GLEWContext* const glewContext )
00028     : _glewContext( glewContext )
00029     , _width( 0 )
00030     , _height( 0 )
00031     , _abo( 0 )
00032     , _numSteps( 0 )
00033     , _totalSteps( 0 )
00034 {
00035     EQASSERT( glewContext );
00036 }
00037 
00038 Accum::~Accum()
00039 {
00040     exit();
00041 }
00042 
00043 bool Accum::init( const PixelViewport& pvp, GLuint textureFormat )
00044 {
00045     if( usesFBO( ))
00046     {
00047         _abo = new AccumBufferObject( _glewContext );
00048         if( !_abo->init( pvp, textureFormat ))
00049         {
00050             delete _abo;
00051             _abo = 0;
00052             return false;
00053         }
00054     }
00055 
00056     if( _totalSteps == 0 )
00057         _totalSteps = getMaxSteps();
00058 
00059     _width = pvp.w;
00060     _height = pvp.h;
00061 
00062     return ( _totalSteps > 0 );
00063 }
00064 
00065 void Accum::exit()
00066 {
00067     clear();
00068 
00069     if( _abo )
00070         _abo->exit();
00071 
00072     delete _abo;
00073     _abo = 0;
00074 }
00075 
00076 void Accum::clear()
00077 {
00078     _numSteps = 0;
00079 }
00080 
00081 bool Accum::resize( const int width, const int height )
00082 {
00083     if( usesFBO( ))
00084     {
00085         const PixelViewport& pvp = _abo->getPixelViewport();
00086         if( pvp.w == width && pvp.h == height )
00087             return false;
00088 
00089         return _abo->resize( width, height );
00090     }
00091     
00092     if( width != _width || height != _height )
00093     {
00094         _width = width;
00095         _height = height;
00096         return true;
00097     }
00098 
00099     return false;
00100 }
00101 
00102 void Accum::accum()
00103 {
00104     EQASSERT( _numSteps < _totalSteps );
00105 
00106     if( _abo )
00107     {
00108         if( _numSteps == 0 )
00109             _abo->load( 1.0f );
00110         else
00111             _abo->accum( 1.0f );
00112     }
00113     else
00114     {
00115         // This is the only working implementation on MacOS found at the moment.
00116         // glAccum function seems to be implemented differently.
00117         if( _numSteps == 0 )
00118 #ifdef Darwin
00119             glAccum( GL_LOAD, 1.0f / _totalSteps );
00120 #else
00121             glAccum( GL_LOAD, 1.0f );
00122 #endif
00123         else
00124 #ifdef Darwin
00125             glAccum( GL_ACCUM, 1.0f / _totalSteps );
00126 #else
00127             glAccum( GL_ACCUM, 1.0f );
00128 #endif
00129     }
00130 
00131     ++_numSteps;
00132 }
00133 
00134 void Accum::display()
00135 {
00136     EQASSERT( _numSteps <= _totalSteps );
00137 
00138 
00139     if( _abo )
00140     {
00141         const float factor = 1.0f / _numSteps;
00142         _abo->display( factor );
00143     }
00144     else
00145     {
00146 #ifdef Darwin
00147         const float factor = static_cast<float>( _totalSteps ) / _numSteps;
00148 #else
00149         const float factor = 1.0f / _numSteps;
00150 #endif
00151         glAccum( GL_RETURN, factor );
00152     }
00153 }
00154 
00155 uint32_t Accum::getMaxSteps() const
00156 {
00157     if( usesFBO( ))
00158         return 256;
00159     
00160     GLint accumBits;
00161     glGetIntegerv( GL_ACCUM_RED_BITS, &accumBits );
00162 
00163     return accumBits >= 16 ? 256 : 0;
00164 }
00165 
00166 bool Accum::usesFBO() const
00167 {
00168     return usesFBO( glewGetContext( ));
00169 }
00170 
00171 #define glewGetContext() glewContext
00172 
00173 bool Accum::usesFBO( const GLEWContext* glewContext )
00174 {
00175 #ifdef Darwin
00176     return false;
00177 #else
00178     return ( GLEW_EXT_framebuffer_object &&
00179            ( GLEW_VERSION_3_0 || GLEW_ARB_texture_float ));
00180 #endif
00181 }
00182 
00183 #undef glewGetContext
00184 
00185 }
00186 }
00187 
Generated on Sat Feb 6 12:59:39 2010 for Equalizer 0.9.1 by  doxygen 1.6.1