llvertexbuffer.h

Go to the documentation of this file.
00001 
00032 #ifndef LL_LLVERTEXBUFFER_H
00033 #define LL_LLVERTEXBUFFER_H
00034 
00035 #include "llgl.h"
00036 #include "v2math.h"
00037 #include "v3math.h"
00038 #include "v4math.h"
00039 #include "v4coloru.h"
00040 #include "llstrider.h"
00041 #include "llmemory.h"
00042 #include <set>
00043 #include <vector>
00044 
00045 //============================================================================
00046 // NOTES
00047 // Threading:
00048 //  All constructors should take an 'create' paramater which should only be
00049 //  'true' when called from the main thread. Otherwise createGLBuffer() will
00050 //  be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
00051 //  called from the main (i.e OpenGL) thread)
00052 
00053 
00054 //============================================================================
00055 // gl name pools for dynamic and streaming buffers
00056 
00057 class LLVBOPool : public LLGLNamePool
00058 {
00059 protected:
00060         virtual GLuint allocateName()
00061         {
00062                 GLuint name;
00063                 glGenBuffersARB(1, &name);
00064                 return name;
00065         }
00066 
00067         virtual void releaseName(GLuint name)
00068         {
00069                 glDeleteBuffersARB(1, &name);
00070         }
00071 };
00072 
00073 
00074 //============================================================================
00075 // base class
00076 
00077 class LLVertexBuffer : public LLRefCount
00078 {
00079 public:
00080         static LLVBOPool sStreamVBOPool;
00081         static LLVBOPool sDynamicVBOPool;
00082         static LLVBOPool sStreamIBOPool;
00083         static LLVBOPool sDynamicIBOPool;
00084 
00085         static void initClass(bool use_vbo);
00086         static void cleanupClass();
00087         static void setupClientArrays(U32 data_mask);
00088         static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
00089         static void unbind(); //unbind any bound vertex buffer
00090 
00091         //get the size of a vertex with the given typemask
00092         //if offsets is not NULL, its contents will be filled
00093         //with the offset of each vertex component in the buffer, 
00094         // indexed by the following enum
00095         static S32 calcStride(const U32& typemask, S32* offsets = NULL);                                                                                
00096 
00097         enum {
00098                 TYPE_VERTEX,
00099                 TYPE_NORMAL,
00100                 TYPE_TEXCOORD,
00101                 TYPE_TEXCOORD2,
00102                 TYPE_COLOR,
00103                 // These use VertexAttribPointer and should possibly be made generic
00104                 TYPE_BINORMAL,
00105                 TYPE_WEIGHT,
00106                 TYPE_CLOTHWEIGHT,
00107                 TYPE_MAX,
00108                 TYPE_INDEX,
00109         };
00110         enum {
00111                 MAP_VERTEX = (1<<TYPE_VERTEX),
00112                 MAP_NORMAL = (1<<TYPE_NORMAL),
00113                 MAP_TEXCOORD = (1<<TYPE_TEXCOORD),
00114                 MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
00115                 MAP_COLOR = (1<<TYPE_COLOR),
00116                 // These use VertexAttribPointer and should possibly be made generic
00117                 MAP_BINORMAL = (1<<TYPE_BINORMAL),
00118                 MAP_WEIGHT = (1<<TYPE_WEIGHT),
00119                 MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
00120                 MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode
00121                 MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data
00122                 MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
00123         };
00124         
00125         enum {
00126                 TRIANGLES = 0,
00127                 TRIANGLE_STRIP,
00128                 TRIANGLE_FAN,
00129                 POINTS,
00130                 LINES,
00131                 LINE_STRIP,
00132                 QUADS,
00133                 LINE_LOOP,
00134                 NUM_MODES
00135         };
00136 protected:
00137         friend class LLGLImmediate;
00138 
00139         virtual ~LLVertexBuffer(); // use unref()
00140 
00141         virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
00142         
00143         void    genBuffer();
00144         void    genIndices();
00145         void    releaseBuffer();
00146         void    releaseIndices();
00147         void    createGLBuffer();
00148         void    createGLIndices();
00149         void    destroyGLBuffer();
00150         void    destroyGLIndices();
00151         void    updateNumVerts(S32 nverts);
00152         void    updateNumIndices(S32 nindices); 
00153         virtual BOOL    useVBOs() const;
00154         void    unmapBuffer();
00155                 
00156 public:
00157         LLVertexBuffer(U32 typemask, S32 usage);
00158         
00159         // map for data access
00160         U8*             mapBuffer(S32 access = -1);
00161         // set for rendering
00162         virtual void    setBuffer(U32 data_mask);       // calls  setupVertexBuffer() if data_mask is not 0
00163         // allocate buffer
00164         void    allocateBuffer(S32 nverts, S32 nindices, bool create);
00165         virtual void resizeBuffer(S32 newnverts, S32 newnindices);
00166                 
00167         // Only call each getVertexPointer, etc, once before calling unmapBuffer()
00168         // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
00169         // example:
00170         //   vb->getVertexBuffer(verts);
00171         //   vb->getNormalStrider(norms);
00172         //   setVertsNorms(verts, norms);
00173         //   vb->unmapBuffer();
00174         bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
00175         bool getIndexStrider(LLStrider<U16>& strider, S32 index=0);
00176         bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
00177         bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
00178         bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
00179         bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
00180         bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
00181         bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
00182         bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
00183         
00184         BOOL isEmpty() const                                    { return mEmpty; }
00185         BOOL isLocked() const                                   { return mLocked; }
00186         S32 getNumVerts() const                                 { return mNumVerts; }
00187         S32 getNumIndices() const                               { return mNumIndices; }
00188         S32 getRequestedVerts() const                   { return mRequestedNumVerts; }
00189         S32 getRequestedIndices() const                 { return mRequestedNumIndices; }
00190 
00191         U8* getIndicesPointer() const                   { return useVBOs() ? NULL : mMappedIndexData; }
00192         U8* getVerticesPointer() const                  { return useVBOs() ? NULL : mMappedData; }
00193         S32 getStride() const                                   { return mStride; }
00194         S32 getTypeMask() const                                 { return mTypeMask; }
00195         BOOL hasDataType(S32 type) const                { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
00196         S32 getSize() const                                             { return mNumVerts*mStride; }
00197         S32 getIndicesSize() const                              { return mNumIndices * sizeof(U16); }
00198         U8* getMappedData() const                               { return mMappedData; }
00199         U8* getMappedIndices() const                    { return mMappedIndexData; }
00200         S32 getOffset(S32 type) const                   { return mOffsets[type]; }
00201         S32 getUsage() const                                    { return mUsage; }
00202 
00203         void setStride(S32 type, S32 new_stride);
00204         
00205         void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
00206 
00207         void draw(U32 mode, U32 count, U32 indices_offset) const;
00208         void drawArrays(U32 mode, U32 offset, U32 count) const;
00209         void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const;
00210 
00211 protected:      
00212         S32             mNumVerts;              // Number of vertices allocated
00213         S32             mNumIndices;    // Number of indices allocated
00214         S32             mRequestedNumVerts;  // Number of vertices requested
00215         S32             mRequestedNumIndices;  // Number of indices requested
00216 
00217         S32             mStride;
00218         U32             mTypeMask;
00219         S32             mUsage;                 // GL usage
00220         U32             mGLBuffer;              // GL VBO handle
00221         U32             mGLIndices;             // GL IBO handle
00222         U8*             mMappedData;    // pointer to currently mapped data (NULL if unmapped)
00223         U8*             mMappedIndexData;       // pointer to currently mapped indices (NULL if unmapped)
00224         BOOL    mLocked;                        // if TRUE, buffer is being or has been written to in client memory
00225         BOOL    mFinal;                 // if TRUE, buffer can not be mapped again
00226         BOOL    mFilthy;                // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
00227         BOOL    mEmpty;                 // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
00228         S32             mOffsets[TYPE_MAX];
00229         BOOL    mResized;               // if TRUE, client buffer has been resized and GL buffer has not
00230         BOOL    mDynamicSize;   // if TRUE, buffer has been resized at least once (and should be padded)
00231 
00232         class DirtyRegion
00233         {
00234         public:
00235                 U32 mIndex;
00236                 U32 mCount;
00237                 U32 mIndicesIndex;
00238                 U32 mIndicesCount;
00239 
00240                 DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
00241                         : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
00242                 { }     
00243         };
00244 
00245         std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
00246 
00247 public:
00248         static S32 sCount;
00249         static S32 sGLCount;
00250         static S32 sMappedCount;
00251         static BOOL sMapped;
00252         static std::vector<U32> sDeleteList;
00253         typedef std::list<LLVertexBuffer*> buffer_list_t;
00254                 
00255         static BOOL sEnableVBOs;
00256         static S32 sTypeOffsets[TYPE_MAX];
00257         static U32 sGLMode[NUM_MODES];
00258         static U32 sGLRenderBuffer;
00259         static U32 sGLRenderIndices;
00260         static BOOL sVBOActive;
00261         static BOOL sIBOActive;
00262         static U32 sLastMask;
00263         static U32 sAllocatedBytes;
00264         static U32 sBindCount;
00265         static U32 sSetCount;
00266 };
00267 
00268 
00269 #endif // LL_LLVERTEXBUFFER_H

Generated on Fri May 16 08:32:50 2008 for SecondLife by  doxygen 1.5.5