summaryrefslogtreecommitdiff
path: root/indra/llrender/llvertexbuffer.h
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llvertexbuffer.h')
-rw-r--r--indra/llrender/llvertexbuffer.h179
1 files changed, 179 insertions, 0 deletions
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
new file mode 100644
index 0000000000..e672321e76
--- /dev/null
+++ b/indra/llrender/llvertexbuffer.h
@@ -0,0 +1,179 @@
+#ifndef LL_LLVERTEXBUFFER_H
+#define LL_LLVERTEXBUFFER_H
+
+#include "llgl.h"
+#include "v2math.h"
+#include "v3math.h"
+#include "v4math.h"
+#include "v4coloru.h"
+#include "llstrider.h"
+#include "llmemory.h"
+#include <set>
+#include <vector>
+
+//============================================================================
+// NOTES
+// Threading:
+// All constructors should take an 'create' paramater which should only be
+// 'true' when called from the main thread. Otherwise createGLBuffer() will
+// be called as soon as getVertexPointer(), etc is called (which MUST ONLY be
+// called from the main (i.e OpenGL) thread)
+
+//============================================================================
+// base class
+
+class LLVertexBuffer : public LLRefCount
+{
+public:
+ static void initClass(bool use_vbo);
+ static void cleanupClass();
+ static void startRender(); //between start and stop render, no client copies will occur
+ static void stopRender(); //any buffer not copied to GL will be rendered from client memory
+ static void clientCopy(); //copy data from client to GL
+ static void unbind(); //unbind any bound vertex buffer
+
+ enum {
+ TYPE_VERTEX,
+ TYPE_NORMAL,
+ TYPE_TEXCOORD,
+ TYPE_TEXCOORD2,
+ TYPE_COLOR,
+ // These use VertexAttribPointer and should possibly be made generic
+ TYPE_BINORMAL,
+ TYPE_WEIGHT,
+ TYPE_CLOTHWEIGHT,
+ TYPE_MAX,
+ TYPE_INDEX,
+ };
+ enum {
+ MAP_VERTEX = (1<<TYPE_VERTEX),
+ MAP_NORMAL = (1<<TYPE_NORMAL),
+ MAP_TEXCOORD = (1<<TYPE_TEXCOORD),
+ MAP_TEXCOORD2 = (1<<TYPE_TEXCOORD2),
+ MAP_COLOR = (1<<TYPE_COLOR),
+ // These use VertexAttribPointer and should possibly be made generic
+ MAP_BINORMAL = (1<<TYPE_BINORMAL),
+ MAP_WEIGHT = (1<<TYPE_WEIGHT),
+ MAP_CLOTHWEIGHT = (1<<TYPE_CLOTHWEIGHT),
+ MAP_DRAW = 0x2000, // Buffer is in draw (read-only) mode
+ MAP_MAPPED = 0x4000, // Indicates that buffer has been mapped, but not to any type of data
+ MAP_UNMAPPED = 0x8000 // Indicates that buffer has been logically un-mapped
+ };
+
+protected:
+ virtual ~LLVertexBuffer(); // use unref()
+
+ virtual void setupVertexBuffer(U32 data_mask) const; // pure virtual, called from mapBuffer()
+
+ void createGLBuffer();
+ void createGLIndices();
+ void destroyGLBuffer();
+ void destroyGLIndices();
+ void updateNumVerts(S32 nverts);
+ void updateNumIndices(S32 nindices);
+ virtual BOOL useVBOs() const;
+ void unmapBuffer();
+
+public:
+ LLVertexBuffer(U32 typemask, S32 usage);
+
+ // map for data access
+ U8* mapBuffer(S32 access = -1);
+ // set for rendering
+ virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0
+ // allocate buffer
+ void allocateBuffer(S32 nverts, S32 nindices, bool create);
+ virtual void resizeBuffer(S32 newnverts, S32 newnindices);
+ void makeStatic();
+
+ // Only call each getVertexPointer, etc, once before calling unmapBuffer()
+ // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer()
+ // example:
+ // vb->getVertexBuffer(verts);
+ // vb->getNormalStrider(norms);
+ // setVertsNorms(verts, norms);
+ // vb->unmapBuffer();
+ bool getVertexStrider(LLStrider<LLVector3>& strider, S32 index=0);
+ bool getIndexStrider(LLStrider<U32>& strider, S32 index=0);
+ bool getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index=0);
+ bool getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index=0);
+ bool getNormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
+ bool getBinormalStrider(LLStrider<LLVector3>& strider, S32 index=0);
+ bool getColorStrider(LLStrider<LLColor4U>& strider, S32 index=0);
+ bool getWeightStrider(LLStrider<F32>& strider, S32 index=0);
+ bool getClothWeightStrider(LLStrider<LLVector4>& strider, S32 index=0);
+
+ BOOL isEmpty() const { return mEmpty; }
+ BOOL isLocked() const { return mLocked; }
+ S32 getNumVerts() const { return mNumVerts; }
+ S32 getNumIndices() const { return mNumIndices; }
+ U8* getIndicesPointer() const { return useVBOs() ? NULL : mMappedIndexData; }
+ U8* getVerticesPointer() const { return useVBOs() ? NULL : mMappedData; }
+ S32 getStride() const { return mStride; }
+ S32 getTypeMask() const { return mTypeMask; }
+ BOOL hasDataType(S32 type) const { return ((1 << type) & getTypeMask()) ? TRUE : FALSE; }
+ S32 getSize() const { return mNumVerts*mStride; }
+ S32 getIndicesSize() const { return mNumIndices * sizeof(U32); }
+ U8* getMappedData() const { return mMappedData; }
+ U8* getMappedIndices() const { return mMappedIndexData; }
+ S32 getOffset(S32 type) const { return mOffsets[type]; }
+ S32 getUsage() const { return mUsage; }
+
+ void setStride(S32 type, S32 new_stride);
+
+ void markDirty(U32 vert_index, U32 vert_count, U32 indices_index, U32 indices_count);
+ void markClean();
+
+protected:
+ S32 mNumVerts; // Number of vertices
+ S32 mNumIndices; // Number of indices
+ S32 mStride;
+ U32 mTypeMask;
+ S32 mUsage; // GL usage
+ U32 mGLBuffer; // GL VBO handle
+ U32 mGLIndices; // GL IBO handle
+ U8* mMappedData; // pointer to currently mapped data (NULL if unmapped)
+ U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped)
+ BOOL mLocked; // if TRUE, buffer is being or has been written to in client memory
+ BOOL mFinal; // if TRUE, buffer can not be mapped again
+ BOOL mFilthy; // if TRUE, entire buffer must be copied (used to prevent redundant dirty flags)
+ BOOL mEmpty; // if TRUE, client buffer is empty (or NULL). Old values have been discarded.
+ S32 mOffsets[TYPE_MAX];
+ BOOL mResized; // if TRUE, client buffer has been resized and GL buffer has not
+ BOOL mDynamicSize; // if TRUE, buffer has been resized at least once (and should be padded)
+
+ class DirtyRegion
+ {
+ public:
+ U32 mIndex;
+ U32 mCount;
+ U32 mIndicesIndex;
+ U32 mIndicesCount;
+
+ DirtyRegion(U32 vi, U32 vc, U32 ii, U32 ic)
+ : mIndex(vi), mCount(vc), mIndicesIndex(ii), mIndicesCount(ic)
+ { }
+ };
+
+ std::vector<DirtyRegion> mDirtyRegions; //vector of dirty regions to rebuild
+
+public:
+ static BOOL sRenderActive;
+ static S32 sCount;
+ static S32 sGLCount;
+ static std::vector<U32> sDeleteList;
+ typedef std::list<LLVertexBuffer*> buffer_list_t;
+ static buffer_list_t sLockedList;
+
+ static BOOL sEnableVBOs;
+ static S32 sTypeOffsets[TYPE_MAX];
+ static S32 sGLRenderBuffer;
+ static S32 sGLRenderIndices;
+ static BOOL sVBOActive;
+ static BOOL sIBOActive;
+ static U32 sLastMask;
+ static U32 sAllocatedBytes;
+};
+
+
+#endif // LL_LLVERTEXBUFFER_H