gKitGL
TPBuffer.h
00001 
00002 #ifndef _TP_BUFFER_H
00003 #define _TP_BUFFER_H
00004 
00005 #include <cstdio>
00006 #include <cassert>
00007 
00008 #include "GL/GLPlatform.h"
00009 #include "GLResource.h"
00010 #include "GL/TPProgramName.h"
00011 #include "GL/TPAttributes.h"
00012 
00013 
00014 namespace gk {
00015 
00016 //! utilisation interne. representation d'un buffer openGL.
00017 class GLBuffer : public GLResource
00018 {
00019     // non copyable
00020     GLBuffer( const GLBuffer& );
00021     GLBuffer& operator=( const GLBuffer& );
00022     
00023 protected:
00024     GLenum m_usage;
00025     unsigned int m_length;
00026     unsigned int m_count;
00027     
00028 public:
00029     //! constructeur d'un buffer, un tableau de vecteurs de 'count' elements.
00030     //! \param count nombre de vecteurs,
00031     //! \param length longueur totale du buffer en OCTETS,
00032     //! \param data pointeur sur les donnees a transferer dans le buffer, ou NULL pour initialiser un buffer vide,
00033     //! \param usage decrit le type d'utilisation du buffer, cf glBufferData().
00034     GLBuffer( const GLenum target, 
00035         const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00036         :
00037         GLResource(),
00038         m_usage(usage),
00039         m_length(length),
00040         m_count(count)
00041     {
00042         glGenBuffers(1, &m_name);
00043         
00044         glBindBuffer(target, m_name);
00045         glBufferData(target, m_length, data, m_usage);
00046     }
00047 
00048     //! efface le contenu du buffer.
00049     int clear( const GLenum target )
00050     {
00051         if(m_name == 0)
00052             return -1;
00053         
00054         glBindBuffer(target, m_name);
00055         glBufferData(target, m_length, NULL, m_usage);
00056         
00057         //! \todo GL4.3 glInvalidateBufferData(m_mane);
00058         return 0;
00059     }
00060 
00061     //! modifie le contenu d'une partie du buffer.
00062     //! \param offset position du premier octet a modifier,
00063     //! \param length nombre d'octets a modifier.
00064     int update( const GLenum target, 
00065         const unsigned long int offset, const unsigned long int length, const void *data )
00066     {
00067         if(m_name == 0)
00068             return -1;
00069         if(offset + length > m_length)
00070             return -1;
00071         
00072         glBindBuffer(target, m_name);
00073         glBufferSubData(target, offset, length, data);
00074         return 0;
00075     }
00076     
00077     //! mappe le contenu du buffer en memoire host.
00078     //! cf. glMapBufferRange() pour les flags 'access'.
00079     void *map( const GLenum target, 
00080         const unsigned long int offset, const unsigned int length, const GLbitfield access )
00081     {
00082         if(m_name == 0)
00083             return NULL;
00084         if(offset + length > m_length)
00085         {
00086             printf("GLBuffer::map( ): offset + length > buffer length\n");
00087             return NULL;
00088         }
00089         
00090         glBindBuffer(target, m_name);
00091         return glMapBufferRange(target, offset, length, access);
00092     }
00093     
00094     int unmap( const GLenum target )
00095     {
00096         if(m_name == 0)
00097             return -1;
00098         glUnmapBuffer(target);
00099         return 0;
00100     }
00101     
00102     int flush( const GLenum target, 
00103         const unsigned long int offset, const unsigned int length )
00104     {
00105         if(m_name == 0)
00106             return -1;
00107         if(offset + length > m_length)
00108         {
00109             printf("GLBuffer::flush( ): offset + length > buffer length\n");
00110             return -1;
00111         }
00112         
00113         glFlushMappedBufferRange(target, offset, length);
00114         return 0;
00115     }
00116     
00117     
00118 public:
00119     //! destructeur.
00120     virtual ~GLBuffer( )
00121     {
00122         if(m_name != 0)
00123             glDeleteBuffers(1, &m_name);
00124     }
00125 
00126     //! creation de la ressource openGL.
00127     int createGLResource( )
00128     {
00129         return (m_name != 0) ? 0 : -1;
00130     }
00131 
00132     //! destruction de la ressource openGL.
00133     int releaseGLResource( )
00134     {
00135         return (m_name != 0) ? 0 : -1;
00136     }
00137 
00138     //! renvoie le nombre de vecteurs alloues (valeur passee au contructeur, cf GLBuffer()).
00139     unsigned int count( ) const
00140     {
00141         if(m_name == 0)
00142             return 0;
00143         return m_count;
00144     }
00145 
00146     //! renvoie le nombre d'octets alloues.
00147     unsigned long int length( ) const
00148     {
00149         return m_length;
00150     }
00151 };
00152 
00153 //! representation d'un buffer d'attribut.
00154 class GLAttributeBuffer : public GLBuffer
00155 {
00156 public:
00157     //! constructeur.
00158     GLAttributeBuffer( const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00159         :
00160         GLBuffer(GL_ARRAY_BUFFER, count, length, data, usage)
00161     {}
00162     
00163     //! destructeur.
00164     ~GLAttributeBuffer( ) {}
00165     
00166     //! renvoie l'identifiant des proprietes modifiees par le buffer.
00167     GLenum target( ) const
00168     {
00169         return GL_ARRAY_BUFFER;
00170     }
00171     
00172     //! efface le contenu du buffer.
00173     int clear( )
00174     {
00175         return GLBuffer::clear(GL_ARRAY_BUFFER);
00176     }
00177     
00178     //! remplace une partie de contenu du buffer.
00179     int update( const unsigned long int offset, const unsigned long int length, const void *data )
00180     {
00181         return GLBuffer::update(GL_ARRAY_BUFFER, offset, length, data );
00182     }
00183     
00184     //! mappe une partie du buffer en memoire centrale.
00185     //! cf. glMapBufferRange pour les flags 'access'.
00186     void *map( const unsigned long int offset, const unsigned long int length, const GLbitfield access )
00187     {
00188         return GLBuffer::map(GL_ARRAY_BUFFER, offset, length, access );
00189     }
00190     
00191     //! termine le mapping du contenu du buffer en memoire centrale, les donnees modifiees sont transferees sur le gpu.
00192     int unmap( )
00193     {
00194         return GLBuffer::unmap(GL_ARRAY_BUFFER);
00195     }
00196     
00197     //! termine une partie du mapping du contenu du buffer en memoire centrale, les donnees modifiiees sont transferees sur le gpu.
00198     int flush( const unsigned long int offset, const unsigned long int length )
00199     {
00200         return GLBuffer::flush(GL_ARRAY_BUFFER, offset, length);
00201     }
00202 };
00203 
00204 template < typename T >
00205 class ScopedMapAttributeBuffer
00206 {
00207     GLAttributeBuffer *m_buffer;
00208     T *m_begin;
00209     T *m_end;
00210     
00211     ScopedMapAttributeBuffer( );
00212     ScopedMapAttributeBuffer( const ScopedMapAttributeBuffer& );
00213     ScopedMapAttributeBuffer& operator=( const ScopedMapAttributeBuffer& );
00214     
00215 public:
00216     //! cf. glMapBufferRange pour les flags 'access'.
00217     ScopedMapAttributeBuffer( GLAttributeBuffer *buffer, 
00218         GLbitfield access= GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 
00219         const unsigned long int offset= 0, const unsigned int _length= 0 )
00220         :
00221         m_buffer(buffer),
00222         m_begin(NULL),
00223         m_end(NULL)
00224     {
00225         if(m_buffer == NULL)
00226             return;
00227         
00228         int length= (_length == 0) ? m_buffer->length() : _length;
00229         m_begin= (T *) m_buffer->map(offset, length, access);
00230         m_end= m_begin + length / sizeof(T);
00231     }
00232     
00233     T& operator[] ( const unsigned int id )
00234     {
00235         assert(m_begin != NULL);
00236         assert(m_begin + id < m_end);
00237         return m_begin[id];
00238     }
00239     
00240     ~ScopedMapAttributeBuffer( )
00241     {
00242         if(m_buffer == NULL)
00243             return;
00244         m_buffer->unmap();
00245     }
00246 };
00247 
00248 
00249 //! representation d'un buffer d'indexation.
00250 class GLIndexBuffer : public GLBuffer
00251 {
00252 public:
00253     GLIndexBuffer( const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00254         :
00255         GLBuffer(GL_ELEMENT_ARRAY_BUFFER, count, length, data, usage )
00256     {}
00257     
00258     ~GLIndexBuffer( ) {}
00259     
00260     //! renvoie l'identifiant des proprietes modifiees par le buffer.
00261     GLenum target( ) const
00262     {
00263         return GL_ELEMENT_ARRAY_BUFFER;
00264     }
00265     
00266     int clear( )
00267     {
00268         return GLBuffer::clear(GL_ELEMENT_ARRAY_BUFFER);
00269     }
00270     
00271     int update( const unsigned long int offset, const unsigned long int length, const void *data )
00272     {
00273         return GLBuffer::update(GL_ELEMENT_ARRAY_BUFFER, offset, length, data );
00274     }
00275     
00276     //! cf. glMapBufferRange pour les flags 'access'.
00277     void *map( const unsigned long int offset, const unsigned long int length, const GLbitfield access )
00278     {
00279         return GLBuffer::map(GL_ELEMENT_ARRAY_BUFFER, offset, length, access );
00280     }
00281     
00282     int unmap( )
00283     {
00284         return GLBuffer::unmap(GL_ELEMENT_ARRAY_BUFFER);
00285     }
00286     
00287     int flush( const unsigned long int offset, const unsigned long int length )
00288     {
00289         return GLBuffer::flush(GL_ELEMENT_ARRAY_BUFFER, offset, length);
00290     }
00291 };
00292 
00293 
00294 template < typename T >
00295 class ScopedMapIndexBuffer
00296 {
00297     GLIndexBuffer *m_buffer;
00298     T *m_begin;
00299     T *m_end;
00300     
00301     ScopedMapIndexBuffer( );
00302     ScopedMapIndexBuffer( const ScopedMapIndexBuffer& );
00303     ScopedMapIndexBuffer& operator=( const ScopedMapIndexBuffer& );
00304     
00305 public:
00306     //! cf. glMapBufferRange pour les flags 'access'.
00307     ScopedMapIndexBuffer( GLIndexBuffer *buffer, 
00308         GLbitfield access= GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT, 
00309         const unsigned long int offset= 0, const unsigned int _length= 0 )
00310         :
00311         m_buffer(buffer),
00312         m_begin(NULL),
00313         m_end(NULL)
00314     {
00315         if(m_buffer == NULL)
00316             return;
00317         
00318         int length= (_length == 0) ? m_buffer->length() : _length;
00319         m_begin= (T *) m_buffer->map(offset, length, access);
00320         m_end= m_begin + length / sizeof(T);
00321     }
00322     
00323     T& operator[] ( const unsigned int id )
00324     {
00325         assert(m_begin != NULL);
00326         assert(m_begin + id < m_end);
00327         return m_begin[id];
00328     }
00329     
00330     ~ScopedMapIndexBuffer( )
00331     {
00332         if(m_buffer == NULL)
00333             return;
00334         m_buffer->unmap();
00335     }
00336 };
00337 
00338 //! organisation des donnees (attributs/indices) dans un buffer
00339 struct BufferLayout
00340 {
00341     int size;
00342     GLenum type;
00343     unsigned long int stride;
00344     unsigned long int offset;
00345     unsigned long int length;
00346     int divisor;
00347     bool normalize_flag;
00348     bool integer_flag;
00349     
00350     enum
00351     {
00352         NORMALIZE_BIT= 1,
00353         INTEGER_BIT= 2
00354     };
00355     
00356     BufferLayout( )
00357         :
00358         size(0),
00359         type(GL_NONE),
00360         stride(0),
00361         offset(0),
00362         length(0),
00363         divisor(0),
00364         normalize_flag(false),
00365         integer_flag(false)
00366     {}
00367     
00368     BufferLayout( const int _size, const GLenum _type, const unsigned long int _stride, const unsigned long int _offset= 0, 
00369         const int _divisor= 0, const unsigned int flags= 0 )
00370         :
00371         size(_size),
00372         type(_type),
00373         stride(_stride),
00374         offset(_offset),
00375         length(0),
00376         divisor(_divisor),
00377         normalize_flag((flags & NORMALIZE_BIT)),
00378         integer_flag((flags & INTEGER_BIT))
00379     {
00380         assert(stride != 0);
00381     }
00382     
00383     const GLvoid *getOffset( const unsigned int begin= 0 )
00384     {
00385         return (const GLvoid *) (offset + begin * stride);
00386     }
00387     
00388     bool operator== ( const BufferLayout& b ) const
00389     {
00390         if(stride != b.stride)
00391             return false;
00392         if(offset != b.offset)
00393             return false;
00394         if(length != b.length)
00395             return false;
00396         if(size != b.size || type != b.type)
00397             return false;
00398         if(divisor != b.divisor)
00399             return false;
00400         
00401         return true;
00402     }
00403     
00404     bool operator!= ( const BufferLayout& b ) const
00405     {
00406         return !operator==(b);
00407     }
00408     
00409     friend bool less( const BufferLayout& a, const BufferLayout& b );
00410     bool operator< ( const BufferLayout& b ) const
00411     {
00412         return less(*this, b);
00413     }
00414 };
00415 
00416 inline
00417 bool less( const BufferLayout& a, const BufferLayout& b )
00418 {
00419     if(a.stride >= b.stride)
00420         return false;
00421     if(a.offset >= b.offset)
00422         return false;
00423     if(a.length >= b.length)
00424         return false;
00425     if(a.size >= b.size)
00426         return false;
00427     if(a.type >= b.type)
00428         return false;
00429     if(a.divisor >= b.divisor)
00430         return false;
00431     
00432     return true;
00433 }
00434 
00435 
00436 //! organisation d'uniforms dans un buffer
00437 struct BufferRange
00438 {
00439     unsigned long int offset;
00440     unsigned long int length;
00441 };
00442 
00443 
00444 //! representation d'un vertex attrib array, 
00445 //! necessaire en core profile pour stocker l'association des attributs du shader program et du contenu des vertex buffers.
00446 class GLVertexArray : public GLResource
00447 {
00448     // non copyable
00449     GLVertexArray( const GLVertexArray& );
00450     GLVertexArray& operator= ( const GLVertexArray& );
00451     
00452 public:
00453     GLVertexArray( )
00454         :
00455         GLResource()
00456     {
00457         glGenVertexArrays(1, &m_name);
00458         glBindVertexArray(m_name);
00459     }
00460     
00461     ~GLVertexArray( )
00462     {
00463         glDeleteVertexArrays(1, &m_name);
00464     }
00465     
00466     int createGLResource( )
00467     {
00468         return (m_name != 0) ? 0 : -1;
00469     }
00470     
00471     int releaseGLResource( )
00472     {
00473         return (m_name != 0) ? 0 : -1;    
00474     }
00475 };
00476 
00477 }
00478 
00479 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends