summaryrefslogtreecommitdiff
path: root/indra/newview/pipeline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rwxr-xr-x[-rw-r--r--]indra/newview/pipeline.cpp2391
1 files changed, 1875 insertions, 516 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9f0e2906d0..03712c1065 100644..100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -30,7 +30,6 @@
// library includes
#include "llaudioengine.h" // For debugging.
-#include "imageids.h"
#include "llerror.h"
#include "llviewercontrol.h"
#include "llfasttimer.h"
@@ -40,7 +39,6 @@
#include "llprimitive.h"
#include "llvolume.h"
#include "material_codes.h"
-#include "timing.h"
#include "v3color.h"
#include "llui.h"
#include "llglheaders.h"
@@ -71,6 +69,7 @@
#include "llhudtext.h"
#include "lllightconstants.h"
#include "llmeshrepository.h"
+#include "llpipelinelistener.h"
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llsky.h"
@@ -86,6 +85,7 @@
#include "llviewerregion.h" // for audio debugging.
#include "llviewerwindow.h" // For getSpinAxis
#include "llvoavatarself.h"
+#include "llvocache.h"
#include "llvoground.h"
#include "llvosky.h"
#include "llvotree.h"
@@ -110,7 +110,11 @@
#include "llpathinglib.h"
#include "llfloaterpathfindingconsole.h"
#include "llfloaterpathfindingcharacters.h"
+#include "llfloatertools.h"
+#include "llpanelface.h"
#include "llpathfindingpathtool.h"
+#include "llscenemonitor.h"
+#include "llprogressview.h"
#ifdef _DEBUG
// Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -119,6 +123,10 @@
//#define DEBUG_INDICES
#endif
+// Expensive and currently broken
+//
+#define MATERIALS_IN_REFLECTIONS 0
+
bool gShiftFrame = false;
//cached settings
@@ -162,6 +170,7 @@ S32 LLPipeline::RenderGlowIterations;
F32 LLPipeline::RenderGlowWidth;
F32 LLPipeline::RenderGlowStrength;
BOOL LLPipeline::RenderDepthOfField;
+BOOL LLPipeline::RenderDepthOfFieldInEditMode;
F32 LLPipeline::CameraFocusTransitionTime;
F32 LLPipeline::CameraFNumber;
F32 LLPipeline::CameraFocalLength;
@@ -196,16 +205,11 @@ BOOL LLPipeline::CameraOffset;
F32 LLPipeline::CameraMaxCoF;
F32 LLPipeline::CameraDoFResScale;
F32 LLPipeline::RenderAutoHideSurfaceAreaLimit;
+LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize");
-const F32 BACKLIGHT_DAY_MAGNITUDE_AVATAR = 0.2f;
-const F32 BACKLIGHT_NIGHT_MAGNITUDE_AVATAR = 0.1f;
const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f;
const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f;
-const S32 MAX_OFFSCREEN_GEOMETRY_CHANGES_PER_FRAME = 10;
-const U32 REFLECTION_MAP_RES = 128;
const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1;
-// Max number of occluders to search for. JC
-const S32 MAX_OCCLUDER_COUNT = 2;
extern S32 gBoxFrame;
//extern BOOL gHideSelectedObjects;
@@ -218,39 +222,51 @@ BOOL gDebugPipeline = FALSE;
LLPipeline gPipeline;
const LLMatrix4* gGLLastMatrix = NULL;
-LLFastTimer::DeclareTimer FTM_RENDER_GEOMETRY("Render Geometry");
-LLFastTimer::DeclareTimer FTM_RENDER_GRASS("Grass");
-LLFastTimer::DeclareTimer FTM_RENDER_INVISIBLE("Invisible");
-LLFastTimer::DeclareTimer FTM_RENDER_OCCLUSION("Occlusion");
-LLFastTimer::DeclareTimer FTM_RENDER_SHINY("Shiny");
-LLFastTimer::DeclareTimer FTM_RENDER_SIMPLE("Simple");
-LLFastTimer::DeclareTimer FTM_RENDER_TERRAIN("Terrain");
-LLFastTimer::DeclareTimer FTM_RENDER_TREES("Trees");
-LLFastTimer::DeclareTimer FTM_RENDER_UI("UI");
-LLFastTimer::DeclareTimer FTM_RENDER_WATER("Water");
-LLFastTimer::DeclareTimer FTM_RENDER_WL_SKY("Windlight Sky");
-LLFastTimer::DeclareTimer FTM_RENDER_ALPHA("Alpha Objects");
-LLFastTimer::DeclareTimer FTM_RENDER_CHARACTERS("Avatars");
-LLFastTimer::DeclareTimer FTM_RENDER_BUMP("Bump");
-LLFastTimer::DeclareTimer FTM_RENDER_FULLBRIGHT("Fullbright");
-LLFastTimer::DeclareTimer FTM_RENDER_GLOW("Glow");
-LLFastTimer::DeclareTimer FTM_GEO_UPDATE("Geo Update");
-LLFastTimer::DeclareTimer FTM_PIPELINE_CREATE("Pipeline Create");
-LLFastTimer::DeclareTimer FTM_POOLRENDER("RenderPool");
-LLFastTimer::DeclareTimer FTM_POOLS("Pools");
-LLFastTimer::DeclareTimer FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
-LLFastTimer::DeclareTimer FTM_DEFERRED_POOLS("Pools (Deferred)");
-LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
-LLFastTimer::DeclareTimer FTM_POST_DEFERRED_POOLS("Pools (Post)");
-LLFastTimer::DeclareTimer FTM_RENDER_BLOOM_FBO("First FBO");
-LLFastTimer::DeclareTimer FTM_STATESORT("Sort Draw State");
-LLFastTimer::DeclareTimer FTM_PIPELINE("Pipeline");
-LLFastTimer::DeclareTimer FTM_CLIENT_COPY("Client Copy");
-LLFastTimer::DeclareTimer FTM_RENDER_DEFERRED("Deferred Shading");
-
-
-static LLFastTimer::DeclareTimer FTM_STATESORT_DRAWABLE("Sort Drawables");
-static LLFastTimer::DeclareTimer FTM_STATESORT_POSTSORT("Post Sort");
+LLTrace::BlockTimerStatHandle FTM_RENDER_GEOMETRY("Render Geometry");
+LLTrace::BlockTimerStatHandle FTM_RENDER_GRASS("Grass");
+LLTrace::BlockTimerStatHandle FTM_RENDER_INVISIBLE("Invisible");
+LLTrace::BlockTimerStatHandle FTM_RENDER_OCCLUSION("Occlusion");
+LLTrace::BlockTimerStatHandle FTM_RENDER_SHINY("Shiny");
+LLTrace::BlockTimerStatHandle FTM_RENDER_SIMPLE("Simple");
+LLTrace::BlockTimerStatHandle FTM_RENDER_TERRAIN("Terrain");
+LLTrace::BlockTimerStatHandle FTM_RENDER_TREES("Trees");
+LLTrace::BlockTimerStatHandle FTM_RENDER_UI("UI");
+LLTrace::BlockTimerStatHandle FTM_RENDER_WATER("Water");
+LLTrace::BlockTimerStatHandle FTM_RENDER_WL_SKY("Windlight Sky");
+LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA("Alpha Objects");
+LLTrace::BlockTimerStatHandle FTM_RENDER_CHARACTERS("Avatars");
+LLTrace::BlockTimerStatHandle FTM_RENDER_BUMP("Bump");
+LLTrace::BlockTimerStatHandle FTM_RENDER_MATERIALS("Render Materials");
+LLTrace::BlockTimerStatHandle FTM_RENDER_FULLBRIGHT("Fullbright");
+LLTrace::BlockTimerStatHandle FTM_RENDER_GLOW("Glow");
+LLTrace::BlockTimerStatHandle FTM_GEO_UPDATE("Geo Update");
+LLTrace::BlockTimerStatHandle FTM_PIPELINE_CREATE("Pipeline Create");
+LLTrace::BlockTimerStatHandle FTM_POOLRENDER("RenderPool");
+LLTrace::BlockTimerStatHandle FTM_POOLS("Pools");
+LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLRENDER("RenderPool (Deferred)");
+LLTrace::BlockTimerStatHandle FTM_DEFERRED_POOLS("Pools (Deferred)");
+LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLRENDER("RenderPool (Post)");
+LLTrace::BlockTimerStatHandle FTM_POST_DEFERRED_POOLS("Pools (Post)");
+LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM_FBO("First FBO");
+LLTrace::BlockTimerStatHandle FTM_STATESORT("Sort Draw State");
+LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline");
+LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy");
+LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading");
+
+
+static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables");
+static LLTrace::BlockTimerStatHandle FTM_STATESORT_POSTSORT("Post Sort");
+
+static LLStaticHashedString sTint("tint");
+static LLStaticHashedString sAmbiance("ambiance");
+static LLStaticHashedString sAlphaScale("alpha_scale");
+static LLStaticHashedString sNormMat("norm_mat");
+static LLStaticHashedString sOffset("offset");
+static LLStaticHashedString sScreenRes("screenRes");
+static LLStaticHashedString sDelta("delta");
+static LLStaticHashedString sDistFactor("dist_factor");
+static LLStaticHashedString sKern("kern");
+static LLStaticHashedString sKernScale("kern_scale");
//----------------------------------------
std::string gPoolNames[] =
@@ -261,10 +277,13 @@ std::string gPoolNames[] =
"POOL_GROUND",
"POOL_FULLBRIGHT",
"POOL_BUMP",
+ "POOL_MATERIALS",
"POOL_TERRAIN,"
"POOL_SKY",
"POOL_WL_SKY",
"POOL_TREE",
+ "POOL_ALPHA_MASK",
+ "POOL_FULLBRIGHT_ALPHA_MASK",
"POOL_GRASS",
"POOL_INVISIBLE",
"POOL_AVATAR",
@@ -274,7 +293,7 @@ std::string gPoolNames[] =
"POOL_ALPHA"
};
-void drawBox(const LLVector3& c, const LLVector3& r);
+void drawBox(const LLVector4a& c, const LLVector4a& r);
void drawBoxOutline(const LLVector3& pos, const LLVector3& size);
U32 nhpo2(U32 v);
LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage);
@@ -351,6 +370,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE;
BOOL LLPipeline::sRenderSoundBeacons = FALSE;
BOOL LLPipeline::sRenderBeacons = FALSE;
BOOL LLPipeline::sRenderHighlight = TRUE;
+LLRender::eTexIndex LLPipeline::sRenderHighlightTextureChannel = LLRender::DIFFUSE_MAP;
BOOL LLPipeline::sForceOldBakedUpload = FALSE;
S32 LLPipeline::sUseOcclusion = 0;
BOOL LLPipeline::sDelayVBUpdate = TRUE;
@@ -367,6 +387,7 @@ BOOL LLPipeline::sWaterReflections = FALSE;
BOOL LLPipeline::sRenderGlow = FALSE;
BOOL LLPipeline::sReflectionRender = FALSE;
BOOL LLPipeline::sImpostorRender = FALSE;
+BOOL LLPipeline::sImpostorRenderAlphaDepthPass = FALSE;
BOOL LLPipeline::sUnderWaterRender = FALSE;
BOOL LLPipeline::sTextureBindTest = FALSE;
BOOL LLPipeline::sRenderFrameTest = FALSE;
@@ -376,42 +397,27 @@ BOOL LLPipeline::sRenderDeferred = FALSE;
BOOL LLPipeline::sMemAllocationThrottled = FALSE;
S32 LLPipeline::sVisibleLightCount = 0;
F32 LLPipeline::sMinRenderSize = 0.f;
+BOOL LLPipeline::sRenderingHUDs;
+// EventHost API LLPipeline listener.
+static LLPipelineListener sPipelineListener;
static LLCullResult* sCull = NULL;
-static const U32 gl_cube_face[] =
-{
- GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB,
- GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB,
- GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB,
-};
-
void validate_framebuffer_object();
bool addDeferredAttachments(LLRenderTarget& target)
{
- return target.addColorAttachment(GL_RGBA) && //specular
- target.addColorAttachment(GL_RGBA); //normal+z
+ return target.addColorAttachment(GL_SRGB8_ALPHA8) && //specular
+ target.addColorAttachment(GL_RGB10_A2); //normal+z
}
LLPipeline::LLPipeline() :
mBackfaceCull(FALSE),
- mBatchCount(0),
mMatrixOpCount(0),
mTextureMatrixOps(0),
- mMaxBatchSize(0),
- mMinBatchSize(0),
- mMeanBatchSize(0),
- mTrianglesDrawn(0),
mNumVisibleNodes(0),
- mVerticesRelit(0),
- mLightingChanges(0),
- mGeometryChanges(0),
mNumVisibleFaces(0),
mInitialized(FALSE),
@@ -432,10 +438,14 @@ LLPipeline::LLPipeline() :
mWaterPool(NULL),
mGroundPool(NULL),
mSimplePool(NULL),
+ mGrassPool(NULL),
+ mAlphaMaskPool(NULL),
+ mFullbrightAlphaMaskPool(NULL),
mFullbrightPool(NULL),
mInvisiblePool(NULL),
mGlowPool(NULL),
mBumpPool(NULL),
+ mMaterialsPool(NULL),
mWLSkyPool(NULL),
mLightMask(0),
mLightMovingMask(0),
@@ -453,7 +463,7 @@ void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name)
LLPointer<LLControlVariable> cntrl_ptr = gSavedSettings.getControl(name);
if ( cntrl_ptr.isNull() )
{
- llwarns << "Global setting name not found:" << name << llendl;
+ LL_WARNS() << "Global setting name not found:" << name << LL_ENDL;
}
else
{
@@ -466,6 +476,7 @@ void LLPipeline::init()
refreshCachedSettings();
gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity");
+ gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize");
sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");
sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
@@ -482,28 +493,40 @@ void LLPipeline::init()
//create render pass pools
getPool(LLDrawPool::POOL_ALPHA);
getPool(LLDrawPool::POOL_SIMPLE);
+ getPool(LLDrawPool::POOL_ALPHA_MASK);
+ getPool(LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK);
getPool(LLDrawPool::POOL_GRASS);
getPool(LLDrawPool::POOL_FULLBRIGHT);
getPool(LLDrawPool::POOL_INVISIBLE);
getPool(LLDrawPool::POOL_BUMP);
+ getPool(LLDrawPool::POOL_MATERIALS);
getPool(LLDrawPool::POOL_GLOW);
- LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
resetFrameStats();
- for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
{
- mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+ clearAllRenderDebugFeatures();
}
+ else
+ {
+ setAllRenderDebugFeatures(); // By default, all debugging features on
+ }
+ clearAllRenderDebugDisplays(); // All debug displays off
- mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
- mRenderDebugMask = 0; // All debug starts off
-
- // Don't turn on ground when this is set
- // Mac Books with intel 950s need this
- if(!gSavedSettings.getBOOL("RenderGround"))
+ if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
+ {
+ clearAllRenderTypes();
+ }
+ else
{
- toggleRenderType(RENDER_TYPE_GROUND);
+ setAllRenderTypes(); // By default, all rendering types start enabled
+ // Don't turn on ground when this is set
+ // Mac Books with intel 950s need this
+ if(!gSavedSettings.getBOOL("RenderGround"))
+ {
+ toggleRenderType(RENDER_TYPE_GROUND);
+ }
}
// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -589,6 +612,7 @@ void LLPipeline::init()
connectRefreshCachedSettingsSafe("RenderGlowWidth");
connectRefreshCachedSettingsSafe("RenderGlowStrength");
connectRefreshCachedSettingsSafe("RenderDepthOfField");
+ connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
connectRefreshCachedSettingsSafe("CameraFNumber");
connectRefreshCachedSettingsSafe("CameraFocalLength");
@@ -663,11 +687,11 @@ void LLPipeline::cleanup()
if (!mTerrainPools.empty())
{
- llwarns << "Terrain Pools not cleaned up" << llendl;
+ LL_WARNS() << "Terrain Pools not cleaned up" << LL_ENDL;
}
if (!mTreePools.empty())
{
- llwarns << "Tree Pools not cleaned up" << llendl;
+ LL_WARNS() << "Tree Pools not cleaned up" << LL_ENDL;
}
delete mAlphaPool;
@@ -733,7 +757,7 @@ void LLPipeline::destroyGL()
}
}
-static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
+static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
//static
void LLPipeline::throttleNewMemoryAllocation(BOOL disable)
@@ -755,20 +779,28 @@ void LLPipeline::throttleNewMemoryAllocation(BOOL disable)
void LLPipeline::resizeScreenTexture()
{
- LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE);
+ LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE);
if (gPipeline.canUseVertexShaders() && assertInitialized())
{
GLuint resX = gViewerWindow->getWorldViewWidthRaw();
GLuint resY = gViewerWindow->getWorldViewHeightRaw();
+ if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight()))
+ {
+ releaseScreenBuffers();
if (!allocateScreenBuffer(resX,resY))
- { //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
+ {
+#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE
+ //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled
//NOTE: if the session closes successfully after this call, deferred rendering will be
// disabled on future sessions
if (LLPipeline::sRenderDeferred)
{
gSavedSettings.setBOOL("RenderDeferred", FALSE);
LLPipeline::refreshCachedSettings();
+
+ }
+#endif
}
}
}
@@ -868,7 +900,7 @@ LLPipeline::eFBOStatus LLPipeline::doAllocateScreenBuffer(U32 resX, U32 resY)
releaseScreenBuffers();
}
- llwarns << "Unable to allocate screen buffer at any resolution!" << llendl;
+ LL_WARNS() << "Unable to allocate screen buffer at any resolution!" << LL_ENDL;
}
return ret;
@@ -903,12 +935,26 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
S32 shadow_detail = RenderShadowDetail;
BOOL ssao = RenderDeferredSSAO;
+ const U32 occlusion_divisor = 3;
+
//allocate deferred rendering color buffers
- if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mDeferredScreen.allocate(resX, resY, GL_SRGB8_ALPHA8, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ if (!mOcclusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (!addDeferredAttachments(mDeferredScreen)) return false;
- if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
+ GLuint screenFormat = GL_RGBA16;
+ if (gGLManager.mIsATI)
+ {
+ screenFormat = GL_RGBA12;
+ }
+
+ if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA)
+ {
+ screenFormat = GL_RGBA16F_ARB;
+ }
+
+ if (!mScreen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false;
if (samples > 0)
{
if (!mFXAABuffer.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false;
@@ -935,6 +981,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false;
}
}
else
@@ -942,6 +989,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 4; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -954,6 +1002,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false;
+ if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false;
}
}
else
@@ -961,6 +1010,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 4; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -977,11 +1027,13 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
mFXAABuffer.release();
mScreen.release();
mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first
mDeferredDepth.release();
+ mOcclusionDepth.release();
if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false;
}
@@ -999,11 +1051,18 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)
}
//static
+void LLPipeline::updateRenderBump()
+{
+ sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+}
+
+//static
void LLPipeline::updateRenderDeferred()
{
BOOL deferred = ((RenderDeferred &&
LLRenderTarget::sUseFBO &&
LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&
+ LLPipeline::sRenderBump &&
VertexShaderEnable &&
RenderAvatarVP &&
WindLightUseAtmosShaders) ? TRUE : FALSE) &&
@@ -1072,6 +1131,7 @@ void LLPipeline::refreshCachedSettings()
RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
+ RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
CameraFNumber = gSavedSettings.getF32("CameraFNumber");
CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
@@ -1116,13 +1176,13 @@ void LLPipeline::releaseGLBuffers()
if (mNoiseMap)
{
- LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mNoiseMap);
+ LLImageGL::deleteTextures(1, &mNoiseMap);
mNoiseMap = 0;
}
if (mTrueNoiseMap)
{
- LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 0, 1, &mTrueNoiseMap);
+ LLImageGL::deleteTextures(1, &mTrueNoiseMap);
mTrueNoiseMap = 0;
}
@@ -1130,6 +1190,7 @@ void LLPipeline::releaseGLBuffers()
mWaterRef.release();
mWaterDis.release();
+ mHighlight.release();
for (U32 i = 0; i < 3; i++)
{
@@ -1146,7 +1207,7 @@ void LLPipeline::releaseLUTBuffers()
{
if (mLightFunc)
{
- LLImageGL::deleteTextures(LLTexUnit::TT_TEXTURE, GL_R8, 0, 1, &mLightFunc);
+ LLImageGL::deleteTextures(1, &mLightFunc);
mLightFunc = 0;
}
}
@@ -1160,12 +1221,12 @@ void LLPipeline::releaseScreenBuffers()
mDeferredScreen.release();
mDeferredDepth.release();
mDeferredLight.release();
-
- mHighlight.release();
+ mOcclusionDepth.release();
for (U32 i = 0; i < 6; i++)
{
mShadow[i].release();
+ mShadowOcclusion[i].release();
}
}
@@ -1177,14 +1238,31 @@ void LLPipeline::createGLBuffers()
updateRenderDeferred();
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (LLPipeline::sWaterReflections)
{ //water reflection texture
U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512);
+ // Set up SRGB targets if we're doing deferred-path reflection rendering
+ //
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE);
+ //always use FBO for mWaterDis so it can be used for avatar texture bakes
+ mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
+ }
+ else
+ {
mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE);
//always use FBO for mWaterDis so it can be used for avatar texture bakes
mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true);
}
+ }
mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE);
@@ -1223,7 +1301,7 @@ void LLPipeline::createGLBuffers()
noise[i].mV[2] = ll_frand()*scaler+1.f-scaler/2.f;
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mNoiseMap);
+ LLImageGL::generateTextures(1, &mNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap);
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise, false);
@@ -1239,7 +1317,7 @@ void LLPipeline::createGLBuffers()
noise[i] = ll_frand()*2.0-1.0;
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_RGB16F_ARB, 1, &mTrueNoiseMap);
+ LLImageGL::generateTextures(1, &mTrueNoiseMap);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap);
LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise, false);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
@@ -1251,6 +1329,11 @@ void LLPipeline::createGLBuffers()
gBumpImageList.restoreGL();
}
+F32 lerpf(F32 a, F32 b, F32 w)
+{
+ return a + w * (b - a);
+}
+
void LLPipeline::createLUTBuffers()
{
if (sRenderDeferred)
@@ -1259,9 +1342,9 @@ void LLPipeline::createLUTBuffers()
{
U32 lightResX = gSavedSettings.getU32("RenderSpecularResX");
U32 lightResY = gSavedSettings.getU32("RenderSpecularResY");
- U8* ls = new U8[lightResX*lightResY];
+ F32* ls = new F32[lightResX*lightResY];
F32 specExp = gSavedSettings.getF32("RenderSpecularExponent");
- // Calculate the (normalized) Blinn-Phong specular lookup texture.
+ // Calculate the (normalized) blinn-phong specular lookup texture. (with a few tweaks)
for (U32 y = 0; y < lightResY; ++y)
{
for (U32 x = 0; x < lightResX; ++x)
@@ -1277,29 +1360,27 @@ void LLPipeline::createLUTBuffers()
// Apply our normalization function.
// Note: This is the full equation that applies the full normalization curve, not an approximation.
// This is fine, given we only need to create our LUT once per buffer initialization.
- // The only trade off is we have a really low dynamic range.
- // This means we have to account for things not being able to exceed 0 to 1 in our shaders.
spec *= (((n + 2) * (n + 4)) / (8 * F_PI * (powf(2, -n/2) + n)));
-
- // Always sample at a 1.0/2.2 curve.
- // This "Gamma corrects" our specular term, boosting our lower exponent reflections.
- spec = powf(spec, 1.f/2.2f);
-
- // Easy fix for our dynamic range problem: divide by 6 here, multiply by 6 in our shaders.
- // This allows for our specular term to exceed a value of 1 in our shaders.
- // This is something that can be important for energy conserving specular models where higher exponents can result in highlights that exceed a range of 0 to 1.
- // Technically, we could just use an R16F texture, but driver support for R16F textures can be somewhat spotty at times.
- // This works remarkably well for higher specular exponents, though banding can sometimes be seen on lower exponents.
- // Combined with a bit of noise and trilinear filtering, the banding is hardly noticable.
- ls[y*lightResX+x] = (U8)(llclamp(spec * (1.f / 6), 0.f, 1.f) * 255);
+
+ // Since we use R16F, we no longer have a dynamic range issue we need to work around here.
+ // Though some older drivers may not like this, newer drivers shouldn't have this problem.
+ ls[y*lightResX+x] = spec;
}
}
- LLImageGL::generateTextures(LLTexUnit::TT_TEXTURE, GL_R8, 1, &mLightFunc);
+ U32 pix_format = GL_R16F;
+#if LL_DARWIN
+ // Need to work around limited precision with 10.6.8 and older drivers
+ //
+ pix_format = GL_R32F;
+#endif
+ LLImageGL::generateTextures(1, &mLightFunc);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc);
- LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls, false);
+ LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, pix_format, lightResX, lightResY, GL_RED, GL_FLOAT, ls, false);
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
delete [] ls;
}
@@ -1377,7 +1458,7 @@ void LLPipeline::unloadShaders()
void LLPipeline::assertInitializedDoError()
{
- llerrs << "LLPipeline used when uninitialized." << llendl;
+ LL_ERRS() << "LLPipeline used when uninitialized." << LL_ENDL;
}
//============================================================================
@@ -1420,18 +1501,18 @@ S32 LLPipeline::setLightingDetail(S32 level)
return mLightingDetail;
}
-class LLOctreeDirtyTexture : public LLOctreeTraveler<LLDrawable>
+class LLOctreeDirtyTexture : public OctreeTraveler
{
public:
const std::set<LLViewerFetchedTexture*>& mTextures;
LLOctreeDirtyTexture(const std::set<LLViewerFetchedTexture*>& textures) : mTextures(textures) { }
- virtual void visit(const LLOctreeNode<LLDrawable>* node)
+ virtual void visit(const OctreeNode* node)
{
LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
- if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
+ if (!group->hasState(LLSpatialGroup::GEOM_DIRTY) && !group->isEmpty())
{
for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i)
{
@@ -1503,6 +1584,14 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
poolp = mGrassPool;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ poolp = mAlphaMaskPool;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ poolp = mFullbrightAlphaMaskPool;
+ break;
+
case LLDrawPool::POOL_FULLBRIGHT:
poolp = mFullbrightPool;
break;
@@ -1526,7 +1615,9 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
case LLDrawPool::POOL_BUMP:
poolp = mBumpPool;
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ poolp = mMaterialsPool;
+ break;
case LLDrawPool::POOL_ALPHA:
poolp = mAlphaPool;
break;
@@ -1552,7 +1643,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerTexture *tex0)
default:
llassert(0);
- llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl;
+ LL_ERRS() << "Invalid Pool Type in LLPipeline::findPool() type=" << type << LL_ENDL;
break;
}
@@ -1590,20 +1681,44 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima
return 0;
}
- bool alpha = te->getColor().mV[3] < 0.999f;
+ LLMaterial* mat = te->getMaterialParams().get();
+
+ bool color_alpha = te->getColor().mV[3] < 0.999f;
+ bool alpha = color_alpha;
if (imagep)
{
alpha = alpha || (imagep->getComponents() == 4 && imagep->getType() != LLViewerTexture::MEDIA_TEXTURE) || (imagep->getComponents() == 2);
}
+ if (alpha && mat)
+ {
+ switch (mat->getDiffuseAlphaMode())
+ {
+ case 1:
+ alpha = true; // Material's alpha mode is set to blend. Toss it into the alpha draw pool.
+ break;
+ case 0: //alpha mode set to none, never go to alpha pool
+ case 3: //alpha mode set to emissive, never go to alpha pool
+ alpha = color_alpha;
+ break;
+ default: //alpha mode set to "mask", go to alpha pool if fullbright
+ alpha = color_alpha; // Material's alpha mode is set to none, mask, or emissive. Toss it into the opaque material draw pool.
+ break;
+ }
+ }
+
if (alpha)
{
return LLDrawPool::POOL_ALPHA;
}
- else if ((te->getBumpmap() || te->getShiny()))
+ else if ((te->getBumpmap() || te->getShiny()) && (!mat || mat->getNormalID().isNull()))
{
return LLDrawPool::POOL_BUMP;
}
+ else if (mat && !alpha)
+ {
+ return LLDrawPool::POOL_MATERIALS;
+ }
else
{
return LLDrawPool::POOL_SIMPLE;
@@ -1620,11 +1735,9 @@ void LLPipeline::addPool(LLDrawPool *new_poolp)
void LLPipeline::allocDrawable(LLViewerObject *vobj)
{
- LLDrawable *drawable = new LLDrawable();
+ LLDrawable *drawable = new LLDrawable(vobj);
vobj->mDrawable = drawable;
- drawable->mVObjp = vobj;
-
//encompass completely sheared objects by taking
//the most extreme point possible (<1,1,0.5>)
drawable->setRadius(LLVector3(1,1,0.5f).scaleVec(vobj->getScale()).length());
@@ -1636,15 +1749,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");
+static LLTrace::BlockTimerStatHandle FTM_UNLINK("Unlink");
+static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_MOVE_LIST("Movelist");
+static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition");
+static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_LIGHT_SET("Light Set");
+static LLTrace::BlockTimerStatHandle FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set");
void LLPipeline::unlinkDrawable(LLDrawable *drawable)
{
- LLFastTimer t(FTM_UNLINK);
+ LL_RECORD_BLOCK_TIME(FTM_UNLINK);
assertInitialized();
@@ -1653,7 +1766,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);
+ LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_MOVE_LIST);
LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep);
if (iter != mMovedList.end())
{
@@ -1663,19 +1776,19 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
if (drawablep->getSpatialGroup())
{
- LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION);
- if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup()))
+ LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_SPATIAL_PARTITION);
+ if (!drawablep->getSpatialGroup()->getSpatialPartition()->remove(drawablep, drawablep->getSpatialGroup()))
{
#ifdef LL_RELEASE_FOR_DOWNLOAD
- llwarns << "Couldn't remove object from spatial group!" << llendl;
+ LL_WARNS() << "Couldn't remove object from spatial group!" << LL_ENDL;
#else
- llerrs << "Couldn't remove object from spatial group!" << llendl;
+ LL_ERRS() << "Couldn't remove object from spatial group!" << LL_ENDL;
#endif
}
}
{
- LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+ LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET);
mLights.erase(drawablep);
for (light_set_t::iterator iter = mNearbyLights.begin();
@@ -1690,7 +1803,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
}
{
- LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET);
+ LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_HIGHLIGHT_SET);
HighlightItem item(drawablep);
mHighlightSet.erase(item);
@@ -1719,7 +1832,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
//static
void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
{
- LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET);
+ LL_RECORD_BLOCK_TIME(FTM_REMOVE_FROM_LIGHT_SET);
for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
iter != gPipeline.mNearbyLights.end(); iter++)
{
@@ -1747,7 +1860,7 @@ U32 LLPipeline::addObject(LLViewerObject *vobj)
void LLPipeline::createObjects(F32 max_dtime)
{
- LLFastTimer ftm(FTM_PIPELINE_CREATE);
+ LL_RECORD_BLOCK_TIME(FTM_PIPELINE_CREATE);
LLTimer update_timer;
@@ -1779,7 +1892,7 @@ void LLPipeline::createObject(LLViewerObject* vobj)
}
else
{
- llerrs << "Redundant drawable creation!" << llendl;
+ LL_ERRS() << "Redundant drawable creation!" << LL_ENDL;
}
llassert(drawablep);
@@ -1810,17 +1923,7 @@ void LLPipeline::resetFrameStats()
{
assertInitialized();
- LLViewerStats::getInstance()->mTrianglesDrawnStat.addValue(mTrianglesDrawn/1000.f);
-
- if (mBatchCount > 0)
- {
- mMeanBatchSize = gPipeline.mTrianglesDrawn/gPipeline.mBatchCount;
- }
- mTrianglesDrawn = 0;
sCompiles = 0;
- mVerticesRelit = 0;
- mLightingChanges = 0;
- mGeometryChanges = 0;
mNumVisibleFaces = 0;
if (mOldRenderDebugMask != mRenderDebugMask)
@@ -1828,7 +1931,6 @@ void LLPipeline::resetFrameStats()
gObjectList.clearDebugText();
mOldRenderDebugMask = mRenderDebugMask;
}
-
}
//external functions for asynchronous updating
@@ -1840,7 +1942,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep)
}
if (!drawablep)
{
- llerrs << "updateMove called with NULL drawablep" << llendl;
+ LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
return;
}
if (drawablep->isState(LLDrawable::EARLY_MOVE))
@@ -1870,7 +1972,7 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep)
}
if (!drawablep)
{
- llerrs << "updateMove called with NULL drawablep" << llendl;
+ LL_ERRS() << "updateMove called with NULL drawablep" << LL_ENDL;
return;
}
if (drawablep->isState(LLDrawable::EARLY_MOVE))
@@ -1927,12 +2029,14 @@ void LLPipeline::updateMovedList(LLDrawable::drawable_vector_t& moved_list)
}
}
-static LLFastTimer::DeclareTimer FTM_OCTREE_BALANCE("Balance Octree");
-static LLFastTimer::DeclareTimer FTM_UPDATE_MOVE("Update Move");
+static LLTrace::BlockTimerStatHandle FTM_OCTREE_BALANCE("Balance Octree");
+static LLTrace::BlockTimerStatHandle FTM_UPDATE_MOVE("Update Move");
+static LLTrace::BlockTimerStatHandle FTM_RETEXTURE("Retexture");
+static LLTrace::BlockTimerStatHandle FTM_MOVED_LIST("Moved List");
void LLPipeline::updateMove()
{
- LLFastTimer t(FTM_UPDATE_MOVE);
+ LL_RECORD_BLOCK_TIME(FTM_UPDATE_MOVE);
if (FreezeTime)
{
@@ -1942,8 +2046,7 @@ void LLPipeline::updateMove()
assertInitialized();
{
- static LLFastTimer::DeclareTimer ftm("Retexture");
- LLFastTimer t(ftm);
+ LL_RECORD_BLOCK_TIME(FTM_RETEXTURE);
for (LLDrawable::drawable_set_t::iterator iter = mRetexturedList.begin();
iter != mRetexturedList.end(); ++iter)
@@ -1958,14 +2061,13 @@ void LLPipeline::updateMove()
}
{
- static LLFastTimer::DeclareTimer ftm("Moved List");
- LLFastTimer t(ftm);
+ LL_RECORD_BLOCK_TIME(FTM_MOVED_LIST);
updateMovedList(mMovedList);
}
//balance octrees
{
- LLFastTimer ot(FTM_OCTREE_BALANCE);
+ LL_RECORD_BLOCK_TIME(FTM_OCTREE_BALANCE);
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
@@ -1979,6 +2081,13 @@ void LLPipeline::updateMove()
part->mOctree->balance();
}
}
+
+ //balance the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->mOctree->balance();
+ }
}
}
}
@@ -2048,9 +2157,9 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- if (drawable == *i)
+ if (drawable == (LLDrawable*)(*i)->getDrawable())
{
- llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl;
+ LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL;
}
}
}
@@ -2061,7 +2170,7 @@ void check_references(LLDrawable* drawable, LLFace* face)
{
if (drawable->getFace(i) == face)
{
- llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLFace deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
}
@@ -2070,10 +2179,13 @@ void check_references(LLSpatialGroup* group, LLFace* face)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawable = *i;
+ LLDrawable* drawable = (LLDrawable*)(*i)->getDrawable();
+ if(drawable)
+ {
check_references(drawable, face);
}
}
+}
void LLPipeline::checkReferences(LLFace* face)
{
@@ -2134,7 +2246,7 @@ void LLPipeline::checkReferences(LLDrawable* drawable)
{
if (drawable == *iter)
{
- llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLDrawable deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
}
@@ -2151,7 +2263,7 @@ void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info)
LLDrawInfo* params = *j;
if (params == draw_info)
{
- llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLDrawInfo deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
}
@@ -2193,7 +2305,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
{
if (group == *iter)
{
- llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
@@ -2201,7 +2313,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
{
if (group == *iter)
{
- llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
@@ -2209,7 +2321,7 @@ void LLPipeline::checkReferences(LLSpatialGroup* group)
{
if (group == *iter)
{
- llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl;
+ LL_ERRS() << "LLSpatialGroup deleted while actively referenced by LLPipeline." << LL_ENDL;
}
}
}
@@ -2250,7 +2362,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
min = LLVector3(X,X,X);
max = LLVector3(-X,-X,-X);
- U32 saved_camera_id = LLViewerCamera::sCurCameraID;
+ LLViewerCamera::eCameraID saved_camera_id = LLViewerCamera::sCurCameraID;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
BOOL res = TRUE;
@@ -2281,11 +2393,16 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3&
return res;
}
-static LLFastTimer::DeclareTimer FTM_CULL("Object Culling");
+static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling");
void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep)
{
- LLFastTimer t(FTM_CULL);
+ static LLCachedControl<bool> use_occlusion(gSavedSettings,"UseOcclusion");
+ static bool can_use_occlusion = LLGLSLShader::sNoFixedFunction
+ && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion")
+ && gGLManager.mHasOcclusionQuery;
+
+ LL_RECORD_BLOCK_TIME(FTM_CULL);
grabReferences(result);
@@ -2299,7 +2416,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.bindTarget();
+ if (LLPipeline::sRenderDeferred)
+ {
+ mOcclusionDepth.bindTarget();
+ }
+ else
+ {
+ mScreen.bindTarget();
+ }
}
if (sUseOcclusion > 1)
@@ -2395,6 +2519,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
}
}
}
+
+ //scan the VO Cache tree
+ LLVOCachePartition* vo_part = region->getVOCachePartition();
+ if(vo_part)
+ {
+ bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe/* && !gViewerWindow->getProgressView()->getVisible()*/;
+ vo_part->cull(camera, do_occlusion_cull);
+ }
}
if (bound_shader)
@@ -2437,7 +2569,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl
if (to_texture)
{
- mScreen.flush();
+ if (LLPipeline::sRenderDeferred)
+ {
+ mOcclusionDepth.flush();
+ }
+ else
+ {
+ mScreen.flush();
+ }
}
}
@@ -2462,15 +2601,16 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera)
return;
}
+ const LLVector4a* bounds = group->getBounds();
if (sMinRenderSize > 0.f &&
- llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize)
+ llmax(llmax(bounds[1][0], bounds[1][1]), bounds[1][2]) < sMinRenderSize)
{
return;
}
assertInitialized();
- if (!group->mSpatialPartition->mRenderByGroup)
+ if (!group->getSpatialPartition()->mRenderByGroup)
{ //render by drawable
sCull->pushDrawableGroup(group);
}
@@ -2505,9 +2645,77 @@ void LLPipeline::markOccluder(LLSpatialGroup* group)
}
}
+void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ LLGLSLShader* last_shader = LLGLSLShader::sCurBoundShaderPtr;
+
+ LLGLSLShader* shader = NULL;
+
+ if (scratch_space)
+ {
+ scratch_space->copyContents(source,
+ 0, 0, source.getWidth(), source.getHeight(),
+ 0, 0, scratch_space->getWidth(), scratch_space->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ dest.bindTarget();
+ dest.clear(GL_DEPTH_BUFFER_BIT);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+ LLStrider<LLVector2> tc0;
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ if (source.getUsage() == LLTexUnit::TT_RECT_TEXTURE)
+ {
+ shader = &gDownsampleDepthRectProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f, 1.f);
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, source.getWidth(), source.getHeight());
+ }
+ else
+ {
+ shader = &gDownsampleDepthProgram;
+ shader->bind();
+ shader->uniform2f(sDelta, 1.f/source.getWidth(), 1.f/source.getHeight());
+ shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, 1.f, 1.f);
+ }
+
+ gGL.getTexUnit(0)->bind(scratch_space ? scratch_space : &source, TRUE);
+
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ dest.flush();
+
+ if (last_shader)
+ {
+ last_shader->bind();
+ }
+ else
+ {
+ shader->unbind();
+ }
+}
+
+void LLPipeline::doOcclusion(LLCamera& camera, LLRenderTarget& source, LLRenderTarget& dest, LLRenderTarget* scratch_space)
+{
+ downsampleDepthBuffer(source, dest, scratch_space);
+ dest.bindTarget();
+ doOcclusion(camera);
+ dest.flush();
+}
+
void LLPipeline::doOcclusion(LLCamera& camera)
{
- if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups())
+ if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested &&
+ (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck))
{
LLVertexBuffer::unbind();
@@ -2553,6 +2761,17 @@ void LLPipeline::doOcclusion(LLCamera& camera)
group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION);
}
+ //apply occlusion culling to object cache tree
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLVOCachePartition* vo_part = (*iter)->getVOCachePartition();
+ if(vo_part)
+ {
+ vo_part->processOccluders(&camera);
+ }
+ }
+
if (bind_shader)
{
if (LLPipeline::sShadowRender)
@@ -2575,19 +2794,18 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority)
if (update_complete && assertInitialized())
{
drawablep->setState(LLDrawable::BUILT);
- mGeometryChanges++;
}
return update_complete;
}
-static LLFastTimer::DeclareTimer FTM_SEED_VBO_POOLS("Seed VBO Pool");
+static LLTrace::BlockTimerStatHandle FTM_SEED_VBO_POOLS("Seed VBO Pool");
-static LLFastTimer::DeclareTimer FTM_UPDATE_GL("Update GL");
+static LLTrace::BlockTimerStatHandle FTM_UPDATE_GL("Update GL");
void LLPipeline::updateGL()
{
{
- LLFastTimer t(FTM_UPDATE_GL);
+ LL_RECORD_BLOCK_TIME(FTM_UPDATE_GL);
while (!LLGLUpdate::sGLQ.empty())
{
LLGLUpdate* glu = LLGLUpdate::sGLQ.front();
@@ -2598,12 +2816,12 @@ void LLPipeline::updateGL()
}
{ //seed VBO Pools
- LLFastTimer t(FTM_SEED_VBO_POOLS);
+ LL_RECORD_BLOCK_TIME(FTM_SEED_VBO_POOLS);
LLVertexBuffer::seedPools();
}
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
+static LLTrace::BlockTimerStatHandle FTM_REBUILD_PRIORITY_GROUPS("Rebuild Priority Groups");
void LLPipeline::clearRebuildGroups()
{
@@ -2663,9 +2881,55 @@ void LLPipeline::clearRebuildGroups()
mGroupQ2Locked = false;
}
+void LLPipeline::clearRebuildDrawables()
+{
+ // Clear all drawables on the priority build queue,
+ for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin();
+ iter != mBuildQ1.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+ if (drawablep && !drawablep->isDead())
+ {
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q1);
+ }
+ }
+ mBuildQ1.clear();
+
+ // clear drawables on the non-priority build queue
+ for (LLDrawable::drawable_list_t::iterator iter = mBuildQ2.begin();
+ iter != mBuildQ2.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+ if (!drawablep->isDead())
+ {
+ drawablep->clearState(LLDrawable::IN_REBUILD_Q2);
+ }
+ }
+ mBuildQ2.clear();
+
+ //clear all moving bridges
+ for (LLDrawable::drawable_vector_t::iterator iter = mMovedBridge.begin();
+ iter != mMovedBridge.end(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
+ }
+ mMovedBridge.clear();
+
+ //clear all moving drawables
+ for (LLDrawable::drawable_vector_t::iterator iter = mMovedList.begin();
+ iter != mMovedList.end(); ++iter)
+ {
+ LLDrawable *drawablep = *iter;
+ drawablep->clearState(LLDrawable::EARLY_MOVE | LLDrawable::MOVE_UNDAMPED | LLDrawable::ON_MOVE_LIST | LLDrawable::ANIMATED_CHILD);
+ }
+ mMovedList.clear();
+}
+
void LLPipeline::rebuildPriorityGroups()
{
- LLFastTimer t(FTM_REBUILD_PRIORITY_GROUPS);
+ LL_RECORD_BLOCK_TIME(FTM_REBUILD_PRIORITY_GROUPS);
LLTimer update_timer;
assertInitialized();
@@ -2687,7 +2951,7 @@ void LLPipeline::rebuildPriorityGroups()
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_GROUPS("Rebuild Groups");
+static LLTrace::BlockTimerStatHandle FTM_REBUILD_GROUPS("Rebuild Groups");
void LLPipeline::rebuildGroups()
{
@@ -2696,7 +2960,7 @@ void LLPipeline::rebuildGroups()
return;
}
- LLFastTimer t(FTM_REBUILD_GROUPS);
+ LL_RECORD_BLOCK_TIME(FTM_REBUILD_GROUPS);
mGroupQ2Locked = true;
// Iterate through some drawables on the non-priority build queue
S32 size = (S32) mGroupQ2.size();
@@ -2719,7 +2983,7 @@ void LLPipeline::rebuildGroups()
{
group->rebuildGeom();
- if (group->mSpatialPartition->mRenderByGroup)
+ if (group->getSpatialPartition()->mRenderByGroup)
{
count++;
}
@@ -2740,7 +3004,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
LLTimer update_timer;
LLPointer<LLDrawable> drawablep;
- LLFastTimer t(FTM_GEO_UPDATE);
+ LL_RECORD_BLOCK_TIME(FTM_GEO_UPDATE);
assertInitialized();
@@ -2788,7 +3052,7 @@ void LLPipeline::updateGeom(F32 max_dtime)
S32 count = 0;
- max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, max_dtime);
+ max_dtime = llmax(update_timer.getElapsedTimeF32()+0.001f, F32SecondsImplicit(max_dtime));
LLSpatialGroup* last_group = NULL;
LLSpatialBridge* last_bridge = NULL;
@@ -2848,7 +3112,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
llassert(vobj); // trying to catch a bad assumption
if (vobj) // this test may not be needed, see above
{
- const LLVOAvatar* av = vobj->asAvatar();
+ LLVOAvatar* av = vobj->asAvatar();
if (av && av->isImpostor())
{
return;
@@ -2872,13 +3136,13 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion)
{
if (!drawablep)
{
- //llerrs << "Sending null drawable to moved list!" << llendl;
+ //LL_ERRS() << "Sending null drawable to moved list!" << LL_ENDL;
return;
}
if (drawablep->isDead())
{
- llwarns << "Marking NULL or dead drawable moved!" << llendl;
+ LL_WARNS() << "Marking NULL or dead drawable moved!" << LL_ENDL;
return;
}
@@ -2933,9 +3197,9 @@ void LLPipeline::markShift(LLDrawable *drawablep)
}
}
-static LLFastTimer::DeclareTimer FTM_SHIFT_DRAWABLE("Shift Drawable");
-static LLFastTimer::DeclareTimer FTM_SHIFT_OCTREE("Shift Octree");
-static LLFastTimer::DeclareTimer FTM_SHIFT_HUD("Shift HUD");
+static LLTrace::BlockTimerStatHandle FTM_SHIFT_DRAWABLE("Shift Drawable");
+static LLTrace::BlockTimerStatHandle FTM_SHIFT_OCTREE("Shift Octree");
+static LLTrace::BlockTimerStatHandle FTM_SHIFT_HUD("Shift HUD");
void LLPipeline::shiftObjects(const LLVector3 &offset)
{
@@ -2948,7 +3212,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
offseta.load3(offset.mV);
{
- LLFastTimer t(FTM_SHIFT_DRAWABLE);
+ LL_RECORD_BLOCK_TIME(FTM_SHIFT_DRAWABLE);
for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin();
iter != mShiftList.end(); iter++)
@@ -2966,7 +3230,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
{
- LLFastTimer t(FTM_SHIFT_OCTREE);
+ LL_RECORD_BLOCK_TIME(FTM_SHIFT_OCTREE);
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
{
@@ -2983,7 +3247,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset)
}
{
- LLFastTimer t(FTM_SHIFT_HUD);
+ LL_RECORD_BLOCK_TIME(FTM_SHIFT_HUD);
LLHUDText::shiftAll(offset);
LLHUDNameTag::shiftAll(offset);
}
@@ -3017,10 +3281,10 @@ void LLPipeline::markPartitionMove(LLDrawable* drawable)
}
}
-static LLFastTimer::DeclareTimer FTM_PROCESS_PARTITIONQ("PartitionQ");
+static LLTrace::BlockTimerStatHandle FTM_PROCESS_PARTITIONQ("PartitionQ");
void LLPipeline::processPartitionQ()
{
- LLFastTimer t(FTM_PROCESS_PARTITIONQ);
+ LL_RECORD_BLOCK_TIME(FTM_PROCESS_PARTITIONQ);
for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter)
{
LLDrawable* drawable = *iter;
@@ -3042,23 +3306,23 @@ void LLPipeline::markMeshDirty(LLSpatialGroup* group)
void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
{
- if (group && !group->isDead() && group->mSpatialPartition)
+ if (group && !group->isDead() && group->getSpatialPartition())
{
- if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD)
+ if (group->getSpatialPartition()->mPartitionType == LLViewerRegion::PARTITION_HUD)
{
priority = TRUE;
}
if (priority)
{
- if (!group->isState(LLSpatialGroup::IN_BUILD_Q1))
+ if (!group->hasState(LLSpatialGroup::IN_BUILD_Q1))
{
llassert_always(!mGroupQ1Locked);
mGroupQ1.push_back(group);
group->setState(LLSpatialGroup::IN_BUILD_Q1);
- if (group->isState(LLSpatialGroup::IN_BUILD_Q2))
+ if (group->hasState(LLSpatialGroup::IN_BUILD_Q2))
{
LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group);
if (iter != mGroupQ2.end())
@@ -3069,7 +3333,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority)
}
}
}
- else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
+ else if (!group->hasState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1))
{
llassert_always(!mGroupQ2Locked);
mGroupQ2.push_back(group);
@@ -3108,7 +3372,7 @@ void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags f
}
}
-static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order");
+static LLTrace::BlockTimerStatHandle FTM_RESET_DRAWORDER("Reset Draw Order");
void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
{
@@ -3122,11 +3386,11 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
LLPipeline::END_RENDER_TYPES))
{
//clear faces from face pools
- LLFastTimer t(FTM_RESET_DRAWORDER);
+ LL_RECORD_BLOCK_TIME(FTM_RESET_DRAWORDER);
gPipeline.resetDrawOrders();
}
- LLFastTimer ftm(FTM_STATESORT);
+ LL_RECORD_BLOCK_TIME(FTM_STATESORT);
//LLVertexBuffer::unbind();
@@ -3144,7 +3408,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
group->setVisible();
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- markVisible(*i, camera);
+ markVisible((LLDrawable*)(*i)->getDrawable(), camera);
}
if (!sDelayVBUpdate)
@@ -3210,7 +3474,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)
}
{
- LLFastTimer ftm(FTM_STATESORT_DRAWABLE);
+ LL_RECORD_BLOCK_TIME(FTM_STATESORT_DRAWABLE);
for (LLCullResult::drawable_iterator iter = sCull->beginVisibleList();
iter != sCull->endVisibleList(); ++iter)
{
@@ -3231,8 +3495,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera)
{
for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
{
- LLDrawable* drawablep = *i;
- stateSort(drawablep, camera);
+ stateSort((LLDrawable*)(*i)->getDrawable(), camera);
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3293,11 +3556,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
{
drawablep->setVisible(camera, NULL, FALSE);
}
- else if (drawablep->isState(LLDrawable::CLEAR_INVISIBLE))
- {
- // clear invisible flag here to avoid single frame glitch
- drawablep->clearState(LLDrawable::FORCE_INVISIBLE|LLDrawable::CLEAR_INVISIBLE);
- }
}
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
@@ -3338,7 +3596,6 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera)
}
}
-
mNumVisibleFaces += drawablep->getNumFaces();
}
@@ -3351,7 +3608,10 @@ void forAllDrawables(LLCullResult::sg_iterator begin,
{
for (LLSpatialGroup::element_iter j = (*i)->getDataBegin(); j != (*i)->getDataEnd(); ++j)
{
- func(*j);
+ if((*j)->hasDrawable())
+ {
+ func((LLDrawable*)(*j)->getDrawable());
+ }
}
}
}
@@ -3544,11 +3804,11 @@ void renderSoundHighlights(LLDrawable* drawablep)
void LLPipeline::postSort(LLCamera& camera)
{
- LLFastTimer ftm(FTM_STATESORT_POSTSORT);
+ LL_RECORD_BLOCK_TIME(FTM_STATESORT_POSTSORT);
assertInitialized();
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
//rebuild drawable geometry
for (LLCullResult::sg_iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i)
{
@@ -3559,27 +3819,27 @@ void LLPipeline::postSort(LLCamera& camera)
group->rebuildGeom();
}
}
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
//rebuild groups
sCull->assertDrawMapsEmpty();
rebuildPriorityGroups();
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
//build render map
for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i)
{
LLSpatialGroup* group = *i;
- if (sUseOcclusion &&
- group->isOcclusionState(LLSpatialGroup::OCCLUDED) ||
+ if ((sUseOcclusion &&
+ group->isOcclusionState(LLSpatialGroup::OCCLUDED)) ||
(RenderAutoHideSurfaceAreaLimit > 0.f &&
group->mSurfaceArea > RenderAutoHideSurfaceAreaLimit*llmax(group->mObjectBoxSize, 10.f)))
{
continue;
}
- if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY))
+ if (group->hasState(LLSpatialGroup::NEW_DRAWINFO) && group->hasState(LLSpatialGroup::GEOM_DIRTY))
{ //no way this group is going to be drawable without a rebuild
group->rebuildGeom();
}
@@ -3617,7 +3877,7 @@ void LLPipeline::postSort(LLCamera& camera)
if (alpha != group->mDrawMap.end())
{ //store alpha groups for sorting
- LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD)
{
if (bridge)
@@ -3675,7 +3935,7 @@ void LLPipeline::postSort(LLCamera& camera)
std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
}
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender)
{
@@ -3728,7 +3988,7 @@ void LLPipeline::postSort(LLCamera& camera)
forAllVisibleDrawables(renderSoundHighlights);
}
}
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
if (LLFloaterTelehub::renderBeacons())
{
@@ -3738,7 +3998,9 @@ void LLPipeline::postSort(LLCamera& camera)
if (!sShadowRender)
{
mSelectedFaces.clear();
-
+
+ LLPipeline::setRenderHighlightTextureChannel(gFloaterTools->getPanelFace()->getTextureChannelToEdit());
+
// Draw face highlights for selected faces.
if (LLSelectMgr::getInstance()->getTEMode())
{
@@ -3761,41 +4023,14 @@ void LLPipeline::postSort(LLCamera& camera)
}
}
- /*static LLFastTimer::DeclareTimer FTM_TRANSFORM_WAIT("Transform Fence");
- static LLFastTimer::DeclareTimer FTM_TRANSFORM_DO_WORK("Transform Work");
- if (use_transform_feedback)
- { //using transform feedback, wait for transform feedback to complete
- LLFastTimer t(FTM_TRANSFORM_WAIT);
-
- S32 done = 0;
- //glGetQueryivARB(GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, GL_CURRENT_QUERY, &count);
-
- glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
-
- while (!done)
- {
- {
- LLFastTimer t(FTM_TRANSFORM_DO_WORK);
- F32 max_time = llmin(gFrameIntervalSeconds*10.f, 1.f);
- //do some useful work while we wait
- LLAppViewer::getTextureCache()->update(max_time); // unpauses the texture cache thread
- LLAppViewer::getImageDecodeThread()->update(max_time); // unpauses the image thread
- LLAppViewer::getTextureFetch()->update(max_time); // unpauses the texture fetch thread
- }
- glGetQueryObjectivARB(mMeshDirtyQueryObject, GL_QUERY_RESULT_AVAILABLE, &done);
- }
-
- mTransformFeedbackPrimitives = 0;
- }*/
-
//LLSpatialGroup::sNoDelete = FALSE;
- llpushcallstacks ;
+ LL_PUSH_CALLSTACKS();
}
void render_hud_elements()
{
- LLFastTimer t(FTM_RENDER_UI);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_UI);
gPipeline.disableLights();
LLGLDisable fog(GL_FOG);
@@ -3961,13 +4196,14 @@ void LLPipeline::renderHighlights()
gGL.diffuseColor4f(1,1,1,0.5f);
}
- if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED))
- {
- // Make sure the selection image gets downloaded and decoded
- if (!mFaceSelectImagep)
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && !mFaceSelectImagep)
{
mFaceSelectImagep = LLViewerTextureManager::getFetchedTexture(IMG_FACE_SELECT);
}
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::DIFFUSE_MAP))
+ {
+ // Make sure the selection image gets downloaded and decoded
mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
U32 count = mSelectedFaces.size();
@@ -3976,7 +4212,7 @@ void LLPipeline::renderHighlights()
LLFace *facep = mSelectedFaces[i];
if (!facep || facep->getDrawable()->isDead())
{
- llerrs << "Bad face on selection" << llendl;
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
return;
}
@@ -4005,6 +4241,67 @@ void LLPipeline::renderHighlights()
{
gHighlightProgram.unbind();
}
+
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP))
+ {
+ color.setVec(1.0f, 0.5f, 0.5f, 0.5f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightNormalProgram.unbind();
+ }
+ }
+
+ if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP))
+ {
+ color.setVec(0.0f, 0.3f, 1.0f, 0.8f);
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.bind();
+ gGL.diffuseColor4f(1,1,1,0.5f);
+ }
+
+ mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA);
+
+ U32 count = mSelectedFaces.size();
+ for (U32 i = 0; i < count; i++)
+ {
+ LLFace *facep = mSelectedFaces[i];
+ if (!facep || facep->getDrawable()->isDead())
+ {
+ LL_ERRS() << "Bad face on selection" << LL_ENDL;
+ return;
+ }
+
+ facep->renderSelected(mFaceSelectImagep, color);
+ }
+
+ if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0))
+ {
+ gHighlightSpecularProgram.unbind();
+ }
+ }
}
//debug use
@@ -4012,7 +4309,7 @@ U32 LLPipeline::sCurRenderPoolType = 0 ;
void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
{
- LLFastTimer t(FTM_RENDER_GEOMETRY);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
assertInitialized();
@@ -4047,7 +4344,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
{
if (!verify())
{
- llerrs << "Pipeline verification failed!" << llendl;
+ LL_ERRS() << "Pipeline verification failed!" << LL_ENDL;
}
}
@@ -4099,7 +4396,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
}
{
- LLFastTimer t(FTM_POOLS);
+ LL_RECORD_BLOCK_TIME(FTM_POOLS);
// HACK: don't calculate local lights if we're rendering the HUD!
// Removing this check will cause bad flickering when there are
@@ -4135,7 +4432,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0)
{
- LLFastTimer t(FTM_POOLRENDER);
+ LL_RECORD_BLOCK_TIME(FTM_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4264,9 +4561,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
{
LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred");
- LLFastTimer t(FTM_RENDER_GEOMETRY);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY);
- LLFastTimer t2(FTM_DEFERRED_POOLS);
+ LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLS);
LLGLEnable cull(GL_CULL_FACE);
@@ -4308,7 +4605,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumDeferredPasses() > 0)
{
- LLFastTimer t(FTM_DEFERRED_POOLRENDER);
+ LL_RECORD_BLOCK_TIME(FTM_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4358,9 +4655,9 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
}
-void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
+void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion)
{
- LLFastTimer t(FTM_POST_DEFERRED_POOLS);
+ LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLS);
U32 cur_type = 0;
LLGLEnable cull(GL_CULL_FACE);
@@ -4373,7 +4670,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGL.setColorMask(true, false);
pool_set_t::iterator iter1 = mPools.begin();
- BOOL occlude = LLPipeline::sUseOcclusion > 1;
+ BOOL occlude = LLPipeline::sUseOcclusion > 1 && do_occlusion;
while ( iter1 != mPools.end() )
{
@@ -4387,14 +4684,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
LLGLSLShader::bindNoShader();
- doOcclusion(camera);
+ doOcclusion(camera, mScreen, mOcclusionDepth, &mDeferredDepth);
gGL.setColorMask(true, false);
}
pool_set_t::iterator iter2 = iter1;
if (hasRenderType(poolp->getType()) && poolp->getNumPostDeferredPasses() > 0)
{
- LLFastTimer t(FTM_POST_DEFERRED_POOLRENDER);
+ LL_RECORD_BLOCK_TIME(FTM_POST_DEFERRED_POOLRENDER);
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
@@ -4531,10 +4828,8 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type)
count = index_count/3;
}
- mTrianglesDrawn += count;
- mBatchCount++;
- mMaxBatchSize = llmax(mMaxBatchSize, count);
- mMinBatchSize = llmin(mMinBatchSize, count);
+ record(sStatBatchSize, count);
+ add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count));
if (LLPipeline::sRenderFrameTest)
{
@@ -4583,18 +4878,6 @@ void LLPipeline::renderPhysicsDisplay()
}
}
- for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
- {
- LLSpatialBridge* bridge = *i;
- if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
- {
- gGL.pushMatrix();
- gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
- bridge->renderPhysicsShapes();
- gGL.popMatrix();
- }
- }
-
gGL.flush();
if (LLGLSLShader::sNoFixedFunction)
@@ -4605,6 +4888,7 @@ void LLPipeline::renderPhysicsDisplay()
mPhysicsDisplay.flush();
}
+extern std::set<LLSpatialGroup*> visible_selected_groups;
void LLPipeline::renderDebug()
{
@@ -4630,9 +4914,9 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("ambiance", 1.f);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
}
//Requried character physics capsule render parameters
@@ -4649,7 +4933,7 @@ void LLPipeline::renderDebug()
llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
gGL.setColorMask(true, false);
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderSimpleShapeCapsuleID( gGL, id, pos, rot );
gPathfindingProgram.bind();
}
@@ -4676,9 +4960,9 @@ void LLPipeline::renderDebug()
{
gPathfindingProgram.bind();
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("ambiance", ambiance);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
}
if ( !pathfindingConsole->isRenderWorld() )
@@ -4702,7 +4986,7 @@ void LLPipeline::renderDebug()
if ( pathfindingConsole->isRenderWorld() )
{
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.66f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.66f);
llPathingLibInstance->renderNavMesh();
}
else
@@ -4714,8 +4998,8 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f("tint", 1.f);
- gPathfindingNoNormalsProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sTint, 1.f);
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, 1.f);
llPathingLibInstance->renderNavMeshEdges();
gPathfindingProgram.bind();
}
@@ -4755,7 +5039,7 @@ void LLPipeline::renderDebug()
gGL.setColorMask(true, false);
//render the bookends
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_START );
llPathingLibInstance->renderPathBookend( gGL, LLPathingLib::LLPL_END );
gPathfindingProgram.bind();
@@ -4773,7 +5057,7 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
LLGLEnable blend(GL_BLEND);
- gPathfindingProgram.uniform1f("alpha_scale", 0.90f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 0.90f);
llPathingLibInstance->renderSimpleShapes( gGL, gAgent.getRegion()->getWaterHeight() );
}
else
@@ -4821,7 +5105,7 @@ void LLPipeline::renderDebug()
LLGLEnable blend(GL_BLEND);
{
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
{ //draw solid overlay
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_LEQUAL);
@@ -4836,8 +5120,8 @@ void LLPipeline::renderDebug()
if (pathfindingConsole->isRenderXRay())
{
- gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
LLGLEnable blend(GL_BLEND);
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER);
@@ -4845,13 +5129,13 @@ void LLPipeline::renderDebug()
if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
{ //draw hidden wireframe as darker and less opaque
- gPathfindingProgram.uniform1f("ambiance", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
}
else
{
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
llPathingLibInstance->renderNavMeshShapesVBO( render_order[i] );
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
@@ -4859,9 +5143,9 @@ void LLPipeline::renderDebug()
{ //draw visible wireframe as brighter, thicker and more opaque
glPolygonOffset(offset, offset);
- gPathfindingProgram.uniform1f("ambiance", 1.f);
- gPathfindingProgram.uniform1f("tint", 1.f);
- gPathfindingProgram.uniform1f("alpha_scale", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
+ gPathfindingProgram.uniform1f(sTint, 1.f);
+ gPathfindingProgram.uniform1f(sAlphaScale, 1.f);
glLineWidth(gSavedSettings.getF32("PathfindingLineWidth"));
LLGLDisable blendOut(GL_BLEND);
@@ -4893,19 +5177,19 @@ void LLPipeline::renderDebug()
glLineWidth(2.0f);
LLGLEnable cull(GL_CULL_FACE);
- gPathfindingProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
if (gSavedSettings.getBOOL("PathfindingXRayWireframe"))
{ //draw hidden wireframe as darker and less opaque
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
- gPathfindingProgram.uniform1f("ambiance", 1.f);
+ gPathfindingProgram.uniform1f(sAmbiance, 1.f);
llPathingLibInstance->renderNavMesh();
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
}
else
{
- gPathfindingProgram.uniform1f("ambiance", ambiance);
+ gPathfindingProgram.uniform1f(sAmbiance, ambiance);
llPathingLibInstance->renderNavMesh();
}
@@ -4913,8 +5197,8 @@ void LLPipeline::renderDebug()
if (LLGLSLShader::sNoFixedFunction)
{
gPathfindingNoNormalsProgram.bind();
- gPathfindingNoNormalsProgram.uniform1f("tint", gSavedSettings.getF32("PathfindingXRayTint"));
- gPathfindingNoNormalsProgram.uniform1f("alpha_scale", gSavedSettings.getF32("PathfindingXRayOpacity"));
+ gPathfindingNoNormalsProgram.uniform1f(sTint, gSavedSettings.getF32("PathfindingXRayTint"));
+ gPathfindingNoNormalsProgram.uniform1f(sAlphaScale, gSavedSettings.getF32("PathfindingXRayOpacity"));
llPathingLibInstance->renderNavMeshEdges();
gPathfindingProgram.bind();
}
@@ -4963,7 +5247,7 @@ void LLPipeline::renderDebug()
{
DebugBlip& blip = *iter;
- blip.mAge += gFrameIntervalSeconds;
+ blip.mAge += gFrameIntervalSeconds.value();
if (blip.mAge > 2.f)
{
mDebugBlips.erase(iter++);
@@ -4973,7 +5257,7 @@ void LLPipeline::renderDebug()
iter++;
}
- blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f;
+ blip.mPosition.mV[2] += gFrameIntervalSeconds.value()*2.f;
gGL.color4fv(blip.mColor.mV);
gGL.vertex3fv(blip.mPosition.mV);
@@ -4994,8 +5278,8 @@ void LLPipeline::renderDebug()
LLSpatialPartition* part = region->getSpatialPartition(i);
if (part)
{
- if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) ||
- !hud_only && hasRenderType(part->mDrawableType) )
+ if ( (hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES)) ||
+ (!hud_only && hasRenderType(part->mDrawableType)) )
{
part->renderDebug();
}
@@ -5015,11 +5299,69 @@ void LLPipeline::renderDebug()
}
}
+ if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION) && LLGLSLShader::sNoFixedFunction)
+ { //render visible selected group occlusion geometry
+ gDebugProgram.bind();
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ gGL.diffuseColor3f(1,0,1);
+ for (std::set<LLSpatialGroup*>::iterator iter = visible_selected_groups.begin(); iter != visible_selected_groups.end(); ++iter)
+ {
+ LLSpatialGroup* group = *iter;
+
+ LLVector4a fudge;
+ fudge.splat(0.25f); //SG_OCCLUSION_FUDGE
+
+ LLVector4a size;
+ const LLVector4a* bounds = group->getBounds();
+ size.setAdd(fudge, bounds[1]);
+
+ drawBox(bounds[0], size);
+ }
+ }
+
+ visible_selected_groups.clear();
+
if (LLGLSLShader::sNoFixedFunction)
{
gUIProgram.bind();
}
+ if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
+ { //draw crosshairs on particle intersection
+ if (gDebugRaycastParticle)
+ {
+ if (LLGLSLShader::sNoFixedFunction)
+ { //this debug display requires shaders
+ gDebugProgram.bind();
+
+ gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+ LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
+ LLVector3 size(0.1f, 0.1f, 0.1f);
+
+ LLVector3 p[6];
+
+ p[0] = center + size.scaledVec(LLVector3(1,0,0));
+ p[1] = center + size.scaledVec(LLVector3(-1,0,0));
+ p[2] = center + size.scaledVec(LLVector3(0,1,0));
+ p[3] = center + size.scaledVec(LLVector3(0,-1,0));
+ p[4] = center + size.scaledVec(LLVector3(0,0,1));
+ p[5] = center + size.scaledVec(LLVector3(0,0,-1));
+
+ gGL.begin(LLRender::LINES);
+ gGL.diffuseColor3f(1.f, 1.f, 0.f);
+ for (U32 i = 0; i < 6; i++)
+ {
+ gGL.vertex3fv(p[i].mV);
+ }
+ gGL.end();
+ gGL.flush();
+
+ gDebugProgram.unbind();
+ }
+ }
+ }
+
if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
{
LLVertexBuffer::unbind();
@@ -5053,7 +5395,7 @@ void LLPipeline::renderDebug()
if (i > 3)
{ //render shadow frusta as volumes
if (mShadowFrustPoints[i-4].empty())
- {
+ {
continue;
}
@@ -5215,7 +5557,7 @@ void LLPipeline::renderDebug()
continue;
}
- LLSpatialBridge* bridge = group->mSpatialPartition->asBridge();
+ LLSpatialBridge* bridge = group->getSpatialPartition()->asBridge();
if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead()))
{
@@ -5255,11 +5597,11 @@ void LLPipeline::renderDebug()
}
}
-static LLFastTimer::DeclareTimer FTM_REBUILD_POOLS("Rebuild Pools");
+static LLTrace::BlockTimerStatHandle FTM_REBUILD_POOLS("Rebuild Pools");
void LLPipeline::rebuildPools()
{
- LLFastTimer t(FTM_REBUILD_POOLS);
+ LL_RECORD_BLOCK_TIME(FTM_REBUILD_POOLS);
assertInitialized();
@@ -5302,7 +5644,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if (mSimplePool)
{
llassert(0);
- llwarns << "Ignoring duplicate simple pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
}
else
{
@@ -5310,11 +5652,37 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
}
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ if (mAlphaMaskPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
+ break;
+ }
+ else
+ {
+ mAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ if (mFullbrightAlphaMaskPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignoring duplicate alpha mask pool." << LL_ENDL;
+ break;
+ }
+ else
+ {
+ mFullbrightAlphaMaskPool = (LLRenderPass*) new_poolp;
+ }
+ break;
+
case LLDrawPool::POOL_GRASS:
if (mGrassPool)
{
llassert(0);
- llwarns << "Ignoring duplicate grass pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate grass pool." << LL_ENDL;
}
else
{
@@ -5326,7 +5694,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if (mFullbrightPool)
{
llassert(0);
- llwarns << "Ignoring duplicate simple pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
}
else
{
@@ -5338,7 +5706,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if (mInvisiblePool)
{
llassert(0);
- llwarns << "Ignoring duplicate simple pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate simple pool." << LL_ENDL;
}
else
{
@@ -5350,7 +5718,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if (mGlowPool)
{
llassert(0);
- llwarns << "Ignoring duplicate glow pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate glow pool." << LL_ENDL;
}
else
{
@@ -5370,23 +5738,33 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if (mBumpPool)
{
llassert(0);
- llwarns << "Ignoring duplicate bump pool." << llendl;
+ LL_WARNS() << "Ignoring duplicate bump pool." << LL_ENDL;
}
else
{
mBumpPool = new_poolp;
}
break;
-
+ case LLDrawPool::POOL_MATERIALS:
+ if (mMaterialsPool)
+ {
+ llassert(0);
+ LL_WARNS() << "Ignorning duplicate materials pool." << LL_ENDL;
+ }
+ else
+ {
+ mMaterialsPool = new_poolp;
+ }
+ break;
case LLDrawPool::POOL_ALPHA:
if( mAlphaPool )
{
llassert(0);
- llwarns << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << llendl;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Alpha pool" << LL_ENDL;
}
else
{
- mAlphaPool = new_poolp;
+ mAlphaPool = (LLDrawPoolAlpha*) new_poolp;
}
break;
@@ -5397,7 +5775,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if( mSkyPool )
{
llassert(0);
- llwarns << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << llendl;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Sky pool" << LL_ENDL;
}
else
{
@@ -5409,7 +5787,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if( mWaterPool )
{
llassert(0);
- llwarns << "LLPipeline::addPool(): Ignoring duplicate Water pool" << llendl;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Water pool" << LL_ENDL;
}
else
{
@@ -5421,7 +5799,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if( mGroundPool )
{
llassert(0);
- llwarns << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << llendl;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate Ground Pool" << LL_ENDL;
}
else
{
@@ -5433,7 +5811,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
if( mWLSkyPool )
{
llassert(0);
- llwarns << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << llendl;
+ LL_WARNS() << "LLPipeline::addPool(): Ignoring duplicate WLSky Pool" << LL_ENDL;
}
else
{
@@ -5443,7 +5821,7 @@ void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
default:
llassert(0);
- llwarns << "Invalid Pool Type in LLPipeline::addPool()" << llendl;
+ LL_WARNS() << "Invalid Pool Type in LLPipeline::addPool()" << LL_ENDL;
break;
}
}
@@ -5466,6 +5844,16 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mSimplePool = NULL;
break;
+ case LLDrawPool::POOL_ALPHA_MASK:
+ llassert(mAlphaMaskPool == poolp);
+ mAlphaMaskPool = NULL;
+ break;
+
+ case LLDrawPool::POOL_FULLBRIGHT_ALPHA_MASK:
+ llassert(mFullbrightAlphaMaskPool == poolp);
+ mFullbrightAlphaMaskPool = NULL;
+ break;
+
case LLDrawPool::POOL_GRASS:
llassert(mGrassPool == poolp);
mGrassPool = NULL;
@@ -5518,6 +5906,11 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
mBumpPool = NULL;
break;
+ case LLDrawPool::POOL_MATERIALS:
+ llassert(poolp == mMaterialsPool);
+ mMaterialsPool = NULL;
+ break;
+
case LLDrawPool::POOL_ALPHA:
llassert( poolp == mAlphaPool );
mAlphaPool = NULL;
@@ -5543,7 +5936,7 @@ void LLPipeline::removeFromQuickLookup( LLDrawPool* poolp )
default:
llassert(0);
- llwarns << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << llendl;
+ LL_WARNS() << "Invalid Pool Type in LLPipeline::removeFromQuickLookup() type=" << poolp->getType() << LL_ENDL;
break;
}
}
@@ -5580,6 +5973,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
LLLightState* light = gGL.getLight(1);
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f);
+ diffuse.mV[1] = powf(diffuse.mV[1], 2.2f);
+ diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[1] = diffuse;
light->setDiffuse(diffuse);
@@ -5620,6 +6020,13 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)
}
backlight_diffuse *= backlight_mag / max_component;
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f);
+ backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f);
+ backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[1] = backlight_diffuse;
LLLightState* light = gGL.getLight(1);
@@ -5779,7 +6186,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
{
if (farthest_light->fade >= 0.f)
{
- farthest_light->fade = -gFrameIntervalSeconds;
+ farthest_light->fade = -(gFrameIntervalSeconds.value());
}
}
else
@@ -5789,6 +6196,13 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
}
}
+ //mark nearby lights not-removable.
+ for (light_set_t::iterator iter = mNearbyLights.begin();
+ iter != mNearbyLights.end(); iter++)
+ {
+ const Light* light = &(*iter);
+ ((LLViewerOctreeEntryData*) light->drawable)->setVisible();
+ }
}
}
@@ -5826,6 +6240,14 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
LLVector4 light_pos(mSunDir, 0.0f);
LLColor4 light_diffuse = mSunDiffuse;
+
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f);
+ light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f);
+ light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/
+ }
+
mHWLightColors[0] = light_diffuse;
LLLightState* light = gGL.getLight(0);
@@ -5875,12 +6297,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (fade >= 0.f)
{
fade = fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds;
+ ((Light*) (&(*iter)))->fade += gFrameIntervalSeconds.value();
}
else
{
fade = 1.f + fade / LIGHT_FADE_TIME;
- ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds;
+ ((Light*) (&(*iter)))->fade -= gFrameIntervalSeconds.value();
}
fade = llclamp(fade,0.f,1.f);
light_color *= fade;
@@ -5904,7 +6326,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (sRenderDeferred)
{
F32 size = light_radius*1.5f;
- light_state->setLinearAttenuation(size*size);
+ light_state->setLinearAttenuation(size);
light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f);
}
else
@@ -5917,7 +6339,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
if (light->isLightSpotlight() // directional (spot-)light
&& (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
{
- 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;
@@ -5968,6 +6389,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
F32 x = 3.f;
float linatten = x / (light_radius); // % of brightness at radius
+ if (LLPipeline::sRenderDeferred)
+ {
+ /*light_color.mV[0] = powf(light_color.mV[0], 2.2f);
+ light_color.mV[1] = powf(light_color.mV[1], 2.2f);
+ light_color.mV[2] = powf(light_color.mV[2], 2.2f);*/
+ }
+
mHWLightColors[2] = light_color;
LLLightState* light = gGL.getLight(2);
@@ -6186,28 +6614,28 @@ void LLPipeline::findReferences(LLDrawable *drawablep)
assertInitialized();
if (mLights.find(drawablep) != mLights.end())
{
- llinfos << "In mLights" << llendl;
+ LL_INFOS() << "In mLights" << LL_ENDL;
}
if (std::find(mMovedList.begin(), mMovedList.end(), drawablep) != mMovedList.end())
{
- llinfos << "In mMovedList" << llendl;
+ LL_INFOS() << "In mMovedList" << LL_ENDL;
}
if (std::find(mShiftList.begin(), mShiftList.end(), drawablep) != mShiftList.end())
{
- llinfos << "In mShiftList" << llendl;
+ LL_INFOS() << "In mShiftList" << LL_ENDL;
}
if (mRetexturedList.find(drawablep) != mRetexturedList.end())
{
- llinfos << "In mRetexturedList" << llendl;
+ LL_INFOS() << "In mRetexturedList" << LL_ENDL;
}
if (std::find(mBuildQ1.begin(), mBuildQ1.end(), drawablep) != mBuildQ1.end())
{
- llinfos << "In mBuildQ1" << llendl;
+ LL_INFOS() << "In mBuildQ1" << LL_ENDL;
}
if (std::find(mBuildQ2.begin(), mBuildQ2.end(), drawablep) != mBuildQ2.end())
{
- llinfos << "In mBuildQ2" << llendl;
+ LL_INFOS() << "In mBuildQ2" << LL_ENDL;
}
S32 count;
@@ -6215,7 +6643,7 @@ void LLPipeline::findReferences(LLDrawable *drawablep)
count = gObjectList.findReferences(drawablep);
if (count)
{
- llinfos << "In other drawables: " << count << " references" << llendl;
+ LL_INFOS() << "In other drawables: " << count << " references" << LL_ENDL;
}
}
@@ -6236,7 +6664,7 @@ BOOL LLPipeline::verify()
if (!ok)
{
- llwarns << "Pipeline verify failed!" << llendl;
+ LL_WARNS() << "Pipeline verify failed!" << LL_ENDL;
}
return ok;
}
@@ -6374,11 +6802,11 @@ void LLPipeline::toggleRenderTypeControl(void* data)
U32 bit = (1<<type);
if (gPipeline.hasRenderType(type))
{
- llinfos << "Toggling render type mask " << std::hex << bit << " off" << std::dec << llendl;
+ LL_INFOS() << "Toggling render type mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
}
else
{
- llinfos << "Toggling render type mask " << std::hex << bit << " on" << std::dec << llendl;
+ LL_INFOS() << "Toggling render type mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
}
gPipeline.toggleRenderType(type);
}
@@ -6404,11 +6832,11 @@ void LLPipeline::toggleRenderDebug(void* data)
U32 bit = (U32)(intptr_t)data;
if (gPipeline.hasRenderDebugMask(bit))
{
- llinfos << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << llendl;
+ LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " off" << std::dec << LL_ENDL;
}
else
{
- llinfos << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << llendl;
+ LL_INFOS() << "Toggling render debug mask " << std::hex << bit << " on" << std::dec << LL_ENDL;
}
gPipeline.mRenderDebugMask ^= bit;
}
@@ -6448,6 +6876,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
}
}
+void LLPipeline::pushRenderDebugFeatureMask()
+{
+ mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+}
+
+void LLPipeline::popRenderDebugFeatureMask()
+{
+ if (mRenderDebugFeatureStack.empty())
+ {
+ LL_ERRS() << "Depleted render feature stack." << LL_ENDL;
+ }
+
+ mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+ mRenderDebugFeatureStack.pop();
+}
+
// static
void LLPipeline::setRenderScriptedBeacons(BOOL val)
{
@@ -6592,20 +7036,68 @@ BOOL LLPipeline::getRenderHighlights(void*)
return sRenderHighlight;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, const LLVector3& end,
+// static
+void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
+{
+ sRenderHighlightTextureChannel = channel;
+}
+
+LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+ S32* face_hit)
+{
+ LLVector4a local_end = end;
+
+ LLVector4a position;
+
+ LLDrawable* drawable = NULL;
+
+ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
+ iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+ {
+ LLViewerRegion* region = *iter;
+
+ LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
+ if (part && hasRenderType(part->mDrawableType))
+ {
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, face_hit, &position, NULL, NULL, NULL);
+ if (hit)
+ {
+ drawable = hit;
+ local_end = position;
+ }
+ }
+ }
+
+ LLVOPartGroup* ret = NULL;
+ if (drawable)
+ {
+ //make sure we're returning an LLVOPartGroup
+ llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP);
+ ret = (LLVOPartGroup*) drawable->getVObj().get();
+ }
+
+ if (intersection)
+ {
+ *intersection = position;
+ }
+
+ return ret;
+}
+
+LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
- LLVector3 local_end = end;
+ LLVector4a local_end = end;
- LLVector3 position;
+ LLVector4a position;
sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE;
@@ -6625,7 +7117,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(j);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6640,8 +7132,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
//save hit info in case we need to restore
//due to attachment override
- LLVector3 local_normal;
- LLVector3 local_binormal;
+ LLVector4a local_normal;
+ LLVector4a local_tangent;
LLVector2 local_texcoord;
S32 local_face_hit = -1;
@@ -6653,14 +7145,22 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
local_texcoord = *tex_coord;
}
- if (bi_normal)
+ if (tangent)
{
- local_binormal = *bi_normal;
+ local_tangent = *tangent;
+ }
+ else
+ {
+ local_tangent.clear();
}
if (normal)
{
local_normal = *normal;
}
+ else
+ {
+ local_normal.clear();
+ }
const F32 ATTACHMENT_OVERRIDE_DIST = 0.1f;
@@ -6674,12 +7174,15 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_BRIDGE);
if (part && hasRenderType(part->mDrawableType))
{
- LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, local_end, pick_transparent, face_hit, &position, tex_coord, normal, tangent);
if (hit)
{
+ LLVector4a delta;
+ delta.setSub(position, local_end);
+
if (!drawable ||
!drawable->getVObj()->isAttachment() ||
- (position-local_end).magVec() > ATTACHMENT_OVERRIDE_DIST)
+ delta.getLength3().getF32() > ATTACHMENT_OVERRIDE_DIST)
{ //avatar overrides if previously hit drawable is not an attachment or
//attachment is far enough away from detected intersection
drawable = hit;
@@ -6697,9 +7200,9 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
{
*tex_coord = local_texcoord;
}
- if (bi_normal)
+ if (tangent)
{
- *bi_normal = local_binormal;
+ *tangent = local_tangent;
}
if (normal)
{
@@ -6733,13 +7236,13 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start,
return drawable ? drawable->getVObj().get() : NULL;
}
-LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, const LLVector3& end,
+LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
BOOL pick_transparent,
S32* face_hit,
- LLVector3* intersection, // return the intersection point
+ LLVector4a* intersection, // return the intersection point
LLVector2* tex_coord, // return the texture coordinates of the intersection point
- LLVector3* normal, // return the surface normal at the intersection point
- LLVector3* bi_normal // return the surface bi-normal at the intersection point
+ LLVector4a* normal, // return the surface normal at the intersection point
+ LLVector4a* tangent // return the surface tangent at the intersection point
)
{
LLDrawable* drawable = NULL;
@@ -6759,7 +7262,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co
LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_HUD);
if (part)
{
- LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, bi_normal);
+ LLDrawable* hit = part->lineSegmentIntersect(start, end, pick_transparent, face_hit, intersection, tex_coord, normal, tangent);
if (hit)
{
drawable = hit;
@@ -6809,16 +7312,30 @@ void LLPipeline::resetVertexBuffers()
mResetVertexBuffers = true;
}
-static LLFastTimer::DeclareTimer FTM_RESET_VB("Reset VB");
+static LLTrace::BlockTimerStatHandle FTM_RESET_VB("Reset VB");
-void LLPipeline::doResetVertexBuffers()
+void LLPipeline::doResetVertexBuffers(bool forced)
{
if (!mResetVertexBuffers)
{
return;
}
+ if(!forced && LLSpatialPartition::sTeleportRequested)
+ {
+ if(gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
+ {
+ return; //wait for teleporting to finish
+ }
+ else
+ {
+ //teleporting aborted
+ LLSpatialPartition::sTeleportRequested = FALSE;
+ mResetVertexBuffers = false;
+ return;
+ }
+ }
- LLFastTimer t(FTM_RESET_VB);
+ LL_RECORD_BLOCK_TIME(FTM_RESET_VB);
mResetVertexBuffers = false;
mCubeVB = NULL;
@@ -6836,6 +7353,13 @@ void LLPipeline::doResetVertexBuffers()
}
}
}
+ if(LLSpatialPartition::sTeleportRequested)
+ {
+ LLSpatialPartition::sTeleportRequested = FALSE;
+
+ LLWorld::getInstance()->clearAllVisibleObjects();
+ clearRebuildDrawables();
+ }
resetDrawOrders();
@@ -6858,12 +7382,14 @@ void LLPipeline::doResetVertexBuffers()
if (LLVertexBuffer::sGLCount > 0)
{
- llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
+ LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL;
}
LLVertexBuffer::unbind();
- sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");
+ updateRenderBump();
+ updateRenderDeferred();
+
sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips");
LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");
@@ -6889,6 +7415,17 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_text
gGLLastMatrix = NULL;
}
+void LLPipeline::renderMaskedObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture)
+{
+ assertInitialized();
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+ mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture);
+ gGL.loadMatrix(gGLModelView);
+ gGLLastMatrix = NULL;
+}
+
+
void apply_cube_face_rotation(U32 face)
{
switch (face)
@@ -6928,18 +7465,18 @@ void validate_framebuffer_object()
break;
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
// frame buffer not OK: probably means unsupported depth buffer format
- llerrs << "Framebuffer Incomplete Missing Attachment." << llendl;
+ LL_ERRS() << "Framebuffer Incomplete Missing Attachment." << LL_ENDL;
break;
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
// frame buffer not OK: probably means unsupported depth buffer format
- llerrs << "Framebuffer Incomplete Attachment." << llendl;
+ LL_ERRS() << "Framebuffer Incomplete Attachment." << LL_ENDL;
break;
case GL_FRAMEBUFFER_UNSUPPORTED:
/* choose different formats */
- llerrs << "Framebuffer unsupported." << llendl;
+ LL_ERRS() << "Framebuffer unsupported." << LL_ENDL;
break;
default:
- llerrs << "Unknown framebuffer status." << llendl;
+ LL_ERRS() << "Unknown framebuffer status." << LL_ENDL;
break;
}
}
@@ -6949,7 +7486,7 @@ void LLPipeline::bindScreenToTexture()
}
-static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom");
+static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom");
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
@@ -6974,7 +7511,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
LLVector2 tc2((F32) mScreen.getWidth()*2,
(F32) mScreen.getHeight()*2);
- LLFastTimer ftm(FTM_RENDER_BLOOM);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM);
gGL.color4f(1,1,1,1);
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -6996,7 +7533,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
{
- LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
mGlow[2].bindTarget();
mGlow[2].clear();
}
@@ -7064,7 +7601,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
for (S32 i = 0; i < kernel; i++)
{
{
- LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
mGlow[i%2].bindTarget();
mGlow[i%2].clear();
}
@@ -7106,7 +7643,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
/*if (LLRenderTarget::sUseFBO)
{
- LLFastTimer ftm(FTM_RENDER_BLOOM_FBO);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
}*/
@@ -7127,7 +7664,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
- !LLToolMgr::getInstance()->inBuildMode() &&
+ (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
RenderDepthOfField;
@@ -7165,18 +7702,27 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
{
if (LLViewerJoystick::getInstance()->getOverrideCamera())
{ //focus on point under cursor
- focus_point = gDebugRaycastIntersection;
+ focus_point.set(gDebugRaycastIntersection.getF32ptr());
}
else if (gAgentCamera.cameraMouselook())
{ //focus on point under mouselook crosshairs
+ LLVector4a result;
+ result.clear();
+
gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE,
NULL,
- &focus_point);
+ &result);
+
+ focus_point.set(result.getF32ptr());
}
else
{
//focus on alt-zoom target
- focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal());
+ LLViewerRegion* region = gAgent.getRegion();
+ if (region)
+ {
+ focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal());
+ }
}
}
@@ -7195,7 +7741,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
else if (transition_time < 1.f)
{ //currently in a transition, continue interpolating
- transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds;
+ transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value();
transition_time = llmin(transition_time, 1.f);
F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f;
@@ -7332,6 +7878,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
}
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
+
shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF);
shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale);
shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1);
@@ -7373,6 +7926,13 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
mScreen.bindTexture(0, channel);
}
+ if (!LLViewerCamera::getInstance()->cameraUnderWater())
+ {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2);
+ } else {
+ shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0);
+ }
+
gGL.begin(LLRender::TRIANGLE_STRIP);
gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);
gGL.vertex2f(-1,-1);
@@ -7583,11 +8143,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
}
-static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred");
+static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred");
void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map)
{
- LLFastTimer t(FTM_BIND_DEFERRED);
+ LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED);
if (noise_map == 0xFFFFFFFF)
{
@@ -7785,23 +8345,39 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n
shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff);
- if (shader.getUniformLocation("norm_mat") >= 0)
+ if (shader.getUniformLocation(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0)
{
glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose();
- shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m);
+ shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m);
}
}
-static LLFastTimer::DeclareTimer FTM_GI_TRACE("Trace");
-static LLFastTimer::DeclareTimer FTM_GI_GATHER("Gather");
-static LLFastTimer::DeclareTimer FTM_SUN_SHADOW("Shadow Map");
-static LLFastTimer::DeclareTimer FTM_SOFTEN_SHADOW("Shadow Soften");
-static LLFastTimer::DeclareTimer FTM_EDGE_DETECTION("Find Edges");
-static LLFastTimer::DeclareTimer FTM_LOCAL_LIGHTS("Local Lights");
-static LLFastTimer::DeclareTimer FTM_ATMOSPHERICS("Atmospherics");
-static LLFastTimer::DeclareTimer FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
-static LLFastTimer::DeclareTimer FTM_PROJECTORS("Projectors");
-static LLFastTimer::DeclareTimer FTM_POST("Post");
+LLColor3 pow3f(LLColor3 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+LLVector4 pow4fsrgb(LLVector4 v, F32 f)
+{
+ v.mV[0] = powf(v.mV[0], f);
+ v.mV[1] = powf(v.mV[1], f);
+ v.mV[2] = powf(v.mV[2], f);
+ return v;
+}
+
+static LLTrace::BlockTimerStatHandle FTM_GI_TRACE("Trace");
+static LLTrace::BlockTimerStatHandle FTM_GI_GATHER("Gather");
+static LLTrace::BlockTimerStatHandle FTM_SUN_SHADOW("Shadow Map");
+static LLTrace::BlockTimerStatHandle FTM_SOFTEN_SHADOW("Shadow Soften");
+static LLTrace::BlockTimerStatHandle FTM_EDGE_DETECTION("Find Edges");
+static LLTrace::BlockTimerStatHandle FTM_LOCAL_LIGHTS("Local Lights");
+static LLTrace::BlockTimerStatHandle FTM_ATMOSPHERICS("Atmospherics");
+static LLTrace::BlockTimerStatHandle FTM_FULLSCREEN_LIGHTS("Fullscreen Lights");
+static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors");
+static LLTrace::BlockTimerStatHandle FTM_POST("Post");
void LLPipeline::renderDeferredLighting()
@@ -7812,7 +8388,7 @@ void LLPipeline::renderDeferredLighting()
}
{
- LLFastTimer ftm(FTM_RENDER_DEFERRED);
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
LLViewerCamera* camera = LLViewerCamera::getInstance();
{
@@ -7845,11 +8421,7 @@ void LLPipeline::renderDeferredLighting()
LLStrider<LLVector3> vert;
mDeferredVB->getVertexStrider(vert);
- LLStrider<LLVector2> tc0;
- LLStrider<LLVector2> tc1;
- mDeferredVB->getTexCoord0Strider(tc0);
- mDeferredVB->getTexCoord1Strider(tc1);
-
+
vert[0].set(-1,1,0);
vert[1].set(-1,-3,0);
vert[2].set(3,1,0);
@@ -7872,7 +8444,7 @@ void LLPipeline::renderDeferredLighting()
{
mDeferredLight.bindTarget();
{ //paint shadow/SSAO light map (direct lighting lightmap)
- LLFastTimer ftm(FTM_SUN_SHADOW);
+ LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
bindDeferredShader(gDeferredSunProgram, 0);
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
glClearColor(1,1,1,1);
@@ -7898,8 +8470,8 @@ void LLPipeline::renderDeferredLighting()
}
}
- gDeferredSunProgram.uniform3fv("offset", slice, offset);
- gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight());
+ gDeferredSunProgram.uniform3fv(sOffset, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
{
LLGLDisable blend(GL_BLEND);
@@ -7916,7 +8488,7 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredSSAO)
{ //soften direct lighting lightmap
- LLFastTimer ftm(FTM_SOFTEN_SHADOW);
+ LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW);
//blur lightmap
mScreen.bindTarget();
glClearColor(1,1,1,1);
@@ -7943,10 +8515,10 @@ void LLPipeline::renderDeferredLighting()
x += 1.f;
}
- 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));
+ gDeferredBlurLightProgram.uniform2f(sDelta, 1.f, 0.f);
+ gDeferredBlurLightProgram.uniform1f(sDistFactor, dist_factor);
+ gDeferredBlurLightProgram.uniform3fv(sKern, kern_length, gauss[0].mV);
+ gDeferredBlurLightProgram.uniform1f(sKernScale, blur_size * (kern_length/2.f - 0.5f));
{
LLGLDisable blend(GL_BLEND);
@@ -7963,7 +8535,7 @@ void LLPipeline::renderDeferredLighting()
mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredLight.bindTarget();
- gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f);
+ gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f);
{
LLGLDisable blend(GL_BLEND);
@@ -7991,8 +8563,8 @@ void LLPipeline::renderDeferredLighting()
if (RenderDeferredAtmospheric)
{ //apply sunlight contribution
- LLFastTimer ftm(FTM_ATMOSPHERICS);
- bindDeferredShader(gDeferredSoftenProgram);
+ LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
+ bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
{
LLGLDepthTest depth(GL_FALSE);
LLGLDisable blend(GL_BLEND);
@@ -8014,7 +8586,7 @@ void LLPipeline::renderDeferredLighting()
gGL.popMatrix();
}
- unbindDeferredShader(gDeferredSoftenProgram);
+ unbindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram);
}
{ //render non-deferred geometry (fullbright, alpha, etc)
@@ -8030,7 +8602,7 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::END_RENDER_TYPES);
- renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
gPipeline.popRenderTypeMask();
}
@@ -8124,9 +8696,13 @@ void LLPipeline::renderDeferredLighting()
continue;
}
- LLFastTimer ftm(FTM_LOCAL_LIGHTS);
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8147,7 +8723,7 @@ void LLPipeline::renderDeferredLighting()
glh::vec3f tc(c);
mat.mult_matrix_vec(tc);
- fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s));
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
}
}
@@ -8165,7 +8741,7 @@ void LLPipeline::renderDeferredLighting()
for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
{
- LLFastTimer ftm(FTM_PROJECTORS);
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
LLDrawable* drawablep = *iter;
LLVOVolume* volume = drawablep->getVOVolume();
@@ -8180,9 +8756,12 @@ void LLPipeline::renderDeferredLighting()
setupSpotLight(gDeferredSpotLightProgram, drawablep);
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
- gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
gGL.syncMatrices();
@@ -8200,10 +8779,6 @@ void LLPipeline::renderDeferredLighting()
vert[2].set(3,1,0);
{
- bindDeferredShader(gDeferredMultiLightProgram);
-
- mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
-
LLGLDepthTest depth(GL_FALSE);
//full screen blit
@@ -8215,7 +8790,7 @@ void LLPipeline::renderDeferredLighting()
U32 count = 0;
- const U32 max_count = 8;
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
LLVector4 light[max_count];
LLVector4 col[max_count];
@@ -8223,29 +8798,35 @@ void LLPipeline::renderDeferredLighting()
while (!fullscreen_lights.empty())
{
- LLFastTimer ftm(FTM_FULLSCREEN_LIGHTS);
+ LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
light[count] = fullscreen_lights.front();
fullscreen_lights.pop_front();
col[count] = light_colors.front();
light_colors.pop_front();
- far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z);
-
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
count++;
if (count == max_count || fullscreen_lights.empty())
{
- gDeferredMultiLightProgram.uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
- gDeferredMultiLightProgram.uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
- gDeferredMultiLightProgram.uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
far_z = 0.f;
count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ unbindDeferredShader(gDeferredMultiLightProgram[idx]);
}
}
- unbindDeferredShader(gDeferredMultiLightProgram);
-
bindDeferredShader(gDeferredMultiSpotLightProgram);
gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
@@ -8254,7 +8835,7 @@ void LLPipeline::renderDeferredLighting()
for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
{
- LLFastTimer ftm(FTM_PROJECTORS);
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
LLDrawable* drawablep = *iter;
LLVOVolume* volume = drawablep->getVOVolume();
@@ -8272,8 +8853,12 @@ void LLPipeline::renderDeferredLighting()
LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
- gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
@@ -8291,6 +8876,65 @@ void LLPipeline::renderDeferredLighting()
gGL.setColorMask(true, true);
}
+ mScreen.flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) mScreen.getWidth()*2,
+ (F32) mScreen.getHeight()*2);
+
+ mScreen.bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage());
+ if (channel > -1)
+ {
+ mScreen.bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ 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.getTexUnit(channel)->unbind(mScreen.getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ mScreen.flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ mScreen.bindTarget();
+
{ //render non-deferred geometry (alpha, fullbright, glow)
LLGLDisable blend(GL_BLEND);
LLGLDisable stencil(GL_STENCIL_TEST);
@@ -8315,6 +8959,8 @@ void LLPipeline::renderDeferredLighting()
LLPipeline::RENDER_TYPE_PASS_INVISIBLE,
LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY,
LLPipeline::RENDER_TYPE_AVATAR,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
END_RENDER_TYPES);
renderGeomPostDeferred(*LLViewerCamera::getInstance());
@@ -8342,6 +8988,537 @@ void LLPipeline::renderDeferredLighting()
}
+void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target)
+{
+ if (!sCull)
+ {
+ return;
+ }
+
+ {
+ LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED);
+
+ LLViewerCamera* camera = LLViewerCamera::getInstance();
+
+ {
+ LLGLDepthTest depth(GL_TRUE);
+ mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(),
+ 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+ }
+
+ LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0);
+
+ if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD))
+ {
+ gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);
+ }
+
+ //ati doesn't seem to love actually using the stencil buffer on FBO's
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF);
+ //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
+
+ gGL.setColorMask(true, true);
+
+ //draw a cube around every light
+ LLVertexBuffer::unbind();
+
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLEnable blend(GL_BLEND);
+
+ glh::matrix4f mat = glh_copy_matrix(gGLModelView);
+
+ LLStrider<LLVector3> vert;
+ mDeferredVB->getVertexStrider(vert);
+
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ setupHWLights(NULL); //to set mSunDir;
+ LLVector4 dir(mSunDir, 0.f);
+ glh::vec4f tc(dir.mV);
+ mat.mult_matrix_vec(tc);
+ mTransformedSunDir.set(tc.v);
+ }
+
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ if (RenderDeferredSSAO || RenderShadowDetail > 0)
+ {
+ mDeferredLight.bindTarget();
+ { //paint shadow/SSAO light map (direct lighting lightmap)
+ LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW);
+ bindDeferredShader(gDeferredSunProgram);
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ glClearColor(1,1,1,1);
+ mDeferredLight.clear(GL_COLOR_BUFFER_BIT);
+ glClearColor(0,0,0,0);
+
+ glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose();
+
+ const U32 slice = 32;
+ F32 offset[slice*3];
+ for (U32 i = 0; i < 4; i++)
+ {
+ for (U32 j = 0; j < 8; j++)
+ {
+ glh::vec3f v;
+ v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i);
+ v.normalize();
+ inv_trans.mult_matrix_vec(v);
+ v.normalize();
+ offset[(i*8+j)*3+0] = v.v[0];
+ offset[(i*8+j)*3+1] = v.v[2];
+ offset[(i*8+j)*3+2] = v.v[1];
+ }
+ }
+
+ gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset);
+ gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight());
+
+ {
+ LLGLDisable blend(GL_BLEND);
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
+ stop_glerror();
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ stop_glerror();
+ }
+
+ unbindDeferredShader(gDeferredSunProgram);
+ }
+ mDeferredLight.flush();
+ }
+
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ stop_glerror();
+ gGL.popMatrix();
+ stop_glerror();
+
+ target->bindTarget();
+
+ //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky
+ glClearColor(0,0,0,0);
+ target->clear(GL_COLOR_BUFFER_BIT);
+
+ if (RenderDeferredAtmospheric)
+ { //apply sunlight contribution
+ LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS);
+ bindDeferredShader(gDeferredSoftenProgram);
+ {
+ LLGLDepthTest depth(GL_FALSE);
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable test(GL_ALPHA_TEST);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+
+ unbindDeferredShader(gDeferredSoftenProgram);
+ }
+
+ { //render non-deferred geometry (fullbright, alpha, etc)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+ gGL.setSceneBlendType(LLRender::BT_ALPHA);
+
+ gPipeline.pushRenderTypeMask();
+
+ gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
+ LLPipeline::RENDER_TYPE_CLOUDS,
+ LLPipeline::RENDER_TYPE_WL_SKY,
+ LLPipeline::END_RENDER_TYPES);
+
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance(), false);
+ gPipeline.popRenderTypeMask();
+ }
+
+ BOOL render_local = RenderLocalLights;
+
+ if (render_local)
+ {
+ gGL.setSceneBlendType(LLRender::BT_ADD);
+ std::list<LLVector4> fullscreen_lights;
+ LLDrawable::drawable_list_t spot_lights;
+ LLDrawable::drawable_list_t fullscreen_spot_lights;
+
+ for (U32 i = 0; i < 2; i++)
+ {
+ mTargetShadowSpotLight[i] = NULL;
+ }
+
+ std::list<LLVector4> light_colors;
+
+ LLVertexBuffer::unbind();
+
+ {
+ bindDeferredShader(gDeferredLightProgram);
+
+ if (mCubeVB.isNull())
+ {
+ mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB);
+ }
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter)
+ {
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+ if (!volume)
+ {
+ continue;
+ }
+
+ if (volume->isAttachment())
+ {
+ if (!sRenderAttachedLights)
+ {
+ continue;
+ }
+ }
+
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ LLColor3 col = volume->getLightColor();
+
+ if (col.magVecSquared() < 0.001f)
+ {
+ continue;
+ }
+
+ if (s <= 0.001f)
+ {
+ continue;
+ }
+
+ LLVector4a sa;
+ sa.splat(s);
+ if (camera->AABBInFrustumNoFarClip(center, sa) == 0)
+ {
+ continue;
+ }
+
+ sVisibleLightCount++;
+
+ if (camera->getOrigin().mV[0] > c[0] + s + 0.2f ||
+ camera->getOrigin().mV[0] < c[0] - s - 0.2f ||
+ camera->getOrigin().mV[1] > c[1] + s + 0.2f ||
+ camera->getOrigin().mV[1] < c[1] - s - 0.2f ||
+ camera->getOrigin().mV[2] > c[2] + s + 0.2f ||
+ camera->getOrigin().mV[2] < c[2] - s - 0.2f)
+ { //draw box if camera is outside box
+ if (render_local)
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ stop_glerror();
+ }
+ }
+ else
+ {
+ if (volume->isLightSpotlight())
+ {
+ drawablep->getVOVolume()->updateSpotLightPriority();
+ fullscreen_spot_lights.push_back(drawablep);
+ continue;
+ }
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s));
+ light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f));
+ }
+ }
+ unbindDeferredShader(gDeferredLightProgram);
+ }
+
+ if (!spot_lights.empty())
+ {
+ LLGLDepthTest depth(GL_TRUE, GL_FALSE);
+ bindDeferredShader(gDeferredSpotLightProgram);
+
+ mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector4a center;
+ center.load3(drawablep->getPositionAgent().mV);
+ const F32* c = center.getF32ptr();
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ setupSpotLight(gDeferredSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ gGL.syncMatrices();
+
+ mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center));
+ }
+ gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredSpotLightProgram);
+ }
+
+ //reset mDeferredVB to fullscreen triangle
+ mDeferredVB->getVertexStrider(vert);
+ vert[0].set(-1,1,0);
+ vert[1].set(-1,-3,0);
+ vert[2].set(3,1,0);
+
+ {
+ LLGLDepthTest depth(GL_FALSE);
+
+ //full screen blit
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ U32 count = 0;
+
+ const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT;
+ LLVector4 light[max_count];
+ LLVector4 col[max_count];
+
+ F32 far_z = 0.f;
+
+ while (!fullscreen_lights.empty())
+ {
+ LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS);
+ light[count] = fullscreen_lights.front();
+ fullscreen_lights.pop_front();
+ col[count] = light_colors.front();
+ light_colors.pop_front();
+
+ /*col[count].mV[0] = powf(col[count].mV[0], 2.2f);
+ col[count].mV[1] = powf(col[count].mV[1], 2.2f);
+ col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/
+
+ far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z);
+ //col[count] = pow4fsrgb(col[count], 2.2f);
+ count++;
+ if (count == max_count || fullscreen_lights.empty())
+ {
+ U32 idx = count-1;
+ bindDeferredShader(gDeferredMultiLightProgram[idx]);
+ gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light);
+ gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col);
+ gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z);
+ far_z = 0.f;
+ count = 0;
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+ }
+
+ unbindDeferredShader(gDeferredMultiLightProgram[0]);
+
+ bindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+
+ mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+
+ for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter)
+ {
+ LL_RECORD_BLOCK_TIME(FTM_PROJECTORS);
+ LLDrawable* drawablep = *iter;
+
+ LLVOVolume* volume = drawablep->getVOVolume();
+
+ LLVector3 center = drawablep->getPositionAgent();
+ F32* c = center.mV;
+ F32 s = volume->getLightRadius()*1.5f;
+
+ sVisibleLightCount++;
+
+ glh::vec3f tc(c);
+ mat.mult_matrix_vec(tc);
+
+ setupSpotLight(gDeferredMultiSpotLightProgram, drawablep);
+
+ LLColor3 col = volume->getLightColor();
+
+ /*col.mV[0] = powf(col.mV[0], 2.2f);
+ col.mV[1] = powf(col.mV[1], 2.2f);
+ col.mV[2] = powf(col.mV[2], 2.2f);*/
+
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s);
+ gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV);
+ gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f);
+ mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3);
+ }
+
+ gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION);
+ unbindDeferredShader(gDeferredMultiSpotLightProgram);
+
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+ }
+ }
+
+ gGL.setColorMask(true, true);
+ }
+
+ /*target->flush();
+
+ //gamma correct lighting
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.pushMatrix();
+ gGL.loadIdentity();
+
+ {
+ LLGLDepthTest depth(GL_FALSE, GL_FALSE);
+
+ LLVector2 tc1(0,0);
+ LLVector2 tc2((F32) target->getWidth()*2,
+ (F32) target->getHeight()*2);
+
+ target->bindTarget();
+ // Apply gamma correction to the frame here.
+ gDeferredPostGammaCorrectProgram.bind();
+ //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX);
+ S32 channel = 0;
+ channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage());
+ if (channel > -1)
+ {
+ target->bindTexture(0,channel);
+ gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+ }
+
+ gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight());
+
+ F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma");
+
+ gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f));
+
+ 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.getTexUnit(channel)->unbind(target->getUsage());
+ gDeferredPostGammaCorrectProgram.unbind();
+ target->flush();
+ }
+
+ gGL.matrixMode(LLRender::MM_PROJECTION);
+ gGL.popMatrix();
+ gGL.matrixMode(LLRender::MM_MODELVIEW);
+ gGL.popMatrix();
+
+ target->bindTarget();*/
+
+ { //render non-deferred geometry (alpha, fullbright, glow)
+ LLGLDisable blend(GL_BLEND);
+ LLGLDisable stencil(GL_STENCIL_TEST);
+
+ 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,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ END_RENDER_TYPES);
+
+ renderGeomPostDeferred(*LLViewerCamera::getInstance());
+ popRenderTypeMask();
+ }
+
+ //target->flush();
+}
+
void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep)
{
//construct frustum
@@ -8588,6 +9765,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
water_clip = 1;
}
+ bool materials_in_water = false;
+
+#if MATERIALS_IN_REFLECTIONS
+ materials_in_water = gSavedSettings.getS32("RenderWaterMaterials");
+#endif
+
if (!LLViewerCamera::getInstance()->cameraUnderWater())
{ //generate planar reflection map
@@ -8596,7 +9779,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLPipeline::sUseOcclusion = 0;
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();
@@ -8645,11 +9830,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
updateCull(camera, result);
stateSort(camera, result);
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterRef.flush();
+
+ gPipeline.grabReferences(result);
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera, TRUE);
+ }
gPipeline.popRenderTypeMask();
}
+ gGL.setColorMask(true, false);
gPipeline.pushRenderTypeMask();
clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
@@ -8687,9 +9888,23 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
{
gPipeline.grabReferences(ref_result);
LLGLUserClipPlane clip_plane(plane, mat, projection);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
}
}
+ }
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterRef);
+ }
gPipeline.popRenderTypeMask();
}
@@ -8725,10 +9940,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLViewerCamera::updateFrustumPlanes(camera);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
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)
@@ -8744,14 +9961,36 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
gGL.setColorMask(true, true);
mWaterDis.clear();
+
+
gGL.setColorMask(true, false);
+
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ mWaterDis.flush();
+ gPipeline.mDeferredScreen.bindTarget();
+ gGL.setColorMask(true, true);
+ glClearColor(0,0,0,0);
+ gPipeline.mDeferredScreen.clear();
+ gPipeline.grabReferences(result);
+ renderGeomDeferred(camera);
+ }
+ else
+ {
renderGeom(camera);
+ }
+ if (LLPipeline::sRenderDeferred && materials_in_water)
+ {
+ gPipeline.mDeferredScreen.flush();
+ renderDeferredLightingToRT(&mWaterDis);
+ }
}
- LLPipeline::sUnderWaterRender = FALSE;
mWaterDis.flush();
+ LLPipeline::sUnderWaterRender = FALSE;
+
}
last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
@@ -8846,13 +10085,13 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max)
return ret;
}
-static LLFastTimer::DeclareTimer FTM_SHADOW_RENDER("Render Shadows");
-static LLFastTimer::DeclareTimer FTM_SHADOW_ALPHA("Alpha Shadow");
-static LLFastTimer::DeclareTimer FTM_SHADOW_SIMPLE("Simple Shadow");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow");
+static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow");
void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, BOOL use_shader, BOOL use_occlusion, U32 target_width)
{
- LLFastTimer t(FTM_SHADOW_RENDER);
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_RENDER);
//clip out geometry on the same side of water as the camera
S32 occlude = LLPipeline::sUseOcclusion;
@@ -8867,19 +10106,36 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLRenderPass::PASS_FULLBRIGHT,
LLRenderPass::PASS_SHINY,
LLRenderPass::PASS_BUMP,
- LLRenderPass::PASS_FULLBRIGHT_SHINY
+ LLRenderPass::PASS_FULLBRIGHT_SHINY ,
+ LLRenderPass::PASS_MATERIAL,
+ LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLRenderPass::PASS_SPECMAP,
+ LLRenderPass::PASS_SPECMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMMAP,
+ LLRenderPass::PASS_NORMMAP_EMISSIVE,
+ LLRenderPass::PASS_NORMSPEC,
+ LLRenderPass::PASS_NORMSPEC_EMISSIVE,
};
LLGLEnable cull(GL_CULL_FACE);
+ //enable depth clamping if available
+ LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0);
+
if (use_shader)
{
gDeferredShadowCubeProgram.bind();
}
+ LLRenderTarget& occlusion_target = mShadowOcclusion[LLViewerCamera::sCurCameraID-1];
+
+ occlusion_target.bindTarget();
updateCull(shadow_cam, result);
+ occlusion_target.flush();
+
stateSort(shadow_cam, result);
+
//generate shadow map
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
@@ -8910,7 +10166,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gGL.diffuseColor4f(1,1,1,1);
gGL.setColorMask(false, false);
- LLFastTimer ftm(FTM_SHADOW_SIMPLE);
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE);
gGL.getTexUnit(0)->disable();
for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i)
@@ -8936,9 +10192,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
}
{
- LLFastTimer ftm(FTM_SHADOW_ALPHA);
+ LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA);
gDeferredShadowAlphaMaskProgram.bind();
- gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width);
U32 mask = LLVertexBuffer::MAP_VERTEX |
@@ -8946,10 +10201,19 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLVertexBuffer::MAP_COLOR |
LLVertexBuffer::MAP_TEXTURE_INDEX;
- renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
- renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE);
+ renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE);
+ gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE);
+
+ mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX;
+
gDeferredTreeShadowProgram.bind();
+ renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask);
+ renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask);
+
gDeferredTreeShadowProgram.setMinimumAlpha(0.598f);
renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE);
}
@@ -8959,7 +10223,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
gDeferredShadowCubeProgram.bind();
gGLLastMatrix = NULL;
gGL.loadMatrix(gGLModelView);
- doOcclusion(shadow_cam);
+
+ LLRenderTarget& occlusion_source = mShadow[LLViewerCamera::sCurCameraID-1];
+
+ doOcclusion(shadow_cam, occlusion_source, occlusion_target);
if (use_shader)
{
@@ -8978,10 +10245,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera
LLPipeline::sShadowRender = FALSE;
}
-static LLFastTimer::DeclareTimer FTM_VISIBLE_CLOUD("Visible Cloud");
+static LLTrace::BlockTimerStatHandle 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);
+ LL_RECORD_BLOCK_TIME(FTM_VISIBLE_CLOUD);
//get point cloud of intersection of frust and min, max
if (getVisibleExtents(camera, min, max))
@@ -9012,7 +10279,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
//add corners of camera frustum
- for (U32 i = 0; i < 8; i++)
+ for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++)
{
pp.push_back(camera.mAgentFrustum[i]);
}
@@ -9039,7 +10306,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
for (U32 i = 0; i < 12; i++)
{ //for each line segment in bounding box
- for (U32 j = 0; j < 6; j++)
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++)
{ //for each plane in camera frustum
const LLPlane& cp = camera.getAgentPlane(j);
const LLVector3& v1 = pp[bs[i*2+0]];
@@ -9081,9 +10348,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
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 < 6; ++j)
@@ -9128,19 +10392,19 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
}
}
- for (U32 j = 0; j < 6; ++j)
+ for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++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)
- {
+ if (found)
+ {
fp.push_back(pp[i]);
}
}
@@ -9187,7 +10451,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
if (!mHighlightSet.empty())
{
- F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime;
+ F32 transition = gFrameIntervalSeconds.value()/RenderHighlightFadeTime;
LLGLDisable test(GL_ALPHA_TEST);
LLGLDepthTest depth(GL_FALSE);
@@ -9231,7 +10495,7 @@ void LLPipeline::generateHighlight(LLCamera& camera)
}
-static LLFastTimer::DeclareTimer FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
+static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow");
void LLPipeline::generateSunShadow(LLCamera& camera)
{
@@ -9240,7 +10504,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
return;
}
- LLFastTimer t(FTM_GEN_SUN_SHADOW);
+ LL_RECORD_BLOCK_TIME(FTM_GEN_SUN_SHADOW);
BOOL skip_avatar_update = FALSE;
if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
@@ -9283,6 +10547,22 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT,
LLPipeline::RENDER_TYPE_PASS_SHINY,
LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_PASS_MATERIAL_ALPHA_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_SPECMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMMAP_EMISSIVE,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_BLEND,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_MASK,
+ LLPipeline::RENDER_TYPE_PASS_NORMSPEC_EMISSIVE,
END_RENDER_TYPES);
gGL.setColorMask(false, false);
@@ -9309,7 +10589,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
//currently used for amount to extrude frusta corners for constructing shadow frusta
- LLVector3 n = RenderShadowNearDist;
+ //LLVector3 n = 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
@@ -9445,7 +10725,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
mShadowFrustPoints[j].clear();
}
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j);
//restore render matrices
glh_set_current_modelview(saved_view);
@@ -9802,7 +11082,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
{
static LLCullResult result[4];
- //LLGLEnable enable(GL_DEPTH_CLAMP_NV);
renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width);
}
@@ -9822,12 +11101,14 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
if (gen_shadow)
{
- F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f);
+ LLTrace::CountStatHandle<>* velocity_stat = LLViewerCamera::getVelocityStat();
+ F32 fade_amt = gFrameIntervalSeconds.value()
+ * llmax(LLTrace::get_frame_recording().getLastRecording().getSum(*velocity_stat) / LLTrace::get_frame_recording().getLastRecording().getDuration().value(), 1.0);
//update shadow targets
for (U32 i = 0; i < 2; i++)
{ //for each current shadow
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW4+i);
if (mShadowSpotLight[i].notNull() &&
(mShadowSpotLight[i] == mTargetShadowSpotLight[0] ||
@@ -9946,7 +11227,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
static LLCullResult result[2];
- LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4;
+ LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4);
renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width);
@@ -9996,7 +11277,7 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
LLSpatialGroup* group = *i;
if (!group->isDead() &&
(!sUseOcclusion || !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) &&
- gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
+ gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) &&
group->mDrawMap.find(type) != group->mDrawMap.end())
{
pass->renderGroup(group,type,mask,texture);
@@ -10004,11 +11285,11 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL textu
}
}
-static LLFastTimer::DeclareTimer FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
-static LLFastTimer::DeclareTimer FTM_IMPOSTOR_SETUP("Impostor Setup");
-static LLFastTimer::DeclareTimer FTM_IMPOSTOR_BACKGROUND("Impostor Background");
-static LLFastTimer::DeclareTimer FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
-static LLFastTimer::DeclareTimer FTM_IMPOSTOR_RESIZE("Impostor Resize");
+static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_MARK_VISIBLE("Impostor Mark Visible");
+static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_SETUP("Impostor Setup");
+static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_BACKGROUND("Impostor Background");
+static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_ALLOCATE("Impostor Allocate");
+static LLTrace::BlockTimerStatHandle FTM_IMPOSTOR_RESIZE("Impostor Resize");
void LLPipeline::generateImpostor(LLVOAvatar* avatar)
{
@@ -10027,46 +11308,54 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
assertInitialized();
- bool muted = avatar->isVisuallyMuted();
+ bool visually_muted = avatar->isVisuallyMuted();
pushRenderTypeMask();
- if (muted)
+ if (visually_muted)
{
andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);
}
else
{
- andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME,
- LLPipeline::RENDER_TYPE_AVATAR,
+ andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT,
+ LLPipeline::RENDER_TYPE_VOLUME,
+ LLPipeline::RENDER_TYPE_GLOW,
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_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,
+ LLPipeline::RENDER_TYPE_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK,
+ LLPipeline::RENDER_TYPE_INVISIBLE,
+ LLPipeline::RENDER_TYPE_SIMPLE,
END_RENDER_TYPES);
}
S32 occlusion = sUseOcclusion;
sUseOcclusion = 0;
+
sReflectionRender = sRenderDeferred ? FALSE : TRUE;
+
sShadowRender = TRUE;
sImpostorRender = TRUE;
LLViewerCamera* viewer_camera = LLViewerCamera::getInstance();
{
- LLFastTimer t(FTM_IMPOSTOR_MARK_VISIBLE);
+ LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);
markVisible(avatar->mDrawable, *viewer_camera);
LLVOAvatar::sUseImpostors = FALSE;
@@ -10096,7 +11385,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
U32 resX = 0;
{
- LLFastTimer t(FTM_IMPOSTOR_SETUP);
+ LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_SETUP);
const LLVector4a* ext = avatar->mDrawable->getSpatialExtents();
LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset());
@@ -10109,11 +11398,13 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLVector4a left;
left.load3(camera.getLeftAxis().mV);
left.mul(left);
+ llassert(left.dot3(left).getF32() > F_APPROXIMATELY_ZERO);
left.normalize3fast();
LLVector4a up;
up.load3(camera.getUpAxis().mV);
up.mul(up);
+ llassert(up.dot3(up).getF32() > F_APPROXIMATELY_ZERO);
up.normalize3fast();
tdim.mV[0] = fabsf(half_height.dot3(left).getF32());
@@ -10151,33 +11442,60 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (!avatar->mImpostor.isComplete())
{
- LLFastTimer t(FTM_IMPOSTOR_ALLOCATE);
- avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_ALLOCATE);
+
if (LLPipeline::sRenderDeferred)
{
+ avatar->mImpostor.allocate(resX,resY,GL_SRGB8_ALPHA8,TRUE,FALSE);
addDeferredAttachments(avatar->mImpostor);
}
+ else
+ {
+ avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE);
+ }
gGL.getTexUnit(0)->bind(&avatar->mImpostor);
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
}
- else if(resX != avatar->mImpostor.getWidth() ||
- resY != avatar->mImpostor.getHeight())
+ else if(resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight())
{
- LLFastTimer t(FTM_IMPOSTOR_RESIZE);
- avatar->mImpostor.resize(resX,resY,GL_RGBA);
+ LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_RESIZE);
+ avatar->mImpostor.resize(resX,resY);
}
avatar->mImpostor.bindTarget();
}
+ F32 old_alpha = LLDrawPoolAvatar::sMinimumAlpha;
+
+ if (visually_muted)
+ { //disable alpha masking for muted avatars (get whole skin silhouette)
+ LLDrawPoolAvatar::sMinimumAlpha = 0.f;
+ }
+
if (LLPipeline::sRenderDeferred)
{
avatar->mImpostor.clear();
renderGeomDeferred(camera);
+
+ renderGeomPostDeferred(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
renderGeomPostDeferred(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
+
}
else
{
@@ -10185,10 +11503,27 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
glScissor(0, 0, resX, resY);
avatar->mImpostor.clear();
renderGeom(camera);
+
+ // Shameless hack time: render it all again,
+ // this time writing the depth
+ // values we need to generate the alpha mask below
+ // while preserving the alpha-sorted color rendering
+ // from the previous pass
+ //
+ sImpostorRenderAlphaDepthPass = true;
+
+ // depth-only here...
+ //
+ gGL.setColorMask(false,false);
+ renderGeom(camera);
+
+ sImpostorRenderAlphaDepthPass = false;
}
-
+
+ LLDrawPoolAvatar::sMinimumAlpha = old_alpha;
+
{ //create alpha mask based on depth buffer (grey out if muted)
- LLFastTimer t(FTM_IMPOSTOR_BACKGROUND);
+ LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_BACKGROUND);
if (LLPipeline::sRenderDeferred)
{
GLuint buff = GL_COLOR_ATTACHMENT0;
@@ -10197,7 +11532,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
LLGLDisable blend(GL_BLEND);
- if (muted)
+ if (visually_muted)
{
gGL.setColorMask(true, true);
}
@@ -10222,10 +11557,20 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.bind();
+ gDebugProgram.bind();
+ }
+
+
+ if (LLMuteList::getInstance()->isMuted(avatar->getID()))
+ { //grey muted avatar
+ gGL.diffuseColor4ub(64,64,64,255);
+ }
+ else
+ { // Visually muted avatar
+ gGL.diffuseColor4fv( avatar->getMutedAVColor().mV );
}
- gGL.color4ub(64,64,64,255);
+ {
gGL.begin(LLRender::QUADS);
gGL.vertex3f(-1, -1, clip_plane);
gGL.vertex3f(1, -1, clip_plane);
@@ -10233,10 +11578,11 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
gGL.vertex3f(-1, 1, clip_plane);
gGL.end();
gGL.flush();
+ }
if (LLGLSLShader::sNoFixedFunction)
{
- gUIProgram.unbind();
+ gDebugProgram.unbind();
}
gGL.popMatrix();
@@ -10316,7 +11662,7 @@ void LLPipeline::setRenderTypeMask(U32 type, ...)
if (type > END_RENDER_TYPES)
{
- llerrs << "Invalid render type." << llendl;
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
}
}
@@ -10337,7 +11683,7 @@ BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const
if (type > END_RENDER_TYPES)
{
- llerrs << "Invalid render type." << llendl;
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
}
return FALSE;
@@ -10354,7 +11700,7 @@ void LLPipeline::popRenderTypeMask()
{
if (mRenderTypeEnableStack.empty())
{
- llerrs << "Depleted render type stack." << llendl;
+ LL_ERRS() << "Depleted render type stack." << LL_ENDL;
}
memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled));
@@ -10385,7 +11731,7 @@ void LLPipeline::andRenderTypeMask(U32 type, ...)
if (type > END_RENDER_TYPES)
{
- llerrs << "Invalid render type." << llendl;
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
}
for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i)
@@ -10410,7 +11756,23 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)
if (type > END_RENDER_TYPES)
{
- llerrs << "Invalid render type." << llendl;
+ LL_ERRS() << "Invalid render type." << LL_ENDL;
+ }
+}
+
+void LLPipeline::setAllRenderTypes()
+{
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = TRUE;
+ }
+}
+
+void LLPipeline::clearAllRenderTypes()
+{
+ for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+ {
+ mRenderTypeEnabled[i] = FALSE;
}
}
@@ -10557,6 +11919,3 @@ void LLPipeline::restoreHiddenObject( const LLUUID& id )
}
}
-
-
-