1 #ifndef __GPU__VBO_H__
2 #define __GPU__VBO_H__
3 
4 
5 
6 
7 #include "InstantiatedObject.h"
8 
9 
10 // Macro enabling to recover the offset, in bytes, of a field in a structure.
11 #ifdef OffsetOf
12 #undef OffsetOf
13 #endif
14 #define OffsetOf( STRUCT, FIELD )   ( (unsigned int) &((STRUCT*)NULL)->FIELD )
15 
16 
17 namespace GPU
18 {
19     // Class used to stop recursive template inheritance of class VBO.
20     class DefaultVBO
21     {
22     public:
Alloc()23         inline bool Alloc()     { return true; }
Destroy()24         inline bool Destroy()   { return true; }
Bind()25         inline void Bind()      {}
Unbind()26         inline void Unbind()    {}
Enable()27         inline void Enable()    {}
Disable()28         inline void Disable()   {}
29     };
30 
31 
32     // Class defining a VBO's component without a neutral behaviour. Necessary for recursive template inheritance
33     // with an arbitrary number of unordered parameters.
34     template <typename TStoreMode,typename T>
35     class DefaultVBOComponent : public T
36     {
37     public:
Alloc()38         inline bool Alloc()     { return T::Alloc(); }
Destroy()39         inline bool Destroy()   { return T::Destroy(); }
Bind()40         inline void Bind()      { T::Bind(); }
Unbind()41         inline void Unbind()    { T::Unbind(); }
Enable()42         inline void Enable()    { T::Enable(); }
Disable()43         inline void Disable()   { T::Disable(); }
44     };
45 
46 
47     class InterlacedBuffers {};
48     class DistinctBuffers   {};
49 
50 
51 
52 
53     template < typename TStoreMode,
54                template <typename,typename> class A = DefaultVBOComponent,
55                template <typename,typename> class B = DefaultVBOComponent,
56                template <typename,typename> class C = DefaultVBOComponent,
57                template <typename,typename> class D = DefaultVBOComponent,
58                template <typename,typename> class E = DefaultVBOComponent,
59                template <typename,typename> class F = DefaultVBOComponent,
60                template <typename,typename> class G = DefaultVBOComponent,
61                template <typename,typename> class H = DefaultVBOComponent > class VBO;
62 
63 
64     template < template <typename,typename> class A,
65                template <typename,typename> class B,
66                template <typename,typename> class C,
67                template <typename,typename> class D,
68                template <typename,typename> class E,
69                template <typename,typename> class F,
70                template <typename,typename> class G,
71                template <typename,typename> class H >
72     class VBO<InterlacedBuffers,A,B,C,D,E,F,G,H> : public H< InterlacedBuffers,
73                                                           G< InterlacedBuffers,
74                                                           F< InterlacedBuffers,
75                                                           E< InterlacedBuffers,
76                                                           D< InterlacedBuffers,
77                                                           C< InterlacedBuffers,
78                                                           B< InterlacedBuffers,
79                                                           A< InterlacedBuffers,DefaultVBO >>>>>>>>,
80                                                    public InstantiatedObject
81     {
82     private:
83         typedef H< InterlacedBuffers,
84                 G< InterlacedBuffers,
85                 F< InterlacedBuffers,
86                 E< InterlacedBuffers,
87                 D< InterlacedBuffers,
88                 C< InterlacedBuffers,
89                 B< InterlacedBuffers,
90                 A< InterlacedBuffers,DefaultVBO >>>>>>>>  Super;
91 
92         GLuint  m_DataVBOId;
93 
94     protected:
Allocate()95         inline bool Allocate()
96         {
97             glGenBuffersARB( 1, &m_DataVBOId );
98             glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
99             glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
100             return m_DataVBOId!=0 && Super::Alloc();
101         }
Unallocate()102         inline bool Unallocate()
103         {
104             glDeleteBuffersARB( 1, &m_DataVBOId );
105             m_DataVBOId = 0;
106             return Super::Destroy();
107         }
108 
109     public:
VBO()110         inline      VBO() : InstantiatedObject(), m_DataVBOId(0)    {}
~VBO()111         inline      ~VBO()                                          { Release(); }
112 
Create()113         inline bool Create()    { return Instantiate(); }
114         template <typename T>
Create(GLenum usage,T * buffer,GLsizei count)115         inline bool Create( GLenum usage, T *buffer, GLsizei count )
116         {
117             return Instantiate() && LoadData( usage, buffer, count );
118         }
119 
120         template <typename T>
LoadData(GLenum usage,T * buffer,GLsizei count)121         inline bool LoadData( GLenum usage, T *buffer, GLsizei count )
122         {
123             if( m_DataVBOId )
124             {
125                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
126                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, count*sizeof(T), buffer, usage );
127                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
128                 return true;
129             }
130             return false;
131         }
132 
Bind()133         inline void Bind()
134         {
135             glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
136             if( m_DataVBOId )
137             {
138                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
139                 Super::Bind();
140             }
141         }
Unbind()142         inline void Unbind()
143         {
144             Super::Unbind();
145             glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
146             glPopClientAttrib();
147         }
148 
DrawArrays(GLenum mode,GLint first,GLsizei count)149         inline void DrawArrays( GLenum mode, GLint first, GLsizei count )   { glDrawArrays( mode, first, count ); }
150     };
151 
152 
153     template < template <typename,typename> class A,
154                template <typename,typename> class B,
155                template <typename,typename> class C,
156                template <typename,typename> class D,
157                template <typename,typename> class E,
158                template <typename,typename> class F,
159                template <typename,typename> class G,
160                template <typename,typename> class H >
161     class VBO<DistinctBuffers,A,B,C,D,E,F,G,H> : public H< DistinctBuffers,
162                                                         G< DistinctBuffers,
163                                                         F< DistinctBuffers,
164                                                         E< DistinctBuffers,
165                                                         D< DistinctBuffers,
166                                                         C< DistinctBuffers,
167                                                         B< DistinctBuffers,
168                                                         A< DistinctBuffers,DefaultVBO >>>>>>>>,
169                                                  public InstantiatedObject
170     {
171     private:
172         typedef H< DistinctBuffers,
173                 G< DistinctBuffers,
174                 F< DistinctBuffers,
175                 E< DistinctBuffers,
176                 D< DistinctBuffers,
177                 C< DistinctBuffers,
178                 B< DistinctBuffers,
179                 A< DistinctBuffers,DefaultVBO >>>>>>>>  Super;
180 
181     protected:
Allocate()182         inline bool Allocate()                      { return Super::Alloc();   }
Unallocate()183         inline bool Unallocate()                    { return Super::Destroy(); }
184 
185     public:
VBO()186         inline      VBO() : InstantiatedObject()    {}
~VBO()187         inline      ~VBO()                          { Release(); }
188 
Create()189         inline bool Create()                        { return Instantiate(); }
190 
Bind()191         inline void Bind()
192         {
193             glPushClientAttrib( GL_CLIENT_VERTEX_ARRAY_BIT );
194             Super::Bind();
195         }
Unbind()196         inline void Unbind()
197         {
198             Super::Unbind();
199             glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
200             glPopClientAttrib();
201         }
202 
DrawArrays(GLenum mode,GLint first,GLsizei count)203         inline void DrawArrays( GLenum mode, GLint first, GLsizei count )   { glDrawArrays( mode, first, count ); }
204     };
205 
206 
207 
208 
209     template <typename TStoreMode> class VBOComponentContainer;
210 
211 
212     template <>
213     class VBOComponentContainer<InterlacedBuffers>
214     {
215         static const GLuint ENABLE_MASK = 1 << (8*sizeof(GLuint) - 1);
216         static const GLuint STRIDE_MASK = ((GLuint)-1) ^ ENABLE_MASK;
217 
218     private:
219         GLuint          m_StrideEnable;
220         GLuint          m_Offset;
221 
222     public:
VBOComponentContainer()223         inline          VBOComponentContainer() : m_StrideEnable(0), m_Offset(0)   {}
224 
SetPointer(GLuint stride,GLuint offset)225         inline void     SetPointer( GLuint stride, GLuint offset )
226         {
227             m_StrideEnable = stride | (m_StrideEnable & ENABLE_MASK);
228             m_Offset = offset;
229         }
Stride()230         inline GLuint   Stride() const                                  { return m_StrideEnable & STRIDE_MASK; }
Offset()231         inline GLuint   Offset() const                                  { return m_Offset; }
232 
Alloc()233         inline bool     Alloc()                                         { return true; }
Destroy()234         inline bool     Destroy()                                       { return true; }
Bind()235         inline void     Bind()                                          {}
Unbind()236         inline void     Unbind()                                        {}
237 
IsEnabled()238         inline bool     IsEnabled() const                               { return (m_StrideEnable & ENABLE_MASK) == 0; }
IsDisabled()239         inline bool     IsDisabled() const                              { return !IsEnabled(); }
Enable()240         inline void     Enable()                                        { m_StrideEnable &= STRIDE_MASK; }
Disable()241         inline void     Disable()                                       { m_StrideEnable |= ENABLE_MASK; }
242     };
243 
244 
245     template <>
246     class VBOComponentContainer<DistinctBuffers> : public VBOComponentContainer<InterlacedBuffers>
247     {
248     private:
249         GLuint      m_DataVBOId;
250 
251     public:
VBOComponentContainer()252         inline      VBOComponentContainer() : VBOComponentContainer<InterlacedBuffers>(), m_DataVBOId(0)  {}
253 
Alloc()254         inline bool Alloc()
255         {
256             glGenBuffersARB( 1, &m_DataVBOId );
257             glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
258             glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
259             return m_DataVBOId!=0;
260         }
Destroy()261         inline bool Destroy()
262         {
263             glDeleteBuffersARB( 1, &m_DataVBOId );
264             m_DataVBOId = 0;
265             return true;
266         }
Bind()267         inline void Bind()
268         {
269             if( m_DataVBOId )
270                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
271         }
Unbind()272         inline void Unbind()    {}
273 
274         template <typename T>
LoadData(GLenum usage,T * buffer,GLsizei count)275         inline bool LoadData( GLenum usage, T *buffer, GLsizei count )
276         {
277             if( m_DataVBOId )
278             {
279                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_DataVBOId );
280                 glBufferDataARB( GL_ARRAY_BUFFER_ARB, count*sizeof(T), buffer, usage );
281                 glBindBufferARB( GL_ARRAY_BUFFER_ARB, 0 );
282                 return true;
283             }
284             return false;
285         }
286     };
287 
288 
289 
290 
291     template <typename TStoreMode,int TSize,int TGLType,typename T>
292     class VertexVBOComponent : public T
293     {
294     public:
295         VBOComponentContainer<TStoreMode>  Vertex;
Alloc()296         inline bool Alloc()     { return Vertex.Alloc() && T::Alloc(); }
Destroy()297         inline bool Destroy()   { return Vertex.Destroy() && T::Destroy(); }
Bind()298         inline void Bind()
299         {
300             if( Vertex.IsEnabled() )
301             {
302                 Vertex.Bind();
303                 glEnableClientState( GL_VERTEX_ARRAY );
304                 glVertexPointer( TSize, TGLType, Vertex.Stride(), (const GLvoid*)(Vertex.Offset()) );
305             }
306             T::Bind();
307         }
Unbind()308         inline void Unbind()    { Vertex.Unbind(); T::Unbind(); }
Enable()309         inline void Enable()    { Vertex.Enable(); T::Enable(); }
Disable()310         inline void Disable()   { Vertex.Disable(); T::Disable(); }
311     };
312 
313     template <typename TStoreMode,typename T> class Vertex2s : public VertexVBOComponent<TStoreMode,2,GL_SHORT ,T> {};
314     template <typename TStoreMode,typename T> class Vertex2i : public VertexVBOComponent<TStoreMode,2,GL_INT   ,T> {};
315     template <typename TStoreMode,typename T> class Vertex2f : public VertexVBOComponent<TStoreMode,2,GL_FLOAT ,T> {};
316     template <typename TStoreMode,typename T> class Vertex2d : public VertexVBOComponent<TStoreMode,2,GL_DOUBLE,T> {};
317     template <typename TStoreMode,typename T> class Vertex3s : public VertexVBOComponent<TStoreMode,3,GL_SHORT ,T> {};
318     template <typename TStoreMode,typename T> class Vertex3i : public VertexVBOComponent<TStoreMode,3,GL_INT   ,T> {};
319     template <typename TStoreMode,typename T> class Vertex3f : public VertexVBOComponent<TStoreMode,3,GL_FLOAT ,T> {};
320     template <typename TStoreMode,typename T> class Vertex3d : public VertexVBOComponent<TStoreMode,3,GL_DOUBLE,T> {};
321     template <typename TStoreMode,typename T> class Vertex4s : public VertexVBOComponent<TStoreMode,4,GL_SHORT ,T> {};
322     template <typename TStoreMode,typename T> class Vertex4i : public VertexVBOComponent<TStoreMode,4,GL_INT   ,T> {};
323     template <typename TStoreMode,typename T> class Vertex4f : public VertexVBOComponent<TStoreMode,4,GL_FLOAT ,T> {};
324     template <typename TStoreMode,typename T> class Vertex4d : public VertexVBOComponent<TStoreMode,4,GL_DOUBLE,T> {};
325 
326 
327     template <typename TStoreMode,int TGLType,typename T>
328     class NormalVBOComponent : public T
329     {
330     public:
331         VBOComponentContainer<TStoreMode>  Normal;
Alloc()332         inline bool Alloc()     { return Normal.Alloc() && T::Alloc(); }
Destroy()333         inline bool Destroy()   { return Normal.Destroy() && T::Destroy(); }
Bind()334         inline void Bind()
335         {
336             if( Normal.IsEnabled() )
337             {
338                 Normal.Bind();
339                 glEnableClientState( GL_NORMAL_ARRAY );
340                 glNormalPointer( TGLType, Normal.Stride(), (const GLvoid*)(Normal.Offset()) );
341             }
342             T::Bind();
343         }
Unbind()344         inline void Unbind()    { Normal.Unbind(); T::Unbind(); }
Enable()345         inline void Enable()    { Normal.Enable(); T::Enable(); }
Disable()346         inline void Disable()   { Normal.Disable(); T::Disable(); }
347     };
348 
349     template <typename TStoreMode,typename T> class Normal3b : public NormalVBOComponent<typename TStoreMode,GL_BYTE  ,T> {};
350     template <typename TStoreMode,typename T> class Normal3s : public NormalVBOComponent<typename TStoreMode,GL_SHORT ,T> {};
351     template <typename TStoreMode,typename T> class Normal3i : public NormalVBOComponent<typename TStoreMode,GL_INT   ,T> {};
352     template <typename TStoreMode,typename T> class Normal3f : public NormalVBOComponent<typename TStoreMode,GL_FLOAT ,T> {};
353     template <typename TStoreMode,typename T> class Normal3d : public NormalVBOComponent<typename TStoreMode,GL_DOUBLE,T> {};
354 
355 
356     template <typename TStoreMode,int TSize,int TGLType,typename T>
357     class ColorVBOComponent : public T
358     {
359     public:
360         VBOComponentContainer<TStoreMode>  Color;
Alloc()361         inline bool Alloc()     { return Color.Alloc() && T::Alloc(); }
Destroy()362         inline bool Destroy()   { return Color.Destroy() && T::Destroy(); }
Bind()363         inline void Bind()
364         {
365             if( Color.IsEnabled() )
366             {
367                 Color.Bind();
368                 glEnableClientState( GL_COLOR_ARRAY );
369                 glColorPointer( TSize, TGLType, Color.Stride(), (const GLvoid*)(Color.Offset()) );
370             }
371             T::Bind();
372         }
Unbind()373         inline void Unbind()    { Color.Unbind(); T::Unbind(); }
Enable()374         inline void Enable()    { Color.Enable(); T::Enable(); }
Disable()375         inline void Disable()   { Color.Disable(); T::Disable(); }
376     };
377 
378     template <typename TStoreMode,typename T> class Color3b  : public ColorVBOComponent<typename TStoreMode,3,GL_BYTE          ,T> {};
379     template <typename TStoreMode,typename T> class Color3ub : public ColorVBOComponent<typename TStoreMode,3,GL_UNSIGNED_BYTE ,T> {};
380     template <typename TStoreMode,typename T> class Color3s  : public ColorVBOComponent<typename TStoreMode,3,GL_SHORT         ,T> {};
381     template <typename TStoreMode,typename T> class Color3us : public ColorVBOComponent<typename TStoreMode,3,GL_UNSIGNED_SHORT,T> {};
382     template <typename TStoreMode,typename T> class Color3i  : public ColorVBOComponent<typename TStoreMode,3,GL_INT           ,T> {};
383     template <typename TStoreMode,typename T> class Color3ui : public ColorVBOComponent<typename TStoreMode,3,GL_UNSIGNED_INT  ,T> {};
384     template <typename TStoreMode,typename T> class Color3f  : public ColorVBOComponent<typename TStoreMode,3,GL_FLOAT         ,T> {};
385     template <typename TStoreMode,typename T> class Color3d  : public ColorVBOComponent<typename TStoreMode,3,GL_DOUBLE        ,T> {};
386     template <typename TStoreMode,typename T> class Color4b  : public ColorVBOComponent<typename TStoreMode,4,GL_BYTE          ,T> {};
387     template <typename TStoreMode,typename T> class Color4ub : public ColorVBOComponent<typename TStoreMode,4,GL_UNSIGNED_BYTE ,T> {};
388     template <typename TStoreMode,typename T> class Color4s  : public ColorVBOComponent<typename TStoreMode,4,GL_SHORT         ,T> {};
389     template <typename TStoreMode,typename T> class Color4us : public ColorVBOComponent<typename TStoreMode,4,GL_UNSIGNED_SHORT,T> {};
390     template <typename TStoreMode,typename T> class Color4i  : public ColorVBOComponent<typename TStoreMode,4,GL_INT           ,T> {};
391     template <typename TStoreMode,typename T> class Color4ui : public ColorVBOComponent<typename TStoreMode,4,GL_UNSIGNED_INT  ,T> {};
392     template <typename TStoreMode,typename T> class Color4f  : public ColorVBOComponent<typename TStoreMode,4,GL_FLOAT         ,T> {};
393     template <typename TStoreMode,typename T> class Color4d  : public ColorVBOComponent<typename TStoreMode,4,GL_DOUBLE        ,T> {};
394 
395 
396     template <typename TStoreMode,int TSize,int TGLType,typename T>
397     class TexCoordVBOComponent : public T
398     {
399     public:
400         VBOComponentContainer<TStoreMode>  TexCoord;
Alloc()401         inline bool Alloc()     { return TexCoord.Alloc() && T::Alloc(); }
Destroy()402         inline bool Destroy()   { return TexCoord.Destroy() && T::Destroy(); }
Bind()403         inline void Bind()
404         {
405             if( TexCoord.IsEnabled() )
406             {
407                 TexCoord.Bind();
408                 glEnableClientState( GL_TEXTURE_COORD_ARRAY );
409                 glTexCoordPointer( TSize, TGLType, TexCoord.Stride(), (const GLvoid*)(TexCoord.Offset()) );
410             }
411             T::Bind();
412         }
Unbind()413         inline void Unbind()    { TexCoord.Unbind(); T::Unbind(); }
Enable()414         inline void Enable()    { TexCoord.Enable(); T::Enable(); }
Disable()415         inline void Disable()   { TexCoord.Disable(); T::Disable(); }
416     };
417 
418     template <typename TStoreMode,typename T> class TexCoord1s : public TexCoordVBOComponent<typename TStoreMode,1,GL_SHORT ,T> {};
419     template <typename TStoreMode,typename T> class TexCoord1i : public TexCoordVBOComponent<typename TStoreMode,1,GL_INT   ,T> {};
420     template <typename TStoreMode,typename T> class TexCoord1f : public TexCoordVBOComponent<typename TStoreMode,1,GL_FLOAT ,T> {};
421     template <typename TStoreMode,typename T> class TexCoord1d : public TexCoordVBOComponent<typename TStoreMode,1,GL_DOUBLE,T> {};
422     template <typename TStoreMode,typename T> class TexCoord2s : public TexCoordVBOComponent<typename TStoreMode,2,GL_SHORT ,T> {};
423     template <typename TStoreMode,typename T> class TexCoord2i : public TexCoordVBOComponent<typename TStoreMode,2,GL_INT   ,T> {};
424     template <typename TStoreMode,typename T> class TexCoord2f : public TexCoordVBOComponent<typename TStoreMode,2,GL_FLOAT ,T> {};
425     template <typename TStoreMode,typename T> class TexCoord2d : public TexCoordVBOComponent<typename TStoreMode,2,GL_DOUBLE,T> {};
426     template <typename TStoreMode,typename T> class TexCoord3s : public TexCoordVBOComponent<typename TStoreMode,3,GL_SHORT ,T> {};
427     template <typename TStoreMode,typename T> class TexCoord3i : public TexCoordVBOComponent<typename TStoreMode,3,GL_INT   ,T> {};
428     template <typename TStoreMode,typename T> class TexCoord3f : public TexCoordVBOComponent<typename TStoreMode,3,GL_FLOAT ,T> {};
429     template <typename TStoreMode,typename T> class TexCoord3d : public TexCoordVBOComponent<typename TStoreMode,3,GL_DOUBLE,T> {};
430     template <typename TStoreMode,typename T> class TexCoord4s : public TexCoordVBOComponent<typename TStoreMode,4,GL_SHORT ,T> {};
431     template <typename TStoreMode,typename T> class TexCoord4i : public TexCoordVBOComponent<typename TStoreMode,4,GL_INT   ,T> {};
432     template <typename TStoreMode,typename T> class TexCoord4f : public TexCoordVBOComponent<typename TStoreMode,4,GL_FLOAT ,T> {};
433     template <typename TStoreMode,typename T> class TexCoord4d : public TexCoordVBOComponent<typename TStoreMode,4,GL_DOUBLE,T> {};
434 
435 
436     template <typename TRealType,int TGLType,typename T>
437     class IndexVBOComponent : public T
438     {
439     private:
440         GLuint  m_IndexVBOId;
441 
442     public:
Alloc()443         inline bool Alloc()
444         {
445             glGenBuffersARB( 1, &m_IndexVBOId );
446             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_IndexVBOId );
447             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
448             return m_IndexVBOId!=0 && T::Alloc();
449         }
Destroy()450         inline bool Destroy()
451         {
452             glDeleteBuffersARB( 1, &m_IndexVBOId );
453             m_IndexVBOId = 0;
454             return T::Destroy();
455         }
456 
Bind()457         inline void Bind()
458         {
459             if( m_IndexVBOId )
460                 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_IndexVBOId );
461             T::Bind();
462         }
Unbind()463         inline void Unbind()
464         {
465             glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
466             T::Unbind();
467         }
468 
LoadIndices(GLenum usage,TRealType * buffer,GLsizei count)469         inline bool LoadIndices( GLenum usage, TRealType *buffer, GLsizei count )
470         {
471             if( m_IndexVBOId )
472             {
473                 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, m_IndexVBOId );
474                 glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, count*sizeof(TRealType), buffer, usage );
475                 glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, 0 );
476                 return true;
477             }
478             return false;
479         }
480 
DrawElements(GLenum mode,GLint first,GLsizei count)481         inline void DrawElements( GLenum mode, GLint first, GLsizei count )
482         {
483             glDrawElements(	mode, count, TGLType, (const GLvoid*)(first*sizeof(TRealType)) );
484         }
485     };
486 
487     template <typename TStoreMode,typename T> class Indexub : public IndexVBOComponent<GLubyte ,GL_UNSIGNED_BYTE ,T> {};
488     template <typename TStoreMode,typename T> class Indexus : public IndexVBOComponent<GLushort,GL_UNSIGNED_SHORT,T> {};
489     template <typename TStoreMode,typename T> class Indexui : public IndexVBOComponent<GLuint  ,GL_UNSIGNED_INT  ,T> {};
490 }; // namespace GPU
491 
492 
493 
494 
495 #endif /*__GPU__VBO_H__*/
496