summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/llcommon/lldarray.h2
-rw-r--r--indra/llcommon/llstrider.h2
-rwxr-xr-xindra/llcrashlogger/llcrashlogger.cpp2
-rw-r--r--indra/llmath/llvolume.cpp93
-rw-r--r--indra/llmessage/llpumpio.cpp7
-rw-r--r--indra/llprimitive/llprimitive.h1
-rw-r--r--indra/llrender/llgl.cpp69
-rw-r--r--indra/llrender/llgl.h1
-rw-r--r--indra/llrender/llglheaders.h22
-rw-r--r--indra/llrender/llimagegl.cpp89
-rw-r--r--indra/llrender/llimagegl.h2
-rw-r--r--indra/llrender/llrender.cpp41
-rw-r--r--indra/llrender/llrender.h10
-rw-r--r--indra/llrender/llvertexbuffer.cpp6
-rw-r--r--indra/llrender/llvertexbuffer.h2
-rw-r--r--indra/newview/app_settings/high_graphics.xml11
-rw-r--r--indra/newview/app_settings/low_graphics.xml11
-rw-r--r--indra/newview/app_settings/mid_graphics.xml11
-rw-r--r--indra/newview/app_settings/settings.xml142
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl23
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/giF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl4
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl103
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl99
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl191
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl124
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/treeF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class1/deferred/waterF.glsl14
-rw-r--r--indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl24
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl25
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl11
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl64
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl86
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl18
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl80
-rw-r--r--indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl257
-rw-r--r--indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl9
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl10
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/giF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl77
-rw-r--r--indra/newview/app_settings/shaders/class3/deferred/treeF.glsl3
-rw-r--r--indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl27
-rw-r--r--indra/newview/app_settings/ultra_graphics.xml13
-rw-r--r--indra/newview/featuretable.txt55
-rw-r--r--indra/newview/featuretable_linux.txt86
-rw-r--r--indra/newview/featuretable_mac.txt1
-rw-r--r--indra/newview/llappviewer.cpp33
-rw-r--r--indra/newview/lldrawable.cpp2
-rw-r--r--indra/newview/lldrawpool.cpp1
-rw-r--r--indra/newview/lldrawpool.h1
-rw-r--r--indra/newview/lldrawpoolalpha.cpp185
-rw-r--r--indra/newview/lldrawpoolalpha.h7
-rw-r--r--indra/newview/lldrawpoolavatar.cpp31
-rw-r--r--indra/newview/lldrawpoolavatar.h4
-rw-r--r--indra/newview/lldrawpoolbump.cpp57
-rw-r--r--indra/newview/lldrawpoolbump.h10
-rw-r--r--indra/newview/lldrawpoolsimple.cpp7
-rw-r--r--indra/newview/llface.cpp23
-rw-r--r--indra/newview/llface.h2
-rw-r--r--indra/newview/llfloaterpreference.cpp95
-rw-r--r--indra/newview/llpanelvolume.cpp4
-rw-r--r--indra/newview/llspatialpartition.cpp43
-rw-r--r--indra/newview/llspatialpartition.h18
-rw-r--r--indra/newview/llviewercontrol.cpp21
-rw-r--r--indra/newview/llviewerdisplay.cpp19
-rw-r--r--indra/newview/llviewerjoint.cpp4
-rw-r--r--indra/newview/llviewerjoint.h2
-rw-r--r--indra/newview/llviewerjointmesh.cpp103
-rw-r--r--indra/newview/llviewerjointmesh.h2
-rw-r--r--indra/newview/llviewermessage.cpp2
-rw-r--r--indra/newview/llviewershadermgr.cpp55
-rw-r--r--indra/newview/llviewerstats.cpp2
-rw-r--r--indra/newview/llviewerwindow.cpp147
-rw-r--r--indra/newview/llvoavatar.cpp234
-rw-r--r--indra/newview/llvoavatar.h4
-rw-r--r--indra/newview/llvovolume.cpp96
-rw-r--r--indra/newview/llvovolume.h1
-rw-r--r--indra/newview/llworld.cpp2
-rw-r--r--indra/newview/pipeline.cpp1337
-rw-r--r--indra/newview/pipeline.h33
-rw-r--r--indra/newview/skins/default/xui/en/menu_viewer.xml18
-rw-r--r--indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml281
98 files changed, 3043 insertions, 1938 deletions
diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h
index 0e56a11d53..af647c7e7a 100644
--- a/indra/llcommon/lldarray.h
+++ b/indra/llcommon/lldarray.h
@@ -202,7 +202,7 @@ public:
{
U32 n = mVector.size();
mIndexMap[k] = n;
- mVector.resize(n+1);
+ mVector.push_back(Type());
llassert(mVector.size() == mIndexMap.size());
return mVector[n];
}
diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h
index 369b06b48a..44ea80a36b 100644
--- a/indra/llcommon/llstrider.h
+++ b/indra/llcommon/llstrider.h
@@ -51,7 +51,7 @@ public:
void setStride (S32 skipBytes) { mSkip = (skipBytes ? skipBytes : sizeof(Object));}
void skip(const U32 index) { mBytep += mSkip*index;}
-
+ U32 getSkip() const { return mSkip; }
Object* get() { return mObjectp; }
Object* operator->() { return mObjectp; }
Object& operator *() { return *mObjectp; }
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index c1022c1195..4bda00ed86 100755
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -370,6 +370,8 @@ void LLCrashLogger::updateApplication(const std::string& message)
bool LLCrashLogger::init()
{
+ LLCurl::initClass();
+
// We assume that all the logs we're looking for reside on the current drive
gDirUtilp->initAppDirs("SecondLife");
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 34348230b6..3c3356f41d 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -86,6 +86,8 @@ const F32 SKEW_MAX = 0.95f;
const F32 SCULPT_MIN_AREA = 0.002f;
const S32 SCULPT_MIN_AREA_DETAIL = 1;
+#define GEN_TRI_STRIP 0
+
BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)
{
LLVector3 test = (pt2-pt1)%(pt3-pt2);
@@ -1688,7 +1690,7 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mGenerateSingleFace = generate_single_face;
generate();
- if (mParams.getSculptID().isNull())
+ if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE)
{
createVolumeFaces();
}
@@ -1864,6 +1866,11 @@ void LLVolume::createVolumeFaces()
LLProfile::Face& face = mProfilep->mFaces[i];
vf.mBeginS = face.mIndex;
vf.mNumS = face.mCount;
+ if (vf.mNumS < 0)
+ {
+ llerrs << "Volume face corruption detected." << llendl;
+ }
+
vf.mBeginT = 0;
vf.mNumT= getPath().mPath.size();
vf.mID = i;
@@ -1907,6 +1914,10 @@ void LLVolume::createVolumeFaces()
if (face.mFlat && vf.mNumS > 2)
{ //flat inner faces have to copy vert normals
vf.mNumS = vf.mNumS*2;
+ if (vf.mNumS < 0)
+ {
+ llerrs << "Volume face corruption detected." << llendl;
+ }
}
}
else
@@ -4521,7 +4532,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
if (!partial_build)
{
+#if GEN_TRI_STRIP
mTriStrip.clear();
+#endif
S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};
for(S32 gx = 0;gx<grid_size;gx++)
{
@@ -4535,6 +4548,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
}
+#if GEN_TRI_STRIP
if (gy == 0)
{
mTriStrip.push_back((gx+1)*(grid_size+1));
@@ -4550,6 +4564,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
mTriStrip.push_back(gy+1+gx*(grid_size+1));
}
+#endif
}
else
{
@@ -4558,6 +4573,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);
}
+#if GEN_TRI_STRIP
if (gy == 0)
{
mTriStrip.push_back(gx*(grid_size+1));
@@ -4572,15 +4588,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
{
mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));
}
+#endif
}
}
}
+#if GEN_TRI_STRIP
if (mTriStrip.size()%2 == 1)
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
+#endif
}
return TRUE;
@@ -4950,6 +4969,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
mIndices[3*i+v2] = i + 1;
}
+#if GEN_TRI_STRIP
//make tri strip
if (mTypeMask & OPEN_MASK)
{
@@ -4992,6 +5012,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
}
+#endif
}
return TRUE;
@@ -4999,6 +5020,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)
void LLVolumeFace::makeTriStrip()
{
+#if GEN_TRI_STRIP
for (U32 i = 0; i < mIndices.size(); i+=3)
{
U16 i0 = mIndices[i];
@@ -5027,6 +5049,7 @@ void LLVolumeFace::makeTriStrip()
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
+#endif
}
void LLVolumeFace::createBinormals()
@@ -5112,12 +5135,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mHasBinormals = FALSE;
}
-
- LLVector3& face_min = mExtents[0];
- LLVector3& face_max = mExtents[1];
-
- mCenter.clearVec();
-
S32 begin_stex = llfloor( profile[mBeginS].mV[2] );
S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS;
@@ -5173,15 +5190,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
-
- if (cur_vertex == 0)
- {
- face_min = face_max = mesh[i].mPos;
- }
- else
- {
- update_min_max(face_min, face_max, mesh[i].mPos);
- }
cur_vertex++;
@@ -5215,12 +5223,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mVertices[cur_vertex].mNormal = LLVector3(0,0,0);
mVertices[cur_vertex].mBinormal = LLVector3(0,0,0);
- update_min_max(face_min,face_max,mesh[i].mPos);
-
cur_vertex++;
}
}
+
+ //get bounding box for this side
+ LLVector3& face_min = mExtents[0];
+ LLVector3& face_max = mExtents[1];
+ mCenter.clearVec();
+
+ face_min = face_max = mVertices[0].mPosition;
+ for (U32 i = 1; i < mVertices.size(); ++i)
+ {
+ update_min_max(face_min, face_max, mVertices[i].mPosition);
+ }
+
mCenter = (face_min + face_max) * 0.5f;
S32 cur_index = 0;
@@ -5229,13 +5247,17 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
if (!partial_build)
{
+#if GEN_TRI_STRIP
mTriStrip.clear();
+#endif
// Now we generate the indices.
for (t = 0; t < (mNumT-1); t++)
{
+#if GEN_TRI_STRIP
//prepend terminating index to strip
mTriStrip.push_back(mNumS*t);
+#endif
for (s = 0; s < (mNumS-1); s++)
{
@@ -5246,6 +5268,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
mIndices[cur_index++] = s+1 + mNumS*t; //bottom right
mIndices[cur_index++] = s+1 + mNumS*(t+1); //top right
+#if GEN_TRI_STRIP
if (s == 0)
{
mTriStrip.push_back(s+mNumS*t);
@@ -5253,6 +5276,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
mTriStrip.push_back(s+1+mNumS*t);
mTriStrip.push_back(s+1+mNumS*(t+1));
+#endif
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1; //bottom left/top right neighbor face
if (t < mNumT-2) { //top right/top left neighbor face
@@ -5294,44 +5318,37 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)
}
mEdge[cur_edge++] = (mNumS-1)*2*t+s*2; //top right/bottom left neighbor face
}
+#if GEN_TRI_STRIP
//append terminating vertex to strip
mTriStrip.push_back(mNumS-1+mNumS*(t+1));
+#endif
}
+#if GEN_TRI_STRIP
if (mTriStrip.size()%2 == 1)
{
mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);
}
+#endif
}
//generate normals
for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle
{
- const S32 i0 = mIndices[i*3+0];
- const S32 i1 = mIndices[i*3+1];
- const S32 i2 = mIndices[i*3+2];
- const VertexData& v0 = mVertices[i0];
- const VertexData& v1 = mVertices[i1];
- const VertexData& v2 = mVertices[i2];
+ const U16* idx = &(mIndices[i*3]);
+
+ VertexData* v[] =
+ { &mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] };
//calculate triangle normal
- LLVector3 norm = (v0.mPosition-v1.mPosition) % (v0.mPosition-v2.mPosition);
+ LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition);
- for (U32 j = 0; j < 3; j++)
- { //add triangle normal to vertices
- const S32 idx = mIndices[i*3+j];
- mVertices[idx].mNormal += norm; // * (weight_sum - d[j])/weight_sum;
- }
+ v[0]->mNormal += norm;
+ v[1]->mNormal += norm;
+ v[2]->mNormal += norm;
//even out quad contributions
- if ((i & 1) == 0)
- {
- mVertices[i2].mNormal += norm;
- }
- else
- {
- mVertices[i1].mNormal += norm;
- }
+ v[i%2+1]->mNormal += norm;
}
// adjust normals based on wrapping and stitching
diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
index 5e9dfd81fa..e3ce2c5ad3 100644
--- a/indra/llmessage/llpumpio.cpp
+++ b/indra/llmessage/llpumpio.cpp
@@ -444,13 +444,13 @@ void LLPumpIO::pump()
pump(DEFAULT_POLL_TIMEOUT);
}
-static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");
//timeout is in microseconds
void LLPumpIO::pump(const S32& poll_timeout)
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
- LLFastTimer t1(FTM_PUMP);
+ LLFastTimer t1(FTM_PUMP_IO);
//llinfos << "LLPumpIO::pump()" << llendl;
// Run any pending runners.
@@ -778,6 +778,8 @@ bool LLPumpIO::respond(
return true;
}
+static LLFastTimer::DeclareTimer FTM_PUMP_CALLBACK_CHAIN("Chain");
+
void LLPumpIO::callback()
{
LLMemType m1(LLMemType::MTYPE_IO_PUMP);
@@ -799,6 +801,7 @@ void LLPumpIO::callback()
callbacks_t::iterator end = mCallbacks.end();
for(; it != end; ++it)
{
+ LLFastTimer t(FTM_PUMP_CALLBACK_CHAIN);
// it's always the first and last time for respone chains
(*it).mHead = (*it).mChainLinks.begin();
(*it).mInit = true;
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 4f828186cb..e67d436887 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -286,6 +286,7 @@ public:
void setLightTexture(const LLUUID& id) { mLightTexture = id; }
LLUUID getLightTexture() const { return mLightTexture; }
+ bool isLightSpotlight() const { return mLightTexture.notNull(); }
void setParams(const LLVector3& params) { mParams = params; }
LLVector3 getParams() const { return mParams; }
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index a3f7a946ec..7ff68fe34b 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -185,6 +185,9 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT =
// GL_EXT_framebuffer_blit
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
+// GL_EXT_blend_func_separate
+PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
+
// GL_ARB_draw_buffers
PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL;
@@ -324,6 +327,7 @@ LLGLManager::LLGLManager() :
mHasCompressedTextures(FALSE),
mHasFramebufferObject(FALSE),
mHasFramebufferMultisample(FALSE),
+ mHasBlendFuncSeparate(FALSE),
mHasVertexBufferObject(FALSE),
mHasPBuffer(FALSE),
@@ -633,6 +637,11 @@ void LLGLManager::initExtensions()
#else
mHasDrawBuffers = FALSE;
# endif
+# if GL_EXT_blend_func_separate
+ mHasBlendFuncSeparate = TRUE;
+#else
+ mHasBlendFuncSeparate = FALSE;
+# endif
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
@@ -659,6 +668,7 @@ void LLGLManager::initExtensions()
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
+ mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);
#if !LL_DARWIN
mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts);
@@ -682,6 +692,7 @@ void LLGLManager::initExtensions()
mHasFramebufferObject = FALSE;
mHasFramebufferMultisample = FALSE;
mHasDrawBuffers = FALSE;
+ mHasBlendFuncSeparate = FALSE;
mHasMipMapGeneration = FALSE;
mHasSeparateSpecularColor = FALSE;
mHasAnisotropic = FALSE;
@@ -706,6 +717,7 @@ void LLGLManager::initExtensions()
mHasShaderObjects = FALSE;
mHasVertexShader = FALSE;
mHasFragmentShader = FALSE;
+ mHasBlendFuncSeparate = FALSE;
LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;
}
if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */
@@ -734,7 +746,8 @@ void LLGLManager::initExtensions()
if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S
if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;
if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE;
-
+ if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S
+
}
#endif // LL_LINUX || LL_SOLARIS
@@ -782,6 +795,14 @@ void LLGLManager::initExtensions()
{
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;
}
+ if (!mHasBlendFuncSeparate)
+ {
+ LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL;
+ }
+ if (!mHasDrawBuffers)
+ {
+ LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL;
+ }
// Disable certain things due to known bugs
if (mIsIntel && mHasMipMapGeneration)
@@ -852,6 +873,10 @@ void LLGLManager::initExtensions()
{
glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");
}
+ if (mHasBlendFuncSeparate)
+ {
+ glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT");
+ }
#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
@@ -1014,24 +1039,9 @@ void flush_glerror()
glGetError();
}
-void assert_glerror()
+void do_assert_glerror()
{
- if (!gGLActive)
- {
- //llwarns << "GL used while not active!" << llendl;
-
- if (gDebugSession)
- {
- //ll_fail("GL used while not active");
- }
- }
-
- if (gNoRender || !gDebugGL)
- {
- return;
- }
-
- if (!gGLManager.mInited)
+ if (LL_UNLIKELY(!gGLManager.mInited))
{
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
}
@@ -1039,10 +1049,9 @@ void assert_glerror()
GLenum error;
error = glGetError();
BOOL quit = FALSE;
- while (error)
+ while (LL_UNLIKELY(error))
{
quit = TRUE;
-#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
GLubyte const * gl_error_msg = gluErrorString(error);
if (NULL != gl_error_msg)
{
@@ -1066,7 +1075,6 @@ void assert_glerror()
}
}
error = glGetError();
-#endif
}
if (quit)
@@ -1082,6 +1090,25 @@ void assert_glerror()
}
}
+void assert_glerror()
+{
+ if (!gGLActive)
+ {
+ //llwarns << "GL used while not active!" << llendl;
+
+ if (gDebugSession)
+ {
+ //ll_fail("GL used while not active");
+ }
+ }
+
+ if (!gNoRender && gDebugGL)
+ {
+ do_assert_glerror();
+ }
+}
+
+
void clear_glerror()
{
// Create or update texture to be used with this data
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 91421f3c95..0c2da7dd08 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -87,6 +87,7 @@ public:
BOOL mHasCompressedTextures;
BOOL mHasFramebufferObject;
BOOL mHasFramebufferMultisample;
+ BOOL mHasBlendFuncSeparate;
// ARB Extensions
BOOL mHasVertexBufferObject;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index f33ae7d8f0..f6d35bc766 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -216,6 +216,9 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
+//GL_EXT_blend_func_separate
+extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
+
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@@ -249,7 +252,10 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
# include "GL/glh_extensions.h"
# undef __APPLE__
-#elif LL_LINUX
+#elif LL_LINUX
+//----------------------------------------------------------------------------
+// LL_LINUX
+
//----------------------------------------------------------------------------
// Linux, MESA headers, but not necessarily assuming MESA runtime.
// quotes so we get libraries/.../GL/ version
@@ -285,6 +291,7 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
# define LL_LINUX_NV_GL_HEADERS 0
#endif // LL_LINUX && defined(WINGDIAPI)
+
#if LL_LINUX_NV_GL_HEADERS
// Missing functions when using nvidia headers:
extern PFNGLACTIVETEXTUREARBPROC glActiveTextureARB;
@@ -445,6 +452,9 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
+//GL_EXT_blend_func_separate
+extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
+
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@@ -473,7 +483,10 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
+
#elif LL_WINDOWS
+//----------------------------------------------------------------------------
+// LL_WINDOWS
// windows gl headers depend on things like APIENTRY, so include windows.
#define WIN32_LEAN_AND_MEAN
@@ -641,6 +654,9 @@ extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
+//GL_EXT_blend_func_separate
+extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
+
//GL_EXT_framebuffer_object
extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
@@ -669,6 +685,7 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
//GL_ARB_draw_buffers
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
+
#elif LL_DARWIN
//----------------------------------------------------------------------------
// LL_DARWIN
@@ -685,6 +702,9 @@ extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
// Note that they also must not be called on 10.3.9. This should be taken care of by a runtime check for the existence of the GL extension.
#include <AvailabilityMacros.h>
+//GL_EXT_blend_func_separate
+extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
+
// GL_EXT_framebuffer_object
extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
extern void glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index ff47c57c70..2f02ccf30b 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1645,7 +1645,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
}
}
-void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
+void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
{
if(!mNeedsAlphaAndPickMask)
{
@@ -1653,26 +1653,91 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)
}
U32 length = w * h;
- const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ;
+ U32 alphatotal = 0;
- S32 sample[16];
- memset(sample, 0, sizeof(S32)*16);
-
- for (U32 i = 0; i < length; i++)
+ U32 sample[16];
+ memset(sample, 0, sizeof(U32)*16);
+
+ // generate histogram of quantized alpha.
+ // also add-in the histogram of a 2x2 box-sampled version. The idea is
+ // this will mid-skew the data (and thus increase the chances of not
+ // being used as a mask) from high-frequency alpha maps which
+ // suffer the worst from aliasing when used as alpha masks.
+ if (w >= 2 && h >= 2)
+ {
+ llassert(w%2 == 0);
+ llassert(h%2 == 0);
+ const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset;
+ for (U32 y = 0; y < h; y+=2)
+ {
+ const GLubyte* current = rowstart;
+ for (U32 x = 0; x < w; x+=2)
+ {
+ const U32 s1 = current[0];
+ alphatotal += s1;
+ const U32 s2 = current[w * mAlphaStride];
+ alphatotal += s2;
+ current += mAlphaStride;
+ const U32 s3 = current[0];
+ alphatotal += s3;
+ const U32 s4 = current[w * mAlphaStride];
+ alphatotal += s4;
+ current += mAlphaStride;
+
+ ++sample[s1/16];
+ ++sample[s2/16];
+ ++sample[s3/16];
+ ++sample[s4/16];
+
+ const U32 asum = (s1+s2+s3+s4);
+ alphatotal += asum;
+ sample[asum/(16*4)] += 4;
+ }
+
+ rowstart += 2 * w * mAlphaStride;
+ }
+ length *= 2; // we sampled everything twice, essentially
+ }
+ else
{
- ++sample[*current/16];
- current += mAlphaStride ;
+ const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset;
+ for (U32 i = 0; i < length; i++)
+ {
+ const U32 s1 = *current;
+ alphatotal += s1;
+ ++sample[s1/16];
+ current += mAlphaStride;
+ }
}
+
+ // if more than 1/16th of alpha samples are mid-range, this
+ // shouldn't be treated as a 1-bit mask
- U32 total = 0;
+ // also, if all of the alpha samples are clumped on one half
+ // of the range (but not at an absolute extreme), then consider
+ // this to be an intentional effect and don't treat as a mask.
+
+ U32 midrangetotal = 0;
for (U32 i = 4; i < 11; i++)
{
- total += sample[i];
+ midrangetotal += sample[i];
+ }
+ U32 lowerhalftotal = 0;
+ for (U32 i = 0; i < 8; i++)
+ {
+ lowerhalftotal += sample[i];
+ }
+ U32 upperhalftotal = 0;
+ for (U32 i = 8; i < 16; i++)
+ {
+ upperhalftotal += sample[i];
}
- if (total > length/16)
+ if (midrangetotal > length/16 || // lots of midrange, or
+ (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or
+ (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque
{
- mIsMask = FALSE;
+ mIsMask = FALSE; // not suitable for masking
}
else
{
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 41239d24c8..03939888a5 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -91,7 +91,7 @@ public:
protected:
virtual ~LLImageGL();
- void analyzeAlpha(const void* data_in, S32 w, S32 h);
+ void analyzeAlpha(const void* data_in, U32 w, U32 h);
void calcAlphaChannelOffsetAndStride();
public:
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index c3540a717c..5597b23c69 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -778,8 +778,10 @@ LLRender::LLRender()
mCurrAlphaFunc = CF_DEFAULT;
mCurrAlphaFuncVal = 0.01f;
- mCurrBlendSFactor = BF_UNDEF;
- mCurrBlendDFactor = BF_UNDEF;
+ mCurrBlendColorSFactor = BF_UNDEF;
+ mCurrBlendAlphaSFactor = BF_UNDEF;
+ mCurrBlendColorDFactor = BF_UNDEF;
+ mCurrBlendAlphaDFactor = BF_UNDEF;
}
LLRender::~LLRender()
@@ -995,15 +997,44 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)
{
llassert(sfactor < BF_UNDEF);
llassert(dfactor < BF_UNDEF);
- if (mCurrBlendSFactor != sfactor || mCurrBlendDFactor != dfactor)
+ if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor ||
+ mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)
{
- mCurrBlendSFactor = sfactor;
- mCurrBlendDFactor = dfactor;
+ mCurrBlendColorSFactor = sfactor;
+ mCurrBlendAlphaSFactor = sfactor;
+ mCurrBlendColorDFactor = dfactor;
+ mCurrBlendAlphaDFactor = dfactor;
flush();
glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);
}
}
+void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
+ eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor)
+{
+ llassert(color_sfactor < BF_UNDEF);
+ llassert(color_dfactor < BF_UNDEF);
+ llassert(alpha_sfactor < BF_UNDEF);
+ llassert(alpha_dfactor < BF_UNDEF);
+ if (!gGLManager.mHasBlendFuncSeparate)
+ {
+ LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl;
+ blendFunc(color_sfactor, color_dfactor);
+ return;
+ }
+ if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor ||
+ mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor)
+ {
+ mCurrBlendColorSFactor = color_sfactor;
+ mCurrBlendAlphaSFactor = alpha_sfactor;
+ mCurrBlendColorDFactor = color_dfactor;
+ mCurrBlendAlphaDFactor = alpha_dfactor;
+ flush();
+ glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor],
+ sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
+ }
+}
+
LLTexUnit* LLRender::getTexUnit(U32 index)
{
if (index < mTexUnits.size())
diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h
index a90fbd4a5c..f6c87aa1db 100644
--- a/indra/llrender/llrender.h
+++ b/indra/llrender/llrender.h
@@ -323,7 +323,11 @@ public:
void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f);
+ // applies blend func to both color and alpha
void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor);
+ // applies separate blend functions to color and alpha
+ void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
+ eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
LLTexUnit* getTexUnit(U32 index);
@@ -362,8 +366,10 @@ private:
std::vector<LLTexUnit*> mTexUnits;
LLTexUnit* mDummyTexUnit;
- eBlendFactor mCurrBlendSFactor;
- eBlendFactor mCurrBlendDFactor;
+ eBlendFactor mCurrBlendColorSFactor;
+ eBlendFactor mCurrBlendColorDFactor;
+ eBlendFactor mCurrBlendAlphaSFactor;
+ eBlendFactor mCurrBlendAlphaDFactor;
F32 mMaxAnisotropy;
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index bf5eda21eb..ae43915a9d 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -61,6 +61,7 @@ BOOL LLVertexBuffer::sVBOActive = FALSE;
BOOL LLVertexBuffer::sIBOActive = FALSE;
U32 LLVertexBuffer::sAllocatedBytes = 0;
BOOL LLVertexBuffer::sMapped = FALSE;
+BOOL LLVertexBuffer::sUseStreamDraw = TRUE;
std::vector<U32> LLVertexBuffer::sDeleteList;
@@ -381,6 +382,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :
{
mUsage = 0 ;
}
+
+ if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw)
+ {
+ mUsage = 0;
+ }
S32 stride = calcStride(typemask, mOffsets);
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index b785a22976..e2fecdffef 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -83,6 +83,8 @@ public:
static LLVBOPool sDynamicVBOPool;
static LLVBOPool sStreamIBOPool;
static LLVBOPool sDynamicIBOPool;
+
+ static BOOL sUseStreamDraw;
static void initClass(bool use_vbo);
static void cleanupClass();
diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml
index 6368f7099e..587b2f2a89 100644
--- a/indra/newview/app_settings/high_graphics.xml
+++ b/indra/newview/app_settings/high_graphics.xml
@@ -12,8 +12,6 @@
<RenderFlexTimeFactor value="1"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="9"/>
- <!--Sun/Moon only-->
- <RenderLightingDetail value="1"/>
<!--Low number-->
<RenderMaxPartCount value="4096"/>
<!--bump okay-->
@@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <RenderWaterReflections value="FALSE"/>
- <!--NO SHADERS-->
<VertexShaderEnable value="TRUE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="TRUE"/>
+ <!--Deferred Shading-->
+ <RenderDeferred value="FALSE"/>
+ <!--SSAO Disabled-->
+ <RenderDeferredSSAO value="FALSE"/>
+ <!--Sun Shadows-->
+ <RenderShadowDetail value="0"/>
+
</settings>
diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml
index 3f67a70d7a..a300c8646c 100644
--- a/indra/newview/app_settings/low_graphics.xml
+++ b/indra/newview/app_settings/low_graphics.xml
@@ -12,8 +12,6 @@
<RenderFlexTimeFactor value="0.5"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="8"/>
- <!--Sun/Moon only-->
- <RenderLightingDetail value="0"/>
<!--Low number-->
<RenderMaxPartCount value="1024"/>
<!--bump okay-->
@@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <RenderWaterReflections value="FALSE"/>
- <!--NO SHADERS-->
<VertexShaderEnable value="FALSE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
+ <!--No Deferred Shading-->
+ <RenderDeferred value="FALSE"/>
+ <!--SSAO Disabled-->
+ <RenderDeferredSSAO value="FALSE"/>
+ <!--No Shadows-->
+ <RenderShadowDetail value="0"/>
+
</settings>
diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml
index 12da77da40..a1430a58f9 100644
--- a/indra/newview/app_settings/mid_graphics.xml
+++ b/indra/newview/app_settings/mid_graphics.xml
@@ -12,8 +12,6 @@
<RenderFlexTimeFactor value="1"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="8"/>
- <!--Sun/Moon only-->
- <RenderLightingDetail value="1"/>
<!--Low number-->
<RenderMaxPartCount value="2048"/>
<!--bump okay-->
@@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="1.125"/>
<!--NO SHADERS-->
- <RenderWaterReflections value="FALSE"/>
- <!--NO SHADERS-->
<VertexShaderEnable value="TRUE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="FALSE"/>
+ <!--No Deferred Shading-->
+ <RenderDeferred value="FALSE"/>
+ <!--SSAO Disabled-->
+ <RenderDeferredSSAO value="FALSE"/>
+ <!--No Shadows-->
+ <RenderShadowDetail value="0"/>
+
</settings>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4e4c0274e7..56d8719e46 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -6241,7 +6241,7 @@
<key>Type</key>
<string>U32</string>
<key>Value</key>
- <integer>60</integer>
+ <integer>200</integer>
</map>
<key>RenderSSAOFactor</key>
<map>
@@ -6616,6 +6616,52 @@
<real>0.01</real>
</map>
+ <key>RenderShadowBiasError</key>
+ <map>
+ <key>Comment</key>
+ <string>Error scale for shadow bias (based on altitude).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+ <key>RenderShadowOffsetError</key>
+ <map>
+ <key>Comment</key>
+ <string>Error scale for shadow offset (based on altitude).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0</real>
+ </map>
+
+ <key>RenderSpotShadowBias</key>
+ <map>
+ <key>Comment</key>
+ <string>Bias value for shadows (prevent shadow acne).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.0</real>
+ </map>
+ <key>RenderSpotShadowOffset</key>
+ <map>
+ <key>Comment</key>
+ <string>Offset value for shadows (prevent shadow acne).</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>F32</string>
+ <key>Value</key>
+ <real>0.04</real>
+ </map>
+
<key>RenderShadowResolutionScale</key>
<map>
<key>Comment</key>
@@ -6628,8 +6674,6 @@
<real>1.0</real>
</map>
-
-
<key>RenderDeferredTreeShadowBias</key>
<map>
<key>Comment</key>
@@ -6751,7 +6795,7 @@
<key>Type</key>
<string>F32</string>
<key>Value</key>
- <real>1</real>
+ <real>8</real>
</map>
<key>RenderDeferred</key>
@@ -6765,19 +6809,7 @@
<key>Value</key>
<integer>0</integer>
</map>
-
- <key>RenderDeferredShadow</key>
- <map>
- <key>Comment</key>
- <string>Enable shadows in deferred renderer.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
-
+
<key>RenderDeferredGI</key>
<map>
<key>Comment</key>
@@ -6790,10 +6822,10 @@
<integer>0</integer>
</map>
- <key>RenderDeferredSunShadow</key>
+ <key>RenderDeferredSun</key>
<map>
<key>Comment</key>
- <string>Generate shadows from the sun.</string>
+ <string>Execute sunlight shader in deferred renderer.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6802,10 +6834,10 @@
<integer>1</integer>
</map>
- <key>RenderDeferredSun</key>
+ <key>RenderDeferredAtmospheric</key>
<map>
<key>Comment</key>
- <string>Execute sunlight shader in deferred renderer.</string>
+ <string>Execute atmospheric shader in deferred renderer.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -6814,10 +6846,10 @@
<integer>1</integer>
</map>
- <key>RenderDeferredAtmospheric</key>
+ <key>RenderDeferredSSAO</key>
<map>
<key>Comment</key>
- <string>Execute atmospheric shader in deferred renderer.</string>
+ <string>Execute screen space ambient occlusion shader in deferred renderer.</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7076,10 +7108,10 @@
<key>Value</key>
<real>256.0</real>
</map>
- <key>RenderFastAlpha</key>
+ <key>RenderAutoMaskAlphaNonDeferred</key>
<map>
<key>Comment</key>
- <string>Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces).</string>
+ <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>
<key>Persist</key>
<integer>1</integer>
<key>Type</key>
@@ -7087,6 +7119,17 @@
<key>Value</key>
<integer>0</integer>
</map>
+ <key>RenderAutoMaskAlphaDeferred</key>
+ <map>
+ <key>Comment</key>
+ <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderFastUI</key>
<map>
<key>Comment</key>
@@ -7348,17 +7391,6 @@
<key>Value</key>
<integer>0</integer>
</map>
- <key>RenderLightingDetail</key>
- <map>
- <key>Comment</key>
- <string>Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights)</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>S32</string>
- <key>Value</key>
- <integer>1</integer>
- </map>
<key>RenderMaxPartCount</key>
<map>
<key>Comment</key>
@@ -7458,7 +7490,19 @@
<key>Value</key>
<integer>2</integer>
</map>
- <key>RenderReflectionRes</key>
+ <key>RenderShadowDetail</key>
+ <map>
+ <key>Comment</key>
+ <string>Detail of shadows.</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>S32</string>
+ <key>Value</key>
+ <integer>2</integer>
+ </map>
+
+ <key>RenderReflectionRes</key>
<map>
<key>Comment</key>
<string>Reflection map resolution.</string>
@@ -7588,7 +7632,7 @@
<key>Type</key>
<string>Boolean</string>
<key>Value</key>
- <integer>0</integer>
+ <integer>1</integer>
</map>
<key>RenderUIBuffer</key>
<map>
@@ -7689,6 +7733,17 @@
<key>Value</key>
<integer>1</integer>
</map>
+ <key>RenderUseStreamVBO</key>
+ <map>
+ <key>Comment</key>
+ <string>Use VBO's for stream buffers</string>
+ <key>Persist</key>
+ <integer>1</integer>
+ <key>Type</key>
+ <string>Boolean</string>
+ <key>Value</key>
+ <integer>1</integer>
+ </map>
<key>RenderVolumeLODFactor</key>
<map>
<key>Comment</key>
@@ -7733,17 +7788,6 @@
<key>Value</key>
<integer>512</integer>
</map>
- <key>RenderWaterReflections</key>
- <map>
- <key>Comment</key>
- <string>Reflect the environment in the water.</string>
- <key>Persist</key>
- <integer>1</integer>
- <key>Type</key>
- <string>Boolean</string>
- <key>Value</key>
- <integer>0</integer>
- </map>
<key>RotateRight</key>
<map>
<key>Comment</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
index 4fb109d687..fea2e16090 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl
@@ -24,8 +24,6 @@ varying vec3 vary_fragcoord;
varying vec3 vary_position;
varying vec3 vary_light;
-uniform float alpha_soften;
-
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
@@ -57,15 +55,6 @@ void main()
color.rgb = scaleSoftClip(color.rgb);
- if (samp_pos.z != 0.0 && gl_Color.a < 1.0)
- {
- float dist_factor = alpha_soften;
- float a = gl_Color.a;
- a *= a;
- dist_factor *= 1.0/(1.0-a);
- color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
- }
-
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
index 1a7d58b07b..04e556c11a 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl
@@ -9,7 +9,7 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -41,23 +41,22 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
- vec4 col;
- col.a = gl_Color.a;
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
- col.rgb = scaleUpLight(col.rgb);
+
+ vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
- col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
- col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
- col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
- col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
+ col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
+ col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
+ col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
+ col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
+ // Add windlight lights
+ col.rgb += atmosAmbient(vec3(0.));
+
vary_light = gl_LightSource[0].position.xyz;
vary_ambient = col.rgb*gl_Color.rgb;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
index c1988d3c78..650fbcc3f5 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl
@@ -10,7 +10,7 @@ mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -47,23 +47,22 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
- vec4 col;
- col.a = gl_Color.a;
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
- col.rgb = scaleUpLight(col.rgb);
+
+ vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
- col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
- col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
- col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
- col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
+ col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
+ col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
+ col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
+ col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
+ // Add windlight lights
+ col.rgb += atmosAmbient(vec3(0.));
+
vary_ambient = col.rgb*gl_Color.rgb;
vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
index 75df388941..afbe08a579 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl
@@ -20,6 +20,7 @@ void main()
gl_FragData[0] = vec4(diff.rgb, 0.0);
gl_FragData[1] = vec4(0,0,0,0);
- gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
+ vec3 nvn = normalize(vary_normal);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
index 00083eb6b3..085ffddeec 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl
@@ -10,7 +10,7 @@ uniform sampler2D diffuseMap;
void main()
{
- gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
- //gl_FragColor = vec4(1,1,1,1);
+ //gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a);
+ gl_FragColor = vec4(1,1,1,1);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
index bd5e9dd758..d1c5d7cb19 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl
@@ -10,13 +10,11 @@
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
-uniform sampler2DRect giLightMap;
uniform float dist_factor;
uniform float blur_size;
uniform vec2 delta;
-uniform vec3 kern[32];
-uniform int kern_length;
+uniform vec3 kern[4];
uniform float kern_scale;
varying vec2 vary_fragcoord;
@@ -39,7 +37,8 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(vary_fragcoord.xy).xyz;
vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba;
@@ -50,7 +49,7 @@ void main()
vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free'
vec4 col = defined_weight.xyxx * ccol;
- for (int i = 1; i < kern_length; i++)
+ for (int i = 1; i < 4; i++)
{
vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;
vec3 samppos = getPosition(tc).xyz;
@@ -61,12 +60,22 @@ void main()
defined_weight += kern[i].xy;
}
}
+ for (int i = 1; i < 4; i++)
+ {
+ vec2 tc = vary_fragcoord.xy - kern[i].z*dlt;
+ vec3 samppos = getPosition(tc).xyz;
+ float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane
+ if (d*d <= 0.003)
+ {
+ col += texture2DRect(lightMap, tc)*kern[i].xyxx;
+ defined_weight += kern[i].xy;
+ }
+ }
col /= defined_weight.xyxx;
gl_FragColor = col;
-
- //gl_FragColor = ccol;
}
+
diff --git a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
index 1c29dae5f7..2197744a37 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl
@@ -14,14 +14,16 @@ varying vec3 vary_mat2;
void main()
{
- vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
+ vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0;
vec3 tnorm = vec3(dot(norm,vary_mat0),
- dot(norm,vary_mat1),
- dot(norm,vary_mat2));
+ dot(norm,vary_mat1),
+ dot(norm,vary_mat2));
- gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0);
- gl_FragData[1] = vec4(col*gl_Color.a, gl_Color.a);
- gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0);
+ gl_FragData[0] = vec4(col, 0.0);
+ gl_FragData[1] = gl_Color.aaaa; // spec
+ //gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
+ vec3 nvn = normalize(tnorm);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
index 5895ebda84..3803119cda 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl
@@ -11,8 +11,10 @@ varying vec3 vary_normal;
void main()
{
- vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
- gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0);
- gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a);
- gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
+ vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb;
+ gl_FragData[0] = vec4(col, 0.0);
+ gl_FragData[1] = gl_Color.aaaa; // spec
+ //gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested
+ vec3 nvn = normalize(vary_normal);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
index e518bddb98..0db9586a88 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl
@@ -23,8 +23,6 @@ varying vec4 vary_position;
varying vec3 vary_normal;
varying vec3 vary_fragcoord;
-uniform float alpha_soften;
-
uniform mat4 inv_proj;
vec4 getPosition(vec2 pos_screen)
@@ -56,15 +54,6 @@ void main()
color.rgb = fullbrightScaleSoftClip(color.rgb);
- if (samp_pos.z != 0.0 && color.a < 1.0)
- {
- float dist_factor = alpha_soften;
- float a = color.a;
- a *= a;
- dist_factor *= 1.0/(1.0-a);
- color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
- }
-
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
index b351eec6e5..d4b153c4af 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl
@@ -159,7 +159,8 @@ void main()
{
vec2 pos_screen = vary_fragcoord.xy;
vec4 pos = getPosition(pos_screen);
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
gl_FragData[0].xyz = giAmbient(pos, norm);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index 8c140a7b4f..508bbf415e 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -11,7 +11,8 @@ uniform sampler2D specularMap;
void main()
{
- gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy);
+ vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
+ gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);
gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 797b9e9f3b..b494b521ca 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -53,7 +53,9 @@ void main()
discard;
}
- vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0);
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+ norm = normalize(norm);
vec4 spec = texture2DRect(specularRect, frag.xy);
vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
float noise = texture2D(noiseMap, frag.xy/128.0).b;
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 28bcd720c0..82e9450e68 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -5,9 +5,10 @@
* $License$
*/
-
#version 120
+//class 1 -- no shadows
+
#extension GL_ARB_texture_rectangle : enable
uniform sampler2DRect diffuseRect;
@@ -26,12 +27,15 @@ uniform vec3 proj_n;
uniform float proj_focus; //distance from plane to begin blurring
uniform float proj_lod; //(number of mips in proj map)
uniform float proj_range; //range between near clip and far clip plane of projection
+uniform float proj_ambient_lod;
uniform float proj_ambiance;
uniform float near_clip;
uniform float far_clip;
uniform vec3 proj_origin; //origin of projection to be used for angular attenuation
uniform float sun_wash;
+uniform int proj_shadow_idx;
+uniform float shadow_fade;
varying vec4 vary_light;
@@ -40,6 +44,52 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -68,7 +118,7 @@ void main()
{
discard;
}
-
+
vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
norm = normalize(norm);
@@ -83,7 +133,11 @@ void main()
proj_tc.xyz /= proj_tc.w;
float fa = gl_Color.a+1.0;
- float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0);
+ float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0);
+ if (dist_atten <= 0.0)
+ {
+ discard;
+ }
lv = proj_origin-pos.xyz;
lv = normalize(lv);
@@ -101,32 +155,32 @@ void main()
proj_tc.y > 0.0)
{
float lit = 0.0;
+ float amb_da = proj_ambiance;
+
if (da > 0.0)
{
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
lit = da * dist_atten * noise;
col = lcol*lit*diff_tex;
+ amb_da += (da*0.5)*proj_ambiance;
}
- float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- float lod = diff * proj_lod;
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
- //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0));
- float amb_da = proj_ambiance;
-
+ //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
+
amb_da += (da*da*0.5+0.5)*proj_ambiance;
-
+
amb_da *= dist_atten * noise;
-
+
amb_da = min(amb_da, 1.0-lit);
-
+
col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a;
}
@@ -144,35 +198,28 @@ void main()
{
vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds;
- vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz;
+ vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));
if (stc.z > 0.0)
{
- stc.xy /= stc.z+proj_near;
-
+ stc.xy /= stc.w;
+
+ float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;
}
}
}
}
- /*if (spec.a > 0.0)
- {
- //vec3 ref = reflect(normalize(pos), norm);
- float sa = dot(normalize(lv-normalize(pos)),norm);;
- //sa = max(sa, 0.0);
- //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
- sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*lcol*spec.rgb;
- }*/
-
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index 78256e20cc..3aecbc5f23 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -55,7 +55,8 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
float da = dot(norm, lv);
if (da < 0.0)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
index 9612aee405..bd554c2d84 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl
@@ -38,10 +38,10 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(vary_fragcoord.xy).xyz;
-
vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
vec2 dlt = kern_scale * delta/(1.0+norm.xy*norm.xy);
dlt /= max(-pos.z*dist_factor, 1.0);
@@ -51,9 +51,10 @@ void main()
for (int i = 0; i < kern_length; i++)
{
vec2 tc = vary_fragcoord.xy + kern[i].y*dlt;
- vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0;
+ vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz;
+ sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm
- float d = dot(norm.xyz, sampNorm);
+ float d = dot(norm.xyz, sampNorm);
if (d > 0.8)
{
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index b4b0d0ce9d..bef91e735d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect positionMap;
uniform sampler2DRect normalMap;
+uniform sampler2DRect lightMap;
uniform sampler2DRect depthMap;
uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
@@ -40,7 +41,7 @@ uniform float scene_light_strength;
uniform vec3 env_mat[3];
//uniform mat4 shadow_matrix[3];
//uniform vec4 shadow_clip;
-//uniform mat3 ssao_effect_mat;
+uniform mat3 ssao_effect_mat;
varying vec4 vary_light;
varying vec2 vary_fragcoord;
@@ -55,9 +56,8 @@ vec3 vary_AtmosAttenuation;
uniform mat4 inv_proj;
uniform vec2 screen_res;
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -68,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+vec4 getPosition(vec2 pos_screen)
+{ //get position in screen space (world units) given window coordinate and depth map
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ return getPosition_d(pos_screen, depth);
+}
+
vec3 getPositionEye()
{
return vary_PositionEye;
@@ -178,7 +184,17 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {
temp2.x += .25;
//increase ambient when there are more clouds
- vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
+ vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;
+
+ /* decrease value and saturation (that in HSV, not HSL) for occluded areas
+ * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html
+ * // The following line of code performs the equivalent of:
+ * float ambAlpha = tmpAmbient.a;
+ * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis
+ * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue);
+ * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha);
+ */
+ tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a);
//haze color
setAdditiveColor(
@@ -241,8 +257,10 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 pos = getPosition(tc).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
+ float depth = texture2DRect(depthMap, tc.xy).a;
+ vec3 pos = getPosition_d(tc, depth).xyz;
+ vec3 norm = texture2DRect(normalMap, tc).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
@@ -250,23 +268,76 @@ void main()
vec4 diffuse = texture2DRect(diffuseRect, tc);
vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
- calcAtmospherics(pos.xyz, 0.0);
+ vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
+ float scol = max(scol_ambocc.r, diffuse.a);
+ float ambocc = scol_ambocc.g;
+
+ calcAtmospherics(pos.xyz, ambocc);
vec3 col = atmosAmbient(vec3(0));
- col += atmosAffectDirectionalLight(clamp(da, diffuse.a, 1.0));
+ col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));
col *= diffuse.rgb;
- if (spec.a > 0.0)
+ if (spec.a > 0.0) // specular reflection
{
- vec3 ref = normalize(reflect(pos.xyz, norm.xyz));
- float sa = dot(ref, vary_light.xyz);
- col.rgb += vary_SunlitColor*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
+ // the old infinite-sky shiny reflection
+ //
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnormpersp, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+ /*
+ // screen-space cheap fakey reflection map
+ //
+ vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
+ depth -= 0.5; // unbias depth
+ // first figure out where we'll make our 2D guess from
+ vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
+ // Offset the guess source a little according to a trivial
+ // checkerboard dither function and spec.a.
+ // This is meant to be similar to sampling a blurred version
+ // of the diffuse map. LOD would be better in that regard.
+ // The goal of the blur is to soften reflections in surfaces
+ // with low shinyness, and also to disguise our lameness.
+ float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
+ float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
+ ref2d += vec2(checkoffset, checkoffset);
+ ref2d += tc.xy; // use as offset from destination
+ // Get attributes from the 2D guess point.
+ // We average two samples of diffuse (not of anything else) per
+ // pixel to try to reduce aliasing some more.
+ vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
+ texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
+ float refdepth = texture2DRect(depthMap, ref2d).a;
+ vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
+ vec3 refn = texture2DRect(normalMap, ref2d).rgb;
+ refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm
+ // figure out how appropriate our guess actually was
+ float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
+ // darken reflections from points which face away from the reflected ray - our guess was a back-face
+ //refapprop *= step(dot(refnorm, refn), 0.0);
+ refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
+ // get appropriate light strength for guess-point.
+ // reflect light direction to increase the illusion that
+ // these are reflections.
+ vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
+ float reflit = max(dot(refn, reflight.xyz), 0.0);
+ // apply sun color to guess-point, dampen according to inappropriateness of guess
+ float refmod = min(refapprop, reflit);
+ vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
+ vec3 ssshiny = (refprod * spec.a);
+ ssshiny *= 0.3; // dampen it even more
+ */
+ vec3 ssshiny = vec3(0,0,0);
+
+ // add the two types of shiny together
+ col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);
col = scaleSoftClip(col);
-
+
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
index 2a7234fd83..1b95b253c3 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl
@@ -68,7 +68,8 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -161,17 +162,6 @@ void main()
}
}
- /*if (spec.a > 0.0)
- {
- //vec3 ref = reflect(normalize(pos), norm);
- float sa = dot(normalize(lv-normalize(pos)),norm);;
- //sa = max(sa, 0.0);
- //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
- sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*lcol*spec.rgb;
- }*/
-
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
index 22bdd2c7f3..56e4055c02 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl
@@ -5,196 +5,11 @@
* $License$
*/
-#extension GL_ARB_texture_rectangle : enable
-
-uniform sampler2DRect depthMap;
-uniform sampler2DRect normalMap;
-uniform sampler2DRectShadow shadowMap0;
-uniform sampler2DRectShadow shadowMap1;
-uniform sampler2DRectShadow shadowMap2;
-uniform sampler2DRectShadow shadowMap3;
-uniform sampler2DRectShadow shadowMap4;
-uniform sampler2DRectShadow shadowMap5;
-uniform sampler2D noiseMap;
-
-uniform sampler2D lightFunc;
-
-
-// Inputs
-uniform mat4 shadow_matrix[6];
-uniform vec4 shadow_clip;
-uniform float ssao_radius;
-uniform float ssao_max_radius;
-uniform float ssao_factor;
-uniform float ssao_factor_inv;
-
-varying vec2 vary_fragcoord;
-varying vec4 vary_light;
-
-uniform mat4 inv_proj;
-uniform vec2 screen_res;
-
-uniform float shadow_bias;
-uniform float shadow_offset;
-
-vec4 getPosition(vec2 pos_screen)
-{
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
- vec2 sc = pos_screen.xy*2.0;
- sc /= screen_res;
- sc -= vec2(1.0,1.0);
- vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
- vec4 pos = inv_proj * ndc;
- pos /= pos.w;
- pos.w = 1.0;
- return pos;
-}
+//class 1, no shadow, no SSAO, should never be called
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- int points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
- // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
- angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- points = points + int(diff.z > -1.0);
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-
- return (1.0 - (float(points != 0) * angle_hidden));
-}
+#extension GL_ARB_texture_rectangle : enable
void main()
{
- vec2 pos_screen = vary_fragcoord.xy;
-
- //try doing an unproject here
-
- vec4 pos = getPosition(pos_screen);
-
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
-
- /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
- {
- gl_FragColor = vec4(0.0); // doesn't matter
- return;
- }*/
-
- float shadow = 1.0;
- float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
-
- vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0);
-
- //vec3 debug = vec3(0,0,0);
-
- if (dp_directional_light == 0.0)
- {
- // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
- shadow = 0.0;
- }
- else if (spos.z > -shadow_clip.w)
- {
- vec4 lpos;
-
- if (spos.z < -shadow_clip.z)
- {
- lpos = shadow_matrix[3]*spos;
- lpos.xy *= screen_res;
- shadow = shadow2DRectProj(shadowMap3, lpos).x;
- shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
- }
- else if (spos.z < -shadow_clip.y)
- {
- lpos = shadow_matrix[2]*spos;
- lpos.xy *= screen_res;
- shadow = shadow2DRectProj(shadowMap2, lpos).x;
- }
- else if (spos.z < -shadow_clip.x)
- {
- lpos = shadow_matrix[1]*spos;
- lpos.xy *= screen_res;
- shadow = shadow2DRectProj(shadowMap1, lpos).x;
- }
- else
- {
- lpos = shadow_matrix[0]*spos;
- lpos.xy *= screen_res;
- shadow = shadow2DRectProj(shadowMap0, lpos).x;
- }
-
- // take the most-shadowed value out of these two:
- // * the blurred sun shadow in the light (shadow) map
- // * an unblurred dot product between the sun and this norm
- // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
- shadow = min(shadow, dp_directional_light);
-
- /*debug.r = lpos.y / (lpos.w*screen_res.y);
-
- lpos.xy /= lpos.w*32.0;
- if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
- {
- debug.gb = vec2(0.5, 0.5);
- }
-
- debug += (1.0-shadow)*0.5;*/
-
- }
- else
- {
- // more distant than the shadow map covers - just use directional shading as shadow
- shadow = dp_directional_light;
- }
-
- gl_FragColor[0] = shadow;
- gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
-
- //spotlight shadow 1
- vec4 lpos = shadow_matrix[4]*spos;
- lpos.xy *= screen_res;
- gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x;
-
- //spotlight shadow 2
- lpos = shadow_matrix[5]*spos;
- lpos.xy *= screen_res;
- gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x;
-
- //gl_FragColor.rgb = pos.xyz;
- //gl_FragColor.b = shadow;
- //gl_FragColor.rgb = debug;
+ gl_FragColor = vec4(0,0,0,0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
new file mode 100644
index 0000000000..cdbed4b791
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl
@@ -0,0 +1,124 @@
+/**
+ * @file sunLightSSAOF.glsl
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+//class 1 -- no shadow, SSAO only
+
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform sampler2D noiseMap;
+
+uniform sampler2D lightFunc;
+
+
+// Inputs
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float ssao_radius;
+uniform float ssao_max_radius;
+uniform float ssao_factor;
+uniform float ssao_factor_inv;
+
+varying vec2 vary_fragcoord;
+varying vec4 vary_light;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+
+uniform float shadow_bias;
+uniform float shadow_offset;
+
+vec4 getPosition(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ vec2 sc = pos_screen.xy*2.0;
+ sc /= screen_res;
+ sc -= vec2(1.0,1.0);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+//calculate decreases in ambient lighting when crowded out (SSAO)
+float calcAmbientOcclusion(vec4 pos, vec3 norm)
+{
+ float ret = 1.0;
+
+ float dist = dot(pos.xyz,pos.xyz);
+
+ if (dist < 64.0*64.0)
+ {
+ vec2 kern[8];
+ // exponentially (^2) distant occlusion samples spread around origin
+ kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
+ kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
+ kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
+ kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
+ kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
+ kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
+ kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
+ kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
+
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec3 pos_world = pos.xyz;
+ vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
+
+ float angle_hidden = 0.0;
+ int points = 0;
+
+ float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
+
+ // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
+ for (int i = 0; i < 8; i++)
+ {
+ vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
+ vec3 samppos_world = getPosition(samppos_screen).xyz;
+
+ vec3 diff = pos_world - samppos_world;
+ float dist2 = dot(diff, diff);
+
+ // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
+ // --> solid angle shrinking by the square of distance
+ //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
+ //(k should vary inversely with # of samples, but this is taken care of later)
+
+ //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
+ // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
+ angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
+
+ // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
+ points = points + int(diff.z > -1.0);
+ }
+
+ angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
+
+ ret = (1.0 - (float(points != 0) * angle_hidden));
+ ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0);
+ }
+
+ return min(ret, 1.0);
+}
+
+void main()
+{
+ vec2 pos_screen = vary_fragcoord.xy;
+
+ //try doing an unproject here
+
+ vec4 pos = getPosition(pos_screen);
+
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
+
+ gl_FragColor[0] = 1.0;
+ gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
+ gl_FragColor[2] = 1.0;
+ gl_FragColor[3] = 1.0;
+}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
index 3cccfb7202..fa0a60c98d 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl
@@ -29,6 +29,7 @@ void main()
gl_FragData[0] = vec4(outColor.rgb, 0.0);
gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2);
- gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
+ vec3 nvn = normalize(vary_normal);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
index 258acee08c..5b33ea5bfe 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl
@@ -14,5 +14,6 @@ void main()
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
gl_FragData[1] = vec4(0,0,0,0);
- gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
+ vec3 nvn = normalize(vary_normal);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
index d21575119d..361ae8dc84 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl
@@ -115,7 +115,7 @@ void main()
vec4 fb = texture2D(screenTex, distort2);
//mix with reflection
- // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug
+ // Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug
color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);
float shadow = 1.0;
@@ -131,11 +131,11 @@ void main()
//color.rgb = scaleSoftClip(color.rgb);
//color.a = spec * sunAngle2;
- //wavef.z = -0.25f;
- wavef = normalize(wavef);
- wavef = (norm_mat*vec4(wavef, 1.0)).xyz;
+ //wavef.z *= 0.1f;
+ //wavef = normalize(wavef);
+ vec3 screenspacewavef = (norm_mat*vec4(wavef, 1.0)).xyz;
- gl_FragData[0] = vec4(color.rgb, 0.75);
- gl_FragData[1] = vec4(1,1,1, 0.8);
- gl_FragData[2] = vec4(wavef*0.5+0.5, 0.0);
+ gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse
+ gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec
+ gl_FragData[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace
}
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
index 3e8fdfb3e4..da49e59b89 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl
@@ -12,7 +12,8 @@ float calcDirectionalLight(vec3 n, vec3 l)
return a;
}
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la)
+
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)
{
//get light vector
vec3 lv = lp.xyz-v;
@@ -26,9 +27,13 @@ float calcPointLight(vec3 v, vec3 n, vec4 lp, float la)
//distance attenuation
float da = clamp(1.0/(la * d), 0.0, 1.0);
+ // spotlight coefficient.
+ float spot = max(dot(-ln, lv), is_pointlight);
+ da *= spot*spot; // GL_SPOT_EXPONENT=2
+
//angular attenuation
da *= calcDirectionalLight(n, lv);
-
+
return da;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
index ad16de6d81..665fe16b43 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl
@@ -29,8 +29,6 @@ varying vec3 vary_fragcoord;
varying vec3 vary_position;
varying vec3 vary_light;
-uniform float alpha_soften;
-
uniform float shadow_bias;
uniform mat4 inv_proj;
@@ -115,15 +113,6 @@ void main()
color.rgb = scaleSoftClip(color.rgb);
- if (samp_pos.z != 0.0 && gl_Color.a < 1.0)
- {
- float dist_factor = alpha_soften;
- float a = gl_Color.a;
- a *= a;
- dist_factor *= 1.0/(1.0-a);
- color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0);
- }
-
//gl_FragColor = gl_Color;
gl_FragColor = color;
//gl_FragColor = vec4(1,0,1,1)*shadow;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
index 5991e1f3b5..1fae8c4da3 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl
@@ -9,7 +9,7 @@ vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol);
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -42,23 +42,21 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
- vec4 col;
- col.a = gl_Color.a;
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
- col.rgb = scaleUpLight(col.rgb);
+ vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
- col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
- col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
- col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
- col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
+ col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
+ col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
+ col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
+ col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
+ // Add windlight lights
+ col.rgb += atmosAmbient(vec3(0.));
+
vary_light = gl_LightSource[0].position.xyz;
vary_ambient = col.rgb*gl_Color.rgb;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
index a939499b17..f8dd1b7431 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl
@@ -10,7 +10,7 @@ mat4 getSkinnedTransform();
void calcAtmospherics(vec3 inPositionEye);
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -53,23 +53,22 @@ void main()
calcAtmospherics(pos.xyz);
//vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.));
- vec4 col;
- col.a = gl_Color.a;
-
- // Add windlight lights
- col.rgb = atmosAmbient(vec3(0.));
- col.rgb = scaleUpLight(col.rgb);
+
+ vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);
// Collect normal lights (need to be divided by two, as we later multiply by 2)
- col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
- col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
- col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
- col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
+ col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
+ col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
+ col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
+ col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
+ // Add windlight lights
+ col.rgb += atmosAmbient(vec3(0.));
+
vary_ambient = col.rgb*gl_Color.rgb;
vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a)));
diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
index 0fad5b4b50..d1c5d7cb19 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl
@@ -37,7 +37,8 @@ vec4 getPosition(vec2 pos_screen)
void main()
{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
vec3 pos = getPosition(vary_fragcoord.xy).xyz;
vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl
index 02beddd43b..e32e9f4b32 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl
@@ -31,7 +31,8 @@ float getDepth(vec2 pos_screen)
void main()
{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
float depth = getDepth(vary_fragcoord.xy);
vec2 tc = vary_fragcoord.xy;
@@ -46,8 +47,12 @@ void main()
de = step(depth_cutoff, de);
vec2 ne;
- ne.x = dot(texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb*2.0-1.0, norm);
- ne.y = dot(texture2DRect(normalMap, tc+vec2(sc,sc)).rgb*2.0-1.0, norm);
+ vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb;
+ nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm
+ ne.x = dot(nexnorm, norm);
+ vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb;
+ neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm
+ ne.y = dot(neynorm, norm);
ne = 1.0-ne;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 651959413c..22ffb58c63 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -43,6 +43,52 @@ uniform vec2 screen_res;
uniform mat4 inv_proj;
+vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float det = max(1.0-lod/(proj_lod*0.5), 0.0);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = vec2(0.5) - abs(tc-vec2(0.5));
+
+ float det = min(lod/(proj_lod*0.5), 1.0);
+
+ float d = min(dist.x, dist.y);
+
+ float edge = 0.25*det;
+
+ ret *= clamp(d/edge, 0.0, 1.0);
+
+ return ret;
+}
+
+vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod)
+{
+ vec4 ret = texture2DLod(projectionMap, tc, lod);
+
+ vec2 dist = tc-vec2(0.5);
+
+ float d = dot(dist,dist);
+
+ ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0);
+
+ return ret;
+}
+
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -83,7 +129,8 @@ void main()
shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -126,7 +173,7 @@ void main()
float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0);
float lod = diff * proj_lod;
- vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod);
+ vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);
vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;
@@ -137,7 +184,7 @@ void main()
}
//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0);
- vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod);
+ vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);
amb_da += (da*da*0.5+0.5)*proj_ambiance;
@@ -167,22 +214,23 @@ void main()
if (stc.z > 0.0)
{
stc.xy /= stc.w;
-
+
+ float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0);
+
+ stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5);
+
if (stc.x < 1.0 &&
stc.y < 1.0 &&
stc.x > 0.0 &&
stc.y > 0.0)
{
- vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
+ vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);
col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow;
}
}
}
}
- //attenuate point light contribution by SSAO component
- col *= texture2DRect(lightMap, frag.xy).g;
-
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index 531f7376a3..fd6ae2b960 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;
uniform sampler2DRect specularRect;
uniform sampler2DRect normalMap;
uniform sampler2DRect lightMap;
+uniform sampler2DRect depthMap;
uniform sampler2D noiseMap;
uniform samplerCube environmentMap;
uniform sampler2D lightFunc;
@@ -41,7 +42,6 @@ uniform vec3 env_mat[3];
uniform vec4 shadow_clip;
uniform mat3 ssao_effect_mat;
-uniform sampler2DRect depthMap;
uniform mat4 inv_proj;
uniform vec2 screen_res;
@@ -55,9 +55,8 @@ vec3 vary_AmblitColor;
vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -68,6 +67,12 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+vec4 getPosition(vec2 pos_screen)
+{ //get position in screen space (world units) given window coordinate and depth map
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ return getPosition_d(pos_screen, depth);
+}
+
vec3 getPositionEye()
{
return vary_PositionEye;
@@ -251,8 +256,10 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 pos = getPosition(tc).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
+ float depth = texture2DRect(depthMap, tc.xy).a;
+ vec3 pos = getPosition_d(tc, depth).xyz;
+ vec3 norm = texture2DRect(normalMap, tc).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
@@ -271,24 +278,67 @@ void main()
col *= diffuse.rgb;
- if (spec.a > 0.0)
+ if (spec.a > 0.0) // specular reflection
{
- vec3 ref = normalize(reflect(pos.xyz, norm.xyz));
- float sa = dot(ref, vary_light.xyz);
- col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
+ // the old infinite-sky shiny reflection
+ //
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnormpersp, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+ /*
+ // screen-space cheap fakey reflection map
+ //
+ vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
+ depth -= 0.5; // unbias depth
+ // first figure out where we'll make our 2D guess from
+ vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
+ // Offset the guess source a little according to a trivial
+ // checkerboard dither function and spec.a.
+ // This is meant to be similar to sampling a blurred version
+ // of the diffuse map. LOD would be better in that regard.
+ // The goal of the blur is to soften reflections in surfaces
+ // with low shinyness, and also to disguise our lameness.
+ float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
+ float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
+ ref2d += vec2(checkoffset, checkoffset);
+ ref2d += tc.xy; // use as offset from destination
+ // Get attributes from the 2D guess point.
+ // We average two samples of diffuse (not of anything else) per
+ // pixel to try to reduce aliasing some more.
+ vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
+ texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
+ float refdepth = texture2DRect(depthMap, ref2d).a;
+ vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
+ float refshad = texture2DRect(lightMap, ref2d).r;
+ vec3 refn = texture2DRect(normalMap, ref2d).rgb;
+ refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm
+ refn = normalize(refn);
+ // figure out how appropriate our guess actually was
+ float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
+ // darken reflections from points which face away from the reflected ray - our guess was a back-face
+ //refapprop *= step(dot(refnorm, refn), 0.0);
+ refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
+ // get appropriate light strength for guess-point
+ // reflect light direction to increase the illusion that
+ // these are reflections.
+ vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
+ float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad);
+ // apply sun color to guess-point, dampen according to inappropriateness of guess
+ float refmod = min(refapprop, reflit);
+ vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
+ vec3 ssshiny = (refprod * spec.a);
+ ssshiny *= 0.3; // dampen it even more
+ */
+ vec3 ssshiny = vec3(0,0,0);
+
+ // add the two types of shiny together
+ col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);
col = scaleSoftClip(col);
gl_FragColor.rgb = col;
-
- //gl_FragColor.rgb = gi_col.rgb;
gl_FragColor.a = 0.0;
-
- //gl_FragColor.rg = scol_ambocc.rg;
- //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb;
- //gl_FragColor.rgb = norm.rgb*0.5+0.5;
- //gl_FragColor.rgb = vec3(ambocc);
- //gl_FragColor.rgb = vec3(scol);
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index d6534083cf..8a90199b7c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -82,7 +82,8 @@ void main()
discard;
}
- vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, frag.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
norm = normalize(norm);
float l_dist = -dot(lv, proj_n);
@@ -179,21 +180,6 @@ void main()
}
}
- /*if (spec.a > 0.0)
- {
- //vec3 ref = reflect(normalize(pos), norm);
- float sa = dot(normalize(lv-normalize(pos)),norm);;
- //sa = max(sa, 0.0);
- //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0);
- sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0);
- sa *= noise;
- col += da*sa*lcol*spec.rgb;
- }*/
-
- //attenuate point light contribution by SSAO component
- col *= texture2DRect(lightMap, frag.xy).g;
-
-
gl_FragColor.rgb = col;
gl_FragColor.a = 0.0;
}
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
index a0026edcd2..7423347346 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl
@@ -7,6 +7,8 @@
#extension GL_ARB_texture_rectangle : enable
+//class 2, shadows, no SSAO
+
uniform sampler2DRect depthMap;
uniform sampler2DRect normalMap;
uniform sampler2DRectShadow shadowMap0;
@@ -39,6 +41,9 @@ uniform vec2 proj_shadow_res;
uniform float shadow_bias;
uniform float shadow_offset;
+uniform float spot_shadow_bias;
+uniform float spot_shadow_offset;
+
vec4 getPosition(vec2 pos_screen)
{
float depth = texture2DRect(depthMap, pos_screen.xy).a;
@@ -52,56 +57,6 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
-//calculate decreases in ambient lighting when crowded out (SSAO)
-float calcAmbientOcclusion(vec4 pos, vec3 norm)
-{
- vec2 kern[8];
- // exponentially (^2) distant occlusion samples spread around origin
- kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
- kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
- kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
- kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
- kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
- kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
- kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
- kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
-
- vec2 pos_screen = vary_fragcoord.xy;
- vec3 pos_world = pos.xyz;
- vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
-
- float angle_hidden = 0.0;
- int points = 0;
-
- float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
-
- // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
- for (int i = 0; i < 8; i++)
- {
- vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
- vec3 samppos_world = getPosition(samppos_screen).xyz;
-
- vec3 diff = pos_world - samppos_world;
- float dist2 = dot(diff, diff);
-
- // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
- // --> solid angle shrinking by the square of distance
- //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
- //(k should vary inversely with # of samples, but this is taken care of later)
-
- //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
- // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
- angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
-
- // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
- points = points + int(diff.z > -1.0);
- }
-
- angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
-
- return (1.0 - (float(points != 0) * angle_hidden));
-}
-
float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
{
stc.xyz /= stc.w;
@@ -123,7 +78,7 @@ float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
{
stc.xyz /= stc.w;
- stc.z += shadow_bias*scl;
+ stc.z += spot_shadow_bias*scl;
float cs = shadow2D(shadowMap, stc.xyz).x;
float shadow = cs;
@@ -134,8 +89,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
-
-
+
return shadow/5.0;
//return shadow;
@@ -149,7 +103,10 @@ void main()
vec4 pos = getPosition(pos_screen);
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
+ vec4 nmap4 = texture2DRect(normalMap, pos_screen);
+ nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
+ float displace = nmap4.w;
+ vec3 norm = nmap4.xyz;
/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
{
@@ -158,9 +115,12 @@ void main()
}*/
float shadow = 1.0;
- float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
+ float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
- vec4 spos = vec4(pos.xyz + vary_light.xyz * (1.0-dp_directional_light)*shadow_offset, 1.0);
+ vec3 shadow_pos = pos.xyz + displace*norm;
+ vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
+
+ vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
if (spos.z > -shadow_clip.w)
{
@@ -220,15 +180,17 @@ void main()
}
gl_FragColor[0] = shadow;
- gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
+ gl_FragColor[1] = 1.0;
+
+ spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);
//spotlight shadow 1
vec4 lpos = shadow_matrix[4]*spos;
- gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.1).x;
+ gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8);
//spotlight shadow 2
lpos = shadow_matrix[5]*spos;
- gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.1).x;
+ gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8);
//gl_FragColor.rgb = pos.xyz;
//gl_FragColor.b = shadow;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
new file mode 100644
index 0000000000..4e33a1af45
--- /dev/null
+++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl
@@ -0,0 +1,257 @@
+/**
+ * @file sunLightSSAOF.glsl
+ *
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+#extension GL_ARB_texture_rectangle : enable
+
+//class 2 -- shadows and SSAO
+
+uniform sampler2DRect depthMap;
+uniform sampler2DRect normalMap;
+uniform sampler2DRectShadow shadowMap0;
+uniform sampler2DRectShadow shadowMap1;
+uniform sampler2DRectShadow shadowMap2;
+uniform sampler2DRectShadow shadowMap3;
+uniform sampler2DShadow shadowMap4;
+uniform sampler2DShadow shadowMap5;
+uniform sampler2D noiseMap;
+
+uniform sampler2D lightFunc;
+
+// Inputs
+uniform mat4 shadow_matrix[6];
+uniform vec4 shadow_clip;
+uniform float ssao_radius;
+uniform float ssao_max_radius;
+uniform float ssao_factor;
+uniform float ssao_factor_inv;
+
+varying vec2 vary_fragcoord;
+varying vec4 vary_light;
+
+uniform mat4 inv_proj;
+uniform vec2 screen_res;
+uniform vec2 shadow_res;
+uniform vec2 proj_shadow_res;
+
+uniform float shadow_bias;
+uniform float shadow_offset;
+
+uniform float spot_shadow_bias;
+uniform float spot_shadow_offset;
+
+vec4 getPosition(vec2 pos_screen)
+{
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ vec2 sc = pos_screen.xy*2.0;
+ sc /= screen_res;
+ sc -= vec2(1.0,1.0);
+ vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0);
+ vec4 pos = inv_proj * ndc;
+ pos /= pos.w;
+ pos.w = 1.0;
+ return pos;
+}
+
+//calculate decreases in ambient lighting when crowded out (SSAO)
+float calcAmbientOcclusion(vec4 pos, vec3 norm)
+{
+ float ret = 1.0;
+
+ float dist = dot(pos.xyz,pos.xyz);
+
+ if (dist < 64.0*64.0)
+ {
+ vec2 kern[8];
+ // exponentially (^2) distant occlusion samples spread around origin
+ kern[0] = vec2(-1.0, 0.0) * 0.125*0.125;
+ kern[1] = vec2(1.0, 0.0) * 0.250*0.250;
+ kern[2] = vec2(0.0, 1.0) * 0.375*0.375;
+ kern[3] = vec2(0.0, -1.0) * 0.500*0.500;
+ kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625;
+ kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750;
+ kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875;
+ kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000;
+
+ vec2 pos_screen = vary_fragcoord.xy;
+ vec3 pos_world = pos.xyz;
+ vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy;
+
+ float angle_hidden = 0.0;
+ int points = 0;
+
+ float scale = min(ssao_radius / -pos_world.z, ssao_max_radius);
+
+ // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?)
+ for (int i = 0; i < 8; i++)
+ {
+ vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect);
+ vec3 samppos_world = getPosition(samppos_screen).xyz;
+
+ vec3 diff = pos_world - samppos_world;
+ float dist2 = dot(diff, diff);
+
+ // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area
+ // --> solid angle shrinking by the square of distance
+ //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2
+ //(k should vary inversely with # of samples, but this is taken care of later)
+
+ //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces
+ // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor)
+ angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv);
+
+ // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion"
+ points = points + int(diff.z > -1.0);
+ }
+
+ angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0);
+
+ ret = (1.0 - (float(points != 0) * angle_hidden));
+ ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0);
+ }
+
+ return min(ret, 1.0);
+}
+
+float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)
+{
+ stc.xyz /= stc.w;
+ stc.z += shadow_bias*scl;
+
+ float cs = shadow2DRect(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs);
+ shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs);
+ shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs);
+ shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs);
+
+ return shadow/5.0;
+
+ //return shadow;
+}
+
+float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)
+{
+ stc.xyz /= stc.w;
+ stc.z += spot_shadow_bias*scl;
+
+ float cs = shadow2D(shadowMap, stc.xyz).x;
+ float shadow = cs;
+
+ vec2 off = 1.5/proj_shadow_res;
+
+ shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs);
+ shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);
+ shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);
+ shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs);
+
+
+ return shadow/5.0;
+
+ //return shadow;
+}
+
+void main()
+{
+ vec2 pos_screen = vary_fragcoord.xy;
+
+ //try doing an unproject here
+
+ vec4 pos = getPosition(pos_screen);
+
+ vec4 nmap4 = texture2DRect(normalMap, pos_screen);
+ nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm
+ float displace = nmap4.w;
+ vec3 norm = nmap4.xyz;
+
+ /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL
+ {
+ gl_FragColor = vec4(0.0); // doesn't matter
+ return;
+ }*/
+
+ float shadow = 1.0;
+ float dp_directional_light = max(0.0, dot(norm, vary_light.xyz));
+
+ vec3 shadow_pos = pos.xyz + displace*norm;
+ vec3 offset = vary_light.xyz * (1.0-dp_directional_light);
+
+ vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);
+
+ if (spos.z > -shadow_clip.w)
+ {
+ if (dp_directional_light == 0.0)
+ {
+ // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup
+ shadow = 0.0;
+ }
+ else
+ {
+ vec4 lpos;
+
+ if (spos.z < -shadow_clip.z)
+ {
+ lpos = shadow_matrix[3]*spos;
+ lpos.xy *= shadow_res;
+ shadow = pcfShadow(shadowMap3, lpos, 0.25);
+ shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0);
+ }
+ else if (spos.z < -shadow_clip.y)
+ {
+ lpos = shadow_matrix[2]*spos;
+ lpos.xy *= shadow_res;
+ shadow = pcfShadow(shadowMap2, lpos, 0.5);
+ }
+ else if (spos.z < -shadow_clip.x)
+ {
+ lpos = shadow_matrix[1]*spos;
+ lpos.xy *= shadow_res;
+ shadow = pcfShadow(shadowMap1, lpos, 0.75);
+ }
+ else
+ {
+ lpos = shadow_matrix[0]*spos;
+ lpos.xy *= shadow_res;
+ shadow = pcfShadow(shadowMap0, lpos, 1.0);
+ }
+
+ // take the most-shadowed value out of these two:
+ // * the blurred sun shadow in the light (shadow) map
+ // * an unblurred dot product between the sun and this norm
+ // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting
+ shadow = min(shadow, dp_directional_light);
+
+ //lpos.xy /= lpos.w*32.0;
+ //if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1)
+ //{
+ // shadow = 0.0;
+ //}
+
+ }
+ }
+ else
+ {
+ // more distant than the shadow map covers
+ shadow = 1.0;
+ }
+
+ gl_FragColor[0] = shadow;
+ gl_FragColor[1] = calcAmbientOcclusion(pos, norm);
+
+ spos.xyz = shadow_pos+offset*spot_shadow_offset;
+
+ //spotlight shadow 1
+ vec4 lpos = shadow_matrix[4]*spos;
+ gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8);
+
+ //spotlight shadow 2
+ lpos = shadow_matrix[5]*spos;
+ gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8);
+
+ //gl_FragColor.rgb = pos.xyz;
+ //gl_FragColor.b = shadow;
+}
diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
index f4c59734a4..19800d96dc 100644
--- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl
@@ -6,7 +6,7 @@
*/
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -18,9 +18,10 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
// Collect normal lights (need to be divided by two, as we later multiply by 2)
col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
- col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- //col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
+
+ col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ //col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
col.rgb = scaleDownLight(col.rgb);
// Add windlight lights
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl
index 7325825d6d..66606233cd 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl
@@ -44,7 +44,8 @@ float getDepth(vec2 pos_screen)
void main()
{
- vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
float depth = getDepth(vary_fragcoord.xy);
vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;
@@ -56,9 +57,10 @@ void main()
for (int i = 0; i < kern_length; i++)
{
vec2 tc = vary_fragcoord.xy + kern[i].y*dlt;
- vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0;
-
- float d = dot(norm.xyz, sampNorm);
+ vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz;
+ sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm
+
+ float d = dot(norm.xyz, sampNorm);
if (d > 0.5)
{
diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl
index 939710cb56..1b8354dbd1 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl
@@ -178,7 +178,8 @@ void main()
float rad = gi_range*0.5;
- vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0;
+ vec3 norm = texture2DRect(normalMap, pos_screen).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
float dist = max(length(pos.xyz)-rad, 0.0);
float da = clamp(1.0-dist/rad, 0.0, 1.0);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
index 96a083b522..c88edd0a60 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl
@@ -56,9 +56,8 @@ vec3 vary_AdditiveColor;
vec3 vary_AtmosAttenuation;
uniform float gi_ambiance;
-vec4 getPosition(vec2 pos_screen)
-{ //get position in screen space (world units) given window coordinate and depth map
- float depth = texture2DRect(depthMap, pos_screen.xy).a;
+vec4 getPosition_d(vec2 pos_screen, float depth)
+{
vec2 sc = pos_screen.xy*2.0;
sc /= screen_res;
sc -= vec2(1.0,1.0);
@@ -69,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)
return pos;
}
+vec4 getPosition(vec2 pos_screen)
+{ //get position in screen space (world units) given window coordinate and depth map
+ float depth = texture2DRect(depthMap, pos_screen.xy).a;
+ return getPosition_d(pos_screen, depth);
+}
+
vec3 getPositionEye()
{
return vary_PositionEye;
@@ -252,8 +257,10 @@ vec3 scaleSoftClip(vec3 light)
void main()
{
vec2 tc = vary_fragcoord.xy;
- vec3 pos = getPosition(tc).xyz;
- vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0;
+ float depth = texture2DRect(depthMap, tc.xy).a;
+ vec3 pos = getPosition_d(tc, depth).xyz;
+ vec3 norm = texture2DRect(normalMap, tc).xyz;
+ norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm
//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;
float da = max(dot(norm.xyz, vary_light.xyz), 0.0);
@@ -274,11 +281,63 @@ void main()
col *= diffuse.rgb;
- if (spec.a > 0.0)
+ if (spec.a > 0.0) // specular reflection
{
- vec3 ref = normalize(reflect(pos.xyz, norm.xyz));
- float sa = dot(ref, vary_light.xyz);
- col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a;
+ // the old infinite-sky shiny reflection
+ //
+ vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz));
+ float sa = dot(refnormpersp, vary_light.xyz);
+ vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a;
+
+ /*
+ // screen-space cheap fakey reflection map
+ //
+ vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz));
+ depth -= 0.5; // unbias depth
+ // first figure out where we'll make our 2D guess from
+ vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth;
+ // Offset the guess source a little according to a trivial
+ // checkerboard dither function and spec.a.
+ // This is meant to be similar to sampling a blurred version
+ // of the diffuse map. LOD would be better in that regard.
+ // The goal of the blur is to soften reflections in surfaces
+ // with low shinyness, and also to disguise our lameness.
+ float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0
+ float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5);
+
+ ref2d += vec2(checkoffset, checkoffset);
+ ref2d += tc.xy; // use as offset from destination
+ // Get attributes from the 2D guess point.
+ // We average two samples of diffuse (not of anything else) per
+ // pixel to try to reduce aliasing some more.
+ vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb +
+ texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb);
+ float refdepth = texture2DRect(depthMap, ref2d).a;
+ vec3 refpos = getPosition_d(ref2d, refdepth).xyz;
+ float refshad = texture2DRect(lightMap, ref2d).r;
+ vec3 refn = texture2DRect(normalMap, ref2d).rgb;
+ refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm
+ refn = normalize(refn);
+ // figure out how appropriate our guess actually was
+ float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos)));
+ // darken reflections from points which face away from the reflected ray - our guess was a back-face
+ //refapprop *= step(dot(refnorm, refn), 0.0);
+ refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant
+ // get appropriate light strength for guess-point.
+ // reflect light direction to increase the illusion that
+ // these are reflections.
+ vec3 reflight = reflect(lightnorm.xyz, norm.xyz);
+ float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad);
+ // apply sun color to guess-point, dampen according to inappropriateness of guess
+ float refmod = min(refapprop, reflit);
+ vec3 refprod = vary_SunlitColor * refcol.rgb * refmod;
+ vec3 ssshiny = (refprod * spec.a);
+ ssshiny *= 0.3; // dampen it even more
+ */
+ vec3 ssshiny = vec3(0,0,0);
+
+ // add the two types of shiny together
+ col += (ssshiny + dumbshiny) * spec.rgb;
}
col = atmosLighting(col);
diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl
index 258acee08c..5b33ea5bfe 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl
@@ -14,5 +14,6 @@ void main()
vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy);
gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005);
gl_FragData[1] = vec4(0,0,0,0);
- gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0);
+ vec3 nvn = normalize(vary_normal);
+ gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);
}
diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
index 1c5234c450..f129a1517b 100644
--- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
+++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl
@@ -6,7 +6,7 @@
*/
float calcDirectionalLight(vec3 n, vec3 l);
-float calcPointLight(vec3 v, vec3 n, vec4 lp, float la);
+float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);
vec3 atmosAmbient(vec3 light);
vec3 atmosAffectDirectionalLight(float lightIntensity);
@@ -15,24 +15,21 @@ vec3 scaleUpLight(vec3 light);
vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)
{
- vec4 col;
- col.a = color.a;
+ vec4 col = vec4(0.0, 0.0, 0.0, color.a);
- // Add windlight lights
- col.rgb = atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz));
- col.rgb += atmosAmbient(baseLight.rgb);
- col.rgb = scaleUpLight(col.rgb);
-
// Collect normal lights (need to be divided by two, as we later multiply by 2)
- col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation);
- col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation);
- col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation);
- col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation);
- col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation);
- col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation);
+ col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a);
+ col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a);
+ col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);
+ col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a);
+ col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a);
+ col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);
col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);
col.rgb = scaleDownLight(col.rgb);
-
+
+ // Add windlight lights
+ col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz));
+ col.rgb += atmosAmbient(baseLight.rgb);
col.rgb = min(col.rgb*color.rgb, 1.0);
diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml
index f16ec6c30f..f741089ca2 100644
--- a/indra/newview/app_settings/ultra_graphics.xml
+++ b/indra/newview/app_settings/ultra_graphics.xml
@@ -12,14 +12,12 @@
<RenderFlexTimeFactor value="1"/>
<!--256... but they don't use this-->
<RenderGlowResolutionPow value="9"/>
- <!--Sun/Moon only-->
- <RenderLightingDetail value="1"/>
<!--Low number-->
<RenderMaxPartCount value="4096"/>
<!--bump okay-->
<RenderObjectBump value="TRUE"/>
<!--NO SHADERS-->
- <RenderReflectionDetail value="3"/>
+ <RenderReflectionDetail value="4"/>
<!--Simple-->
<RenderTerrainDetail value="1"/>
<!--Default for now-->
@@ -31,9 +29,14 @@
<!--Default for now-->
<RenderVolumeLODFactor value="2.0"/>
<!--NO SHADERS-->
- <RenderWaterReflections value="TRUE"/>
- <!--NO SHADERS-->
<VertexShaderEnable value="TRUE"/>
<!--NO SHADERS-->
<WindLightUseAtmosShaders value="TRUE"/>
+ <!--Deferred Shading-->
+ <RenderDeferred value="TRUE"/>
+ <!--SSAO Enabled-->
+ <RenderDeferredSSAO value="TRUE"/>
+ <!--Full Shadows-->
+ <RenderShadowDetail value="2"/>
+
</settings>
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index 5f31ccbb19..d2c13a43be 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -23,7 +23,7 @@ version 21
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
-RenderAnisotropic 1 0
+RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarVP 1 1
@@ -35,18 +35,16 @@ RenderFogRatio 1 4.0
RenderGamma 1 0
RenderGlowResolutionPow 1 9
RenderGround 1 1
-RenderLightingDetail 1 1
RenderMaxPartCount 1 8192
RenderNightBrightness 1 1.0
RenderObjectBump 1 1
-RenderReflectionDetail 1 3
+RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 1.0
RenderUseImpostors 1 1
RenderVBOEnable 1 1
RenderVolumeLODFactor 1 2.0
-RenderWaterReflections 1 1
UseStartScreen 1 1
UseOcclusion 1 1
VertexShaderEnable 1 1
@@ -56,6 +54,9 @@ Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
RenderShaderLightingMaxLevel 1 3
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
//
@@ -69,7 +70,6 @@ RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0.5
RenderGlowResolutionPow 1 8
-RenderLightingDetail 1 0
RenderMaxPartCount 1 1024
RenderObjectBump 1 0
RenderReflectionDetail 1 0
@@ -78,10 +78,13 @@ RenderTerrainLODFactor 1 1
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
//
// Mid Graphics Settings
@@ -94,7 +97,6 @@ RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
-RenderLightingDetail 1 1
RenderMaxPartCount 1 2048
RenderObjectBump 1 1
RenderReflectionDetail 1 0
@@ -103,10 +105,13 @@ RenderTerrainLODFactor 1 1.0
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
//
// High Graphics Settings (purty)
@@ -119,7 +124,6 @@ RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLightingDetail 1 1
RenderMaxPartCount 1 4096
RenderObjectBump 1 1
RenderReflectionDetail 1 2
@@ -128,10 +132,13 @@ RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
//
// Ultra graphics (REALLY PURTY!)
@@ -144,19 +151,21 @@ RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLightingDetail 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
-RenderReflectionDetail 1 3
+RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 1.0
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 2.0
-RenderWaterReflections 1 1
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
+
//
// Class Unknown Hardware (unknown)
@@ -194,9 +203,12 @@ RenderVBOEnable 1 1
list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
//
// No Vertex Shaders available
@@ -204,9 +216,13 @@ WindLightUseAtmosShaders 0 0
list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
// "Default" setups for safe, low, medium, high
//
@@ -214,14 +230,17 @@ list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
RenderAvatarVP 0 0
-RenderLightingDetail 1 0
RenderObjectBump 0 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
RenderUseImpostors 0 0
RenderVBOEnable 1 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
//
// CPU based feature masks
@@ -245,11 +264,9 @@ RenderVBOEnable 1 0
list Intel
RenderAnisotropic 1 0
-RenderLightingDetail 1 0
list GeForce2
RenderAnisotropic 1 0
-RenderLightingDetail 1 0
RenderMaxPartCount 1 2048
RenderTerrainDetail 1 0
RenderVBOEnable 1 1
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index 61a8e51c50..254b9c4ce4 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -23,7 +23,7 @@ version 21
// NOTE: All settings are set to the MIN of applied values, including 'all'!
//
list all
-RenderAnisotropic 1 0
+RenderAnisotropic 1 1
RenderAvatarCloth 1 1
RenderAvatarLODFactor 1 1.0
RenderAvatarVP 1 1
@@ -35,18 +35,16 @@ RenderFogRatio 1 4.0
RenderGamma 1 0
RenderGlowResolutionPow 1 9
RenderGround 1 1
-RenderLightingDetail 1 1
RenderMaxPartCount 1 8192
RenderNightBrightness 1 1.0
RenderObjectBump 1 1
-RenderReflectionDetail 1 3
+RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 1.0
RenderUseImpostors 1 1
RenderVBOEnable 1 1
RenderVolumeLODFactor 1 2.0
-RenderWaterReflections 1 1
UseStartScreen 1 1
UseOcclusion 1 1
VertexShaderEnable 1 1
@@ -55,6 +53,10 @@ WLSkyDetail 1 128
Disregard128DefaultDrawDistance 1 1
Disregard96DefaultDrawDistance 1 1
RenderTextureMemoryMultiple 1 1.0
+RenderShaderLightingMaxLevel 1 3
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
//
// Low Graphics Settings
@@ -67,7 +69,6 @@ RenderAvatarVP 1 0
RenderFarClip 1 64
RenderFlexTimeFactor 1 0.5
RenderGlowResolutionPow 1 8
-RenderLightingDetail 1 0
RenderMaxPartCount 1 1024
RenderObjectBump 1 0
RenderReflectionDetail 1 0
@@ -76,10 +77,13 @@ RenderTerrainLODFactor 1 1
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 0
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
//
// Mid Graphics Settings
@@ -92,7 +96,6 @@ RenderAvatarVP 1 1
RenderFarClip 1 96
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 8
-RenderLightingDetail 1 1
RenderMaxPartCount 1 2048
RenderObjectBump 1 1
RenderReflectionDetail 1 0
@@ -101,10 +104,13 @@ RenderTerrainLODFactor 1 1.0
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 0
WLSkyDetail 1 48
+RenderDeferred 1 0
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 0
+
//
// High Graphics Settings (purty)
@@ -117,7 +123,6 @@ RenderAvatarVP 1 1
RenderFarClip 1 128
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLightingDetail 1 1
RenderMaxPartCount 1 4096
RenderObjectBump 1 1
RenderReflectionDetail 1 2
@@ -126,10 +131,13 @@ RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 0.5
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 1.125
-RenderWaterReflections 1 0
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 48
+RenderDeferred 1 1
+RenderDeferredSSAO 1 0
+RenderShadowDetail 1 1
+
//
// Ultra graphics (REALLY PURTY!)
@@ -142,19 +150,21 @@ RenderAvatarVP 1 1
RenderFarClip 1 256
RenderFlexTimeFactor 1 1.0
RenderGlowResolutionPow 1 9
-RenderLightingDetail 1 1
RenderMaxPartCount 1 8192
RenderObjectBump 1 1
-RenderReflectionDetail 1 3
+RenderReflectionDetail 1 4
RenderTerrainDetail 1 1
RenderTerrainLODFactor 1 2.0
RenderTreeLODFactor 1 1.0
RenderUseImpostors 1 1
RenderVolumeLODFactor 1 2.0
-RenderWaterReflections 1 1
VertexShaderEnable 1 1
WindLightUseAtmosShaders 1 1
WLSkyDetail 1 128
+RenderDeferred 1 1
+RenderDeferredSSAO 1 1
+RenderShadowDetail 1 2
+
//
// Class Unknown Hardware (unknown)
@@ -192,9 +202,12 @@ RenderVBOEnable 1 1
list NoPixelShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
//
// No Vertex Shaders available
@@ -202,9 +215,13 @@ WindLightUseAtmosShaders 0 0
list NoVertexShaders
RenderAvatarVP 0 0
RenderAvatarCloth 0 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
VertexShaderEnable 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
// "Default" setups for safe, low, medium, high
//
@@ -212,14 +229,17 @@ list safe
RenderAnisotropic 1 0
RenderAvatarCloth 0 0
RenderAvatarVP 0 0
-RenderLightingDetail 1 0
RenderObjectBump 0 0
RenderMaxPartCount 1 1024
RenderTerrainDetail 1 0
RenderUseImpostors 0 0
RenderVBOEnable 1 0
-RenderWaterReflections 0 0
+RenderReflectionDetail 0 0
WindLightUseAtmosShaders 0 0
+RenderDeferred 0 0
+RenderDeferredSSAO 0 0
+RenderShadowDetail 0 0
+
//
// CPU based feature masks
@@ -243,13 +263,11 @@ RenderVBOEnable 1 0
list Intel
RenderAnisotropic 1 0
-RenderLightingDetail 1 0
// Avoid some Intel crashes on Linux
RenderCubeMap 0 0
list GeForce2
RenderAnisotropic 1 0
-RenderLightingDetail 1 0
RenderMaxPartCount 1 2048
RenderTerrainDetail 1 0
RenderVBOEnable 1 1
@@ -461,17 +479,47 @@ list NVIDIA_GeForce_Go_6
RenderVBOEnable 1 0
Disregard128DefaultDrawDistance 1 0
+list NVIDIA_GeForce_7000
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7100
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_7200
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_7300
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_7400
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7500
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7600
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7700
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7800
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_7900
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_Go_7200
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_Go_7300
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7300_LE
+RenderShaderLightingMaxLevel 1 2
list NVIDIA_GeForce_Go_7400
Disregard128DefaultDrawDistance 1 0
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7600
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7700
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7800
+RenderShaderLightingMaxLevel 1 2
+list NVIDIA_GeForce_Go_7900
+RenderShaderLightingMaxLevel 1 2
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index 12d47a904c..db0252d2e7 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -366,6 +366,7 @@ list ATI_Radeon_X1500
Disregard128DefaultDrawDistance 1 0
list ATI_Radeon_X1600
Disregard128DefaultDrawDistance 1 0
+RenderUseFBO 0 0
list ATI_Radeon_X1700
Disregard128DefaultDrawDistance 1 0
list ATI_Mobility_Radeon_X1xxx
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f7f7cb599e..fd78bc62c8 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -903,6 +903,11 @@ static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");
static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");
static LLFastTimer::DeclareTimer FTM_IDLE("Idle");
static LLFastTimer::DeclareTimer FTM_PUMP("Pump");
+static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares");
+static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service");
+static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback");
+static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot");
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");
bool LLAppViewer::mainLoop()
{
@@ -1012,10 +1017,20 @@ bool LLAppViewer::mainLoop()
LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);
pingMainloopTimeout("Main:ServicePump");
LLFastTimer t4(FTM_PUMP);
- gAres->process();
- // this pump is necessary to make the login screen show up
- gServicePump->pump();
- gServicePump->callback();
+ {
+ LLFastTimer t(FTM_PUMP_ARES);
+ gAres->process();
+ }
+ {
+ LLFastTimer t(FTM_PUMP_SERVICE);
+ // this pump is necessary to make the login screen show up
+ gServicePump->pump();
+
+ {
+ LLFastTimer t(FTM_SERVICE_CALLBACK);
+ gServicePump->callback();
+ }
+ }
}
resumeMainloopTimeout();
@@ -3474,9 +3489,12 @@ void LLAppViewer::idle()
gAgent.moveYaw(-1.f);
}
- // Handle automatic walking towards points
- gAgentPilot.updateTarget();
- gAgent.autoPilot(&yaw);
+ {
+ LLFastTimer t(FTM_AGENT_AUTOPILOT);
+ // Handle automatic walking towards points
+ gAgentPilot.updateTarget();
+ gAgent.autoPilot(&yaw);
+ }
static LLFrameTimer agent_update_timer;
static U32 last_control_flags;
@@ -3487,6 +3505,7 @@ void LLAppViewer::idle()
if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
{
+ LLFastTimer t(FTM_AGENT_UPDATE);
// Send avatar and camera info
last_control_flags = gAgent.getControlFlags();
send_agent_update(TRUE);
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 38eda5bd2e..ed6a791e7f 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -523,7 +523,7 @@ F32 LLDrawable::updateXform(BOOL undamped)
{
// snap to final position
dist_squared = 0.0f;
- if (!isRoot())
+ if (getVOVolume() && !isRoot())
{ //child prim snapping to some position, needs a rebuild
gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
}
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index e3e66fa00d..ae30af3647 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -474,6 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
if (params.mTexture.notNull())
{
+ params.mTexture->addTextureStats(params.mVSize);
gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;
if (params.mTextureMatrix)
{
diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h
index 67870c10e9..f85b46cfba 100644
--- a/indra/newview/lldrawpool.h
+++ b/indra/newview/lldrawpool.h
@@ -133,6 +133,7 @@ public:
PASS_FULLBRIGHT_SHINY,
PASS_SHINY,
PASS_BUMP,
+ PASS_POST_BUMP,
PASS_GLOW,
PASS_ALPHA,
PASS_ALPHA_MASK,
diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp
index 875c9ac6a9..def463cb41 100644
--- a/indra/newview/lldrawpoolalpha.cpp
+++ b/indra/newview/lldrawpoolalpha.cpp
@@ -60,7 +60,9 @@ static BOOL deferred_render = FALSE;
LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :
LLRenderPass(type), current_shader(NULL), target_shader(NULL),
- simple_shader(NULL), fullbright_shader(NULL)
+ simple_shader(NULL), fullbright_shader(NULL),
+ mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF),
+ mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)
{
}
@@ -178,9 +180,16 @@ void LLDrawPoolAlpha::render(S32 pass)
LLGLSPipelineAlpha gls_pipeline_alpha;
- if (LLPipeline::sFastAlpha && !deferred_render)
+ gGL.setColorMask(true, true);
+
+ if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render)
{
- LLGLDisable blend_disable(GL_BLEND);
+ mColorSFactor = LLRender::BF_ONE; // }
+ mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow
+ mAlphaSFactor = LLRender::BF_ZERO;
+ mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);
if (mVertexShaderLevel > 0)
{
@@ -204,8 +213,17 @@ void LLDrawPoolAlpha::render(S32 pass)
}
LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE);
+
+ mColorSFactor = LLRender::BF_SOURCE_ALPHA; // } regular alpha blend
+ mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+ mAlphaSFactor = LLRender::BF_ZERO; // } glow suppression
+ mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // }
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+
renderAlpha(getVertexDataMask());
+ gGL.setColorMask(true, false);
+
if (deferred_render && current_shader != NULL)
{
gPipeline.unbindDeferredShader(*current_shader);
@@ -283,9 +301,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
+ llassert(group);
+ llassert(group->mSpatialPartition);
+
if (group->mSpatialPartition->mRenderByGroup &&
- !group->isDead())
+ !group->isDead())
{
+ bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow.
+ // All particle systems seem to come off the wire with texture entries which claim that they glow. This is probably a bug in the data. Suppress.
+ group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE &&
+ group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD &&
+ group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE;
+
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
@@ -294,96 +321,118 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)
LLRenderPass::applyModelMatrix(params);
- if (params.mFullbright)
{
- // Turn off lighting if it hasn't already been so.
- if (light_enabled || !initialized_lighting)
+ if (params.mFullbright)
+ {
+ // Turn off lighting if it hasn't already been so.
+ if (light_enabled || !initialized_lighting)
+ {
+ initialized_lighting = TRUE;
+ if (use_shaders)
+ {
+ target_shader = fullbright_shader;
+ }
+ else
+ {
+ gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ }
+ light_enabled = FALSE;
+ }
+ }
+ // Turn on lighting if it isn't already.
+ else if (!light_enabled || !initialized_lighting)
{
initialized_lighting = TRUE;
if (use_shaders)
{
- target_shader = fullbright_shader;
+ target_shader = simple_shader;
}
else
{
- gPipeline.enableLightsFullbright(LLColor4(1,1,1,1));
+ gPipeline.enableLightsDynamic();
}
- light_enabled = FALSE;
+ light_enabled = TRUE;
}
- }
- // Turn on lighting if it isn't already.
- else if (!light_enabled || !initialized_lighting)
- {
- initialized_lighting = TRUE;
- if (use_shaders)
- {
- target_shader = simple_shader;
- }
- else
- {
- gPipeline.enableLightsDynamic();
- }
- light_enabled = TRUE;
- }
- // If we need shaders, and we're not ALREADY using the proper shader, then bind it
- // (this way we won't rebind shaders unnecessarily).
- if(use_shaders && (current_shader != target_shader))
- {
- llassert(target_shader != NULL);
- if (deferred_render && current_shader != NULL)
+ // If we need shaders, and we're not ALREADY using the proper shader, then bind it
+ // (this way we won't rebind shaders unnecessarily).
+ if(use_shaders && (current_shader != target_shader))
{
- gPipeline.unbindDeferredShader(*current_shader);
- diffuse_channel = 0;
- }
- current_shader = target_shader;
- if (deferred_render)
- {
- gPipeline.bindDeferredShader(*current_shader);
- diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
- }
- else
- {
- current_shader->bind();
+ llassert(target_shader != NULL);
+ if (deferred_render && current_shader != NULL)
+ {
+ gPipeline.unbindDeferredShader(*current_shader);
+ diffuse_channel = 0;
+ }
+ current_shader = target_shader;
+ if (deferred_render)
+ {
+ gPipeline.bindDeferredShader(*current_shader);
+ diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP);
+ }
+ else
+ {
+ current_shader->bind();
+ }
}
- }
- else if (!use_shaders && current_shader != NULL)
- {
- if (deferred_render)
+ else if (!use_shaders && current_shader != NULL)
{
- gPipeline.unbindDeferredShader(*current_shader);
- diffuse_channel = 0;
+ if (deferred_render)
+ {
+ gPipeline.unbindDeferredShader(*current_shader);
+ diffuse_channel = 0;
+ }
+ LLGLSLShader::bindNoShader();
+ current_shader = NULL;
}
- LLGLSLShader::bindNoShader();
- current_shader = NULL;
- }
-
- if (params.mGroup)
- {
- params.mGroup->rebuildMesh();
- }
-
- if (params.mTexture.notNull())
- {
- gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
- if(params.mTexture.notNull())
+ if (params.mGroup)
{
- params.mTexture->addTextureStats(params.mVSize);
+ params.mGroup->rebuildMesh();
}
- if (params.mTextureMatrix)
+
+
+ if (params.mTexture.notNull())
{
- gGL.getTexUnit(0)->activate();
- glMatrixMode(GL_TEXTURE);
- glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
- gPipeline.mTextureMatrixOps++;
+ gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get());
+ if(params.mTexture.notNull())
+ {
+ params.mTexture->addTextureStats(params.mVSize);
+ }
+ if (params.mTextureMatrix)
+ {
+ gGL.getTexUnit(0)->activate();
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
+ gPipeline.mTextureMatrixOps++;
+ }
}
}
params.mVertexBuffer->setBuffer(mask);
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.
+ if (draw_glow_for_this_partition &&
+ params.mGlowColor.mV[3] > 0)
+ {
+ // 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)
+ // glow doesn't use vertex colors from the mesh data
+ params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR);
+ glColor4ubv(params.mGlowColor.mV);
+
+ // do the actual drawing, again
+ params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
+ gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode);
+
+ // restore our alpha blend mode
+ gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor);
+ }
+
if (params.mTextureMatrix && params.mTexture.notNull())
{
gGL.getTexUnit(0)->activate();
diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h
index 3aa752f72c..61f73d0b31 100644
--- a/indra/newview/lldrawpoolalpha.h
+++ b/indra/newview/lldrawpoolalpha.h
@@ -34,6 +34,7 @@
#define LL_LLDRAWPOOLALPHA_H
#include "lldrawpool.h"
+#include "llrender.h"
#include "llframetimer.h"
class LLFace;
@@ -83,6 +84,12 @@ private:
LLGLSLShader* target_shader;
LLGLSLShader* simple_shader;
LLGLSLShader* fullbright_shader;
+
+ // our 'normal' alpha blend function for this pass
+ LLRender::eBlendFactor mColorSFactor;
+ LLRender::eBlendFactor mColorDFactor;
+ LLRender::eBlendFactor mAlphaSFactor;
+ LLRender::eBlendFactor mAlphaDFactor;
};
class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 546b60f286..c58fbbdcd0 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -123,7 +123,7 @@ void LLDrawPoolAvatar::prerender()
if (sShaderLevel > 0)
{
- sBufferUsage = GL_STATIC_DRAW_ARB;
+ sBufferUsage = GL_DYNAMIC_DRAW_ARB;
}
else
{
@@ -157,6 +157,8 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_CHARACTERS);
+ sSkipTransparent = TRUE;
+
if (LLPipeline::sImpostorRender)
{
beginDeferredSkinned();
@@ -181,6 +183,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)
{
LLFastTimer t(FTM_RENDER_CHARACTERS);
+ sSkipTransparent = FALSE;
+
if (LLPipeline::sImpostorRender)
{
endDeferredSkinned();
@@ -250,7 +254,6 @@ S32 LLDrawPoolAvatar::getNumShadowPasses()
void LLDrawPoolAvatar::beginShadowPass(S32 pass)
{
LLFastTimer t(FTM_SHADOW_AVATAR);
-
sVertexProgram = &gDeferredAvatarShadowProgram;
if (sShaderLevel > 0)
{
@@ -272,7 +275,6 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)
void LLDrawPoolAvatar::endShadowPass(S32 pass)
{
LLFastTimer t(FTM_SHADOW_AVATAR);
-
if (sShaderLevel > 0)
{
sRenderingSkinned = FALSE;
@@ -310,6 +312,11 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
return;
}
+ if (sShaderLevel > 0)
+ {
+ gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX];
+ }
+
avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);
}
@@ -346,7 +353,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)
switch (pass)
{
case 0:
- beginFootShadow();
+ beginImpostor();
break;
case 1:
beginRigid();
@@ -370,7 +377,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
switch (pass)
{
case 0:
- endFootShadow();
+ endImpostor();
break;
case 1:
endRigid();
@@ -380,7 +387,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)
}
}
-void LLDrawPoolAvatar::beginFootShadow()
+void LLDrawPoolAvatar::beginImpostor()
{
if (!LLPipeline::sReflectionRender)
{
@@ -392,7 +399,7 @@ void LLDrawPoolAvatar::beginFootShadow()
diffuse_channel = 0;
}
-void LLDrawPoolAvatar::endFootShadow()
+void LLDrawPoolAvatar::endImpostor()
{
gPipeline.enableLightsDynamic();
}
@@ -564,7 +571,6 @@ void LLDrawPoolAvatar::endSkinned()
void LLDrawPoolAvatar::beginDeferredSkinned()
{
- sSkipTransparent = TRUE;
sShaderLevel = mVertexShaderLevel;
sVertexProgram = &gDeferredAvatarProgram;
@@ -579,7 +585,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned()
void LLDrawPoolAvatar::endDeferredSkinned()
{
- sSkipTransparent = FALSE;
// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done
sRenderingSkinned = FALSE;
disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]);
@@ -691,10 +696,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
}
avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel);
}
- else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred)
- {
- avatarp->renderFootShadows();
- }
return;
}
@@ -848,9 +849,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const
LLVertexBufferAvatar::LLVertexBufferAvatar()
: LLVertexBuffer(sDataMask,
- LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 ?
- GL_DYNAMIC_DRAW_ARB :
- GL_STREAM_DRAW_ARB)
+ GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets
{
}
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index b947943619..d247260527 100644
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -88,11 +88,11 @@ public:
/*virtual*/ void renderShadow(S32 pass);
void beginRigid();
- void beginFootShadow();
+ void beginImpostor();
void beginSkinned();
void endRigid();
- void endFootShadow();
+ void endImpostor();
void endSkinned();
void beginDeferredImpostor();
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 19cdccb630..08c9f7fe15 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -618,9 +618,9 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)
}
//static
-void LLDrawPoolBump::beginBump()
+void LLDrawPoolBump::beginBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
+ if (!gPipeline.hasRenderBatches(pass))
{
return;
}
@@ -663,9 +663,9 @@ void LLDrawPoolBump::beginBump()
}
//static
-void LLDrawPoolBump::renderBump()
+void LLDrawPoolBump::renderBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
+ if (!gPipeline.hasRenderBatches(pass))
{
return;
}
@@ -678,13 +678,13 @@ void LLDrawPoolBump::renderBump()
/// Get rid of z-fighting with non-bump pass.
LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(-1.0f, -1.0f);
- renderBump(LLRenderPass::PASS_BUMP, sVertexMask);
+ renderBump(pass, sVertexMask);
}
//static
-void LLDrawPoolBump::endBump()
+void LLDrawPoolBump::endBump(U32 pass)
{
- if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
+ if (!gPipeline.hasRenderBatches(pass))
{
return;
}
@@ -701,6 +701,18 @@ void LLDrawPoolBump::endBump()
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
+S32 LLDrawPoolBump::getNumDeferredPasses()
+{
+ if (gSavedSettings.getBOOL("RenderObjectBump"))
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
void LLDrawPoolBump::beginDeferredPass(S32 pass)
{
if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP))
@@ -755,17 +767,41 @@ void LLDrawPoolBump::renderDeferred(S32 pass)
void LLDrawPoolBump::beginPostDeferredPass(S32 pass)
{
- beginFullbrightShiny();
+ switch (pass)
+ {
+ case 0:
+ beginFullbrightShiny();
+ break;
+ case 1:
+ beginBump(LLRenderPass::PASS_POST_BUMP);
+ break;
+ }
}
void LLDrawPoolBump::endPostDeferredPass(S32 pass)
{
- endFullbrightShiny();
+ switch (pass)
+ {
+ case 0:
+ endFullbrightShiny();
+ break;
+ case 1:
+ endBump(LLRenderPass::PASS_POST_BUMP);
+ break;
+ }
}
void LLDrawPoolBump::renderPostDeferred(S32 pass)
{
- renderFullbrightShiny();
+ switch (pass)
+ {
+ case 0:
+ renderFullbrightShiny();
+ break;
+ case 1:
+ renderBump(LLRenderPass::PASS_POST_BUMP);
+ break;
+ }
}
////////////////////////////////////////////////////////////////
@@ -851,6 +887,7 @@ void LLBumpImageList::updateImages()
}
}
}
+
for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )
{
bump_image_map_t::iterator curiter = iter++;
diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h
index bf940cf1e4..e35598448d 100644
--- a/indra/newview/lldrawpoolbump.h
+++ b/indra/newview/lldrawpoolbump.h
@@ -75,16 +75,16 @@ public:
void renderFullbrightShiny();
void endFullbrightShiny();
- void beginBump();
- void renderBump();
- void endBump();
+ void beginBump(U32 pass = LLRenderPass::PASS_BUMP);
+ void renderBump(U32 pass = LLRenderPass::PASS_BUMP);
+ void endBump(U32 pass = LLRenderPass::PASS_BUMP);
- virtual S32 getNumDeferredPasses() { return 1; }
+ virtual S32 getNumDeferredPasses();
/*virtual*/ void beginDeferredPass(S32 pass);
/*virtual*/ void endDeferredPass(S32 pass);
/*virtual*/ void renderDeferred(S32 pass);
- virtual S32 getNumPostDeferredPasses() { return 1; }
+ virtual S32 getNumPostDeferredPasses() { return 2; }
/*virtual*/ void beginPostDeferredPass(S32 pass);
/*virtual*/ void endPostDeferredPass(S32 pass);
/*virtual*/ void renderPostDeferred(S32 pass);
diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp
index ca7a1b47c2..91191287cd 100644
--- a/indra/newview/lldrawpoolsimple.cpp
+++ b/indra/newview/lldrawpoolsimple.cpp
@@ -55,6 +55,10 @@ void LLDrawPoolGlow::render(S32 pass)
LLFastTimer t(FTM_RENDER_GLOW);
LLGLEnable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
+ gGL.flush();
+ /// Get rid of z-fighting with non-glow pass.
+ LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);
+ glPolygonOffset(-1.0f, -1.0f);
gGL.setSceneBlendType(LLRender::BT_ADD);
U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT);
@@ -147,7 +151,8 @@ void LLDrawPoolSimple::render(S32 pass)
renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());
if (LLPipeline::sRenderDeferred)
- {
+ { //if deferred rendering is enabled, bump faces aren't reigstered as simple
+ //render bump faces here as simple so bump faces will appear under water
renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask());
}
}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index a1336815f7..f6932b0e68 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -862,11 +862,34 @@ void LLFace::updateRebuildFlags()
}
}
+
+bool LLFace::canRenderAsMask()
+{
+ const LLTextureEntry* te = getTextureEntry();
+ return (
+ (
+ (LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaDeferred) ||
+
+ (!LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaNonDeferred)
+ ) // do we want masks at all?
+ &&
+ (te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha
+ !(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid
+ (te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask
+
+ getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily recalculated but expensive)
+ );
+}
+
+
+static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom");
+
BOOL LLFace::getGeometryVolume(const LLVolume& volume,
const S32 &f,
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
const U16 &index_offset)
{
+ LLFastTimer t(FTM_FACE_GET_GEOM);
const LLVolumeFace &vf = volume.getVolumeFace(f);
S32 num_vertices = (S32)vf.mVertices.size();
S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size();
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 67dd97e6f7..02cc2af433 100644
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -138,10 +138,10 @@ public:
void unsetFaceColor(); // switch back to material color
const LLColor4& getFaceColor() const { return mFaceColor; }
const LLColor4& getRenderColor() const;
-
//for volumes
void updateRebuildFlags();
+ bool canRenderAsMask(); // logic helper
BOOL getGeometryVolume(const LLVolume& volume,
const S32 &f,
const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 0eeef0039c..f29f7160e8 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -799,7 +799,7 @@ void LLFloaterPreference::buildPopupLists()
void LLFloaterPreference::refreshEnabledState()
{
- LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections");
+ LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
LLRadioGroup* radio_reflection_detail = getChild<LLRadioGroup>("ReflectionDetailRadio");
// Reflections
@@ -812,7 +812,7 @@ void LLFloaterPreference::refreshEnabledState()
bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");
getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE);
- radio_reflection_detail->setEnabled(ctrl_reflections->get() && reflections);
+ radio_reflection_detail->setEnabled(reflections);
// Avatar Mode
// Enable Avatar Shaders
@@ -858,6 +858,30 @@ void LLFloaterPreference::refreshEnabledState()
// *HACK just checks to see if we can use shaders...
// maybe some cards that use shaders, but don't support windlight
ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders);
+
+ //Deferred/SSAO/Shadows
+ LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseFBO") &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ shaders)
+ {
+ BOOL enabled = (ctrl_wind_light->get()) ? TRUE : FALSE;
+
+ ctrl_deferred->setEnabled(enabled);
+
+ LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
+ LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail");
+
+ enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE);
+
+ ctrl_ssao->setEnabled(enabled);
+
+ enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail");
+
+ ctrl_shadow->setEnabled(enabled);
+ }
+
+
// now turn off any features that are unavailable
disableUnavailableSettings();
@@ -866,12 +890,15 @@ void LLFloaterPreference::refreshEnabledState()
void LLFloaterPreference::disableUnavailableSettings()
{
- LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections");
+ LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");
LLCheckBoxCtrl* ctrl_avatar_vp = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");
LLCheckBoxCtrl* ctrl_avatar_cloth = getChild<LLCheckBoxCtrl>("AvatarCloth");
LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");
LLCheckBoxCtrl* ctrl_wind_light = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");
LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors");
+ LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders");
+ LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail");
+ LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");
// if vertex shaders off, disable all shader related products
if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable"))
@@ -883,13 +910,22 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_wind_light->setValue(FALSE);
ctrl_reflections->setEnabled(FALSE);
- ctrl_reflections->setValue(FALSE);
+ ctrl_reflections->setValue(0);
ctrl_avatar_vp->setEnabled(FALSE);
ctrl_avatar_vp->setValue(FALSE);
ctrl_avatar_cloth->setEnabled(FALSE);
ctrl_avatar_cloth->setValue(FALSE);
+
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+
+ ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setValue(FALSE);
+
+ ctrl_deferred->setEnabled(FALSE);
+ ctrl_deferred->setValue(FALSE);
}
// disabled windlight
@@ -897,10 +933,47 @@ void LLFloaterPreference::disableUnavailableSettings()
{
ctrl_wind_light->setEnabled(FALSE);
ctrl_wind_light->setValue(FALSE);
+
+ //deferred needs windlight, disable deferred
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+
+ ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setValue(FALSE);
+
+ ctrl_deferred->setEnabled(FALSE);
+ ctrl_deferred->setValue(FALSE);
+ }
+
+ // disabled deferred
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred"))
+ {
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+
+ ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setValue(FALSE);
+
+ ctrl_deferred->setEnabled(FALSE);
+ ctrl_deferred->setValue(FALSE);
+ }
+
+ // disabled deferred SSAO
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO"))
+ {
+ ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setValue(FALSE);
}
+ // disabled deferred shadows
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"))
+ {
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+ }
+
// disabled reflections
- if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections"))
+ if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))
{
ctrl_reflections->setEnabled(FALSE);
ctrl_reflections->setValue(FALSE);
@@ -914,13 +987,25 @@ void LLFloaterPreference::disableUnavailableSettings()
ctrl_avatar_cloth->setEnabled(FALSE);
ctrl_avatar_cloth->setValue(FALSE);
+
+ //deferred needs AvatarVP, disable deferred
+ ctrl_shadows->setEnabled(FALSE);
+ ctrl_shadows->setValue(0);
+
+ ctrl_ssao->setEnabled(FALSE);
+ ctrl_ssao->setValue(FALSE);
+
+ ctrl_deferred->setEnabled(FALSE);
+ ctrl_deferred->setValue(FALSE);
}
+
// disabled cloth
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))
{
ctrl_avatar_cloth->setEnabled(FALSE);
ctrl_avatar_cloth->setValue(FALSE);
}
+
// disabled impostors
if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))
{
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index fbe68b4d92..8b01637239 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -574,7 +574,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
LLUUID id = LightTextureCtrl->getImageAssetID();
if (id.notNull())
{
- if (volobjp->getLightTextureID().isNull())
+ if (!volobjp->isLightSpotlight())
{ //this commit is making this a spot light, set UI to default params
volobjp->setLightTextureID(id);
LLVector3 spot_params = volobjp->getSpotLightParams();
@@ -591,7 +591,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )
volobjp->setSpotLightParams(spot_params);
}
}
- else if (volobjp->getLightTextureID().notNull())
+ else if (volobjp->isLightSpotlight())
{ //no longer a spot light
volobjp->setLightTextureID(id);
//self->childDisable("Light FOV");
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index d6e9256fee..c229657ded 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -1513,6 +1513,7 @@ void LLSpatialGroup::checkOcclusion()
{
if (LLPipeline::sUseOcclusion > 1)
{
+ LLFastTimer t(FTM_OCCLUSION_READBACK);
LLSpatialGroup* parent = getParent();
if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED))
{ //if the parent has been marked as occluded, the child is implicitly occluded
@@ -1520,7 +1521,6 @@ void LLSpatialGroup::checkOcclusion()
}
else if (isOcclusionState(QUERY_PENDING))
{ //otherwise, if a query is pending, read it back
- LLFastTimer t(FTM_OCCLUSION_READBACK);
GLuint res = 1;
if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])
{
@@ -1924,11 +1924,8 @@ public:
return;
}
- if (mRes == 2)
- {
- //fully in, don't traverse further (won't effect extents
- }
- else if (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK))
+ if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) ||
+ mRes == 2)
{ //don't need to do frustum check
LLSpatialGroup::OctreeTraveler::traverse(n);
}
@@ -3423,11 +3420,23 @@ LLCullResult::LLCullResult()
void LLCullResult::clear()
{
mVisibleGroupsSize = 0;
+ mVisibleGroupsEnd = mVisibleGroups.begin();
+
mAlphaGroupsSize = 0;
+ mAlphaGroupsEnd = mAlphaGroups.begin();
+
mOcclusionGroupsSize = 0;
+ mOcclusionGroupsEnd = mOcclusionGroups.begin();
+
mDrawableGroupsSize = 0;
+ mDrawableGroupsEnd = mDrawableGroups.begin();
+
mVisibleListSize = 0;
+ mVisibleListEnd = mVisibleList.begin();
+
mVisibleBridgeSize = 0;
+ mVisibleBridgeEnd = mVisibleBridge.begin();
+
for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)
{
@@ -3436,6 +3445,7 @@ void LLCullResult::clear()
mRenderMap[i][j] = 0;
}
mRenderMapSize[i] = 0;
+ mRenderMapEnd[i] = mRenderMap[i].begin();
}
}
@@ -3446,7 +3456,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups()
LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups()
{
- return mVisibleGroups.begin() + mVisibleGroupsSize;
+ return mVisibleGroupsEnd;
}
LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()
@@ -3456,7 +3466,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()
LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups()
{
- return mAlphaGroups.begin() + mAlphaGroupsSize;
+ return mAlphaGroupsEnd;
}
LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()
@@ -3466,7 +3476,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()
LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups()
{
- return mOcclusionGroups.begin() + mOcclusionGroupsSize;
+ return mOcclusionGroupsEnd;
}
LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()
@@ -3476,7 +3486,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()
LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups()
{
- return mDrawableGroups.begin() + mDrawableGroupsSize;
+ return mDrawableGroupsEnd;
}
LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()
@@ -3486,7 +3496,7 @@ LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()
LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList()
{
- return mVisibleList.begin() + mVisibleListSize;
+ return mVisibleListEnd;
}
LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()
@@ -3496,7 +3506,7 @@ LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()
LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge()
{
- return mVisibleBridge.begin() + mVisibleBridgeSize;
+ return mVisibleBridgeEnd;
}
LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)
@@ -3506,7 +3516,7 @@ LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)
LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type)
{
- return mRenderMap[type].begin() + mRenderMapSize[type];
+ return mRenderMapEnd[type];
}
void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
@@ -3520,6 +3530,7 @@ void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)
mVisibleGroups.push_back(group);
}
++mVisibleGroupsSize;
+ mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize;
}
void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
@@ -3533,6 +3544,7 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
mAlphaGroups.push_back(group);
}
++mAlphaGroupsSize;
+ mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize;
}
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
@@ -3546,6 +3558,7 @@ void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
mOcclusionGroups.push_back(group);
}
++mOcclusionGroupsSize;
+ mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize;
}
void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
@@ -3559,6 +3572,7 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)
mDrawableGroups.push_back(group);
}
++mDrawableGroupsSize;
+ mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize;
}
void LLCullResult::pushDrawable(LLDrawable* drawable)
@@ -3572,6 +3586,7 @@ void LLCullResult::pushDrawable(LLDrawable* drawable)
mVisibleList.push_back(drawable);
}
++mVisibleListSize;
+ mVisibleListEnd = mVisibleList.begin()+mVisibleListSize;
}
void LLCullResult::pushBridge(LLSpatialBridge* bridge)
@@ -3585,6 +3600,7 @@ void LLCullResult::pushBridge(LLSpatialBridge* bridge)
mVisibleBridge.push_back(bridge);
}
++mVisibleBridgeSize;
+ mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize;
}
void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
@@ -3598,6 +3614,7 @@ void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)
mRenderMap[type].push_back(draw_info);
}
++mRenderMapSize[type];
+ mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type];
}
diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h
index 7896488379..19af6a0c38 100644
--- a/indra/newview/llspatialpartition.h
+++ b/indra/newview/llspatialpartition.h
@@ -346,11 +346,11 @@ public:
F32 mBuilt;
OctreeNode* mOctreeNode;
LLSpatialPartition* mSpatialPartition;
- LLVector3 mBounds[2];
- LLVector3 mExtents[2];
+ LLVector3 mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects)
+ LLVector3 mExtents[2]; // extents (min, max) of this node and all its children
- LLVector3 mObjectExtents[2];
- LLVector3 mObjectBounds[2];
+ LLVector3 mObjectExtents[2]; // extents (min, max) of objects in this node
+ LLVector3 mObjectBounds[2]; // bounding box (center, size) of objects in this node
LLPointer<LLVertexBuffer> mVertexBuffer;
F32* mOcclusionVerts;
@@ -534,12 +534,19 @@ private:
U32 mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];
sg_list_t mVisibleGroups;
+ sg_list_t::iterator mVisibleGroupsEnd;
sg_list_t mAlphaGroups;
+ sg_list_t::iterator mAlphaGroupsEnd;
sg_list_t mOcclusionGroups;
+ sg_list_t::iterator mOcclusionGroupsEnd;
sg_list_t mDrawableGroups;
+ sg_list_t::iterator mDrawableGroupsEnd;
drawable_list_t mVisibleList;
+ drawable_list_t::iterator mVisibleListEnd;
bridge_list_t mVisibleBridge;
+ bridge_list_t::iterator mVisibleBridgeEnd;
drawinfo_list_t mRenderMap[LLRenderPass::NUM_RENDER_TYPES];
+ drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];
};
@@ -606,14 +613,13 @@ public:
//class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)
class LLVolumeGeometryManager: public LLGeometryManager
{
-public:
+ public:
virtual ~LLVolumeGeometryManager() { }
virtual void rebuildGeom(LLSpatialGroup* group);
virtual void rebuildMesh(LLSpatialGroup* group);
virtual void getGeometry(LLSpatialGroup* group);
void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE);
void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type);
-
};
//spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp)
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 514f72c334..ef3f09f251 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -299,15 +299,6 @@ static bool handleWLSkyDetailChanged(const LLSD&)
return true;
}
-static bool handleRenderLightingDetailChanged(const LLSD& newvalue)
-{
- if (gPipeline.isInit())
- {
- gPipeline.setLightingDetail(newvalue.asInteger());
- }
- return true;
-}
-
static bool handleResetVertexBuffersChanged(const LLSD&)
{
if (gPipeline.isInit())
@@ -514,6 +505,10 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
+ gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));
gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
@@ -534,7 +529,8 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));
gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));
gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
- gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
+ gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2));
@@ -544,7 +540,8 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));
gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));
gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
- gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
+ gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));
gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));
gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2));
@@ -569,8 +566,8 @@ void settings_setup_listeners()
gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));
gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2));
+ gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));
gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2));
- gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _2));
gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));
gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index f0800e82e7..570dd1a105 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -595,7 +595,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLPipeline::sUseOcclusion = 3;
}
- LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha");
+ LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred");
+ LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");
LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");
LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");
LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate");
@@ -868,12 +869,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
}
}
- /// We copy the frame buffer straight into a texture here,
- /// and then display it again with compositor effects.
- /// Using render to texture would be faster/better, but I don't have a
- /// grasp of their full display stack just yet.
- // gPostProcess->apply(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
-
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
gPipeline.renderDeferredLighting();
@@ -935,9 +930,10 @@ void render_hud_attachments()
bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");
//only render hud objects
- U32 mask = gPipeline.getRenderTypeMask();
+ gPipeline.pushRenderTypeMask();
+
// turn off everything
- gPipeline.setRenderTypeMask(0);
+ gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);
// turn on HUD
gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
// turn on HUD particles
@@ -991,7 +987,8 @@ void render_hud_attachments()
render_hud_elements();
//restore type mask
- gPipeline.setRenderTypeMask(mask);
+ gPipeline.popRenderTypeMask();
+
if (has_ui)
{
gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI);
@@ -1116,7 +1113,7 @@ void render_ui(F32 zoom_factor, int subfield)
{
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
}
-
+
render_hud_elements();
render_hud_attachments();
}
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index 95f05b5f5f..8f2006b431 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -440,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix
}
}
-void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
+void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLViewerJoint* joint = (LLViewerJoint*)(*iter);
- joint->updateFaceData(face, pixel_area, damp_wind);
+ joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
}
}
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 0d3092a044..67bd7786c3 100644
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -126,7 +126,7 @@ public:
PickName getPickName() { return mPickName; }
virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
- virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
+ virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
virtual void updateJointGeometry();
virtual void dump();
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 7225aa1523..6be7c442ef 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -667,7 +667,9 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32
//-----------------------------------------------------------------------------
// updateFaceData()
//-----------------------------------------------------------------------------
-void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind)
+static LLFastTimer::DeclareTimer FTM_AVATAR_FACE("Avatar Face");
+
+void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
{
mFace = face;
@@ -676,6 +678,8 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
return;
}
+ LLFastTimer t(FTM_AVATAR_FACE);
+
LLStrider<LLVector3> verticesp;
LLStrider<LLVector3> normalsp;
LLStrider<LLVector2> tex_coordsp;
@@ -694,29 +698,98 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w
face->mVertexBuffer->getIndexStrider(indicesp);
stop_glerror();
- for (U16 i = 0; i < mMesh->getNumVertices(); i++)
+ verticesp += mMesh->mFaceVertexOffset;
+ tex_coordsp += mMesh->mFaceVertexOffset;
+ normalsp += mMesh->mFaceVertexOffset;
+ vertex_weightsp += mMesh->mFaceVertexOffset;
+ clothing_weightsp += mMesh->mFaceVertexOffset;
+
+ const U32* __restrict coords = (U32*) mMesh->getCoords();
+ const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords();
+ const U32* __restrict normals = (U32*) mMesh->getNormals();
+ const U32* __restrict weights = (U32*) mMesh->getWeights();
+ const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights();
+
+ const U32 num_verts = mMesh->getNumVertices();
+
+ U32 i = 0;
+
+ const U32 skip = verticesp.getSkip()/sizeof(U32);
+
+ U32* __restrict v = (U32*) verticesp.get();
+ U32* __restrict n = (U32*) normalsp.get();
+
+ if (terse_update)
{
- verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i);
- tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i);
- normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i);
- vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i);
- if (damp_wind)
+ for (S32 i = num_verts; i > 0; --i)
{
- clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0);
+ //morph target application only, only update positions and normals
+ v[0] = coords[0];
+ v[1] = coords[1];
+ v[2] = coords[2];
+ coords += 3;
+ v += skip;
}
- else
+
+ for (S32 i = num_verts; i > 0; --i)
{
- clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i));
+ n[0] = normals[0];
+ n[1] = normals[1];
+ n[2] = normals[2];
+ normals += 3;
+ n += skip;
}
}
+ else
+ {
- for (S32 i = 0; i < mMesh->getNumFaces(); i++)
- {
- for (U32 j = 0; j < 3; j++)
+ U32* __restrict tc = (U32*) tex_coordsp.get();
+ U32* __restrict vw = (U32*) vertex_weightsp.get();
+ U32* __restrict cw = (U32*) clothing_weightsp.get();
+
+ do
+ {
+ v[0] = *(coords++);
+ v[1] = *(coords++);
+ v[2] = *(coords++);
+ v += skip;
+
+ tc[0] = *(tex_coords++);
+ tc[1] = *(tex_coords++);
+ tc += skip;
+
+ n[0] = *(normals++);
+ n[1] = *(normals++);
+ n[2] = *(normals++);
+ n += skip;
+
+ vw[0] = *(weights++);
+ vw += skip;
+
+ cw[0] = *(cloth_weights++);
+ cw[1] = *(cloth_weights++);
+ cw[2] = *(cloth_weights++);
+ cw[3] = *(cloth_weights++);
+ cw += skip;
+ }
+ while (++i < num_verts);
+
+ const U32 idx_count = mMesh->getNumFaces()*3;
+
+ indicesp += mMesh->mFaceIndexOffset;
+
+ U16* __restrict idx = indicesp.get();
+ S32* __restrict src_idx = (S32*) mMesh->getFaces();
+
+ i = 0;
+
+ const S32 offset = (S32) mMesh->mFaceVertexOffset;
+
+ do
{
- U32 k = i*3+j+mMesh->mFaceIndexOffset;
- indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset;
+ *(idx++) = *(src_idx++)+offset;
}
+ while (++i < idx_count);
}
}
}
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index d62b0ada85..3b8d9c82b8 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -140,7 +140,7 @@ public:
/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
- /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE);
+ /*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
/*virtual*/ void updateJointGeometry();
/*virtual*/ void dump();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index fb178f0868..4f51f15684 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3607,6 +3607,7 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f; // ~= 2.5 degrees -- if its less th
const F32 MAX_HEAD_ROT_QDOT = 0.99999f; // ~= 0.5 degrees -- if its greater than this then no need to update head_rot
// between these values we delay the updates (but no more than one second)
+static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");
void send_agent_update(BOOL force_send, BOOL send_reliable)
{
@@ -3765,6 +3766,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
if (duplicate_count < DUP_MSGS && !gDisconnected)
{
+ LLFastTimer t(FTM_AGENT_UPDATE_SEND);
// Build the message
msg->newMessageFast(_PREHASH_AgentUpdate);
msg->nextBlockFast(_PREHASH_AgentData);
diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp
index 86b1a8c910..0e29851778 100644
--- a/indra/newview/llviewershadermgr.cpp
+++ b/indra/newview/llviewershadermgr.cpp
@@ -317,10 +317,16 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)
void LLViewerShaderMgr::setShaders()
{
- if (!gPipeline.mInitialized || !sInitialized)
+ //setShaders might be called redundantly by gSavedSettings, so return on reentrance
+ static bool reentrance = false;
+
+ if (!gPipeline.mInitialized || !sInitialized || reentrance)
{
return;
}
+
+ reentrance = true;
+
// Make sure the compiled shader map is cleared before we recompile shaders.
mShaderObjects.clear();
@@ -368,17 +374,11 @@ void LLViewerShaderMgr::setShaders()
S32 wl_class = 2;
S32 water_class = 2;
S32 deferred_class = 0;
- if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
- && gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
- {
- // user has disabled WindLight in their settings, downgrade
- // windlight shaders to stub versions.
- wl_class = 1;
- }
-
- if (LLPipeline::sRenderDeferred)
+
+ if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ gSavedSettings.getBOOL("RenderDeferred"))
{
- if (gSavedSettings.getBOOL("RenderDeferredShadow"))
+ if (gSavedSettings.getS32("RenderShadowDetail") > 0)
{
if (gSavedSettings.getBOOL("RenderDeferredGI"))
{ //shadows + gi
@@ -393,6 +393,24 @@ void LLViewerShaderMgr::setShaders()
{ //no shadows
deferred_class = 1;
}
+
+ //make sure framebuffer objects are enabled
+ gSavedSettings.setBOOL("RenderUseFBO", TRUE);
+
+ //make sure hardware skinning is enabled
+ gSavedSettings.setBOOL("RenderAvatarVP", TRUE);
+
+ //make sure atmospheric shaders are enabled
+ gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE);
+ }
+
+
+ if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders")
+ && gSavedSettings.getBOOL("WindLightUseAtmosShaders")))
+ {
+ // user has disabled WindLight in their settings, downgrade
+ // windlight shaders to stub versions.
+ wl_class = 1;
}
if(!gSavedSettings.getBOOL("EnableRippleWater"))
@@ -517,6 +535,8 @@ void LLViewerShaderMgr::setShaders()
gViewerWindow->setCursor(UI_CURSOR_ARROW);
}
gPipeline.createGLBuffers();
+
+ reentrance = false;
}
void LLViewerShaderMgr::unloadShaders()
@@ -973,10 +993,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()
if (success)
{
+ std::string fragment;
+
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ {
+ fragment = "deferred/sunLightSSAOF.glsl";
+ }
+ else
+ {
+ fragment = "deferred/sunLightF.glsl";
+ }
+
gDeferredSunProgram.mName = "Deferred Sun Shader";
gDeferredSunProgram.mShaderFiles.clear();
gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB));
- gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightF.glsl", GL_FRAGMENT_SHADER_ARB));
+ gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));
gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];
success = gDeferredSunProgram.createShader(NULL, NULL);
}
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index bdc34d0f18..6ada122662 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -592,7 +592,7 @@ void update_statistics(U32 frame_count)
}
}
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
- LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail"));
+ LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
#if 0 // 1.9.2
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 56d22a0608..3ee912e00f 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1372,7 +1372,7 @@ LLViewerWindow::LLViewerWindow(
gSavedSettings.getBOOL("DisableVerticalSync"),
!gNoRender,
ignore_pixel_depth,
- gSavedSettings.getU32("RenderFSAASamples"));
+ 0); //gSavedSettings.getU32("RenderFSAASamples"));
if (!LLAppViewer::instance()->restoreErrorTrap())
{
@@ -3829,140 +3829,6 @@ void LLViewerWindow::playSnapshotAnimAndSound()
BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)
{
return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type);
-
- // *TODO below code was broken in deferred pipeline
- /*
- if ((!raw) || preview_width < 10 || preview_height < 10)
- {
- return FALSE;
- }
-
- if(gResizeScreenTexture) //the window is resizing
- {
- return FALSE ;
- }
-
- setCursor(UI_CURSOR_WAIT);
-
- // Hide all the UI widgets first and draw a frame
- BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI);
-
- if ( prev_draw_ui != show_ui)
- {
- LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments;
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = FALSE;
- }
-
- S32 render_name = gSavedSettings.getS32("RenderName");
- gSavedSettings.setS32("RenderName", 0);
- LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame
-
- S32 w = preview_width ;
- S32 h = preview_height ;
- LLVector2 display_scale = mDisplayScale ;
- mDisplayScale.setVec((F32)w / mWindowRectRaw.getWidth(), (F32)h / mWindowRectRaw.getHeight()) ;
- LLRect window_rect = mWindowRectRaw;
- mWindowRectRaw.set(0, h, w, 0);
-
- gDisplaySwapBuffers = FALSE;
- gDepthDirty = TRUE;
- glClearColor(0.f, 0.f, 0.f, 0.f);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
- setup3DRender();
-
- LLFontGL::setFontDisplay(FALSE) ;
- LLHUDText::setDisplayText(FALSE) ;
- if (type == SNAPSHOT_TYPE_OBJECT_ID)
- {
- gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE);
- }
- else
- {
- display(do_rebuild, 1.0f, 0, TRUE);
- render_ui();
- }
-
- S32 glformat, gltype, glpixel_length ;
- if(SNAPSHOT_TYPE_DEPTH == type)
- {
- glpixel_length = 4 ;
- glformat = GL_DEPTH_COMPONENT ;
- gltype = GL_FLOAT ;
- }
- else
- {
- glpixel_length = 3 ;
- glformat = GL_RGB ;
- gltype = GL_UNSIGNED_BYTE ;
- }
-
- raw->resize(w, h, glpixel_length);
- glReadPixels(0, 0, w, h, glformat, gltype, raw->getData());
-
- if(SNAPSHOT_TYPE_DEPTH == type)
- {
- LLViewerCamera* camerap = LLViewerCamera::getInstance();
- F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
- F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear());
-
- //calculate the depth
- for (S32 y = 0 ; y < h ; y++)
- {
- for(S32 x = 0 ; x < w ; x++)
- {
- S32 i = (w * y + x) << 2 ;
-
- F32 depth_float_i = *(F32*)(raw->getData() + i);
-
- F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2));
- U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar());
- *(raw->getData() + i + 0) = depth_byte;
- *(raw->getData() + i + 1) = depth_byte;
- *(raw->getData() + i + 2) = depth_byte;
- *(raw->getData() + i + 3) = 255;
- }
- }
- }
-
- LLFontGL::setFontDisplay(TRUE) ;
- LLHUDText::setDisplayText(TRUE) ;
- mDisplayScale.setVec(display_scale) ;
- mWindowRectRaw = window_rect;
- setup3DRender();
- gDisplaySwapBuffers = FALSE;
- gDepthDirty = TRUE;
-
- // POST SNAPSHOT
- if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI);
- }
-
- if (hide_hud)
- {
- LLPipeline::sShowHUDAttachments = TRUE;
- }
-
- setCursor(UI_CURSOR_ARROW);
-
- if (do_rebuild)
- {
- // If we had to do a rebuild, that means that the lists of drawables to be rendered
- // was empty before we started.
- // Need to reset these, otherwise we call state sort on it again when render gets called the next time
- // and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of
- // objects on them.
- gPipeline.resetDrawOrders();
- }
-
- gSavedSettings.setS32("RenderName", render_name);
-
- return TRUE;*/
}
// Saves the image from the screen to the specified filename and path.
@@ -4722,8 +4588,9 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
return TRUE;
}
- U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
- U32 old_fsaa = mWindow->getFSAASamples();
+ //U32 fsaa = gSavedSettings.getU32("RenderFSAASamples");
+ //U32 old_fsaa = mWindow->getFSAASamples();
+
// going from windowed to windowed
if (!old_fullscreen && !fullscreen)
{
@@ -4733,7 +4600,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
mWindow->setSize(size);
}
- if (fsaa == old_fsaa)
+ //if (fsaa == old_fsaa)
{
return TRUE;
}
@@ -4762,13 +4629,13 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
gSavedSettings.setS32("WindowY", old_pos.mY);
}
- mWindow->setFSAASamples(fsaa);
+ //mWindow->setFSAASamples(fsaa);
result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync);
if (!result_first_try)
{
// try to switch back
- mWindow->setFSAASamples(old_fsaa);
+ //mWindow->setFSAASamples(old_fsaa);
result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync);
if (!result_second_try)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 2ec8ced543..a6cb22a111 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -692,10 +692,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
}
- mDirtyMesh = TRUE; // Dirty geometry, need to regenerate.
+ mDirtyMesh = 2; // Dirty geometry, need to regenerate.
mMeshTexturesDirty = FALSE;
- mShadow0Facep = NULL;
- mShadow1Facep = NULL;
mHeadp = NULL;
mIsBuilt = FALSE;
@@ -731,12 +729,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mRippleTimeLast = 0.f;
- mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c");
-
- // GL NOT ACTIVE HERE
- //gGL.getTexUnit(0)->bind(mShadowImagep.get());
- //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
-
mInAir = FALSE;
mStepOnLand = TRUE;
@@ -1922,7 +1914,7 @@ void LLVOAvatar::updateMeshData()
}
if(num_vertices < 1)//skip empty meshes
{
- break ;
+ continue ;
}
if(last_v_num > 0)//put the last inserted part into next vertex buffer.
{
@@ -1944,6 +1936,8 @@ void LLVOAvatar::updateMeshData()
// resize immediately
facep->setSize(num_vertices, num_indices);
+ bool terse_update = false;
+
if(facep->mVertexBuffer.isNull())
{
facep->mVertexBuffer = new LLVertexBufferAvatar();
@@ -1951,7 +1945,15 @@ void LLVOAvatar::updateMeshData()
}
else
{
- facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
+ if (facep->mVertexBuffer->getRequestedIndices() == num_indices &&
+ facep->mVertexBuffer->getRequestedVerts() == num_vertices)
+ {
+ terse_update = true;
+ }
+ else
+ {
+ facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ;
+ }
}
facep->setGeomIndex(0);
@@ -1966,7 +1968,7 @@ void LLVOAvatar::updateMeshData()
for(S32 k = j ; k < part_index ; k++)
{
- mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR);
+ mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);
}
stop_glerror();
@@ -2319,12 +2321,6 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
LLJoint::sNumUpdates = 0;
LLJoint::sNumTouches = 0;
- // *NOTE: this is necessary for the floating name text above your head.
- if (mDrawable.notNull())
- {
- gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE);
- }
-
BOOL visible = isVisible() || mNeedsAnimUpdate;
// update attachments positions
@@ -3652,12 +3648,19 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
return num_indices;
}
- if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ LLFace* face = mDrawable->getFace(0);
+
+ bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY);
+
+ if (needs_rebuild || mDirtyMesh)
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
- updateMeshData();
- mDirtyMesh = FALSE;
- mNeedsSkin = TRUE;
- mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
+ {
+ updateMeshData();
+ mDirtyMesh = 0;
+ mNeedsSkin = TRUE;
+ mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+ }
}
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -3905,54 +3908,6 @@ U32 LLVOAvatar::renderRigid()
return num_indices;
}
-U32 LLVOAvatar::renderFootShadows()
-{
- U32 num_indices = 0;
-
- if (!mIsBuilt)
- {
- return 0;
- }
-
- if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead()))
- {
- return 0;
- }
-
- if (!mIsBuilt)
- {
- return 0;
- }
-
- // Don't render foot shadows if your lower body is completely invisible.
- // (non-humanoid avatars rule!)
- if (!isTextureVisible(TEX_LOWER_BAKED))
- {
- return 0;
- }
-
- // Update the shadow, tractor, and text label geometry.
- if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor())
- {
- updateShadowFaces();
- mDrawable->clearState(LLDrawable::REBUILD_SHADOW);
- }
-
- U32 foot_mask = LLVertexBuffer::MAP_VERTEX |
- LLVertexBuffer::MAP_TEXCOORD0;
-
- LLGLDepthTest test(GL_TRUE, GL_FALSE);
- //render foot shadows
- LLGLEnable blend(GL_BLEND);
- gGL.getTexUnit(0)->bind(mShadowImagep, TRUE);
- glColor4fv(mShadow0Facep->getRenderColor().mV);
- mShadow0Facep->renderIndexed(foot_mask);
- glColor4fv(mShadow1Facep->getRenderColor().mV);
- mShadow1Facep->renderIndexed(foot_mask);
-
- return num_indices;
-}
-
U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
{
if (!mImpostor.isComplete())
@@ -4073,11 +4028,6 @@ void LLVOAvatar::updateTextures()
{
setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));
}
-
- if( render_avatar )
- {
- mShadowImagep->addTextureStats(mPixelArea);
- }
}
@@ -5223,7 +5173,7 @@ BOOL LLVOAvatar::updateJointLODs()
if (res)
{
sNumLODChangesThisFrame++;
- dirtyMesh();
+ dirtyMesh(2);
return TRUE;
}
}
@@ -5247,18 +5197,9 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)
mDrawable->addFace(poolp, NULL);
mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR);
- LLFace *facep;
-
- // Add faces for the foot shadows
- facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
- mShadow0Facep = facep;
-
- facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep);
- mShadow1Facep = facep;
-
mNumInitFaces = mDrawable->getNumFaces() ;
- dirtyMesh();
+ dirtyMesh(2);
return mDrawable;
}
@@ -5298,107 +5239,6 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)
}
//-----------------------------------------------------------------------------
-// updateShadowFaces()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::updateShadowFaces()
-{
- LLFace *face0p = mShadow0Facep;
- LLFace *face1p = mShadow1Facep;
-
- //
- // render avatar shadows
- //
- if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD)
- {
- face0p->setSize(0, 0);
- face1p->setSize(0, 0);
- return;
- }
-
- LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null);
- sprite.setFollow(FALSE);
- const F32 cos_angle = gSky.getSunDirection().mV[2];
- F32 cos_elev = sqrt(1 - cos_angle * cos_angle);
- if (cos_angle < 0) cos_elev = -cos_elev;
- sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f);
- LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f);
-
- if (mShadowImagep->hasGLTexture())
- {
- LLVector3 normal;
- LLVector3d shadow_pos;
- LLVector3 shadow_pos_agent;
- F32 foot_height;
-
- if (mFootLeftp)
- {
- LLVector3 joint_world_pos = mFootLeftp->getWorldPosition();
- // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
- // but we make an explicit ray trace call in expectation of future improvements
- resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
- shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
- foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
- // Pull sprite in direction of surface normal
- shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
- // Render sprite
- sprite.setNormal(normal);
- if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
- {
- sprite.setColor(0.f, 0.f, 0.f, 0.f);
- }
- else
- {
- sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
- }
- sprite.setPosition(shadow_pos_agent);
-
- LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos;
- //foot_to_knee.normalize();
- foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
- sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-
- sprite.updateFace(*face0p);
- }
-
- if (mFootRightp)
- {
- LLVector3 joint_world_pos = mFootRightp->getWorldPosition();
- // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now
- // but we make an explicit ray trace call in expectation of future improvements
- resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),
- gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal);
- shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos);
- foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ];
-
- // Pull sprite in direction of surface normal
- shadow_pos_agent += normal * SHADOW_OFFSET_AMT;
-
- // Render sprite
- sprite.setNormal(normal);
- if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
- {
- sprite.setColor(0.f, 0.f, 0.f, 0.f);
- }
- else
- {
- sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f));
- }
- sprite.setPosition(shadow_pos_agent);
-
- LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos;
- //foot_to_knee.normalize();
- foot_to_knee -= projected_vec(foot_to_knee, sun_vec);
- sprite.setYaw(azimuth(sun_vec - foot_to_knee));
-
- sprite.updateFace(*face1p);
- }
- }
-}
-
-//-----------------------------------------------------------------------------
// updateSexDependentLayerSets()
//-----------------------------------------------------------------------------
void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
@@ -5413,9 +5253,12 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )
//-----------------------------------------------------------------------------
void LLVOAvatar::dirtyMesh()
{
- mDirtyMesh = TRUE;
+ dirtyMesh(1);
+}
+void LLVOAvatar::dirtyMesh(S32 priority)
+{
+ mDirtyMesh = llmax(mDirtyMesh, priority);
}
-
//-----------------------------------------------------------------------------
// hideSkirt()
//-----------------------------------------------------------------------------
@@ -7593,18 +7436,15 @@ BOOL LLVOAvatar::updateLOD()
BOOL res = updateJointLODs();
LLFace* facep = mDrawable->getFace(0);
- if (facep->mVertexBuffer.isNull() ||
- (LLVertexBuffer::sEnableVBOs &&
- ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) !=
- (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))))
+ if (facep->mVertexBuffer.isNull())
{
- mDirtyMesh = TRUE;
+ dirtyMesh(2);
}
- if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
+ if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))
{ //LOD changed or new mesh created, allocate new vertex buffer if needed
updateMeshData();
- mDirtyMesh = FALSE;
+ mDirtyMesh = 0;
mNeedsSkin = TRUE;
mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 9533d820eb..8aef1d0431 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -337,7 +337,6 @@ private:
**/
public:
- U32 renderFootShadows();
U32 renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
U32 renderRigid();
U32 renderSkinned(EAvatarRenderPass pass);
@@ -571,7 +570,8 @@ protected:
void releaseMeshData();
virtual void restoreMeshData();
private:
- BOOL mDirtyMesh;
+ void dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+ S32 mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
BOOL mMeshTexturesDirty;
typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 594435475f..15b04fa746 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2451,6 +2451,17 @@ void LLVOVolume::updateSpotLightPriority()
}
+bool LLVOVolume::isLightSpotlight() const
+{
+ LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE);
+ if (params)
+ {
+ return params->isLightSpotlight();
+ }
+ return false;
+}
+
+
LLViewerTexture* LLVOVolume::getLightTexture()
{
LLUUID id = getLightTextureID();
@@ -2910,9 +2921,7 @@ F32 LLVOVolume::getBinRadius()
{
LLFace* face = mDrawable->getFace(i);
if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
- (!LLPipeline::sFastAlpha ||
- face->getFaceColor().mV[3] != 1.f ||
- !face->getTexture()->getIsAlphaMask()))
+ !face->canRenderAsMask())
{
alpha_wrap = TRUE;
break;
@@ -3188,11 +3197,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
S32 idx = draw_vec.size()-1;
-
BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) ||
- (type == LLRenderPass::PASS_INVISIBLE) ||
- (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE);
-
+ (type == LLRenderPass::PASS_INVISIBLE) ||
+ (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT));
+
if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))
{
llwarns << "Non fullbright face has no normals!" << llendl;
@@ -3217,16 +3225,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
model_mat = &(drawable->getRegion()->mRenderMatrix);
}
- U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0);
+
+ U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;
LLViewerTexture* tex = facep->getTexture();
- U8 glow = 0;
-
- if (type == LLRenderPass::PASS_GLOW)
- {
- glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
- }
+ U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
if (facep->mVertexBuffer.isNull())
{
@@ -3291,6 +3295,7 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");
static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt");
+
void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
{
if (group->changeLOD())
@@ -3416,10 +3421,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
if (type == LLDrawPool::POOL_ALPHA)
{
- if (LLPipeline::sFastAlpha &&
- (te->getColor().mV[VW] == 1.0f) &&
- (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid
- facep->getTexture()->getIsAlphaMask())
+ if (facep->canRenderAsMask())
{ //can be treated as alpha mask
simple_faces.push_back(facep);
}
@@ -3521,6 +3523,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
}
static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry");
+static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild");
+
void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
{
llassert(group);
@@ -3533,6 +3537,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
{
+ LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);
LLDrawable* drawablep = *drawable_iter;
if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
@@ -3760,15 +3765,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
const LLTextureEntry* te = facep->getTextureEntry();
- BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;
+ BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;
if (is_alpha)
{
// can we safely treat this as an alpha mask?
- if (LLPipeline::sFastAlpha &&
- (te->getColor().mV[VW] == 1.0f) &&
- (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid
- facep->getTexture()->getIsAlphaMask())
+ if (facep->canRenderAsMask())
{
if (te->getFullbright())
{
@@ -3793,66 +3795,76 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
&& group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD
&& LLPipeline::sRenderBump
&& te->getShiny())
- {
+ { //shiny
if (tex->getPrimaryFormat() == GL_ALPHA)
- {
+ { //invisiprim+shiny
registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
}
else if (LLPipeline::sRenderDeferred)
- {
- if (te->getBumpmap())
- {
- registerFace(group, facep, LLRenderPass::PASS_BUMP);
- }
- else if (te->getFullbright())
- {
+ { //deferred rendering
+ if (te->getFullbright())
+ { //register in post deferred fullbright shiny pass
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
+ if (te->getBumpmap())
+ { //register in post deferred bump pass
+ registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
+ }
+ }
+ else if (te->getBumpmap())
+ { //register in deferred bump pass
+ registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
- {
+ { //register in deferred simple pass (deferred simple includes shiny)
llassert(mask & LLVertexBuffer::MAP_NORMAL);
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
}
else if (fullbright)
- {
+ { //not deferred, register in standard fullbright shiny pass
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
}
else
- {
+ { //not deferred or fullbright, register in standard shiny pass
registerFace(group, facep, LLRenderPass::PASS_SHINY);
}
}
else
- {
+ { //not alpha and not shiny
if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
- {
+ { //invisiprim
registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
}
else if (fullbright)
- {
+ { //fullbright
registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
+ { //if this is the deferred render and a bump map is present, register in post deferred bump
+ registerFace(group, facep, LLRenderPass::PASS_POST_BUMP);
+ }
}
else
{
- if (LLPipeline::sRenderDeferred && te->getBumpmap())
- {
+ if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap())
+ { //non-shiny or fullbright deferred bump
registerFace(group, facep, LLRenderPass::PASS_BUMP);
}
else
- {
+ { //all around simple
llassert(mask & LLVertexBuffer::MAP_NORMAL);
registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
}
}
+ //not sure why this is here -- shiny HUD attachments maybe? -- davep 5/11/2010
if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump)
{
registerFace(group, facep, LLRenderPass::PASS_SHINY);
}
}
+ //not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010
if (!is_alpha && !LLPipeline::sRenderDeferred)
{
llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
@@ -3864,7 +3876,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::
}
}
- if (LLPipeline::sRenderGlow && te->getGlow() > 0.f)
+ if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)
{
registerFace(group, facep, LLRenderPass::PASS_GLOW);
}
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a8bb597f93..fbae011ffc 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -215,6 +215,7 @@ public:
LLColor3 getLightBaseColor() const; // not scaled by intensity
LLColor3 getLightColor() const; // scaled by intensity
LLUUID getLightTextureID() const;
+ bool isLightSpotlight() const;
LLVector3 getSpotLightParams() const;
void updateSpotLightPriority();
F32 getSpotLightPriority() const;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 58b9f5ce18..71809e3972 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1029,9 +1029,11 @@ void LLWorld::disconnectRegions()
}
}
+static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");
void process_enable_simulator(LLMessageSystem *msg, void **user_data)
{
+ LLFastTimer t(FTM_ENABLE_SIMULATOR);
// enable the appropriate circuit for this simulator and
// add its values into the gSimulator structure
U64 handle;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2d2fc38573..b027fae033 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -191,6 +191,7 @@ std::string gPoolNames[] =
};
void drawBox(const LLVector3& c, const LLVector3& r);
+void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v)
{
@@ -268,7 +269,8 @@ BOOL LLPipeline::sRenderHighlight = TRUE;
BOOL LLPipeline::sForceOldBakedUpload = FALSE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
-BOOL LLPipeline::sFastAlpha = TRUE;
+BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE;
+BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE;
BOOL LLPipeline::sDisableShaders = FALSE;
BOOL LLPipeline::sRenderBump = TRUE;
BOOL LLPipeline::sUseTriStrips = TRUE;
@@ -327,7 +329,6 @@ LLPipeline::LLPipeline() :
mInitialized(FALSE),
mVertexShadersEnabled(FALSE),
mVertexShadersLoaded(0),
- mRenderTypeMask(0),
mRenderDebugFeatureMask(0),
mRenderDebugMask(0),
mOldRenderDebugMask(0),
@@ -361,6 +362,7 @@ void LLPipeline::init()
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+ LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
@@ -380,7 +382,11 @@ void LLPipeline::init()
LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
resetFrameStats();
- mRenderTypeMask = 0xffffffff; // All render types start on
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+ }
+
mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
mRenderDebugMask = 0; // All debug starts off
@@ -407,6 +413,8 @@ void LLPipeline::init()
{
mSpotLightFade[i] = 1.f;
}
+
+ setLightingDetail(-1);
}
LLPipeline::~LLPipeline()
@@ -509,6 +517,7 @@ void LLPipeline::destroyGL()
}
static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
+
void LLPipeline::resizeScreenTexture()
{
LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
@@ -565,9 +574,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
+ //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug)
+ U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0;
+
for (U32 i = 0; i < 4; i++)
{
- mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
}
@@ -576,11 +588,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
for (U32 i = 4; i < 6; i++)
{
- mShadow[i].allocate(width, height, 0, TRUE, FALSE);
+ mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE);
}
-
-
width = nhpo2(resX)/2;
height = nhpo2(resY)/2;
mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE);
@@ -624,10 +634,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
void LLPipeline::updateRenderDeferred()
{
BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") &&
- LLRenderTarget::sUseFBO &&
- gSavedSettings.getBOOL("VertexShaderEnable") &&
- gSavedSettings.getBOOL("RenderAvatarVP") &&
- gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE;
+ LLRenderTarget::sUseFBO &&
+ LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ gSavedSettings.getBOOL("VertexShaderEnable") &&
+ gSavedSettings.getBOOL("RenderAvatarVP") &&
+ (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&
+ !gUseWireframe;
sRenderDeferred = deferred;
}
@@ -902,13 +914,18 @@ S32 LLPipeline::setLightingDetail(S32 level)
if (level < 0)
{
- level = gSavedSettings.getS32("RenderLightingDetail");
+ if (gSavedSettings.getBOOL("VertexShaderEnable"))
+ {
+ level = 1;
+ }
+ else
+ {
+ level = 0;
+ }
}
level = llclamp(level, 0, getMaxLightingDetail());
if (level != mLightingDetail)
{
- gSavedSettings.setS32("RenderLightingDetail", level);
-
mLightingDetail = level;
if (mVertexShadersLoaded == 1)
@@ -1512,8 +1529,10 @@ BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max)
{
- min = LLVector3(F32_MAX, F32_MAX, F32_MAX);
- max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX);
+ const F32 X = 65536.f;
+
+ min = LLVector3(X,X,X);
+ max = LLVector3(-X,-X,-X);
U32 saved_camera_id = LLViewerCamera::sCurCameraID;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
@@ -1946,31 +1965,40 @@ void LLPipeline::updateGeom(F32 max_dtime)
void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE);
- if(!drawablep || drawablep->isDead())
- {
- return;
- }
-
- if (drawablep->isSpatialBridge())
- {
- LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
- if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment())
+ if(drawablep && !drawablep->isDead())
+ {
+ if (drawablep->isSpatialBridge())
{
- LLVOAvatar* av = root->getParent()->getVObj()->asAvatar();
- if (av && av->isImpostor())
+ const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
+ llassert(root); // trying to catch a bad assumption
+ if (root && // // this test may not be needed, see above
+ root->getVObj()->isAttachment())
{
- return;
+ LLDrawable* rootparent = root->getParent();
+ if (rootparent) // this IS sometimes NULL
+ {
+ LLViewerObject *vobj = rootparent->getVObj();
+ llassert(vobj); // trying to catch a bad assumption
+ if (vobj) // this test may not be needed, see above
+ {
+ const LLVOAvatar* av = vobj->asAvatar();
+ if (av && av->isImpostor())
+ {
+ return;
+ }
+ }
+ }
}
+ sCull->pushBridge((LLSpatialBridge*) drawablep);
+ }
+ else
+ {
+ sCull->pushDrawable(drawablep);
}
- sCull->pushBridge((LLSpatialBridge*) drawablep);
- }
- else
- {
- sCull->pushDrawable(drawablep);
- }
- drawablep->setVisible(camera);
+ drawablep->setVisible(camera);
+ }
}
void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
@@ -2180,14 +2208,13 @@ static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order");
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
- const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) |
- (1 << LLPipeline::RENDER_TYPE_GROUND) |
- (1 << LLPipeline::RENDER_TYPE_TERRAIN) |
- (1 << LLPipeline::RENDER_TYPE_TREE) |
- (1 << LLPipeline::RENDER_TYPE_SKY) |
- (1 << LLPipeline::RENDER_TYPE_WATER);
-
- if (mRenderTypeMask & face_mask)
+ if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_GROUND,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::END_RENDER_TYPES))
{
//clear faces from face pools
LLFastTimer t(FTM_RESET_DRAWORDER);
@@ -3410,26 +3437,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
- renderHighlights();
- mHighlightFaces.clear();
-
- renderDebug();
-
- LLVertexBuffer::unbind();
-
- if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
- {
- // Render debugging beacons.
- gObjectList.renderObjectBeacons();
- gObjectList.resetObjectBeacons();
- }
-
if (occlude)
{
occlude = FALSE;
gGLLastMatrix = NULL;
glLoadMatrixd(gGLModelView);
doOcclusion(camera);
+ gGLLastMatrix = NULL;
+ glLoadMatrixd(gGLModelView);
}
}
@@ -3592,12 +3607,17 @@ void LLPipeline::renderDebug()
for (U32 i = 0; i < 8; i++)
{
+ LLVector3* frust = mShadowCamera[i].mAgentFrustum;
+
if (i > 3)
- {
+ { //render shadow frusta as volumes
+ if (mShadowFrustPoints[i-4].empty())
+ {
+ continue;
+ }
+
gGL.color4fv(col+(i-4)*4);
- LLVector3* frust = mShadowCamera[i].mAgentFrustum;
-
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
@@ -3625,31 +3645,49 @@ void LLPipeline::renderDebug()
if (i < 4)
{
- gGL.begin(LLRender::LINES);
-
- F32* c = col+i*4;
- for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j)
+
+ if (i == 0 || !mShadowFrustPoints[i].empty())
{
-
- gGL.color3fv(c);
+ //render visible point cloud
+ gGL.flush();
+ glPointSize(8.f);
+ gGL.begin(LLRender::POINTS);
- for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k)
- {
- if (j != k)
- {
- gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
- gGL.vertex3fv(mShadowFrustPoints[i][k].mV);
- }
- }
+ F32* c = col+i*4;
+ gGL.color3fv(c);
- if (!mShadowFrustOrigin[i].isExactlyZero())
- {
+ for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j)
+ {
gGL.vertex3fv(mShadowFrustPoints[i][j].mV);
- gGL.color4f(1,1,1,1);
- gGL.vertex3fv(mShadowFrustOrigin[i].mV);
+
}
+ gGL.end();
+
+ gGL.flush();
+ glPointSize(1.f);
+
+ LLVector3* ext = mShadowExtents[i];
+ LLVector3 pos = (ext[0]+ext[1])*0.5f;
+ LLVector3 size = (ext[1]-ext[0])*0.5f;
+ drawBoxOutline(pos, size);
+
+ //render camera frustum splits as outlines
+ gGL.begin(LLRender::LINES);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV);
+ gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV);
+ gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV);
+ gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV);
+ gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV);
+ gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV);
+ gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV);
+ gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV);
+ gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
+ gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
+ gGL.end();
}
- gGL.end();
+
}
/*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
@@ -4273,7 +4311,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f);
glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);
glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f);
- glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
+ glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
}
else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)
{
@@ -4561,32 +4599,41 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos_gl(light_pos, 1.0f);
F32 light_radius = llmax(light->getLightRadius(), 0.001f);
- F32 atten, quad;
-#if 0 //1.9.1
- if (pool->getVertexShaderLevel() > 0)
- {
- atten = light_radius;
- quad = llmax(light->getLightFalloff(), 0.0001f);
- }
- else
-#endif
- {
- F32 x = (3.f * (1.f + light->getLightFalloff()));
- atten = x / (light_radius); // % of brightness at radius
- quad = 0.0f;
- }
+ F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior.
+ float linatten = x / (light_radius); // % of brightness at radius
+
mHWLightColors[cur_light] = light_color;
S32 gllight = GL_LIGHT0+cur_light;
glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
glLightfv(gllight, GL_DIFFUSE, light_color.mV);
glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
- glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f);
- glLightf (gllight, GL_LINEAR_ATTENUATION, atten);
- glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad);
- glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
- glLightf (gllight, GL_SPOT_CUTOFF, 180.0f);
+ glLightf (gllight, GL_LINEAR_ATTENUATION, linatten);
+ glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f);
+ if (light->isLightSpotlight()) // directional (spot-)light
+ {
+ LLVector3 spotparams = light->getSpotLightParams();
+ LLQuaternion quat = light->getRenderRotation();
+ LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
+ at_axis *= quat;
+ //llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl;
+ glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV);
+ glLightf (gllight, GL_SPOT_EXPONENT, 2.0f); // 2.0 = good old dot product ^ 2
+ glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere
+ const float specular[] = {0.f, 0.f, 0.f, 0.f};
+ glLightfv(gllight, GL_SPECULAR, specular);
+ }
+ else // omnidirectional (point) light
+ {
+ glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
+ glLightf (gllight, GL_SPOT_CUTOFF, 180.0f);
+
+ // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight
+ const float specular[] = {0.f, 0.f, 0.f, 1.f};
+ glLightfv(gllight, GL_SPECULAR, specular);
+ //llinfos << "boring light" << llendl;
+ }
cur_light++;
if (cur_light >= 8)
{
@@ -4613,13 +4660,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos_gl(light_pos, 1.0f);
F32 light_radius = 16.f;
- F32 atten, quad;
- {
- F32 x = 3.f;
- atten = x / (light_radius); // % of brightness at radius
- quad = 0.0f;
- }
+ F32 x = 3.f;
+ float linatten = x / (light_radius); // % of brightness at radius
+
mHWLightColors[2] = light_color;
S32 gllight = GL_LIGHT2;
glLightfv(gllight, GL_POSITION, light_pos_gl.mV);
@@ -4627,8 +4671,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f);
- glLightf (gllight, GL_LINEAR_ATTENUATION, atten);
- glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad);
+ glLightf (gllight, GL_LINEAR_ATTENUATION, linatten);
+ glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f);
glLightf (gllight, GL_SPOT_EXPONENT, 0.0f);
glLightf (gllight, GL_SPOT_CUTOFF, 180.0f);
}
@@ -4749,16 +4793,16 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)
enableLights(mask);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV);
- if (mLightingDetail >= 2)
+ /*if (mLightingDetail >= 2)
{
glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default
- }
+ }*/
}
void LLPipeline::disableLights()
{
enableLights(0); // no lighting (full bright)
- glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
+ //glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default
}
//============================================================================
@@ -4948,8 +4992,7 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light)
//static
void LLPipeline::toggleRenderType(U32 type)
{
- U32 bit = (1<<type);
- gPipeline.mRenderTypeMask ^= bit;
+ gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type];
}
//static
@@ -5361,6 +5404,7 @@ void LLPipeline::resetVertexBuffers()
{
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
+ LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -5496,6 +5540,7 @@ void LLPipeline::bindScreenToTexture()
}
static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
+
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM);
@@ -5818,6 +5863,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+
+ 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);
+ }
}
@@ -5834,8 +5885,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
+static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred");
+
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map)
{
+ LLFastTimer t(FTM_BIND_DEFERRED);
+
if (noise_map == 0xFFFFFFFF)
{
noise_map = mNoiseMap;
@@ -6173,11 +6228,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
matrix_nondiag, matrix_nondiag, matrix_diag};
shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat);
+ F32 shadow_offset_error = 1.f + gSavedSettings.getF32("RenderShadowOffsetError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+ F32 shadow_bias_error = 1.f + gSavedSettings.getF32("RenderShadowBiasError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]);
+
shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());
shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f);
- shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften"));
- shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset"));
- shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias"));
+ shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")*shadow_offset_error);
+ shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")*shadow_bias_error);
+ shader.uniform1f ("spot_shadow_offset", gSavedSettings.getF32("RenderSpotShadowOffset"));
+ shader.uniform1f("spot_shadow_bias", gSavedSettings.getF32("RenderSpotShadowBias"));
+
shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale"));
shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale"));
shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset"));
@@ -6271,16 +6331,16 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
}
- if (gSavedSettings.getBOOL("RenderDeferredShadow"))
- {
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
- mDeferredLight[0].bindTarget();
- if (gSavedSettings.getBOOL("RenderDeferredSun"))
+ mDeferredLight[0].bindTarget();
+
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)
+ {
{ //paint shadow/SSAO light map (direct lighting lightmap)
LLFastTimer ftm(FTM_SUN_SHADOW);
bindDeferredShader(gDeferredSunProgram, 0);
@@ -6321,18 +6381,22 @@ void LLPipeline::renderDeferredLighting()
unbindDeferredShader(gDeferredSunProgram);
}
- else
- {
- mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
- }
+ }
+ else
+ {
+ glClearColor(1,1,1,1);
+ mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+ }
- mDeferredLight[0].flush();
+ mDeferredLight[0].flush();
+ { //global illumination specific block (still experimental)
if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
- gSavedSettings.getBOOL("RenderDeferredGI"))
- {
+ gSavedSettings.getBOOL("RenderDeferredGI"))
+ {
LLFastTimer ftm(FTM_EDGE_DETECTION);
- //get edge map
+ //generate edge map
LLGLDisable blend(GL_BLEND);
LLGLDisable test(GL_ALPHA_TEST);
LLGLDepthTest depth(GL_FALSE);
@@ -6429,79 +6493,79 @@ void LLPipeline::renderDeferredLighting()
unbindDeferredShader(gDeferredPostGIProgram);
}
}
+ }
- if (gSavedSettings.getBOOL("RenderDeferredBlurLight"))
- { //soften direct lighting lightmap
- LLFastTimer ftm(FTM_SOFTEN_SHADOW);
- //blur lightmap
- mDeferredLight[1].bindTarget();
+ if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
+ { //soften direct lighting lightmap
+ LLFastTimer ftm(FTM_SOFTEN_SHADOW);
+ //blur lightmap
+ mDeferredLight[1].bindTarget();
- glClearColor(1,1,1,1);
- mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
-
- bindDeferredShader(gDeferredBlurLightProgram);
+ glClearColor(1,1,1,1);
+ mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+
+ bindDeferredShader(gDeferredBlurLightProgram);
- LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
- const U32 kern_length = 4;
- F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
- F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
+ LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian");
+ const U32 kern_length = 4;
+ F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize");
+ F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor");
- // sample symmetrically with the middle sample falling exactly on 0.0
- F32 x = 0.f;
+ // sample symmetrically with the middle sample falling exactly on 0.0
+ F32 x = 0.f;
- LLVector3 gauss[32]; // xweight, yweight, offset
+ LLVector3 gauss[32]; // xweight, yweight, offset
- for (U32 i = 0; i < kern_length; i++)
- {
- gauss[i].mV[0] = llgaussian(x, go.mV[0]);
- gauss[i].mV[1] = llgaussian(x, go.mV[1]);
- gauss[i].mV[2] = x;
- x += 1.f;
- }
+ for (U32 i = 0; i < kern_length; i++)
+ {
+ gauss[i].mV[0] = llgaussian(x, go.mV[0]);
+ gauss[i].mV[1] = llgaussian(x, go.mV[1]);
+ gauss[i].mV[2] = x;
+ x += 1.f;
+ }
- gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
- gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
- gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
- gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+ gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor);
+ gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f));
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+ stop_glerror();
+ }
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
- stop_glerror();
- }
-
- mDeferredLight[1].flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
+ mDeferredLight[1].flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
- bindDeferredShader(gDeferredBlurLightProgram, 1);
- mDeferredLight[0].bindTarget();
+ bindDeferredShader(gDeferredBlurLightProgram, 1);
+ mDeferredLight[0].bindTarget();
- gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
- {
- LLGLDisable blend(GL_BLEND);
- LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
- stop_glerror();
- glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
- stop_glerror();
- }
- mDeferredLight[0].flush();
- unbindDeferredShader(gDeferredBlurLightProgram);
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 3);
+ stop_glerror();
}
-
- stop_glerror();
- glPopMatrix();
- stop_glerror();
- glMatrixMode(GL_MODELVIEW);
- stop_glerror();
- glPopMatrix();
- stop_glerror();
+ mDeferredLight[0].flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
}
+ stop_glerror();
+ glPopMatrix();
+ stop_glerror();
+ glMatrixMode(GL_MODELVIEW);
+ stop_glerror();
+ glPopMatrix();
+ stop_glerror();
+
//copy depth and stencil from deferred screen
//mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
// 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST);
@@ -6509,11 +6573,15 @@ void LLPipeline::renderDeferredLighting()
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
{
mDeferredLight[1].bindTarget();
- mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT);
+ // clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
+ mScreen.clear(GL_COLOR_BUFFER_BIT);
}
else
{
mScreen.bindTarget();
+ // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
mScreen.clear(GL_COLOR_BUFFER_BIT);
}
@@ -6550,15 +6618,16 @@ void LLPipeline::renderDeferredLighting()
LLGLDisable stencil(GL_STENCIL_TEST);
gGL.setSceneBlendType(LLRender::BT_ALPHA);
- U32 render_mask = mRenderTypeMask;
- mRenderTypeMask = mRenderTypeMask &
- ((1 << LLPipeline::RENDER_TYPE_SKY) |
- (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
- (1 << LLPipeline::RENDER_TYPE_WL_SKY));
+ gPipeline.pushRenderTypeMask();
+
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
- mRenderTypeMask = render_mask;
+ gPipeline.popRenderTypeMask();
}
BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
@@ -6603,6 +6672,15 @@ void LLPipeline::renderDeferredLighting()
continue;
}
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+
LLVector3 center = drawablep->getPositionAgent();
F32* c = center.mV;
F32 s = volume->getLightRadius()*1.5f;
@@ -6653,7 +6731,7 @@ void LLPipeline::renderDeferredLighting()
{ //draw box if camera is outside box
if (render_local)
{
- if (volume->getLightTexture())
+ if (volume->isLightSpotlight())
{
drawablep->getVOVolume()->updateSpotLightPriority();
spot_lights.push_back(drawablep);
@@ -6670,7 +6748,7 @@ void LLPipeline::renderDeferredLighting()
}
else if (render_fullscreen)
{
- if (volume->getLightTexture())
+ if (volume->isLightSpotlight())
{
drawablep->getVOVolume()->updateSpotLightPriority();
fullscreen_spot_lights.push_back(drawablep);
@@ -6871,29 +6949,48 @@ void LLPipeline::renderDeferredLighting()
LLGLDisable blend(GL_BLEND);
LLGLDisable stencil(GL_STENCIL_TEST);
- U32 render_mask = mRenderTypeMask;
- mRenderTypeMask = mRenderTypeMask &
- ((1 << LLPipeline::RENDER_TYPE_ALPHA) |
- (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) |
- (1 << LLPipeline::RENDER_TYPE_VOLUME) |
- (1 << LLPipeline::RENDER_TYPE_GLOW) |
- (1 << LLPipeline::RENDER_TYPE_BUMP) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
- (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
- (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) |
- (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_AVATAR));
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_POST_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_GLOW,
+ LLPipeline::RENDER_TYPE_PASS_GRASS,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
- mRenderTypeMask = render_mask;
+ popRenderTypeMask();
+ }
+
+ {
+ //render highlights, etc.
+ renderHighlights();
+ mHighlightFaces.clear();
+
+ renderDebug();
+
+ LLVertexBuffer::unbind();
+
+ if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI))
+ {
+ // Render debugging beacons.
+ gObjectList.renderObjectBeacons();
+ LLHUDObject::renderAll();
+ gObjectList.resetObjectBeacons();
+ }
}
mScreen.flush();
@@ -7130,8 +7227,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::sUseOcclusion = llmin(occlusion, 1);
- U32 type_mask = gPipeline.mRenderTypeMask;
-
+ gPipeline.pushRenderTypeMask();
+
glh::matrix4f projection = glh_get_current_projection();
glh::matrix4f mat;
@@ -7199,44 +7296,48 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
glCullFace(GL_FRONT);
static LLCullResult ref_result;
- U32 ref_mask = 0;
+
if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
//initial sky pass (no user clip plane)
{ //mask out everything but the sky
- U32 tmp = mRenderTypeMask;
- mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
- (1 << LLPipeline::RENDER_TYPE_WL_SKY));
+ gPipeline.pushRenderTypeMask();
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
static LLCullResult result;
updateCull(camera, result);
llpushcallstacks ;
stateSort(camera, result);
- mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) |
- (1 << LLPipeline::RENDER_TYPE_CLOUDS) |
- (1 << LLPipeline::RENDER_TYPE_WL_SKY));
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
renderGeom(camera, TRUE);
- mRenderTypeMask = tmp;
+ gPipeline.popRenderTypeMask();
}
- U32 mask = mRenderTypeMask;
- mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_WATER) |
- (1<<LLPipeline::RENDER_TYPE_GROUND) |
- (1<<LLPipeline::RENDER_TYPE_SKY) |
- (1<<LLPipeline::RENDER_TYPE_CLOUDS));
-
- if (gSavedSettings.getBOOL("RenderWaterReflections"))
+ gPipeline.pushRenderTypeMask();
+
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_GROUND,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::END_RENDER_TYPES);
+
+ S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+ if (detail > 0)
{ //mask out selected geometry based on reflection detail
-
- S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
- if (detail < 3)
+ if (detail < 4)
{
- mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES);
- if (detail < 2)
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
+ if (detail < 3)
{
- mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR);
- if (detail < 1)
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+ if (detail < 2)
{
- mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME);
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
}
}
}
@@ -7248,18 +7349,17 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
stateSort(camera, ref_result);
}
- ref_mask = mRenderTypeMask;
- mRenderTypeMask = mask;
- }
- if (LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- mRenderTypeMask = ref_mask;
- if (gSavedSettings.getBOOL("RenderWaterReflections"))
+ if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
- gPipeline.grabReferences(ref_result);
- LLGLUserClipPlane clip_plane(plane, mat, projection);
- renderGeom(camera);
+ if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
+ {
+ gPipeline.grabReferences(ref_result);
+ LLGLUserClipPlane clip_plane(plane, mat, projection);
+ renderGeom(camera);
+ }
}
+
+ gPipeline.popRenderTypeMask();
}
glCullFace(GL_BACK);
glPopMatrix();
@@ -7273,18 +7373,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
if (last_update)
{
camera.setFar(camera_in.getFar());
- mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) |
- (1<<LLPipeline::RENDER_TYPE_GROUND));
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_GROUND,
+ END_RENDER_TYPES);
stop_glerror();
LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE;
if (LLPipeline::sUnderWaterRender)
{
- mRenderTypeMask &= ~((1<<LLPipeline::RENDER_TYPE_GROUND) |
- (1<<LLPipeline::RENDER_TYPE_SKY) |
- (1<<LLPipeline::RENDER_TYPE_CLOUDS) |
- (1<<LLPipeline::RENDER_TYPE_WL_SKY));
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_GROUND,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ END_RENDER_TYPES);
}
LLViewerCamera::updateFrustumPlanes(camera);
@@ -7326,7 +7428,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
}
glClearColor(0.f, 0.f, 0.f, 0.f);
gViewerWindow->setup3DViewport();
- mRenderTypeMask = type_mask;
+ gPipeline.popRenderTypeMask();
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
@@ -7518,115 +7620,172 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLPipeline::sShadowRender = FALSE;
}
-
+static LLFastTimer::DeclareTimer FTM_VISIBLE_CLOUD("Visible Cloud");
BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)
{
+ LLFastTimer t(FTM_VISIBLE_CLOUD);
//get point cloud of intersection of frust and min, max
- //get set of planes
- std::vector<LLPlane> ps;
-
if (getVisibleExtents(camera, min, max))
{
return FALSE;
}
- ps.push_back(LLPlane(min, LLVector3(-1,0,0)));
- ps.push_back(LLPlane(min, LLVector3(0,-1,0)));
- ps.push_back(LLPlane(min, LLVector3(0,0,-1)));
- ps.push_back(LLPlane(max, LLVector3(1,0,0)));
- ps.push_back(LLPlane(max, LLVector3(0,1,0)));
- ps.push_back(LLPlane(max, LLVector3(0,0,1)));
+ //get set of planes on bounding box
+ std::vector<LLPlane> bp;
+
+ bp.push_back(LLPlane(min, LLVector3(-1,0,0)));
+ bp.push_back(LLPlane(min, LLVector3(0,-1,0)));
+ bp.push_back(LLPlane(min, LLVector3(0,0,-1)));
+ bp.push_back(LLPlane(max, LLVector3(1,0,0)));
+ bp.push_back(LLPlane(max, LLVector3(0,1,0)));
+ bp.push_back(LLPlane(max, LLVector3(0,0,1)));
+
+ //potential points
+ std::vector<LLVector3> pp;
+
+ //add corners of AABB
+ pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2]));
+ pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
- /*if (!light_dir.isExactlyZero())
+ //add corners of camera frustum
+ for (U32 i = 0; i < 8; i++)
{
- LLPlane ucp;
- LLPlane mcp;
+ pp.push_back(camera.mAgentFrustum[i]);
+ }
- F32 maxd = -1.f;
- F32 mind = 1.f;
- for (U32 i = 0; i < ps.size(); ++i)
- { //pick the plane most aligned to lightDir for user clip plane
- LLVector3 n(ps[i].mV);
- F32 da = n*light_dir;
- if (da > maxd)
- {
- maxd = da;
- ucp = ps[i];
- }
+ //bounding box line segments
+ U32 bs[] =
+ {
+ 0,1,
+ 1,3,
+ 3,2,
+ 2,0,
+
+ 4,5,
+ 5,7,
+ 7,6,
+ 6,4,
+
+ 0,4,
+ 1,5,
+ 3,7,
+ 2,6
+ };
+
+ for (U32 i = 0; i < 12; i++)
+ { //for each line segment in bounding box
+ for (U32 j = 0; j < 6; j++)
+ { //for each plane in camera frustum
+ const LLPlane& cp = camera.getAgentPlane(j);
+ const LLVector3& v1 = pp[bs[i*2+0]];
+ const LLVector3& v2 = pp[bs[i*2+1]];
+ const LLVector3 n(cp.mV);
+
+ LLVector3 line = v1-v2;
+
+ F32 d1 = line*n;
+ F32 d2 = -cp.dist(v2);
+
+ F32 t = d2/d1;
- if (da < mind)
+ if (t > 0.f && t < 1.f)
{
- mind = da;
- mcp = ps[i];
+ LLVector3 intersect = v2+line*t;
+ pp.push_back(intersect);
}
}
-
- camera.setUserClipPlane(ucp);
+ }
- ps.clear();
- ps.push_back(ucp);
- ps.push_back(mcp);
- }*/
-
- for (U32 i = 0; i < 6; i++)
+ //camera frustum line segments
+ const U32 fs[] =
{
- ps.push_back(camera.getAgentPlane(i));
- }
+ 0,1,
+ 1,2,
+ 2,3,
+ 3,1,
- //get set of points where planes intersect and points are not above any plane
- fp.clear();
-
- for (U32 i = 0; i < ps.size(); ++i)
+ 4,5,
+ 5,6,
+ 6,7,
+ 7,4,
+
+ 0,4,
+ 1,5,
+ 2,6,
+ 3,7
+ };
+
+ LLVector3 center = (max+min)*0.5f;
+ LLVector3 size = (max-min)*0.5f;
+
+ for (U32 i = 0; i < 12; i++)
{
- for (U32 j = 0; j < ps.size(); ++j)
+ for (U32 j = 0; j < 6; ++j)
{
- for (U32 k = 0; k < ps.size(); ++k)
- {
- if (i == j ||
- i == k ||
- k == j)
- {
- continue;
- }
+ const LLVector3& v1 = pp[fs[i*2+0]+8];
+ const LLVector3& v2 = pp[fs[i*2+1]+8];
+ const LLPlane& cp = bp[j];
+ const LLVector3 n(cp.mV);
- LLVector3 n1,n2,n3;
- F32 d1,d2,d3;
+ LLVector3 line = v1-v2;
- n1.setVec(ps[i].mV);
- n2.setVec(ps[j].mV);
- n3.setVec(ps[k].mV);
+ F32 d1 = line*n;
+ F32 d2 = -cp.dist(v2);
- d1 = ps[i].mV[3];
- d2 = ps[j].mV[3];
- d3 = ps[k].mV[3];
-
- //get point of intersection of 3 planes "p"
- LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3));
-
- if (llround(p*n1+d1, 0.0001f) == 0.f &&
- llround(p*n2+d2, 0.0001f) == 0.f &&
- llround(p*n3+d3, 0.0001f) == 0.f)
- { //point is on all three planes
- BOOL found = TRUE;
- for (U32 l = 0; l < ps.size() && found; ++l)
- {
- if (llround(ps[l].dist(p), 0.0001f) > 0.0f)
- { //point is above some plane, not contained
- found = FALSE;
- }
- }
+ F32 t = d2/d1;
- if (found)
- {
- fp.push_back(p);
- }
- }
- }
+ if (t > 0.f && t < 1.f)
+ {
+ LLVector3 intersect = v2+line*t;
+ pp.push_back(intersect);
+ }
}
}
+ LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
+ max+LLVector3(0.05f,0.05f,0.05f) };
+
+ for (U32 i = 0; i < pp.size(); ++i)
+ {
+ bool found = true;
+
+ const F32* p = pp[i].mV;
+
+ for (U32 j = 0; j < 3; ++j)
+ {
+ if (p[j] < ext[0].mV[j] ||
+ p[j] > ext[1].mV[j])
+ {
+ found = false;
+ break;
+ }
+ }
+
+ for (U32 j = 0; j < 6; ++j)
+ {
+ const LLPlane& cp = camera.getAgentPlane(j);
+ F32 dist = cp.dist(pp[i]);
+ if (dist > 0.05f) //point is above some plane, not contained
+ {
+ found = false;
+ break;
+ }
+ }
+
+ if (found)
+ {
+ fp.push_back(pp[i]);
+ }
+ }
+
if (fp.empty())
{
return FALSE;
@@ -7724,21 +7883,22 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L
sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
static LLCullResult result;
- U32 type_mask = mRenderTypeMask;
+ pushRenderTypeMask();
- mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
- (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
- (1<<LLPipeline::RENDER_TYPE_BUMP) |
- (1<<LLPipeline::RENDER_TYPE_VOLUME) |
- (1<<LLPipeline::RENDER_TYPE_TREE) |
- (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
- (1<<LLPipeline::RENDER_TYPE_WATER) |
- (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
- (1<<LLPipeline::RENDER_TYPE_AVATAR) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SHINY));
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ END_RENDER_TYPES);
@@ -7807,7 +7967,7 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L
LLPipeline::sShadowRender = FALSE;
sMinRenderSize = 0.f;
- mRenderTypeMask = type_mask;
+ popRenderTypeMask();
}
@@ -7891,30 +8051,11 @@ void LLPipeline::generateHighlight(LLCamera& camera)
void LLPipeline::generateSunShadow(LLCamera& camera)
{
- if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderDeferredShadow"))
+ if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0)
{
return;
}
- //temporary hack to disable shadows but keep local lights
- static BOOL clear = TRUE;
- BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow");
- if (!gen_shadow)
- {
- if (clear)
- {
- clear = FALSE;
- for (U32 i = 0; i < 6; i++)
- {
- mShadow[i].bindTarget();
- mShadow[i].clear();
- mShadow[i].flush();
- }
- }
- return;
- }
- clear = TRUE;
-
F64 last_modelview[16];
F64 last_projection[16];
for (U32 i = 0; i < 16; i++)
@@ -7923,23 +8064,24 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
last_projection[i] = gGLLastProjection[i];
}
- U32 type_mask = mRenderTypeMask;
- mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) |
- (1<<LLPipeline::RENDER_TYPE_ALPHA) |
- (1<<LLPipeline::RENDER_TYPE_GRASS) |
- (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
- (1<<LLPipeline::RENDER_TYPE_BUMP) |
- (1<<LLPipeline::RENDER_TYPE_VOLUME) |
- (1<<LLPipeline::RENDER_TYPE_AVATAR) |
- (1<<LLPipeline::RENDER_TYPE_TREE) |
- (1<<LLPipeline::RENDER_TYPE_TERRAIN) |
- (1<<LLPipeline::RENDER_TYPE_WATER) |
- (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY));
+ pushRenderTypeMask();
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE,
+ LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_GRASS,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_TREE,
+ LLPipeline::RENDER_TYPE_TERRAIN,
+ LLPipeline::RENDER_TYPE_WATER,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_BUMP,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -7991,17 +8133,32 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
at.normVec();
+ LLCamera main_camera = camera;
+
F32 near_clip = 0.f;
{
//get visible point cloud
std::vector<LLVector3> fp;
+ main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum);
+
LLVector3 min,max;
- getVisiblePointCloud(camera,min,max,fp);
+ getVisiblePointCloud(main_camera,min,max,fp);
if (fp.empty())
{
- mRenderTypeMask = type_mask;
+ if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA))
+ {
+ mShadowCamera[0] = main_camera;
+ mShadowExtents[0][0] = min;
+ mShadowExtents[0][1] = max;
+
+ mShadowFrustPoints[0].clear();
+ mShadowFrustPoints[1].clear();
+ mShadowFrustPoints[2].clear();
+ mShadowFrustPoints[3].clear();
+ }
+ popRenderTypeMask();
return;
}
@@ -8075,7 +8232,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
shadow_cam = camera;
shadow_cam.setFar(16.f);
- LLViewerCamera::updateFrustumPlanes(shadow_cam);
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
LLVector3* frust = shadow_cam.mAgentFrustum;
@@ -8087,10 +8244,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
for (U32 i = 0; i < 4; i++)
{
LLVector3 delta = frust[i+4]-eye;
+ delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;
delta.normVec();
F32 dp = delta*pn;
- frust[i] = eye + (delta*dist[j])/dp;
- frust[i+4] = eye + (delta*dist[j+1])/dp;
+ frust[i] = eye + (delta*dist[j]*0.95f)/dp;
+ frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp;
}
shadow_cam.calcAgentFrustumPlanes(frust);
@@ -8430,135 +8588,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
}
}
-
-
- F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+ //hack to disable projector shadows
+ static bool clear = true;
+ bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1;
+
+ if (gen_shadow)
+ {
+ clear = true;
+ F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
- if (mShadowSpotLight[i].notNull() &&
- (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
- mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
- { //keep this spotlight
- mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
- }
- else
- { //fade out this light
- mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
-
- if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
- { //faded out, grab one of the pending spots (whichever one isn't already taken)
- if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[0];
- }
- else
- {
- mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ //update shadow targets
+ for (U32 i = 0; i < 2; i++)
+ { //for each current shadow
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+
+ if (mShadowSpotLight[i].notNull() &&
+ (mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
+ mShadowSpotLight[i] == mTargetShadowSpotLight[1]))
+ { //keep this spotlight
+ mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f);
+ }
+ else
+ { //fade out this light
+ mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f);
+
+ if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull())
+ { //faded out, grab one of the pending spots (whichever one isn't already taken)
+ if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2])
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[0];
+ }
+ else
+ {
+ mShadowSpotLight[i] = mTargetShadowSpotLight[1];
+ }
}
}
}
- }
-
- for (S32 i = 0; i < 2; i++)
- {
- glh_set_current_modelview(saved_view);
- glh_set_current_projection(saved_proj);
-
- if (mShadowSpotLight[i].isNull())
+
+ for (S32 i = 0; i < 2; i++)
{
- continue;
- }
+ glh_set_current_modelview(saved_view);
+ glh_set_current_projection(saved_proj);
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- LLDrawable* drawable = mShadowSpotLight[i];
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLDrawable* drawable = mShadowSpotLight[i];
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
+ at_axis *= quat;
- //get origin that has given fov for plane np, at_axis, and given scale
- F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
+ LLVector3 np = center+at_axis;
+ at_axis.normVec();
- LLVector3 origin = np - at_axis*dist;
+ //get origin that has given fov for plane np, at_axis, and given scale
+ F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f);
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLVector3 origin = np - at_axis*dist;
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- view[i+4] = view[i+4].inverse();
+ view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
- //get perspective matrix
- F32 near_clip = dist+0.01f;
- F32 width = scale.mV[VX];
- F32 height = scale.mV[VY];
- F32 far_clip = dist+volume->getLightRadius()*1.5f;
+ view[i+4] = view[i+4].inverse();
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ //get perspective matrix
+ F32 near_clip = dist+0.01f;
+ F32 width = scale.mV[VX];
+ F32 height = scale.mV[VY];
+ F32 far_clip = dist+volume->getLightRadius()*1.5f;
- //translate and scale to from [-1, 1] to [0, 1]
- glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
- 0.f, 0.5f, 0.f, 0.5f,
- 0.f, 0.f, 0.5f, 0.5f,
- 0.f, 0.f, 0.f, 1.f);
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width/height;
+
+ proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- glh_set_current_modelview(view[i+4]);
- glh_set_current_projection(proj[i+4]);
+ //translate and scale to from [-1, 1] to [0, 1]
+ glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
+ 0.f, 0.5f, 0.f, 0.5f,
+ 0.f, 0.f, 0.5f, 0.5f,
+ 0.f, 0.f, 0.f, 1.f);
- mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
-
- for (U32 j = 0; j < 16; j++)
- {
- gGLLastModelView[j] = mShadowModelview[i+4].m[j];
- gGLLastProjection[j] = mShadowProjection[i+4].m[j];
- }
+ glh_set_current_modelview(view[i+4]);
+ glh_set_current_projection(proj[i+4]);
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view;
+
+ for (U32 j = 0; j < 16; j++)
+ {
+ gGLLastModelView[j] = mShadowModelview[i+4].m[j];
+ gGLLastProjection[j] = mShadowProjection[i+4].m[j];
+ }
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ mShadowModelview[i+4] = view[i+4];
+ mShadowProjection[i+4] = proj[i+4];
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- stop_glerror();
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+
+ stop_glerror();
- mShadow[i+4].bindTarget();
- mShadow[i+4].getViewport(gGLViewport);
+ mShadow[i+4].bindTarget();
+ mShadow[i+4].getViewport(gGLViewport);
- static LLCullResult result[2];
+ static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
- renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
+ renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE);
- mShadow[i+4].flush();
- }
+ mShadow[i+4].flush();
+ }
+ }
+ else
+ {
+ if (clear)
+ {
+ clear = false;
+ for (U32 i = 4; i < 6; i++)
+ {
+ mShadow[i].bindTarget();
+ mShadow[i].clear();
+ mShadow[i].flush();
+ }
+ }
+ }
if (!gSavedSettings.getBOOL("CameraOffset"))
{
@@ -8582,7 +8760,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
gGLLastProjection[i] = last_projection[i];
}
- mRenderTypeMask = type_mask;
+ popRenderTypeMask();
}
void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture)
@@ -8618,38 +8796,36 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
- U32 mask;
BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID());
+ pushRenderTypeMask();
+
if (muted)
{
- mask = 1 << LLPipeline::RENDER_TYPE_AVATAR;
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
}
else
{
- mask = (1<<LLPipeline::RENDER_TYPE_VOLUME) |
- (1<<LLPipeline::RENDER_TYPE_AVATAR) |
- (1<<LLPipeline::RENDER_TYPE_BUMP) |
- (1<<LLPipeline::RENDER_TYPE_GRASS) |
- (1<<LLPipeline::RENDER_TYPE_SIMPLE) |
- (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) |
- (1<<LLPipeline::RENDER_TYPE_ALPHA) |
- (1<<LLPipeline::RENDER_TYPE_INVISIBLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) |
- (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) |
- (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) |
- (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) |
- (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY);
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_BUMP,
+ LLPipeline::RENDER_TYPE_GRASS,
+ LLPipeline::RENDER_TYPE_SIMPLE,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_SIMPLE,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
+ LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
+ END_RENDER_TYPES);
}
- mask = mask & gPipeline.getRenderTypeMask();
- U32 saved_mask = gPipeline.mRenderTypeMask;
- gPipeline.mRenderTypeMask = mask;
-
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
sReflectionRender = sRenderDeferred ? FALSE : TRUE;
@@ -8823,7 +8999,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
sReflectionRender = FALSE;
sImpostorRender = FALSE;
sShadowRender = FALSE;
- gPipeline.mRenderTypeMask = saved_mask;
+ popRenderTypeMask();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
@@ -8864,4 +9040,121 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()
return sCull->endAlphaGroups();
}
+BOOL LLPipeline::hasRenderType(const U32 type) const
+{
+ return mRenderTypeEnabled[type];
+}
+
+void LLPipeline::setRenderTypeMask(U32 type, ...)
+{
+ va_list args;
+
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ mRenderTypeEnabled[type] = TRUE;
+ type = va_arg(args, U32);
+ }
+ va_end(args);
+
+ if (type > END_RENDER_TYPES)
+ {
+ llerrs << "Invalid render type." << llendl;
+ }
+}
+
+BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const
+{
+ va_list args;
+
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ if (mRenderTypeEnabled[type])
+ {
+ return TRUE;
+ }
+ type = va_arg(args, U32);
+ }
+ va_end(args);
+
+ if (type > END_RENDER_TYPES)
+ {
+ llerrs << "Invalid render type." << llendl;
+ }
+
+ return FALSE;
+}
+
+void LLPipeline::pushRenderTypeMask()
+{
+ std::string cur_mask;
+ cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled));
+ mRenderTypeEnableStack.push(cur_mask);
+}
+
+void LLPipeline::popRenderTypeMask()
+{
+ if (mRenderTypeEnableStack.empty())
+ {
+ llerrs << "Depleted render type stack." << llendl;
+ }
+
+ memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled));
+ mRenderTypeEnableStack.pop();
+}
+
+void LLPipeline::andRenderTypeMask(U32 type, ...)
+{
+ va_list args;
+
+ BOOL tmp[NUM_RENDER_TYPES];
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ tmp[i] = FALSE;
+ }
+
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ if (mRenderTypeEnabled[type])
+ {
+ tmp[type] = TRUE;
+ }
+
+ type = va_arg(args, U32);
+ }
+ va_end(args);
+
+ if (type > END_RENDER_TYPES)
+ {
+ llerrs << "Invalid render type." << llendl;
+ }
+
+ for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = tmp[i];
+ }
+
+}
+
+void LLPipeline::clearRenderTypeMask(U32 type, ...)
+{
+ va_list args;
+
+ va_start(args, type);
+ while (type < END_RENDER_TYPES)
+ {
+ mRenderTypeEnabled[type] = FALSE;
+
+ type = va_arg(args, U32);
+ }
+ va_end(args);
+
+ if (type > END_RENDER_TYPES)
+ {
+ llerrs << "Invalid render type." << llendl;
+ }
+}
+
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 60e0b0ae8c..9d25e6d189 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -46,6 +46,8 @@
#include "lldrawable.h"
#include "llrendertarget.h"
+#include <stack>
+
class LLViewerTexture;
class LLEdge;
class LLFace;
@@ -277,12 +279,25 @@ public:
LLCullResult::sg_list_t::iterator beginAlphaGroups();
LLCullResult::sg_list_t::iterator endAlphaGroups();
+
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);
- BOOL hasRenderType(const U32 type) const { return (type && (mRenderTypeMask & (1<<type))) ? TRUE : FALSE; }
+
BOOL hasRenderDebugFeatureMask(const U32 mask) const { return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
BOOL hasRenderDebugMask(const U32 mask) const { return (mRenderDebugMask & mask) ? TRUE : FALSE; }
- void setRenderTypeMask(const U32 mask) { mRenderTypeMask = mask; }
- U32 getRenderTypeMask() const { return mRenderTypeMask; }
+
+
+
+ BOOL hasRenderType(const U32 type) const;
+ BOOL hasAnyRenderType(const U32 type, ...) const;
+
+ void setRenderTypeMask(U32 type, ...);
+ void orRenderTypeMask(U32 type, ...);
+ void andRenderTypeMask(U32 type, ...);
+ void clearRenderTypeMask(U32 type, ...);
+
+ void pushRenderTypeMask();
+ void popRenderTypeMask();
+
static void toggleRenderType(U32 type);
// For UI control of render features
@@ -360,6 +375,7 @@ public:
RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY,
RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY,
RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP,
+ RENDER_TYPE_PASS_POST_BUMP = LLRenderPass::PASS_POST_BUMP,
RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW,
RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA,
RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK,
@@ -370,7 +386,9 @@ public:
RENDER_TYPE_VOLUME,
RENDER_TYPE_PARTICLES,
RENDER_TYPE_CLOUDS,
- RENDER_TYPE_HUD_PARTICLES
+ RENDER_TYPE_HUD_PARTICLES,
+ NUM_RENDER_TYPES,
+ END_RENDER_TYPES = NUM_RENDER_TYPES
};
enum LLRenderDebugFeatureMask
@@ -444,7 +462,8 @@ public:
static BOOL sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.
static S32 sUseOcclusion; // 0 = no occlusion, 1 = read only, 2 = read/write
static BOOL sDelayVBUpdate;
- static BOOL sFastAlpha;
+ static BOOL sAutoMaskAlphaDeferred;
+ static BOOL sAutoMaskAlphaNonDeferred;
static BOOL sDisableShaders; // if TRUE, rendering will be done without shaders
static BOOL sRenderBump;
static BOOL sUseTriStrips;
@@ -532,7 +551,9 @@ public:
S32 mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed
protected:
- U32 mRenderTypeMask;
+ BOOL mRenderTypeEnabled[NUM_RENDER_TYPES];
+ std::stack<std::string> mRenderTypeEnableStack;
+
U32 mRenderDebugFeatureMask;
U32 mRenderDebugMask;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index c9ebeb60fb..66a6696a2c 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2137,14 +2137,24 @@
parameter="RenderDebugPipeline" />
</menu_item_check>
<menu_item_check
- label="Fast Alpha"
- name="Fast Alpha">
+ label="Automatic Alpha Masks (deferred)"
+ name="Automatic Alpha Masks (deferred)">
<menu_item_check.on_check
function="CheckControl"
- parameter="RenderFastAlpha" />
+ parameter="RenderAutoMaskAlphaDeferred" />
<menu_item_check.on_click
function="ToggleControl"
- parameter="RenderFastAlpha" />
+ parameter="RenderAutoMaskAlphaDeferred" />
+ </menu_item_check>
+ <menu_item_check
+ label="Automatic Alpha Masks (non-deferred)"
+ name="Automatic Alpha Masks (non-deferred)">
+ <menu_item_check.on_check
+ function="CheckControl"
+ parameter="RenderAutoMaskAlphaNonDeferred" />
+ <menu_item_check.on_click
+ function="ToggleControl"
+ parameter="RenderAutoMaskAlphaNonDeferred" />
</menu_item_check>
<menu_item_check
label="Animation Textures"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 0a56f711dd..68a0db3b89 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -155,12 +155,12 @@
visiblity_control="ShowAdvancedGraphicsSettings"
border="false"
follows="top|left"
- height="260"
+ height="283"
label="CustomGraphics"
layout="topleft"
left="5"
name="CustomGraphics Panel"
- top="124"
+ top="101"
width="485">
<text
type="string"
@@ -211,119 +211,111 @@
<check_box.commit_callback
function="Pref.VertexShaderEnable" />
</check_box>
- <check_box
- control_name="RenderWaterReflections"
+ <check_box
+ control_name="RenderDeferred"
height="16"
initial_value="true"
- label="Water reflections"
+ label="Lighting and Shadows"
layout="topleft"
left_delta="0"
- name="Reflections"
+ name="UseLightShaders"
top_pad="1"
width="256">
- <check_box.commit_callback
+ <check_box.commit_callback
function="Pref.VertexShaderEnable" />
- </check_box>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="12"
- layout="topleft"
- left_delta="0"
- name="ReflectionDetailText"
- top_pad="7"
- width="128">
- Reflection detail:
- </text>
- <radio_group
- control_name="RenderReflectionDetail"
- draw_border="false"
- height="70"
- layout="topleft"
- left_delta="-2"
- name="ReflectionDetailRadio"
- top_pad="3"
- width="321">
- <radio_item
- height="16"
- label="Terrain and trees"
- layout="topleft"
- left="3"
- name="0"
- top="3"
- width="315" />
- <radio_item
- height="16"
- label="All static objects"
- layout="topleft"
- left_delta="0"
- name="1"
- top_delta="16"
- width="315" />
- <radio_item
- height="16"
- label="All avatars and objects"
- layout="topleft"
- left_delta="0"
- name="2"
- top_delta="16"
- width="315" />
- <radio_item
- height="16"
- label="Everything"
- layout="topleft"
- left_delta="0"
- name="3"
- top_delta="16"
- width="315" />
- </radio_group>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="12"
- layout="topleft"
- left_delta="2"
- name="AvatarRenderingText"
- top_pad="5"
- width="158">
- Avatar rendering:
- </text>
- <check_box
- control_name="RenderUseImpostors"
+ </check_box>
+ <check_box
+ control_name="RenderDeferredSSAO"
height="16"
initial_value="true"
- label="Avatar impostors"
+ label="Ambient Occlusion"
layout="topleft"
left_delta="0"
- name="AvatarImpostors"
- top_pad="7"
- width="256" />
- <check_box
- control_name="RenderAvatarVP"
- height="16"
- initial_value="true"
- label="Hardware skinning"
- layout="topleft"
- left_delta="0"
- name="AvatarVertexProgram"
+ name="UseSSAO"
top_pad="1"
width="256">
- <check_box.commit_callback
+ <check_box.commit_callback
function="Pref.VertexShaderEnable" />
- </check_box>
- <check_box
- control_name="RenderAvatarCloth"
- height="16"
- initial_value="true"
- label="Avatar cloth"
- layout="topleft"
- left_delta="0"
- name="AvatarCloth"
- top_pad="1"
- width="256" />
+ </check_box>
+ <text
+ type="string"
+ length="1"
+ top_pad="8"
+ follows="top|left"
+ height="23"
+ width="110"
+ word_wrap="true"
+ layout="topleft"
+ left="10"
+ name="shadows_label">
+ Shadows:
+ </text>
+ <combo_box
+ control_name="RenderShadowDetail"
+ height="23"
+ layout="topleft"
+ left="10"
+ top_pad="0"
+ name="ShadowDetail"
+ width="150">
+ <combo_box.item
+ label="None"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Sun/Moon"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="Sun/Moon + Projectors"
+ name="2"
+ value="2"/>
+ </combo_box>
+
+ <text
+ type="string"
+ length="1"
+ top_pad="8"
+ follows="top|left"
+ height="23"
+ width="110"
+ word_wrap="true"
+ layout="topleft"
+ left="10"
+ name="reflection_label">
+ Water Reflections:
+ </text>
+ <combo_box
+ control_name="RenderReflectionDetail"
+ height="23"
+ layout="topleft"
+ left_="10"
+ top_pad ="0"
+ name="Reflections"
+ width="150">
+ <combo_box.item
+ label="Minimal"
+ name="0"
+ value="0"/>
+ <combo_box.item
+ label="Terrain and trees"
+ name="1"
+ value="1"/>
+ <combo_box.item
+ label="All static objects"
+ name="2"
+ value="2"/>
+ <combo_box.item
+ label="All avatars and objects"
+ name="3"
+ value="3"/>
+ <combo_box.item
+ label="Everything"
+ name="4"
+ value="4"/>
+ </combo_box>
+
<slider
control_name="RenderFarClip"
decimal_digits="0"
@@ -522,7 +514,7 @@
layout="topleft"
left="469"
name="PostProcessText"
- top="305"
+ top="328"
width="128">
Low
</text>
@@ -599,52 +591,61 @@
width="128">
Low
</text>
+ <text
+ type="string"
+ length="1"
+ follows="left|top"
+ height="12"
+ layout="topleft"
+ left_delta="-260"
+ name="AvatarRenderingText"
+ top_pad="8"
+ width="128">
+ Avatar rendering:
+ </text>
+ <check_box
+ control_name="RenderUseImpostors"
+ height="16"
+ initial_value="true"
+ label="Avatar impostors"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarImpostors"
+ top_pad="7"
+ width="256" />
+ <check_box
+ control_name="RenderAvatarVP"
+ height="16"
+ initial_value="true"
+ label="Hardware skinning"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarVertexProgram"
+ top_pad="1"
+ width="256">
+ <check_box.commit_callback
+ function="Pref.VertexShaderEnable" />
+ </check_box>
+ <check_box
+ control_name="RenderAvatarCloth"
+ height="16"
+ initial_value="true"
+ label="Avatar cloth"
+ layout="topleft"
+ left_delta="0"
+ name="AvatarCloth"
+ top_pad="1"
+ width="256" />
<text
type="string"
length="1"
follows="left|top"
height="12"
layout="topleft"
- left="200"
- name="LightingDetailText"
- top_pad="8"
- width="140">
- Lighting detail:
- </text>
- <radio_group
- control_name="RenderLightingDetail"
- draw_border="false"
- height="38"
- layout="topleft"
- name="LightingDetailRadio"
- top_pad="5"
- width="200">
- <radio_item
- height="16"
- label="Sun and moon only"
- layout="topleft"
- name="SunMoon"
- value="0"
- top="3"
- width="156" />
- <radio_item
- height="16"
- label="Nearby local lights"
- layout="topleft"
- name="LocalLights"
- value="1"
- top_delta="16"
- width="156" />
- </radio_group>
- <text
- type="string"
- length="1"
- follows="left|top"
- height="12"
- layout="topleft"
+ left="358"
left_pad="-30"
name="TerrainDetailText"
- top="465"
+ top="488"
width="155">
Terrain detail:
</text>
@@ -671,7 +672,7 @@
name="2"
top_delta="16"
width="50" />
- </radio_group>
+ </radio_group> -->
</panel>
<button