diff --git a/indra/llappearance/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp index 5850fed08..aeaf79f33 100644 --- a/indra/llappearance/llpolymorph.cpp +++ b/indra/llappearance/llpolymorph.cpp @@ -77,9 +77,11 @@ LLPolyMorphData::LLPolyMorphData(const LLPolyMorphData &rhs) : { const S32 numVertices = mNumIndices; - mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); - mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); - mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + U32 size = sizeof(LLVector4a)*numVertices; + + mCoords = static_cast( ll_aligned_malloc_16(size) ); + mNormals = static_cast( ll_aligned_malloc_16(size) ); + mBinormals = static_cast( ll_aligned_malloc_16(size) ); mTexCoords = new LLVector2[numVertices]; mVertexIndices = new U32[numVertices]; @@ -125,9 +127,13 @@ BOOL LLPolyMorphData::loadBinary(LLFILE *fp, LLPolyMeshSharedData *mesh) //------------------------------------------------------------------------- // allocate vertices //------------------------------------------------------------------------- - mCoords = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); - mNormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); - mBinormals = static_cast(ll_aligned_malloc_16(numVertices * sizeof(LLVector4a))); + + U32 size = sizeof(LLVector4a)*numVertices; + + mCoords = static_cast(ll_aligned_malloc_16(size)); + mNormals = static_cast(ll_aligned_malloc_16(size)); + mBinormals = static_cast(ll_aligned_malloc_16(size)); + mTexCoords = new LLVector2[numVertices]; // Actually, we are allocating more space than we need for the skiplist mVertexIndices = new U32[numVertices]; @@ -889,17 +895,29 @@ void LLPolyMorphTarget::apply( ESex avatar_sex ) norm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); scaled_normals[vert_index_mesh].add(norm); norm = scaled_normals[vert_index_mesh]; + + // guard against degenerate input data before we create NaNs below! + // norm.normalize3fast(); normals[vert_index_mesh] = norm; // calculate new binormals LLVector4a binorm = mMorphData->mBinormals[vert_index_morph]; + + // guard against degenerate input data before we create NaNs below! + // + if (!binorm.isFinite3() || (binorm.dot3(binorm).getF32() <= F_APPROXIMATELY_ZERO)) + { + binorm.set(1,0,0,1); + } + binorm.mul(delta_weight*maskWeight*NORMAL_SOFTEN_FACTOR); scaled_binormals[vert_index_mesh].add(binorm); LLVector4a tangent; tangent.setCross3(scaled_binormals[vert_index_mesh], norm); LLVector4a& normalized_binormal = binormals[vert_index_mesh]; - normalized_binormal.setCross3(norm, tangent); + + normalized_binormal.setCross3(norm, tangent); normalized_binormal.normalize3fast(); tex_coords[vert_index_mesh] += mMorphData->mTexCoords[vert_index_morph] * delta_weight * maskWeight; diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h index 3aac66dd7..b5252d055 100644 --- a/indra/llmath/lloctree.h +++ b/indra/llmath/lloctree.h @@ -636,7 +636,10 @@ public: parent = node->getOctParent(); } - node->insert(data); + if(node != this) + { + node->insert(data); + } } return false; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 65a7fda5e..7b890c57a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -858,14 +858,25 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade { //dump every 128 lines LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; - ostr.str(""); - ostr.clear(); + ostr = std::stringstream(); } } LL_WARNS("ShaderLoading") << "\n" << ostr.str() << llendl; -#endif // LL_WINDOWS +#else + std::string str; + + for (GLuint i = 0; i < count; i++) { + str.append(text[i]); + + if (i % 128 == 0) + { + LL_WARNS("ShaderLoading") << str << llendl; + str = ""; + } + } +#endif glDeleteObjectARB(ret); //no longer need handle ret = 0; } diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h index c502d0f9f..ba4665a99 100644 --- a/indra/newview/lldrawable.h +++ b/indra/newview/lldrawable.h @@ -290,7 +290,6 @@ public: NEARBY_LIGHT = 0x00200000, // In gPipeline.mNearbyLightSet BUILT = 0x00400000, FORCE_INVISIBLE = 0x00800000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) - CLEAR_INVISIBLE = 0x01000000, // clear FORCE_INVISIBLE next draw frame REBUILD_SHADOW = 0x02000000, HAS_ALPHA = 0x04000000, RIGGED = 0x08000000, diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index bdce7b2b3..4887eb084 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -112,41 +112,6 @@ void planarProjection(LLVector2 &tc, const LLVector4a& normal, tc.mV[0] = 1.0f+((binormal.dot3(vec).getF32())*2 - 0.5f); } -void sphericalProjection(LLVector2 &tc, const LLVector4a& normal, - const LLVector4a &mCenter, const LLVector4a& vec) -{ //BROKEN - /*tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/3.14159f; - - tc.mV[1] = acosf(vd.mNormal * LLVector3(0,0,1))/6.284f; - if (vd.mNormal.mV[1] > 0) - { - tc.mV[1] = 1.0f-tc.mV[1]; - }*/ -} - -void cylindricalProjection(LLVector2 &tc, const LLVector4a& normal, const LLVector4a &mCenter, const LLVector4a& vec) -{ //BROKEN - /*LLVector3 binormal; - float d = vd.mNormal * LLVector3(1,0,0); - if (d >= 0.5f || d <= -0.5f) - { - binormal = LLVector3(0,1,0); - } - else{ - binormal = LLVector3(1,0,0); - } - LLVector3 tangent = binormal % vd.mNormal; - - tc.mV[1] = -((tangent*vec)*2 - 0.5f); - - tc.mV[0] = acosf(vd.mNormal * LLVector3(1,0,0))/6.284f; - - if (vd.mNormal.mV[1] < 0) - { - tc.mV[0] = 1.0f-tc.mV[0]; - }*/ -} - //////////////////// // // LLFace implementation @@ -942,20 +907,10 @@ LLVector2 LLFace::surfaceToTexture(LLVector2 surface_coord, LLVector3 position, volume_normal.load3(mDrawablep->getVOVolume()->agentDirectionToVolume(normal).mV); volume_normal.normalize3fast(); - switch (texgen) + if (texgen == LLTextureEntry::TEX_GEN_PLANAR) { - case LLTextureEntry::TEX_GEN_PLANAR: planarProjection(tc, volume_normal, center, volume_position); - break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, volume_normal, center, volume_position); - break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, volume_normal, center, volume_position); - break; - default: - break; - } + } } if (mTextureMatrix) // if we have a texture matrix, use it @@ -1297,19 +1252,37 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLColor4U color = (tep ? LLColor4U(tep->getColor()) : LLColor4U::white); if (rebuild_color) // FALSE if tep == NULL - { - if (tep) + { //decide if shiny goes in alpha channel of color + if (tep && + getPoolType() != LLDrawPool::POOL_ALPHA) // <--- alpha channel MUST contain transparency, not shiny { - GLfloat alpha[4] = + bool shiny_in_alpha = false; + + if (LLPipeline::sRenderDeferred) + { //store shiny in alpha if we don't have a specular map + //if (!mat || mat->getSpecularID().isNull()) + { + shiny_in_alpha = true; + } + } + else { + if(LLPipeline::sRenderBump && tep->getShiny()) + { + shiny_in_alpha = true; + } + } + if(shiny_in_alpha) + { + GLfloat alpha[4] = + { 0.00f, 0.25f, 0.5f, 0.75f - }; + }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) - { + llassert(tep->getShiny() <= 3); color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } } @@ -1644,7 +1617,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (!do_bump) { //not in atlas or not bump mapped, might be able to do a cheap update - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount); + mVertexBuffer->getTexCoord0Strider(tex_coords0, mGeomIndex, mGeomCount); if (texgen != LLTextureEntry::TEX_GEN_PLANAR) { @@ -1655,12 +1628,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { LLFastTimer t(FTM_FACE_TEX_QUICK_NO_XFORM); S32 tc_size = (num_vertices*2*sizeof(F32)+0xF) & ~0xF; - LLVector4a::memcpyNonAliased16((F32*) tex_coords.get(), (F32*) vf.mTexCoords, tc_size); + LLVector4a::memcpyNonAliased16((F32*) tex_coords0.get(), (F32*) vf.mTexCoords, tc_size); } else { LLFastTimer t(FTM_FACE_TEX_QUICK_XFORM); - F32* dst = (F32*) tex_coords.get(); + F32* dst = (F32*) tex_coords0.get(); LLVector4a* src = (LLVector4a*) vf.mTexCoords; LLVector4a trans; @@ -1706,7 +1679,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, tmp = tmp * *mTextureMatrix; tc.mV[0] = tmp.mV[0]; tc.mV[1] = tmp.mV[1]; - *tex_coords++ = tc; + *tex_coords0++ = tc; } } } @@ -1729,7 +1702,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, tc.mV[0] = tmp.mV[0]; tc.mV[1] = tmp.mV[1]; - *tex_coords++ = tc; + *tex_coords0++ = tc; } } else @@ -1745,7 +1718,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); - *tex_coords++ = tc; + *tex_coords0++ = tc; } } } @@ -1758,9 +1731,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, else { //either bump mapped or in atlas, just do the whole expensive loop LLFastTimer t(FTM_FACE_TEX_DEFAULT); - mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex, mGeomCount, map_range); std::vector bump_tc; + + LLStrider dst; + + mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range); + for (S32 i = 0; i < num_vertices; i++) { @@ -1776,20 +1753,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, vec.mul(scalea); - switch (texgen) + if (texgen == LLTextureEntry::TEX_GEN_PLANAR) { - case LLTextureEntry::TEX_GEN_PLANAR: - planarProjection(tc, norm, center, vec); - break; - case LLTextureEntry::TEX_GEN_SPHERICAL: - sphericalProjection(tc, norm, center, vec); - break; - case LLTextureEntry::TEX_GEN_CYLINDRICAL: - cylindricalProjection(tc, norm, center, vec); - break; - default: - break; - } + planarProjection(tc, norm, center, vec); + } } if (tex_mode && mTextureMatrix) @@ -1804,8 +1771,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); } - - *tex_coords++ = tc; + *dst++ = tc; if (do_bump) { bump_tc.push_back(tc); @@ -1819,7 +1785,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (do_bump) { - mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range); for (S32 i = 0; i < num_vertices; i++) { @@ -1843,10 +1809,11 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } binormal.normalize3fast(); + LLVector2 tc = bump_tc[i]; tc += LLVector2( bump_s_primary_light_ray.dot3(tangent).getF32(), bump_t_primary_light_ray.dot3(binormal).getF32() ); - *tex_coords2++ = tc; + *tex_coords1++ = tc; } if (map_range) diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 9a00bc1e6..d6e58fdc1 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -196,7 +196,7 @@ public: }; }; -LL_ALIGN_PREFIX(16) +LL_ALIGN_PREFIX(64) class LLSpatialGroup : public LLOctreeListener { friend class LLSpatialPartition; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 362048462..6429b89c7 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -2249,7 +2249,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys, if (mDrawable->isState(LLDrawable::FORCE_INVISIBLE) && !mOrphaned) { // lldebugs << "Clearing force invisible: " << mID << ":" << getPCodeString() << ":" << getPositionAgent() << llendl; - mDrawable->setState(LLDrawable::CLEAR_INVISIBLE); + mDrawable->clearState(LLDrawable::FORCE_INVISIBLE); + gPipeline.markRebuild( mDrawable, LLDrawable::REBUILD_ALL, TRUE ); } } diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp index c4aa02be9..dfe5db84b 100644 --- a/indra/newview/llviewerobjectlist.cpp +++ b/indra/newview/llviewerobjectlist.cpp @@ -2164,8 +2164,9 @@ void LLViewerObjectList::findOrphans(LLViewerObject* objectp, U32 ip, U32 port) if (childp->mDrawable.notNull()) { // Make the drawable visible again and set the drawable parent - childp->mDrawable->setState(LLDrawable::CLEAR_INVISIBLE); + childp->mDrawable->clearState(LLDrawable::FORCE_INVISIBLE); childp->setDrawableParent(objectp->mDrawable); // LLViewerObjectList::findOrphans() + gPipeline.markRebuild( childp->mDrawable, LLDrawable::REBUILD_ALL, TRUE ); } // Make certain particles, icon and HUD aren't hidden diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index eea72a9f7..465df0465 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -1043,6 +1043,7 @@ void LLVOSurfacePatch::updateSpatialExtents(LLVector4a& newMin, LLVector4a &newM { LLVector3 posAgent = getPositionAgent(); LLVector3 scale = getScale(); + //make z-axis scale at least 1 to avoid shadow artifacts on totally flat land scale.mV[VZ] = llmax(scale.mV[VZ], 1.f); newMin.load3( (posAgent-scale*0.5f).mV); // Changing to 2.f makes the culling a -little- better, but still wrong newMax.load3( (posAgent+scale*0.5f).mV); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 808d80d59..80f9dd3e5 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -4128,7 +4128,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd += facep->getGeomCount(); draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); - if (index >= draw_vec[idx]->mTextureList.size()) + if (index < 255 && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; @@ -4449,6 +4449,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool can_be_shiny = mode == LLMaterial::DIFFUSE_ALPHA_MODE_NONE || mode == LLMaterial::DIFFUSE_ALPHA_MODE_EMISSIVE; + bool is_deferred_simple = LLPipeline::sRenderDeferred && !fullbright; if (mode == LLMaterial::DIFFUSE_ALPHA_MODE_MASK && te->getColor().mV[3] >= 0.999f) { pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); @@ -4459,18 +4460,21 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_ALPHA : LLDrawPoolAvatar::RIGGED_ALPHA); } + is_deferred_simple = false; } else if (gPipeline.canUseVertexShaders() && LLPipeline::sRenderBump && te->getShiny() && can_be_shiny) { - pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : LLDrawPoolAvatar::RIGGED_SHINY); + pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT_SHINY : !LLPipeline::sRenderDeferred ? LLDrawPoolAvatar::RIGGED_SHINY : LLDrawPoolAvatar::RIGGED_SIMPLE); } else { pool->addRiggedFace(facep, fullbright ? LLDrawPoolAvatar::RIGGED_FULLBRIGHT : LLDrawPoolAvatar::RIGGED_SIMPLE); } + if(is_deferred_simple) + pool->addRiggedFace(facep, LLDrawPoolAvatar::RIGGED_DEFERRED_SIMPLE); } else { @@ -5209,7 +5213,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: && te->getShiny() && can_be_shiny) { - registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : LLRenderPass::PASS_SHINY); + registerFace(group, facep, fullbright ? LLRenderPass::PASS_FULLBRIGHT_SHINY : (!LLPipeline::sRenderDeferred || hud_group) ? LLRenderPass::PASS_SHINY : LLRenderPass::PASS_SIMPLE); } else { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7ae7dffc9..c57ab4219 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1415,12 +1415,32 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima return 0; } - bool alpha = te->getColor().mV[3] < 0.999f; + LLMaterial* mat = te->getMaterialParams().get(); + + bool color_alpha = te->getColor().mV[3] < 0.999f; + bool alpha = color_alpha; if (imagep) { alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2); } - + + if (alpha && mat) + { + switch (mat->getDiffuseAlphaMode()) + { + case 1: + alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool. + break; + case 0: //alpha mode set to none, never go to alpha pool + case 3: //alpha mode set to emissive, never go to alpha pool + alpha = color_alpha; + break; + default: //alpha mode set to "mask", go to alpha pool if fullbright + alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool. + break; + } + } + if (alpha) { return LLDrawPool::POOL_ALPHA; @@ -2405,17 +2425,6 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) BOOL update_complete = drawablep->updateGeometry(priority); if (update_complete && assertInitialized()) { - //Workaround for 'missing prims' until it's fixed upstream by LL. - //Sometimes clearing CLEAR_INVISIBLE and FORCE_INVISIBLE in LLPipeline::stateSort was too late. Do it here instead, before - //the rebuild state is picked up on and LLVolumeGeometryManager::rebuildGeom is called. - //If the FORCE_INVISIBLE isn't cleared before the rebuildGeom call, the geometry will NOT BE REBUILT! - if(drawablep->isState(LLDrawable::CLEAR_INVISIBLE)) - { - // clear invisible flag here to avoid single frame glitch - drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE); - return false; //Defer to next mBuildQ1 iteration - } - drawablep->setState(LLDrawable::BUILT); mGeometryChanges++; } @@ -3162,11 +3171,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) { drawablep->setVisible(camera, NULL, FALSE); } - else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE)) - { - // clear invisible flag here to avoid single frame glitch - drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE); - } } if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) @@ -9739,11 +9743,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector4a left; left.load3(camera.getLeftAxis().mV); left.mul(left); + llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO); left.normalize3fast(); LLVector4a up; up.load3(camera.getUpAxis().mV); up.mul(up); + llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO); up.normalize3fast(); tdim.mV[0] = fabsf(half_height.dot3(left).getF32());