diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 5009 |
1 files changed, 2924 insertions, 2085 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 15477e0a80..ab994c71cb 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -67,6 +67,7 @@ #include "llhudnametag.h" #include "llhudtext.h" #include "lllightconstants.h" +#include "llmeshrepository.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llsky.h" @@ -74,6 +75,7 @@ #include "lltool.h" #include "lltoolmgr.h" #include "llviewercamera.h" +#include "llviewermediafocus.h" #include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -100,6 +102,8 @@ #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" +#include "llcurl.h" +#include "llnotifications.h" #ifdef _DEBUG @@ -109,13 +113,88 @@ //#define DEBUG_INDICES #endif +//cached settings +BOOL LLPipeline::RenderAvatarVP; +BOOL LLPipeline::VertexShaderEnable; +BOOL LLPipeline::WindLightUseAtmosShaders; +BOOL LLPipeline::RenderDeferred; +F32 LLPipeline::RenderDeferredSunWash; +U32 LLPipeline::RenderFSAASamples; +U32 LLPipeline::RenderResolutionDivisor; +BOOL LLPipeline::RenderUIBuffer; +S32 LLPipeline::RenderShadowDetail; +BOOL LLPipeline::RenderDeferredSSAO; +F32 LLPipeline::RenderShadowResolutionScale; +BOOL LLPipeline::RenderLocalLights; +BOOL LLPipeline::RenderDelayCreation; +BOOL LLPipeline::RenderAnimateRes; +BOOL LLPipeline::FreezeTime; +S32 LLPipeline::DebugBeaconLineWidth; +F32 LLPipeline::RenderHighlightBrightness; +LLColor4 LLPipeline::RenderHighlightColor; +F32 LLPipeline::RenderHighlightThickness; +BOOL LLPipeline::RenderSpotLightsInNondeferred; +LLColor4 LLPipeline::PreviewAmbientColor; +LLColor4 LLPipeline::PreviewDiffuse0; +LLColor4 LLPipeline::PreviewSpecular0; +LLColor4 LLPipeline::PreviewDiffuse1; +LLColor4 LLPipeline::PreviewSpecular1; +LLColor4 LLPipeline::PreviewDiffuse2; +LLColor4 LLPipeline::PreviewSpecular2; +LLVector3 LLPipeline::PreviewDirection0; +LLVector3 LLPipeline::PreviewDirection1; +LLVector3 LLPipeline::PreviewDirection2; +F32 LLPipeline::RenderGlowMinLuminance; +F32 LLPipeline::RenderGlowMaxExtractAlpha; +F32 LLPipeline::RenderGlowWarmthAmount; +LLVector3 LLPipeline::RenderGlowLumWeights; +LLVector3 LLPipeline::RenderGlowWarmthWeights; +S32 LLPipeline::RenderGlowResolutionPow; +S32 LLPipeline::RenderGlowIterations; +F32 LLPipeline::RenderGlowWidth; +F32 LLPipeline::RenderGlowStrength; +BOOL LLPipeline::RenderDepthOfField; +F32 LLPipeline::CameraFocusTransitionTime; +F32 LLPipeline::CameraFNumber; +F32 LLPipeline::CameraFocalLength; +F32 LLPipeline::CameraFieldOfView; +F32 LLPipeline::RenderShadowNoise; +F32 LLPipeline::RenderShadowBlurSize; +F32 LLPipeline::RenderSSAOScale; +U32 LLPipeline::RenderSSAOMaxScale; +F32 LLPipeline::RenderSSAOFactor; +LLVector3 LLPipeline::RenderSSAOEffect; +F32 LLPipeline::RenderShadowOffsetError; +F32 LLPipeline::RenderShadowBiasError; +F32 LLPipeline::RenderShadowOffset; +F32 LLPipeline::RenderShadowBias; +F32 LLPipeline::RenderSpotShadowOffset; +F32 LLPipeline::RenderSpotShadowBias; +F32 LLPipeline::RenderEdgeDepthCutoff; +F32 LLPipeline::RenderEdgeNormCutoff; +LLVector3 LLPipeline::RenderShadowGaussian; +F32 LLPipeline::RenderShadowBlurDistFactor; +BOOL LLPipeline::RenderDeferredAtmospheric; +S32 LLPipeline::RenderReflectionDetail; +F32 LLPipeline::RenderHighlightFadeTime; +LLVector3 LLPipeline::RenderShadowClipPlanes; +LLVector3 LLPipeline::RenderShadowOrthoClipPlanes; +LLVector3 LLPipeline::RenderShadowNearDist; +F32 LLPipeline::RenderFarClip; +LLVector3 LLPipeline::RenderShadowSplitExponent; +F32 LLPipeline::RenderShadowErrorCutoff; +F32 LLPipeline::RenderShadowFOVCutoff; +BOOL LLPipeline::CameraOffset; +F32 LLPipeline::CameraMaxCoF; +F32 LLPipeline::CameraDoFResScale; + 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; @@ -124,10 +203,6 @@ extern S32 gBoxFrame; extern BOOL gDisplaySwapBuffers; extern BOOL gDebugGL; -// hack counter for rendering a fixed number of frames after toggling -// fullscreen to work around DEV-5361 -static S32 sDelayedVBOEnable = 0; - BOOL gAvatarBacklight = FALSE; BOOL gDebugPipeline = FALSE; @@ -169,40 +244,30 @@ std::string gPoolNames[] = // Correspond to LLDrawpool enum render type "NONE", "POOL_SIMPLE", - "POOL_TERRAIN", + "POOL_GROUND", + "POOL_FULLBRIGHT", "POOL_BUMP", - "POOL_TREE", + "POOL_TERRAIN," "POOL_SKY", "POOL_WL_SKY", - "POOL_GROUND", + "POOL_TREE", + "POOL_GRASS", "POOL_INVISIBLE", "POOL_AVATAR", + "POOL_VOIDWATER", "POOL_WATER", - "POOL_GRASS", - "POOL_FULLBRIGHT", "POOL_GLOW", - "POOL_ALPHA", + "POOL_ALPHA" }; void drawBox(const LLVector3& c, const LLVector3& r); void drawBoxOutline(const LLVector3& pos, const LLVector3& size); +U32 nhpo2(U32 v); -U32 nhpo2(U32 v) -{ - U32 r = 1; - while (r < v) { - r *= 2; - } - return r; -} - -glh::matrix4f glh_copy_matrix(GLdouble* src) +glh::matrix4f glh_copy_matrix(F32* src) { glh::matrix4f ret; - for (U32 i = 0; i < 16; i++) - { - ret.m[i] = (F32) src[i]; - } + ret.set_value(src); return ret; } @@ -216,7 +281,17 @@ glh::matrix4f glh_get_current_projection() return glh_copy_matrix(gGLProjection); } -void glh_copy_matrix(const glh::matrix4f& src, GLdouble* dst) +glh::matrix4f glh_get_last_modelview() +{ + return glh_copy_matrix(gGLLastModelView); +} + +glh::matrix4f glh_get_last_projection() +{ + return glh_copy_matrix(gGLLastProjection); +} + +void glh_copy_matrix(const glh::matrix4f& src, F32* dst) { for (U32 i = 0; i < 16; i++) { @@ -253,6 +328,7 @@ S32 LLPipeline::sCompiles = 0; BOOL LLPipeline::sPickAvatar = TRUE; BOOL LLPipeline::sDynamicLOD = TRUE; BOOL LLPipeline::sShowHUDAttachments = TRUE; +BOOL LLPipeline::sRenderMOAPBeacons = FALSE; BOOL LLPipeline::sRenderPhysicalBeacons = TRUE; BOOL LLPipeline::sRenderScriptedBeacons = FALSE; BOOL LLPipeline::sRenderScriptedTouchBeacons = TRUE; @@ -267,6 +343,8 @@ BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; BOOL LLPipeline::sAutoMaskAlphaNonDeferred = FALSE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; +BOOL LLPipeline::sBakeSunlight = FALSE; +BOOL LLPipeline::sNoAlpha = FALSE; BOOL LLPipeline::sUseTriStrips = TRUE; BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sShadowRender = FALSE; @@ -280,7 +358,7 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; -BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; +BOOL LLPipeline::sMemAllocationThrottled = FALSE; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -300,10 +378,10 @@ static const U32 gl_cube_face[] = void validate_framebuffer_object(); -void addDeferredAttachments(LLRenderTarget& target) +bool addDeferredAttachments(LLRenderTarget& target) { - target.addColorAttachment(GL_RGBA); //specular - target.addColorAttachment(GL_RGBA); //normal+z + return target.addColorAttachment(GL_RGBA) && //specular + target.addColorAttachment(GL_RGBA); //normal+z } LLPipeline::LLPipeline() : @@ -327,6 +405,9 @@ LLPipeline::LLPipeline() : mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), + mGroupQ1Locked(false), + mGroupQ2Locked(false), + mResetVertexBuffers(false), mLastRebuildPool(NULL), mAlphaPool(NULL), mSkyPool(NULL), @@ -354,10 +435,15 @@ void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); + refreshCachedSettings(); + + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -392,6 +478,14 @@ void LLPipeline::init() toggleRenderType(RENDER_TYPE_GROUND); } + // make sure RenderPerformanceTest persists (hackity hack hack) + // disables non-object rendering (UI, sky, water, etc) + if (gSavedSettings.getBOOL("RenderPerformanceTest")) + { + gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); + gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); + } + mOldRenderDebugMask = mRenderDebugMask; mBackfaceCull = TRUE; @@ -409,7 +503,95 @@ void LLPipeline::init() mSpotLightFade[i] = 1.f; } + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); + mDeferredVB->allocateBuffer(8, 0, true); setLightingDetail(-1); + + // + // Update all settings to trigger a cached settings refresh + // + + gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderUseFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderAvatarMaxVisible")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDelayVBUpdate")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + + gSavedSettings.getControl("UseOcclusion")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + + gSavedSettings.getControl("VertexShaderEnable")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderAvatarVP")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("WindLightUseAtmosShaders")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDeferredSunWash")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderFSAASamples")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderResolutionDivisor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderUIBuffer")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDeferredSSAO")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowResolutionScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderLocalLights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDelayCreation")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderAnimateRes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("FreezeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("DebugBeaconLineWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderHighlightBrightness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderHighlightColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderHighlightThickness")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSpotLightsInNondeferred")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewAmbientColor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDiffuse0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewSpecular0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDiffuse1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewSpecular1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDiffuse2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewSpecular2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDirection0")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDirection1")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("PreviewDirection2")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowMinLuminance")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowMaxExtractAlpha")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowWarmthAmount")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowLumWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowWarmthWeights")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowResolutionPow")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowIterations")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowWidth")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderGlowStrength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDepthOfField")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraFocusTransitionTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraFNumber")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraFocalLength")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraFieldOfView")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowNoise")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowBlurSize")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSSAOScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSSAOMaxScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSSAOFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSSAOEffect")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowOffsetError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowBiasError")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSpotShadowOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderSpotShadowBias")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderEdgeDepthCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderEdgeNormCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowGaussian")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowBlurDistFactor")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderDeferredAtmospheric")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderReflectionDetail")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderHighlightFadeTime")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowOrthoClipPlanes")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowNearDist")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderFarClip")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowSplitExponent")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowErrorCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("RenderShadowFOVCutoff")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraOffset")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraMaxCoF")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); + gSavedSettings.getControl("CameraDoFResScale")->getCommitSignal()->connect(boost::bind(&LLPipeline::refreshCachedSettings)); } LLPipeline::~LLPipeline() @@ -487,6 +669,8 @@ void LLPipeline::cleanup() mMovedBridge.clear(); mInitialized = FALSE; + + mDeferredVB = NULL; } //============================================================================ @@ -505,14 +689,30 @@ void LLPipeline::destroyGL() if (LLVertexBuffer::sEnableVBOs) { - // render 30 frames after switching to work around DEV-5361 - sDelayedVBOEnable = 30; LLVertexBuffer::sEnableVBOs = FALSE; } } static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); +//static +void LLPipeline::throttleNewMemoryAllocation(BOOL disable) +{ + if(sMemAllocationThrottled != disable) + { + sMemAllocationThrottled = disable ; + + if(sMemAllocationThrottled) + { + //send out notification + LLNotification::Params params("LowMemory"); + LLNotifications::instance().add(params); + + //release some memory. + } + } +} + void LLPipeline::resizeScreenTexture() { LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); @@ -525,15 +725,75 @@ void LLPipeline::resizeScreenTexture() } } +void LLPipeline::allocatePhysicsBuffer() +{ + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) + { + mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } +} + void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { + refreshCachedSettings(); + U32 samples = RenderFSAASamples; + + //try to allocate screen buffers at requested resolution and samples + // - on failure, shrink number of samples and try again + // - if not multisampled, shrink resolution and try again (favor X resolution over Y) + // Make sure to call "releaseScreenBuffers" after each failure to cleanup the partially loaded state + + if (!allocateScreenBuffer(resX, resY, samples)) + { + releaseScreenBuffers(); + //reduce number of samples + while (samples > 0) + { + samples /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { //success + return; + } + releaseScreenBuffers(); + } + + samples = 0; + + //reduce resolution + while (resY > 0 && resX > 0) + { + resY /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return; + } + releaseScreenBuffers(); + + resX /= 2; + if (allocateScreenBuffer(resX, resY, samples)) + { + return; + } + releaseScreenBuffers(); + } + + llwarns << "Unable to allocate screen buffer at any resolution!" << llendl; + } +} + + +bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) +{ + refreshCachedSettings(); + // remember these dimensions mScreenWidth = resX; mScreenHeight = resY; - //never use more than 4 samples for render targets - U32 samples = llmin(gSavedSettings.getU32("RenderFSAASamples"), (U32) 4); - U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); + U32 res_mod = RenderResolutionDivisor; if (res_mod > 1 && res_mod < resX && res_mod < resY) { @@ -541,101 +801,222 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) resY /= res_mod; } - if (gSavedSettings.getBOOL("RenderUIBuffer")) + if (RenderUIBuffer) { - mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + if (!mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) + { + return false; + } } if (LLPipeline::sRenderDeferred) { + // Set this flag in case we crash while resizing window or allocating space for deferred rendering targets + gSavedSettings.setBOOL("RenderInitError", TRUE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); + + S32 shadow_detail = RenderShadowDetail; + BOOL ssao = RenderDeferredSSAO; + //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - addDeferredAttachments(mDeferredScreen); + if (!mDeferredScreen.allocate(resX, resY, GL_RGBA, 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 (!addDeferredAttachments(mDeferredScreen)) return false; - mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - - for (U32 i = 0; i < 3; i++) + if (!mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; + if (samples > 0) { - mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + if (!mFXAABuffer.allocate(nhpo2(resX), nhpo2(resY), GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE, samples)) return false; } - - for (U32 i = 0; i < 2; i++) + else { - mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mFXAABuffer.release(); + } + + if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0) + { //only need mDeferredLight for shadows OR ssao OR dof OR fxaa + if (!mDeferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + } + else + { + mDeferredLight.release(); } - F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); - - //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) - U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; + F32 scale = RenderShadowResolutionScale; - for (U32 i = 0; i < 4; i++) + if (shadow_detail > 0) + { //allocate 4 sun shadow maps + for (U32 i = 0; i < 4; i++) + { + if (!mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE)) return false; + } + } + else { - mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + for (U32 i = 0; i < 4; i++) + { + mShadow[i].release(); + } } - U32 width = nhpo2(U32(resX*scale))/2; U32 height = width; - for (U32 i = 4; i < 6; i++) + if (shadow_detail > 1) + { //allocate two spot shadow maps + for (U32 i = 4; i < 6; i++) + { + if (!mShadow[i].allocate(width, height, 0, TRUE, FALSE)) return false; + } + } + else { - mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + for (U32 i = 4; i < 6; i++) + { + mShadow[i].release(); + } } - width = nhpo2(resX)/2; - height = nhpo2(resY)/2; - mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); + // don't disable shaders on next session + gSavedSettings.setBOOL("RenderInitError", FALSE); + gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE ); } else { - mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - } - - - if (LLRenderTarget::sUseFBO && gGLManager.mHasFramebufferMultisample && samples > 1) - { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); - if (LLPipeline::sRenderDeferred) + mDeferredLight.release(); + + for (U32 i = 0; i < 6; i++) { - addDeferredAttachments(mSampleBuffer); - mDeferredScreen.setSampleBuffer(&mSampleBuffer); + mShadow[i].release(); } - - mScreen.setSampleBuffer(&mSampleBuffer); - - stop_glerror(); + mFXAABuffer.release(); + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + + if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; } if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 3; i++) - { //share stencil buffer with screen space lightmap to stencil out sky - mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); - } } gGL.getTexUnit(0)->disable(); stop_glerror(); + return true; } //static void LLPipeline::updateRenderDeferred() { - BOOL deferred = ((gSavedSettings.getBOOL("RenderDeferred") && + BOOL deferred = ((RenderDeferred && LLRenderTarget::sUseFBO && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - gSavedSettings.getBOOL("VertexShaderEnable") && - gSavedSettings.getBOOL("RenderAvatarVP") && - gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + VertexShaderEnable && + RenderAvatarVP && + WindLightUseAtmosShaders) ? TRUE : FALSE) && !gUseWireframe; - sRenderDeferred = deferred; + sRenderDeferred = deferred; + if (deferred) + { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all + sRenderGlow = TRUE; + } +} + +//static +void LLPipeline::refreshCachedSettings() +{ + LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); + LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred"); + LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip"); + LLVOAvatar::sMaxVisible = (U32)gSavedSettings.getS32("RenderAvatarMaxVisible"); + LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); + + LLPipeline::sUseOcclusion = + (!gUseWireframe + && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") + && gSavedSettings.getBOOL("UseOcclusion") + && gGLManager.mHasOcclusionQuery) ? 2 : 0; + + VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); + RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); + WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); + RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); + RenderDeferredSunWash = gSavedSettings.getF32("RenderDeferredSunWash"); + RenderFSAASamples = gSavedSettings.getU32("RenderFSAASamples"); + RenderResolutionDivisor = gSavedSettings.getU32("RenderResolutionDivisor"); + RenderUIBuffer = gSavedSettings.getBOOL("RenderUIBuffer"); + RenderShadowDetail = gSavedSettings.getS32("RenderShadowDetail"); + RenderDeferredSSAO = gSavedSettings.getBOOL("RenderDeferredSSAO"); + RenderShadowResolutionScale = gSavedSettings.getF32("RenderShadowResolutionScale"); + RenderLocalLights = gSavedSettings.getBOOL("RenderLocalLights"); + RenderDelayCreation = gSavedSettings.getBOOL("RenderDelayCreation"); + RenderAnimateRes = gSavedSettings.getBOOL("RenderAnimateRes"); + FreezeTime = gSavedSettings.getBOOL("FreezeTime"); + DebugBeaconLineWidth = gSavedSettings.getS32("DebugBeaconLineWidth"); + RenderHighlightBrightness = gSavedSettings.getF32("RenderHighlightBrightness"); + RenderHighlightColor = gSavedSettings.getColor4("RenderHighlightColor"); + RenderHighlightThickness = gSavedSettings.getF32("RenderHighlightThickness"); + RenderSpotLightsInNondeferred = gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"); + PreviewAmbientColor = gSavedSettings.getColor4("PreviewAmbientColor"); + PreviewDiffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); + PreviewSpecular0 = gSavedSettings.getColor4("PreviewSpecular0"); + PreviewDiffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); + PreviewSpecular1 = gSavedSettings.getColor4("PreviewSpecular1"); + PreviewDiffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); + PreviewSpecular2 = gSavedSettings.getColor4("PreviewSpecular2"); + PreviewDirection0 = gSavedSettings.getVector3("PreviewDirection0"); + PreviewDirection1 = gSavedSettings.getVector3("PreviewDirection1"); + PreviewDirection2 = gSavedSettings.getVector3("PreviewDirection2"); + RenderGlowMinLuminance = gSavedSettings.getF32("RenderGlowMinLuminance"); + RenderGlowMaxExtractAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); + RenderGlowWarmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); + RenderGlowLumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); + RenderGlowWarmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); + RenderGlowResolutionPow = gSavedSettings.getS32("RenderGlowResolutionPow"); + RenderGlowIterations = gSavedSettings.getS32("RenderGlowIterations"); + RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth"); + RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength"); + RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField"); + CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime"); + CameraFNumber = gSavedSettings.getF32("CameraFNumber"); + CameraFocalLength = gSavedSettings.getF32("CameraFocalLength"); + CameraFieldOfView = gSavedSettings.getF32("CameraFieldOfView"); + RenderShadowNoise = gSavedSettings.getF32("RenderShadowNoise"); + RenderShadowBlurSize = gSavedSettings.getF32("RenderShadowBlurSize"); + RenderSSAOScale = gSavedSettings.getF32("RenderSSAOScale"); + RenderSSAOMaxScale = gSavedSettings.getU32("RenderSSAOMaxScale"); + RenderSSAOFactor = gSavedSettings.getF32("RenderSSAOFactor"); + RenderSSAOEffect = gSavedSettings.getVector3("RenderSSAOEffect"); + RenderShadowOffsetError = gSavedSettings.getF32("RenderShadowOffsetError"); + RenderShadowBiasError = gSavedSettings.getF32("RenderShadowBiasError"); + RenderShadowOffset = gSavedSettings.getF32("RenderShadowOffset"); + RenderShadowBias = gSavedSettings.getF32("RenderShadowBias"); + RenderSpotShadowOffset = gSavedSettings.getF32("RenderSpotShadowOffset"); + RenderSpotShadowBias = gSavedSettings.getF32("RenderSpotShadowBias"); + RenderEdgeDepthCutoff = gSavedSettings.getF32("RenderEdgeDepthCutoff"); + RenderEdgeNormCutoff = gSavedSettings.getF32("RenderEdgeNormCutoff"); + RenderShadowGaussian = gSavedSettings.getVector3("RenderShadowGaussian"); + RenderShadowBlurDistFactor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + RenderDeferredAtmospheric = gSavedSettings.getBOOL("RenderDeferredAtmospheric"); + RenderReflectionDetail = gSavedSettings.getS32("RenderReflectionDetail"); + RenderHighlightFadeTime = gSavedSettings.getF32("RenderHighlightFadeTime"); + RenderShadowClipPlanes = gSavedSettings.getVector3("RenderShadowClipPlanes"); + RenderShadowOrthoClipPlanes = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); + RenderShadowNearDist = gSavedSettings.getVector3("RenderShadowNearDist"); + RenderFarClip = gSavedSettings.getF32("RenderFarClip"); + RenderShadowSplitExponent = gSavedSettings.getVector3("RenderShadowSplitExponent"); + RenderShadowErrorCutoff = gSavedSettings.getF32("RenderShadowErrorCutoff"); + RenderShadowFOVCutoff = gSavedSettings.getF32("RenderShadowFOVCutoff"); + CameraOffset = gSavedSettings.getBOOL("CameraOffset"); + CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); + CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); + + updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() @@ -654,46 +1035,53 @@ void LLPipeline::releaseGLBuffers() mTrueNoiseMap = 0; } + releaseLUTBuffers(); + + mWaterRef.release(); + mWaterDis.release(); + + for (U32 i = 0; i < 3; i++) + { + mGlow[i].release(); + } + + releaseScreenBuffers(); + + gBumpImageList.destroyGL(); + LLVOAvatar::resetImpostors(); +} + +void LLPipeline::releaseLUTBuffers() +{ if (mLightFunc) { LLImageGL::deleteTextures(1, &mLightFunc); mLightFunc = 0; } +} - mWaterRef.release(); - mWaterDis.release(); - mScreen.release(); +void LLPipeline::releaseScreenBuffers() +{ mUIScreen.release(); - mSampleBuffer.releaseSampleBuffer(); + mScreen.release(); + mFXAABuffer.release(); + mPhysicsDisplay.release(); mDeferredScreen.release(); mDeferredDepth.release(); - for (U32 i = 0; i < 3; i++) - { - mDeferredLight[i].release(); - } - - mEdgeMap.release(); - mGIMap.release(); - mGIMapPost[0].release(); - mGIMapPost[1].release(); - mHighlight.release(); - mLuminanceMap.release(); + mDeferredLight.release(); + mHighlight.release(); + for (U32 i = 0; i < 6; i++) { mShadow[i].release(); } - - for (U32 i = 0; i < 3; i++) - { - mGlow[i].release(); - } - - LLVOAvatar::resetImpostors(); } + void LLPipeline::createGLBuffers() { + stop_glerror(); LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS); assertInitialized(); @@ -701,10 +1089,11 @@ void LLPipeline::createGLBuffers() if (LLPipeline::sWaterReflections) { //water reflection texture - U32 res = (U32) gSavedSettings.getS32("RenderWaterRefResolution"); + U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); - mWaterDis.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); @@ -727,7 +1116,6 @@ void LLPipeline::createGLBuffers() allocateScreenBuffer(resX,resY); mScreenWidth = 0; mScreenHeight = 0; - } if (sRenderDeferred) @@ -767,54 +1155,69 @@ void LLPipeline::createGLBuffers() gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + createLUTBuffers(); + } + + gBumpImageList.restoreGL(); +} + +void LLPipeline::createLUTBuffers() +{ + if (sRenderDeferred) + { if (!mLightFunc) { U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); - U8* lg = new U8[lightResX*lightResY]; - + U8* ls = new U8[lightResX*lightResY]; + F32 specExp = gSavedSettings.getF32("RenderSpecularExponent"); + // Calculate the (normalized) Blinn-Phong specular lookup texture. for (U32 y = 0; y < lightResY; ++y) { for (U32 x = 0; x < lightResX; ++x) { - //spec func + ls[y*lightResX+x] = 0; F32 sa = (F32) x/(lightResX-1); F32 spec = (F32) y/(lightResY-1); - //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); - - //F32 sp = acosf(sa)/(1.f-spec); - - sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); - F32 a = acosf(sa*0.25f+0.75f); - F32 m = llmax(0.5f-spec*0.5f, 0.001f); - F32 t2 = tanf(a)/m; - t2 *= t2; - - F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; - F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); - - lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); + F32 n = spec * spec * specExp; + + // Nothing special here. Just your typical blinn-phong term. + spec = powf(sa, n); + + // 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); } } - + LLImageGL::generateTextures(1, &mLightFunc); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); - LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_R8, lightResX, lightResY, GL_RED, GL_UNSIGNED_BYTE, ls); gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - - delete [] lg; - } - - if (gSavedSettings.getBOOL("RenderDeferredGI")) - { - mGIMap.allocate(512,512,GL_RGBA, TRUE, FALSE); - addDeferredAttachments(mGIMap); + + delete [] ls; } } } -void LLPipeline::restoreGL() + +void LLPipeline::restoreGL() { LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_RESTORE_GL); assertInitialized(); @@ -842,10 +1245,12 @@ void LLPipeline::restoreGL() BOOL LLPipeline::canUseVertexShaders() { + static const std::string vertex_shader_enable_feature_string = "VertexShaderEnable"; + if (sDisableShaders || !gGLManager.mHasVertexShader || !gGLManager.mHasFragmentShader || - !LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable") || + !LLFeatureManager::getInstance()->isFeatureAvailable(vertex_shader_enable_feature_string) || (assertInitialized() && mVertexShadersLoaded != 1) ) { return FALSE; @@ -871,7 +1276,7 @@ BOOL LLPipeline::canUseWindLightShadersOnObjects() const BOOL LLPipeline::canUseAntiAliasing() const { - return TRUE; //(gSavedSettings.getBOOL("RenderUseFBO")); + return TRUE; } void LLPipeline::unloadShaders() @@ -909,11 +1314,11 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL); - assertInitialized(); + refreshCachedSettings(); if (level < 0) { - if (gSavedSettings.getBOOL("VertexShaderEnable")) + if (RenderLocalLights) { level = 1; } @@ -923,15 +1328,8 @@ S32 LLPipeline::setLightingDetail(S32 level) } } level = llclamp(level, 0, getMaxLightingDetail()); - if (level != mLightingDetail) - { - mLightingDetail = level; - - if (mVertexShadersLoaded == 1) - { - LLViewerShaderMgr::instance()->setShaders(); - } - } + mLightingDetail = level; + return mLightingDetail; } @@ -1157,9 +1555,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) } +static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set"); + void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LLFastTimer t(FTM_PIPELINE); + LLFastTimer t(FTM_UNLINK); assertInitialized(); @@ -1168,6 +1572,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) // Based on flags, remove the drawable from the queues that it's on. if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) { + LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST); LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); if (iter != mMovedList.end()) { @@ -1177,6 +1582,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { + LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -1187,18 +1593,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } } - mLights.erase(drawablep); - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) { - if (iter->drawable == drawablep) + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + mLights.erase(drawablep); + + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) { - mNearbyLights.erase(iter); - break; + if (iter->drawable == drawablep) + { + mNearbyLights.erase(iter); + break; + } } } { + LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET); HighlightItem item(drawablep); mHighlightSet.erase(item); @@ -1227,12 +1638,8 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) U32 LLPipeline::addObject(LLViewerObject *vobj) { LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT); - if (gNoRender) - { - return 0; - } - if (gSavedSettings.getBOOL("RenderDelayCreation")) + if (RenderDelayCreation) { mCreateQ.push_back(vobj); } @@ -1295,7 +1702,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) markRebuild(drawablep, LLDrawable::REBUILD_ALL, TRUE); - if (drawablep->getVOVolume() && gSavedSettings.getBOOL("RenderAnimateRes")) + if (drawablep->getVOVolume() && RenderAnimateRes) { // fun animated res drawablep->updateXform(TRUE); @@ -1334,7 +1741,7 @@ void LLPipeline::resetFrameStats() //external functions for asynchronous updating void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) { - if (gSavedSettings.getBOOL("FreezeTime")) + if (FreezeTime) { return; } @@ -1364,7 +1771,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) { - if (gSavedSettings.getBOOL("FreezeTime")) + if (FreezeTime) { return; } @@ -1421,7 +1828,7 @@ void LLPipeline::updateMove() LLFastTimer t(FTM_UPDATE_MOVE); LLMemType mt_um(LLMemType::MTYPE_PIPELINE_UPDATE_MOVE); - if (gSavedSettings.getBOOL("FreezeTime")) + if (FreezeTime) { return; } @@ -1495,11 +1902,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera return radius*radius * F_PI; } +//static +F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) +{ + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.getLength3().getF32(); + + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + + //get area of circle around node + F32 app_angle = atanf(size.getLength3().getF32()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; +} + void LLPipeline::grabReferences(LLCullResult& result) { sCull = &result; } +void LLPipeline::clearReferences() +{ + sCull = NULL; +} + +void check_references(LLSpatialGroup* group, LLDrawable* drawable) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + if (drawable == *i) + { + llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; + } + } +} + +void check_references(LLDrawable* drawable, LLFace* face) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl; + } + } +} + +void check_references(LLSpatialGroup* group, LLFace* face) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + check_references(drawable, face); + } +} + +void LLPipeline::checkReferences(LLFace* face) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } +#endif +} + +void LLPipeline::checkReferences(LLDrawable* drawable) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + +void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) +{ + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl; + } + } + } +} + + +void LLPipeline::checkReferences(LLDrawInfo* draw_info) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } +#endif +} + +void LLPipeline::checkReferences(LLSpatialGroup* group) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + + BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1566,7 +2176,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLFastTimer::DeclareTimer FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { LLFastTimer t(FTM_CULL); LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL); @@ -1586,13 +2196,18 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.bindTarget(); } - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixd(gGLLastProjection); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadMatrix(gGLLastProjection); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); gGLLastMatrix = NULL; - glLoadMatrixd(gGLLastModelView); + gGL.loadMatrix(gGLLastModelView); LLVertexBuffer::unbind(); @@ -1600,13 +2215,48 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (sUseOcclusion > 1) + + //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling) + LLViewerRegion* region = gAgent.getRegion(); + LLPlane plane; + + if (planep) { - gGL.setColorMask(false, false); + plane = *planep; } + else + { + if (region) + { + LLVector3 pnorm; + F32 height = region->getWaterHeight(); + if (water_clip < 0) + { //camera is above water, clip plane points up + pnorm.setVec(0,0,1); + plane.setVec(pnorm, -height); + } + else if (water_clip > 0) + { //camera is below water, clip plane points down + pnorm = LLVector3(0,0,-1); + plane.setVec(pnorm, height); + } + } + } + + glh::matrix4f modelview = glh_get_last_modelview(); + glh::matrix4f proj = glh_get_last_projection(); + LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bool bound_shader = false; + if (gPipeline.canUseVertexShaders() && LLGLSLShader::sCurBoundShader == 0) + { //if no shader is currently bound, use the occlusion shader instead of fixed function if we can + // (shadow render uses a special shader that clamps to clip planes) + bound_shader = true; + gOcclusionProgram.bind(); + } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -1634,6 +2284,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } } + if (bound_shader) + { + gOcclusionProgram.unbind(); + } + camera.disableUserClipPlane(); if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && @@ -1657,10 +2312,10 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); if (sUseOcclusion > 1) { @@ -1695,7 +2350,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) { return; } @@ -1739,33 +2394,60 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::doOcclusion(LLCamera& camera) { - LLVertexBuffer::unbind(); - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) - { - gGL.setColorMask(true, false, false, false); - } - else + if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups()) { - gGL.setColorMask(false, false); - } - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLVertexBuffer::unbind(); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + gGL.setColorMask(true, false, false, false); + } + else + { + gGL.setColorMask(false, false); + } + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + LLGLDisable cull(GL_CULL_FACE); + + + bool bind_shader = LLGLSLShader::sNoFixedFunction && LLGLSLShader::sCurBoundShader == 0; + if (bind_shader) + { + if (LLPipeline::sShadowRender) + { + gDeferredShadowProgram.bind(); + } + else + { + gOcclusionProgram.bind(); + } + } - LLGLDisable cull(GL_CULL_FACE); - if (LLPipeline::sUseOcclusion > 1) - { for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } - } + + if (bind_shader) + { + if (LLPipeline::sShadowRender) + { + gDeferredShadowProgram.unbind(); + } + else + { + gOcclusionProgram.unbind(); + } + } - gGL.setColorMask(true, false); + gGL.setColorMask(true, false); + } } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) @@ -1792,17 +2474,14 @@ void LLPipeline::updateGL() void LLPipeline::rebuildPriorityGroups() { - if(!sAllowRebuildPriorityGroup) - { - return ; - } - sAllowRebuildPriorityGroup = FALSE ; - LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); assertInitialized(); + gMeshRepo.notifyLoadedMeshes(); + + mGroupQ1Locked = true; // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) @@ -1813,10 +2492,18 @@ void LLPipeline::rebuildPriorityGroups() } mGroupQ1.clear(); + mGroupQ1Locked = false; + } void LLPipeline::rebuildGroups() { + if (mGroupQ2.empty()) + { + return; + } + + mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); @@ -1826,33 +2513,30 @@ void LLPipeline::rebuildGroups() std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); LLSpatialGroup::sg_vector_t::iterator iter; + LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin(); + for (iter = mGroupQ2.begin(); - iter != mGroupQ2.end(); ++iter) + iter != mGroupQ2.end() && count <= min_count; ++iter) { LLSpatialGroup* group = *iter; + last_iter = iter; - if (group->isDead()) + if (!group->isDead()) { - continue; + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } } - group->rebuildGeom(); - - if (group->mSpatialPartition->mRenderByGroup) - { - count++; - } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - - if (count > min_count) - { - ++iter; - break; - } } - mGroupQ2.erase(mGroupQ2.begin(), iter); + mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); + + mGroupQ2Locked = false; updateMovedList(mMovedBridge); } @@ -1867,15 +2551,6 @@ void LLPipeline::updateGeom(F32 max_dtime) assertInitialized(); - if (sDelayedVBOEnable > 0) - { - if (--sDelayedVBOEnable <= 0) - { - resetVertexBuffers(); - LLVertexBuffer::sEnableVBOs = TRUE; - } - } - // notify various object types to reset internal cost metrics, etc. // for now, only LLVOVolume does this to throttle LOD changes LLVOVolume::preUpdateGeom(); @@ -1967,12 +2642,12 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if(drawablep && !drawablep->isDead()) { - if (drawablep->isSpatialBridge()) - { + if (drawablep->isSpatialBridge()) + { const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; llassert(root); // trying to catch a bad assumption if (root && // // this test may not be needed, see above - root->getVObj()->isAttachment()) + root->getVObj()->isAttachment()) { LLDrawable* rootparent = root->getParent(); if (rootparent) // this IS sometimes NULL @@ -1980,24 +2655,24 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) LLViewerObject *vobj = rootparent->getVObj(); llassert(vobj); // trying to catch a bad assumption if (vobj) // this test may not be needed, see above - { + { const LLVOAvatar* av = vobj->asAvatar(); - if (av && av->isImpostor()) - { - return; - } - } + if (av && av->isImpostor()) + { + return; + } + } } } - sCull->pushBridge((LLSpatialBridge*) drawablep); - } - else - { - sCull->pushDrawable(drawablep); - } + sCull->pushBridge((LLSpatialBridge*) drawablep); + } + else + { + sCull->pushDrawable(drawablep); + } - drawablep->setVisible(camera); -} + drawablep->setVisible(camera); + } } void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) @@ -2078,6 +2753,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) glClear(GL_DEPTH_BUFFER_BIT); gDepthDirty = TRUE; + LLVector4a offseta; + offseta.load3(offset.mV); + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); iter++) { @@ -2086,7 +2764,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) { continue; } - drawablep->shiftPos(offset); + drawablep->shiftPos(offseta); drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } mShiftList.resize(0); @@ -2100,7 +2778,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - part->shift(offset); + part->shift(offseta); } } } @@ -2129,11 +2807,36 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu) } } +void LLPipeline::markPartitionMove(LLDrawable* drawable) +{ + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().equals3(LLVector4a::getZero())) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } +} + +void LLPipeline::processPartitionQ() +{ + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } + + mPartitionQ.clear(); +} + void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - //assert_main_thread(); - + if (group && !group->isDead() && group->mSpatialPartition) { if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) @@ -2145,6 +2848,8 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) { + llassert_always(!mGroupQ1Locked); + mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); @@ -2161,11 +2866,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { - //llerrs << "Non-priority updates not yet supported!" << llendl; - if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) - { - llerrs << "WTF?" << llendl; - } + llassert_always(!mGroupQ2Locked); mGroupQ2.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q2); @@ -2243,8 +2944,49 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { markVisible(*i, camera); } + + if (!sDelayVBUpdate) + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); + } } } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + LLSpatialGroup* last_group = NULL; + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_list_t::iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + + if (last_group == NULL) + { + last_group = group; + } + + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group != group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + + last_group = group; + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + } + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2257,22 +2999,14 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) { group->setVisible(); stateSort(group, camera); - } - } - - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLCullResult::bridge_list_t::iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera); + + if (!sDelayVBUpdate) + { //rebuild mesh as soon as we know it's visible + group->rebuildMesh(); } } } + { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -2285,11 +3019,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - { - LLFastTimer ftm(FTM_CLIENT_COPY); - LLVertexBuffer::clientCopy(); - } - + postSort(camera); } @@ -2303,6 +3033,11 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) LLDrawable* drawablep = *i; stateSort(drawablep, camera); } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } } } @@ -2310,7 +3045,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); - if (!sShadowRender && bridge->getSpatialGroup()->changeLOD()) + if (bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2369,21 +3104,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here { - if (drawablep->isVisible()) + if (!drawablep->isActive()) { - if (!drawablep->isActive()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); - } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } + bool force_update = false; + drawablep->updateDistance(camera, force_update); + } + else if (drawablep->isAvatar()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() } } } @@ -2444,7 +3175,7 @@ void renderScriptedBeacons(LLDrawable* drawablep) { if (gPipeline.sRenderBeacons) { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); } if (gPipeline.sRenderHighlight) @@ -2470,7 +3201,7 @@ void renderScriptedTouchBeacons(LLDrawable* drawablep) { if (gPipeline.sRenderBeacons) { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 0.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); } if (gPipeline.sRenderHighlight) @@ -2495,7 +3226,43 @@ void renderPhysicalBeacons(LLDrawable* drawablep) { if (gPipeline.sRenderBeacons) { - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(0.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + } + } + } +} + +void renderMOAPBeacons(LLDrawable* drawablep) +{ + LLViewerObject *vobj = drawablep->getVObj(); + + if(!vobj || vobj->isAvatar()) + return; + + BOOL beacon=FALSE; + U8 tecount=vobj->getNumTEs(); + for(int x=0;x<tecount;x++) + { + if(vobj->getTE(x)->hasMedia()) + { + beacon=TRUE; + break; + } + } + if(beacon==TRUE) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); } if (gPipeline.sRenderHighlight) @@ -2520,7 +3287,7 @@ void renderParticleBeacons(LLDrawable* drawablep) if (gPipeline.sRenderBeacons) { LLColor4 light_blue(0.5f, 0.5f, 1.f, 0.5f); - gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", light_blue, LLColor4(1.f, 1.f, 1.f, 0.5f), LLPipeline::DebugBeaconLineWidth); } if (gPipeline.sRenderHighlight) @@ -2575,21 +3342,6 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - /*LLSpatialGroup::sNoDelete = FALSE; - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (sUseOcclusion && - group->isState(LLSpatialGroup::OCCLUDED)) - { - continue; - } - - group->rebuildGeom(); - } - LLSpatialGroup::sNoDelete = TRUE;*/ - - rebuildPriorityGroups(); llpushcallstacks ; @@ -2635,8 +3387,10 @@ void LLPipeline::postSort(LLCamera& camera) { if (sMinRenderSize > 0.f) { - LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; - if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) { sCull->pushDrawInfo(j->first, *k); } @@ -2678,19 +3432,6 @@ void LLPipeline::postSort(LLCamera& camera) if (!sShadowRender) { - //sort by texture or bump map - for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; ++i) - { - if (i == LLRenderPass::PASS_BUMP) - { - std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareBump()); - } - else - { - std::sort(sCull->beginRenderMap(i), sCull->endRenderMap(i), LLDrawInfo::CompareTexturePtrMatrix()); - } - } - std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); } llpushcallstacks ; @@ -2715,6 +3456,11 @@ void LLPipeline::postSort(LLCamera& camera) forAllVisibleDrawables(renderPhysicalBeacons); } + if(sRenderMOAPBeacons) + { + forAllVisibleDrawables(renderMOAPBeacons); + } + if (sRenderParticleBeacons) { forAllVisibleDrawables(renderParticleBeacons); @@ -2734,7 +3480,7 @@ void LLPipeline::postSort(LLCamera& camera) if (gPipeline.sRenderBeacons) { //pos += LLVector3(0.f, 0.f, 0.2f); - gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + gObjectList.addDebugBeacon(pos, "", LLColor4(1.f, 1.f, 0.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), DebugBeaconLineWidth); } } // now deal with highlights for all those seeable sound sources @@ -2790,9 +3536,16 @@ void render_hud_elements() glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); gGL.color4f(1,1,1,1); + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(LLPipeline::RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() // Draw the tracking overlays @@ -2815,6 +3568,11 @@ void render_hud_elements() { LLHUDText::renderAllHUD(); } + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } gGL.flush(); } @@ -2859,10 +3617,10 @@ void LLPipeline::renderHighlights() //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); gGL.pushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); - glLoadIdentity(); + gGL.loadIdentity(); gGL.getTexUnit(0)->bind(&mHighlight); @@ -2874,9 +3632,9 @@ void LLPipeline::renderHighlights() gGL.begin(LLRender::TRIANGLES); - F32 scale = gSavedSettings.getF32("RenderHighlightBrightness"); - LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor"); - F32 thickness = gSavedSettings.getF32("RenderHighlightThickness"); + F32 scale = RenderHighlightBrightness; + LLColor4 color = RenderHighlightColor; + F32 thickness = RenderHighlightThickness; for (S32 pass = 0; pass < 2; ++pass) { @@ -2922,7 +3680,7 @@ void LLPipeline::renderHighlights() gGL.end(); gGL.popMatrix(); - glMatrixMode(GL_MODELVIEW); + gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); //gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -2931,7 +3689,7 @@ void LLPipeline::renderHighlights() if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightProgram.bind(); - gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); + gGL.diffuseColor4f(1,1,1,0.5f); } if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) @@ -2961,10 +3719,7 @@ void LLPipeline::renderHighlights() { // Paint 'em red! color.setVec(1.f, 0.f, 0.f, 0.5f); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,0,0,0.5f); - } + int count = mHighlightFaces.size(); for (S32 i = 0; i < count; i++) { @@ -2993,8 +3748,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) assertInitialized(); - F64 saved_modelview[16]; - F64 saved_projection[16]; + F32 saved_modelview[16]; + F32 saved_projection[16]; //HACK: preserve/restore matrices around HUD render if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -3031,12 +3786,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO"); // Initialize lots of GL state to "safe" values - glMatrixMode(GL_TEXTURE); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + gGL.matrixMode(LLRender::MM_TEXTURE); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); LLGLSPipeline gls_pipeline; - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); @@ -3102,7 +3858,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { occlude = FALSE; gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); doOcclusion(camera); } @@ -3112,7 +3869,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); for( S32 i = 0; i < poolp->getNumPasses(); i++ ) { @@ -3130,22 +3887,12 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } poolp->endRenderPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) + if (gDebugGL) { - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) - { - if (gDebugSession) - { - ll_fail("GL matrix stack corrupted."); - } - llerrs << "GL matrix stack corrupted!" << llendl; - } - std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); + std::string msg = llformat("pass %d", i); LLGLState::checkStates(msg); - LLGLState::checkTextureChannels(msg); - LLGLState::checkClientArrays(msg); + //LLGLState::checkTextureChannels(msg); + //LLGLState::checkClientArrays(msg); } } } @@ -3164,90 +3911,84 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) iter1 = iter2; stop_glerror(); } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); - - LLVertexBuffer::unbind(); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); + + LLVertexBuffer::unbind(); + gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); if (occlude) { occlude = FALSE; gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); doOcclusion(camera); } } LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - - - - stop_glerror(); - - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); - - if (!sReflectionRender) + if (!LLPipeline::sImpostorRender) { - renderHighlights(); - } + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); + if (!sReflectionRender) + { + renderHighlights(); + } + + // Contains a list of the faces of objects that are physical or + // have touch-handlers. + mHighlightFaces.clear(); - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug"); - renderDebug(); + renderDebug(); - LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) - { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + gObjectList.resetObjectBeacons(); + } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } } else { // Make sure particle effects disappear LLHUDObject::renderAllForTimer(); } - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) + //HACK: preserve/restore matrices around HUD render + if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { - gGLModelView[i] = saved_modelview[i]; - gGLProjection[i] = saved_projection[i]; + for (U32 i = 0; i < 16; i++) + { + gGLModelView[i] = saved_modelview[i]; + gGLProjection[i] = saved_projection[i]; + } } } LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); +// LLGLState::checkTextureChannels(); +// LLGLState::checkClientArrays(); } void LLPipeline::renderGeomDeferred(LLCamera& camera) @@ -3276,7 +4017,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); LLVertexBuffer::unbind(); @@ -3302,7 +4043,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); for( S32 i = 0; i < poolp->getNumDeferredPasses(); i++ ) { @@ -3323,15 +4064,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) if (gDebugGL || gDebugPipeline) { - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) - { - llerrs << "GL matrix stack corrupted!" << llendl; - } LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } } @@ -3352,7 +4085,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); gGL.setColorMask(true, false); } @@ -3365,7 +4098,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLGLEnable cull(GL_CULL_FACE); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); calcNearbyLights(camera); setupHWLights(NULL); @@ -3385,7 +4118,8 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) { occlude = FALSE; gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); doOcclusion(camera); gGL.setColorMask(true, false); } @@ -3396,7 +4130,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLFastTimer t(FTM_POOLRENDER); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); for( S32 i = 0; i < poolp->getNumPostDeferredPasses(); i++ ) { @@ -3417,15 +4151,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) if (gDebugGL || gDebugPipeline) { - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) - { - llerrs << "GL matrix stack corrupted!" << llendl; - } LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } } @@ -3446,16 +4172,17 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) } gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); if (occlude) { occlude = FALSE; gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); + LLGLSLShader::bindNoShader(); doOcclusion(camera); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); } } @@ -3479,8 +4206,10 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) pool_set_t::iterator iter2 = iter1; if (hasRenderType(poolp->getType()) && poolp->getNumShadowPasses() > 0) { + poolp->prerender() ; + gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); for( S32 i = 0; i < poolp->getNumShadowPasses(); i++ ) { @@ -3500,8 +4229,6 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } else @@ -3521,7 +4248,7 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) } gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); } @@ -3550,6 +4277,69 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) } } +void LLPipeline::renderPhysicsDisplay() +{ + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + return; + } + + allocatePhysicsBuffer(); + + gGL.flush(); + mPhysicsDisplay.bindTarget(); + glClearColor(0,0,0,1); + gGL.setColorMask(true, true); + mPhysicsDisplay.clear(); + glClearColor(0,0,0,0); + + gGL.setColorMask(true, false); + + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.bind(); + } + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderPhysicsShapes(); + } + } + } + } + + for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderPhysicsShapes(); + gGL.popMatrix(); + } + } + + gGL.flush(); + + if (LLGLSLShader::sNoFixedFunction) + { + gDebugProgram.unbind(); + } + + mPhysicsDisplay.flush(); +} + + void LLPipeline::renderDebug() { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3559,9 +4349,50 @@ void LLPipeline::renderDebug() gGL.color4f(1,1,1,1); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); gGL.setColorMask(true, false); + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + + + if (!hud_only && !mDebugBlips.empty()) + { //render debug blips + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); + + glPointSize(8.f); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + gGL.begin(LLRender::POINTS); + for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) + { + DebugBlip& blip = *iter; + + blip.mAge += gFrameIntervalSeconds; + if (blip.mAge > 2.f) + { + mDebugBlips.erase(iter++); + } + else + { + iter++; + } + + blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + + gGL.color4fv(blip.mColor.mV); + gGL.vertex3fv(blip.mPosition.mV); + } + gGL.end(); + gGL.flush(); + glPointSize(1.f); + } + + // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -3572,7 +4403,8 @@ void LLPipeline::renderDebug() LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - if (hasRenderType(part->mDrawableType)) + if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) || + !hud_only && hasRenderType(part->mDrawableType) ) { part->renderDebug(); } @@ -3585,15 +4417,22 @@ void LLPipeline::renderDebug() LLSpatialBridge* bridge = *i; if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) { - glPushMatrix(); - glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + gGL.pushMatrix(); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); bridge->renderDebug(); - glPopMatrix(); + gGL.popMatrix(); } } + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(TRUE, FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -3657,7 +4496,7 @@ void LLPipeline::renderDebug() if (i < 4) { - if (i == 0 || !mShadowFrustPoints[i].empty()) + //if (i == 0 || !mShadowFrustPoints[i].empty()) { //render visible point cloud gGL.flush(); @@ -3697,11 +4536,12 @@ void LLPipeline::renderDebug() gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); gGL.end(); - } - + } } - /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + /*gGL.flush(); + glLineWidth(16-i*2); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3716,10 +4556,17 @@ void LLPipeline::renderDebug() } } } - }*/ + } + gGL.flush(); + glLineWidth(1.f);*/ } } + if (mRenderDebugMask & RENDER_DEBUG_WIND_VECTORS) + { + gAgent.getRegion()->mWind.renderVectors(); + } + if (mRenderDebugMask & RENDER_DEBUG_COMPOSITION) { // Debug composition layers @@ -3756,13 +4603,19 @@ void LLPipeline::renderDebug() if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) { U32 count = 0; - U32 size = mBuildQ2.size(); + U32 size = mGroupQ2.size(); LLColor4 col; + LLVertexBuffer::unbind(); LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -3781,10 +4634,10 @@ void LLPipeline::renderDebug() if (bridge) { gGL.pushMatrix(); - glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); } - F32 alpha = (F32) (size-count)/size; + F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); LLVector2 c(1.f-alpha, alpha); @@ -3792,7 +4645,7 @@ void LLPipeline::renderDebug() ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); group->drawObjectBox(col); if (bridge) @@ -3800,9 +4653,15 @@ void LLPipeline::renderDebug() gGL.popMatrix(); } } + + gGL.popMatrix(); } gGL.flush(); + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } } void LLPipeline::rebuildPools() @@ -4134,16 +4993,19 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) light_pos.normalize(); + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = diffuse; - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + light->setDiffuse(diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setPosition(light_pos); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { @@ -4174,22 +5036,28 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) backlight_diffuse *= backlight_mag / max_component; mHWLightColors[1] = backlight_diffuse; - glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(1); + + light->setPosition(backlight_pos); + light->setDiffuse(backlight_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } else { + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = LLColor4::black; - glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); } } @@ -4208,7 +5076,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ { return max_dist; } - F32 dist = fsqrtf(dist2); + F32 dist = (F32) sqrt(dist2); dist *= 1.f / inten; dist -= radius; if (selected) @@ -4237,7 +5105,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) // mNearbyLight (and all light_set_t's) are sorted such that // begin() == the closest light and rbegin() == the farthest light const S32 MAX_LOCAL_LIGHTS = 6; -// LLVector3 cam_pos = gAgentCamera.getCameraPositionAgent(); +// LLVector3 cam_pos = gAgent.getCameraPositionAgent(); LLVector3 cam_pos = LLViewerJoystick::getInstance()->getOverrideCamera() ? camera.getOrigin() : gAgent.getPositionAgent(); @@ -4342,10 +5210,14 @@ void LLPipeline::calcNearbyLights(LLCamera& camera) void LLPipeline::setupHWLights(LLDrawPool* pool) { assertInitialized(); - + // Ambient - LLColor4 ambient = gSky.getTotalAmbientColor(); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); + if (!LLGLSLShader::sNoFixedFunction) + { + gGL.syncMatrices(); + LLColor4 ambient = gSky.getTotalAmbientColor(); + gGL.setAmbientLightColor(ambient); + } // Light 0 = Sun or Moon (All objects) { @@ -4370,15 +5242,17 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos(mSunDir, 0.0f); LLColor4 light_diffuse = mSunDiffuse; mHWLightColors[0] = light_diffuse; - glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); - glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(0); + light->setPosition(light_pos); + light->setDiffuse(light_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } // Light 1 = Backlight (for avatars) @@ -4436,36 +5310,48 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); + LLLightState* light_state = gGL.getLight(cur_light); + + light_state->setPosition(light_pos_gl); + light_state->setDiffuse(light_color); + light_state->setAmbient(LLColor4::black); + light_state->setConstantAttenuation(0.f); + if (sRenderDeferred) + { + F32 size = light_radius*1.5f; + light_state->setLinearAttenuation(size*size); + light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } + + if (light->isLightSpotlight() // directional (spot-)light - && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on + && (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; - //llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; - glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); - glLightf (gllight, GL_SPOT_EXPONENT, 2.0f); // 2.0 = good old dot product ^ 2 - glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere - const float specular[] = {0.f, 0.f, 0.f, 0.f}; - glLightfv(gllight, GL_SPECULAR, specular); + + light_state->setSpotDirection(at_axis); + light_state->setSpotCutoff(90.f); + light_state->setSpotExponent(2.f); + + const LLColor4 specular(0.f, 0.f, 0.f, 0.f); + light_state->setSpecular(specular); } else // omnidirectional (point) light { - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); - + light_state->setSpotExponent(0.f); + light_state->setSpotCutoff(180.f); + // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const float specular[] = {0.f, 0.f, 0.f, 1.f}; - glLightfv(gllight, GL_SPECULAR, specular); - //llinfos << "boring light" << llendl; + const LLColor4 specular(0.f, 0.f, 0.f, 1.f); + light_state->setSpecular(specular); } cur_light++; if (cur_light >= 8) @@ -4477,13 +5363,13 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) for ( ; cur_light < 8 ; cur_light++) { mHWLightColors[cur_light] = LLColor4::black; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - } + LLLightState* light = gGL.getLight(cur_light); - if (isAgentAvatarValid() && + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + } + if (gAgentAvatarp && gAgentAvatarp->mSpecialRenderMode == 3) { LLColor4 light_color = LLColor4::white; @@ -4498,23 +5384,28 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[2] = light_color; - S32 gllight = GL_LIGHT2; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + LLLightState* light = gGL.getLight(2); + + light->setPosition(light_pos_gl); + light->setDiffuse(light_color); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setQuadraticAttenuation(0.f); + light->setConstantAttenuation(0.f); + light->setLinearAttenuation(linatten); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } // Init GL state - glDisable(GL_LIGHTING); - for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++) + if (!LLGLSLShader::sNoFixedFunction) + { + glDisable(GL_LIGHTING); + } + + for (S32 i = 0; i < 8; ++i) { - glDisable(gllight); + gGL.getLight(i)->disable(); } mLightMask = 0; } @@ -4532,35 +5423,42 @@ void LLPipeline::enableLights(U32 mask) stop_glerror(); if (!mLightMask) { - glEnable(GL_LIGHTING); + if (!LLGLSLShader::sNoFixedFunction) + { + glEnable(GL_LIGHTING); + } } if (mask) { stop_glerror(); for (S32 i=0; i<8; i++) { + LLLightState* light = gGL.getLight(i); if (mask & (1<<i)) { - glEnable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mHWLightColors[i].mV); + light->enable(); + light->setDiffuse(mHWLightColors[i]); } else { - glDisable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV); + light->disable(); + light->setDiffuse(LLColor4::black); } } stop_glerror(); } else { - glDisable(GL_LIGHTING); + if (!LLGLSLShader::sNoFixedFunction) + { + glDisable(GL_LIGHTING); + } } - stop_glerror(); mLightMask = mask; - LLColor4 ambient = gSky.getTotalAmbientColor(); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); stop_glerror(); + + LLColor4 ambient = gSky.getTotalAmbientColor(); + gGL.setAmbientLightColor(ambient); } } @@ -4571,7 +5469,6 @@ void LLPipeline::enableLightsStatic() if (mLightingDetail >= 2) { mask |= mLightMovingMask; // Hardware moving lights - glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default } else { @@ -4585,11 +5482,7 @@ void LLPipeline::enableLightsDynamic() assertInitialized(); U32 mask = 0xff & (~2); // Local lights enableLights(mask); - if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } - + if (isAgentAvatarValid() && getLightingDetail() <= 0) { if (gAgentAvatarp->mSpecialRenderMode == 0) // normal @@ -4610,13 +5503,75 @@ void LLPipeline::enableLightsAvatar() enableLights(mask); } +void LLPipeline::enableLightsPreview() +{ + disableLights(); + + if (!LLGLSLShader::sNoFixedFunction) + { + glEnable(GL_LIGHTING); + } + + LLColor4 ambient = PreviewAmbientColor; + gGL.setAmbientLightColor(ambient); + + LLColor4 diffuse0 = PreviewDiffuse0; + LLColor4 specular0 = PreviewSpecular0; + LLColor4 diffuse1 = PreviewDiffuse1; + LLColor4 specular1 = PreviewSpecular1; + LLColor4 diffuse2 = PreviewDiffuse2; + LLColor4 specular2 = PreviewSpecular2; + + LLVector3 dir0 = PreviewDirection0; + LLVector3 dir1 = PreviewDirection1; + LLVector3 dir2 = PreviewDirection2; + + dir0.normVec(); + dir1.normVec(); + dir2.normVec(); + + LLVector4 light_pos(dir0, 0.0f); + + LLLightState* light = gGL.getLight(0); + + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse0); + light->setAmbient(LLColor4::black); + light->setSpecular(specular0); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir1, 0.f); + + light = gGL.getLight(1); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse1); + light->setAmbient(LLColor4::black); + light->setSpecular(specular1); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir2, 0.f); + light = gGL.getLight(2); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse2); + light->setAmbient(LLColor4::black); + light->setSpecular(specular2); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); +} + + void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) { U32 mask = 0x2002; // Avatar backlight only, set ambient setupAvatarLights(TRUE); enableLights(mask); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); + gGL.setAmbientLightColor(color); } void LLPipeline::enableLightsFullbright(const LLColor4& color) @@ -4625,17 +5580,12 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) U32 mask = 0x1000; // Non-0 mask, set ambient enableLights(mask); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - /*if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - }*/ + gGL.setAmbientLightColor(color); } void LLPipeline::disableLights() { enableLights(0); // no lighting (full bright) - glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } //============================================================================ @@ -4901,6 +5851,18 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data) return gPipeline.hasRenderDebugFeatureMask(bit); } +void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) +{ + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } +} + // static void LLPipeline::setRenderScriptedBeacons(BOOL val) { @@ -4938,6 +5900,24 @@ BOOL LLPipeline::getRenderScriptedTouchBeacons(void*) } // static +void LLPipeline::setRenderMOAPBeacons(BOOL val) +{ + sRenderMOAPBeacons = val; +} + +// static +void LLPipeline::toggleRenderMOAPBeacons(void*) +{ + sRenderMOAPBeacons = !sRenderMOAPBeacons; +} + +// static +BOOL LLPipeline::getRenderMOAPBeacons(void*) +{ + return sRenderMOAPBeacons; +} + +// static void LLPipeline::setRenderPhysicalBeacons(BOOL val) { sRenderPhysicalBeacons = val; @@ -5222,10 +6202,9 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) return NULL; } - void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { - if (!drawable || drawable->isDead()) + if (!drawable) { return; } @@ -5233,16 +6212,23 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } void LLPipeline::resetVertexBuffers() { - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + mResetVertexBuffers = true; +} + +void LLPipeline::doResetVertexBuffers() +{ + if (!mResetVertexBuffers) + { + return; + } + + mResetVertexBuffers = false; for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5262,85 +6248,67 @@ void LLPipeline::resetVertexBuffers() gSky.resetVertexBuffers(); - if (LLVertexBuffer::sGLCount > 0) - { - LLVertexBuffer::cleanupClass(); - } - + LLVertexBuffer::cleanupClass(); + //delete all name pool caches LLGLNamePool::cleanupPools(); if (LLVertexBuffer::sGLCount > 0) { - llwarns << "VBO wipe failed." << llendl; - } - - if (!LLVertexBuffer::sStreamIBOPool.mNameList.empty() || - !LLVertexBuffer::sStreamVBOPool.mNameList.empty() || - !LLVertexBuffer::sDynamicIBOPool.mNameList.empty() || - !LLVertexBuffer::sDynamicVBOPool.mNameList.empty()) - { - llwarns << "VBO name pool cleanup failed." << llendl; + llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl; } - LLVertexBuffer::unbind(); - + LLVertexBuffer::unbind(); + + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); + LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); + LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; + sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); + sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); + + LLVertexBuffer::initClass(LLVertexBuffer::sEnableVBOs, LLVertexBuffer::sDisableVBOMapping); } -void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) +void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture, BOOL batch_texture) { LLMemType mt_ro(LLMemType::MTYPE_PIPELINE_RENDER_OBJECTS); assertInitialized(); - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; - mSimplePool->pushBatches(type, mask); - glLoadMatrixd(gGLModelView); + mSimplePool->pushBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } -void LLPipeline::setUseVBO(BOOL use_vbo) -{ - if (use_vbo != LLVertexBuffer::sEnableVBOs) - { - if (use_vbo) - { - llinfos << "Enabling VBO." << llendl; - } - else - { - llinfos << "Disabling VBO." << llendl; - } - - resetVertexBuffers(); - LLVertexBuffer::initClass(use_vbo); - } -} - void apply_cube_face_rotation(U32 face) { switch (face) { case 0: - glRotatef(90.f, 0, 1, 0); - glRotatef(180.f, 1, 0, 0); + gGL.rotatef(90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); break; case 2: - glRotatef(-90.f, 1, 0, 0); + gGL.rotatef(-90.f, 1, 0, 0); break; case 4: - glRotatef(180.f, 0, 1, 0); - glRotatef(180.f, 0, 0, 1); + gGL.rotatef(180.f, 0, 1, 0); + gGL.rotatef(180.f, 0, 0, 1); break; case 1: - glRotatef(-90.f, 0, 1, 0); - glRotatef(180.f, 1, 0, 0); + gGL.rotatef(-90.f, 0, 1, 0); + gGL.rotatef(180.f, 1, 0, 0); break; case 3: - glRotatef(90, 1, 0, 0); + gGL.rotatef(90, 1, 0, 0); break; case 5: - glRotatef(180, 0, 0, 1); + gGL.rotatef(180, 0, 0, 1); break; } } @@ -5348,21 +6316,21 @@ void apply_cube_face_rotation(U32 face) void validate_framebuffer_object() { GLenum status; - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); switch(status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: + case GL_FRAMEBUFFER_COMPLETE: //framebuffer OK, no error. break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Dimensions." << llendl; + llerrs << "Framebuffer Incomplete Missing Attachment." << llendl; break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format llerrs << "Framebuffer Incomplete Attachment." << llendl; break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + case GL_FRAMEBUFFER_UNSUPPORTED: /* choose different formats */ llerrs << "Framebuffer unsupported." << llendl; break; @@ -5399,19 +6367,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } - U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); - LLVector2 tc1(0,0); - LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, - (F32) gViewerWindow->getWorldViewHeightRaw()*2); - - if (res_mod > 1) - { - tc2 /= (F32) res_mod; - } + LLVector2 tc2((F32) mScreen.getWidth()*2, + (F32) mScreen.getHeight()*2); - gGL.setColorMask(true, true); - LLFastTimer ftm(FTM_RENDER_BLOOM); gGL.color4f(1,1,1,1); LLGLDepthTest depth(GL_FALSE); @@ -5420,71 +6379,18 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) enableLightsFullbright(LLColor4(1,1,1,1)); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); LLGLDisable test(GL_ALPHA_TEST); gGL.setColorMask(true, true); glClearColor(0,0,0,0); - - if (for_snapshot) - { - gGL.getTexUnit(0)->bind(&mGlow[1]); - { - //LLGLEnable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - //LLGLDisable blend(GL_BLEND); - - // If the snapshot is constructed from tiles, calculate which - // tile we're in. - const S32 num_horizontal_tiles = llceil(zoom_factor); - const LLVector2 tile(subfield % num_horizontal_tiles, - (S32)(subfield / num_horizontal_tiles)); - llassert(zoom_factor > 0.0); // Non-zero, non-negative. - const F32 tile_size = 1.0/zoom_factor; - - tc1 = tile*tile_size; // Top left texture coordinates - tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates - - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ADD); - - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); - - gGL.end(); - - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - gGL.flush(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - return; - } - + { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -5493,26 +6399,25 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } gGlowExtractProgram.bind(); - F32 minLum = llmax(gSavedSettings.getF32("RenderGlowMinLuminance"), 0.0f); - F32 maxAlpha = gSavedSettings.getF32("RenderGlowMaxExtractAlpha"); - F32 warmthAmount = gSavedSettings.getF32("RenderGlowWarmthAmount"); - LLVector3 lumWeights = gSavedSettings.getVector3("RenderGlowLumWeights"); - LLVector3 warmthWeights = gSavedSettings.getVector3("RenderGlowWarmthWeights"); - gGlowExtractProgram.uniform1f("minLuminance", minLum); - gGlowExtractProgram.uniform1f("maxExtractAlpha", maxAlpha); - gGlowExtractProgram.uniform3f("lumWeights", lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); - gGlowExtractProgram.uniform3f("warmthWeights", warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); - gGlowExtractProgram.uniform1f("warmthAmount", warmthAmount); + F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); + F32 maxAlpha = RenderGlowMaxExtractAlpha; + F32 warmthAmount = RenderGlowWarmthAmount; + LLVector3 lumWeights = RenderGlowLumWeights; + LLVector3 warmthWeights = RenderGlowWarmthWeights; + + + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); + gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); + gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); LLGLEnable blend_on(GL_BLEND); LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->disable(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); - gGL.getTexUnit(0)->bind(&mScreen); - + mScreen.bindTexture(0, 0); + gGL.color4f(1,1,1,1); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); gGL.begin(LLRender::TRIANGLE_STRIP); @@ -5527,7 +6432,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.end(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(mScreen.getUsage()); mGlow[2].flush(); } @@ -5536,26 +6441,25 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) tc2.setVec(2,2); // power of two between 1 and 1024 - U32 glowResPow = gSavedSettings.getS32("RenderGlowResolutionPow"); + U32 glowResPow = RenderGlowResolutionPow; const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); - S32 kernel = gSavedSettings.getS32("RenderGlowIterations")*2; - F32 delta = gSavedSettings.getF32("RenderGlowWidth") / glow_res; + S32 kernel = RenderGlowIterations*2; + F32 delta = RenderGlowWidth / glow_res; // Use half the glow width if we have the res set to less than 9 so that it looks // almost the same in either case. if (glowResPow < 9) { delta *= 0.5f; } - F32 strength = gSavedSettings.getF32("RenderGlowStrength"); + F32 strength = RenderGlowStrength; gGlowProgram.bind(); - gGlowProgram.uniform1f("glowStrength", strength); + gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); for (S32 i = 0; i < kernel; i++) { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); mGlow[i%2].bindTarget(); @@ -5573,11 +6477,11 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (i%2 == 0) { - gGlowProgram.uniform2f("glowDelta", delta, 0); + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); } else { - gGlowProgram.uniform2f("glowDelta", 0, delta); + gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); } gGL.begin(LLRender::TRIANGLE_STRIP); @@ -5600,7 +6504,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -5609,46 +6513,358 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - tc2.setVec((F32) gViewerWindow->getWorldViewWidthRaw(), - (F32) gViewerWindow->getWorldViewHeightRaw()); + tc2.setVec((F32) mScreen.getWidth(), + (F32) mScreen.getHeight()); gGL.flush(); LLVertexBuffer::unbind(); - if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + if (LLPipeline::sRenderDeferred) { - LLGLDisable blend(GL_BLEND); - bindDeferredShader(gDeferredGIFinalProgram); - S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) + bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && + !LLToolMgr::getInstance()->inBuildMode() && + RenderDepthOfField; + + + bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); + + gViewerWindow->setup3DViewport(); + + if (dof_enabled) { - mScreen.bindTexture(0, channel); - } + LLGLSLShader* shader = &gDeferredPostProgram; + LLGLDisable blend(GL_BLEND); - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); + //depth of field focal plane calculations + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { //focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { //focus on point under cursor + focus_point = gDebugRaycastIntersection; + } + else if (gAgentCamera.cameraMouselook()) + { //focus on point under mouselook crosshairs + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, + NULL, + &focus_point); + } + else + { + LLViewerObject* obj = gAgentCamera.getFocusObject(); + if (obj) + { //focus on alt-zoom target + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + } + else + { //focus on your avatar + focus_point = gAgent.getPositionAgent(); + } + } + } + + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); + } + + if (transition_time >= 1.f && + fabsf(current_distance-target_distance)/current_distance > 0.01f) + { //large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { //currently in a transition, continue interpolating + transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds; + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; + current_distance = start_distance + (target_distance-start_distance)*t; + } + else + { //small or no change, just snap to target distance + current_distance = target_distance; + } + + //convert to mm + F32 subject_distance = current_distance*1000.f; + F32 fnumber = CameraFNumber; + F32 default_focal_length = CameraFocalLength; + + F32 fov = LLViewerCamera::getInstance()->getView(); - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); + const F32 default_fov = CameraFieldOfView * F_PI/180.f; + //const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); - gGL.end(); + //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + + F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + //F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); - unbindDeferredShader(gDeferredGIFinalProgram); - } - else - { + F32 focal_length = dv/(2*tanf(fov/2.f)); + + //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); + blur_constant /= 1000.f; //convert to meters for shader + F32 magnification = focal_length/(subject_distance-focal_length); + + { //build diffuse+bloom+CoF + mDeferredLight.bindTarget(); + shader = &gDeferredCoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); + shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); + shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); + shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + 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(); - if (res_mod > 1) + unbindDeferredShader(*shader); + mDeferredLight.flush(); + } + + U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); + U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); + + { //perform DoF sampling at half-res (preserve alpha channel) + mScreen.bindTarget(); + glViewport(0,0, dof_width, dof_height); + gGL.setColorMask(true, false); + + shader = &gDeferredPostProgram; + bindDeferredShader(*shader); + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + + 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(); + + unbindDeferredShader(*shader); + mScreen.flush(); + gGL.setColorMask(true, true); + } + + { //combine result based on alpha + if (multisample) + { + mDeferredLight.bindTarget(); + glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + } + else + { + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + } + + shader = &gDeferredDoFCombineProgram; + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); + shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); + shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); + shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); + + 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(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } + } + } + else { - tc2 /= (F32) res_mod; + if (multisample) + { + mDeferredLight.bindTarget(); + } + LLGLSLShader* shader = &gDeferredPostNoDoFProgram; + + bindDeferredShader(*shader); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + if (channel > -1) + { + mScreen.bindTexture(0, channel); + } + + 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(); + + unbindDeferredShader(*shader); + + if (multisample) + { + mDeferredLight.flush(); + } } + if (multisample) + { + //bake out texture2D with RGBL for FXAA shader + mFXAABuffer.bindTarget(); + + S32 width = mScreen.getWidth(); + S32 height = mScreen.getHeight(); + glViewport(0, 0, width, height); + + LLGLSLShader* shader = &gGlowCombineFXAAProgram; + + shader->bind(); + shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + + S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + if (channel > -1) + { + mDeferredLight.bindTexture(0, channel); + } + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1,-1); + gGL.vertex2f(-1,3); + gGL.vertex2f(3,-1); + gGL.end(); + + gGL.flush(); + + shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); + shader->unbind(); + + mFXAABuffer.flush(); + + shader = &gFXAAProgram; + shader->bind(); + + channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); + if (channel > -1) + { + mFXAABuffer.bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; + gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; + gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); + gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); + glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + + F32 scale_x = (F32) width/mFXAABuffer.getWidth(); + F32 scale_y = (F32) height/mFXAABuffer.getHeight(); + shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); + shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); + shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex2f(-1,-1); + gGL.vertex2f(-1,3); + gGL.vertex2f(3,-1); + gGL.end(); + + gGL.flush(); + shader->unbind(); + } + } + else + { U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); buff->allocateBuffer(3,0,TRUE); @@ -5673,48 +6889,96 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) v[1] = LLVector3(-1,3,0); v[2] = LLVector3(3,-1,0); - buff->setBuffer(0); + buff->flush(); LLGLDisable blend(GL_BLEND); - //tex unit 0 - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); - - gGL.getTexUnit(0)->bind(&mGlow[1]); - gGL.getTexUnit(1)->activate(); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_RECT_TEXTURE); - - - //tex unit 1 - gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.bind(); + } + else + { + //tex unit 0 + gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); + //tex unit 1 + gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); + } + gGL.getTexUnit(0)->bind(&mGlow[1]); gGL.getTexUnit(1)->bind(&mScreen); - gGL.getTexUnit(1)->activate(); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); buff->setBuffer(mask); buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); - gGL.getTexUnit(1)->disable(); - gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + if (LLGLSLShader::sNoFixedFunction) + { + gGlowCombineProgram.unbind(); + } + else + { + gGL.getTexUnit(1)->disable(); + gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } + + } + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.bind(); + } + + gGL.setColorMask(true, false); + + LLVector2 tc1(0,0); + LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, + (F32) gViewerWindow->getWorldViewHeightRaw()*2); + + LLGLEnable blend(GL_BLEND); + gGL.color4f(1,1,1,0.75f); + + gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + + gGL.begin(LLRender::TRIANGLES); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + gGL.flush(); - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + if (LLGLSLShader::sNoFixedFunction) + { + gSplatTextureRectProgram.unbind(); } } + + + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } - gGL.setSceneBlendType(LLRender::BT_ALPHA); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); LLVertexBuffer::unbind(); @@ -5725,7 +6989,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred"); -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map) { LLFastTimer t(FTM_BIND_DEFERRED); @@ -5734,184 +6998,58 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen noise_map = mNoiseMap; } - LLGLState::checkTextureChannels(); - shader.bind(); S32 channel = 0; - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - if (gi_source) - { - BOOL has_gi = FALSE; - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); - if (channel > -1) - { - has_gi = TRUE; - gi_source->bindTexture(3, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); - if (channel > -1) - { - has_gi = TRUE; - last_gi_post->bindTexture(3, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); - if (channel > -1) - { - has_gi = TRUE; - gGL.getTexUnit(channel)->bind(gi_source, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - stop_glerror(); - - glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); - - stop_glerror(); - } - - if (has_gi) - { - F32 range_x = llmin(mGIRange.mV[0], 1.f); - F32 range_y = llmin(mGIRange.mV[1], 1.f); - - LLVector2 scale(range_x,range_y); - - LLVector2 kern[25]; - - for (S32 i = 0; i < 5; ++i) - { - for (S32 j = 0; j < 5; ++j) - { - S32 idx = i*5+j; - kern[idx].mV[0] = (i-2)*0.5f; - kern[idx].mV[1] = (j-2)*0.5f; - kern[idx].scaleVec(scale); - } - } - - shader.uniform2fv("gi_kern", 25, (F32*) kern); - shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m); - shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m); - shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m); - shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); - } - } - - /*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredScreen.bindTexture(3, channel); - }*/ - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); if (channel > -1) { gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); stop_glerror(); glh::matrix4f projection = glh_get_current_projection(); glh::matrix4f inv_proj = projection.inverse(); - shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m); - shader.uniform4f("viewport", (F32) gGLViewport[0], + shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); + shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], (F32) gGLViewport[1], (F32) gGLViewport[2], (F32) gGLViewport[3]); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE); if (channel > -1) { gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC); if (channel > -1) { gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); @@ -5919,60 +7057,31 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage()); if (channel > -1) { - mDeferredLight[light_index].bindTexture(0, channel); + if (light_index > 0) + { + mScreen.bindTexture(0, channel); + } + else + { + mDeferredLight.bindTexture(0, channel); + } gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); - if (channel > -1) - { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_BLOOM); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM); if (channel > -1) { mGlow[1].bindTexture(0, channel); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - gi_source->bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mEdgeMap.bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredLight[1].bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredLight[2].bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - stop_glerror(); for (U32 i = 0; i < 4; i++) { - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); stop_glerror(); if (channel > -1) { @@ -5990,7 +7099,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen for (U32 i = 4; i < 6; i++) { - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i); stop_glerror(); if (channel > -1) { @@ -6019,12 +7128,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen mat[i+80] = mSunShadowMatrix[5].m[i]; } - shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat); - shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat); + shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_SHADOW_MATRIX, 6, FALSE, mat); stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + channel = shader.enableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; @@ -6032,31 +7140,29 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen { cube_map->enable(channel); cube_map->bind(); - F64* m = gGLModelView; - - + F32* m = gGLModelView; + F32 mat[] = { m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10] }; - shader.uniform3fv("env_mat[0]", 3, mat); - shader.uniform3fv("env_mat", 3, mat); + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_ENV_MAT, 1, TRUE, mat); } } - shader.uniform4fv("shadow_clip", 1, mSunClipPlanes.mV); - shader.uniform1f("sun_wash", gSavedSettings.getF32("RenderDeferredSunWash")); - shader.uniform1f("shadow_noise", gSavedSettings.getF32("RenderShadowNoise")); - shader.uniform1f("blur_size", gSavedSettings.getF32("RenderShadowBlurSize")); + shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); + shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash); + shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); + shader.uniform1f(LLShaderMgr::DEFERRED_BLUR_SIZE, RenderShadowBlurSize); - shader.uniform1f("ssao_radius", gSavedSettings.getF32("RenderSSAOScale")); - shader.uniform1f("ssao_max_radius", gSavedSettings.getU32("RenderSSAOMaxScale")); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_RADIUS, RenderSSAOScale); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_MAX_RADIUS, RenderSSAOMaxScale); - F32 ssao_factor = gSavedSettings.getF32("RenderSSAOFactor"); - shader.uniform1f("ssao_factor", ssao_factor); - shader.uniform1f("ssao_factor_inv", 1.0/ssao_factor); + F32 ssao_factor = RenderSSAOFactor; + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR, ssao_factor); + shader.uniform1f(LLShaderMgr::DEFERRED_SSAO_FACTOR_INV, 1.0/ssao_factor); - LLVector3 ssao_effect = gSavedSettings.getVector3("RenderSSAOEffect"); + LLVector3 ssao_effect = RenderSSAOEffect; F32 matrix_diag = (ssao_effect[0] + 2.0*ssao_effect[1])/3.0; F32 matrix_nondiag = (ssao_effect[0] - ssao_effect[1])/3.0; // This matrix scales (proj of color onto <1/rt(3),1/rt(3),1/rt(3)>) by @@ -6064,35 +7170,24 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen F32 ssao_effect_mat[] = { matrix_diag, matrix_nondiag, matrix_nondiag, matrix_nondiag, matrix_diag, matrix_nondiag, matrix_nondiag, matrix_nondiag, matrix_diag}; - shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat); - - F32 shadow_offset_error = 1.f + gSavedSettings.getF32("RenderShadowOffsetError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - F32 shadow_bias_error = 1.f + gSavedSettings.getF32("RenderShadowBiasError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); - - shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); - shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); - shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")*shadow_offset_error); - shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")*shadow_bias_error); - shader.uniform1f ("spot_shadow_offset", gSavedSettings.getF32("RenderSpotShadowOffset")); - shader.uniform1f("spot_shadow_bias", gSavedSettings.getF32("RenderSpotShadowBias")); - - shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale")); - shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale")); - shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset")); - shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail")); - shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange")); - shader.uniform1f("gi_brightness", gSavedSettings.getF32("RenderGIBrightness")); - shader.uniform1f("gi_luminance", gSavedSettings.getF32("RenderGILuminance")); - shader.uniform1f("gi_edge_weight", gSavedSettings.getF32("RenderGIBlurEdgeWeight")); - shader.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness")); - shader.uniform1f("gi_sample_width", mGILightRadius); - shader.uniform1f("gi_noise", gSavedSettings.getF32("RenderGINoise")); - shader.uniform1f("gi_attenuation", gSavedSettings.getF32("RenderGIAttenuation")); - shader.uniform1f("gi_ambiance", gSavedSettings.getF32("RenderGIAmbiance")); - shader.uniform2f("shadow_res", mShadow[0].getWidth(), mShadow[0].getHeight()); - shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight()); - shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff")); - shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff")); + shader.uniformMatrix3fv(LLShaderMgr::DEFERRED_SSAO_EFFECT_MAT, 1, GL_FALSE, ssao_effect_mat); + + F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + F32 shadow_bias_error = 1.f + RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); + + shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + shader.uniform1f(LLShaderMgr::DEFERRED_NEAR_CLIP, LLViewerCamera::getInstance()->getNear()*2.f); + shader.uniform1f (LLShaderMgr::DEFERRED_SHADOW_OFFSET, RenderShadowOffset*shadow_offset_error); + shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_BIAS, RenderShadowBias*shadow_bias_error); + shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_OFFSET, RenderSpotShadowOffset); + shader.uniform1f(LLShaderMgr::DEFERRED_SPOT_SHADOW_BIAS, RenderSpotShadowBias); + + shader.uniform3fv(LLShaderMgr::DEFERRED_SUN_DIR, 1, mTransformedSunDir.mV); + shader.uniform2f(LLShaderMgr::DEFERRED_SHADOW_RES, mShadow[0].getWidth(), mShadow[0].getHeight()); + shader.uniform2f(LLShaderMgr::DEFERRED_PROJ_SHADOW_RES, mShadow[4].getWidth(), mShadow[4].getHeight()); + shader.uniform1f(LLShaderMgr::DEFERRED_DEPTH_CUTOFF, RenderEdgeDepthCutoff); + shader.uniform1f(LLShaderMgr::DEFERRED_NORM_CUTOFF, RenderEdgeNormCutoff); + if (shader.getUniformLocation("norm_mat") >= 0) { @@ -6130,7 +7225,7 @@ void LLPipeline::renderDeferredLighting() 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { @@ -6138,9 +7233,9 @@ void LLPipeline::renderDeferredLighting() } //ati doesn't seem to love actually using the stencil buffer on FBO's - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + LLGLDisable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); @@ -6152,39 +7247,40 @@ void LLPipeline::renderDeferredLighting() glh::matrix4f mat = glh_copy_matrix(gGLModelView); - F32 vert[] = - { - -1,1, - -1,-3, - 3,1, - }; - glVertexPointer(2, GL_FLOAT, 0, vert); - glColor3f(1,1,1); + 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); + { setupHWLights(NULL); //to set mSunDir; LLVector4 dir(mSunDir, 0.f); glh::vec4f tc(dir.mV); mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); + mTransformedSunDir.set(tc.v); } - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - mDeferredLight[0].bindTarget(); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) + if (RenderDeferredSSAO || RenderShadowDetail > 0) { + mDeferredLight.bindTarget(); { //paint shadow/SSAO light map (direct lighting lightmap) LLFastTimer ftm(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, 0); - + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + mDeferredLight.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); @@ -6207,251 +7303,129 @@ void LLPipeline::renderDeferredLighting() } gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight.getWidth(), mDeferredLight.getHeight()); { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); stop_glerror(); } unbindDeferredShader(gDeferredSunProgram); } + mDeferredLight.flush(); } - else - { + + if (RenderDeferredSSAO) + { //soften direct lighting lightmap + LLFastTimer ftm(FTM_SOFTEN_SHADOW); + //blur lightmap + mScreen.bindTarget(); glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + mScreen.clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - } + + bindDeferredShader(gDeferredBlurLightProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLVector3 go = RenderShadowGaussian; + const U32 kern_length = 4; + F32 blur_size = RenderShadowBlurSize; + F32 dist_factor = RenderShadowBlurDistFactor; - mDeferredLight[0].flush(); + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = 0.f; - { //global illumination specific block (still experimental) - if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && - gSavedSettings.getBOOL("RenderDeferredGI")) - { - LLFastTimer ftm(FTM_EDGE_DETECTION); - //generate edge map - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable stencil(GL_STENCIL_TEST); + LLVector3 gauss[32]; // xweight, yweight, offset - { - gDeferredEdgeProgram.bind(); - mEdgeMap.bindTarget(); - bindDeferredShader(gDeferredEdgeProgram); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - unbindDeferredShader(gDeferredEdgeProgram); - mEdgeMap.flush(); - } + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; } - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + 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)); + { - { //get luminance map from previous frame's light map - LLGLEnable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable stencil(GL_STENCIL_TEST); - - //static F32 fade = 1.f; - - { - gGL.setSceneBlendType(LLRender::BT_ALPHA); - gLuminanceGatherProgram.bind(); - gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - mLuminanceMap.bindTarget(); - bindDeferredShader(gLuminanceGatherProgram); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - unbindDeferredShader(gLuminanceGatherProgram); - mLuminanceMap.flush(); - gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); - gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glGenerateMipmapEXT(GL_TEXTURE_2D); - } - } - - { //paint noisy GI map (bounce lighting lightmap) - LLFastTimer ftm(FTM_GI_TRACE); - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable test(GL_ALPHA_TEST); - - mGIMapPost[0].bindTarget(); - - bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0, mTrueNoiseMap); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - unbindDeferredShader(gDeferredGIProgram); - mGIMapPost[0].flush(); - } - - U32 pass_count = 0; - if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) - { - pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128); - } - - for (U32 i = 0; i < pass_count; ++i) - { //gather/soften indirect lighting map - LLFastTimer ftm(FTM_GI_GATHER); - bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL, mTrueNoiseMap); - F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")/((F32) i * gSavedSettings.getF32("RenderGIBlurIncrement")+1.f); - gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); - gDeferredPostGIProgram.uniform1f("kern_scale", blur_size); - gDeferredPostGIProgram.uniform1f("gi_blur_brightness", gSavedSettings.getF32("RenderGIBlurBrightness")); - - mGIMapPost[1].bindTarget(); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mGIMapPost[1].flush(); - unbindDeferredShader(gDeferredPostGIProgram); - bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL, mTrueNoiseMap); - mGIMapPost[0].bindTarget(); - - gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); - } - mGIMapPost[0].flush(); - unbindDeferredShader(gDeferredPostGIProgram); - } + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); } - } - - if (gSavedSettings.getBOOL("RenderDeferredSSAO")) - { //soften direct lighting lightmap - LLFastTimer ftm(FTM_SOFTEN_SHADOW); - //blur lightmap - mDeferredLight[1].bindTarget(); - - glClearColor(1,1,1,1); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - bindDeferredShader(gDeferredBlurLightProgram); - - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - const U32 kern_length = 4; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); - F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); - - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = 0.f; - - LLVector3 gauss[32]; // xweight, yweight, offset - - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } - - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + mScreen.flush(); + unbindDeferredShader(gDeferredBlurLightProgram); - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mDeferredLight.bindTarget(); - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - mDeferredLight[0].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + stop_glerror(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + stop_glerror(); } + mDeferredLight.flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + } - stop_glerror(); - glPopMatrix(); - stop_glerror(); - glMatrixMode(GL_MODELVIEW); - stop_glerror(); - glPopMatrix(); - stop_glerror(); + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + stop_glerror(); + gGL.popMatrix(); + stop_glerror(); //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) - { - mDeferredLight[1].bindTarget(); - // clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky - glClearColor(0,0,0,0); - mScreen.clear(GL_COLOR_BUFFER_BIT); - } - else - { - mScreen.bindTarget(); - // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky - glClearColor(0,0,0,0); - mScreen.clear(GL_COLOR_BUFFER_BIT); - } - - if (gSavedSettings.getBOOL("RenderDeferredAtmospheric")) + mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + mScreen.clear(GL_COLOR_BUFFER_BIT); + + if (RenderDeferredAtmospheric) { //apply sunlight contribution LLFastTimer ftm(FTM_ATMOSPHERICS); - bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); + bindDeferredShader(gDeferredSoftenProgram); { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); LLGLDisable test(GL_ALPHA_TEST); //full screen blit - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); - glVertexPointer(2, GL_FLOAT, 0, vert); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); } unbindDeferredShader(gDeferredSoftenProgram); } - { //render sky + { //render non-deferred geometry (fullbright, alpha, etc) LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -6468,18 +7442,9 @@ void LLPipeline::renderDeferredLighting() gPipeline.popRenderTypeMask(); } - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); - - - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) - { - mDeferredLight[1].flush(); - mDeferredLight[2].bindTarget(); - mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); - } - - if (render_local || render_fullscreen) + BOOL render_local = RenderLocalLights; + + if (render_local) { gGL.setSceneBlendType(LLRender::BT_ADD); std::list<LLVector4> fullscreen_lights; @@ -6493,12 +7458,13 @@ void LLPipeline::renderDeferredLighting() std::list<LLVector4> light_colors; - F32 v[24]; - glVertexPointer(3, GL_FLOAT, 0, v); - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); + LLVertexBuffer::unbind(); + LLVector4a* v = (LLVector4a*) vert.get(); { bindDeferredShader(gDeferredLightProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { @@ -6519,13 +7485,13 @@ void LLPipeline::renderDeferredLighting() } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - + if (col.magVecSquared() < 0.001f) { continue; @@ -6536,7 +7502,9 @@ void LLPipeline::renderDeferredLighting() continue; } - if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) { continue; } @@ -6550,15 +7518,16 @@ void LLPipeline::renderDeferredLighting() //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear //meaning negative facing - v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 - v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 - v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 - v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + mDeferredVB->getVertexStrider(vert); + v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000 + v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001 + v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010 + v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011 - v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 - v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 - v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 - v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 + v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 + v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 + v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 + v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || camera->getOrigin().mV[0] < c[0] - s - 0.2f || @@ -6577,14 +7546,20 @@ void LLPipeline::renderDeferredLighting() } LLFastTimer ftm(FTM_LOCAL_LIGHTS); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + //glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); + gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + //gGL.diffuseColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + gGL.syncMatrices(); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); stop_glerror(); } } - else if (render_fullscreen) + else { if (volume->isLightSpotlight()) { @@ -6605,7 +7580,9 @@ void LLPipeline::renderDeferredLighting() LLGLDepthTest depth(GL_TRUE, GL_FALSE); bindDeferredShader(gDeferredSpotLightProgram); - gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + + gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) { @@ -6614,8 +7591,9 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; @@ -6626,42 +7604,54 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredSpotLightProgram, drawablep); LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - + //vertex positions are encoded so the 3 bits of their vertex index //correspond to their axis facing, with bit position 3,2,1 matching //axis facing x,y,z, bit set meaning positive facing, bit clear //meaning negative facing - v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 - v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 - v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 - v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + mDeferredVB->getVertexStrider(vert); + v[0].set(c[0]-s,c[1]-s,c[2]-s); // 0 - 0000 + v[1].set(c[0]-s,c[1]-s,c[2]+s); // 1 - 0001 + v[2].set(c[0]-s,c[1]+s,c[2]-s); // 2 - 0010 + v[3].set(c[0]-s,c[1]+s,c[2]+s); // 3 - 0011 - v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 - v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 - v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 - v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); + v[4].set(c[0]+s,c[1]-s,c[2]-s); // 4 - 0100 + v[5].set(c[0]+s,c[1]-s,c[2]+s); // 5 - 0101 + v[6].set(c[0]+s,c[1]+s,c[2]-s); // 6 - 0110 + v[7].set(c[0]+s,c[1]+s,c[2]+s); // 7 - 0111 + + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*s); + gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gGL.syncMatrices(); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_SHORT, get_box_fan_indices_ptr(camera, center)); } - gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + 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); + { bindDeferredShader(gDeferredMultiLightProgram); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + LLGLDepthTest depth(GL_FALSE); //full screen blit - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); U32 count = 0; @@ -6669,7 +7659,7 @@ void LLPipeline::renderDeferredLighting() LLVector4 light[max_count]; LLVector4 col[max_count]; - glVertexPointer(2, GL_FLOAT, 0, vert); +// glVertexPointer(2, GL_FLOAT, 0, vert); F32 far_z = 0.f; @@ -6686,15 +7676,13 @@ void LLPipeline::renderDeferredLighting() count++; if (count == max_count || fullscreen_lights.empty()) { - gDeferredMultiLightProgram.uniform1i("light_count", count); - gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); - gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); - gDeferredMultiLightProgram.uniform1f("far_z", far_z); + 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); far_z = 0.f; - count = 0; - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + count = 0; + mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); } } @@ -6702,7 +7690,9 @@ void LLPipeline::renderDeferredLighting() bindDeferredShader(gDeferredMultiSpotLightProgram); - gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + 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) { @@ -6723,64 +7713,24 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); - glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + + gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); + gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s*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(LLViewerShaderMgr::DEFERRED_PROJECTION); + gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredMultiSpotLightProgram); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); } } gGL.setColorMask(true, true); - - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) - { - mDeferredLight[2].flush(); - - mScreen.bindTarget(); - mScreen.clear(GL_COLOR_BUFFER_BIT); - - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - { //mix various light maps (local, sun, gi) - LLFastTimer ftm(FTM_POST); - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - LLGLDepthTest depth(GL_FALSE); - LLGLDisable stencil(GL_STENCIL_TEST); - - bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]); - - gDeferredPostProgram.bind(); - - LLVertexBuffer::unbind(); - - glVertexPointer(2, GL_FLOAT, 0, vert); - glColor3f(1,1,1); - - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - - glDrawArrays(GL_TRIANGLES, 0, 3); - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - unbindDeferredShader(gDeferredPostProgram); - } - } } { //render non-deferred geometry (alpha, fullbright, glow) @@ -6826,7 +7776,6 @@ void LLPipeline::renderDeferredLighting() { // Render debugging beacons. gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } } @@ -6897,13 +7846,13 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) F32 proj_range = far_clip - near_clip; glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); screen_to_light = trans * light_proj * screen_to_light; - shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m); - shader.uniform1f("proj_near", near_clip); - shader.uniform3fv("proj_p", 1, p1.v); - shader.uniform3fv("proj_n", 1, n.v); - shader.uniform3fv("proj_origin", 1, screen_origin.v); - shader.uniform1f("proj_range", proj_range); - shader.uniform1f("proj_ambiance", params.mV[2]); + shader.uniformMatrix4fv(LLShaderMgr::PROJECTOR_MATRIX, 1, FALSE, screen_to_light.m); + shader.uniform1f(LLShaderMgr::PROJECTOR_NEAR, near_clip); + shader.uniform3fv(LLShaderMgr::PROJECTOR_P, 1, p1.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_N, 1, n.v); + shader.uniform3fv(LLShaderMgr::PROJECTOR_ORIGIN, 1, screen_origin.v); + shader.uniform1f(LLShaderMgr::PROJECTOR_RANGE, proj_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIANCE, params.mV[2]); S32 s_idx = -1; for (U32 i = 0; i < 2; i++) @@ -6914,15 +7863,15 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) } } - shader.uniform1i("proj_shadow_idx", s_idx); + shader.uniform1i(LLShaderMgr::PROJECTOR_SHADOW_INDEX, s_idx); if (s_idx >= 0) { - shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]); + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f-mSpotLightFade[s_idx]); } else { - shader.uniform1f("shadow_fade", 1.f); + shader.uniform1f(LLShaderMgr::PROJECTOR_SHADOW_FADE, 1.f); } { @@ -6951,51 +7900,43 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLViewerTexture* img = volume->getLightTexture(); - S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + if (img == NULL) + { + img = LLViewerFetchedTexture::sWhiteImagep; + } + + S32 channel = shader.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - if (channel > -1 && img) + if (channel > -1) { - gGL.getTexUnit(channel)->bind(img); + if (img) + { + gGL.getTexUnit(channel)->bind(img); - F32 lod_range = logf(img->getWidth())/logf(2.f); + F32 lod_range = logf(img->getWidth())/logf(2.f); - shader.uniform1f("proj_focus", focus); - shader.uniform1f("proj_lod", lod_range); - shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + shader.uniform1f(LLShaderMgr::PROJECTOR_FOCUS, focus); + shader.uniform1f(LLShaderMgr::PROJECTOR_LOD, lod_range); + shader.uniform1f(LLShaderMgr::PROJECTOR_AMBIENT_LOD, llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } } + } void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { stop_glerror(); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); - shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_BLOOM); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + shader.disableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage()); + shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); + shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM); for (U32 i = 0; i < 4; i++) { - if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) { glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } @@ -7003,16 +7944,16 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) for (U32 i = 4; i < 6; i++) { - if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) + if (shader.disableTexture(LLShaderMgr::DEFERRED_SHADOW0+i) > -1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } - shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); + shader.disableTexture(LLShaderMgr::DEFERRED_NOISE); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHTFUNC); - S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); + S32 channel = shader.disableTexture(LLShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) { LLCubeMap* cube_map = gSky.mVOSkyp ? gSky.mVOSkyp->getCubeMap() : NULL; @@ -7024,8 +7965,6 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); - - LLGLState::checkTextureChannels(); } inline float sgn(float a) @@ -7040,11 +7979,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { BOOL skip_avatar_update = FALSE; - if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { skip_avatar_update = TRUE; } - + if (!skip_avatar_update) { gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); @@ -7058,11 +7997,6 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = TRUE; - S32 occlusion = LLPipeline::sUseOcclusion; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - LLPipeline::sUseOcclusion = llmin(occlusion, 1); gPipeline.pushRenderTypeMask(); @@ -7098,28 +8032,33 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map + + //disable occlusion culling for reflection map for now + S32 occlusion = LLPipeline::sUseOcclusion; + 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(); gGL.setColorMask(true, false); mWaterRef.getViewport(gGLViewport); - + stop_glerror(); - glPushMatrix(); + gGL.pushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - + glh::matrix4f current = glh_get_current_modelview(); mat = current * mat; glh_set_current_modelview(mat); - glLoadMatrixf(mat.m); + gGL.loadMatrix(mat.m); LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); @@ -7133,47 +8072,46 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); static LLCullResult ref_result; - - if (LLDrawPoolWater::sNeedsDistortionUpdate) + + if (LLDrawPoolWater::sNeedsReflectionUpdate) { //initial sky pass (no user clip plane) { //mask out everything but the sky gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); stateSort(camera, result); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); + gPipeline.popRenderTypeMask(); } gPipeline.pushRenderTypeMask(); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); - S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); + S32 detail = RenderReflectionDetail; if (detail > 0) { //mask out selected geometry based on reflection detail if (detail < 4) { clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); - if (detail < 3) - { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); - if (detail < 2) + if (detail < 3) { + clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); + if (detail < 2) + { clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES); } } @@ -7181,26 +8119,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, ref_result, 1); + updateCull(camera, ref_result, -water_clip, &plane); stateSort(camera, ref_result); - } - - if (LLDrawPoolWater::sNeedsDistortionUpdate) - { - if (gSavedSettings.getS32("RenderReflectionDetail") > 0) + } + + if (LLDrawPoolWater::sNeedsDistortionUpdate) { - gPipeline.grabReferences(ref_result); - LLGLUserClipPlane clip_plane(plane, mat, projection); - renderGeom(camera); - } - } + if (RenderReflectionDetail > 0) + { + gPipeline.grabReferences(ref_result); + LLGLUserClipPlane clip_plane(plane, mat, projection); + renderGeom(camera); + } + } gPipeline.popRenderTypeMask(); } glCullFace(GL_BACK); - glPopMatrix(); + gGL.popMatrix(); mWaterRef.flush(); glh_set_current_modelview(current); + LLPipeline::sUseOcclusion = occlusion; } camera.setOrigin(camera_in.getOrigin()); @@ -7231,15 +8170,18 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera mat = glh_get_current_modelview(); - LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection); + LLPlane plane(-pnorm, -(pd+pad)); + + LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; - updateCull(camera, result, water_clip); + updateCull(camera, result, water_clip, &plane); stateSort(camera, result); gGL.setColorMask(true, true); @@ -7267,17 +8209,17 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.popRenderTypeMask(); LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; - LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); - LLPipeline::sUseOcclusion = occlusion; + LLPlane npnorm(-pnorm, -pd); + LLViewerCamera::getInstance()->setUserClipPlane(npnorm); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); if (!skip_avatar_update) { gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; } } @@ -7363,7 +8305,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera } LLPipeline::sShadowRender = TRUE; - U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP, LLRenderPass::PASS_FULLBRIGHT_SHINY }; + U32 types[] = { + LLRenderPass::PASS_SIMPLE, + LLRenderPass::PASS_FULLBRIGHT, + LLRenderPass::PASS_SHINY, + LLRenderPass::PASS_BUMP, + LLRenderPass::PASS_FULLBRIGHT_SHINY + }; + LLGLEnable cull(GL_CULL_FACE); if (use_shader) @@ -7375,40 +8324,49 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera stateSort(shadow_cam, result); //generate shadow map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj.m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view.m); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadMatrix(proj.m); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadMatrix(gGLModelView); stop_glerror(); gGLLastMatrix = NULL; { - LLGLDepthTest depth(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + //LLGLDepthTest depth(GL_TRUE); + //glClear(GL_DEPTH_BUFFER_BIT); } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - glColor4f(1,1,1,1); stop_glerror(); - - gGL.setColorMask(false, false); //glCullFace(GL_FRONT); + LLVertexBuffer::unbind(); + { + if (!use_shader) + { //occlusion program is general purpose depth-only no-textures + gOcclusionProgram.bind(); + } + + gGL.diffuseColor4f(1,1,1,1); + gGL.setColorMask(false, false); + LLFastTimer ftm(FTM_SHADOW_SIMPLE); - LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->disable(); for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) { renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); } gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + if (!use_shader) + { + gOcclusionProgram.unbind(); + } } if (use_shader) @@ -7424,18 +8382,27 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { LLFastTimer ftm(FTM_SHADOW_ALPHA); - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); - glColor4f(1,1,1,1); + gDeferredShadowAlphaMaskProgram.bind(); + gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); + + U32 mask = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_COLOR | + LLVertexBuffer::MAP_TEXTURE_INDEX; + + renderObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); + renderObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); + gDeferredTreeShadowProgram.bind(); + gDeferredTreeShadowProgram.setMinimumAlpha(0.598f); renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } //glCullFace(GL_BACK); + gDeferredShadowProgram.bind(); gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); + gGL.loadMatrix(gGLModelView); doOcclusion(shadow_cam); if (use_shader) @@ -7445,10 +8412,10 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGL.setColorMask(true, true); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); gGLLastMatrix = NULL; LLPipeline::sUseOcclusion = occlude; @@ -7467,14 +8434,13 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } //get set of planes on bounding box - std::vector<LLPlane> bp; - - bp.push_back(LLPlane(min, LLVector3(-1,0,0))); - bp.push_back(LLPlane(min, LLVector3(0,-1,0))); - bp.push_back(LLPlane(min, LLVector3(0,0,-1))); - bp.push_back(LLPlane(max, LLVector3(1,0,0))); - bp.push_back(LLPlane(max, LLVector3(0,1,0))); - bp.push_back(LLPlane(max, LLVector3(0,0,1))); + LLPlane bp[] = { + LLPlane(min, LLVector3(-1,0,0)), + LLPlane(min, LLVector3(0,-1,0)), + LLPlane(min, LLVector3(0,0,-1)), + LLPlane(max, LLVector3(1,0,0)), + LLPlane(max, LLVector3(0,1,0)), + LLPlane(max, LLVector3(0,0,1))}; //potential points std::vector<LLVector3> pp; @@ -7522,7 +8488,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLPlane& cp = camera.getAgentPlane(j); const LLVector3& v1 = pp[bs[i*2+0]]; const LLVector3& v2 = pp[bs[i*2+1]]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7536,8 +8503,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector LLVector3 intersect = v2+line*t; pp.push_back(intersect); } - } } + } //camera frustum line segments const U32 fs[] = @@ -7545,7 +8512,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector 0,1, 1,2, 2,3, - 3,1, + 3,0, 4,5, 5,6, @@ -7568,7 +8535,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLVector3& v1 = pp[fs[i*2+0]+8]; const LLVector3& v2 = pp[fs[i*2+1]+8]; const LLPlane& cp = bp[j]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7583,7 +8551,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector pp.push_back(intersect); } } - } + } LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), max+LLVector3(0.05f,0.05f,0.05f) }; @@ -7629,184 +8597,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector return TRUE; } -void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<LLVector3>& vpc) -{ - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) < 3) - { - return; - } - - LLVector3 up; - - //LLGLEnable depth_clamp(GL_DEPTH_CLAMP_NV); - - if (lightDir.mV[2] > 0.5f) - { - up = LLVector3(1,0,0); - } - else - { - up = LLVector3(0, 0, 1); - } - - - F32 gi_range = gSavedSettings.getF32("RenderGIRange"); - - U32 res = mGIMap.getWidth(); - - F32 atten = llmax(gSavedSettings.getF32("RenderGIAttenuation"), 0.001f); - - //set radius to range at which distance attenuation of incoming photons is near 0 - - F32 lrad = sqrtf(1.f/(atten*0.01f)); - - F32 lrange = lrad+gi_range*0.5f; - - LLVector3 pad(lrange,lrange,lrange); - - glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up); - - LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f); - - glh::vec3f scp(cp.mV); - view.mult_matrix_vec(scp); - cp.setVec(scp.v); - - F32 pix_width = lrange/(res*0.5f); - - //move cp to the nearest pix_width - for (U32 i = 0; i < 3; i++) - { - cp.mV[i] = llround(cp.mV[i], pix_width); - } - - LLVector3 min = cp-pad; - LLVector3 max = cp+pad; - - //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point - mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res; - mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res; - mGILightRadius = lrad/lrange*0.5f; - - glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - - LLCamera sun_cam = camera; - - glh::matrix4f eye_view = glh_get_current_modelview(); - - //get eye space to camera space matrix - mGIMatrix = view*eye_view.inverse(); - mGINormalMatrix = mGIMatrix.inverse().transpose(); - mGIInvProj = proj.inverse(); - mGIMatrixProj = proj*mGIMatrix; - - //translate and scale to [0,1] - glh::matrix4f trans(.5f, 0.f, 0.f, .5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); - - mGIMatrixProj = trans*mGIMatrixProj; - - glh_set_current_modelview(view); - glh_set_current_projection(proj); - - LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE); - - sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); - static LLCullResult result; - - pushRenderTypeMask(); - - andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_TREE, - LLPipeline::RENDER_TYPE_TERRAIN, - LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_SHINY, - END_RENDER_TYPES); - - - - S32 occlude = LLPipeline::sUseOcclusion; - //LLPipeline::sUseOcclusion = 0; - LLPipeline::sShadowRender = TRUE; - - //only render large objects into GI map - sMinRenderSize = gSavedSettings.getF32("RenderGIMinRenderSize"); - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_GI_SOURCE; - mGIMap.bindTarget(); - - F64 last_modelview[16]; - F64 last_projection[16]; - for (U32 i = 0; i < 16; i++) - { - last_modelview[i] = gGLLastModelView[i]; - last_projection[i] = gGLLastProjection[i]; - gGLLastModelView[i] = mGIModelview.m[i]; - gGLLastProjection[i] = mGIProjection.m[i]; - } - - sun_cam.setOrigin(0.f, 0.f, 0.f); - updateCull(sun_cam, result); - stateSort(sun_cam, result); - - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = last_modelview[i]; - gGLLastProjection[i] = last_projection[i]; - } - - mGIProjection = proj; - mGIModelview = view; - - LLGLEnable cull(GL_CULL_FACE); - - //generate GI map - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadMatrixf(proj.m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadMatrixf(view.m); - - stop_glerror(); - gGLLastMatrix = NULL; - - mGIMap.clear(); - - { - //LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderGeomDeferred(camera); - } - - mGIMap.flush(); - - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; - - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; - sMinRenderSize = 0.f; - - popRenderTypeMask(); - -} - void LLPipeline::renderHighlight(const LLViewerObject* obj, F32 fade) { if (obj && obj->getVolume()) @@ -7841,7 +8631,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) if (!mHighlightSet.empty()) { - F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime"); + F32 transition = gFrameIntervalSeconds/RenderHighlightFadeTime; LLGLDisable test(GL_ALPHA_TEST); LLGLDepthTest depth(GL_FALSE); @@ -7887,11 +8677,23 @@ void LLPipeline::generateHighlight(LLCamera& camera) void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0) + if (!sRenderDeferred || RenderShadowDetail <= 0) { return; } + BOOL skip_avatar_update = FALSE; + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) + { + + skip_avatar_update = TRUE; + } + + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); + } + F64 last_modelview[16]; F64 last_projection[16]; for (U32 i = 0; i < 16; i++) @@ -7912,7 +8714,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, - LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, + LLPipeline::RENDER_TYPE_PASS_ALPHA, + LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, + LLPipeline::RENDER_TYPE_PASS_GRASS, LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_BUMP, LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, @@ -7933,20 +8738,28 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glh::matrix4f proj[6]; //clip contains parallel split distances for 3 splits - LLVector3 clip = gSavedSettings.getVector3("RenderShadowClipPlanes"); + LLVector3 clip = RenderShadowClipPlanes; //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); //far clip on last split is minimum of camera view distance and 128 mSunClipPlanes = LLVector4(clip, clip.mV[2] * clip.mV[2]/clip.mV[1]); - clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); + clip = RenderShadowOrthoClipPlanes; 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 = gSavedSettings.getVector3("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 + LLPlane shadow_near_clip; + { + LLVector3 p = gAgent.getPositionAgent(); + p += mSunDir * RenderFarClip*2.f; + shadow_near_clip.setVec(p, mSunDir); + } + LLVector3 lightDir = -mSunDir; lightDir.normVec(); @@ -7996,11 +8809,15 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowFrustPoints[3].clear(); } popRenderTypeMask(); + + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } + return; } - generateGI(camera, lightDir, fp); - //get good split distances for frustum for (U32 i = 0; i < fp.size(); ++i) { @@ -8021,561 +8838,564 @@ void LLPipeline::generateSunShadow(LLCamera& camera) near_clip = -max.mV[2]; F32 far_clip = -min.mV[2]*2.f; - far_clip = llmin(far_clip, 128.f); + //far_clip = llmin(far_clip, 128.f); far_clip = llmin(far_clip, camera.getFar()); F32 range = far_clip-near_clip; - LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent"); + LLVector3 split_exp = RenderShadowSplitExponent; F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); da = powf(da, split_exp.mV[2]); - F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; - - + for (U32 i = 0; i < 4; ++i) { F32 x = (F32)(i+1)/4.f; x = powf(x, sxp); mSunClipPlanes.mV[i] = near_clip+range*x; } + + mSunClipPlanes.mV[0] *= 1.25f; //bump back first split for transition padding } // convenience array of 4 near clip plane distances F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; - for (S32 j = 0; j < 4; j++) - { - if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + + if (mSunDiffuse == LLColor4::black) + { //sun diffuse is totally black, shadows don't matter + LLGLDepthTest depth(GL_TRUE); + + for (S32 j = 0; j < 4; j++) { - mShadowFrustPoints[j].clear(); + mShadow[j].bindTarget(); + mShadow[j].clear(); + mShadow[j].flush(); } + } + else + { + for (S32 j = 0; j < 4; j++) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustPoints[j].clear(); + } - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+j; - //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + //restore render matrices + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - LLVector3 eye = camera.getOrigin(); + LLVector3 eye = camera.getOrigin(); - //camera used for shadow cull/render - LLCamera shadow_cam; + //camera used for shadow cull/render + LLCamera shadow_cam; - //create world space camera frustum for this split - shadow_cam = camera; - shadow_cam.setFar(16.f); + //create world space camera frustum for this split + shadow_cam = camera; + shadow_cam.setFar(16.f); - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - LLVector3* frust = shadow_cam.mAgentFrustum; + LLVector3* frust = shadow_cam.mAgentFrustum; - LLVector3 pn = shadow_cam.getAtAxis(); + LLVector3 pn = shadow_cam.getAtAxis(); - LLVector3 min, max; + LLVector3 min, max; - //construct 8 corners of split frustum section - for (U32 i = 0; i < 4; i++) - { - LLVector3 delta = frust[i+4]-eye; - delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; - delta.normVec(); - F32 dp = delta*pn; - frust[i] = eye + (delta*dist[j]*0.95f)/dp; - frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp; - } + //construct 8 corners of split frustum section + for (U32 i = 0; i < 4; i++) + { + LLVector3 delta = frust[i+4]-eye; + delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f; + delta.normVec(); + F32 dp = delta*pn; + frust[i] = eye + (delta*dist[j]*0.75f)/dp; + frust[i+4] = eye + (delta*dist[j+1]*1.25f)/dp; + } - shadow_cam.calcAgentFrustumPlanes(frust); - shadow_cam.mFrustumCornerDist = 0.f; + shadow_cam.calcAgentFrustumPlanes(frust); + shadow_cam.mFrustumCornerDist = 0.f; - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowCamera[j] = shadow_cam; - } - - std::vector<LLVector3> fp; - - if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) - { - //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { - mShadowExtents[j][0] = LLVector3(); - mShadowExtents[j][1] = LLVector3(); - mShadowCamera[j+4] = shadow_cam; + mShadowCamera[j] = shadow_cam; } - mShadow[j].bindTarget(); - { - LLGLDepthTest depth(GL_TRUE); - mShadow[j].clear(); - } - mShadow[j].flush(); + std::vector<LLVector3> fp; - mShadowError.mV[j] = 0.f; - mShadowFOV.mV[j] = 0.f; + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) + { + //no possible shadow receivers + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowExtents[j][0] = LLVector3(); + mShadowExtents[j][1] = LLVector3(); + mShadowCamera[j+4] = shadow_cam; + } - continue; - } + mShadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mShadow[j].clear(); + } + mShadow[j].flush(); - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowExtents[j][0] = min; - mShadowExtents[j][1] = max; - mShadowFrustPoints[j] = fp; - } - + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; - //find a good origin for shadow projection - LLVector3 origin; + continue; + } - //get a temporary view projection - view[j] = look(camera.getOrigin(), lightDir, -up); + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowExtents[j][0] = min; + mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; + } + - std::vector<LLVector3> wpf; + //find a good origin for shadow projection + LLVector3 origin; - for (U32 i = 0; i < fp.size(); i++) - { - glh::vec3f p = glh::vec3f(fp[i].mV); - view[j].mult_matrix_vec(p); - wpf.push_back(LLVector3(p.v)); - } + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); - min = wpf[0]; - max = wpf[0]; + std::vector<LLVector3> wpf; - for (U32 i = 0; i < fp.size(); ++i) - { //get AABB in camera space - update_min_max(min, max, wpf[i]); - } - - // Construct a perspective transform with perspective along y-axis that contains - // points in wpf - //Known: - // - far clip plane - // - near clip plane - // - points in frustum - //Find: - // - origin - - //get some "interesting" points of reference - LLVector3 center = (min+max)*0.5f; - LLVector3 size = (max-min)*0.5f; - LLVector3 near_center = center; - near_center.mV[1] += size.mV[1]*2.f; - - - //put all points in wpf in quadrant 0, reletive to center of min/max - //get the best fit line using least squares - F32 bfm = 0.f; - F32 bfb = 0.f; + for (U32 i = 0; i < fp.size(); i++) + { + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); + } - for (U32 i = 0; i < wpf.size(); ++i) - { - wpf[i] -= center; - wpf[i].mV[0] = fabsf(wpf[i].mV[0]); - wpf[i].mV[2] = fabsf(wpf[i].mV[2]); - } + min = wpf[0]; + max = wpf[0]; - if (!wpf.empty()) - { - F32 sx = 0.f; - F32 sx2 = 0.f; - F32 sy = 0.f; - F32 sxy = 0.f; - - for (U32 i = 0; i < wpf.size(); ++i) - { - sx += wpf[i].mV[0]; - sx2 += wpf[i].mV[0]*wpf[i].mV[0]; - sy += wpf[i].mV[1]; - sxy += wpf[i].mV[0]*wpf[i].mV[1]; + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); } - bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); - bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); - } + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin + + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; - { - // best fit line is y=bfm*x+bfb - //find point that is furthest to the right of line - F32 off_x = -1.f; - LLVector3 lp; - - for (U32 i = 0; i < wpf.size(); ++i) - { - //y = bfm*x+bfb - //x = (y-bfb)/bfm - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - - lx = wpf[i].mV[0]-lx; - - if (off_x < lx) - { - off_x = lx; - lp = wpf[i]; - } - } - - //get line with slope bfm through lp - // bfb = y-bfm*x - bfb = lp.mV[1]-bfm*lp.mV[0]; - - //calculate error - mShadowError.mV[j] = 0.f; + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; for (U32 i = 0; i < wpf.size(); ++i) { - F32 lx = (wpf[i].mV[1]-bfb)/bfm; - mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); } - mShadowError.mV[j] /= wpf.size(); - mShadowError.mV[j] /= size.mV[0]; + if (!wpf.empty()) + { + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; + } - if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff")) - { //just use ortho projection - mShadowFOV.mV[j] = -1.f; - origin.clearVec(); - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); } - else + { - //origin is where line x = 0; - origin.setVec(0,bfb,0); - - F32 fovz = 1.f; - F32 fovx = 1.f; - - LLVector3 zp; - LLVector3 xp; + // best fit line is y=bfm*x+bfb + + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; for (U32 i = 0; i < wpf.size(); ++i) { - LLVector3 atz = wpf[i]-origin; - atz.mV[0] = 0.f; - atz.normVec(); - if (fovz > -atz.mV[1]) - { - zp = wpf[i]; - fovz = -atz.mV[1]; - } - - LLVector3 atx = wpf[i]-origin; - atx.mV[2] = 0.f; - atx.normVec(); - if (fovx > -atx.mV[1]) + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) { - fovx = -atx.mV[1]; - xp = wpf[i]; + off_x = lx; + lp = wpf[i]; } } - fovx = acos(fovx); - fovz = acos(fovz); + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; - F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f); - - mShadowFOV.mV[j] = fovx; - - if (fovx < cutoff && fovz > cutoff) + //calculate error + mShadowError.mV[j] = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) { - //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff - F32 d = zp.mV[2]/tan(cutoff); - F32 ny = zp.mV[1] + fabsf(d); + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + } - origin.mV[1] = ny; + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; + + if (mShadowError.mV[j] > RenderShadowErrorCutoff) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); - fovz = 1.f; - fovx = 1.f; + F32 fovz = 1.f; + F32 fovx = 1.f; + + LLVector3 zp; + LLVector3 xp; for (U32 i = 0; i < wpf.size(); ++i) { LLVector3 atz = wpf[i]-origin; atz.mV[0] = 0.f; atz.normVec(); - fovz = llmin(fovz, -atz.mV[1]); - + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } + LLVector3 atx = wpf[i]-origin; atx.mV[2] = 0.f; atx.normVec(); - fovx = llmin(fovx, -atx.mV[1]); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } } fovx = acos(fovx); fovz = acos(fovz); - if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) + F32 cutoff = llmin((F32) RenderShadowFOVCutoff, 1.4f); + + mShadowFOV.mV[j] = fovx; + + if (fovx < cutoff && fovz > cutoff) { - // llerrs << "WTF?" << llendl; - } + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); - mShadowFOV.mV[j] = cutoff; - } + origin.mV[1] = ny; + + fovz = 1.f; + fovx = 1.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } + + fovx = acos(fovx); + fovz = acos(fovz); + + mShadowFOV.mV[j] = cutoff; + } - origin += center; + origin += center; - F32 ynear = -(max.mV[1]-origin.mV[1]); - F32 yfar = -(min.mV[1]-origin.mV[1]); + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); - if (ynear < 0.1f) //keep a sensible near clip plane - { - F32 diff = 0.1f-ynear; - origin.mV[1] += diff; - ynear += diff; - yfar += diff; - } + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } - if (fovx > cutoff) - { //just use ortho projection - origin.clearVec(); - mShadowError.mV[j] = -1.f; - proj[j] = gl_ortho(min.mV[0], max.mV[0], - min.mV[1], max.mV[1], - -max.mV[2], -min.mV[2]); - } - else - { - //get perspective projection - view[j] = view[j].inverse(); + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //get perspective projection + view[j] = view[j].inverse(); - glh::vec3f origin_agent(origin.mV); + glh::vec3f origin_agent(origin.mV); - //translate view to origin - view[j].mult_matrix_vec(origin_agent); + //translate view to origin + view[j].mult_matrix_vec(origin_agent); - eye = LLVector3(origin_agent.v); + eye = LLVector3(origin_agent.v); - if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - mShadowFrustOrigin[j] = eye; - } + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustOrigin[j] = eye; + } - view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); - F32 fx = 1.f/tanf(fovx); - F32 fz = 1.f/tanf(fovz); + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); - proj[j] = glh::matrix4f(-fx, 0, 0, 0, - 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), - 0, 0, -fz, 0, - 0, -1.f, 0, 0); + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } } } - } - shadow_cam.setFar(128.f); - shadow_cam.setOriginAndLookAt(eye, up, center); + //shadow_cam.setFar(128.f); + shadow_cam.setOriginAndLookAt(eye, up, center); - shadow_cam.setOrigin(0,0,0); + shadow_cam.setOrigin(0,0,0); - glh_set_current_modelview(view[j]); - glh_set_current_projection(proj[j]); + glh_set_current_modelview(view[j]); + glh_set_current_projection(proj[j]); - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + //shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + shadow_cam.getAgentPlane(LLCamera::AGENT_PLANE_NEAR).set(shadow_near_clip); - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[j]); - glh_set_current_projection(proj[j]); + glh_set_current_modelview(view[j]); + glh_set_current_projection(proj[j]); - for (U32 i = 0; i < 16; i++) - { - gGLLastModelView[i] = mShadowModelview[j].m[i]; - gGLLastProjection[i] = mShadowProjection[j].m[i]; - } + for (U32 i = 0; i < 16; i++) + { + gGLLastModelView[i] = mShadowModelview[j].m[i]; + gGLLastProjection[i] = mShadowProjection[j].m[i]; + } - mShadowModelview[j] = view[j]; - mShadowProjection[j] = proj[j]; + mShadowModelview[j] = view[j]; + mShadowProjection[j] = proj[j]; - mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; + mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - stop_glerror(); - - mShadow[j].bindTarget(); - mShadow[j].getViewport(gGLViewport); + stop_glerror(); - { - static LLCullResult result[4]; + mShadow[j].bindTarget(); + mShadow[j].getViewport(gGLViewport); + mShadow[j].clear(); + + { + static LLCullResult result[4]; - //LLGLEnable enable(GL_DEPTH_CLAMP_NV); - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE); - } + //LLGLEnable enable(GL_DEPTH_CLAMP_NV); + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE); + } - mShadow[j].flush(); + mShadow[j].flush(); - if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) - { - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - mShadowCamera[j+4] = shadow_cam; + if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + mShadowCamera[j+4] = shadow_cam; + } } } //hack to disable projector shadows - static bool clear = true; - bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; + bool gen_shadow = RenderShadowDetail > 1; if (gen_shadow) { - clear = true; - F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - //update shadow targets - for (U32 i = 0; i < 2; i++) - { //for each current shadow - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; - - if (mShadowSpotLight[i].notNull() && - (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || - mShadowSpotLight[i] == mTargetShadowSpotLight[1])) - { //keep this spotlight - mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); - } - else - { //fade out this light - mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); - - if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) - { //faded out, grab one of the pending spots (whichever one isn't already taken) - if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) - { - mShadowSpotLight[i] = mTargetShadowSpotLight[0]; - } - else - { - mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } } } } - } - - for (S32 i = 0; i < 2; i++) - { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); - if (mShadowSpotLight[i].isNull()) + for (S32 i = 0; i < 2; i++) { - continue; - } + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + if (mShadowSpotLight[i].isNull()) + { + continue; + } - if (!volume) - { - mShadowSpotLight[i] = NULL; - continue; - } + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); - LLDrawable* drawable = mShadowSpotLight[i]; + if (!volume) + { + mShadowSpotLight[i] = NULL; + continue; + } - LLVector3 params = volume->getSpotLightParams(); - F32 fov = params.mV[0]; + LLDrawable* drawable = mShadowSpotLight[i]; - //get agent->light space matrix (modelview) - LLVector3 center = drawable->getPositionAgent(); - LLQuaternion quat = volume->getRenderRotation(); + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; - //get near clip plane - LLVector3 scale = volume->getScale(); - LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); - at_axis *= quat; + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); - LLVector3 np = center+at_axis; - at_axis.normVec(); + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; - //get origin that has given fov for plane np, at_axis, and given scale - F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + LLVector3 np = center+at_axis; + at_axis.normVec(); - LLVector3 origin = np - at_axis*dist; + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); - LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + LLVector3 origin = np - at_axis*dist; - view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); - view[i+4] = view[i+4].inverse(); + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); - //get perspective matrix - F32 near_clip = dist+0.01f; - F32 width = scale.mV[VX]; - F32 height = scale.mV[VY]; - F32 far_clip = dist+volume->getLightRadius()*1.5f; + view[i+4] = view[i+4].inverse(); - F32 fovy = fov * RAD_TO_DEG; - F32 aspect = width/height; - - proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; - //translate and scale to from [-1, 1] to [0, 1] - glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, - 0.f, 0.5f, 0.f, 0.5f, - 0.f, 0.f, 0.5f, 0.5f, - 0.f, 0.f, 0.f, 1.f); + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - glh_set_current_modelview(view[i+4]); - glh_set_current_projection(proj[i+4]); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - - for (U32 j = 0; j < 16; j++) - { - gGLLastModelView[j] = mShadowModelview[i+4].m[j]; - gGLLastProjection[j] = mShadowProjection[i+4].m[j]; - } + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - mShadowModelview[i+4] = view[i+4]; - mShadowProjection[i+4] = proj[i+4]; + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; + + for (U32 j = 0; j < 16; j++) + { + gGLLastModelView[j] = mShadowModelview[i+4].m[j]; + gGLLastProjection[j] = mShadowProjection[i+4].m[j]; + } - LLCamera shadow_cam = camera; - shadow_cam.setFar(far_clip); - shadow_cam.setOrigin(origin); + mShadowModelview[i+4] = view[i+4]; + mShadowProjection[i+4] = proj[i+4]; - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - stop_glerror(); + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + stop_glerror(); - mShadow[i+4].bindTarget(); - mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].clear(); - static LLCullResult result[2]; + static LLCullResult result[2]; - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; - renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); - mShadow[i+4].flush(); - } + mShadow[i+4].flush(); + } } else - { - if (clear) - { - clear = false; - for (U32 i = 4; i < 6; i++) - { - mShadow[i].bindTarget(); - mShadow[i].clear(); - mShadow[i].flush(); - } - } + { //no spotlight shadows + mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; } - if (!gSavedSettings.getBOOL("CameraOffset")) + + if (!CameraOffset) { glh_set_current_modelview(saved_view); glh_set_current_projection(saved_proj); @@ -8584,10 +9404,10 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { glh_set_current_modelview(view[1]); glh_set_current_projection(proj[1]); - glLoadMatrixf(view[1].m); - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(proj[1].m); - glMatrixMode(GL_MODELVIEW); + gGL.loadMatrix(view[1].m); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.loadMatrix(proj[1].m); + gGL.matrixMode(LLRender::MM_MODELVIEW); } gGL.setColorMask(true, false); @@ -8598,6 +9418,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } popRenderTypeMask(); + + if (!skip_avatar_update) + { + gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); + } } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -8633,7 +9458,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) assertInitialized(); - BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); + bool muted = avatar->isVisuallyMuted(); pushRenderTypeMask(); @@ -8692,7 +9517,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) stateSort(*LLViewerCamera::getInstance(), result); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); LLCamera camera = *viewer_camera; @@ -8701,44 +9526,47 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector2 tdim; - LLVector3 half_height = (ext[1]-ext[0])*0.5f; - LLVector3 left = camera.getLeftAxis(); - left *= left; - left.normalize(); + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); - LLVector3 up = camera.getUpAxis(); - up *= up; - up.normalize(); + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + left.normalize3fast(); - tdim.mV[0] = fabsf(half_height * left); - tdim.mV[1] = fabsf(half_height * up); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - //glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + F32 distance = (pos-camera.getOrigin()).length(); F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; - F32 aspect = tdim.mV[0]/tdim.mV[1]; //128.f/256.f; + F32 aspect = tdim.mV[0]/tdim.mV[1]; glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); glh_set_current_projection(persp); - glLoadMatrixf(persp.m); + gGL.loadMatrix(persp.m); - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); glh::matrix4f mat; camera.getOpenGLTransform(mat.m); mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; - glLoadMatrixf(mat.m); + gGL.loadMatrix(mat.m); glh_set_current_modelview(mat); glClearColor(0.0f,0.0f,0.0f,0.0f); gGL.setColorMask(true, true); - glStencilMask(0xFFFFFFFF); - glClearStencil(0); - + // get the number of pixels per angle F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); @@ -8749,7 +9577,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE); + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); if (LLPipeline::sRenderDeferred) { @@ -8761,43 +9589,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilMask(0xFFFFFFFF); - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + avatar->mImpostor.bindTarget(); - { - LLGLEnable scissor(GL_SCISSOR_TEST); - glScissor(0, 0, resX, resY); - avatar->mImpostor.bindTarget(); - avatar->mImpostor.clear(); - } - if (LLPipeline::sRenderDeferred) { - stop_glerror(); + avatar->mImpostor.clear(); renderGeomDeferred(camera); renderGeomPostDeferred(camera); } else { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, resX, resY); + avatar->mImpostor.clear(); renderGeom(camera); } - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); - - { //create alpha mask based on stencil buffer (grey out if muted) - LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; - LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; - + { //create alpha mask based on depth buffer (grey out if muted) if (LLPipeline::sRenderDeferred) { - GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + GLuint buff = GL_COLOR_ATTACHMENT0; glDrawBuffersARB(1, &buff); } - LLGLEnable blend(muted ? 0 : GL_BLEND); + LLGLDisable blend(GL_BLEND); if (muted) { @@ -8808,24 +9623,43 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.setColorMask(false, true); } - gGL.setSceneBlendType(LLRender::BT_ADD); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + gGL.flush(); + + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + + static const F32 clip_plane = 0.99999f; + + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.bind(); + } - gGL.color4f(1,1,1,1); gGL.color4ub(64,64,64,255); gGL.begin(LLRender::QUADS); - gGL.vertex3fv((pos+left-up).mV); - gGL.vertex3fv((pos-left-up).mV); - gGL.vertex3fv((pos-left+up).mV); - gGL.vertex3fv((pos+left+up).mV); + gGL.vertex3f(-1, -1, clip_plane); + gGL.vertex3f(1, -1, clip_plane); + gGL.vertex3f(1, 1, clip_plane); + gGL.vertex3f(-1, 1, clip_plane); gGL.end(); gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } + if (LLGLSLShader::sNoFixedFunction) + { + gUIProgram.unbind(); + } + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + } avatar->mImpostor.flush(); @@ -8838,10 +9672,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sShadowRender = FALSE; popRenderTypeMask(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); avatar->mNeedsImpostorUpdate = FALSE; avatar->cacheImpostorValues(); @@ -8997,4 +9831,9 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) } } +void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) +{ + DebugBlip blip(position, color); + mDebugBlips.push_back(blip); +} |