00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #pragma once
00024
00025 #include "cinder/gl/gl.h"
00026 #include "cinder/TriMesh.h"
00027
00028 #include <vector>
00029 #include <utility>
00030
00031 namespace cinder { namespace gl {
00032
00033 class Vbo {
00034 public:
00035 Vbo() {}
00036 Vbo( GLenum aTarget );
00037
00038 void bind();
00039 void unbind();
00040
00041 void bufferData( size_t size, const void *data, GLenum usage );
00042 void bufferSubData( ptrdiff_t offset, size_t size, const void *data );
00043
00044 uint8_t* map( GLenum access );
00045 void unmap();
00046
00047 GLenum getTarget() const { return mObj->mTarget; }
00048 GLuint getId() const { return mObj->mId; }
00049
00050 protected:
00051 struct Obj {
00052 Obj( GLenum aTarget );
00053 ~Obj();
00054
00055 GLenum mTarget;
00056 GLuint mId;
00057 };
00058
00059 std::shared_ptr<Obj> mObj;
00060
00061 public:
00063
00064 typedef std::shared_ptr<Obj> Vbo::*unspecified_bool_type;
00065 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &Vbo::mObj; }
00066 void reset() { mObj.reset(); }
00068 };
00069
00070 class VboMesh {
00071 public:
00072 enum { NONE, STATIC, DYNAMIC };
00073 enum { ATTR_INDICES, ATTR_POSITIONS, ATTR_NORMALS, ATTR_COLORS_RGB, ATTR_COLORS_RGBA, ATTR_TEXCOORDS2D_0, ATTR_TEXCOORDS2D_1, ATTR_TEXCOORDS2D_2, ATTR_TEXCOORDS2D_3, ATTR_TEXCOORDS3D_0, ATTR_TEXCOORDS3D_1, ATTR_TEXCOORDS3D_2, ATTR_TEXCOORDS3D_3, ATTR_TOTAL };
00074 enum { ATTR_MAX_TEXTURE_UNIT = 3 };
00075
00076 struct Layout {
00077 Layout() { initAttributes(); }
00078
00080 bool isDefaults() const { for( int a = 0; a < ATTR_TOTAL; ++a ) if( mAttributes[a] != NONE ) return false; return true; }
00081
00082 bool hasNormals() const { return hasDynamicNormals() || hasStaticNormals(); }
00083 bool hasStaticNormals() const { return mAttributes[ATTR_NORMALS] == STATIC; }
00084 bool hasDynamicNormals() const { return mAttributes[ATTR_NORMALS] == DYNAMIC; }
00085 void setStaticNormals() { mAttributes[ATTR_NORMALS] = STATIC; }
00086 void setDynamicNormals() { mAttributes[ATTR_NORMALS] = DYNAMIC; }
00087
00088 bool hasColorsRGB() const { return hasDynamicColorsRGB() || hasStaticColorsRGB(); }
00089 bool hasStaticColorsRGB() const { return mAttributes[ATTR_COLORS_RGB] == STATIC; }
00090 bool hasDynamicColorsRGB() const { return mAttributes[ATTR_COLORS_RGB] == DYNAMIC; }
00091 void setStaticColorsRGB() { mAttributes[ATTR_COLORS_RGB] = STATIC; mAttributes[ATTR_COLORS_RGBA] = NONE; }
00092 void setDynamicColorsRGB() { mAttributes[ATTR_COLORS_RGB] = DYNAMIC; mAttributes[ATTR_COLORS_RGBA] = NONE; }
00093
00094 bool hasColorsRGBA() const { return hasDynamicColorsRGBA() || hasStaticColorsRGBA(); }
00095 bool hasStaticColorsRGBA() const { return mAttributes[ATTR_COLORS_RGBA] == STATIC; }
00096 bool hasDynamicColorsRGBA() const { return mAttributes[ATTR_COLORS_RGBA] == DYNAMIC; }
00097 void setStaticColorsRGBA() { mAttributes[ATTR_COLORS_RGBA] = STATIC; mAttributes[ATTR_COLORS_RGB] = NONE; }
00098 void setDynamicColorsRGBA() { mAttributes[ATTR_COLORS_RGBA] = DYNAMIC; mAttributes[ATTR_COLORS_RGB] = NONE; }
00099
00100 bool hasTexCoords2d( size_t unit = 0 ) const { return hasDynamicTexCoords2d( unit ) || hasStaticTexCoords2d( unit ); }
00101 bool hasStaticTexCoords2d( size_t unit = 0 ) const { return mAttributes[ATTR_TEXCOORDS2D_0 + unit] == STATIC; }
00102 bool hasDynamicTexCoords2d( size_t unit = 0 ) const { return mAttributes[ATTR_TEXCOORDS2D_0 + unit] == DYNAMIC; }
00103 void setStaticTexCoords2d( size_t unit = 0 ) { mAttributes[ATTR_TEXCOORDS2D_0 + unit] = STATIC; mAttributes[ATTR_TEXCOORDS3D_0 + unit] = NONE; }
00104 void setDynamicTexCoords2d( size_t unit = 0 ) { mAttributes[ATTR_TEXCOORDS2D_0 + unit] = DYNAMIC; mAttributes[ATTR_TEXCOORDS3D_0 + unit] = NONE; }
00106 bool hasStaticTexCoords() const;
00108 bool hasDynamicTexCoords() const;
00110 bool hasTexCoords( size_t unit ) const { return ( mAttributes[ATTR_TEXCOORDS2D_0 + unit] != NONE ) || ( mAttributes[ATTR_TEXCOORDS3D_0 + unit] != NONE ); }
00111
00112 bool hasTexCoords3d( size_t unit = 0 ) const { return hasDynamicTexCoords3d( unit ) || hasStaticTexCoords3d( unit ); }
00113 bool hasStaticTexCoords3d( size_t unit = 0 ) const { return mAttributes[ATTR_TEXCOORDS3D_0 + unit] == STATIC; }
00114 bool hasDynamicTexCoords3d( size_t unit = 0 ) const { return mAttributes[ATTR_TEXCOORDS3D_0 + unit] == DYNAMIC; }
00115 void setStaticTexCoords3d( size_t unit = 0 ) { mAttributes[ATTR_TEXCOORDS3D_0 + unit] = STATIC; mAttributes[ATTR_TEXCOORDS2D_0 + unit] = NONE; }
00116 void setDynamicTexCoords3d( size_t unit = 0 ) { mAttributes[ATTR_TEXCOORDS3D_0 + unit] = DYNAMIC; mAttributes[ATTR_TEXCOORDS2D_0 + unit] = NONE; }
00117
00118 bool hasIndices() const { return hasStaticIndices() || hasDynamicIndices(); }
00119 bool hasStaticIndices() const { return mAttributes[ATTR_INDICES] == STATIC; }
00120 bool hasDynamicIndices() const { return mAttributes[ATTR_INDICES] == DYNAMIC; }
00121 void setStaticIndices() { mAttributes[ATTR_INDICES] = STATIC; }
00122 void setDynamicIndices() { mAttributes[ATTR_INDICES] = DYNAMIC; }
00123
00124 bool hasPositions() const { return hasStaticPositions() || hasDynamicPositions(); }
00125 bool hasStaticPositions() const { return mAttributes[ATTR_POSITIONS] == STATIC; }
00126 bool hasDynamicPositions() const { return mAttributes[ATTR_POSITIONS] == DYNAMIC; }
00127 void setStaticPositions() { mAttributes[ATTR_POSITIONS] = STATIC; }
00128 void setDynamicPositions() { mAttributes[ATTR_POSITIONS] = DYNAMIC; }
00129
00130 enum CustomAttr { CUSTOM_ATTR_FLOAT, CUSTOM_ATTR_FLOAT2, CUSTOM_ATTR_FLOAT3, CUSTOM_ATTR_FLOAT4, TOTAL_CUSTOM_ATTR_TYPES };
00131 static int sCustomAttrSizes[TOTAL_CUSTOM_ATTR_TYPES];
00132 static GLint sCustomAttrNumComponents[TOTAL_CUSTOM_ATTR_TYPES];
00133 static GLenum sCustomAttrTypes[TOTAL_CUSTOM_ATTR_TYPES];
00134 void addDynamicCustomFloat() { mCustomDynamic.push_back( std::make_pair( CUSTOM_ATTR_FLOAT, 0 ) ); }
00135 void addDynamicCustomVec2f() { mCustomDynamic.push_back( std::make_pair( CUSTOM_ATTR_FLOAT2, 0 ) ); }
00136 void addDynamicCustomVec3f() { mCustomDynamic.push_back( std::make_pair( CUSTOM_ATTR_FLOAT3, 0 ) ); }
00137 void addDynamicCustomVec4f() { mCustomDynamic.push_back( std::make_pair( CUSTOM_ATTR_FLOAT4, 0 ) ); }
00138
00139 int mAttributes[ATTR_TOTAL];
00140 std::vector<std::pair<CustomAttr,size_t> > mCustomDynamic, mCustomStatic;
00141
00142 private:
00143 void initAttributes() { for( int a = 0; a < ATTR_TOTAL; ++a ) mAttributes[a] = NONE; }
00144 };
00145
00146 enum { INDEX_BUFFER = 0, STATIC_BUFFER, DYNAMIC_BUFFER, TOTAL_BUFFERS };
00147
00148 protected:
00149 struct Obj {
00150 size_t mNumIndices, mNumVertices;
00151
00152 Vbo mBuffers[TOTAL_BUFFERS];
00153 size_t mPositionOffset;
00154 size_t mNormalOffset;
00155 size_t mColorRGBOffset, mColorRGBAOffset;
00156 size_t mTexCoordOffset[ATTR_MAX_TEXTURE_UNIT+1];
00157 size_t mStaticStride, mDynamicStride;
00158 GLenum mPrimitiveType;
00159 Layout mLayout;
00160 std::vector<GLint> mCustomStaticLocations;
00161 std::vector<GLint> mCustomDynamicLocations;
00162 };
00163
00164 public:
00165 class VertexIter;
00166
00167 VboMesh() {}
00168 explicit VboMesh( const TriMesh &triMesh, Layout layout = Layout() );
00169 explicit VboMesh( const TriMesh2d &triMesh, Layout layout = Layout() );
00170
00171 VboMesh( size_t numVertices, size_t numIndices, Layout layout, GLenum primitiveType );
00172
00173 VboMesh( size_t numVertices, size_t numIndices, Layout layout, GLenum primitiveType, Vbo *indexBuffer, Vbo *staticBuffer, Vbo *dynamicBuffer );
00174
00175 size_t getNumIndices() const { return mObj->mNumIndices; }
00176 size_t getNumVertices() const { return mObj->mNumVertices; }
00177 GLenum getPrimitiveType() const { return mObj->mPrimitiveType; }
00178
00179 const Layout& getLayout() const { return mObj->mLayout; }
00180
00181 void bindIndexBuffer() const;
00182 void enableClientStates() const;
00183 void disableClientStates() const;
00184 void bindAllData() const;
00185 static void unbindBuffers();
00186
00187 void bufferIndices( const std::vector<uint32_t> &indices );
00188 void bufferPositions( const std::vector<Vec3f> &positions );
00189 void bufferPositions( const Vec3f *positions, size_t count );
00190 void bufferNormals( const std::vector<Vec3f> &normals );
00191 void bufferTexCoords2d( size_t unit, const std::vector<Vec2f> &texCoords );
00192 void bufferTexCoords3d( size_t unit, const std::vector<Vec3f> &texCoords );
00193 void bufferColorsRGB( const std::vector<Color> &colors );
00194 void bufferColorsRGBA( const std::vector<ColorA> &colors );
00195 class VertexIter mapVertexBuffer();
00196
00197 Vbo& getIndexVbo() const { return mObj->mBuffers[INDEX_BUFFER]; }
00198 Vbo& getStaticVbo() const { return mObj->mBuffers[STATIC_BUFFER]; }
00199 Vbo& getDynamicVbo() const { return mObj->mBuffers[DYNAMIC_BUFFER]; }
00200
00201 void setCustomStaticLocation( size_t internalIndex, GLuint location ) { mObj->mCustomStaticLocations[internalIndex] = location; }
00202 void setCustomDynamicLocation( size_t internalIndex, GLuint location ) { mObj->mCustomDynamicLocations[internalIndex] = location; }
00203
00204 size_t getTexCoordOffset( size_t unit ) const { return mObj->mTexCoordOffset[unit]; }
00205 void setTexCoordOffset( size_t unit, size_t aTexCoordOffset ) { mObj->mTexCoordOffset[unit] = aTexCoordOffset; }
00206
00208
00209 typedef std::shared_ptr<Obj> VboMesh::*unspecified_bool_type;
00210 operator unspecified_bool_type() const { return ( mObj.get() == 0 ) ? 0 : &VboMesh::mObj; }
00211 void reset() { mObj.reset(); }
00213
00214 class VertexIter {
00215 public:
00216 VertexIter( const VboMesh &mesh );
00217
00218 void setPosition( const Vec3f &v ) { *(reinterpret_cast<Vec3f*>( &mPtr[mPositionOffset] )) = v; }
00219 void setPosition( float x, float y, float z ) { *(reinterpret_cast<Vec3f*>( &mPtr[mPositionOffset] )) = Vec3f( x, y, z ); }
00220 void setNormal( const Vec3f &n ) { *(reinterpret_cast<Vec3f*>( &mPtr[mNormalOffset] )) = n; }
00221 void setColorRGB( const Color &n ) { *(reinterpret_cast<Color*>( &mPtr[mColorRGBOffset] )) = n; }
00222 void setColorRGBA( const ColorA &n ) { *(reinterpret_cast<ColorA*>( &mPtr[mColorRGBAOffset] )) = n; }
00223 void setTexCoord2d0( const Vec2f &t ) { *(reinterpret_cast<Vec2f*>( &mPtr[mTexCoordOffset[0]] )) = t; }
00224 void setTexCoord3d0( const Vec3f &t ) { *(reinterpret_cast<Vec3f*>( &mPtr[mTexCoordOffset[0]] )) = t; }
00225 void setTexCoord2d1( const Vec2f &t ) { *(reinterpret_cast<Vec2f*>( &mPtr[mTexCoordOffset[1]] )) = t; }
00226 void setTexCoord3d1( const Vec3f &t ) { *(reinterpret_cast<Vec3f*>( &mPtr[mTexCoordOffset[1]] )) = t; }
00227 void setTexCoord2d2( const Vec2f &t ) { *(reinterpret_cast<Vec2f*>( &mPtr[mTexCoordOffset[2]] )) = t; }
00228 void setTexCoord3d2( const Vec3f &t ) { *(reinterpret_cast<Vec3f*>( &mPtr[mTexCoordOffset[2]] )) = t; }
00229 void setCustomFloat( size_t index, float v ) { *(reinterpret_cast<float*>( &mPtr[mObj->mCustomOffsets[index]] )) = v; }
00230 void setCustomVec2f( size_t index, const Vec2f &v ) { *(reinterpret_cast<Vec2f*>( &mPtr[mObj->mCustomOffsets[index]] )) = v; }
00231 void setCustomVec3f( size_t index, const Vec3f &v ) { *(reinterpret_cast<Vec3f*>( &mPtr[mObj->mCustomOffsets[index]] )) = v; }
00232 void setCustomVec4f( size_t index, const Vec4f &v ) { *(reinterpret_cast<Vec4f*>( &mPtr[mObj->mCustomOffsets[index]] )) = v; }
00233
00234 void operator++() { mPtr += mStride; }
00235 bool isDone() const { return mPtr < mDataEnd; }
00236
00238 size_t getIndex() const { return ( mPtr - mData ) / mStride; }
00240 size_t getStride() const { return mStride; }
00242 void* getPointer() const { return reinterpret_cast<void*>( mPtr ); }
00244 Vec3f* getPositionPointer() const { return reinterpret_cast<Vec3f*>( &mPtr[mPositionOffset] ); }
00245
00246
00247
00248
00249 protected:
00250 void set( const VertexIter &other );
00251
00252 struct Obj {
00253 public:
00254 Obj( const VboMesh &mesh );
00255 ~Obj();
00256
00257 uint8_t *mData, *mDataEnd;
00258 std::vector<size_t> mCustomOffsets;
00259 Vbo mVbo;
00260 };
00261
00262 std::shared_ptr<Obj> mObj;
00263 uint8_t *mPtr;
00264 uint8_t *mData, *mDataEnd;
00265 size_t mPositionOffset, mNormalOffset;
00266 size_t mColorRGBOffset, mColorRGBAOffset;
00267 size_t mTexCoordOffset[ATTR_MAX_TEXTURE_UNIT+1];
00268 uint8_t mStride;
00269 };
00270
00271 protected:
00272 void initializeBuffers( bool staticDataPlanar );
00273
00274 std::shared_ptr<Obj> mObj;
00275 };
00276
00277 class VboExc : public std::exception {
00278 public:
00279 virtual const char* what() const throw() { return "OpenGL Vbo exception"; }
00280 };
00281
00282 class VboInvalidTargetExc : public VboExc {
00283 public:
00284 virtual const char* what() const throw() { return "OpenGL Vbo exception: Invalid Target"; }
00285 };
00286
00287 class VboFailedMapExc : public VboExc {
00288 public:
00289 virtual const char* what() const throw() { return "OpenGL Vbo exception: Map failure"; }
00290 };
00291
00292 class VboFailedUnmapExc : public VboExc {
00293 public:
00294 virtual const char* what() const throw() { return "OpenGL Vbo exception: Unmap failure"; }
00295 };
00296
00297 } }