diff options
Diffstat (limited to 'indra/newview/llvovolume.cpp')
-rwxr-xr-x | indra/newview/llvovolume.cpp | 280 |
1 files changed, 209 insertions, 71 deletions
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e6385dceea..17efc5482b 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 { @@ -687,7 +693,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced) } } - static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable"); + static LLCachedControl<bool> dont_load_textures(gSavedSettings,"TextureDisable", false); if (dont_load_textures || LLAppViewer::getTextureFetch()->mDebugPause) // || !mDrawable->isVisible()) { @@ -1030,8 +1036,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - - static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback"); + static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); @@ -1096,6 +1101,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 +1135,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 +1259,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 +1289,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) @@ -3021,7 +3042,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()) @@ -3895,10 +3916,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 +3977,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 +4391,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 +4406,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); @@ -4396,6 +4435,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool emissive = false; + + { LLFastTimer t(FTM_REBUILD_VOLUME_FACE_LIST); @@ -4754,7 +4795,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 { @@ -4762,7 +4806,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 @@ -4782,51 +4829,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; + } } } } @@ -4888,13 +4965,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) { @@ -4919,11 +4996,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) { @@ -4933,11 +5025,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) { @@ -4972,9 +5067,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; } } } @@ -4990,7 +5085,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(); } @@ -5002,9 +5099,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) @@ -5071,12 +5169,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", false); + + 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 @@ -5097,17 +5205,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; @@ -5136,7 +5245,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; @@ -5163,11 +5274,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); @@ -5175,12 +5291,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; @@ -5196,7 +5315,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]) { @@ -5208,7 +5327,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!found) { - cur_tex = texture_list.size(); + cur_tex = texture_count; } } else @@ -5223,7 +5342,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) @@ -5232,6 +5354,9 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } ++i; + + flexi = flexi || facep->getViewerObject()->getVolume()->isUnique(); + index_count += facep->getIndicesCount(); geom_count += facep->getGeomCount(); @@ -5247,7 +5372,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 && @@ -5268,8 +5393,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 @@ -5367,19 +5500,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 { |