summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2012-12-05 17:39:50 -0600
committerDave Parks <davep@lindenlab.com>2012-12-05 17:39:50 -0600
commit1ab00f6cd320df528d448cbb9bd837a55d0151f2 (patch)
tree9ffe5fb440f71f1340f3401c8082d7b77ba375e7
parent06a5cc52852d2e5b8920206a3f56bfe86ba0bae3 (diff)
MAINT-2040 Fix for rigged meshes sometimes not updating properly with color changes.
-rw-r--r--indra/newview/lldrawpoolavatar.cpp127
-rw-r--r--indra/newview/lldrawpoolavatar.h1
2 files changed, 75 insertions, 53 deletions
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 59161d063e..96718f5c9a 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1250,6 +1250,65 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
}
+void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
+{
+ face->setGeomIndex(0);
+ face->setIndicesIndex(0);
+
+ //rigged faces do not batch textures
+ face->setTextureIndex(255);
+
+ if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
+ { //make a new buffer
+ if (sShaderLevel > 0)
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+ }
+ else
+ {
+ buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ }
+ buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
+ }
+ else
+ { //resize existing buffer
+ buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
+ }
+
+ face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
+ face->setVertexBuffer(buffer);
+
+ U16 offset = 0;
+
+ LLMatrix4 mat_vert = skin->mBindShapeMatrix;
+ glh::matrix4f m((F32*) mat_vert.mMatrix);
+ m = m.inverse().transpose();
+
+ F32 mat3[] =
+ { m.m[0], m.m[1], m.m[2],
+ m.m[4], m.m[5], m.m[6],
+ m.m[8], m.m[9], m.m[10] };
+
+ LLMatrix3 mat_normal(mat3);
+
+ //let getGeometryVolume know if alpha should override shiny
+ U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+
+ if (type == LLDrawPool::POOL_ALPHA)
+ {
+ face->setPoolType(LLDrawPool::POOL_ALPHA);
+ }
+ else
+ {
+ face->setPoolType(LLDrawPool::POOL_AVATAR);
+ }
+
+ llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
+ face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
+
+ buffer->flush();
+}
+
void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
{
LLVector4a* weight = vol_face.mWeights;
@@ -1269,60 +1328,27 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
buffer->getNumIndices() != vol_face.mNumIndices ||
(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
{
- face->setGeomIndex(0);
- face->setIndicesIndex(0);
-
- //rigged faces do not batch textures
- face->setTextureIndex(255);
-
- if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
- { //make a new buffer
- if (sShaderLevel > 0)
+ if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
+ { //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
{
- buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
- }
- else
- {
- buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+ LLFace* facep = drawable->getFace(i);
+ U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
+ if (face_data_mask)
+ {
+ LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
+ const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
+ getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
+ }
}
- buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
- }
- else
- { //resize existing buffer
- buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
- }
+ drawable->clearState(LLDrawable::REBUILD_ALL);
- face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
- face->setVertexBuffer(buffer);
-
- U16 offset = 0;
-
- LLMatrix4 mat_vert = skin->mBindShapeMatrix;
- glh::matrix4f m((F32*) mat_vert.mMatrix);
- m = m.inverse().transpose();
-
- F32 mat3[] =
- { m.m[0], m.m[1], m.m[2],
- m.m[4], m.m[5], m.m[6],
- m.m[8], m.m[9], m.m[10] };
-
- LLMatrix3 mat_normal(mat3);
-
- //let getGeometryVolume know if alpha should override shiny
- U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
-
- if (type == LLDrawPool::POOL_ALPHA)
- {
- face->setPoolType(LLDrawPool::POOL_ALPHA);
+ buffer = face->getVertexBuffer();
}
else
- {
- face->setPoolType(LLDrawPool::POOL_AVATAR);
+ { //just rebuild this face
+ getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
}
-
- face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
-
- buffer->flush();
}
if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
@@ -1407,11 +1433,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
}
}
}
-
- if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
- {
- drawable->clearState(LLDrawable::REBUILD_ALL);
- }
}
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 69e3068858..5551d8f6d8 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -129,6 +129,7 @@ public:
void endDeferredRiggedSimple();
void endDeferredRiggedBump();
+ void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
LLFace* facep,
const LLMeshSkinInfo* skin,