diff options
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 1032 |
1 files changed, 553 insertions, 479 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bb8f067e8d..199699449a 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -34,6 +34,7 @@ #include "llmemtype.h" #include "llrender.h" #include "llvector4a.h" +#include "llshadermgr.h" #include "llglslshader.h" #include "llmemory.h" @@ -55,6 +56,7 @@ S32 LLVertexBuffer::sMappedCount = 0; BOOL LLVertexBuffer::sDisableVBOMapping = FALSE ; BOOL LLVertexBuffer::sEnableVBOs = TRUE; U32 LLVertexBuffer::sGLRenderBuffer = 0; +U32 LLVertexBuffer::sGLRenderArray = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sLastMask = 0; BOOL LLVertexBuffer::sVBOActive = FALSE; @@ -62,11 +64,10 @@ BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; BOOL LLVertexBuffer::sMapped = FALSE; BOOL LLVertexBuffer::sUseStreamDraw = TRUE; +BOOL LLVertexBuffer::sUseVAO = FALSE; BOOL LLVertexBuffer::sPreferStreamDraw = FALSE; - std::vector<U32> LLVertexBuffer::sDeleteList; - const U32 FENCE_WAIT_TIME_NANOSECONDS = 10000; //1 ms class LLGLSyncFence : public LLGLFence @@ -121,6 +122,7 @@ public: }; +//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { sizeof(LLVector4), // TYPE_VERTEX, @@ -130,11 +132,12 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector2), // TYPE_TEXCOORD2, sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, - sizeof(U8), // TYPE_EMISSIVE + sizeof(LLColor4U), // TYPE_EMISSIVE, only alpha is used currently sizeof(LLVector4), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, + sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes }; U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = @@ -149,188 +152,130 @@ U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = GL_LINE_LOOP, }; + //static void LLVertexBuffer::setupClientArrays(U32 data_mask) { - /*if (LLGLImmediate::sStarted) - { - llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; - }*/ - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (sLastMask != data_mask) { - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); - static LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr; - llassert(sLastMask == 0 || last_shader == shader); - last_shader = shader; - - U32 mask[] = - { - MAP_VERTEX, - MAP_NORMAL, - MAP_TEXCOORD0, - MAP_COLOR, - MAP_EMISSIVE, - MAP_WEIGHT, - MAP_WEIGHT4, - MAP_BINORMAL, - MAP_CLOTHWEIGHT, - }; - - U32 type[] = - { - TYPE_VERTEX, - TYPE_NORMAL, - TYPE_TEXCOORD0, - TYPE_COLOR, - TYPE_EMISSIVE, - TYPE_WEIGHT, - TYPE_WEIGHT4, - TYPE_BINORMAL, - TYPE_CLOTHWEIGHT, - }; - - GLenum array[] = - { - GL_VERTEX_ARRAY, - GL_NORMAL_ARRAY, - GL_TEXTURE_COORD_ARRAY, - GL_COLOR_ARRAY, - 0, - 0, - 0, - 0, - 0, - }; - BOOL error = FALSE; - for (U32 i = 0; i < 9; ++i) + + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = -1; - if (shader) + for (U32 i = 0; i < TYPE_MAX; ++i) { - loc = shader->getAttribLocation(type[i]); - } - - if (sLastMask & mask[i]) - { //was enabled - if (!(data_mask & mask[i])) - { //needs to be disabled - if (loc >= 0) - { + S32 loc = i; + + U32 mask = 1 << i; + + if (sLastMask & (1 << i)) + { //was enabled + if (!(data_mask & mask)) + { //needs to be disabled glDisableVertexAttribArrayARB(loc); } - else if (!shader) - { + } + else + { //was disabled + if (data_mask & mask) + { //needs to be enabled + glEnableVertexAttribArrayARB(loc); + } + } + } + } + else + { + + GLenum array[] = + { + GL_VERTEX_ARRAY, + GL_NORMAL_ARRAY, + GL_TEXTURE_COORD_ARRAY, + GL_COLOR_ARRAY, + }; + + GLenum mask[] = + { + MAP_VERTEX, + MAP_NORMAL, + MAP_TEXCOORD0, + MAP_COLOR + }; + + + + for (U32 i = 0; i < 4; ++i) + { + if (sLastMask & mask[i]) + { //was enabled + if (!(data_mask & mask[i])) + { //needs to be disabled glDisableClientState(array[i]); } + else if (gDebugGL) + { //needs to be enabled, make sure it was (DEBUG) + if (!glIsEnabled(array[i])) + { + if (gDebugSession) + { + error = TRUE; + gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; + } + else + { + llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + } + } + } } - else if (gDebugGL && !shader && array[i]) - { //needs to be enabled, make sure it was (DEBUG) - if (loc < 0 && !glIsEnabled(array[i])) - { + else + { //was disabled + if (data_mask & mask[i]) + { //needs to be enabled + glEnableClientState(array[i]); + } + else if (gDebugGL && glIsEnabled(array[i])) + { //needs to be disabled, make sure it was (DEBUG TEMPORARY) if (gDebugSession) { error = TRUE; - gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl; + gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; } else { - llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + llerrs << "Bad client state! " << array[i] << " enabled." << llendl; } } } } - else - { //was disabled - if (data_mask & mask[i]) - { //needs to be enabled - if (loc >= 0) - { - glEnableVertexAttribArrayARB(loc); - } - else if (!shader) - { - glEnableClientState(array[i]); - } - } - else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i])) - { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - if (gDebugSession) - { - error = TRUE; - gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl; - } - else - { - llerrs << "Bad client state! " << array[i] << " enabled." << llendl; - } - } - } - } - - if (error) - { - ll_fail("LLVertexBuffer::setupClientArrays failed"); - } - - U32 map_tc[] = - { - MAP_TEXCOORD1, - MAP_TEXCOORD2, - MAP_TEXCOORD3 - }; - - U32 type_tc[] = - { - TYPE_TEXCOORD1, - TYPE_TEXCOORD2, - TYPE_TEXCOORD3 - }; - - for (U32 i = 0; i < 3; i++) - { - S32 loc = -1; - if (shader) + + U32 map_tc[] = { - loc = shader->getAttribLocation(type_tc[i]); - } + MAP_TEXCOORD1, + MAP_TEXCOORD2, + MAP_TEXCOORD3 + }; - if (sLastMask & map_tc[i]) + for (U32 i = 0; i < 3; i++) { - if (!(data_mask & map_tc[i])) - { //disable - if (loc >= 0) - { - glDisableVertexAttribArrayARB(loc); - } - else if (!shader) - { + if (sLastMask & map_tc[i]) + { + if (!(data_mask & map_tc[i])) + { //disable glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glDisableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - } - else if (data_mask & map_tc[i]) - { - if (loc >= 0) - { - glEnableVertexAttribArrayARB(loc); - } - else if (!shader) + else if (data_mask & map_tc[i]) { glClientActiveTextureARB(GL_TEXTURE1_ARB+i); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - } - if (!shader) - { if (sLastMask & MAP_BINORMAL) { if (!(data_mask & MAP_BINORMAL)) @@ -347,7 +292,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) glClientActiveTextureARB(GL_TEXTURE0_ARB); } } - + sLastMask = data_mask; } } @@ -356,6 +301,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm) { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); U32 count = pos.size(); llassert_always(norm.size() >= pos.size()); @@ -369,12 +315,12 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con if (shader) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); + S32 loc = LLVertexBuffer::TYPE_VERTEX; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV); } - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL); + loc = LLVertexBuffer::TYPE_NORMAL; if (loc > -1) { glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV); @@ -394,6 +340,8 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); + U32 mask = LLVertexBuffer::MAP_VERTEX; if (tc) { @@ -404,23 +352,15 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto setupClientArrays(mask); - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - if (shader) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); + S32 loc = LLVertexBuffer::TYPE_VERTEX; + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 16, pos); - if (tc) - { - loc = shader->getAttribLocation(LLVertexBuffer::TYPE_TEXCOORD0); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); - } - } + if (tc) + { + loc = LLVertexBuffer::TYPE_TEXCOORD0; + glVertexAttribPointerARB(loc, 2, GL_FLOAT, GL_FALSE, 0, tc); } } else @@ -465,17 +405,40 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi { validateRange(start, end, count, indices_offset); + gGL.syncMatrices(); + llassert(mRequestedNumVerts >= 0); llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - if (mGLIndices != sGLRenderIndices) + if (mGLArray) + { + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } + } + else { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } - if (mGLBuffer != sGLRenderBuffer) + if (gDebugGL && useVBOs()) { - llerrs << "Wrong vertex buffer bound." << llendl; + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -497,6 +460,8 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); + gGL.syncMatrices(); + llassert(mRequestedNumIndices >= 0); if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) @@ -504,14 +469,24 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } - if (mGLIndices != sGLRenderIndices) + if (mGLArray) { - llerrs << "Wrong index buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } } - - if (mGLBuffer != sGLRenderBuffer) + else { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -530,7 +505,9 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL); - + + gGL.syncMatrices(); + llassert(mRequestedNumVerts >= 0); if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) @@ -538,9 +515,19 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + if (mGLArray) { - llerrs << "Wrong vertex buffer bound." << llendl; + if (mGLArray != sGLRenderArray) + { + llerrs << "Wrong vertex array bound." << llendl; + } + } + else + { + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } } if (mode >= LLRender::NUM_MODES) @@ -581,6 +568,14 @@ void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) //static void LLVertexBuffer::unbind() { + if (sGLRenderArray) + { +#if GL_ARB_vertex_array_object + glBindVertexArray(0); +#endif + sGLRenderArray = 0; + } + if (sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); @@ -632,6 +627,7 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mRequestedNumIndices(-1), mUsage(usage), mGLBuffer(0), + mGLArray(0), mGLIndices(0), mMappedData(NULL), mMappedIndexData(NULL), @@ -661,6 +657,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mUsage = GL_STREAM_DRAW_ARB; } + if (mUsage == 0 && LLRender::sGLCoreProfile) + { //MUST use VBOs for all rendering + mUsage = GL_STREAM_DRAW_ARB; + } + //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { @@ -679,12 +680,12 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) { S32 offset = 0; - for (S32 i=0; i<TYPE_MAX; i++) + for (S32 i=0; i<TYPE_TEXTURE_INDEX; i++) { U32 mask = 1<<i; if (typemask & mask) { - if (offsets) + if (offsets && LLVertexBuffer::sTypeSize[i]) { offsets[i] = offset; offset += LLVertexBuffer::sTypeSize[i]*num_vertices; @@ -693,6 +694,8 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti } } + offsets[TYPE_TEXTURE_INDEX] = offsets[TYPE_VERTEX] + 12; + return offset+16; } @@ -700,7 +703,7 @@ S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_verti S32 LLVertexBuffer::calcVertexSize(const U32& typemask) { S32 size = 0; - for (S32 i = 0; i < TYPE_MAX; i++) + for (S32 i = 0; i < TYPE_TEXTURE_INDEX; i++) { U32 mask = 1<<i; if (typemask & mask) @@ -724,6 +727,14 @@ LLVertexBuffer::~LLVertexBuffer() LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR); destroyGLBuffer(); destroyGLIndices(); + + if (mGLArray) + { +#if GL_ARB_vertex_array_object + glDeleteVertexArrays(1, &mGLArray); +#endif + } + sCount--; if (mFence) @@ -1015,7 +1026,9 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER); - + + stop_glerror(); + if (nverts < 0 || nindices < 0 || nverts > 65536) { @@ -1033,11 +1046,96 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { createGLBuffer(); createGLIndices(); + + + if (gGLManager.mHasVertexArrayObject && useVBOs() && (LLRender::sGLCoreProfile || sUseVAO)) + { +#if GL_ARB_vertex_array_object + glGenVertexArrays(1, &mGLArray); +#endif + setupVertexArray(); + } } sAllocatedBytes += getSize() + getIndicesSize(); } +void LLVertexBuffer::setupVertexArray() +{ + bindGLArray(); + + U32 attrib_size[] = + { + 3, //TYPE_VERTEX, + 3, //TYPE_NORMAL, + 2, //TYPE_TEXCOORD0, + 2, //TYPE_TEXCOORD1, + 2, //TYPE_TEXCOORD2, + 2, //TYPE_TEXCOORD3, + 4, //TYPE_COLOR, + 4, //TYPE_EMISSIVE, + 3, //TYPE_BINORMAL, + 1, //TYPE_WEIGHT, + 4, //TYPE_WEIGHT4, + 4, //TYPE_CLOTHWEIGHT, + 1, //TYPE_TEXTURE_INDEX + }; + + U32 attrib_type[] = + { + GL_FLOAT, //TYPE_VERTEX, + GL_FLOAT, //TYPE_NORMAL, + GL_FLOAT, //TYPE_TEXCOORD0, + GL_FLOAT, //TYPE_TEXCOORD1, + GL_FLOAT, //TYPE_TEXCOORD2, + GL_FLOAT, //TYPE_TEXCOORD3, + GL_UNSIGNED_BYTE, //TYPE_COLOR, + GL_UNSIGNED_BYTE, //TYPE_EMISSIVE, + GL_FLOAT, //TYPE_BINORMAL, + GL_FLOAT, //TYPE_WEIGHT, + GL_FLOAT, //TYPE_WEIGHT4, + GL_FLOAT, //TYPE_CLOTHWEIGHT, + GL_FLOAT, //TYPE_TEXTURE_INDEX + }; + + U32 attrib_normalized[] = + { + GL_FALSE, //TYPE_VERTEX, + GL_FALSE, //TYPE_NORMAL, + GL_FALSE, //TYPE_TEXCOORD0, + GL_FALSE, //TYPE_TEXCOORD1, + GL_FALSE, //TYPE_TEXCOORD2, + GL_FALSE, //TYPE_TEXCOORD3, + GL_TRUE, //TYPE_COLOR, + GL_TRUE, //TYPE_EMISSIVE, + GL_FALSE, //TYPE_BINORMAL, + GL_FALSE, //TYPE_WEIGHT, + GL_FALSE, //TYPE_WEIGHT4, + GL_FALSE, //TYPE_CLOTHWEIGHT, + GL_FALSE, //TYPE_TEXTURE_INDEX + }; + + bindGLBuffer(true); + bindGLIndices(true); + + for (U32 i = 0; i < TYPE_MAX; ++i) + { + if (mTypeMask & (1 << i)) + { + glEnableVertexAttribArrayARB(i); + glVertexAttribPointerARB(i, attrib_size[i], attrib_type[i], attrib_normalized[i], sTypeSize[i], (void*) mOffsets[i]); + } + else + { + glDisableVertexAttribArrayARB(i); + } + } + +#if GL_ARB_vertex_array_object + glBindVertexArray(0); +#endif +} + void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { llassert(newnverts >= 0); @@ -1113,8 +1211,13 @@ void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) if (mResized && useVBOs()) { - freeClientBuffer() ; - setBuffer(0); + freeClientBuffer(); + flush(); + + if (mGLArray) + { //if size changed, offsets changed + setupVertexArray(); + } } } @@ -1179,6 +1282,7 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 index, S32 count) // Map for data access U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) { + bindGLBuffer(true); LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) { @@ -1229,7 +1333,6 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (!mVertexLocked) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); - setBuffer(0, type); mVertexLocked = TRUE; sMappedCount++; stop_glerror(); @@ -1344,6 +1447,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); + bindGLIndices(true); if (mFinal) { llerrs << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << llendl; @@ -1391,11 +1495,21 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); - setBuffer(0, TYPE_INDEX); mIndexLocked = TRUE; sMappedCount++; stop_glerror(); + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + if(sDisableVBOMapping) { map_range = false; @@ -1492,19 +1606,20 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) } } -void LLVertexBuffer::unmapBuffer(S32 type) +void LLVertexBuffer::unmapBuffer() { LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); - if (!useVBOs() || type == -2) + if (!useVBOs()) { return ; //nothing to unmap } bool updated_all = false ; - if (mMappedData && mVertexLocked && type != TYPE_INDEX) + if (mMappedData && mVertexLocked) { - updated_all = (mIndexLocked && type < 0) ; //both vertex and index buffers done updating + bindGLBuffer(true); + updated_all = mIndexLocked; //both vertex and index buffers done updating if(sDisableVBOMapping) { @@ -1568,8 +1683,9 @@ void LLVertexBuffer::unmapBuffer(S32 type) sMappedCount--; } - if (mMappedIndexData && mIndexLocked && (type < 0 || type == TYPE_INDEX)) + if (mMappedIndexData && mIndexLocked) { + bindGLIndices(); if(sDisableVBOMapping) { if (!mMappedIndexRegions.empty()) @@ -1728,9 +1844,9 @@ bool LLVertexBuffer::getColorStrider(LLStrider<LLColor4U>& strider, S32 index, S { return VertexBufferStrider<LLColor4U,TYPE_COLOR>::get(*this, strider, index, count, map_range); } -bool LLVertexBuffer::getEmissiveStrider(LLStrider<U8>& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getEmissiveStrider(LLStrider<LLColor4U>& strider, S32 index, S32 count, bool map_range) { - return VertexBufferStrider<U8,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range); + return VertexBufferStrider<LLColor4U,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range); } bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range) { @@ -1749,31 +1865,148 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in //---------------------------------------------------------------------------- +bool LLVertexBuffer::bindGLArray() +{ + if (mGLArray && sGLRenderArray != mGLArray) + { +#if GL_ARB_vertex_array_object + glBindVertexArray(mGLArray); +#endif + sGLRenderArray = mGLArray; + return true; + } + + return false; +} + +bool LLVertexBuffer::bindGLBuffer(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + + if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + sBindCount++; + sVBOActive = TRUE; + + if (mGLArray) + { + llassert(sGLRenderArray == mGLArray); + //mCachedRenderBuffer = mGLBuffer; + } + + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLBuffer) + { + llerrs << "Wrong vertex buffer bound!" << llendl; + } + } + + return ret; +} + +bool LLVertexBuffer::bindGLIndices(bool force_bind) +{ + bindGLArray(); + + bool ret = false; + if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) + { + /*if (sMapped) + { + llerrs << "VBO bound while another VBO mapped!" << llendl; + }*/ + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + sGLRenderIndices = mGLIndices; + stop_glerror(); + sBindCount++; + sIBOActive = TRUE; + ret = true; + } + + if (gDebugGL && useVBOs()) + { + GLint elem = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + + if (elem != mGLIndices) + { + llerrs << "Wrong index buffer bound!" << llendl; + } + } + + return ret; +} + +void LLVertexBuffer::flush() +{ + if (useVBOs()) + { + if (mResized) + { + if (mGLBuffer) + { + stop_glerror(); + bindGLBuffer(true); + glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); + stop_glerror(); + } + if (mGLIndices) + { + stop_glerror(); + bindGLIndices(true); + glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); + stop_glerror(); + } + + mEmpty = TRUE; + mResized = FALSE; + } + + unmapBuffer(); + } +} + // Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) +void LLVertexBuffer::setBuffer(U32 data_mask) { + flush(); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... BOOL setup = (sLastMask != data_mask); if (gDebugGL && data_mask != 0) - { + { //make sure data requirements are fulfilled LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; if (shader) { U32 required_mask = 0; - for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) + for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i) { if (shader->getAttribLocation(i) > -1) { U32 required = 1 << i; if ((data_mask & required) == 0) { - llwarns << "Missing attribute: " << i << llendl; + llwarns << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << llendl; } required_mask |= required; - } } @@ -1786,34 +2019,25 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) if (useVBOs()) { - if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)) + if (mGLArray) { - /*if (sMapped) - { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - stop_glerror(); - glBindBufferARB(GL_ARRAY_BUFFER_ARB, mGLBuffer); - stop_glerror(); - sBindCount++; - sVBOActive = TRUE; - setup = TRUE; // ... or the bound buffer changed + bindGLArray(); + setup = FALSE; //do NOT perform pointer setup if using VAO } - if (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)) + else { - /*if (sMapped) + if (bindGLBuffer()) { - llerrs << "VBO bound while another VBO mapped!" << llendl; - }*/ - stop_glerror(); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); - stop_glerror(); - sBindCount++; - sIBOActive = TRUE; + setup = TRUE; + } + if (bindGLIndices()) + { + setup = TRUE; + } } - + BOOL error = FALSE; - if (gDebugGL) + if (gDebugGL && !mGLArray) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); @@ -1848,81 +2072,18 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } } - if (mResized) + + } + else + { + if (sGLRenderArray) { - if (gDebugGL) - { - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLBuffer) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL vertex buffer bound: " << std::endl; - } - else - { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; - } - } - - if (mGLIndices != 0) - { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if ((GLuint)buff != mGLIndices) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Invalid GL index buffer bound: "<< std::endl; - } - else - { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; - } - } - } - } - - if (mGLBuffer) - { - stop_glerror(); - glBufferDataARB(GL_ARRAY_BUFFER_ARB, getSize(), NULL, mUsage); - stop_glerror(); - } - if (mGLIndices) - { - stop_glerror(); - glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB, getIndicesSize(), NULL, mUsage); - stop_glerror(); - } - - mEmpty = TRUE; - mResized = FALSE; - - if (data_mask != 0) - { - if (gDebugSession) - { - error = TRUE; - gFailLog << "Buffer set for rendering before being filled after resize." << std::endl; - } - else - { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; - } - } +#if GL_ARB_vertex_array_object + glBindVertexArray(0); +#endif + sGLRenderArray = 0; } - if (error) - { - ll_fail("LLVertexBuffer::mapBuffer failed"); - } - unmapBuffer(type); - } - else - { if (mGLBuffer) { if (sVBOActive) @@ -1934,30 +2095,30 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } if (sGLRenderBuffer != mGLBuffer) { + sGLRenderBuffer = mGLBuffer; setup = TRUE; // ... or a client memory pointer changed } } - if (mGLIndices && sIBOActive) + if (mGLIndices) { - /*if (sMapped) + if (sIBOActive) { - llerrs << "VBO unbound while potentially mapped!" << llendl; - }*/ - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sBindCount++; - sIBOActive = FALSE; + glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); + sBindCount++; + sIBOActive = FALSE; + } + + sGLRenderIndices = mGLIndices; } } - setupClientArrays(data_mask); - - if (mGLIndices) + if (!mGLArray) { - sGLRenderIndices = mGLIndices; + setupClientArrays(data_mask); } + if (mGLBuffer) { - sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { setupVertexBuffer(data_mask); // subclass specific setup (virtual function) @@ -1967,237 +2128,150 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type) } // virtual (default) -void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const +void LLVertexBuffer::setupVertexBuffer(U32 data_mask) { LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); U8* base = useVBOs() ? (U8*) mAlignedOffset : mMappedData; - if ((data_mask & mTypeMask) != data_mask) + /*if ((data_mask & mTypeMask) != data_mask) { llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; - } - - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - - //assert that fixed function is allowed OR a shader is currently bound - llassert(!LLGLSLShader::sNoFixedFunction || shader != NULL); + }*/ - if (data_mask & MAP_NORMAL) + if (LLGLSLShader::sNoFixedFunction) { - S32 loc = -1; - if (shader) + if (data_mask & MAP_NORMAL) { - loc = shader->getAttribLocation(TYPE_NORMAL); + S32 loc = TYPE_NORMAL; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); + glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD3) { - glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + S32 loc = TYPE_TEXCOORD3; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } - else if (!shader) + if (data_mask & MAP_TEXCOORD2) { - glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); + S32 loc = TYPE_TEXCOORD2; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } - } - if (data_mask & MAP_TEXCOORD3) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD1) { - loc = shader->getAttribLocation(TYPE_TEXCOORD3); + S32 loc = TYPE_TEXCOORD1; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } - - if (loc >= 0) + if (data_mask & MAP_BINORMAL) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + S32 loc = TYPE_BINORMAL; + void* ptr = (void*)(base + mOffsets[TYPE_BINORMAL]); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], ptr); } - else if (!shader) + if (data_mask & MAP_TEXCOORD0) { - glClientActiveTextureARB(GL_TEXTURE3_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = TYPE_TEXCOORD0; + void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); + glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } - } - if (data_mask & MAP_TEXCOORD2) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_COLOR) { - loc = shader->getAttribLocation(TYPE_TEXCOORD2); + S32 loc = TYPE_COLOR; + void* ptr = (void*)(base + mOffsets[TYPE_COLOR]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } - - if (loc >= 0) + if (data_mask & MAP_EMISSIVE) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); + S32 loc = TYPE_EMISSIVE; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); + glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); } - else if (!shader) + if (data_mask & MAP_WEIGHT) { - glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = TYPE_WEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } - } - if (data_mask & MAP_TEXCOORD1) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_WEIGHT4) { - loc = shader->getAttribLocation(TYPE_TEXCOORD1); + S32 loc = TYPE_WEIGHT4; + void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } - - if (loc >= 0) + if (data_mask & MAP_CLOTHWEIGHT) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + S32 loc = TYPE_CLOTHWEIGHT; + void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); + glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } - else if (!shader) + if (data_mask & MAP_TEXTURE_INDEX) { - glClientActiveTextureARB(GL_TEXTURE1_ARB); - glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); - glClientActiveTextureARB(GL_TEXTURE0_ARB); + S32 loc = TYPE_TEXTURE_INDEX; + void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); + glVertexAttribPointerARB(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } - } - if (data_mask & MAP_BINORMAL) + if (data_mask & MAP_VERTEX) + { + S32 loc = TYPE_VERTEX; + void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); + glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); + } + } + else { - S32 loc = -1; - if (shader) + if (data_mask & MAP_NORMAL) { - loc = shader->getAttribLocation(TYPE_BINORMAL); + glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL])); } - - if (loc >= 0) + if (data_mask & MAP_TEXCOORD3) { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - else if (!shader) + if (data_mask & MAP_TEXCOORD2) { glClientActiveTextureARB(GL_TEXTURE2_ARB); - glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2])); glClientActiveTextureARB(GL_TEXTURE0_ARB); } - } - if (data_mask & MAP_TEXCOORD0) - { - S32 loc = -1; - if (shader) + if (data_mask & MAP_TEXCOORD1) { - loc = shader->getAttribLocation(TYPE_TEXCOORD0); + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - - if (loc >= 0) + if (data_mask & MAP_BINORMAL) { - glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - else if (!shader) + if (data_mask & MAP_TEXCOORD0) { glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0])); } - } - if (data_mask & MAP_COLOR) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_COLOR); - } - - if (loc >= 0) - { - glVertexAttribPointerARB(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); - } - else if (!shader) + if (data_mask & MAP_COLOR) { glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_COLOR])); } - } - if (data_mask & MAP_EMISSIVE) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_EMISSIVE); - } - - if (loc >= 0) + if (data_mask & MAP_VERTEX) { - glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE])); - } - } - if (data_mask & MAP_WEIGHT) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_WEIGHT); - } - - if (loc < 0) - { //legacy behavior, some shaders have weight hardcoded to location 1 - loc = 1; - } - - glVertexAttribPointerARB(loc, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_WEIGHT])); - - } - - if (data_mask & MAP_WEIGHT4) - { - if (shader) - { - S32 loc = shader->getAttribLocation(TYPE_WEIGHT4); - if (loc > -1) - { - glVertexAttribPointerARB(loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_WEIGHT4])); - } - } - } - - if (data_mask & MAP_CLOTHWEIGHT) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_CLOTHWEIGHT); - } - - if (loc < 0) - { //legacy behavior, some shaders have weight hardcoded to location 4 - loc = 4; - } - glVertexAttribPointerARB(loc, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_CLOTHWEIGHT])); - } - if (data_mask & MAP_VERTEX) - { - S32 loc = -1; - if (shader) - { - loc = shader->getAttribLocation(TYPE_VERTEX); - } - - if (loc >= 0) - { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexAttribPointerARB(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - } - else if (!shader) - { - if (data_mask & MAP_TEXTURE_INDEX) - { - glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - else - { - glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); - } - } + glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0)); + } } llglassertok(); } +LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count) +: mType(type), mIndex(index), mCount(count) +{ + llassert(mType == LLVertexBuffer::TYPE_INDEX || + mType < LLVertexBuffer::TYPE_TEXTURE_INDEX); +} + + |