summaryrefslogtreecommitdiff
path: root/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
authorBrad Payne (Vir Linden) <vir@lindenlab.com>2013-10-16 11:52:43 -0400
committerBrad Payne (Vir Linden) <vir@lindenlab.com>2013-10-16 11:52:43 -0400
commit1f8b37e9ad65f8064b83adac295d9eb162976e4c (patch)
tree3ced849ad5750b7884d291e17e89fec419e03382 /indra/newview/llvovolume.cpp
parent2331b9a93b12eb0a2f5fb6109f990d81b29d0584 (diff)
parentf7158bc5afcec1da8b9d2d5a4ed86921e62d4959 (diff)
merge
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rwxr-xr-xindra/newview/llvovolume.cpp303
1 files changed, 232 insertions, 71 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index fab900cc74..5fdd2894a6 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -101,6 +101,8 @@ static LLFastTimer::DeclareTimer FTM_GEN_TRIANGLES("Generate Triangles");
static LLFastTimer::DeclareTimer FTM_GEN_VOLUME("Generate Volumes");
static LLFastTimer::DeclareTimer FTM_VOLUME_TEXTURES("Volume Textures");
+extern BOOL gGLDebugLoggingEnabled;
+
// Implementation class of LLMediaDataClientObject. See llmediadataclient.h
class LLMediaDataClientObjectImpl : public LLMediaDataClientObject
{
@@ -384,7 +386,6 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
}
else
{
- // CORY TO DO: Figure out how to get the value here
if (update_type != OUT_TERSE_IMPROVED)
{
LLVolumeParams volume_params;
@@ -453,6 +454,11 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
mFaceMappingChanged = TRUE;
mTexAnimMode = 0;
}
+
+ if (value & 0x400)
+ { //particle system (new)
+ unpackParticleSource(*dp, mOwnerID, false);
+ }
}
else
{
@@ -1096,6 +1102,12 @@ void LLVOVolume::notifyMeshLoaded()
{
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
+
+ LLVOAvatar* avatar = getAvatar();
+ if (avatar)
+ {
+ avatar->updateVisualComplexity();
+ }
}
// sculpt replaces generate() for sculpted surfaces
@@ -1124,28 +1136,38 @@ void LLVOVolume::sculpt()
S32 current_discard = getVolume()->getSculptLevel() ;
if(current_discard < -2)
{
- static S32 low_sculpty_discard_warning_count = 100;
- if (++low_sculpty_discard_warning_count >= 100)
- { // Log first time, then every 100 afterwards otherwise this can flood the logs
+ static S32 low_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) low_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( low_sculpty_discard_warning_count < 10 ||
+ (low_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
<< " at " << current_discard
- << " is less than -2." << llendl;
- low_sculpty_discard_warning_count = 0;
+ << " is less than -2."
+ << " Hit this " << low_sculpty_discard_warning_count << " times"
+ << llendl;
}
+ low_sculpty_discard_warning_count++;
// corrupted volume... don't update the sculpty
return;
}
else if (current_discard > MAX_DISCARD_LEVEL)
{
- static S32 high_sculpty_discard_warning_count = 100;
- if (++high_sculpty_discard_warning_count >= 100)
- { // Log first time, then every 100 afterwards otherwise this can flood the logs
+ static S32 high_sculpty_discard_warning_count = 1;
+ S32 exponent = llmax(1, llfloor( log10((F64) high_sculpty_discard_warning_count) ));
+ S32 interval = pow(10.0, exponent);
+ if ( high_sculpty_discard_warning_count < 10 ||
+ (high_sculpty_discard_warning_count % interval) == 0)
+ { // Log first 10 time, then decreasing intervals afterwards otherwise this can flood the logs
llwarns << "WARNING!!: Current discard for sculpty " << mSculptTexture->getID()
<< " at " << current_discard
- << " is more than than allowed max of " << MAX_DISCARD_LEVEL << llendl;
- high_sculpty_discard_warning_count = 0;
+ << " is more than than allowed max of " << MAX_DISCARD_LEVEL
+ << ". Hit this " << high_sculpty_discard_warning_count << " times"
+ << llendl;
}
+ high_sculpty_discard_warning_count++;
// corrupted volume... don't update the sculpty
return;
@@ -1238,7 +1260,7 @@ BOOL LLVOVolume::calcLOD()
else
{
distance = mDrawable->mDistanceWRTCamera;
- radius = getVolume()->mLODScaleBias.scaledVec(getScale()).length();
+ radius = getVolume() ? getVolume()->mLODScaleBias.scaledVec(getScale()).length() : getScale().length();
}
//hold onto unmodified distance for debugging
@@ -1268,7 +1290,7 @@ BOOL LLVOVolume::calcLOD()
{
//setDebugText(llformat("%.2f:%.2f, %d", debug_distance, radius, cur_detail));
- setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
+ //setDebugText(llformat("%d", mDrawable->getFace(0)->getTextureIndex()));
}
if (cur_detail != mLOD)
@@ -2596,6 +2618,7 @@ void LLVOVolume::setLightTextureID(LLUUID id)
if (hasLightTexture())
{
setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true);
+ parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true);
mLightTexture = NULL;
}
}
@@ -2613,7 +2636,8 @@ void LLVOVolume::setSpotLightParams(LLVector3 params)
void LLVOVolume::setIsLight(BOOL is_light)
{
- if (is_light != getIsLight())
+ BOOL was_light = getIsLight();
+ if (is_light != was_light)
{
if (is_light)
{
@@ -2798,7 +2822,7 @@ void LLVOVolume::updateSpotLightPriority()
bool LLVOVolume::isLightSpotlight() const
{
LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
- if (params)
+ if (params && getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE))
{
return params->isLightSpotlight();
}
@@ -3021,7 +3045,7 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p
//transform view vector into volume space
view_vector -= getRenderPosition();
- mDrawable->mDistanceWRTCamera = view_vector.length();
+ //mDrawable->mDistanceWRTCamera = view_vector.length();
LLQuaternion worldRot = getRenderRotation();
view_vector = view_vector * ~worldRot;
if (!isVolumeGlobal())
@@ -3728,8 +3752,30 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a&
{
LLFace* face = mDrawable->getFace(face_hit);
+ bool ignore_alpha = false;
+
+ const LLTextureEntry* te = face->getTextureEntry();
+ if (te)
+ {
+ LLMaterial* mat = te->getMaterialParams();
+ if (mat)
+ {
+ U8 mode = mat->getDiffuseAlphaMode();
+
+ if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE ||
+ mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE)
+ {
+ ignore_alpha = true;
+ }
+ }
+ }
+
if (face &&
- (pick_transparent || !face->getTexture() || !face->getTexture()->hasGLTexture() || face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
+ (ignore_alpha ||
+ pick_transparent ||
+ !face->getTexture() ||
+ !face->getTexture()->hasGLTexture() ||
+ face->getTexture()->getMask(face->surfaceToTexture(tc, p, n))))
{
local_end = p;
if (face_hitp != NULL)
@@ -3895,10 +3941,13 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
}
//build matrix palette
- LLMatrix4a mp[64];
+ static const size_t kMaxJoints = 64;
+
+ LLMatrix4a mp[kMaxJoints];
LLMatrix4* mat = (LLMatrix4*) mp;
- for (U32 j = 0; j < skin->mJointNames.size(); ++j)
+ U32 maxJoints = llmin(skin->mJointNames.size(), kMaxJoints);
+ for (U32 j = 0; j < maxJoints; ++j)
{
LLJoint* joint = avatar->getJoint(skin->mJointNames[j]);
if (joint)
@@ -3953,8 +4002,10 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
F32 w = wght[k];
LLMatrix4a src;
- src.setMul(mp[idx[k]], w);
-
+ // Insure ref'd bone is in our clamped array of mats
+ llassert(idx[k] < kMaxJoints);
+ // clamp k to kMaxJoints to avoid reading garbage off stack in release
+ src.setMul(mp[idx[(k < kMaxJoints) ? k : 0]], w);
final_mat.add(src);
}
@@ -4365,7 +4416,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (pAvatarVO)
{
pAvatarVO->mAttachmentGeometryBytes -= group->mGeometryBytes;
+ pAvatarVO->mAttachmentGeometryBytes = llmax(pAvatarVO->mAttachmentGeometryBytes, 0);
pAvatarVO->mAttachmentSurfaceArea -= group->mSurfaceArea;
+ pAvatarVO->mAttachmentSurfaceArea = llmax(pAvatarVO->mAttachmentSurfaceArea, 0.f);
}
group->mGeometryBytes = 0;
@@ -4378,14 +4431,25 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
mFaceList.clear();
- std::vector<LLFace*> fullbright_faces;
- std::vector<LLFace*> bump_faces;
- std::vector<LLFace*> norm_faces;
- std::vector<LLFace*> spec_faces;
- std::vector<LLFace*> normspec_faces;
- std::vector<LLFace*> simple_faces;
+ const U32 MAX_FACE_COUNT = 4096;
+
+ static LLFace** fullbright_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** bump_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** simple_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+ static LLFace** norm_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** spec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** normspec_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*), 64);
+ static LLFace** alpha_faces = (LLFace**) ll_aligned_malloc(MAX_FACE_COUNT*sizeof(LLFace*),64);
+
+ U32 fullbright_count = 0;
+ U32 bump_count = 0;
+ U32 simple_count = 0;
+ U32 alpha_count = 0;
+ U32 norm_count = 0;
+ U32 spec_count = 0;
+ U32 normspec_count = 0;
+
- std::vector<LLFace*> alpha_faces;
U32 useage = group->mSpatialPartition->mBufferUsage;
U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcVertexSize(group->mSpatialPartition->mVertexDataMask);
@@ -4752,7 +4816,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (facep->canRenderAsMask())
{ //can be treated as alpha mask
- simple_faces.push_back(facep);
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
}
else
{
@@ -4760,7 +4827,10 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{ //only treat as alpha in the pipeline if < 100% transparent
drawablep->setState(LLDrawable::HAS_ALPHA);
}
- alpha_faces.push_back(facep);
+ if (alpha_count < MAX_FACE_COUNT)
+ {
+ alpha_faces[alpha_count++] = facep;
+ }
}
}
else
@@ -4780,51 +4850,81 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (mat->getSpecularID().notNull())
{ //has normal and specular maps (needs texcoord1, texcoord2, and tangent)
- normspec_faces.push_back(facep);
+ if (normspec_count < MAX_FACE_COUNT)
+ {
+ normspec_faces[normspec_count++] = facep;
+ }
}
else
{ //has normal map (needs texcoord1 and tangent)
- norm_faces.push_back(facep);
+ if (norm_count < MAX_FACE_COUNT)
+ {
+ norm_faces[norm_count++] = facep;
+ }
}
}
else if (mat->getSpecularID().notNull())
{ //has specular map but no normal map, needs texcoord2
- spec_faces.push_back(facep);
+ if (spec_count < MAX_FACE_COUNT)
+ {
+ spec_faces[spec_count++] = facep;
+ }
}
else
{ //has neither specular map nor normal map, only needs texcoord0
- simple_faces.push_back(facep);
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
}
}
else if (te->getBumpmap())
{ //needs normal + tangent
- bump_faces.push_back(facep);
+ if (bump_count < MAX_FACE_COUNT)
+ {
+ bump_faces[bump_count++] = facep;
+ }
}
else if (te->getShiny() || !te->getFullbright())
{ //needs normal
- simple_faces.push_back(facep);
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
}
else
{ //doesn't need normal
facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ if (fullbright_count < MAX_FACE_COUNT)
+ {
+ fullbright_faces[fullbright_count++] = facep;
+ }
}
}
else
{
if (te->getBumpmap() && LLPipeline::sRenderBump)
{ //needs normal + tangent
- bump_faces.push_back(facep);
+ if (bump_count < MAX_FACE_COUNT)
+ {
+ bump_faces[bump_count++] = facep;
+ }
}
else if ((te->getShiny() && LLPipeline::sRenderBump) ||
!(te->getFullbright() || bake_sunlight))
{ //needs normal
- simple_faces.push_back(facep);
+ if (simple_count < MAX_FACE_COUNT)
+ {
+ simple_faces[simple_count++] = facep;
+ }
}
else
{ //doesn't need normal
facep->setState(LLFace::FULLBRIGHT);
- fullbright_faces.push_back(facep);
+ if (fullbright_count < MAX_FACE_COUNT)
+ {
+ fullbright_faces[fullbright_count++] = facep;
+ }
}
}
}
@@ -4895,13 +4995,13 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
- genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, FALSE, batch_textures, FALSE);
- genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, FALSE, batch_textures);
- genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, TRUE, batch_textures);
- genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, FALSE, FALSE);
- genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, FALSE, FALSE);
- genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, FALSE, FALSE);
- genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, FALSE, FALSE);
+ genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, simple_faces, simple_count, FALSE, batch_textures, FALSE);
+ genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, fullbright_faces, fullbright_count, FALSE, batch_textures);
+ genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, alpha_faces, alpha_count, TRUE, batch_textures);
+ genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, bump_faces, bump_count, FALSE, FALSE);
+ genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, norm_faces, norm_count, FALSE, FALSE);
+ genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, spec_faces, spec_count, FALSE, FALSE);
+ genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, normspec_faces, normspec_count, FALSE, FALSE);
if (!LLPipeline::sDelayVBUpdate)
{
@@ -4926,11 +5026,26 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (pAvatarVO)
{
+ if (pAvatarVO->mAttachmentGeometryBytes < 0)
+ { // First time through value is -1
+ pAvatarVO->mAttachmentGeometryBytes = group->mGeometryBytes;
+ }
+ else
+ {
pAvatarVO->mAttachmentGeometryBytes += group->mGeometryBytes;
+ }
+ if (pAvatarVO->mAttachmentSurfaceArea < 0.f)
+ { // First time through value is -1
+ pAvatarVO->mAttachmentSurfaceArea = group->mSurfaceArea;
+ }
+ else
+ {
pAvatarVO->mAttachmentSurfaceArea += group->mSurfaceArea;
}
}
+}
+static LLFastTimer::DeclareTimer FTM_REBUILD_MESH_FLUSH("Flush Mesh");
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
@@ -4940,11 +5055,14 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
LLFastTimer ftm(FTM_REBUILD_VOLUME_VB);
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO); //make sure getgeometryvolume shows up in the right place in timers
- S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
-
group->mBuilt = 1.f;
- std::set<LLVertexBuffer*> mapped_buffers;
+ S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ;
+
+ const U32 MAX_BUFFER_COUNT = 4096;
+ LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT];
+
+ U32 buffer_count = 0;
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
{
@@ -4979,9 +5097,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
- if (buff->isLocked())
+ if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT)
{
- mapped_buffers.insert(buff);
+ locked_buffer[buffer_count++] = buff;
}
}
}
@@ -4997,7 +5115,9 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
}
}
- for (std::set<LLVertexBuffer*>::iterator iter = mapped_buffers.begin(); iter != mapped_buffers.end(); ++iter)
+ {
+ LLFastTimer t(FTM_REBUILD_MESH_FLUSH);
+ for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter)
{
(*iter)->flush();
}
@@ -5009,9 +5129,10 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
group->mVertexBuffer->flush();
}
+ }
//if not all buffers are unmapped
- if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
+ if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount)
{
llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter)
@@ -5078,12 +5199,22 @@ static LLFastTimer::DeclareTimer FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
-void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
+void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
LLFastTimer t(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
U32 buffer_usage = group->mBufferUsage;
+ static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback");
+
+ if (use_transform_feedback &&
+ gTransformPositionProgram.mProgramObject && //transform shaders are loaded
+ buffer_usage == GL_DYNAMIC_DRAW_ARB && //target buffer is in VRAM
+ !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights
+ {
+ buffer_usage = GL_DYNAMIC_COPY_ARB;
+ }
+
#if LL_DARWIN
// HACK from Leslie:
// Disable VBO usage for alpha on Mac OS X because it kills the framerate
@@ -5104,17 +5235,18 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
if (!distance_sort)
{
//sort faces by things that break batches
- std::sort(faces.begin(), faces.end(), CompareBatchBreakerModified());
+ std::sort(faces, faces+face_count, CompareBatchBreakerModified());
}
else
{
//sort faces by distance
- std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
+ std::sort(faces, faces+face_count, LLFace::CompareDistanceGreater());
}
}
bool hud_group = group->isHUDGroup() ;
- std::vector<LLFace*>::iterator face_iter = faces.begin();
+ LLFace** face_iter = faces;
+ LLFace** end_faces = faces+face_count;
LLSpatialGroup::buffer_map_t buffer_map;
@@ -5143,7 +5275,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
//NEVER use more than 16 texture index channels (workaround for prevalent driver bug)
texture_index_channels = llmin(texture_index_channels, 16);
- while (face_iter != faces.end())
+ bool flexi = false;
+
+ while (face_iter != end_faces)
{
//pull off next face
LLFace* facep = *face_iter;
@@ -5170,11 +5304,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
U32 index_count = facep->getIndicesCount();
U32 geom_count = facep->getGeomCount();
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
//sum up vertices needed for this render batch
- std::vector<LLFace*>::iterator i = face_iter;
+ LLFace** i = face_iter;
++i;
- std::vector<LLViewerTexture*> texture_list;
+ const U32 MAX_TEXTURE_COUNT = 32;
+ LLViewerTexture* texture_list[MAX_TEXTURE_COUNT];
+
+ U32 texture_count = 0;
{
LLFastTimer t(FTM_GEN_DRAW_INFO_FACE_SIZE);
@@ -5182,12 +5321,15 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
{
U8 cur_tex = 0;
facep->setTextureIndex(cur_tex);
- texture_list.push_back(tex);
+ if (texture_count < MAX_TEXTURE_COUNT)
+ {
+ texture_list[texture_count++] = tex;
+ }
if (can_batch_texture(facep))
{ //populate texture_list with any textures that can be batched
//move i to the next unbatchable face
- while (i != faces.end())
+ while (i != end_faces)
{
facep = *i;
@@ -5203,7 +5345,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
if (distance_sort)
{ //textures might be out of order, see if texture exists in current batch
bool found = false;
- for (U32 tex_idx = 0; tex_idx < texture_list.size(); ++tex_idx)
+ for (U32 tex_idx = 0; tex_idx < texture_count; ++tex_idx)
{
if (facep->getTexture() == texture_list[tex_idx])
{
@@ -5215,7 +5357,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
if (!found)
{
- cur_tex = texture_list.size();
+ cur_tex = texture_count;
}
}
else
@@ -5230,7 +5372,10 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
tex = facep->getTexture();
- texture_list.push_back(tex);
+ if (texture_count < MAX_TEXTURE_COUNT)
+ {
+ texture_list[texture_count++] = tex;
+ }
}
if (geom_count + facep->getGeomCount() > max_vertices)
@@ -5239,6 +5384,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
++i;
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
@@ -5254,7 +5402,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
else
{
- while (i != faces.end() &&
+ while (i != end_faces &&
(LLPipeline::sTextureBindTest ||
(distance_sort ||
((*i)->getTexture() == tex &&
@@ -5275,8 +5423,16 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
++i;
index_count += facep->getIndicesCount();
geom_count += facep->getGeomCount();
+
+ flexi = flexi || facep->getViewerObject()->getVolume()->isUnique();
+ }
}
}
+
+
+ if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW_ARB)
+ {
+ buffer_usage = GL_STREAM_DRAW_ARB;
}
//create vertex buffer
@@ -5374,19 +5530,24 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE;
}
- bool use_legacy_bump = te->getBumpmap() && (!mat || mat->getNormalID().isNull());
+ bool use_legacy_bump = te->getBumpmap() && (te->getBumpmap() < 18) && (!mat || mat->getNormalID().isNull());
+ bool opaque = te->getColor().mV[3] >= 0.999f;
if (mat && LLPipeline::sRenderDeferred && !hud_group)
{
bool material_pass = false;
- if (fullbright)
+ // do NOT use 'fullbright' for this logic or you risk sending
+ // things without normals down the materials pipeline and will
+ // render poorly if not crash NORSPEC-240,314
+ //
+ if (te->getFullbright())
{
if (mat->getDiffuseAlphaMode() == LLMaterial::DIFFUSE_ALPHA_MODE_MASK)
{
- if (te->getColor().mV[3] >= 0.999f)
+ if (opaque)
{
- material_pass = true;
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
}
else
{