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
00017 class GLBuffer : public GLResource
00018 {
00019 protected:
00020 GLenum m_usage;
00021 unsigned int m_length;
00022 unsigned int m_count;
00023
00024
00025 GLBuffer( const GLBuffer& );
00026 GLBuffer& operator=( const GLBuffer& );
00027
00028
00029
00030
00031
00032
00033 GLBuffer( const GLenum target,
00034 const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00035 :
00036 GLResource(),
00037 m_usage(usage),
00038 m_length(length),
00039 m_count(count)
00040 {
00041 glGenBuffers(1, &m_name);
00042
00043 glBindBuffer(target, m_name);
00044 glBufferData(target, m_length, data, m_usage);
00045 }
00046
00047
00048 int clear( const GLenum target )
00049 {
00050 if(m_name == 0)
00051 return -1;
00052
00053 glBindBuffer(target, m_name);
00054 glBufferData(target, m_length, NULL, m_usage);
00055 return 0;
00056 }
00057
00058
00059
00060
00061 int update( const GLenum target,
00062 const unsigned long int offset, const unsigned long int length, const void *data )
00063 {
00064 if(m_name == 0)
00065 return -1;
00066 if(offset + length > m_length)
00067 return -1;
00068
00069 glBindBuffer(target, m_name);
00070 glBufferSubData(target, offset, length, data);
00071 return 0;
00072 }
00073
00074
00075
00076 void *map( const GLenum target,
00077 const unsigned long int offset, const unsigned int length, const GLbitfield access )
00078 {
00079 if(m_name == 0)
00080 return NULL;
00081 if(offset + length > m_length)
00082 {
00083 printf("GLBuffer::map( ): offset + length > buffer length\n");
00084 return NULL;
00085 }
00086
00087 glBindBuffer(target, m_name);
00088 return glMapBufferRange(target, offset, length, access);
00089 }
00090
00091 int unmap( const GLenum target )
00092 {
00093 if(m_name == 0)
00094 return -1;
00095
00096 glUnmapBuffer(target);
00097 return 0;
00098 }
00099
00100 int flush( const GLenum target,
00101 const unsigned long int offset, const unsigned int length )
00102 {
00103 if(m_name == 0)
00104 return -1;
00105 if(offset + length > m_length)
00106 {
00107 printf("GLBuffer::flush( ): offset + length > buffer length\n");
00108 return -1;
00109 }
00110
00111 glFlushMappedBufferRange(target, offset, length);
00112 return 0;
00113 }
00114
00115 public:
00116
00117 virtual ~GLBuffer( )
00118 {
00119 if(m_name != 0)
00120 glDeleteBuffers(1, &m_name);
00121 }
00122
00123
00124 int createGLResource( )
00125 {
00126 return (m_name != 0) ? 0 : -1;
00127 }
00128
00129
00130 int releaseGLResource( )
00131 {
00132 return (m_name != 0) ? 0 : -1;
00133 }
00134
00135
00136 unsigned int count( ) const
00137 {
00138 if(m_name == 0)
00139 return 0;
00140 return m_count;
00141 }
00142
00143
00144 unsigned long int length( ) const
00145 {
00146 return m_length;
00147 }
00148 };
00149
00150
00151 class GLAttributeBuffer : public GLBuffer
00152 {
00153 public:
00154
00155 GLAttributeBuffer( const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00156 :
00157 GLBuffer(GL_ARRAY_BUFFER, count, length, data, usage)
00158 {}
00159
00160
00161 ~GLAttributeBuffer( ) {}
00162
00163
00164 int clear( )
00165 {
00166 return GLBuffer::clear(GL_ARRAY_BUFFER);
00167 }
00168
00169
00170 int update( const unsigned long int offset, const unsigned long int length, const void *data )
00171 {
00172 return GLBuffer::update(GL_ARRAY_BUFFER, offset, length, data );
00173 }
00174
00175
00176
00177 void *map( const unsigned long int offset, const unsigned long int length, const GLbitfield access )
00178 {
00179 return GLBuffer::map(GL_ARRAY_BUFFER, offset, length, access );
00180 }
00181
00182
00183 int unmap( )
00184 {
00185 return GLBuffer::unmap(GL_ARRAY_BUFFER);
00186 }
00187
00188
00189 int flush( const unsigned long int offset, const unsigned long int length )
00190 {
00191 return GLBuffer::flush(GL_ARRAY_BUFFER, offset, length);
00192 }
00193 };
00194
00195 template < typename T >
00196 class ScopedMapAttributeBuffer
00197 {
00198 GLAttributeBuffer *m_buffer;
00199 T *m_begin;
00200 T *m_end;
00201
00202 ScopedMapAttributeBuffer( );
00203 ScopedMapAttributeBuffer( const ScopedMapAttributeBuffer& );
00204 ScopedMapAttributeBuffer& operator=( const ScopedMapAttributeBuffer& );
00205
00206 public:
00207
00208 ScopedMapAttributeBuffer( GLAttributeBuffer *buffer,
00209 GLbitfield access= GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,
00210 const unsigned long int offset= 0, const unsigned int _length= 0 )
00211 :
00212 m_buffer(buffer),
00213 m_begin(NULL),
00214 m_end(NULL)
00215 {
00216 if(m_buffer == NULL)
00217 return;
00218
00219 int length= (_length == 0) ? m_buffer->length() : _length;
00220 m_begin= (T *) m_buffer->map(offset, length, access);
00221 m_end= m_begin + length / sizeof(T);
00222 }
00223
00224 T& operator[] ( const unsigned int id )
00225 {
00226 assert(m_begin != NULL);
00227 assert(m_begin + id < m_end);
00228 return m_begin[id];
00229 }
00230
00231 ~ScopedMapAttributeBuffer( )
00232 {
00233 if(m_buffer == NULL)
00234 return;
00235 m_buffer->unmap();
00236 }
00237 };
00238
00239
00240
00241 class GLIndexBuffer : public GLBuffer
00242 {
00243 public:
00244 GLIndexBuffer( const unsigned int count, const unsigned int length, const void *data, const GLenum usage= GL_STATIC_DRAW )
00245 :
00246 GLBuffer(GL_ELEMENT_ARRAY_BUFFER, count, length, data, usage )
00247 {}
00248
00249 ~GLIndexBuffer( ) {}
00250
00251 int clear( )
00252 {
00253 return GLBuffer::clear(GL_ELEMENT_ARRAY_BUFFER);
00254 }
00255
00256 int update( const unsigned long int offset, const unsigned long int length, const void *data )
00257 {
00258 return GLBuffer::update(GL_ELEMENT_ARRAY_BUFFER, offset, length, data );
00259 }
00260
00261
00262 void *map( const unsigned long int offset, const unsigned long int length, const GLbitfield access )
00263 {
00264 return GLBuffer::map(GL_ELEMENT_ARRAY_BUFFER, offset, length, access );
00265 }
00266
00267 int unmap( )
00268 {
00269 return GLBuffer::unmap(GL_ELEMENT_ARRAY_BUFFER);
00270 }
00271
00272 int flush( const unsigned long int offset, const unsigned long int length )
00273 {
00274 return GLBuffer::flush(GL_ELEMENT_ARRAY_BUFFER, offset, length);
00275 }
00276 };
00277
00278
00279 template < typename T >
00280 class ScopedMapIndexBuffer
00281 {
00282 GLIndexBuffer *m_buffer;
00283 T *m_begin;
00284 T *m_end;
00285
00286 ScopedMapIndexBuffer( );
00287 ScopedMapIndexBuffer( const ScopedMapIndexBuffer& );
00288 ScopedMapIndexBuffer& operator=( const ScopedMapIndexBuffer& );
00289
00290 public:
00291
00292 ScopedMapIndexBuffer( GLIndexBuffer *buffer,
00293 GLbitfield access= GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_BUFFER_BIT,
00294 const unsigned long int offset= 0, const unsigned int _length= 0 )
00295 :
00296 m_buffer(buffer),
00297 m_begin(NULL),
00298 m_end(NULL)
00299 {
00300 if(m_buffer == NULL)
00301 return;
00302
00303 int length= (_length == 0) ? m_buffer->length() : _length;
00304 m_begin= (T *) m_buffer->map(offset, length, access);
00305 m_end= m_begin + length / sizeof(T);
00306 }
00307
00308 T& operator[] ( const unsigned int id )
00309 {
00310 assert(m_begin != NULL);
00311 assert(m_begin + id < m_end);
00312 return m_begin[id];
00313 }
00314
00315 ~ScopedMapIndexBuffer( )
00316 {
00317 if(m_buffer == NULL)
00318 return;
00319 m_buffer->unmap();
00320 }
00321 };
00322
00323 struct BufferLayout
00324 {
00325 int size;
00326 GLenum type;
00327 unsigned long int stride;
00328 unsigned long int offset;
00329 int divisor;
00330 bool normalize_flag;
00331 bool integer_flag;
00332
00333 enum
00334 {
00335 NORMALIZE_BIT= 1,
00336 INTEGER_BIT= 2
00337 };
00338
00339 BufferLayout( )
00340 :
00341 size(0),
00342 type(GL_NONE),
00343 stride(0),
00344 offset(0),
00345 divisor(0),
00346 normalize_flag(false),
00347 integer_flag(false)
00348 {}
00349
00350 BufferLayout( const int _size, const GLenum _type, const unsigned long int _stride= 0, const unsigned long int _offset= 0,
00351 const int _divisor= 0, const unsigned int flags= 0 )
00352 :
00353 size(_size),
00354 type(_type),
00355 stride(_stride),
00356 offset(_offset),
00357 divisor(_divisor),
00358 normalize_flag((flags & NORMALIZE_BIT)),
00359 integer_flag((flags & INTEGER_BIT))
00360 {}
00361
00362 bool operator== ( const BufferLayout& b )
00363 {
00364 if(stride != b.stride)
00365 return false;
00366 if(offset != b.offset)
00367 return false;
00368 if(size != b.size || type != b.type)
00369 return false;
00370 if(divisor != b.divisor)
00371 return false;
00372
00373 return true;
00374 }
00375
00376 bool operator!= ( const BufferLayout& b )
00377 {
00378 return !operator==(b);
00379 }
00380 };
00381
00382 }
00383
00384 #endif