diff options
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r-- | indra/llrender/llvertexbuffer.cpp | 578 |
1 files changed, 483 insertions, 95 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index 9303e00228..de4501dd0f 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -2,30 +2,25 @@ * @file llvertexbuffer.cpp * @brief LLVertexBuffer implementation * - * $LicenseInfo:firstyear=2003&license=viewergpl$ - * - * Copyright (c) 2003-2007, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2003&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlife.com/developers/opensource/gplv2 + * Copyright (C) 2010, Linden Research, Inc. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at http://secondlife.com/developers/opensource/flossexception + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -36,8 +31,8 @@ #include "llvertexbuffer.h" // #include "llrender.h" #include "llglheaders.h" -#include "llmemory.h" #include "llmemtype.h" +#include "llrender.h" //============================================================================ @@ -59,8 +54,8 @@ U32 LLVertexBuffer::sLastMask = 0; BOOL LLVertexBuffer::sVBOActive = FALSE; BOOL LLVertexBuffer::sIBOActive = FALSE; U32 LLVertexBuffer::sAllocatedBytes = 0; -BOOL LLVertexBuffer::sRenderActive = FALSE; BOOL LLVertexBuffer::sMapped = FALSE; +BOOL LLVertexBuffer::sUseStreamDraw = TRUE; std::vector<U32> LLVertexBuffer::sDeleteList; @@ -68,14 +63,247 @@ S32 LLVertexBuffer::sTypeOffsets[LLVertexBuffer::TYPE_MAX] = { sizeof(LLVector3), // TYPE_VERTEX, sizeof(LLVector3), // TYPE_NORMAL, - sizeof(LLVector2), // TYPE_TEXCOORD, + sizeof(LLVector2), // TYPE_TEXCOORD0, + sizeof(LLVector2), // TYPE_TEXCOORD1, sizeof(LLVector2), // TYPE_TEXCOORD2, + sizeof(LLVector2), // TYPE_TEXCOORD3, sizeof(LLColor4U), // TYPE_COLOR, sizeof(LLVector3), // TYPE_BINORMAL, sizeof(F32), // TYPE_WEIGHT, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, }; +U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = +{ + GL_TRIANGLES, + GL_TRIANGLE_STRIP, + GL_TRIANGLE_FAN, + GL_POINTS, + GL_LINES, + GL_LINE_STRIP, + GL_QUADS, + GL_LINE_LOOP, +}; + +//static +void LLVertexBuffer::setupClientArrays(U32 data_mask) +{ + /*if (LLGLImmediate::sStarted) + { + llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; + }*/ + + if (sLastMask != data_mask) + { + U32 mask[] = + { + MAP_VERTEX, + MAP_NORMAL, + MAP_TEXCOORD0, + MAP_COLOR, + }; + + GLenum array[] = + { + GL_VERTEX_ARRAY, + GL_NORMAL_ARRAY, + GL_TEXTURE_COORD_ARRAY, + GL_COLOR_ARRAY, + }; + + BOOL error = FALSE; + for (U32 i = 0; i < 4; ++i) + { + if (sLastMask & mask[i]) + { //was enabled + if (!(data_mask & mask[i]) && i > 0) + { //needs to be disabled + glDisableClientState(array[i]); + } + else if (gDebugGL) + { //needs to be enabled, make sure it was (DEBUG TEMPORARY) + if (i > 0 && !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 + { //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] << " 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 + }; + + for (U32 i = 0; i < 3; i++) + { + if (sLastMask & map_tc[i]) + { + if (!(data_mask & map_tc[i])) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB+i); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + } + else if (data_mask & map_tc[i]) + { + glClientActiveTextureARB(GL_TEXTURE1_ARB+i); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + } + + if (sLastMask & MAP_BINORMAL) + { + if (!(data_mask & MAP_BINORMAL)) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + } + else if (data_mask & MAP_BINORMAL) + { + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } + + sLastMask = data_mask; + } +} + +void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const +{ + llassert(mRequestedNumVerts >= 0); + + if (start >= (U32) mRequestedNumVerts || + end >= (U32) mRequestedNumVerts) + { + llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + } + + llassert(mRequestedNumIndices >= 0); + + if (indices_offset >= (U32) mRequestedNumIndices || + indices_offset + count > (U32) mRequestedNumIndices) + { + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + } + + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + + if (mode >= LLRender::NUM_MODES) + { + llerrs << "Invalid draw mode: " << mode << llendl; + return; + } + + stop_glerror(); + glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, + ((U16*) getIndicesPointer()) + indices_offset); + stop_glerror(); +} + +void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const +{ + llassert(mRequestedNumIndices >= 0); + if (indices_offset >= (U32) mRequestedNumIndices || + indices_offset + count > (U32) mRequestedNumIndices) + { + llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + } + + if (mGLIndices != sGLRenderIndices) + { + llerrs << "Wrong index buffer bound." << llendl; + } + + if (mGLBuffer != sGLRenderBuffer) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + + if (mode >= LLRender::NUM_MODES) + { + llerrs << "Invalid draw mode: " << mode << llendl; + return; + } + + stop_glerror(); + glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, + ((U16*) getIndicesPointer()) + indices_offset); + stop_glerror(); +} + +void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const +{ + llassert(mRequestedNumVerts >= 0); + if (first >= (U32) mRequestedNumVerts || + first + count > (U32) mRequestedNumVerts) + { + llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; + } + + if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) + { + llerrs << "Wrong vertex buffer bound." << llendl; + } + + if (mode >= LLRender::NUM_MODES) + { + llerrs << "Invalid draw mode: " << mode << llendl; + return; + } + + stop_glerror(); + glDrawArrays(sGLMode[mode], first, count); + stop_glerror(); +} + //static void LLVertexBuffer::initClass(bool use_vbo) { @@ -102,41 +330,18 @@ void LLVertexBuffer::unbind() sGLRenderBuffer = 0; sGLRenderIndices = 0; - sLastMask = 0; + + setupClientArrays(0); } //static void LLVertexBuffer::cleanupClass() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - startRender(); - stopRender(); + LLMemType mt2(LLMemType::MTYPE_VERTEX_CLEANUP_CLASS); + unbind(); clientCopy(); // deletes GL buffers } -//static, call before rendering VBOs -void LLVertexBuffer::startRender() -{ - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - if (sEnableVBOs) - { - glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); - glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); - sVBOActive = FALSE; - sIBOActive = FALSE; - } - - sRenderActive = TRUE; - sGLRenderBuffer = 0; - sGLRenderIndices = 0; - sLastMask = 0; -} - -void LLVertexBuffer::stopRender() -{ - sRenderActive = FALSE; -} - void LLVertexBuffer::clientCopy(F64 max_time) { if (!sDeleteList.empty()) @@ -150,7 +355,14 @@ void LLVertexBuffer::clientCopy(F64 max_time) LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : LLRefCount(), - mNumVerts(0), mNumIndices(0), mUsage(usage), mGLBuffer(0), mGLIndices(0), + + mNumVerts(0), + mNumIndices(0), + mRequestedNumVerts(-1), + mRequestedNumIndices(-1), + mUsage(usage), + mGLBuffer(0), + mGLIndices(0), mMappedData(NULL), mMappedIndexData(NULL), mLocked(FALSE), mFinal(FALSE), @@ -159,12 +371,22 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) : mResized(FALSE), mDynamicSize(FALSE) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_CONSTRUCTOR); if (!sEnableVBOs) { mUsage = 0 ; } + + if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw) + { + mUsage = 0; + } + if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw) + { + mUsage = 0; + } + S32 stride = calcStride(typemask, mOffsets); mTypeMask = typemask; @@ -196,7 +418,7 @@ S32 LLVertexBuffer::calcStride(const U32& typemask, S32* offsets) //virtual LLVertexBuffer::~LLVertexBuffer() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTRUCTOR); destroyGLBuffer(); destroyGLIndices(); sCount--; @@ -276,8 +498,8 @@ void LLVertexBuffer::releaseIndices() void LLVertexBuffer::createGLBuffer() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); - + LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_VERTICES); + U32 size = getSize(); if (mGLBuffer) { @@ -308,7 +530,7 @@ void LLVertexBuffer::createGLBuffer() void LLVertexBuffer::createGLIndices() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_CREATE_INDICES); U32 size = getIndicesSize(); if (mGLIndices) @@ -340,7 +562,7 @@ void LLVertexBuffer::createGLIndices() void LLVertexBuffer::destroyGLBuffer() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_BUFFER); if (mGLBuffer) { if (useVBOs()) @@ -362,11 +584,12 @@ void LLVertexBuffer::destroyGLBuffer() } mGLBuffer = 0; + unbind(); } void LLVertexBuffer::destroyGLIndices() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_DESTROY_INDICES); if (mGLIndices) { if (useVBOs()) @@ -388,11 +611,14 @@ void LLVertexBuffer::destroyGLIndices() } mGLIndices = 0; + unbind(); } void LLVertexBuffer::updateNumVerts(S32 nverts) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_VERTS); + + llassert(nverts >= 0); if (nverts >= 65535) { @@ -421,7 +647,10 @@ void LLVertexBuffer::updateNumVerts(S32 nverts) void LLVertexBuffer::updateNumIndices(S32 nindices) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_UPDATE_INDICES); + + llassert(nindices >= 0); + mRequestedNumIndices = nindices; if (!mDynamicSize) { @@ -442,7 +671,7 @@ void LLVertexBuffer::updateNumIndices(S32 nindices) void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_ALLOCATE_BUFFER); updateNumVerts(nverts); updateNumIndices(nindices); @@ -462,10 +691,13 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) void LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) { + llassert(newnverts >= 0); + llassert(newnindices >= 0); + mRequestedNumVerts = newnverts; mRequestedNumIndices = newnindices; - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_RESIZE_BUFFER); mDynamicSize = TRUE; if (mUsage == GL_STATIC_DRAW_ARB) { //always delete/allocate static buffers on resize @@ -586,7 +818,7 @@ BOOL LLVertexBuffer::useVBOs() const return FALSE; } #endif - return sEnableVBOs; // && (!sRenderActive || !mLocked); + return TRUE; } //---------------------------------------------------------------------------- @@ -594,7 +826,7 @@ BOOL LLVertexBuffer::useVBOs() const // Map for data access U8* LLVertexBuffer::mapBuffer(S32 access) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_MAP_BUFFER); if (mFinal) { llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; @@ -606,15 +838,53 @@ U8* LLVertexBuffer::mapBuffer(S32 access) if (!mLocked && useVBOs()) { - setBuffer(0); - mLocked = TRUE; - mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); - /*if (sMapped) { - llerrs << "Mapped two VBOs at the same time!" << llendl; + LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_VERTICES); + setBuffer(0); + mLocked = TRUE; + stop_glerror(); + mMappedData = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + stop_glerror(); + } + { + LLMemType mt_v(LLMemType::MTYPE_VERTEX_MAP_BUFFER_INDICES); + mMappedIndexData = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB); + stop_glerror(); + } + + if (!mMappedData) + { + //-------------------- + //print out more debug info before crash + llinfos << "vertex buffer size: (num verts : num indices) = " << getNumVerts() << " : " << getNumIndices() << llendl ; + GLint size ; + glGetBufferParameterivARB(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SIZE_ARB, &size) ; + llinfos << "GL_ARRAY_BUFFER_ARB size is " << size << llendl ; + //-------------------- + + GLint buff; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLBuffer) + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + + + llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; } - sMapped = TRUE;*/ + + if (!mMappedIndexData) + { + GLint buff; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLIndices) + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + + llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + } + sMappedCount++; } @@ -623,13 +893,16 @@ U8* LLVertexBuffer::mapBuffer(S32 access) void LLVertexBuffer::unmapBuffer() { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_UNMAP_BUFFER); if (mMappedData || mMappedIndexData) { if (useVBOs() && mLocked) { + stop_glerror(); glUnmapBufferARB(GL_ARRAY_BUFFER_ARB); + stop_glerror(); glUnmapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB); + stop_glerror(); /*if (!sMapped) { @@ -666,7 +939,12 @@ template <class T,S32 type> struct VertexBufferStrider strider_t& strider, S32 index) { - vbo.mapBuffer(); + if (vbo.mapBuffer() == NULL) + { + llwarns << "mapBuffer failed!" << llendl; + return FALSE; + } + if (type == LLVertexBuffer::TYPE_INDEX) { S32 stride = sizeof(T); @@ -698,14 +976,22 @@ bool LLVertexBuffer::getIndexStrider(LLStrider<U16>& strider, S32 index) { return VertexBufferStrider<U16,TYPE_INDEX>::get(*this, strider, index); } -bool LLVertexBuffer::getTexCoordStrider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord0Strider(LLStrider<LLVector2>& strider, S32 index) { - return VertexBufferStrider<LLVector2,TYPE_TEXCOORD>::get(*this, strider, index); + return VertexBufferStrider<LLVector2,TYPE_TEXCOORD0>::get(*this, strider, index); } -bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index) +bool LLVertexBuffer::getTexCoord1Strider(LLStrider<LLVector2>& strider, S32 index) +{ + return VertexBufferStrider<LLVector2,TYPE_TEXCOORD1>::get(*this, strider, index); +} +/*bool LLVertexBuffer::getTexCoord2Strider(LLStrider<LLVector2>& strider, S32 index) { return VertexBufferStrider<LLVector2,TYPE_TEXCOORD2>::get(*this, strider, index); } +bool LLVertexBuffer::getTexCoord3Strider(LLStrider<LLVector2>& strider, S32 index) +{ + return VertexBufferStrider<LLVector2,TYPE_TEXCOORD3>::get(*this, strider, index); +}*/ bool LLVertexBuffer::getNormalStrider(LLStrider<LLVector3>& strider, S32 index) { return VertexBufferStrider<LLVector3,TYPE_NORMAL>::get(*this, strider, index); @@ -729,7 +1015,7 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider<LLVector4>& strider, S32 in void LLVertexBuffer::setStride(S32 type, S32 new_stride) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_STRIDE); if (mNumVerts) { llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; @@ -751,7 +1037,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) // Set for rendering void LLVertexBuffer::setBuffer(U32 data_mask) { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SET_BUFFER); //set up pointers if the data mask is different ... BOOL setup = (sLastMask != data_mask); @@ -763,7 +1049,9 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { 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 @@ -774,20 +1062,97 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { llerrs << "VBO bound while another VBO mapped!" << llendl; }*/ + stop_glerror(); glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, mGLIndices); + stop_glerror(); sBindCount++; sIBOActive = TRUE; } + BOOL error = FALSE; + 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: " << buff << std::endl; + } + else + { + llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + } + } + + if (mGLIndices) + { + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + if ((GLuint)buff != mGLIndices) + { + if (gDebugSession) + { + error = TRUE; + gFailLog << "Invalid GL index buffer bound: " << buff << std::endl; + } + else + { + llerrs << "Invalid GL index buffer bound: " << buff << llendl; + } + } + } + } + if (mResized) { + 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; @@ -795,17 +1160,29 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (data_mask != 0) { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; + 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 (error) + { + ll_fail("LLVertexBuffer::mapBuffer failed"); + } unmapBuffer(); } else { if (mGLBuffer) { - if (sEnableVBOs && sVBOActive) + if (sVBOActive) { glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0); sBindCount++; @@ -817,7 +1194,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) setup = TRUE; // ... or a client memory pointer changed } } - if (sEnableVBOs && mGLIndices && sIBOActive) + if (mGLIndices && sIBOActive) { /*if (sMapped) { @@ -828,6 +1205,8 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sIBOActive = FALSE; } } + + setupClientArrays(data_mask); if (mGLIndices) { @@ -838,22 +1217,16 @@ void LLVertexBuffer::setBuffer(U32 data_mask) sGLRenderBuffer = mGLBuffer; if (data_mask && setup) { - if (!sRenderActive) - { - llwarns << "Vertex buffer set for rendering outside of render frame." << llendl; - } setupVertexBuffer(data_mask); // subclass specific setup (virtual function) sSetCount++; } } - - sLastMask = data_mask; } // virtual (default) void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { - LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); + LLMemType mt2(LLMemType::MTYPE_VERTEX_SETUP_VERTEX_BUFFER); stop_glerror(); U8* base = useVBOs() ? NULL : mMappedData; S32 stride = mStride; @@ -867,24 +1240,39 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const { glNormalPointer(GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_NORMAL])); } + if (data_mask & MAP_TEXCOORD3) + { + glClientActiveTextureARB(GL_TEXTURE3_ARB); + glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD3])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); + } if (data_mask & MAP_TEXCOORD2) { - glClientActiveTextureARB(GL_TEXTURE1_ARB); + glClientActiveTextureARB(GL_TEXTURE2_ARB); glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD2])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - if (data_mask & MAP_TEXCOORD) + if (data_mask & MAP_TEXCOORD1) { + glClientActiveTextureARB(GL_TEXTURE1_ARB); + glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD1])); glClientActiveTextureARB(GL_TEXTURE0_ARB); - glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD])); } - if (data_mask & MAP_COLOR) + if (data_mask & MAP_BINORMAL) { - glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR])); + glClientActiveTextureARB(GL_TEXTURE2_ARB); + glTexCoordPointer(3,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_BINORMAL])); + glClientActiveTextureARB(GL_TEXTURE0_ARB); } - if (data_mask & MAP_BINORMAL) + if (data_mask & MAP_TEXCOORD0) { - glVertexAttribPointerARB(6, 3, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_BINORMAL])); + glTexCoordPointer(2,GL_FLOAT, stride, (void*)(base + mOffsets[TYPE_TEXCOORD0])); } + if (data_mask & MAP_COLOR) + { + glColorPointer(4, GL_UNSIGNED_BYTE, stride, (void*)(base + mOffsets[TYPE_COLOR])); + } + if (data_mask & MAP_WEIGHT) { glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, stride, (void*)(base + mOffsets[TYPE_WEIGHT])); |