summaryrefslogtreecommitdiff
path: root/indra/llrender/llvertexbuffer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llrender/llvertexbuffer.cpp')
-rw-r--r--indra/llrender/llvertexbuffer.cpp464
1 files changed, 390 insertions, 74 deletions
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index 8fd1193780..bb8f067e8d 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -63,7 +63,6 @@ U32 LLVertexBuffer::sAllocatedBytes = 0;
BOOL LLVertexBuffer::sMapped = FALSE;
BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
BOOL LLVertexBuffer::sPreferStreamDraw = FALSE;
-S32 LLVertexBuffer::sWeight4Loc = -1;
std::vector<U32> LLVertexBuffer::sDeleteList;
@@ -131,6 +130,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector2), // TYPE_TEXCOORD2,
sizeof(LLVector2), // TYPE_TEXCOORD3,
sizeof(LLColor4U), // TYPE_COLOR,
+ sizeof(U8), // TYPE_EMISSIVE
sizeof(LLVector4), // TYPE_BINORMAL,
sizeof(F32), // TYPE_WEIGHT,
sizeof(LLVector4), // TYPE_WEIGHT4,
@@ -157,36 +157,79 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
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 < 4; ++i)
+ for (U32 i = 0; i < 9; ++i)
{
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(type[i]);
+ }
+
if (sLastMask & mask[i])
{ //was enabled
- if (!(data_mask & mask[i]) && i > 0)
+ if (!(data_mask & mask[i]))
{ //needs to be disabled
- glDisableClientState(array[i]);
+ if (loc >= 0)
+ {
+ glDisableVertexAttribArrayARB(loc);
+ }
+ else if (!shader)
+ {
+ glDisableClientState(array[i]);
+ }
}
- else if (gDebugGL)
- { //needs to be enabled, make sure it was (DEBUG TEMPORARY)
- if (i > 0 && !glIsEnabled(array[i]))
+ else if (gDebugGL && !shader && array[i])
+ { //needs to be enabled, make sure it was (DEBUG)
+ if (loc < 0 && !glIsEnabled(array[i]))
{
if (gDebugSession)
{
@@ -202,11 +245,18 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
else
{ //was disabled
- if (data_mask & mask[i] && i > 0)
+ if (data_mask & mask[i])
{ //needs to be enabled
- glEnableClientState(array[i]);
+ if (loc >= 0)
+ {
+ glEnableVertexAttribArrayARB(loc);
+ }
+ else if (!shader)
+ {
+ glEnableClientState(array[i]);
+ }
}
- else if (gDebugGL && i > 0 && glIsEnabled(array[i]))
+ else if (!shader && array[i] && gDebugGL && glIsEnabled(array[i]))
{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
if (gDebugSession)
{
@@ -233,62 +283,71 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
MAP_TEXCOORD3
};
+ U32 type_tc[] =
+ {
+ TYPE_TEXCOORD1,
+ TYPE_TEXCOORD2,
+ TYPE_TEXCOORD3
+ };
+
for (U32 i = 0; i < 3; i++)
{
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(type_tc[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);
+ { //disable
+ if (loc >= 0)
+ {
+ glDisableVertexAttribArrayARB(loc);
+ }
+ else if (!shader)
+ {
+ 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 (loc >= 0)
+ {
+ glEnableVertexAttribArrayARB(loc);
+ }
+ else if (!shader)
+ {
+ glClientActiveTextureARB(GL_TEXTURE1_ARB+i);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
}
- if (sLastMask & MAP_BINORMAL)
+ if (!shader)
{
- if (!(data_mask & MAP_BINORMAL))
+ if (sLastMask & MAP_BINORMAL)
{
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ 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);
- }
-
- if (sLastMask & MAP_WEIGHT4)
- {
- if (sWeight4Loc < 0)
+ else if (data_mask & MAP_BINORMAL)
{
- llerrs << "Weighting disabled but vertex buffer still bound!" << llendl;
- }
-
- if (!(data_mask & MAP_WEIGHT4))
- { //disable 4-component skin weight
- glDisableVertexAttribArrayARB(sWeight4Loc);
- }
- }
- else if (data_mask & MAP_WEIGHT4)
- {
- if (sWeight4Loc >= 0)
- { //enable 4-component skin weight
- glEnableVertexAttribArrayARB(sWeight4Loc);
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
}
}
-
-
+
sLastMask = data_mask;
}
}
@@ -296,6 +355,8 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
//static
void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
{
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
U32 count = pos.size();
llassert_always(norm.size() >= pos.size());
llassert_always(count > 0) ;
@@ -304,12 +365,73 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, con
setupClientArrays(MAP_VERTEX | MAP_NORMAL);
- glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
- glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ if (shader)
+ {
+ S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX);
+ if (loc > -1)
+ {
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, pos[0].mV);
+ }
+ loc = shader->getAttribLocation(LLVertexBuffer::TYPE_NORMAL);
+ if (loc > -1)
+ {
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, 0, norm[0].mV);
+ }
+ }
+ else
+ {
+ glVertexPointer(3, GL_FLOAT, 0, pos[0].mV);
+ glNormalPointer(GL_FLOAT, 0, norm[0].mV);
+ }
glDrawArrays(sGLMode[mode], 0, count);
}
+//static
+void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp)
+{
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
+ U32 mask = LLVertexBuffer::MAP_VERTEX;
+ if (tc)
+ {
+ mask = mask | LLVertexBuffer::MAP_TEXCOORD0;
+ }
+
+ unbind();
+
+ setupClientArrays(mask);
+
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ if (shader)
+ {
+ S32 loc = shader->getAttribLocation(LLVertexBuffer::TYPE_VERTEX);
+ if (loc > -1)
+ {
+ 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);
+ }
+ }
+ }
+ }
+ else
+ {
+ glTexCoordPointer(2, GL_FLOAT, 0, tc);
+ glVertexPointer(3, GL_FLOAT, 16, pos);
+ }
+
+ glDrawElements(sGLMode[mode], num_indices, GL_UNSIGNED_SHORT, indicesp);
+}
+
void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const
{
if (start >= (U32) mRequestedNumVerts ||
@@ -344,6 +466,7 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
validateRange(start, end, count, indices_offset);
llassert(mRequestedNumVerts >= 0);
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
if (mGLIndices != sGLRenderIndices)
{
@@ -372,6 +495,8 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi
void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
{
+ llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
+
llassert(mRequestedNumIndices >= 0);
if (indices_offset >= (U32) mRequestedNumIndices ||
indices_offset + count > (U32) mRequestedNumIndices)
@@ -404,6 +529,8 @@ 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);
+
llassert(mRequestedNumVerts >= 0);
if (first >= (U32) mRequestedNumVerts ||
first + count > (U32) mRequestedNumVerts)
@@ -1601,6 +1728,10 @@ 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)
+{
+ return VertexBufferStrider<U8,TYPE_EMISSIVE>::get(*this, strider, index, count, map_range);
+}
bool LLVertexBuffer::getWeightStrider(LLStrider<F32>& strider, S32 index, S32 count, bool map_range)
{
return VertexBufferStrider<F32,TYPE_WEIGHT>::get(*this, strider, index, count, map_range);
@@ -1625,6 +1756,34 @@ void LLVertexBuffer::setBuffer(U32 data_mask, S32 type)
//set up pointers if the data mask is different ...
BOOL setup = (sLastMask != data_mask);
+ if (gDebugGL && data_mask != 0)
+ {
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ if (shader)
+ {
+ U32 required_mask = 0;
+ for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i)
+ {
+ if (shader->getAttribLocation(i) > -1)
+ {
+ U32 required = 1 << i;
+ if ((data_mask & required) == 0)
+ {
+ llwarns << "Missing attribute: " << i << llendl;
+ }
+
+ required_mask |= required;
+
+ }
+ }
+
+ if ((data_mask & required_mask) != required_mask)
+ {
+ llerrs << "Shader consumption mismatches data provision." << llendl;
+ }
+ }
+ }
+
if (useVBOs())
{
if (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive))
@@ -1819,66 +1978,223 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const
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)
{
- glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_NORMAL);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ }
+ else if (!shader)
+ {
+ glNormalPointer(GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_NORMAL], (void*)(base + mOffsets[TYPE_NORMAL]));
+ }
}
if (data_mask & MAP_TEXCOORD3)
{
- glClientActiveTextureARB(GL_TEXTURE3_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_TEXCOORD3);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+ }
+ else if (!shader)
+ {
+ glClientActiveTextureARB(GL_TEXTURE3_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], (void*)(base + mOffsets[TYPE_TEXCOORD3]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
if (data_mask & MAP_TEXCOORD2)
{
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_TEXCOORD2);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+ }
+ else if (!shader)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], (void*)(base + mOffsets[TYPE_TEXCOORD2]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
if (data_mask & MAP_TEXCOORD1)
{
- glClientActiveTextureARB(GL_TEXTURE1_ARB);
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_TEXCOORD1);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+ }
+ else if (!shader)
+ {
+ glClientActiveTextureARB(GL_TEXTURE1_ARB);
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], (void*)(base + mOffsets[TYPE_TEXCOORD1]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
if (data_mask & MAP_BINORMAL)
{
- glClientActiveTextureARB(GL_TEXTURE2_ARB);
- glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
- glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_BINORMAL);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ }
+ else if (!shader)
+ {
+ glClientActiveTextureARB(GL_TEXTURE2_ARB);
+ glTexCoordPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_BINORMAL], (void*)(base + mOffsets[TYPE_BINORMAL]));
+ glClientActiveTextureARB(GL_TEXTURE0_ARB);
+ }
}
if (data_mask & MAP_TEXCOORD0)
{
- glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ S32 loc = -1;
+ if (shader)
+ {
+ loc = shader->getAttribLocation(TYPE_TEXCOORD0);
+ }
+
+ if (loc >= 0)
+ {
+ glVertexAttribPointerARB(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ }
+ else if (!shader)
+ {
+ glTexCoordPointer(2,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], (void*)(base + mOffsets[TYPE_TEXCOORD0]));
+ }
}
if (data_mask & MAP_COLOR)
{
- glColorPointer(4, GL_UNSIGNED_BYTE, LLVertexBuffer::sTypeSize[TYPE_COLOR], (void*)(base + mOffsets[TYPE_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)
+ {
+ 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)
+ {
+ glVertexAttribPointerARB(loc, 1, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], (void*)(base + mOffsets[TYPE_EMISSIVE]));
+ }
}
-
if (data_mask & MAP_WEIGHT)
{
- glVertexAttribPointerARB(1, 1, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], (void*)(base + mOffsets[TYPE_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 && sWeight4Loc != -1)
+ if (data_mask & MAP_WEIGHT4)
{
- glVertexAttribPointerARB(sWeight4Loc, 4, GL_FLOAT, FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], (void*)(base+mOffsets[TYPE_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)
{
- glVertexAttribPointerARB(4, 4, GL_FLOAT, TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], (void*)(base + mOffsets[TYPE_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)
{
- if (data_mask & MAP_TEXTURE_INDEX)
+ S32 loc = -1;
+ if (shader)
{
- glVertexPointer(4,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 0));
+ loc = shader->getAttribLocation(TYPE_VERTEX);
}
- else
+
+ if (loc >= 0)
{
- glVertexPointer(3,GL_FLOAT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], (void*)(base + 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));
+ }
}
}