summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r--indra/newview/pipeline.cpp1288
1 files changed, 944 insertions, 344 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 15477e0a80..24327bf535 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -67,6 +67,7 @@
#include "llhudnametag.h"
#include "llhudtext.h"
#include "lllightconstants.h"
+#include "llmeshrepository.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llsky.h"
@@ -100,6 +101,7 @@
#include "llspatialpartition.h"
#include "llmutelist.h"
#include "lltoolpie.h"
+#include "llcurl.h"
#ifdef _DEBUG
@@ -267,6 +269,8 @@ BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE;
BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE;
BOOL LLPipeline::sDisableShaders = FALSE;
BOOL LLPipeline::sRenderBump = TRUE;
+BOOL LLPipeline::sBakeSunlight = FALSE;
+BOOL LLPipeline::sNoAlpha = FALSE;
BOOL LLPipeline::sUseTriStrips = TRUE;
BOOL LLPipeline::sUseFarClip = TRUE;
BOOL LLPipeline::sShadowRender = FALSE;
@@ -392,6 +396,14 @@ void LLPipeline::init()
toggleRenderType(RENDER_TYPE_GROUND);
}
+ // make sure RenderPerformanceTest persists (hackity hack hack)
+ // disables non-object rendering (UI, sky, water, etc)
+ if (gSavedSettings.getBOOL("RenderPerformanceTest"))
+ {
+ gSavedSettings.setBOOL("RenderPerformanceTest", FALSE);
+ gSavedSettings.setBOOL("RenderPerformanceTest", TRUE);
+ }
+
mOldRenderDebugMask = mRenderDebugMask;
mBackfaceCull = TRUE;
@@ -525,6 +537,22 @@ void LLPipeline::resizeScreenTexture()
}
}
+void LLPipeline::allocatePhysicsBuffer()
+{
+ GLuint resX = gViewerWindow->getWorldViewWidthRaw();
+ GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+
+ if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY)
+ {
+ mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
+ if (mSampleBuffer.getWidth() == mPhysicsDisplay.getWidth() &&
+ mSampleBuffer.getHeight() == mPhysicsDisplay.getHeight())
+ {
+ mPhysicsDisplay.setSampleBuffer(&mSampleBuffer);
+ }
+ }
+}
+
void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
{
// remember these dimensions
@@ -533,6 +561,11 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
//never use more than 4 samples for render targets
U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4);
+ if (gGLManager.mIsATI)
+ { //disable multisampling of render targets where ATI is involved
+ samples = 0;
+ }
+
U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor");
if (res_mod > 1 && res_mod < resX && res_mod < resY)
@@ -548,6 +581,10 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
if (LLPipeline::sRenderDeferred)
{
+ S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail");
+ BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO");
+ bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED);
+
//allocate deferred rendering color buffers
mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
@@ -556,14 +593,40 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
- for (U32 i = 0; i < 3; i++)
+ if (shadow_detail > 0 || ssao)
+ { //only need mDeferredLight[0] for shadows OR ssao
+ mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ }
+ else
{
- mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mDeferredLight[0].release();
}
- for (U32 i = 0; i < 2; i++)
+ if (ssao)
+ { //only need mDeferredLight[1] for ssao
+ mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ }
+ else
+ {
+ mDeferredLight[1].release();
+ }
+
+ if (gi)
+ { //only need mDeferredLight[2] and mGIMapPost for gi
+ mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ for (U32 i = 0; i < 2; i++)
+ {
+ mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ }
+ }
+ else
{
- mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ mDeferredLight[2].release();
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mGIMapPost[i].release();
+ }
}
F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale");
@@ -571,18 +634,37 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
//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++)
+ if (shadow_detail > 0)
+ { //allocate 4 sun shadow maps
+ for (U32 i = 0; i < 4; i++)
+ {
+ mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ }
+ }
+ else
{
- mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);
+ for (U32 i = 0; i < 4; i++)
+ {
+ mShadow[i].release();
+ }
}
-
U32 width = nhpo2(U32(resX*scale))/2;
U32 height = width;
- for (U32 i = 4; i < 6; i++)
+ if (shadow_detail > 1)
+ { //allocate two spot shadow maps
+ for (U32 i = 4; i < 6; i++)
+ {
+ mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE);
+ }
+ }
+ else
{
- mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE);
+ for (U32 i = 4; i < 6; i++)
+ {
+ mShadow[i].release();
+ }
}
width = nhpo2(resX)/2;
@@ -591,30 +673,55 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)
}
else
{
+ for (U32 i = 0; i < 3; i++)
+ {
+ mDeferredLight[i].release();
+ }
+ for (U32 i = 0; i < 2; i++)
+ {
+ mGIMapPost[i].release();
+ }
+ for (U32 i = 0; i < 6; i++)
+ {
+ mShadow[i].release();
+ }
+ mScreen.release();
+ mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
+ mDeferredDepth.release();
+ mEdgeMap.release();
+ mLuminanceMap.release();
+
mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);
}
-
- if (LLRenderTarget::sUseFBO && gGLManager.mHasFramebufferMultisample && samples > 1)
- {
+ if (LLRenderTarget::sUseFBO && samples > 1)
+ {
mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples);
if (LLPipeline::sRenderDeferred)
{
addDeferredAttachments(mSampleBuffer);
mDeferredScreen.setSampleBuffer(&mSampleBuffer);
+ mEdgeMap.setSampleBuffer(&mSampleBuffer);
}
mScreen.setSampleBuffer(&mSampleBuffer);
stop_glerror();
}
+ else
+ {
+ mSampleBuffer.release();
+ }
if (LLPipeline::sRenderDeferred)
{ //share depth buffer between deferred targets
mDeferredScreen.shareDepthBuffer(mScreen);
for (U32 i = 0; i < 3; i++)
{ //share stencil buffer with screen space lightmap to stencil out sky
- mDeferredScreen.shareDepthBuffer(mDeferredLight[i]);
+ if (mDeferredLight[i].getTexture(0))
+ {
+ mDeferredScreen.shareDepthBuffer(mDeferredLight[i]);
+ }
}
}
@@ -635,7 +742,11 @@ void LLPipeline::updateRenderDeferred()
gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) &&
!gUseWireframe;
- sRenderDeferred = deferred;
+ sRenderDeferred = deferred;
+ if (deferred)
+ { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all
+ sRenderGlow = TRUE;
+ }
}
void LLPipeline::releaseGLBuffers()
@@ -663,8 +774,9 @@ void LLPipeline::releaseGLBuffers()
mWaterRef.release();
mWaterDis.release();
mScreen.release();
+ mPhysicsDisplay.release();
mUIScreen.release();
- mSampleBuffer.releaseSampleBuffer();
+ mSampleBuffer.release();
mDeferredScreen.release();
mDeferredDepth.release();
for (U32 i = 0; i < 3; i++)
@@ -727,7 +839,6 @@ void LLPipeline::createGLBuffers()
allocateScreenBuffer(resX,resY);
mScreenWidth = 0;
mScreenHeight = 0;
-
}
if (sRenderDeferred)
@@ -871,7 +982,7 @@ BOOL LLPipeline::canUseWindLightShadersOnObjects() const
BOOL LLPipeline::canUseAntiAliasing() const
{
- return TRUE; //(gSavedSettings.getBOOL("RenderUseFBO"));
+ return TRUE;
}
void LLPipeline::unloadShaders()
@@ -913,7 +1024,7 @@ S32 LLPipeline::setLightingDetail(S32 level)
if (level < 0)
{
- if (gSavedSettings.getBOOL("VertexShaderEnable"))
+ if (gSavedSettings.getBOOL("RenderLocalLights"))
{
level = 1;
}
@@ -923,15 +1034,8 @@ S32 LLPipeline::setLightingDetail(S32 level)
}
}
level = llclamp(level, 0, getMaxLightingDetail());
- if (level != mLightingDetail)
- {
- mLightingDetail = level;
-
- if (mVertexShadersLoaded == 1)
- {
- LLViewerShaderMgr::instance()->setShaders();
- }
- }
+ mLightingDetail = level;
+
return mLightingDetail;
}
@@ -1157,9 +1261,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj)
}
+static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set");
+static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
+
void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
- LLFastTimer t(FTM_PIPELINE);
+ LLFastTimer t(FTM_UNLINK);
assertInitialized();
@@ -1168,6 +1278,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
// Based on flags, remove the drawable from the queues that it's on.
if (drawablep->isState(LLDrawable::ON_MOVE_LIST))
{
+ LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST);
LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
if (iter != mMovedList.end())
{
@@ -1177,6 +1288,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
if (drawablep->getSpatialGroup())
{
+ LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
{
#ifdef LL_RELEASE_FOR_DOWNLOAD
@@ -1187,18 +1299,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
}
- mLights.erase(drawablep);
- for (light_set_t::iterator iter = mNearbyLights.begin();
- iter != mNearbyLights.end(); iter++)
{
- if (iter->drawable == drawablep)
+ LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+ mLights.erase(drawablep);
+
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
{
- mNearbyLights.erase(iter);
- break;
+ if (iter->drawable == drawablep)
+ {
+ mNearbyLights.erase(iter);
+ break;
+ }
}
}
{
+ LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET);
HighlightItem item(drawablep);
mHighlightSet.erase(item);
@@ -1495,11 +1612,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera
return radius*radius * F_PI;
}
+//static
+F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera)
+{
+ LLVector4a origin;
+ origin.load3(camera.getOrigin().mV);
+
+ LLVector4a lookAt;
+ lookAt.setSub(center, origin);
+ F32 dist = lookAt.getLength3().getF32();
+
+ //ramp down distance for nearby objects
+ //shrink dist by dist/16.
+ if (dist < 16.f)
+ {
+ dist /= 16.f;
+ dist *= dist;
+ dist *= 16.f;
+ }
+
+ //get area of circle around node
+ F32 app_angle = atanf(size.getLength3().getF32()/dist);
+ F32 radius = app_angle*LLDrawable::sCurPixelAngle;
+ return radius*radius * F_PI;
+}
+
void LLPipeline::grabReferences(LLCullResult& result)
{
sCull = &result;
}
+void LLPipeline::clearReferences()
+{
+ sCull = NULL;
+}
+
+void check_references(LLSpatialGroup* group, LLDrawable* drawable)
+{
+ for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ {
+ if (drawable == *i)
+ {
+ llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;
+ }
+ }
+}
+
+void check_references(LLDrawable* drawable, LLFace* face)
+{
+ for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+ {
+ if (drawable->getFace(i) == face)
+ {
+ llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+}
+
+void check_references(LLSpatialGroup* group, LLFace* face)
+{
+ for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i)
+ {
+ LLDrawable* drawable = *i;
+ check_references(drawable, face);
+ }
+}
+
+void LLPipeline::checkReferences(LLFace* face)
+{
+#if 0
+ if (sCull)
+ {
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, face);
+ }
+
+ for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ {
+ LLDrawable* drawable = *iter;
+ check_references(drawable, face);
+ }
+ }
+#endif
+}
+
+void LLPipeline::checkReferences(LLDrawable* drawable)
+{
+#if 0
+ if (sCull)
+ {
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, drawable);
+ }
+
+ for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter)
+ {
+ if (drawable == *iter)
+ {
+ llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+ }
+#endif
+}
+
+void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
+{
+ for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
+ {
+ LLSpatialGroup::drawmap_elem_t& draw_vec = i->second;
+ for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j)
+ {
+ LLDrawInfo* params = *j;
+ if (params == draw_info)
+ {
+ llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+ }
+}
+
+
+void LLPipeline::checkReferences(LLDrawInfo* draw_info)
+{
+#if 0
+ if (sCull)
+ {
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ check_references(group, draw_info);
+ }
+ }
+#endif
+}
+
+void LLPipeline::checkReferences(LLSpatialGroup* group)
+{
+#if 0
+ if (sCull)
+ {
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter)
+ {
+ if (group == *iter)
+ {
+ llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ }
+ }
+ }
+#endif
+}
+
+
BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)
{
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
@@ -1695,7 +2015,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
}
if (sMinRenderSize > 0.f &&
- llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize)
+ llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize)
{
return;
}
@@ -1803,6 +2123,8 @@ void LLPipeline::rebuildPriorityGroups()
assertInitialized();
+ gMeshRepo.notifyLoadedMeshes();
+
// Iterate through all drawables on the priority build queue,
for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin();
iter != mGroupQ1.end(); ++iter)
@@ -1813,6 +2135,7 @@ void LLPipeline::rebuildPriorityGroups()
}
mGroupQ1.clear();
+
}
void LLPipeline::rebuildGroups()
@@ -1967,8 +2290,8 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
if(drawablep && !drawablep->isDead())
{
- if (drawablep->isSpatialBridge())
- {
+ if (drawablep->isSpatialBridge())
+ {
const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable;
llassert(root); // trying to catch a bad assumption
if (root && // // this test may not be needed, see above
@@ -1980,24 +2303,24 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
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;
- }
- }
+ 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)
@@ -2078,6 +2401,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
glClear(GL_DEPTH_BUFFER_BIT);
gDepthDirty = TRUE;
+ LLVector4a offseta;
+ offseta.load3(offset.mV);
+
for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
iter != mShiftList.end(); iter++)
{
@@ -2086,7 +2412,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
{
continue;
}
- drawablep->shiftPos(offset);
+ drawablep->shiftPos(offseta);
drawablep->clearState(LLDrawable::ON_SHIFT_LIST);
}
mShiftList.resize(0);
@@ -2100,7 +2426,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- part->shift(offset);
+ part->shift(offseta);
}
}
}
@@ -2132,8 +2458,7 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu)
void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
{
LLMemType mt(LLMemType::MTYPE_PIPELINE);
- //assert_main_thread();
-
+
if (group && !group->isDead() && group->mSpatialPartition)
{
if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD)
@@ -2635,8 +2960,10 @@ void LLPipeline::postSort(LLCamera& camera)
{
if (sMinRenderSize > 0.f)
{
- LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0];
- if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize)
+ LLVector4a bounds;
+ bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]);
+
+ if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize)
{
sCull->pushDrawInfo(j->first, *k);
}
@@ -3550,6 +3877,59 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
}
}
+void LLPipeline::renderPhysicsDisplay()
+{
+ if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+ {
+ return;
+ }
+
+ allocatePhysicsBuffer();
+
+ gGL.flush();
+ mPhysicsDisplay.bindTarget();
+ glClearColor(0,0,0,1);
+ gGL.setColorMask(true, true);
+ mPhysicsDisplay.clear();
+ glClearColor(0,0,0,0);
+
+ gGL.setColorMask(true, false);
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+ for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++)
+ {
+ LLSpatialPartition* part = region->getSpatialPartition(i);
+ if (part)
+ {
+ if (hasRenderType(part->mDrawableType))
+ {
+ part->renderPhysicsShapes();
+ }
+ }
+ }
+ }
+
+ for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
+ {
+ LLSpatialBridge* bridge = *i;
+ if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
+ {
+ glPushMatrix();
+ glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+ bridge->renderPhysicsShapes();
+ glPopMatrix();
+ }
+ }
+
+
+ gGL.flush();
+ mPhysicsDisplay.flush();
+}
+
+
void LLPipeline::renderDebug()
{
LLMemType mt(LLMemType::MTYPE_PIPELINE);
@@ -3592,8 +3972,67 @@ void LLPipeline::renderDebug()
}
}
+ if (gSavedSettings.getBOOL("DebugShowUploadCost"))
+ {
+ std::set<LLUUID> textures;
+ std::set<LLUUID> sculpts;
+ std::set<LLUUID> meshes;
+
+ BOOL selected = TRUE;
+ if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+ {
+ selected = FALSE;
+ }
+
+ for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+ LLSpatialGroup::OctreeNode* node = group->mOctreeNode;
+ for (LLSpatialGroup::OctreeNode::element_iter elem = node->getData().begin(); elem != node->getData().end(); ++elem)
+ {
+ LLDrawable* drawable = *elem;
+ LLVOVolume* volume = drawable->getVOVolume();
+ if (volume && volume->isSelected() == selected)
+ {
+ for (U32 i = 0; i < volume->getNumTEs(); ++i)
+ {
+ LLTextureEntry* te = volume->getTE(i);
+ textures.insert(te->getID());
+ }
+
+ if (volume->isSculpted())
+ {
+ LLUUID sculpt_id = volume->getVolume()->getParams().getSculptID();
+ if (volume->isMesh())
+ {
+ meshes.insert(sculpt_id);
+ }
+ else
+ {
+ sculpts.insert(sculpt_id);
+ }
+ }
+ }
+ }
+ }
+
+ gPipeline.mDebugTextureUploadCost = textures.size() * 10;
+ gPipeline.mDebugSculptUploadCost = sculpts.size()*10;
+
+ U32 mesh_cost = 0;
+
+ for (std::set<LLUUID>::iterator iter = meshes.begin(); iter != meshes.end(); ++iter)
+ {
+ mesh_cost += gMeshRepo.getResourceCost(*iter)*10;
+ }
+
+ gPipeline.mDebugMeshUploadCost = mesh_cost;
+ }
+
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
+ LLVertexBuffer::unbind();
+
LLGLEnable blend(GL_BLEND);
LLGLDepthTest depth(TRUE, FALSE);
LLGLDisable cull(GL_CULL_FACE);
@@ -3657,7 +4096,7 @@ void LLPipeline::renderDebug()
if (i < 4)
{
- if (i == 0 || !mShadowFrustPoints[i].empty())
+ //if (i == 0 || !mShadowFrustPoints[i].empty())
{
//render visible point cloud
gGL.flush();
@@ -3697,11 +4136,12 @@ void LLPipeline::renderDebug()
gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV);
gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV);
gGL.end();
- }
-
+ }
}
- /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ /*gGL.flush();
+ glLineWidth(16-i*2);
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
LLViewerRegion* region = *iter;
@@ -3716,7 +4156,9 @@ void LLPipeline::renderDebug()
}
}
}
- }*/
+ }
+ gGL.flush();
+ glLineWidth(1.f);*/
}
}
@@ -3803,6 +4245,8 @@ void LLPipeline::renderDebug()
}
gGL.flush();
+
+ gPipeline.renderPhysicsDisplay();
}
void LLPipeline::rebuildPools()
@@ -4208,7 +4652,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_
{
return max_dist;
}
- F32 dist = fsqrtf(dist2);
+ F32 dist = (F32) sqrt(dist2);
dist *= 1.f / inten;
dist -= radius;
if (selected)
@@ -4237,7 +4681,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
// mNearbyLight (and all light_set_t's) are sorted such that
// begin() == the closest light and rbegin() == the farthest light
const S32 MAX_LOCAL_LIGHTS = 6;
-// LLVector3 cam_pos = gAgentCamera.getCameraPositionAgent();
+// LLVector3 cam_pos = gAgent.getCameraPositionAgent();
LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ?
camera.getOrigin() :
gAgent.getPositionAgent();
@@ -4482,8 +4926,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV);
glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);
}
-
- if (isAgentAvatarValid() &&
+ if (gAgentAvatarp &&
gAgentAvatarp->mSpecialRenderMode == 3)
{
LLColor4 light_color = LLColor4::white;
@@ -4610,6 +5053,61 @@ void LLPipeline::enableLightsAvatar()
enableLights(mask);
}
+void LLPipeline::enableLightsPreview()
+{
+ disableLights();
+
+ glEnable(GL_LIGHTING);
+ LLColor4 ambient = gSavedSettings.getColor4("PreviewAmbientColor");
+ glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV);
+
+
+ LLColor4 diffuse0 = gSavedSettings.getColor4("PreviewDiffuse0");
+ LLColor4 specular0 = gSavedSettings.getColor4("PreviewSpecular0");
+ LLColor4 diffuse1 = gSavedSettings.getColor4("PreviewDiffuse1");
+ LLColor4 specular1 = gSavedSettings.getColor4("PreviewSpecular1");
+ LLColor4 diffuse2 = gSavedSettings.getColor4("PreviewDiffuse2");
+ LLColor4 specular2 = gSavedSettings.getColor4("PreviewSpecular2");
+
+ LLVector3 dir0 = gSavedSettings.getVector3("PreviewDirection0");
+ LLVector3 dir1 = gSavedSettings.getVector3("PreviewDirection1");
+ LLVector3 dir2 = gSavedSettings.getVector3("PreviewDirection2");
+
+ dir0.normVec();
+ dir1.normVec();
+ dir2.normVec();
+
+ LLVector4 light_pos(dir0, 0.0f);
+ glEnable(GL_LIGHT0);
+ glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV);
+ glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse0.mV);
+ glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV);
+ glLightfv(GL_LIGHT0, GL_SPECULAR, specular0.mV);
+ glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f);
+ glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f);
+
+ light_pos = LLVector4(dir1, 0.f);
+ glEnable(GL_LIGHT1);
+ glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV);
+ glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse1.mV);
+ glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV);
+ glLightfv(GL_LIGHT1, GL_SPECULAR, specular1.mV);
+ glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f);
+ glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f);
+
+ light_pos = LLVector4(dir2, 0.f);
+ glEnable(GL_LIGHT2);
+ glLightfv(GL_LIGHT2, GL_POSITION, light_pos.mV);
+ glLightfv(GL_LIGHT2, GL_DIFFUSE, diffuse2.mV);
+ glLightfv(GL_LIGHT2, GL_AMBIENT, LLColor4::black.mV);
+ glLightfv(GL_LIGHT2, GL_SPECULAR, specular2.mV);
+ glLightf (GL_LIGHT2, GL_SPOT_EXPONENT, 0.0f);
+ glLightf (GL_LIGHT2, GL_SPOT_CUTOFF, 180.0f);
+
+
+}
+
+
void LLPipeline::enableLightsAvatarEdit(const LLColor4& color)
{
U32 mask = 0x2002; // Avatar backlight only, set ambient
@@ -4901,6 +5399,18 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data)
return gPipeline.hasRenderDebugFeatureMask(bit);
}
+void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
+{
+ if (value)
+ {
+ gPipeline.mRenderDebugFeatureMask |= bit;
+ }
+ else
+ {
+ gPipeline.mRenderDebugFeatureMask &= !bit;
+ }
+}
+
// static
void LLPipeline::setRenderScriptedBeacons(BOOL val)
{
@@ -5243,6 +5753,8 @@ void LLPipeline::resetVertexBuffers()
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
+ sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight");
+ sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha");
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -5348,21 +5860,21 @@ void apply_cube_face_rotation(U32 face)
void validate_framebuffer_object()
{
GLenum status;
- status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT);
switch(status)
{
- case GL_FRAMEBUFFER_COMPLETE_EXT:
+ case GL_FRAMEBUFFER_COMPLETE:
//framebuffer OK, no error.
break;
- case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
+ case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
// frame buffer not OK: probably means unsupported depth buffer format
- llerrs << "Framebuffer Incomplete Dimensions." << llendl;
+ llerrs << "Framebuffer Incomplete Missing Attachment." << llendl;
break;
- case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
+ case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
// frame buffer not OK: probably means unsupported depth buffer format
llerrs << "Framebuffer Incomplete Attachment." << llendl;
break;
- case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
+ case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
llerrs << "Framebuffer unsupported." << llendl;
break;
@@ -5600,7 +6112,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
if (LLRenderTarget::sUseFBO)
{
LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, 0);
}
gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft;
@@ -5616,16 +6128,84 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
LLVertexBuffer::unbind();
- if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
+ if (LLPipeline::sRenderDeferred)
{
+ LLGLSLShader* shader = &gDeferredPostProgram;
+ if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
+ {
+ shader = &gDeferredGIFinalProgram;
+ }
+
LLGLDisable blend(GL_BLEND);
- bindDeferredShader(gDeferredGIFinalProgram);
+ bindDeferredShader(*shader);
+
+
+ //depth of field focal plane calculations
+
+ F32 subject_distance = 16.f;
+ if (LLViewerJoystick::getInstance()->getOverrideCamera())
+ {
+ //flycam mode, use mouse cursor as focus point
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ subject_distance = (eye-gDebugRaycastIntersection).magVec();
+ }
+ else
+ {
+ LLViewerObject* obj = gAgentCamera.getFocusObject();
+ if (obj)
+ {
+ LLVector3 focus = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+ LLVector3 eye = LLViewerCamera::getInstance()->getOrigin();
+ subject_distance = (focus-eye).magVec();
+ }
+ }
+
+ //convert to mm
+ subject_distance *= 1000.f;
+ F32 fnumber = gSavedSettings.getF32("CameraFNumber");
+ const F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength");
+
+ F32 fov = LLViewerCamera::getInstance()->getView();
+
+ const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f;
+ //const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio");
+
+ //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight();
+
+ F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f);
+ //F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f);
- S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
+ F32 focal_length = dv/(2*tanf(fov/2.f));
+
+ //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle);
+
+ // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f))
+ // where N = fnumber
+ // s2 = dot distance
+ // s1 = subject distance
+ // f = focal length
+ //
+
+ F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length));
+ blur_constant /= 1000.f; //convert to meters for shader
+ F32 magnification = focal_length/(subject_distance-focal_length);
+
+ shader->uniform1f("focal_distance", -subject_distance/1000.f);
+ shader->uniform1f("blur_constant", blur_constant);
+ shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle));
+ shader->uniform1f("magnification", magnification);
+
+ S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE);
if (channel > -1)
{
mScreen.bindTexture(0, channel);
+ gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+ //channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE);
+ //if (channel > -1)
+ //{
+ //gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
+ //}
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
@@ -5639,11 +6219,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.end();
- unbindDeferredShader(gDeferredGIFinalProgram);
+ unbindDeferredShader(*shader);
}
else
{
-
if (res_mod > 1)
{
tc2 /= (F32) res_mod;
@@ -5701,16 +6280,41 @@ 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);
- }
+ 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);
}
-
gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))
+ {
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2,
+ (F32) gViewerWindow->getWorldViewHeightRaw()*2);
+
+ LLGLEnable blend(GL_BLEND);
+ gGL.color4f(1,1,1,0.75f);
+
+ gGL.getTexUnit(0)->bind(&mPhysicsDisplay);
+
+ gGL.begin(LLRender::TRIANGLE_STRIP);
+ gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
+ gGL.vertex2f(-1,-1);
+
+ gGL.texCoord2f(tc1.mV[0], tc2.mV[1]);
+ gGL.vertex2f(-1,3);
+
+ gGL.texCoord2f(tc2.mV[0], tc1.mV[1]);
+ gGL.vertex2f(3,-1);
+
+ gGL.end();
+ gGL.flush();
+ }
+
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
@@ -6093,6 +6697,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen
shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight());
shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff"));
shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff"));
+
if (shader.getUniformLocation("norm_mat") >= 0)
{
@@ -6169,16 +6774,15 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);
}
- glPushMatrix();
- glLoadIdentity();
- glMatrixMode(GL_PROJECTION);
- glPushMatrix();
- glLoadIdentity();
-
- mDeferredLight[0].bindTarget();
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)
{
+ mDeferredLight[0].bindTarget();
{ //paint shadow/SSAO light map (direct lighting lightmap)
LLFastTimer ftm(FTM_SUN_SHADOW);
bindDeferredShader(gDeferredSunProgram, 0);
@@ -6219,16 +6823,9 @@ void LLPipeline::renderDeferredLighting()
unbindDeferredShader(gDeferredSunProgram);
}
- }
- else
- {
- glClearColor(1,1,1,1);
- mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT);
- glClearColor(0,0,0,0);
- }
-
mDeferredLight[0].flush();
-
+ }
+
{ //global illumination specific block (still experimental)
if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&
gSavedSettings.getBOOL("RenderDeferredGI"))
@@ -6271,7 +6868,7 @@ void LLPipeline::renderDeferredLighting()
mLuminanceMap.flush();
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
- glGenerateMipmapEXT(GL_TEXTURE_2D);
+ glGenerateMipmap(GL_TEXTURE_2D);
}
}
@@ -6334,75 +6931,74 @@ void LLPipeline::renderDeferredLighting()
}
if (gSavedSettings.getBOOL("RenderDeferredSSAO"))
- { //soften direct lighting lightmap
- LLFastTimer ftm(FTM_SOFTEN_SHADOW);
- //blur lightmap
- mDeferredLight[1].bindTarget();
+ { //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", 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();
}
+ mDeferredLight[0].flush();
+ unbindDeferredShader(gDeferredBlurLightProgram);
+ }
- stop_glerror();
- glPopMatrix();
- stop_glerror();
- glMatrixMode(GL_MODELVIEW);
- stop_glerror();
- glPopMatrix();
- stop_glerror();
+ 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(),
@@ -6468,10 +7064,8 @@ void LLPipeline::renderDeferredLighting()
gPipeline.popRenderTypeMask();
}
- BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
- BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights");
-
-
+ BOOL render_local = gSavedSettings.getBOOL("RenderLocalLights");
+
if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)
{
mDeferredLight[1].flush();
@@ -6479,7 +7073,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT);
}
- if (render_local || render_fullscreen)
+ if (render_local)
{
gGL.setSceneBlendType(LLRender::BT_ADD);
std::list<LLVector4> fullscreen_lights;
@@ -6493,10 +7087,11 @@ void LLPipeline::renderDeferredLighting()
std::list<LLVector4> light_colors;
+ LLVertexBuffer::unbind();
+
F32 v[24];
glVertexPointer(3, GL_FLOAT, 0, v);
- BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights");
-
+
{
bindDeferredShader(gDeferredLightProgram);
LLGLDepthTest depth(GL_TRUE, GL_FALSE);
@@ -6519,8 +7114,9 @@ void LLPipeline::renderDeferredLighting()
}
- LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
F32 s = volume->getLightRadius()*1.5f;
LLColor3 col = volume->getLightColor();
@@ -6536,7 +7132,9 @@ void LLPipeline::renderDeferredLighting()
continue;
}
- if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0)
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
{
continue;
}
@@ -6580,11 +7178,11 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
+ GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
stop_glerror();
}
}
- else if (render_fullscreen)
+ else
{
if (volume->isLightSpotlight())
{
@@ -6614,8 +7212,9 @@ void LLPipeline::renderDeferredLighting()
LLVOVolume* volume = drawablep->getVOVolume();
- LLVector3 center = drawablep->getPositionAgent();
- F32* c = center.mV;
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
F32 s = volume->getLightRadius()*1.5f;
sVisibleLightCount++;
@@ -6645,7 +7244,7 @@ void LLPipeline::renderDeferredLighting()
glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s);
glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f);
glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8,
- GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center));
+ GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center));
}
gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION);
unbindDeferredShader(gDeferredSpotLightProgram);
@@ -6687,9 +7286,7 @@ void LLPipeline::renderDeferredLighting()
if (count == max_count || fullscreen_lights.empty())
{
gDeferredMultiLightProgram.uniform1i("light_count", count);
- gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light);
gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light);
- gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col);
gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col);
gDeferredMultiLightProgram.uniform1f("far_z", far_z);
far_z = 0.f;
@@ -7058,11 +7655,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLCamera camera = camera_in;
camera.setFar(camera.getFar()*0.87654321f);
LLPipeline::sReflectionRender = TRUE;
- S32 occlusion = LLPipeline::sUseOcclusion;
-
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-
- LLPipeline::sUseOcclusion = llmin(occlusion, 1);
gPipeline.pushRenderTypeMask();
@@ -7101,19 +7693,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
glClearColor(0,0,0,0);
mWaterRef.bindTarget();
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
gGL.setColorMask(true, true);
mWaterRef.clear();
gGL.setColorMask(true, false);
mWaterRef.getViewport(gGLViewport);
-
+
stop_glerror();
glPushMatrix();
mat.set_scale(glh::vec3f(1,1,-1));
mat.set_translate(glh::vec3f(0,0,height*2.f));
-
+
glh::matrix4f current = glh_get_current_modelview();
mat = current * mat;
@@ -7133,22 +7726,24 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
glCullFace(GL_FRONT);
static LLCullResult ref_result;
-
+
if (LLDrawPoolWater::sNeedsDistortionUpdate)
{
//initial sky pass (no user clip plane)
{ //mask out everything but the sky
gPipeline.pushRenderTypeMask();
gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
static LLCullResult result;
updateCull(camera, result);
stateSort(camera, result);
+
andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::RENDER_TYPE_WL_SKY,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
renderGeom(camera, TRUE);
gPipeline.popRenderTypeMask();
@@ -7157,23 +7752,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
- LLPipeline::RENDER_TYPE_VOIDWATER,
- LLPipeline::RENDER_TYPE_GROUND,
- LLPipeline::RENDER_TYPE_SKY,
- LLPipeline::RENDER_TYPE_CLOUDS,
- LLPipeline::END_RENDER_TYPES);
+ LLPipeline::RENDER_TYPE_VOIDWATER,
+ LLPipeline::RENDER_TYPE_GROUND,
+ LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::END_RENDER_TYPES);
- S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
+ S32 detail = gSavedSettings.getS32("RenderReflectionDetail");
if (detail > 0)
{ //mask out selected geometry based on reflection detail
if (detail < 4)
{
clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
- if (detail < 3)
- {
- clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
- if (detail < 2)
+ if (detail < 3)
{
+ clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
+ if (detail < 2)
+ {
clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
}
}
@@ -7183,17 +7778,17 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLGLDisable cull(GL_CULL_FACE);
updateCull(camera, ref_result, 1);
stateSort(camera, ref_result);
- }
-
- if (LLDrawPoolWater::sNeedsDistortionUpdate)
- {
- if (gSavedSettings.getS32("RenderReflectionDetail") > 0)
+ }
+
+ 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();
}
@@ -7231,6 +7826,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLColor4& col = LLDrawPoolWater::sWaterFogColor;
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
mWaterDis.bindTarget();
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
mWaterDis.getViewport(gGLViewport);
if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate)
@@ -7267,8 +7863,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gPipeline.popRenderTypeMask();
LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
- LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd));
- LLPipeline::sUseOcclusion = occlusion;
+ LLPlane npnorm(-pnorm, -pd);
+ LLViewerCamera::getInstance()->setUserClipPlane(npnorm);
LLGLState::checkStates();
LLGLState::checkTextureChannels();
@@ -7278,6 +7874,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
}
+
+ LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
}
}
@@ -7400,6 +7998,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
//glCullFace(GL_FRONT);
+ LLVertexBuffer::unbind();
+
{
LLFastTimer ftm(FTM_SHADOW_SIMPLE);
LLGLDisable test(GL_ALPHA_TEST);
@@ -7467,14 +8067,13 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
}
//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)));
+ LLPlane bp[] = {
+ LLPlane(min, LLVector3(-1,0,0)),
+ LLPlane(min, LLVector3(0,-1,0)),
+ LLPlane(min, LLVector3(0,0,-1)),
+ LLPlane(max, LLVector3(1,0,0)),
+ LLPlane(max, LLVector3(0,1,0)),
+ LLPlane(max, LLVector3(0,0,1))};
//potential points
std::vector<LLVector3> pp;
@@ -7522,7 +8121,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
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 n;
+ cp.getVector3(n);
LLVector3 line = v1-v2;
@@ -7536,8 +8136,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
LLVector3 intersect = v2+line*t;
pp.push_back(intersect);
}
- }
}
+ }
//camera frustum line segments
const U32 fs[] =
@@ -7545,7 +8145,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
0,1,
1,2,
2,3,
- 3,1,
+ 3,0,
4,5,
5,6,
@@ -7568,7 +8168,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
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 n;
+ cp.getVector3(n);
LLVector3 line = v1-v2;
@@ -7583,7 +8184,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
pp.push_back(intersect);
}
}
- }
+ }
LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f),
max+LLVector3(0.05f,0.05f,0.05f) };
@@ -7947,6 +8548,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist");
//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
+ //put together a universal "near clip" plane for shadow frusta
+ LLPlane shadow_near_clip;
+ {
+ LLVector3 p = gAgent.getPositionAgent();
+ p += mSunDir * gSavedSettings.getF32("RenderFarClip")*2.f;
+ shadow_near_clip.setVec(p, mSunDir);
+ }
+
LLVector3 lightDir = -mSunDir;
lightDir.normVec();
@@ -8381,7 +8990,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
+ //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);
+ shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip);
//translate and scale to from [-1, 1] to [0, 1]
glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f,
@@ -8427,152 +9037,137 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
//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);
-
- //update shadow targets
- for (U32 i = 0; i < 2; i++)
- { //for each current shadow
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+ 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);
+
+ if (mShadowSpotLight[i].isNull())
+ {
+ continue;
+ }
- LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
+ LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume();
- if (!volume)
- {
- mShadowSpotLight[i] = NULL;
- continue;
- }
+ if (!volume)
+ {
+ mShadowSpotLight[i] = NULL;
+ continue;
+ }
- LLDrawable* drawable = mShadowSpotLight[i];
+ LLDrawable* drawable = mShadowSpotLight[i];
- LLVector3 params = volume->getSpotLightParams();
- F32 fov = params.mV[0];
+ LLVector3 params = volume->getSpotLightParams();
+ F32 fov = params.mV[0];
- //get agent->light space matrix (modelview)
- LLVector3 center = drawable->getPositionAgent();
- LLQuaternion quat = volume->getRenderRotation();
+ //get agent->light space matrix (modelview)
+ LLVector3 center = drawable->getPositionAgent();
+ LLQuaternion quat = volume->getRenderRotation();
- //get near clip plane
- LLVector3 scale = volume->getScale();
- LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
- at_axis *= quat;
+ //get near clip plane
+ LLVector3 scale = volume->getScale();
+ LLVector3 at_axis(0,0,-scale.mV[2]*0.5f);
+ at_axis *= quat;
- LLVector3 np = center+at_axis;
- at_axis.normVec();
+ LLVector3 np = center+at_axis;
+ at_axis.normVec();
- //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);
+ //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 origin = np - at_axis*dist;
+ LLVector3 origin = np - at_axis*dist;
- LLMatrix4 mat(quat, LLVector4(origin, 1.f));
+ LLMatrix4 mat(quat, LLVector4(origin, 1.f));
- view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
+ view[i+4] = glh::matrix4f((F32*) mat.mMatrix);
- view[i+4] = view[i+4].inverse();
+ view[i+4] = view[i+4].inverse();
- //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;
+ //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;
- F32 fovy = fov * RAD_TO_DEG;
- F32 aspect = width/height;
-
- proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
+ F32 fovy = fov * RAD_TO_DEG;
+ F32 aspect = width/height;
+
+ proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip);
- //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);
+ //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);
- glh_set_current_modelview(view[i+4]);
- glh_set_current_projection(proj[i+4]);
+ glh_set_current_modelview(view[i+4]);
+ glh_set_current_projection(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];
- }
+ 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];
+ }
- mShadowModelview[i+4] = view[i+4];
- mShadowProjection[i+4] = proj[i+4];
+ mShadowModelview[i+4] = view[i+4];
+ mShadowProjection[i+4] = proj[i+4];
- LLCamera shadow_cam = camera;
- shadow_cam.setFar(far_clip);
- shadow_cam.setOrigin(origin);
+ LLCamera shadow_cam = camera;
+ shadow_cam.setFar(far_clip);
+ shadow_cam.setOrigin(origin);
- LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
+ LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);
- stop_glerror();
+ 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();
- }
- }
- else
- {
- if (clear)
- {
- clear = false;
- for (U32 i = 4; i < 6; i++)
- {
- mShadow[i].bindTarget();
- mShadow[i].clear();
- mShadow[i].flush();
- }
- }
+ mShadow[i+4].flush();
+ }
}
if (!gSavedSettings.getBOOL("CameraOffset"))
@@ -8692,7 +9287,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
stateSort(*LLViewerCamera::getInstance(), result);
- const LLVector3* ext = avatar->mDrawable->getSpatialExtents();
+ const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
LLCamera camera = *viewer_camera;
@@ -8701,18 +9296,23 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLVector2 tdim;
- LLVector3 half_height = (ext[1]-ext[0])*0.5f;
- LLVector3 left = camera.getLeftAxis();
- left *= left;
- left.normalize();
+ LLVector4a half_height;
+ half_height.setSub(ext[1], ext[0]);
+ half_height.mul(0.5f);
+
+ LLVector4a left;
+ left.load3(camera.getLeftAxis().mV);
+ left.mul(left);
+ left.normalize3fast();
- LLVector3 up = camera.getUpAxis();
- up *= up;
- up.normalize();
+ LLVector4a up;
+ up.load3(camera.getUpAxis().mV);
+ up.mul(up);
+ up.normalize3fast();
- tdim.mV[0] = fabsf(half_height * left);
- tdim.mV[1] = fabsf(half_height * up);
+ tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
+ tdim.mV[1] = fabsf(half_height.dot3(up).getF32());
glMatrixMode(GL_PROJECTION);
glPushMatrix();