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 // base class
00055 
00056 class LLVertexBuffer : public LLRefCount
00057 {
00058 public:
00059         static void initClass(bool use_vbo);
00060         static void cleanupClass();
00061         static void startRender(); //between start and stop render, no client copies will occur
00062         static void stopRender(); //any buffer not copied to GL will be rendered from client memory
00063         static void clientCopy(F64 max_time = 0.005); //copy data from client to GL
00064         static void unbind(); //unbind any bound vertex buffer
00065 
00066         enum {
00067                 TYPE_VERTEX,
00068                 TYPE_NORMAL,
00069                 TYPE_TEXCOORD,
00070                 TYPE_TEXCOORD2,
00071                 TYPE_COLOR,
00072                 // These use VertexAttribPointer and should possibly be made generic
00073                 TYPE_BINORMAL,
00074                 TYPE_WEIGHT,
00075                 TYPE_CLOTHWEIGHT,
00076                 TYPE_MAX,
00077                 TYPE_INDEX,
00078         };
00079         enum {
00080                 MAP_VERTEX = (1<<TYPE_VERTEX),
00081                 MAP_NORMAL = (1<<TYPE_NORMAL),
00082                 MAP_TEXCOORD = (1<<TYPE_TEXCOORD),
00083                 MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
00084                 MAP_COLOR = (1<<TYPE_COLOR),
00085                 // These use VertexAttribPointer and should possibly be made generic
00086                 MAP_BINORMAL = (1<<TYPE_BINORMAL),
00087                 MAP_WEIGHT = (1<<TYPE_WEIGHT),
00088                 MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
00089                 MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode
00090                 MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data
00091                 MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
00092         };
00093         
00094 protected:
00095         virtual ~LLVertexBuffer(); // use unref()
00096 
00097         virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
00098 
00099         void    createGLBuffer();
00100         void    createGLIndices();
00101         void    destroyGLBuffer();
00102         void    destroyGLIndices();
00103         void    updateNumVerts(S32 nverts);
00104         void    updateNumIndices(S32 nindices); 
00105         virtual BOOL    useVBOs() const;
00106         void    unmapBuffer();
00107         
00108 public:
00109         LLVertexBuffer(U32 typemask, S32 usage);
00110         
00111         // map for data access
00112         U8*             mapBuffer(S32 access = -1);
00113         // set for rendering
00114         virtual void    setBuffer(U32 data_mask);       // calls  setupVertexBuffer() if data_mask is not 0
00115         // allocate buffer
00116         void    allocateBuffer(S32 nverts, S32 nindices, bool create);
00117         virtual void resizeBuffer(S32 newnverts, S32 newnindices);
00118         void    makeStatic();
00119         
00120         // Only call each getVertexPointer, etc, once before calling unmapBuffer()
00121         // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
00122         // example:
00123         //   vb->getVertexBuffer(verts);
00124         //   vb->getNormalStrider(norms);
00125         //   setVertsNorms(verts, norms);
00126         //   vb->unmapBuffer();
00127         bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
00128         bool getIndexStrider(LLStrider<U32>& strider, S32 index=0);
00129         bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
00130         bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
00131         bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
00132         bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
00133         bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
00134         bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
00135         bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
00136         
00137         BOOL isEmpty() const                                    { return mEmpty; }
00138         BOOL isLocked() const                                   { return mLocked; }
00139         S32 getNumVerts() const                                 { return mNumVerts; }
00140         S32 getNumIndices() const                               { return mNumIndices; }
00141         U8* getIndicesPointer() const                   { return useVBOs() ? NULL : mMappedIndexData; }
00142         U8* getVerticesPointer() const                  { return useVBOs() ? NULL : mMappedData; }
00143         S32 getStride() const                                   { return mStride; }
00144         S32 getTypeMask() const                                 { return mTypeMask; }
00145         BOOL hasDataType(S32 type) const                { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
00146         S32 getSize() const                                             { return mNumVerts*mStride; }
00147         S32 getIndicesSize() const                              { return mNumIndices * sizeof(U32); }
00148         U8* getMappedData() const                               { return mMappedData; }
00149         U8* getMappedIndices() const                    { return mMappedIndexData; }
00150         S32 getOffset(S32 type) const                   { return mOffsets[type]; }
00151         S32 getUsage() const                                    { return mUsage; }
00152 
00153         void setStride(S32 type, S32 new_stride);
00154         
00155         void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
00156         void markClean();
00157 
00158 protected:      
00159         S32             mNumVerts;              // Number of vertices
00160         S32             mNumIndices;    // Number of indices
00161         S32             mStride;
00162         U32             mTypeMask;
00163         S32             mUsage;                 // GL usage
00164         U32             mGLBuffer;              // GL VBO handle
00165         U32             mGLIndices;             // GL IBO handle
00166         U8*             mMappedData;    // pointer to currently mapped data (NULL if unmapped)
00167         U8*             mMappedIndexData;       // pointer to currently mapped indices (NULL if unmapped)
00168         BOOL    mLocked;                        // if TRUE, buffer is being or has been written to in client memory
00169         BOOL    mFinal;                 // if TRUE, buffer can not be mapped again
00170         BOOL    mFilthy;                // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
00171         BOOL    mEmpty;                 // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
00172         S32             mOffsets[TYPE_MAX];
00173         BOOL    mResized;               // if TRUE, client buffer has been resized and GL buffer has not
00174         BOOL    mDynamicSize;   // if TRUE, buffer has been resized at least once (and should be padded)
00175 
00176         class DirtyRegion
00177         {
00178         public:
00179                 U32 mIndex;
00180                 U32 mCount;
00181                 U32 mIndicesIndex;
00182                 U32 mIndicesCount;
00183 
00184                 DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
00185                         : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
00186                 { }     
00187         };
00188 
00189         std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
00190 
00191 public:
00192         static BOOL sRenderActive;
00193         static S32 sCount;
00194         static S32 sGLCount;
00195         static std::vector<U32> sDeleteList;
00196         typedef std::list<LLVertexBuffer*> buffer_list_t;
00197         static buffer_list_t sLockedList;
00198         
00199         static BOOL sEnableVBOs;
00200         static S32 sTypeOffsets[TYPE_MAX];
00201         static U32 sGLRenderBuffer;
00202         static U32 sGLRenderIndices;
00203         static BOOL sVBOActive;
00204         static BOOL sIBOActive;
00205         static U32 sLastMask;
00206         static U32 sAllocatedBytes;
00207 };
00208 
00209 
00210 #endif // LL_LLVERTEXBUFFER_H

Generated on Thu Jul 1 06:09:25 2010 for Second Life Viewer by  doxygen 1.4.7