objectManager.cpp

00001 
00002 /* Copyright (c) 2007-2009, Stefan Eilemann <eile@equalizergraphics.com> 
00003  *
00004  * This library is free software; you can redistribute it and/or modify it under
00005  * the terms of the GNU Lesser General Public License version 2.1 as published
00006  * by the Free Software Foundation.
00007  *  
00008  * This library is distributed in the hope that it will be useful, but WITHOUT
00009  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00010  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00011  * details.
00012  * 
00013  * You should have received a copy of the GNU Lesser General Public License
00014  * along with this library; if not, write to the Free Software Foundation, Inc.,
00015  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00016  */
00017 
00018 #include "objectManager.h"
00019 
00020 #include "frameBufferObject.h"
00021 #include "texture.h"
00022 
00023 #include <string.h>
00024 
00025 using namespace eq;
00026 using namespace std;
00027 using namespace stde;
00028 
00029 // instantiate desired key types -- see end of file
00030 
00031 template< typename T >
00032 ObjectManager< T >::ObjectManager( GLEWContext* const glewContext )
00033         : _glewContext( glewContext )
00034         , _data( new SharedData )
00035 {
00036     EQASSERT( glewContext );
00037 }
00038 
00039 template< typename T >
00040 ObjectManager< T >::ObjectManager( GLEWContext* const glewContext, 
00041                               ObjectManager* shared )
00042         : _glewContext( glewContext )
00043         , _data( shared->_data )
00044 {
00045     EQASSERT( glewContext );
00046 }
00047 
00048 template< typename T >
00049 ObjectManager<T>::~ObjectManager()
00050 {
00051     _data = 0;
00052 }
00053 
00054 template< typename T >
00055 ObjectManager<T>::SharedData::~SharedData()
00056 {
00057     // Do not delete GL objects, we may no longer have a GL context.
00058     if( !lists.empty( ))
00059         EQWARN << lists.size() 
00060                << " lists still allocated in ObjectManager destructor" << endl;
00061     lists.clear();
00062 
00063     if( !textures.empty( ))
00064         EQWARN << textures.size() 
00065                << " textures still allocated in ObjectManager destructor" 
00066                << endl;
00067     textures.clear();
00068 
00069     if( !buffers.empty( ))
00070         EQWARN << buffers.size() 
00071                << " buffers still allocated in ObjectManager destructor" 
00072                << endl;
00073     buffers.clear();
00074 
00075     if( !programs.empty( ))
00076         EQWARN << programs.size() 
00077                << " programs still allocated in ObjectManager destructor" 
00078                << endl;
00079     programs.clear();
00080 
00081     if( !shaders.empty( ))
00082         EQWARN << shaders.size() 
00083                << " shaders still allocated in ObjectManager destructor" 
00084                << endl;
00085     shaders.clear();
00086 
00087     if( !eqTextures.empty( ))
00088         EQWARN << eqTextures.size() 
00089                << " eq::Texture's still allocated in ObjectManager destructor" 
00090                << endl;
00091     eqTextures.clear();
00092 
00093     if( !eqFrameBufferObjects.empty( ))
00094         EQWARN << eqFrameBufferObjects.size() 
00095                << " eq::FrameBufferObject's still allocated in ObjectManager "
00096                << "destructor" << endl;
00097     eqFrameBufferObjects.clear();
00098 }
00099 
00100 template< typename T >
00101 void ObjectManager<T>::deleteAll()
00102 {
00103    for( typename ObjectHash::const_iterator i = _data->lists.begin(); 
00104          i != _data->lists.end(); ++i )
00105     {
00106         const Object& object = i->second;
00107         EQVERB << "Delete list " << object.id << endl;
00108         glDeleteLists( object.id, object.num ); 
00109     }
00110     _data->lists.clear();
00111 
00112     for( typename ObjectHash::const_iterator i = _data->textures.begin(); 
00113          i != _data->textures.end(); ++i )
00114     {
00115         const Object& object = i->second;
00116         EQVERB << "Delete texture " << object.id << endl;
00117         glDeleteTextures( 1, &object.id ); 
00118     }
00119     _data->textures.clear();
00120 
00121     for( typename ObjectHash::const_iterator i = _data->buffers.begin(); 
00122          i != _data->buffers.end(); ++i )
00123     {
00124         const Object& object = i->second;
00125         EQVERB << "Delete buffer " << object.id << endl;
00126         glDeleteBuffers( 1, &object.id ); 
00127     }
00128     _data->buffers.clear();
00129 
00130     for( typename ObjectHash::const_iterator i = _data->programs.begin(); 
00131          i != _data->programs.end(); ++i )
00132     {
00133         const Object& object = i->second;
00134         EQVERB << "Delete program " << object.id << endl;
00135         glDeleteProgram( object.id ); 
00136     }
00137     _data->programs.clear();
00138 
00139     for( typename ObjectHash::const_iterator i = _data->shaders.begin(); 
00140          i != _data->shaders.end(); ++i )
00141     {
00142         const Object& object = i->second;
00143         EQVERB << "Delete shader " << object.id << endl;
00144         glDeleteShader( object.id ); 
00145     }
00146     _data->shaders.clear();
00147 
00148     for( typename TextureHash::const_iterator i = _data->eqTextures.begin(); 
00149          i != _data->eqTextures.end(); ++i )
00150     {
00151         Texture* texture = i->second;
00152         EQVERB << "Delete eq::Texture " << i->first << " @" << (void*)texture
00153                << endl;
00154         texture->flush();
00155         delete texture;
00156     }
00157     _data->eqTextures.clear();
00158 
00159     for( typename FrameBufferObjectHash::const_iterator i = 
00160              _data->eqFrameBufferObjects.begin();
00161          i != _data->eqFrameBufferObjects.end(); ++i )
00162     {
00163         FrameBufferObject* frameBufferObject = i->second;
00164         EQVERB << "Delete eq::FrameBufferObject " << i->first << " @" 
00165                << (void*)frameBufferObject << endl;
00166         frameBufferObject->exit();
00167         delete frameBufferObject;
00168     }
00169     _data->eqFrameBufferObjects.clear();
00170 }
00171 
00172 // display list functions
00173 
00174 template< typename T >
00175 GLuint ObjectManager<T>::getList( const T& key )
00176 {
00177     if( _data->lists.find( key ) == _data->lists.end( ))
00178         return INVALID;
00179 
00180     const Object& object = _data->lists[ key ];
00181     return object.id;
00182 }
00183 
00184 template< typename T >
00185 GLuint ObjectManager<T>::newList( const T& key, const GLsizei num )
00186 {
00187     if( _data->lists.find( key ) != _data->lists.end( ))
00188     {
00189         EQWARN << "Requested new list for existing key" << endl;
00190         return INVALID;
00191     }
00192 
00193     const GLuint id = glGenLists( num );
00194     if( !id )
00195     {
00196         EQWARN << "glGenLists failed: " << glGetError() << endl;
00197         return INVALID;
00198     }
00199     
00200     Object& object   = _data->lists[ key ];
00201     object.id        = id;
00202     object.num       = num;
00203 
00204     return id;
00205 }
00206 
00207 template< typename T >
00208 GLuint ObjectManager<T>::obtainList( const T& key, const GLsizei num )
00209 {
00210     const GLuint id = getList( key );
00211     if( id != INVALID )
00212         return id;
00213     return newList( key, num );
00214 }
00215 
00216 template< typename T >
00217 void   ObjectManager<T>::deleteList( const T& key )
00218 {
00219     if( _data->lists.find( key ) == _data->lists.end( ))
00220         return;
00221 
00222     const Object& object = _data->lists[ key ];
00223     glDeleteLists( object.id, object.num );
00224     _data->lists.erase( key );
00225 }
00226 
00227 // texture object functions
00228 
00229 template< typename T >
00230 GLuint ObjectManager<T>::getTexture( const T& key )
00231 {
00232     if( _data->textures.find( key ) == _data->textures.end( ))
00233         return INVALID;
00234 
00235     const Object& object = _data->textures[ key ];
00236     return object.id;
00237 }
00238 
00239 template< typename T >
00240 GLuint ObjectManager<T>::newTexture( const T& key )
00241 {
00242     if( _data->textures.find( key ) != _data->textures.end( ))
00243     {
00244         EQWARN << "Requested new texture for existing key" << endl;
00245         return INVALID;
00246     }
00247 
00248     GLuint id = INVALID;
00249     glGenTextures( 1, &id );
00250     if( id == INVALID )
00251     {
00252         EQWARN << "glGenTextures failed: " << glGetError() << endl;
00253         return INVALID;
00254     }
00255     
00256     Object& object   = _data->textures[ key ];
00257     object.id        = id;
00258     return id;
00259 }
00260 
00261 template< typename T >
00262 GLuint ObjectManager<T>::obtainTexture( const T& key )
00263 {
00264     const GLuint id = getTexture( key );
00265     if( id != INVALID )
00266         return id;
00267     return newTexture( key );
00268 }
00269 
00270 template< typename T >
00271 void   ObjectManager<T>::deleteTexture( const T& key )
00272 {
00273     if( _data->textures.find( key ) == _data->textures.end( ))
00274         return;
00275 
00276     const Object& object = _data->textures[ key ];
00277     glDeleteTextures( 1, &object.id );
00278     _data->textures.erase( key );
00279 }
00280 
00281 // buffer object functions
00282 
00283 template< typename T >
00284 bool ObjectManager<T>::supportsBuffers() const
00285 {
00286     return ( GLEW_VERSION_1_5 );
00287 }
00288 
00289 template< typename T >
00290 GLuint ObjectManager<T>::getBuffer( const T& key )
00291 {
00292     if( _data->buffers.find( key ) == _data->buffers.end() )
00293         return INVALID;
00294 
00295     const Object& object = _data->buffers[ key ];
00296     return object.id;
00297 }
00298 
00299 template< typename T >
00300 GLuint ObjectManager<T>::newBuffer( const T& key )
00301 {
00302     if( !GLEW_VERSION_1_5 )
00303     {
00304         EQWARN << "glGenBuffers not available" << endl;
00305         return INVALID;
00306     }
00307 
00308     if( _data->buffers.find( key ) != _data->buffers.end() )
00309     {
00310         EQWARN << "Requested new buffer for existing key" << endl;
00311         return INVALID;
00312     }
00313 
00314     GLuint id = INVALID;
00315     glGenBuffers( 1, &id );
00316 
00317     if( id == INVALID )
00318     {
00319         EQWARN << "glGenBuffers failed: " << glGetError() << endl;
00320         return INVALID;
00321     }
00322     
00323     Object& object     = _data->buffers[ key ];
00324     object.id          = id;
00325     return id;
00326 }
00327 
00328 template< typename T >
00329 GLuint ObjectManager<T>::obtainBuffer( const T& key )
00330 {
00331     const GLuint id = getBuffer( key );
00332     if( id != INVALID )
00333         return id;
00334     return newBuffer( key );
00335 }
00336 
00337 template< typename T >
00338 void ObjectManager<T>::deleteBuffer( const T& key )
00339 {
00340     if( _data->buffers.find( key ) == _data->buffers.end() )
00341         return;
00342 
00343     const Object& object = _data->buffers[ key ];
00344     glDeleteBuffers( 1, &object.id );
00345     _data->buffers.erase( key );
00346 }
00347 
00348 // program object functions
00349 
00350 template< typename T >
00351 bool ObjectManager<T>::supportsPrograms() const
00352 {
00353     return ( GLEW_VERSION_2_0 );
00354 }
00355 
00356 template< typename T >
00357 GLuint ObjectManager<T>::getProgram( const T& key )
00358 {
00359     if( _data->programs.find( key ) == _data->programs.end() )
00360         return INVALID;
00361 
00362     const Object& object = _data->programs[ key ];
00363     return object.id;
00364 }
00365 
00366 template< typename T >
00367 GLuint ObjectManager<T>::newProgram( const T& key )
00368 {
00369     if( !GLEW_VERSION_2_0 )
00370     {
00371         EQWARN << "glCreateProgram not available" << endl;
00372         return INVALID;
00373     }
00374 
00375     if( _data->programs.find( key ) != _data->programs.end() )
00376     {
00377         EQWARN << "Requested new program for existing key" << endl;
00378         return INVALID;
00379     }
00380 
00381     const GLuint id = glCreateProgram();
00382     if( !id )
00383     {
00384         EQWARN << "glCreateProgram failed: " << glGetError() << endl;
00385         return INVALID;
00386     }
00387     
00388     Object& object     = _data->programs[ key ];
00389     object.id          = id;
00390     return id;
00391 }
00392 
00393 template< typename T >
00394 GLuint ObjectManager<T>::obtainProgram( const T& key )
00395 {
00396     const GLuint id = getProgram( key );
00397     if( id != INVALID )
00398         return id;
00399     return newProgram( key );
00400 }
00401 
00402 template< typename T >
00403 void ObjectManager<T>::deleteProgram( const T& key )
00404 {
00405     if( _data->programs.find( key ) == _data->programs.end() )
00406         return;
00407 
00408     const Object& object = _data->programs[ key ];
00409     glDeleteProgram( object.id );
00410     _data->programs.erase( key );
00411 }
00412 
00413 // shader object functions
00414 
00415 template< typename T >
00416 bool ObjectManager<T>::supportsShaders() const
00417 {
00418     return ( GLEW_VERSION_2_0 );
00419 }
00420 
00421 template< typename T >
00422 GLuint ObjectManager<T>::getShader( const T& key )
00423 {
00424     if( _data->shaders.find( key ) == _data->shaders.end() )
00425         return INVALID;
00426 
00427     const Object& object = _data->shaders[ key ];
00428     return object.id;
00429 }
00430 
00431 template< typename T >
00432 GLuint ObjectManager<T>::newShader( const T& key, const GLenum type )
00433 {
00434     if( !GLEW_VERSION_2_0 )
00435     {
00436         EQWARN << "glCreateShader not available" << endl;
00437         return INVALID;
00438     }
00439 
00440     if( _data->shaders.find( key ) != _data->shaders.end() )
00441     {
00442         EQWARN << "Requested new shader for existing key" << endl;
00443         return INVALID;
00444     }
00445 
00446     const GLuint id = glCreateShader( type );
00447     if( !id )
00448     {
00449         EQWARN << "glCreateShader failed: " << glGetError() << endl;
00450         return INVALID;
00451     }
00452 
00453     
00454     Object& object     = _data->shaders[ key ];
00455     object.id          = id;
00456     return id;
00457 }
00458 
00459 template< typename T >
00460 GLuint ObjectManager<T>::obtainShader( const T& key, const GLenum type )
00461 {
00462     const GLuint id = getShader( key );
00463     if( id != INVALID )
00464         return id;
00465     return newShader( key, type );
00466 }
00467 
00468 template< typename T >
00469 void ObjectManager<T>::deleteShader( const T& key )
00470 {
00471     if( _data->shaders.find( key ) == _data->shaders.end() )
00472         return;
00473 
00474     const Object& object = _data->shaders[ key ];
00475     glDeleteShader( object.id );
00476     _data->shaders.erase( key );
00477 }
00478 
00479 // eq::Texture object functions
00480 template< typename T >
00481 bool ObjectManager<T>::supportsEqTexture() const
00482 {
00483     return (GLEW_ARB_texture_rectangle);
00484 }
00485 
00486 template< typename T >
00487 Texture* ObjectManager<T>::getEqTexture( const T& key )
00488 {
00489     if( _data->eqTextures.find( key ) == _data->eqTextures.end( ))
00490         return 0;
00491 
00492     return _data->eqTextures[ key ];
00493 }
00494 
00495 template< typename T >
00496 Texture* ObjectManager<T>::newEqTexture( const T& key )
00497 {
00498     if( _data->eqTextures.find( key ) != _data->eqTextures.end( ))
00499     {
00500         EQWARN << "Requested new eqTexture for existing key" << endl;
00501         return 0;
00502     }
00503 
00504     Texture* texture = new Texture( _glewContext );
00505     _data->eqTextures[ key ] = texture;
00506     return texture;
00507 }
00508 
00509 template< typename T >
00510 Texture* ObjectManager<T>::obtainEqTexture( const T& key )
00511 {
00512     Texture* texture = getEqTexture( key );
00513     if( texture )
00514         return texture;
00515     return newEqTexture( key );
00516 }
00517 
00518 template< typename T >
00519 void   ObjectManager<T>::deleteEqTexture( const T& key )
00520 {
00521     if( _data->eqTextures.find( key ) == _data->eqTextures.end( ))
00522         return;
00523 
00524     Texture* texture = _data->eqTextures[ key ];
00525     _data->eqTextures.erase( key );
00526 
00527     texture->flush();
00528     delete texture;
00529 }
00530 
00531 // eq::FrameBufferObject object functions
00532 template< typename T >
00533 bool ObjectManager<T>::supportsEqFrameBufferObject() const
00534 {
00535     return (GLEW_EXT_framebuffer_object);
00536 }
00537 
00538 template< typename T >
00539 FrameBufferObject* ObjectManager<T>::getEqFrameBufferObject( const T& key )
00540 {
00541     if( _data->eqFrameBufferObjects.find( key ) == _data->eqFrameBufferObjects.end( ))
00542         return 0;
00543 
00544     return _data->eqFrameBufferObjects[ key ];
00545 }
00546 
00547 template< typename T >
00548 FrameBufferObject* ObjectManager<T>::newEqFrameBufferObject( const T& key )
00549 {
00550     if( _data->eqFrameBufferObjects.find( key ) != _data->eqFrameBufferObjects.end( ))
00551     {
00552         EQWARN << "Requested new eqFrameBufferObject for existing key" << endl;
00553         return 0;
00554     }
00555 
00556     FrameBufferObject* frameBufferObject = new FrameBufferObject( _glewContext );
00557     _data->eqFrameBufferObjects[ key ] = frameBufferObject;
00558     return frameBufferObject;
00559 }
00560 
00561 template< typename T >
00562 FrameBufferObject* ObjectManager<T>::obtainEqFrameBufferObject( const T& key )
00563 {
00564     FrameBufferObject* frameBufferObject = getEqFrameBufferObject( key );
00565     if( frameBufferObject )
00566         return frameBufferObject;
00567     return newEqFrameBufferObject( key );
00568 }
00569 
00570 template< typename T >
00571 void ObjectManager<T>::deleteEqFrameBufferObject( const T& key )
00572 {
00573     if( _data->eqFrameBufferObjects.find( key ) == _data->eqFrameBufferObjects.end( ))
00574         return;
00575 
00576     FrameBufferObject* frameBufferObject = _data->eqFrameBufferObjects[ key ];
00577     _data->eqFrameBufferObjects.erase( key );
00578 
00579     frameBufferObject->exit();
00580     delete frameBufferObject;
00581 }
00582 
00583 // instantiate desired key types
00584 //   Instantiation has to be explicit to have all instantiations in the client
00585 //   library, due to the way the heap is handled with Win32 dll's.
00586 template class ObjectManager< const void* >;
Generated on Mon Aug 10 18:58:40 2009 for Equalizer 0.9 by  doxygen 1.5.8