summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llmath/llvolume.cpp7
-rw-r--r--indra/llmath/llvolume.h2
-rw-r--r--indra/llprimitive/llmaterialid.cpp5
-rw-r--r--indra/llprimitive/llmaterialid.h1
-rw-r--r--indra/llprimitive/llprimitive.cpp10
-rw-r--r--indra/llprimitive/llprimitive.h5
-rw-r--r--indra/llrender/CMakeLists.txt2
-rw-r--r--indra/llrender/llgl.h17
-rw-r--r--indra/llrender/llglcommonfunc.cpp37
-rw-r--r--indra/llrender/llglcommonfunc.h30
-rw-r--r--indra/llrender/llglslshader.cpp62
-rw-r--r--indra/llrender/llglslshader.h11
-rw-r--r--indra/llrender/llvertexbuffer.cpp16
-rw-r--r--indra/llrender/llvertexbuffer.h4
-rw-r--r--indra/llxml/llcontrol.h3
-rw-r--r--indra/newview/CMakeLists.txt2
-rw-r--r--indra/newview/app_settings/settings.xml15
-rw-r--r--indra/newview/lldrawable.cpp43
-rw-r--r--indra/newview/lldrawable.h3
-rw-r--r--indra/newview/lldrawpool.cpp5
-rw-r--r--indra/newview/lldrawpoolalpha.cpp16
-rw-r--r--indra/newview/lldrawpoolavatar.cpp11
-rw-r--r--indra/newview/lldrawpoolmaterials.cpp4
-rw-r--r--indra/newview/llface.cpp16
-rw-r--r--indra/newview/llmaniprotate.cpp1
-rw-r--r--indra/newview/llmanipscale.cpp1
-rw-r--r--indra/newview/llmaniptranslate.cpp5
-rw-r--r--indra/newview/llmaterialmgr.cpp38
-rw-r--r--indra/newview/llmaterialmgr.h6
-rw-r--r--indra/newview/llmeshrepository.cpp2
-rw-r--r--indra/newview/llsculptidsize.cpp154
-rw-r--r--indra/newview/llsculptidsize.h134
-rw-r--r--indra/newview/llselectmgr.cpp167
-rw-r--r--indra/newview/llspatialpartition.cpp4
-rw-r--r--indra/newview/llspatialpartition.h4
-rw-r--r--indra/newview/llviewercamera.cpp10
-rw-r--r--indra/newview/llviewercamera.h3
-rw-r--r--indra/newview/llviewercontrol.cpp2
-rw-r--r--indra/newview/llviewerdisplay.cpp4
-rw-r--r--indra/newview/llviewerobject.cpp8
-rw-r--r--indra/newview/llviewerobject.h1
-rw-r--r--indra/newview/llvieweroctree.cpp2
-rw-r--r--indra/newview/llviewerpartsim.cpp3
-rw-r--r--indra/newview/llviewershadermgr.cpp1
-rw-r--r--indra/newview/llvograss.cpp2
-rw-r--r--indra/newview/llvopartgroup.cpp24
-rw-r--r--indra/newview/llvopartgroup.h3
-rw-r--r--indra/newview/llvovolume.cpp225
-rw-r--r--indra/newview/llvovolume.h9
-rw-r--r--indra/newview/pipeline.cpp43
-rw-r--r--indra/newview/pipeline.h2
51 files changed, 949 insertions, 236 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 648f9a8d93..6b6cd65ce2 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -545,7 +545,7 @@ void LLProfile::genNGon(const LLProfileParams& params, S32 sides, F32 offset, F3
{
// Generate an n-sided "circular" path.
// 0 is (1,0), and we go counter-clockwise along a circular path from there.
- const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
F32 scale = 0.5f;
F32 t, t_step, t_first, t_fraction, ang, ang_step;
LLVector4a pt1,pt2;
@@ -1304,7 +1304,7 @@ S32 LLPath::getNumNGonPoints(const LLPathParams& params, S32 sides, F32 startOff
void LLPath::genNGon(const LLPathParams& params, S32 sides, F32 startOff, F32 end_scale, F32 twist_scale)
{
// Generates a circular path, starting at (1, 0, 0), counterclockwise along the xz plane.
- const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
+ static const F32 tableScale[] = { 1, 1, 1, 0.5f, 0.707107f, 0.53f, 0.525f, 0.5f };
F32 revolutions = params.getRevolutions();
F32 skew = params.getSkew();
@@ -1602,7 +1602,8 @@ BOOL LLPath::generate(const LLPathParams& params, F32 detail, S32 split,
if (is_sculpted)
sides = llmax(sculpt_size, 1);
- genNGon(params, sides);
+ if (0 < sides)
+ genNGon(params, sides);
}
break;
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 4357b69b90..d3c1ac46fe 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -1089,7 +1089,7 @@ public:
F32 mSurfaceArea; //unscaled surface area
BOOL mIsMeshAssetLoaded;
- LLVolumeParams mParams;
+ const LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
LLAlignedArray<LLVector4a,64> mMesh;
diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp
index 820f62c43c..f88a607c4f 100644
--- a/indra/llprimitive/llmaterialid.cpp
+++ b/indra/llprimitive/llmaterialid.cpp
@@ -61,6 +61,11 @@ LLMaterialID::LLMaterialID(const LLMaterialID& pOtherMaterialID)
copyFromOtherMaterialID(pOtherMaterialID);
}
+LLMaterialID::LLMaterialID(const LLUUID& lluid)
+{
+ set(lluid.mData);
+}
+
LLMaterialID::~LLMaterialID()
{
}
diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h
index b4c82d3b7b..ee663f8f99 100644
--- a/indra/llprimitive/llmaterialid.h
+++ b/indra/llprimitive/llmaterialid.h
@@ -40,6 +40,7 @@ public:
LLMaterialID(const LLSD::Binary& pMaterialID);
LLMaterialID(const void* pMemory);
LLMaterialID(const LLMaterialID& pOtherMaterialID);
+ LLMaterialID(const LLUUID& lluid);
~LLMaterialID();
bool operator == (const LLMaterialID& pOtherMaterialID) const;
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index bfa65666b5..edf7c41e40 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -732,6 +732,16 @@ S32 face_index_from_id(LLFaceID face_ID, const std::vector<LLProfile::Face>& fac
BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume)
{
+ if (NO_LOD == detail)
+ {
+ // build the new object
+ setChanged(GEOMETRY);
+ sVolumeManager->unrefVolume(mVolumep);
+ mVolumep = new LLVolume(volume_params, 1, TRUE, TRUE);
+ setNumTEs(mVolumep->getNumFaces());
+ return FALSE;
+ }
+
LLVolume *volumep;
if (unique_volume)
{
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 19d9d52817..99a32e614c 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -489,6 +489,11 @@ protected:
public:
static LLVolumeMgr* sVolumeManager;
+
+ enum
+ {
+ NO_LOD = -1
+ };
};
inline BOOL LLPrimitive::isAvatar() const
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 331f988382..07a0d8c402 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -51,6 +51,7 @@ set(llrender_SOURCE_FILES
lltexture.cpp
lluiimage.cpp
llvertexbuffer.cpp
+ llglcommonfunc.cpp
)
set(llrender_HEADER_FILES
@@ -78,6 +79,7 @@ set(llrender_HEADER_FILES
lltexture.h
lluiimage.h
llvertexbuffer.h
+ llglcommonfunc.h
)
set_source_files_properties(${llrender_HEADER_FILES}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index aa98b3f6bc..4c4302d05b 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -256,6 +256,9 @@ void clear_glerror();
if the existing GL state does not match the expected GL state.
*/
+
+#include "boost/function.hpp"
+
class LLGLState
{
public:
@@ -297,6 +300,20 @@ public:
LLGLEnableAlphaReject(bool enable);
};
+// Enable with functor
+class LLGLEnableFunc : LLGLState
+{
+public:
+ LLGLEnableFunc(LLGLenum state, bool enable, boost::function<void()> func)
+ : LLGLState(state, enable)
+ {
+ if (enable)
+ {
+ func();
+ }
+ }
+};
+
/// TODO: Being deprecated.
class LLGLEnable : public LLGLState
{
diff --git a/indra/llrender/llglcommonfunc.cpp b/indra/llrender/llglcommonfunc.cpp
new file mode 100644
index 0000000000..e9ec28927f
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.cpp
@@ -0,0 +1,37 @@
+/**
+* @file llglcommonfunc.cpp
+* @brief Implementation of the LLGLCommonFunc.
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llglheaders.h"
+#include "llglcommonfunc.h"
+
+namespace LLGLCommonFunc
+{
+ void selected_stencil_test()
+ {
+ glStencilFunc(GL_ALWAYS, 2, 0xffff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+ }
+}
diff --git a/indra/llrender/llglcommonfunc.h b/indra/llrender/llglcommonfunc.h
new file mode 100644
index 0000000000..f1f8ff7bc4
--- /dev/null
+++ b/indra/llrender/llglcommonfunc.h
@@ -0,0 +1,30 @@
+/**
+* @file llphoenixfunc.h
+* @brief File include common opengl code snippets
+*
+* $LicenseInfo:firstyear=2003&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+namespace LLGLCommonFunc
+{
+ void selected_stencil_test();
+}
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 970502f2d6..4702042ab9 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -537,7 +537,11 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
mAttribute.clear();
U32 numAttributes = (attributes == NULL) ? 0 : attributes->size();
+#if LL_RELEASE_WITH_DEBUG_INFO
+ mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, { -1, NULL });
+#else
mAttribute.resize(LLShaderMgr::instance()->mReservedAttribs.size() + numAttributes, -1);
+#endif
if (res)
{ //read back channel locations
@@ -551,7 +555,11 @@ BOOL LLGLSLShader::mapAttributes(const std::vector<LLStaticHashedString> * attri
S32 index = glGetAttribLocationARB(mProgramObject, (const GLcharARB *)name);
if (index != -1)
{
+#if LL_RELEASE_WITH_DEBUG_INFO
+ mAttribute[i] = { index, name };
+#else
mAttribute[i] = index;
+#endif
mAttributeMask |= 1 << i;
LL_DEBUGS("ShaderLoading") << "Attribute " << name << " assigned to channel " << index << LL_ENDL;
}
@@ -744,24 +752,25 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
, even if the "diffuseMap" will be appear and use first in shader code.
As example where this situation appear see: "Deferred Material Shader 28/29/30/31"
- And tickets: MAINT-4165, MAINT-4839, MAINT-3568
+ And tickets: MAINT-4165, MAINT-4839, MAINT-3568, MAINT-6437
*/
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
+ S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set<S32> skip_index;
- if (-1 != diffuseMap && (-1 != bumpMap || -1 != environmentMap))
+ if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024];
- diffuseMap = bumpMap = environmentMap = -1;
+ diffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
{
@@ -775,6 +784,18 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
+
+ if (-1 == specularMap && std::string(name) == "specularMap")
+ {
+ specularMap = i;
+ continue;
+ }
+
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
@@ -788,34 +809,29 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
}
}
+ bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
bool bumpLessDiff = bumpMap < diffuseMap && -1 != bumpMap;
bool envLessDiff = environmentMap < diffuseMap && -1 != environmentMap;
- if (bumpLessDiff && envLessDiff)
+ if (specularDiff || bumpLessDiff || envLessDiff)
{
mapUniform(diffuseMap, uniforms);
- mapUniform(bumpMap, uniforms);
- mapUniform(environmentMap, uniforms);
-
skip_index.insert(diffuseMap);
- skip_index.insert(bumpMap);
- skip_index.insert(environmentMap);
- }
- else if (bumpLessDiff)
- {
- mapUniform(diffuseMap, uniforms);
- mapUniform(bumpMap, uniforms);
- skip_index.insert(diffuseMap);
- skip_index.insert(bumpMap);
- }
- else if (envLessDiff)
- {
- mapUniform(diffuseMap, uniforms);
- mapUniform(environmentMap, uniforms);
+ if (-1 != specularMap) {
+ mapUniform(specularMap, uniforms);
+ skip_index.insert(specularMap);
+ }
- skip_index.insert(diffuseMap);
- skip_index.insert(environmentMap);
+ if (-1 != bumpMap) {
+ mapUniform(bumpMap, uniforms);
+ skip_index.insert(bumpMap);
+ }
+
+ if (-1 != environmentMap) {
+ mapUniform(environmentMap, uniforms);
+ skip_index.insert(environmentMap);
+ }
}
}
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 6f10d122cb..b56b914013 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -167,7 +167,18 @@ public:
U32 mLightHash;
GLhandleARB mProgramObject;
+#if LL_RELEASE_WITH_DEBUG_INFO
+ struct attr_name
+ {
+ GLint loc;
+ const char *name;
+ void operator = (GLint _loc) { loc = _loc; }
+ operator GLint () { return loc; }
+ };
+ std::vector<attr_name> mAttribute; //lookup table of attribute enum to attribute channel
+#else
std::vector<GLint> mAttribute; //lookup table of attribute enum to attribute channel
+#endif
U32 mAttributeMask; //mask of which reserved attributes are set (lines up with LLVertexBuffer::getTypeMask())
std::vector<GLint> mUniform; //lookup table of uniform enum to uniform location
LLStaticStringTable<GLint> mUniformMap; //lookup map of uniform name to uniform location
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index a55ca5ed9c..e3e605d040 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -327,7 +327,7 @@ void LLVBOPool::cleanup()
//NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware
-S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
+const S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
{
sizeof(LLVector4), // TYPE_VERTEX,
sizeof(LLVector4), // TYPE_NORMAL,
@@ -344,7 +344,7 @@ S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] =
sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes
};
-static std::string vb_type_name[] =
+static const std::string vb_type_name[] =
{
"TYPE_VERTEX",
"TYPE_NORMAL",
@@ -363,7 +363,7 @@ static std::string vb_type_name[] =
"TYPE_INDEX",
};
-U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
+const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] =
{
GL_TRIANGLES,
GL_TRIANGLE_STRIP,
@@ -512,7 +512,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
}
}
- U32 map_tc[] =
+ static const U32 map_tc[] =
{
MAP_TEXCOORD1,
MAP_TEXCOORD2,
@@ -1382,7 +1382,7 @@ void LLVertexBuffer::setupVertexArray()
#endif
sGLRenderArray = mGLArray;
- U32 attrib_size[] =
+ static const U32 attrib_size[] =
{
3, //TYPE_VERTEX,
3, //TYPE_NORMAL,
@@ -1399,7 +1399,7 @@ void LLVertexBuffer::setupVertexArray()
1, //TYPE_TEXTURE_INDEX
};
- U32 attrib_type[] =
+ static const U32 attrib_type[] =
{
GL_FLOAT, //TYPE_VERTEX,
GL_FLOAT, //TYPE_NORMAL,
@@ -1416,7 +1416,7 @@ void LLVertexBuffer::setupVertexArray()
GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX
};
- bool attrib_integer[] =
+ static const bool attrib_integer[] =
{
false, //TYPE_VERTEX,
false, //TYPE_NORMAL,
@@ -1433,7 +1433,7 @@ void LLVertexBuffer::setupVertexArray()
true, //TYPE_TEXTURE_INDEX
};
- U32 attrib_normalized[] =
+ static const U32 attrib_normalized[] =
{
GL_FALSE, //TYPE_VERTEX,
GL_FALSE, //TYPE_NORMAL,
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index bd27296eb6..c89d7e3958 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -341,8 +341,8 @@ public:
static bool sDisableVBOMapping; //disable glMapBufferARB
static bool sEnableVBOs;
- static S32 sTypeSize[TYPE_MAX];
- static U32 sGLMode[LLRender::NUM_MODES];
+ static const S32 sTypeSize[TYPE_MAX];
+ static const U32 sGLMode[LLRender::NUM_MODES];
static U32 sGLRenderBuffer;
static U32 sGLRenderArray;
static U32 sGLRenderIndices;
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index 77065dcf8d..8136a3e88a 100644
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -357,7 +357,8 @@ private:
mCachedValue = convert_from_llsd<T>(controlp->get(), mType, name);
// Add a listener to the controls signal...
- mConnection = controlp->getSignal()->connect(
+ // NOTE: All listeners connected to 0 group, for guaranty that variable handlers (gSavedSettings) call last
+ mConnection = controlp->getSignal()->connect(0,
boost::bind(&LLControlCache<T>::handleValueChange, this, _2)
);
mType = controlp->type();
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 23337ddbfb..1629c49276 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -530,6 +530,7 @@ set(viewer_SOURCE_FILES
llscriptfloater.cpp
llscrollingpanelparam.cpp
llscrollingpanelparambase.cpp
+ llsculptidsize.cpp
llsearchcombobox.cpp
llsearchhistory.cpp
llsecapi.cpp
@@ -1143,6 +1144,7 @@ set(viewer_HEADER_FILES
llscriptruntimeperms.h
llscrollingpanelparam.h
llscrollingpanelparambase.h
+ llsculptidsize.h
llsearchcombobox.h
llsearchhistory.h
llsecapi.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index bbd7f65383..b2b3b6bb05 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4646,6 +4646,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>IgnoreFOVZoomForLODs</key>
+ <map>
+ <key>Comment</key>
+ <string>Ignore zoom effect(CTRL+0) when calculating lods.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>0</integer>
+ </map>
<key>IgnoreAllNotifications</key>
<map>
<key>Comment</key>
@@ -10170,9 +10181,9 @@
<key>RenderAutoMuteByteLimit</key>
<map>
<key>Comment</key>
- <string>OBSOLETE and UNUSED.</string>
+ <string>If avatar attachment size exceed this value (in bytes) attachment will not be rendered. Excludes attachments worn by own avatar.</string>
<key>Persist</key>
- <integer>0</integer>
+ <integer>1</integer>
<key>Type</key>
<string>U32</string>
<key>Value</key>
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index f956023358..6ca8f1ae9c 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -50,6 +50,7 @@
#include "llviewerobjectlist.h"
#include "llviewerwindow.h"
#include "llvocache.h"
+#include "lldrawpoolavatar.h"
const F32 MIN_INTERPOLATE_DISTANCE_SQUARED = 0.001f * 0.001f;
const F32 MAX_INTERPOLATE_DISTANCE_SQUARED = 10.f * 10.f;
@@ -143,6 +144,28 @@ void LLDrawable::init(bool new_entry)
initVisible(sCurVisible - 2);//invisible for the current frame and the last frame.
}
+void LLDrawable::unload()
+{
+ LLVOVolume *pVVol = getVOVolume();
+ pVVol->setNoLOD();
+
+ for (S32 i = 0; i < getNumFaces(); i++)
+ {
+ LLFace* facep = getFace(i);
+ if (facep->isState(LLFace::RIGGED))
+ {
+ LLDrawPoolAvatar* pool = (LLDrawPoolAvatar*)facep->getPool();
+ if (pool) {
+ pool->removeRiggedFace(facep);
+ }
+ facep->setVertexBuffer(NULL);
+ }
+ facep->clearState(LLFace::RIGGED);
+ }
+
+ pVVol->markForUpdate(TRUE);
+}
+
// static
void LLDrawable::initClass()
{
@@ -595,7 +618,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
BOOL damped = !undamped;
// Position
- LLVector3 old_pos(mXform.getPosition());
+ const LLVector3 old_pos(mXform.getPosition());
LLVector3 target_pos;
if (mXform.isRoot())
{
@@ -609,7 +632,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
}
// Rotation
- LLQuaternion old_rot(mXform.getRotation());
+ const LLQuaternion old_rot(mXform.getRotation());
LLQuaternion target_rot = mVObjp->getRotation();
//scaling
LLVector3 target_scale = mVObjp->getScale();
@@ -644,6 +667,9 @@ F32 LLDrawable::updateXform(BOOL undamped)
{
// snap to final position (only if no target omega is applied)
dist_squared = 0.0f;
+ //set target scale here, because of dist_squared = 0.0f remove object from move list
+ mCurrentScale = target_scale;
+
if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
@@ -660,11 +686,16 @@ F32 LLDrawable::updateXform(BOOL undamped)
//dist_squared += dist_vec_squared(old_scale, target_scale);
}
- LLVector3 vec = mCurrentScale-target_scale;
+ const LLVector3 vec = mCurrentScale-target_scale;
+
+ //It's a very important on each cycle on Drawable::update form(), when object remained in move
+ //, list update the CurrentScale member, because if do not do that, it remained in this list forever
+ //or when the delta time between two frames a become a sufficiently large (due to interpolation)
+ //for overcome the MIN_INTERPOLATE_DISTANCE_SQUARED.
+ mCurrentScale = target_scale;
if (vec*vec > MIN_INTERPOLATE_DISTANCE_SQUARED)
{ //scale change requires immediate rebuild
- mCurrentScale = target_scale;
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
else if (!isRoot() &&
@@ -979,9 +1010,7 @@ void LLDrawable::updateSpatialExtents()
if (mVObjp)
{
const LLVector4a* exts = getSpatialExtents();
- LLVector4a extents[2];
- extents[0] = exts[0];
- extents[1] = exts[1];
+ LLVector4a extents[2] = { exts[0], exts[1] };
mVObjp->updateSpatialExtents(extents[0], extents[1]);
setSpatialExtents(extents[0], extents[1]);
diff --git a/indra/newview/lldrawable.h b/indra/newview/lldrawable.h
index a3461d4c01..14d782d6f2 100644
--- a/indra/newview/lldrawable.h
+++ b/indra/newview/lldrawable.h
@@ -84,6 +84,7 @@ public:
void markDead(); // Mark this drawable as dead
BOOL isDead() const { return isState(DEAD); }
BOOL isNew() const { return !isState(BUILT); }
+ BOOL isUnload() const { return isState(FOR_UNLOAD); }
BOOL isLight() const;
@@ -141,6 +142,7 @@ public:
void mergeFaces(LLDrawable* src);
void init(bool new_entry);
+ void unload();
void destroy();
void update();
@@ -282,6 +284,7 @@ public:
PARTITION_MOVE = 0x10000000,
ANIMATED_CHILD = 0x20000000,
ACTIVE_CHILD = 0x40000000,
+ FOR_UNLOAD = 0x80000000, //should be unload from memory
} EDrawableFlags;
public:
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index f74164aea6..075375082d 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -49,6 +49,7 @@
#include "llviewercamera.h"
#include "lldrawpoolwlsky.h"
#include "llglslshader.h"
+#include "llglcommonfunc.h"
S32 LLDrawPool::sNumDrawPools = 0;
@@ -504,7 +505,9 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba
{
params.mGroup->rebuildMesh();
}
-
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 60056ac21d..32630237ce 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -47,6 +47,7 @@
#include "llviewerregion.h"
#include "lldrawpoolwater.h"
#include "llspatialpartition.h"
+#include "llglcommonfunc.h"
BOOL LLDrawPoolAlpha::sShowDebugAlpha = FALSE;
@@ -583,11 +584,14 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_PUSH);
- gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
- params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
-
- params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
- gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
+ gGL.blendFunc((LLRender::eBlendFactor) params.mBlendFuncSrc, (LLRender::eBlendFactor) params.mBlendFuncDst, mAlphaSFactor, mAlphaDFactor);
+ params.mVertexBuffer->setBuffer(mask & ~(params.mFullbright ? (LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2) : 0));
+
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
}
// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow). Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha.
@@ -597,7 +601,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, S32 pass)
{
// install glow-accumulating blend mode
gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color
- LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
+ LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow)
emissive_shader->bind();
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 8128790eb6..ef69990170 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -1574,6 +1574,11 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
LLPointer<LLVertexBuffer> buffer = face->getVertexBuffer();
LLDrawable* drawable = face->getDrawable();
+ if (drawable->getVOVolume() && drawable->getVOVolume()->isNoLOD())
+ {
+ return;
+ }
+
U32 data_mask = face->getRiggedVertexBufferDataMask();
if (!vol_face.mWeightsScrubbed)
@@ -1621,7 +1626,9 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(
return;
}
- if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
+ if (!buffer.isNull() &&
+ sShaderLevel <= 0 &&
+ face->mLastSkinTime < avatar->getLastSkinTime())
{
//perform software vertex skinning for this face
LLStrider<LLVector3> position;
@@ -1914,7 +1921,7 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
LLVOVolume* vobj = drawable->getVOVolume();
- if (!vobj)
+ if (!vobj || vobj->isNoLOD())
{
continue;
}
diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp
index f92320490a..63e96a93b5 100644
--- a/indra/newview/lldrawpoolmaterials.cpp
+++ b/indra/newview/lldrawpoolmaterials.cpp
@@ -30,6 +30,7 @@
#include "lldrawpoolmaterials.h"
#include "llviewershadermgr.h"
#include "pipeline.h"
+#include "llglcommonfunc.h"
S32 diffuse_channel = -1;
@@ -211,6 +212,9 @@ void LLDrawPoolMaterials::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture,
{
params.mGroup->rebuildMesh();
}
+
+ LLGLEnableFunc stencil_test(GL_STENCIL_TEST, params.mSelected, &LLGLCommonFunc::selected_stencil_test);
+
params.mVertexBuffer->setBuffer(mask);
params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 50a4925c37..7f7d7f3dcc 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -53,6 +53,7 @@
#include "llviewershadermgr.h"
#include "llviewertexture.h"
#include "llvoavatar.h"
+#include "llsculptidsize.h"
#if LL_LINUX
// Work-around spurious used before init warning on Vector4a
@@ -2650,12 +2651,27 @@ LLViewerTexture* LLFace::getTexture(U32 ch) const
void LLFace::setVertexBuffer(LLVertexBuffer* buffer)
{
+ if (buffer)
+ {
+ LLSculptIDSize::instance().inc(mDrawablep, buffer->getSize() + buffer->getIndicesSize());
+ }
+
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
+
mVertexBuffer = buffer;
llassert(verify());
}
void LLFace::clearVertexBuffer()
{
+ if (mVertexBuffer)
+ {
+ LLSculptIDSize::instance().dec(mDrawablep);
+ }
+
mVertexBuffer = NULL;
}
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 7bd5e4cba2..f158aae3d2 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -283,6 +283,7 @@ void LLManipRotate::render()
LLGLEnable cull_face(GL_CULL_FACE);
LLGLEnable clip_plane0(GL_CLIP_PLANE0);
LLGLDepthTest gls_depth(GL_FALSE);
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
// First pass: centers. Second pass: sides.
for( S32 i=0; i<2; i++ )
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 8b2ac4f303..9a8222d941 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -754,6 +754,7 @@ void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
LLGLDepthTest gls_depth(GL_FALSE);
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
gGL.pushMatrix();
{
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 785022792b..92a09357c8 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1060,6 +1060,7 @@ void LLManipTranslate::render()
renderGuidelines();
}
{
+ LLGLDisable gls_stencil(GL_STENCIL_TEST);
renderTranslationHandles();
renderSnapGuides();
}
@@ -1638,8 +1639,8 @@ void LLManipTranslate::highlightIntersection(LLVector3 normal,
LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
- U32 num_types = LL_ARRAY_SIZE(types);
+ static const U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_ALPHA, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY };
+ static const U32 num_types = LL_ARRAY_SIZE(types);
GLuint stencil_mask = 0xFFFFFFFF;
//stencil in volumes
diff --git a/indra/newview/llmaterialmgr.cpp b/indra/newview/llmaterialmgr.cpp
index d9fc489b4e..52b9fb40ae 100644
--- a/indra/newview/llmaterialmgr.cpp
+++ b/indra/newview/llmaterialmgr.cpp
@@ -350,6 +350,25 @@ void LLMaterialMgr::remove(const LLUUID& object_id, const U8 te)
put(object_id, te, LLMaterial::null);
}
+void LLMaterialMgr::setLocalMaterial(const LLUUID& region_id, LLMaterialPtr material_ptr)
+{
+ LLUUID uuid;
+ uuid.generate();
+ LLMaterialID material_id(uuid);
+ while (mMaterials.end() != mMaterials.find(material_id))
+ { //probability that this loop will executed is very, very low (one in a billion chance)
+ uuid.generate();
+ material_id.set(uuid.mData);
+ }
+
+ LL_DEBUGS("Materials") << "region " << region_id << "new local material id " << material_id << LL_ENDL;
+ mMaterials.insert(std::pair<LLMaterialID, LLMaterialPtr>(material_id, material_ptr));
+
+ setMaterialCallbacks(material_id, material_ptr);
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+}
+
const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data)
{
LL_DEBUGS("Materials") << "region " << region_id << " material id " << material_id << LL_ENDL;
@@ -362,17 +381,26 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
itMaterial = ret.first;
}
+ setMaterialCallbacks(material_id, itMaterial->second);
+
+ mGetPending.erase(pending_material_t(region_id, material_id));
+
+ return itMaterial->second;
+}
+
+void LLMaterialMgr::setMaterialCallbacks(const LLMaterialID& material_id, const LLMaterialPtr material_ptr)
+{
TEMaterialPair te_mat_pair;
te_mat_pair.materialID = material_id;
U32 i = 0;
- while (i < LLTEContents::MAX_TES)
+ while (i < LLTEContents::MAX_TES && !mGetTECallbacks.empty())
{
te_mat_pair.te = i++;
get_callback_te_map_t::iterator itCallbackTE = mGetTECallbacks.find(te_mat_pair);
if (itCallbackTE != mGetTECallbacks.end())
{
- (*itCallbackTE->second)(material_id, itMaterial->second, te_mat_pair.te);
+ (*itCallbackTE->second)(material_id, material_ptr, te_mat_pair.te);
delete itCallbackTE->second;
mGetTECallbacks.erase(itCallbackTE);
}
@@ -381,15 +409,11 @@ const LLMaterialPtr LLMaterialMgr::setMaterial(const LLUUID& region_id, const LL
get_callback_map_t::iterator itCallback = mGetCallbacks.find(material_id);
if (itCallback != mGetCallbacks.end())
{
- (*itCallback->second)(material_id, itMaterial->second);
+ (*itCallback->second)(material_id, material_ptr);
delete itCallback->second;
mGetCallbacks.erase(itCallback);
}
-
- mGetPending.erase(pending_material_t(region_id, material_id));
-
- return itMaterial->second;
}
void LLMaterialMgr::onGetResponse(bool success, const LLSD& content, const LLUUID& region_id)
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 60b58d17de..843dc66fbc 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -56,6 +56,9 @@ public:
boost::signals2::connection getAll(const LLUUID& region_id, getall_callback_t::slot_type cb);
void put(const LLUUID& object_id, const U8 te, const LLMaterial& material);
void remove(const LLUUID& object_id, const U8 te);
+
+ //explicitly add new material to material manager
+ void setLocalMaterial(const LLUUID& region_id, LLMaterialPtr material_ptr);
private:
void clearGetQueues(const LLUUID& region_id);
@@ -63,7 +66,8 @@ private:
bool isGetAllPending(const LLUUID& region_id) const;
void markGetPending(const LLUUID& region_id, const LLMaterialID& material_id);
const LLMaterialPtr setMaterial(const LLUUID& region_id, const LLMaterialID& material_id, const LLSD& material_data);
-
+ void setMaterialCallbacks(const LLMaterialID& material_id, const LLMaterialPtr material_ptr);
+
static void onIdle(void*);
static void CapsRecvForRegion(const LLUUID& regionId, LLUUID regionTest, std::string pumpname);
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 71a161198a..5b6720c3c7 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -4027,7 +4027,7 @@ void LLMeshRepository::uploadModel(std::vector<LLModelInstance>& data, LLVector3
S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
{
- if (mThread && mesh_id.notNull())
+ if (mThread && mesh_id.notNull() && LLPrimitive::NO_LOD != lod)
{
LLMutexLock lock(mThread->mHeaderMutex);
LLMeshRepoThread::mesh_header_map::iterator iter = mThread->mMeshHeader.find(mesh_id);
diff --git a/indra/newview/llsculptidsize.cpp b/indra/newview/llsculptidsize.cpp
new file mode 100644
index 0000000000..9edd78bff0
--- /dev/null
+++ b/indra/newview/llsculptidsize.cpp
@@ -0,0 +1,154 @@
+/**
+* @file llsculptidsize.cpp
+* @brief LLSculptIDSize class implementation
+*
+* $LicenseInfo:firstyear=2002&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+#include "llsculptidsize.h"
+#include "llvovolume.h"
+#include "lldrawable.h"
+#include "llvoavatar.h"
+//boost
+#include "boost/make_shared.hpp"
+
+//...........
+
+extern LLControlGroup gSavedSettings;
+
+//...........
+
+typedef std::pair<LLSculptIDSize::container_BY_SCULPT_ID_view::iterator, LLSculptIDSize::container_BY_SCULPT_ID_view::iterator> pair_iter_iter_BY_SCULPT_ID_t;
+
+//...........
+
+void _nothing_to_do_func(int) { /*nothing todo here because of the size it's a shared member*/ }
+
+void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz)
+{
+ llassert(sz >= 0);
+
+ if (!pdrawable) return;
+ LLVOVolume* vvol = pdrawable->getVOVolume();
+ if (!vvol) return;
+ if (!vvol->isAttachment()) return;
+ if (!vvol->getAvatar()) return;
+ if (vvol->getAvatar()->isSelf()) return;
+ LLVolume *vol = vvol->getVolume();
+ if (!vol) return;
+
+ const LLUUID &sculptId = vol->getParams().getSculptID();
+ if (sculptId.isNull()) return;
+
+ unsigned int total_size = 0;
+
+ pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+ if (itLU.first == itLU.second)
+ { //register
+ llassert(mSizeInfo.get<tag_BY_DRAWABLE>().end() == mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable));
+ mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, boost::make_shared<SizeSum>(sz), sculptId));
+ total_size = sz;
+ }
+ else
+ { //update + register
+ Info &nfo = const_cast<Info &>(*itLU.first);
+ //calc new size
+ total_size = nfo.getSizeSum() + sz;
+ nfo.mSharedSizeSum->mSizeSum = total_size;
+ nfo.mSize = sz;
+ //update size for all LLDrwable in range of sculptId
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+
+ //trying insert the LLDrawable
+ mSizeInfo.get<tag_BY_DRAWABLE>().insert(Info(pdrawable, sz, nfo.mSharedSizeSum, sculptId));
+ }
+
+ static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
+
+ if (0 != render_auto_mute_byte_limit && total_size > render_auto_mute_byte_limit)
+ {
+ pair_iter_iter_BY_SCULPT_ID_t it_eqr = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+ for (; it_eqr.first != it_eqr.second; ++it_eqr.first)
+ {
+ const Info &i = *it_eqr.first;
+ LLVOVolume *pVVol = i.mDrawable->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD != pVVol->getLOD()
+ )
+ {
+ addToUnloaded(sculptId);
+ //immediately
+ const_cast<LLDrawable*>(i.mDrawable)->unload();
+ }
+ }
+ }
+}
+
+void LLSculptIDSize::dec(const LLDrawable *pdrawable)
+{
+ container_BY_DRAWABLE_view::iterator it = mSizeInfo.get<tag_BY_DRAWABLE>().find(pdrawable);
+ if (mSizeInfo.get<tag_BY_DRAWABLE>().end() == it) return;
+
+ unsigned int size = it->getSizeSum() - it->getSize();
+
+ if (0 == size)
+ {
+ mSizeInfo.get<tag_BY_SCULPT_ID>().erase(it->getSculptId());
+ }
+ else
+ {
+ Info &nfo = const_cast<Info &>(*it);
+ nfo.mSize = 0;
+ pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(it->getSculptId());
+ it->mSharedSizeSum->mSizeSum = size;
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first; it != itLU.second; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+ }
+}
+
+void LLSculptIDSize::rem(const LLUUID &sculptId)
+{
+ mSizeInfo.get<tag_BY_SCULPT_ID>().erase(sculptId);
+}
+
+void LLSculptIDSize::resetSizeSum(const LLUUID &sculptId)
+{
+ const pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get<tag_BY_SCULPT_ID>().equal_range(sculptId);
+
+ if (itLU.first != itLU.second) {
+ itLU.first->mSharedSizeSum->mSizeSum = 0;
+ }
+
+ for (pair_iter_iter_BY_SCULPT_ID_t::first_type it = itLU.first, itE = itLU.second; it != itE; ++it)
+ {
+ mSizeInfo.get<tag_BY_SIZE>().modify_key(mSizeInfo.project<tag_BY_SIZE>(it), boost::bind(&_nothing_to_do_func, _1));
+ }
+}
diff --git a/indra/newview/llsculptidsize.h b/indra/newview/llsculptidsize.h
new file mode 100644
index 0000000000..87ee417b86
--- /dev/null
+++ b/indra/newview/llsculptidsize.h
@@ -0,0 +1,134 @@
+/**
+* @file llsculptidsize.h
+* @brief LLSculptIDSize class definition
+*
+* $LicenseInfo:firstyear=2009&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLSCULPTIDSIZE_H
+#define LL_LLSCULPTIDSIZE_H
+
+#include "lluuid.h"
+
+//std
+#include <set>
+//boost
+#include "boost/multi_index_container.hpp"
+#include "boost/multi_index/ordered_index.hpp"
+#include "boost/multi_index/mem_fun.hpp"
+
+class LLDrawable;
+
+
+class LLSculptIDSize
+{
+public:
+ struct SizeSum
+ {
+ SizeSum(int size)
+ : mSizeSum(size)
+ {}
+ unsigned int mSizeSum;
+ };
+
+ struct Info
+ {
+ typedef boost::shared_ptr<SizeSum> PtrSizeSum;
+
+ Info(const LLDrawable *drawable, int size, PtrSizeSum sizeInfo, LLUUID sculptId)
+ : mDrawable(drawable)
+ , mSize(size)
+ , mSharedSizeSum(sizeInfo)
+ , mSculptId(sculptId)
+ {}
+
+ const LLDrawable *mDrawable;
+ unsigned int mSize;
+ PtrSizeSum mSharedSizeSum;
+ LLUUID mSculptId;
+
+ inline const LLDrawable* getPtrLLDrawable() const { return mDrawable; }
+ inline unsigned int getSize() const { return mSize; }
+ inline unsigned int getSizeSum() const { return mSharedSizeSum->mSizeSum; }
+ inline LLUUID getSculptId() const { return mSculptId; }
+ PtrSizeSum getSizeInfo() { return mSharedSizeSum; }
+ };
+
+public:
+ //tags
+ struct tag_BY_DRAWABLE {};
+ struct tag_BY_SCULPT_ID {};
+ struct tag_BY_SIZE {};
+
+ //container
+ typedef boost::multi_index_container <
+ Info,
+ boost::multi_index::indexed_by <
+ boost::multi_index::ordered_unique< boost::multi_index::tag<tag_BY_DRAWABLE>
+ , boost::multi_index::const_mem_fun<Info, const LLDrawable*, &Info::getPtrLLDrawable>
+ >
+ , boost::multi_index::ordered_non_unique<boost::multi_index::tag<tag_BY_SCULPT_ID>
+ , boost::multi_index::const_mem_fun<Info, LLUUID, &Info::getSculptId>
+ >
+ , boost::multi_index::ordered_non_unique < boost::multi_index::tag<tag_BY_SIZE>
+ , boost::multi_index::const_mem_fun < Info, unsigned int, &Info::getSizeSum >
+ >
+ >
+ > container;
+
+ //views
+ typedef container::index<tag_BY_DRAWABLE>::type container_BY_DRAWABLE_view;
+ typedef container::index<tag_BY_SCULPT_ID>::type container_BY_SCULPT_ID_view;
+ typedef container::index<tag_BY_SIZE>::type container_BY_SIZE_view;
+
+private:
+ LLSculptIDSize()
+ {}
+
+public:
+ static LLSculptIDSize & instance()
+ {
+ static LLSculptIDSize inst;
+ return inst;
+ }
+
+public:
+ void inc(const LLDrawable *pdrawable, int sz);
+ void dec(const LLDrawable *pdrawable);
+ void rem(const LLUUID &sculptId);
+
+ inline void addToUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.insert(sculptId); }
+ inline void remFromUnloaded(const LLUUID &sculptId) { mMarkAsUnloaded.erase(sculptId); }
+ inline bool isUnloaded(const LLUUID &sculptId) const { return mMarkAsUnloaded.end() != mMarkAsUnloaded.find(sculptId); }
+ inline void clearUnloaded() { mMarkAsUnloaded.clear(); }
+
+ void resetSizeSum(const LLUUID &sculptId);
+
+ inline const container & getSizeInfo() const { return mSizeInfo; }
+
+private:
+ container mSizeInfo;
+ typedef std::set<LLUUID> std_LLUUID;
+ std_LLUUID mMarkAsUnloaded;
+};
+
+#endif
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c44aca6fa5..ddae109030 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -6271,92 +6271,107 @@ void pushWireframe(LLDrawable* drawable)
void LLSelectNode::renderOneWireframe(const LLColor4& color)
{
- //Need to because crash on ATI 3800 (and similar cards) MAINT-5018
- LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+ //Need to because crash on ATI 3800 (and similar cards) MAINT-5018
+ LLGLDisable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
- LLViewerObject* objectp = getObject();
- if (!objectp)
- {
- return;
- }
+ LLViewerObject* objectp = getObject();
+ if (!objectp)
+ {
+ return;
+ }
- LLDrawable* drawable = objectp->mDrawable;
- if(!drawable)
- {
- return;
- }
+ LLDrawable* drawable = objectp->mDrawable;
+ if (!drawable)
+ {
+ return;
+ }
- LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
+ LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr;
- if (shader)
- {
- gDebugProgram.bind();
- }
+ if (shader)
+ {
+ gDebugProgram.bind();
+ }
- gGL.matrixMode(LLRender::MM_MODELVIEW);
- gGL.pushMatrix();
-
- BOOL is_hud_object = objectp->isHUDAttachment();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
- if (drawable->isActive())
- {
- gGL.loadMatrix(gGLModelView);
- gGL.multMatrix((F32*) objectp->getRenderMatrix().mMatrix);
- }
- else if (!is_hud_object)
- {
- gGL.loadIdentity();
- gGL.multMatrix(gGLModelView);
- LLVector3 trans = objectp->getRegion()->getOriginAgent();
- gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
- }
-
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
- if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
- {
- gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
- LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
- if (shader)
- {
- gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
- pushWireframe(drawable);
- }
- else
- {
- LLGLEnable fog(GL_FOG);
- glFogi(GL_FOG_MODE, GL_LINEAR);
- float d = (LLViewerCamera::getInstance()->getPointOfInterest()-LLViewerCamera::getInstance()->getOrigin()).magVec();
- LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal()-gAgentCamera.getCameraPositionGlobal()).magVec()/(LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec()*4), 0.0, 1.0);
- glFogf(GL_FOG_START, d);
- glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
- glFogfv(GL_FOG_COLOR, fogCol.mV);
+ BOOL is_hud_object = objectp->isHUDAttachment();
- gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
- {
- gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
- pushWireframe(drawable);
- }
- }
- }
+ if (drawable->isActive())
+ {
+ gGL.loadMatrix(gGLModelView);
+ gGL.multMatrix((F32*)objectp->getRenderMatrix().mMatrix);
+ }
+ else if (!is_hud_object)
+ {
+ gGL.loadIdentity();
+ gGL.multMatrix(gGLModelView);
+ LLVector3 trans = objectp->getRegion()->getOriginAgent();
+ gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+ }
- gGL.flush();
- gGL.setSceneBlendType(LLRender::BT_ALPHA);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- gGL.diffuseColor4f(color.mV[VRED]*2, color.mV[VGREEN]*2, color.mV[VBLUE]*2, LLSelectMgr::sHighlightAlpha*2);
-
- LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
- glPolygonOffset(3.f, 3.f);
- glLineWidth(3.f);
- pushWireframe(drawable);
- glLineWidth(1.f);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- gGL.popMatrix();
+ if (LLSelectMgr::sRenderHiddenSelections) // && gFloaterTools && gFloaterTools->getVisible())
+ {
+ gGL.blendFunc(LLRender::BF_SOURCE_COLOR, LLRender::BF_ONE);
+ LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE, GL_GEQUAL);
+ if (shader)
+ {
+ gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+ pushWireframe(drawable);
+ }
+ else
+ {
+ LLGLEnable fog(GL_FOG);
+ glFogi(GL_FOG_MODE, GL_LINEAR);
+ float d = (LLViewerCamera::getInstance()->getPointOfInterest() - LLViewerCamera::getInstance()->getOrigin()).magVec();
+ LLColor4 fogCol = color * (F32)llclamp((LLSelectMgr::getInstance()->getSelectionCenterGlobal() - gAgentCamera.getCameraPositionGlobal()).magVec() / (LLSelectMgr::getInstance()->getBBoxOfSelection().getExtentLocal().magVec() * 4), 0.0, 1.0);
+ glFogf(GL_FOG_START, d);
+ glFogf(GL_FOG_END, d*(1 + (LLViewerCamera::getInstance()->getView() / LLViewerCamera::getInstance()->getDefaultFOV())));
+ glFogfv(GL_FOG_COLOR, fogCol.mV);
+
+ gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
+ {
+ gGL.diffuseColor4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], 0.4f);
+ pushWireframe(drawable);
+ }
+ }
+ }
- if (shader)
- {
- shader->bind();
- }
+ gGL.flush();
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gGL.diffuseColor4f(color.mV[VRED] * 2, color.mV[VGREEN] * 2, color.mV[VBLUE] * 2, LLSelectMgr::sHighlightAlpha * 2);
+
+ {
+ bool wireframe_selection = gFloaterTools && gFloaterTools->getVisible();
+
+ LLGLDisable depth(wireframe_selection ? 0 : GL_BLEND);
+ LLGLEnable stencil(wireframe_selection ? 0 : GL_STENCIL_TEST);
+
+ if (!wireframe_selection)
+ { //modify wireframe into outline selection mode
+ glStencilFunc(GL_NOTEQUAL, 2, 0xffff);
+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+ }
+
+ LLGLEnable offset(GL_POLYGON_OFFSET_LINE);
+ glPolygonOffset(3.f, 3.f);
+ glLineWidth(5.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+ pushWireframe(drawable);
+ }
+
+ glLineWidth(1.f);
+ glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ gGL.popMatrix();
+
+ if (shader)
+ {
+ shader->bind();
+ }
}
//-----------------------------------------------------------------------------
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d2a87ee2af..9791f4a921 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3941,6 +3941,7 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector4a& start, co
LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* texture, LLVertexBuffer* buffer,
+ bool selected,
BOOL fullbright, U8 bump, BOOL particle, F32 part_size)
: LLTrace::MemTrackableNonVirtual<LLDrawInfo, 16>("LLDrawInfo"),
mVertexBuffer(buffer),
@@ -3968,7 +3969,8 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
mHasGlow(FALSE),
mEnvIntensity(0.0f),
mAlphaMaskCutoff(0.5f),
- mDiffuseAlphaMode(0)
+ mDiffuseAlphaMode(0),
+ mSelected(selected)
{
mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset);
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 7633e46200..6104b92d43 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -75,6 +75,7 @@ public:
LLDrawInfo(U16 start, U16 end, U32 count, U32 offset,
LLViewerTexture* image, LLVertexBuffer* buffer,
+ bool selected,
BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0);
@@ -117,6 +118,7 @@ public:
F32 mEnvIntensity;
F32 mAlphaMaskCutoff;
U8 mDiffuseAlphaMode;
+ bool mSelected;
struct CompareTexture
@@ -646,7 +648,7 @@ class LLVolumeGeometryManager: public LLGeometryManager
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
- void genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
+ U32 genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort = FALSE, BOOL batch_textures = FALSE, BOOL no_materials = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
private:
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 57a0195d23..778e275727 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -113,6 +113,7 @@ LLViewerCamera::LLViewerCamera() : LLCamera()
{
calcProjection(getFar());
mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
+ mPrevCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
mPixelMeterRatio = 0.f;
mScreenPixelArea = 0;
@@ -882,6 +883,15 @@ void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads)
mCosHalfCameraFOV = cosf(mCameraFOVDefault * 0.5f);
}
+BOOL LLViewerCamera::isDefaultFOVChanged()
+{
+ if(mPrevCameraFOVDefault != mCameraFOVDefault)
+ {
+ mPrevCameraFOVDefault = mCameraFOVDefault;
+ return !gSavedSettings.getBOOL("IgnoreFOVZoomForLODs");
+ }
+ return FALSE;
+}
// static
void LLViewerCamera::updateCameraAngle( void* user_data, const LLSD& value)
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index f8c973690a..5901de289f 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -115,6 +115,8 @@ public:
void setDefaultFOV(F32 fov) ;
F32 getDefaultFOV() { return mCameraFOVDefault; }
+ BOOL isDefaultFOVChanged();
+
BOOL cameraUnderWater() const;
BOOL areVertsVisible(LLViewerObject* volumep, BOOL all_verts);
@@ -138,6 +140,7 @@ protected:
mutable LLMatrix4 mProjectionMatrix; // Cache of perspective matrix
mutable LLMatrix4 mModelviewMatrix;
F32 mCameraFOVDefault;
+ F32 mPrevCameraFOVDefault;
F32 mCosHalfCameraFOV;
LLVector3 mLastPointOfInterest;
F32 mPixelMeterRatio; // Divide by distance from camera to get pixels per meter at that distance.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 63c62fc990..88984d518a 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -592,6 +592,7 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
return true;
}
+void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value);
////////////////////////////////////////////////////////////////////////////
void settings_setup_listeners()
@@ -745,6 +746,7 @@ void settings_setup_listeners()
gSavedSettings.getControl("SpellCheckDictionary")->getSignal()->connect(boost::bind(&handleSpellCheckChanged));
gSavedSettings.getControl("LoginLocation")->getSignal()->connect(boost::bind(&handleLoginLocationChanged));
gSavedSettings.getControl("DebugAvatarJoints")->getCommitSignal()->connect(boost::bind(&handleDebugAvatarJointsChanged, _2));
+ gSavedSettings.getControl("RenderAutoMuteByteLimit")->getSignal()->connect(boost::bind(&handleRenderAutoMuteByteLimitChanged, _2));
gSavedPerAccountSettings.getControl("AvatarHoverOffsetZ")->getCommitSignal()->connect(boost::bind(&handleAvatarHoverOffsetChanged, _2));
}
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 96ef160c72..86a9e7e2ad 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1005,7 +1005,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.mDeferredScreen.getHeight(), 0, 0,
gPipeline.mDeferredScreen.getWidth(),
gPipeline.mDeferredScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
}
else
@@ -1017,7 +1017,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
gPipeline.mScreen.getHeight(), 0, 0,
gPipeline.mScreen.getWidth(),
gPipeline.mScreen.getHeight(),
- GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
}
}
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 624c48e945..239e357cdd 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -5894,6 +5894,14 @@ void LLViewerObject::markForUpdate(BOOL priority)
}
}
+void LLViewerObject::markForUnload(BOOL priority)
+{
+ if (mDrawable.notNull())
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::FOR_UNLOAD, priority);
+ }
+}
+
bool LLViewerObject::isPermanentEnforced() const
{
return flagObjectPermanent() && (mRegionp != gAgent.getRegion()) && !gAgent.isGodlike();
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 21c95d5533..d61832c2ad 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -412,6 +412,7 @@ public:
void clearIcon();
void markForUpdate(BOOL priority);
+ void markForUnload(BOOL priority);
void updateVolume(const LLVolumeParams& volume_params);
virtual void updateSpatialExtents(LLVector4a& min, LLVector4a& max);
virtual F32 getBinRadius();
diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp
index 023f1b92ba..5f0e21db71 100644
--- a/indra/newview/llvieweroctree.cpp
+++ b/indra/newview/llvieweroctree.cpp
@@ -465,7 +465,7 @@ LLViewerOctreeGroup::LLViewerOctreeGroup(OctreeNode* node)
{
LLVector4a tmp;
tmp.splat(0.f);
- mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[0] = mObjectBounds[1] =
+ mExtents[0] = mExtents[1] = mObjectBounds[0] = mObjectBounds[1] =
mObjectExtents[0] = mObjectExtents[1] = tmp;
mBounds[0] = node->getCenter();
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 25cf082751..e5265f1dcd 100644
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -662,9 +662,6 @@ void LLViewerPartSim::updateSimulation()
{
static LLFrameTimer update_timer;
- //reset VBO cursor
- LLVOPartGroup::sVBSlotCursor = 0;
-
const F32 dt = llmin(update_timer.getElapsedTimeAndResetF32(), 0.1f);
if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES)))
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 3e0cec0f09..ff7647a7e4 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -2811,6 +2811,7 @@ BOOL LLViewerShaderMgr::loadShadersObject()
gSkinnedObjectSimpleWaterProgram.mShaderGroup = LLGLSLShader::SG_WATER;
gSkinnedObjectSimpleWaterProgram.mFeatures.hasObjectSkinning = true;
gSkinnedObjectSimpleWaterProgram.mFeatures.disableTextureIndex = true;
+ gSkinnedObjectSimpleWaterProgram.mFeatures.hasAlphaMask = true;
gSkinnedObjectSimpleWaterProgram.mShaderFiles.clear();
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleSkinnedV.glsl", GL_VERTEX_SHADER_ARB));
gSkinnedObjectSimpleWaterProgram.mShaderFiles.push_back(make_pair("objects/simpleWaterF.glsl", GL_FRAGMENT_SHADER_ARB));
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index de63a3963c..b5c90a8f60 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -741,7 +741,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group)
U32 count = facep->getIndicesCount();
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
- buffer, fullbright);
+ buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index f7b21338f8..b31afca61d 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -47,11 +47,17 @@
extern U64MicrosecondsImplicit gFrameTime;
LLPointer<LLVertexBuffer> LLVOPartGroup::sVB = NULL;
-S32 LLVOPartGroup::sVBSlotCursor = 0;
+S32 LLVOPartGroup::sVBSlotFree[];
+S32* LLVOPartGroup::sVBSlotCursor = NULL;
void LLVOPartGroup::initClass()
{
+ for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i)
+ {
+ sVBSlotFree[i] = i;
+ }
+ sVBSlotCursor = sVBSlotFree;
}
//static
@@ -124,12 +130,14 @@ void LLVOPartGroup::destroyGL()
//static
S32 LLVOPartGroup::findAvailableVBSlot()
{
- if (sVBSlotCursor >= LL_MAX_PARTICLE_COUNT)
+ if (sVBSlotCursor >= sVBSlotFree + LL_MAX_PARTICLE_COUNT)
{ //no more available slots
return -1;
}
- return sVBSlotCursor++;
+ S32 ret = *sVBSlotCursor;
+ sVBSlotCursor++;
+ return ret;
}
bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
@@ -150,7 +158,7 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
//static
void LLVOPartGroup::freeVBSlot(S32 idx)
{
- /*llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
+ llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
//llassert(sVBSlotCursor > sVBSlotFree);
//llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
@@ -158,7 +166,7 @@ void LLVOPartGroup::freeVBSlot(S32 idx)
{
sVBSlotCursor--;
*sVBSlotCursor = idx;
- }*/
+ }
}
LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
@@ -870,7 +878,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
LLFace* facep = *i;
LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject();
- //if (!facep->isState(LLFace::PARTICLE))
+ if (!facep->isState(LLFace::PARTICLE))
{ //set the indices of this face
S32 idx = LLVOPartGroup::findAvailableVBSlot();
if (idx >= 0)
@@ -879,7 +887,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
facep->setIndicesIndex(idx*6);
facep->setVertexBuffer(LLVOPartGroup::sVB);
facep->setPoolType(LLDrawPool::POOL_ALPHA);
- //facep->setState(LLFace::PARTICLE);
+ facep->setState(LLFace::PARTICLE);
}
else
{
@@ -964,7 +972,7 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group)
U32 count = facep->getIndicesCount();
LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(),
//facep->getTexture(),
- buffer, fullbright);
+ buffer, object->isSelected(), fullbright);
const LLVector4a* exts = group->getObjectExtents();
info->mExtents[0] = exts[0];
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 2ef8b1c848..4e4d6e609d 100644
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -42,7 +42,8 @@ public:
//vertex buffer for holding all particles
static LLPointer<LLVertexBuffer> sVB;
- static S32 sVBSlotCursor;
+ static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT];
+ static S32 *sVBSlotCursor;
static void initClass();
static void restoreGL();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index c1ecfd07c1..7d6881f8a8 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -78,6 +78,7 @@
#include "llvoavatar.h"
#include "llvocache.h"
#include "llmaterialmgr.h"
+#include "llsculptidsize.h"
const F32 FORCE_SIMPLE_RENDER_AREA = 512.f;
const F32 FORCE_CULL_AREA = 8.f;
@@ -249,6 +250,8 @@ void LLVOVolume::markDead()
{
if (!mDead)
{
+ LLSculptIDSize::instance().rem(getVolume()->getParams().getSculptID());
+
if(getMDCImplCount() > 0)
{
LLMediaDataClientObject::ptr_t obj = new LLMediaDataClientObjectImpl(const_cast<LLVOVolume*>(this), false);
@@ -956,13 +959,14 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
// if it's a mesh
if ((volume_params.getSculptType() & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH)
{ //meshes might not have all LODs, get the force detail to best existing LOD
- LLUUID mesh_id = volume_params.getSculptID();
-
- lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
- if (lod == -1)
+ if (NO_LOD != lod)
{
- is404 = TRUE;
- lod = 0;
+ lod = gMeshRepo.getActualMeshLOD(volume_params, lod);
+ if (lod == -1)
+ {
+ is404 = TRUE;
+ lod = 0;
+ }
}
}
}
@@ -1059,12 +1063,13 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
LLFace::cacheFaceInVRAM(face);
}
}
-
return TRUE;
}
-
-
+ else if (NO_LOD == lod)
+ {
+ LLSculptIDSize::instance().resetSizeSum(volume_params.getSculptID());
+ }
return FALSE;
}
@@ -1219,18 +1224,18 @@ void LLVOVolume::sculpt()
}
}
-S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
+S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius, F32 lod_factor)
{
S32 cur_detail;
if (LLPipeline::sDynamicLOD)
{
// We've got LOD in the profile, and in the twist. Use radius.
- F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
+ F32 tan_angle = (lod_factor*radius)/distance;
cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f));
}
else
{
- cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
+ cur_detail = llclamp((S32) (sqrtf(radius)*lod_factor*4.f), 0, 3);
}
return cur_detail;
}
@@ -1246,6 +1251,7 @@ BOOL LLVOVolume::calcLOD()
F32 radius;
F32 distance;
+ F32 lod_factor = LLVOVolume::sLODFactor;
if (mDrawable->isState(LLDrawable::RIGGED))
{
@@ -1281,12 +1287,18 @@ BOOL LLVOVolume::calcLOD()
distance *= rampDist;
}
- // DON'T Compensate for field of view changing on FOV zoom.
+
distance *= F_PI/3.f;
- cur_detail = computeLODDetail(ll_round(distance, 0.01f),
- ll_round(radius, 0.01f));
+ static LLCachedControl<bool> ignore_fov_zoom(gSavedSettings,"IgnoreFOVZoomForLODs");
+ if(!ignore_fov_zoom)
+ {
+ lod_factor *= DEFAULT_FIELD_OF_VIEW / LLViewerCamera::getInstance()->getDefaultFOV();
+ }
+ cur_detail = computeLODDetail(ll_round(distance, 0.01f),
+ ll_round(radius, 0.01f),
+ lod_factor);
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_LOD_INFO) &&
mDrawable->getFace(0))
@@ -1299,7 +1311,8 @@ BOOL LLVOVolume::calcLOD()
if (cur_detail != mLOD)
{
mAppAngle = ll_round((F32) atan2( mDrawable->getRadius(), mDrawable->mDistanceWRTCamera) * RAD_TO_DEG, 0.01f);
- mLOD = cur_detail;
+ mLOD = cur_detail;
+
return TRUE;
}
@@ -1313,7 +1326,16 @@ BOOL LLVOVolume::updateLOD()
return FALSE;
}
- BOOL lod_changed = calcLOD();
+ BOOL lod_changed = FALSE;
+
+ if (!LLSculptIDSize::instance().isUnloaded(getVolume()->getParams().getSculptID()))
+ {
+ lod_changed = calcLOD();
+ }
+ else
+ {
+ return FALSE;
+ }
if (lod_changed)
{
@@ -1483,7 +1505,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
res &= face->genVolumeBBoxes(*volume, i,
mRelativeXform,
(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
-
if (rebuild)
{
if (i == 0)
@@ -1759,6 +1780,11 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
dirtySpatialGroup(drawable->isState(LLDrawable::IN_REBUILD_Q1));
compiled = TRUE;
lodOrSculptChanged(drawable, compiled);
+
+ if(drawable->isState(LLDrawable::REBUILD_RIGGED | LLDrawable::RIGGED))
+ {
+ updateRiggedVolume(false);
+ }
genBBoxes(FALSE);
}
// it has its own drawable (it's moved) or it has changed UVs or it has changed xforms from global<->local
@@ -2177,7 +2203,7 @@ bool LLVOVolume::notifyAboutMissingAsset(LLViewerTexture *texture)
//setup new materials
for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
{
- LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
+ LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
LLViewerObject::setTEMaterialParams(it->first, it->second);
}
@@ -2280,7 +2306,7 @@ S32 LLVOVolume::setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialPa
if(new_material) {
pMaterial = new_material;
- LLMaterialMgr::getInstance()->put(getID(),te,*pMaterial);
+ LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), pMaterial);
}
}
@@ -4225,7 +4251,7 @@ void LLRiggedVolume::update(const LLMeshSkinInfo* skin, LLVOAvatar* avatar, cons
LLVector4a* pos = dst_face.mPositions;
- if( pos && weight && dst_face.mExtents )
+ if (pos && dst_face.mExtents)
{
LL_RECORD_BLOCK_TIME(FTM_SKIN_RIGGED);
@@ -4411,7 +4437,9 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
}
- if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
+ bool selected = facep->getViewerObject()->isSelected();
+
+ if (selected && LLSelectMgr::getInstance()->mHideSelectedObjects)
{
return;
}
@@ -4508,7 +4536,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
batchable = true;
}
}
-
+
if (idx >= 0 &&
draw_vec[idx]->mVertexBuffer == facep->getVertexBuffer() &&
draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -4524,7 +4552,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
(!mat || (draw_vec[idx]->mShiny == shiny)) && // need to break batches when a material is shared, but legacy settings are different
draw_vec[idx]->mTextureMatrix == tex_mat &&
draw_vec[idx]->mModelMatrix == model_mat &&
- draw_vec[idx]->mShaderMask == shader_mask)
+ draw_vec[idx]->mShaderMask == shader_mask &&
+ draw_vec[idx]->mSelected == selected)
{
draw_vec[idx]->mCount += facep->getIndicesCount();
draw_vec[idx]->mEnd += facep->getGeomCount();
@@ -4546,7 +4575,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
U32 offset = facep->getIndicesStart();
U32 count = facep->getIndicesCount();
LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset, tex,
- facep->getVertexBuffer(), fullbright, bump);
+ facep->getVertexBuffer(), selected, fullbright, bump);
draw_info->mGroup = group;
draw_info->mVSize = facep->getVirtualSize();
draw_vec.push_back(draw_info);
@@ -4573,26 +4602,25 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
if (mat)
{
- draw_info->mMaterialID = mat_id;
+ draw_info->mMaterialID = mat_id;
- // We have a material. Update our draw info accordingly.
+ // We have a material. Update our draw info accordingly.
- if (!mat->getSpecularID().isNull())
- {
- LLVector4 specColor;
- specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
- specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
- specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
- specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
- draw_info->mSpecColor = specColor;
- draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
- draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
- }
+ if (!mat->getSpecularID().isNull())
+ {
+ LLVector4 specColor;
+ specColor.mV[0] = mat->getSpecularLightColor().mV[0] * (1.f / 255.f);
+ specColor.mV[1] = mat->getSpecularLightColor().mV[1] * (1.f / 255.f);
+ specColor.mV[2] = mat->getSpecularLightColor().mV[2] * (1.f / 255.f);
+ specColor.mV[3] = mat->getSpecularLightExponent() * (1.f / 255.f);
+ draw_info->mSpecColor = specColor;
+ draw_info->mEnvIntensity = mat->getEnvironmentIntensity() * (1.f / 255.f);
+ draw_info->mSpecularMap = facep->getViewerObject()->getTESpecularMap(facep->getTEOffset());
+ }
- draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
- draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
- draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
-
+ draw_info->mAlphaMaskCutoff = mat->getAlphaMaskCutoff() * (1.f / 255.f);
+ draw_info->mDiffuseAlphaMode = mat->getDiffuseAlphaMode();
+ draw_info->mNormalMap = facep->getViewerObject()->getTENormalMap(facep->getTEOffset());
}
else
{
@@ -4663,10 +4691,83 @@ static LLDrawPoolAvatar* get_avatar_drawpool(LLViewerObject* vobj)
return NULL;
}
-void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
+void handleRenderAutoMuteByteLimitChanged(const LLSD& new_value)
{
-
+ static LLCachedControl<U32> render_auto_mute_byte_limit(gSavedSettings, "RenderAutoMuteByteLimit", 0U);
+ if (0 != render_auto_mute_byte_limit)
+ {
+ //for unload
+ LLSculptIDSize::container_BY_SIZE_view::iterator
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().lower_bound(render_auto_mute_byte_limit),
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
+
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD != pVVol->getLOD()
+ )
+ {
+ //postponed
+ pVVol->markForUnload();
+ LLSculptIDSize::instance().addToUnloaded(nfo.getSculptId());
+ }
+ }
+
+ //for load if it was unload
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin();
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().upper_bound(render_auto_mute_byte_limit);
+
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD == pVVol->getLOD()
+ )
+ {
+ LLSculptIDSize::instance().remFromUnloaded(nfo.getSculptId());
+ pVVol->updateLOD();
+ pVVol->markForUpdate(TRUE);
+ }
+ }
+ }
+ else
+ {
+ LLSculptIDSize::instance().clearUnloaded();
+
+ LLSculptIDSize::container_BY_SIZE_view::iterator
+ itL = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().begin(),
+ itU = LLSculptIDSize::instance().getSizeInfo().get<LLSculptIDSize::tag_BY_SIZE>().end();
+
+ for (; itL != itU; ++itL)
+ {
+ const LLSculptIDSize::Info &nfo = *itL;
+ LLVOVolume *pVVol = nfo.getPtrLLDrawable()->getVOVolume();
+ if (pVVol
+ && !pVVol->isDead()
+ && pVVol->isAttachment()
+ && !pVVol->getAvatar()->isSelf()
+ && LLVOVolume::NO_LOD == pVVol->getLOD()
+ )
+ {
+ pVVol->updateLOD();
+ pVVol->markForUpdate(TRUE);
+ }
+ }
+ }
+}
+
+void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
+{
if (group->changeLOD())
{
group->mLastUpdateDistance = group->mDistance;
@@ -5227,13 +5328,19 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
fullbright_mask = fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX;
}
- genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
- genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
- genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
- genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
- genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
- genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
- genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
+ group->mGeometryBytes = 0;
+
+ U32 geometryBytes = 0;
+
+ geometryBytes += genDrawInfo(group, simple_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSimpleFaces, simple_count, FALSE, batch_textures, FALSE);
+ geometryBytes += genDrawInfo(group, fullbright_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sFullbrightFaces, fullbright_count, FALSE, batch_textures);
+ geometryBytes += genDrawInfo(group, alpha_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sAlphaFaces, alpha_count, TRUE, batch_textures);
+ geometryBytes += genDrawInfo(group, bump_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sBumpFaces, bump_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, norm_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormFaces, norm_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, spec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sSpecFaces, spec_count, FALSE, FALSE);
+ geometryBytes += genDrawInfo(group, normspec_mask | LLVertexBuffer::MAP_TEXTURE_INDEX, sNormSpecFaces, normspec_count, FALSE, FALSE);
+
+ group->mGeometryBytes = geometryBytes;
if (!LLPipeline::sDelayVBUpdate)
{
@@ -5291,6 +5398,8 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
if (drawablep && !drawablep->isDead() && drawablep->isState(LLDrawable::REBUILD_ALL) && !drawablep->isState(LLDrawable::RIGGED) )
{
LLVOVolume* vobj = drawablep->getVOVolume();
+ if (vobj->isNoLOD()) continue;
+
vobj->preRebuild();
if (drawablep->isState(LLDrawable::ANIMATED_CHILD))
@@ -5423,10 +5532,11 @@ static LLTrace::BlockTimerStatHandle FTM_GEN_DRAW_INFO_RESIZE_VB("Resize VB");
-void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
+U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace** faces, U32 face_count, BOOL distance_sort, BOOL batch_textures, BOOL no_materials)
{
LL_RECORD_BLOCK_TIME(FTM_REBUILD_VOLUME_GEN_DRAW_INFO);
+ U32 geometryBytes = 0;
U32 buffer_usage = group->mBufferUsage;
static LLCachedControl<bool> use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false);
@@ -5676,7 +5786,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
if (buffer)
{
- group->mGeometryBytes += buffer->getSize() + buffer->getIndicesSize();
+ geometryBytes += buffer->getSize() + buffer->getIndicesSize();
buffer_map[mask][*face_iter].push_back(buffer);
}
@@ -5964,7 +6074,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
}
if (LLPipeline::sRenderDeferred && !hud_group && LLPipeline::sRenderBump && use_legacy_bump)
{ //if this is the deferred render and a bump map is present, register in post deferred bump
@@ -5986,8 +6096,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
}
else
{
- registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
- }
+ registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
+ }
}
}
@@ -6032,6 +6142,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFac
{
group->mBufferMap[mask][i->first] = i->second;
}
+
+ return geometryBytes;
}
void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
@@ -6098,4 +6210,3 @@ void LLHUDPartition::shift(const LLVector4a &offset)
{
//HUD objects don't shift with region crossing. That would be silly.
}
-
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 1a7e49d198..a0342d31a2 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -35,6 +35,8 @@
#include "m3math.h" // LLMatrix3
#include "m4math.h" // LLMatrix4
#include <map>
+#include <set>
+
class LLViewerTextureAnim;
class LLDrawPool;
@@ -125,7 +127,9 @@ public:
void generateSilhouette(LLSelectNode* nodep, const LLVector3& view_point);
/*virtual*/ BOOL setParent(LLViewerObject* parent);
- S32 getLOD() const { return mLOD; }
+ S32 getLOD() const { return mLOD; }
+ void setNoLOD() { mLOD = NO_LOD; mLODChanged = TRUE; }
+ bool isNoLOD() const { return NO_LOD == mLOD; }
const LLVector3 getPivotPositionAgent() const;
const LLMatrix4& getRelativeXform() const { return mRelativeXform; }
const LLMatrix3& getRelativeXformInvTrans() const { return mRelativeXformInvTrans; }
@@ -160,6 +164,7 @@ public:
const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const;
void markForUpdate(BOOL priority) { LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; }
+ void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; }
void faceMappingChanged() { mFaceMappingChanged=TRUE; };
/*virtual*/ void onShift(const LLVector4a &shift_vector); // Called when the drawable shifts
@@ -327,7 +332,7 @@ public:
void clearRiggedVolume();
protected:
- S32 computeLODDetail(F32 distance, F32 radius);
+ S32 computeLODDetail(F32 distance, F32 radius, F32 lod_factor);
BOOL calcLOD();
LLFace* addFace(S32 face_index);
void updateTEData();
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 1d083bb2fd..e541c1054e 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -2656,7 +2656,7 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d
{
scratch_space->copyContents(source,
0, 0, source.getWidth(), source.getHeight(),
- 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
dest.bindTarget();
@@ -3031,6 +3031,12 @@ void LLPipeline::updateGeom(F32 max_dtime)
}
}
+ if (drawablep->isUnload())
+ {
+ drawablep->unload();
+ drawablep->clearState(LLDrawable::FOR_UNLOAD);
+ }
+
if (updateDrawableGeom(drawablep, TRUE))
{
drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
@@ -3424,6 +3430,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
LLSpatialGroup* last_group = NULL;
+ BOOL fov_changed = LLViewerCamera::getInstance()->isDefaultFOVChanged();
for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
{
LLCullResult::bridge_iterator cur_iter = i;
@@ -3437,7 +3444,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED))
{
- stateSort(bridge, camera);
+ stateSort(bridge, camera, fov_changed);
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD &&
@@ -3509,9 +3516,9 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
}
-void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera)
+void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed)
{
- if (bridge->getSpatialGroup()->changeLOD())
+ if (bridge->getSpatialGroup()->changeLOD() || fov_changed)
{
bool force_update = false;
bridge->updateDistance(camera, force_update);
@@ -4577,12 +4584,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
LLGLEnable cull(GL_CULL_FACE);
- LLGLEnable stencil(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF);
- stop_glerror();
- glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
- stop_glerror();
-
for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter)
{
LLDrawPool *poolp = *iter;
@@ -8138,7 +8139,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield)
if (LLRenderTarget::sUseFBO)
{ //copy depth buffer from mScreen to framebuffer
LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),
- 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
@@ -9019,7 +9020,7 @@ void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
{
LLGLDepthTest depth(GL_TRUE);
mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
- 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
}
LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
@@ -9994,7 +9995,19 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
else
{
- renderGeom(camera);
+ renderGeom(camera);
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.bind();
+ }
+
+ LLWorld::getInstance()->renderPropertyLines();
+
+ if (LLGLSLShader::sNoFixedFunction)
+ {
+ gUIProgram.unbind();
+ }
}
if (LLPipeline::sRenderDeferred && materials_in_water)
@@ -10117,7 +10130,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
LLPipeline::sShadowRender = true;
- U32 types[] = {
+ static const U32 types[] = {
LLRenderPass::PASS_SIMPLE,
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
@@ -11622,7 +11635,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
avatar->setImpostorDim(tdim);
- LLVOAvatar::sUseImpostors = true; // @TODO ???
+ LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);
sUseOcclusion = occlusion;
sReflectionRender = false;
sImpostorRender = false;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index c9670a60f2..f43607ccb0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -254,7 +254,7 @@ public:
void stateSort(LLCamera& camera, LLCullResult& result);
void stateSort(LLSpatialGroup* group, LLCamera& camera);
- void stateSort(LLSpatialBridge* bridge, LLCamera& camera);
+ void stateSort(LLSpatialBridge* bridge, LLCamera& camera, BOOL fov_changed = FALSE);
void stateSort(LLDrawable* drawablep, LLCamera& camera);
void postSort(LLCamera& camera);
void forAllVisibleDrawables(void (*func)(LLDrawable*));