diff options
author | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2013-10-16 11:52:43 -0400 |
---|---|---|
committer | Brad Payne (Vir Linden) <vir@lindenlab.com> | 2013-10-16 11:52:43 -0400 |
commit | 1f8b37e9ad65f8064b83adac295d9eb162976e4c (patch) | |
tree | 3ced849ad5750b7884d291e17e89fec419e03382 /indra/newview/llvovolume.cpp | |
parent | 2331b9a93b12eb0a2f5fb6109f990d81b29d0584 (diff) | |
parent | f7158bc5afcec1da8b9d2d5a4ed86921e62d4959 (diff) |
merge
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rwxr-xr-x | indra/newview/llvovolume.cpp | 303 |
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 { |