diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 1747 |
1 files changed, 634 insertions, 1113 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bec33790bd..f0ed303f66 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -88,6 +88,7 @@ #include "llvocache.h" #include "llvoground.h" #include "llvosky.h" +#include "llvowlsky.h" #include "llvotree.h" #include "llvovolume.h" #include "llvosurfacepatch.h" @@ -100,8 +101,6 @@ #include "llviewerstats.h" #include "llviewerjoystick.h" #include "llviewerdisplay.h" -#include "llwlparammanager.h" -#include "llwaterparammanager.h" #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" @@ -116,6 +115,9 @@ #include "llprogressview.h" #include "llcleanup.h" +#include "llenvironment.h" +#include "llsettingsvo.h" + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 //#define DEBUG_INDICES @@ -131,7 +133,6 @@ bool gShiftFrame = false; //cached settings bool LLPipeline::RenderAvatarVP; -bool LLPipeline::VertexShaderEnable; bool LLPipeline::WindLightUseAtmosShaders; bool LLPipeline::RenderDeferred; F32 LLPipeline::RenderDeferredSunWash; @@ -187,6 +188,7 @@ F32 LLPipeline::RenderShadowOffset; F32 LLPipeline::RenderShadowBias; F32 LLPipeline::RenderSpotShadowOffset; F32 LLPipeline::RenderSpotShadowBias; +LLDrawable* LLPipeline::RenderSpotLight = nullptr; F32 LLPipeline::RenderEdgeDepthCutoff; F32 LLPipeline::RenderEdgeNormCutoff; LLVector3 LLPipeline::RenderShadowGaussian; @@ -209,6 +211,7 @@ LLTrace::EventStatHandle<S64> LLPipeline::sStatBatchSize("renderbatchsize"); const F32 BACKLIGHT_DAY_MAGNITUDE_OBJECT = 0.1f; const F32 BACKLIGHT_NIGHT_MAGNITUDE_OBJECT = 0.08f; +const F32 DEFERRED_LIGHT_FALLOFF = 0.5f; const U32 DEFERRED_VB_MASK = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; extern S32 gBoxFrame; @@ -253,6 +256,11 @@ LLTrace::BlockTimerStatHandle FTM_PIPELINE("Pipeline"); LLTrace::BlockTimerStatHandle FTM_CLIENT_COPY("Client Copy"); LLTrace::BlockTimerStatHandle FTM_RENDER_DEFERRED("Deferred Shading"); +LLTrace::BlockTimerStatHandle FTM_RENDER_UI_HUD("HUD"); +LLTrace::BlockTimerStatHandle FTM_RENDER_UI_3D("3D"); +LLTrace::BlockTimerStatHandle FTM_RENDER_UI_2D("2D"); +LLTrace::BlockTimerStatHandle FTM_RENDER_UI_DEBUG_TEXT("Debug Text"); +LLTrace::BlockTimerStatHandle FTM_RENDER_UI_SCENE_MON("Scene Mon"); static LLTrace::BlockTimerStatHandle FTM_STATESORT_DRAWABLE("Sort Drawables"); static LLTrace::BlockTimerStatHandle FTM_STATESORT_POSTSORT("Post Sort"); @@ -298,62 +306,6 @@ void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v); LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); -glh::matrix4f glh_copy_matrix(F32* src) -{ - glh::matrix4f ret; - ret.set_value(src); - return ret; -} - -glh::matrix4f glh_get_current_modelview() -{ - return glh_copy_matrix(gGLModelView); -} - -glh::matrix4f glh_get_current_projection() -{ - return glh_copy_matrix(gGLProjection); -} - -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++) - { - dst[i] = src.m[i]; - } -} - -void glh_set_current_modelview(const glh::matrix4f& mat) -{ - glh_copy_matrix(mat, gGLModelView); -} - -void glh_set_current_projection(glh::matrix4f& mat) -{ - glh_copy_matrix(mat, gGLProjection); -} - -glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, GLfloat znear, GLfloat zfar) -{ - glh::matrix4f ret( - 2.f/(right-left), 0.f, 0.f, -(right+left)/(right-left), - 0.f, 2.f/(top-bottom), 0.f, -(top+bottom)/(top-bottom), - 0.f, 0.f, -2.f/(zfar-znear), -(zfar+znear)/(zfar-znear), - 0.f, 0.f, 0.f, 1.f); - - return ret; -} - void display_update_camera(); //---------------------------------------- @@ -386,6 +338,7 @@ bool LLPipeline::sShadowRender = false; bool LLPipeline::sWaterReflections = false; bool LLPipeline::sRenderGlow = false; bool LLPipeline::sReflectionRender = false; +bool LLPipeline::sDistortionRender = false; bool LLPipeline::sImpostorRender = false; bool LLPipeline::sImpostorRenderAlphaDepthPass = false; bool LLPipeline::sUnderWaterRender = false; @@ -398,6 +351,7 @@ bool LLPipeline::sMemAllocationThrottled = false; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; bool LLPipeline::sRenderingHUDs; +F32 LLPipeline::sDistortionWaterClipPlaneMargin = 1.0125f; // EventHost API LLPipeline listener. static LLPipelineListener sPipelineListener; @@ -456,6 +410,11 @@ LLPipeline::LLPipeline() : mNoiseMap = 0; mTrueNoiseMap = 0; mLightFunc = 0; + + for(U32 i = 0; i < 8; i++) + { + mHWLightColors[i] = LLColor4::black; + } } void LLPipeline::connectRefreshCachedSettingsSafe(const std::string name) @@ -572,7 +531,6 @@ void LLPipeline::init() connectRefreshCachedSettingsSafe("RenderAvatarMaxNonImpostors"); connectRefreshCachedSettingsSafe("RenderDelayVBUpdate"); connectRefreshCachedSettingsSafe("UseOcclusion"); - connectRefreshCachedSettingsSafe("VertexShaderEnable"); connectRefreshCachedSettingsSafe("RenderAvatarVP"); connectRefreshCachedSettingsSafe("WindLightUseAtmosShaders"); connectRefreshCachedSettingsSafe("RenderDeferred"); @@ -777,6 +735,23 @@ void LLPipeline::throttleNewMemoryAllocation(bool disable) } } +void LLPipeline::requestResizeScreenTexture() +{ + gResizeScreenTexture = TRUE; +} + +void LLPipeline::requestResizeShadowTexture() +{ + gResizeShadowTexture = TRUE; +} + +void LLPipeline::resizeShadowTexture() +{ + releaseShadowTargets(); + allocateShadowBuffer(mScreenWidth, mScreenHeight); + gResizeShadowTexture = FALSE; +} + void LLPipeline::resizeScreenTexture() { LL_RECORD_BLOCK_TIME(FTM_RESIZE_SCREEN_TEXTURE); @@ -785,25 +760,14 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWorldViewWidthRaw(); GLuint resY = gViewerWindow->getWorldViewHeightRaw(); - if ((resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) + if (gResizeScreenTexture || (resX != mScreen.getWidth()) || (resY != mScreen.getHeight())) { releaseScreenBuffers(); - if (!allocateScreenBuffer(resX,resY)) - { -#if PROBABLE_FALSE_DISABLES_OF_ALM_HERE - //FAILSAFE: screen buffer allocation failed, disable deferred rendering if it's enabled - //NOTE: if the session closes successfully after this call, deferred rendering will be - // disabled on future sessions - if (LLPipeline::sRenderDeferred) - { - gSavedSettings.setBOOL("RenderDeferred", FALSE); - LLPipeline::refreshCachedSettings(); - + releaseShadowTargets(); + allocateScreenBuffer(resX,resY); + gResizeScreenTexture = FALSE; } -#endif } - } - } } void LLPipeline::allocatePhysicsBuffer() @@ -973,23 +937,78 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) mDeferredLight.release(); } - F32 scale = llmax(0.f, RenderShadowResolutionScale); + allocateShadowBuffer(resX, resY); + + //HACK make screenbuffer allocations start failing after 30 seconds + if (gSavedSettings.getBOOL("SimulateFBOFailure")) + { + return false; + } + } + else + { + mDeferredLight.release(); + + releaseShadowTargets(); + + mFXAABuffer.release(); + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + mOcclusionDepth.release(); + + if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; + } + + if (LLPipeline::sRenderDeferred) + { //share depth buffer between deferred targets + mDeferredScreen.shareDepthBuffer(mScreen); + } + + gGL.getTexUnit(0)->disable(); + + stop_glerror(); + + return true; +} + +// must be even to avoid a stripe in the horizontal shadow blur +inline U32 BlurHappySize(U32 x, F32 scale) { return U32( x * scale + 16.0f) & ~0xF; } + +bool LLPipeline::allocateShadowBuffer(U32 resX, U32 resY) +{ + refreshCachedSettings(); + + if (LLPipeline::sRenderDeferred) + { + S32 shadow_detail = RenderShadowDetail; + + const U32 occlusion_divisor = 3; + + F32 scale = llmax(0.f,RenderShadowResolutionScale); + U32 sun_shadow_map_width = BlurHappySize(resX, scale); + U32 sun_shadow_map_height = BlurHappySize(resY, scale); if (shadow_detail > 0) { //allocate 4 sun shadow maps - U32 sun_shadow_map_width = ((U32(resX*scale)+1)&~1); // must be even to avoid a stripe in the horizontal shadow blur for (U32 i = 0; i < 4; i++) { - if (!mShadow[i].allocate(sun_shadow_map_width,U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; - if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) return false; + if (!mShadow[i].allocate(sun_shadow_map_width, sun_shadow_map_height, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + { + return false; + } + + if (!mShadowOcclusion[i].allocate(sun_shadow_map_width/occlusion_divisor, sun_shadow_map_height/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_TEXTURE)) + { + return false; + } } } else { for (U32 i = 0; i < 4; i++) { - mShadow[i].release(); - mShadowOcclusion[i].release(); + releaseShadowTarget(i); } } @@ -999,54 +1018,28 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (shadow_detail > 1) { //allocate two spot shadow maps U32 spot_shadow_map_width = width; + U32 spot_shadow_map_height = height; for (U32 i = 4; i < 6; i++) { - if (!mShadow[i].allocate(spot_shadow_map_width, height, 0, TRUE, FALSE)) return false; - if (!mShadowOcclusion[i].allocate(mShadow[i].getWidth()/occlusion_divisor, mShadow[i].getHeight()/occlusion_divisor, 0, TRUE, FALSE)) return false; - } - } - else + if (!mShadow[i].allocate(spot_shadow_map_width, spot_shadow_map_height, 0, TRUE, FALSE)) { - for (U32 i = 4; i < 6; i++) - { - mShadow[i].release(); - mShadowOcclusion[i].release(); + return false; } - } - - //HACK make screenbuffer allocations start failing after 30 seconds - if (gSavedSettings.getBOOL("SimulateFBOFailure")) + if (!mShadowOcclusion[i].allocate(spot_shadow_map_width/occlusion_divisor, height/occlusion_divisor, 0, TRUE, FALSE)) { return false; } } + } else { - mDeferredLight.release(); - - for (U32 i = 0; i < 6; i++) + for (U32 i = 4; i < 6; i++) { - mShadow[i].release(); - mShadowOcclusion[i].release(); + releaseShadowTarget(i); } - mFXAABuffer.release(); - mScreen.release(); - mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first - mDeferredDepth.release(); - mOcclusionDepth.release(); - - if (!mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE)) return false; } - - if (LLPipeline::sRenderDeferred) - { //share depth buffer between deferred targets - mDeferredScreen.shareDepthBuffer(mScreen); } - gGL.getTexUnit(0)->disable(); - - stop_glerror(); - return true; } @@ -1063,7 +1056,6 @@ void LLPipeline::updateRenderDeferred() LLRenderTarget::sUseFBO && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && LLPipeline::sRenderBump && - VertexShaderEnable && RenderAvatarVP && WindLightUseAtmosShaders)) && !gUseWireframe; @@ -1092,7 +1084,6 @@ void LLPipeline::refreshCachedSettings() && gSavedSettings.getBOOL("UseOcclusion") && gGLManager.mHasOcclusionQuery) ? 2 : 0; - VertexShaderEnable = gSavedSettings.getBOOL("VertexShaderEnable"); RenderAvatarVP = gSavedSettings.getBOOL("RenderAvatarVP"); WindLightUseAtmosShaders = gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); @@ -1167,7 +1158,7 @@ void LLPipeline::refreshCachedSettings() CameraMaxCoF = gSavedSettings.getF32("CameraMaxCoF"); CameraDoFResScale = gSavedSettings.getF32("CameraDoFResScale"); RenderAutoHideSurfaceAreaLimit = gSavedSettings.getF32("RenderAutoHideSurfaceAreaLimit"); - + RenderSpotLight = nullptr; updateRenderDeferred(); } @@ -1191,6 +1182,7 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); + mBake.release(); mHighlight.release(); for (U32 i = 0; i < 3; i++) @@ -1213,6 +1205,11 @@ void LLPipeline::releaseLUTBuffers() } } +void LLPipeline::releaseShadowBuffers() +{ + releaseShadowTargets(); +} + void LLPipeline::releaseScreenBuffers() { mUIScreen.release(); @@ -1223,48 +1220,39 @@ void LLPipeline::releaseScreenBuffers() mDeferredDepth.release(); mDeferredLight.release(); mOcclusionDepth.release(); +} + +void LLPipeline::releaseShadowTarget(U32 index) +{ + mShadow[index].release(); + mShadowOcclusion[index].release(); +} + +void LLPipeline::releaseShadowTargets() +{ for (U32 i = 0; i < 6; i++) { - mShadow[i].release(); - mShadowOcclusion[i].release(); + releaseShadowTarget(i); } } - void LLPipeline::createGLBuffers() { stop_glerror(); assertInitialized(); updateRenderDeferred(); - - bool materials_in_water = false; - -#if MATERIALS_IN_REFLECTIONS - materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); -#endif - if (LLPipeline::sWaterReflections) { //water reflection texture U32 res = (U32) llmax(gSavedSettings.getS32("RenderWaterRefResolution"), 512); - - // Set up SRGB targets if we're doing deferred-path reflection rendering - // - if (LLPipeline::sRenderDeferred && materials_in_water) - { - mWaterRef.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE); - //always use FBO for mWaterDis so it can be used for avatar texture bakes - mWaterDis.allocate(res,res,GL_SRGB8_ALPHA8,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); - } - else - { mWaterRef.allocate(res,res,GL_RGBA,TRUE,FALSE); - //always use FBO for mWaterDis so it can be used for avatar texture bakes - mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE, true); - } + mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE,LLTexUnit::TT_TEXTURE); } + // Use FBO for bake tex + mBake.allocate(512, 512, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_TEXTURE, true); // SL-12781 Build > Upload > Model; 3D Preview + mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); @@ -1416,12 +1404,9 @@ 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(vertex_shader_enable_feature_string) || (assertInitialized() && mVertexShadersLoaded != 1) ) { return false; @@ -1436,13 +1421,13 @@ bool LLPipeline::canUseWindLightShaders() const { return (!LLPipeline::sDisableShaders && gWLSkyProgram.mProgramObject != 0 && - LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); + LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1); } bool LLPipeline::canUseWindLightShadersOnObjects() const { return (canUseWindLightShaders() - && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); + && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); } bool LLPipeline::canUseAntiAliasing() const @@ -1471,7 +1456,7 @@ void LLPipeline::enableShadows(const bool enable_shadows) S32 LLPipeline::getMaxLightingDetail() const { - /*if (mVertexShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) + /*if (mShaderLevel[SHADER_OBJECT] >= LLDrawPoolSimple::SHADER_LEVEL_LOCAL_LIGHTS) { return 3; } @@ -2158,7 +2143,8 @@ void check_references(LLSpatialGroup* group, LLDrawable* drawable) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - if (drawable == (LLDrawable*)(*i)->getDrawable()) + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); + if (drawable == drawablep) { LL_ERRS() << "LLDrawable deleted while actively reference by LLPipeline." << LL_ENDL; } @@ -2299,7 +2285,7 @@ void LLPipeline::checkReferences(LLDrawInfo* draw_info) void LLPipeline::checkReferences(LLSpatialGroup* group) { -#if 0 +#if CHECK_PIPELINE_REFERENCES if (sCull) { for (LLCullResult::sg_iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) @@ -2409,15 +2395,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl sCull->clear(); - bool to_texture = LLPipeline::sUseOcclusion > 1 && - !hasRenderType(LLPipeline::RENDER_TYPE_HUD) && - LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && - gPipeline.canUseVertexShaders() && - sRenderGlow; + bool to_texture = LLPipeline::sUseOcclusion > 1 && gPipeline.canUseVertexShaders(); if (to_texture) { - if (LLPipeline::sRenderDeferred) + if (LLPipeline::sRenderDeferred && can_use_occlusion) { mOcclusionDepth.bindTarget(); } @@ -2444,38 +2426,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling) - LLViewerRegion* region = gAgent.getRegion(); - LLPlane plane; - - if (planep) - { - 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; @@ -2495,19 +2445,15 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); } + if (!sReflectionRender) + { + camera.disableUserClipPlane(); + } + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; - if (water_clip != 0) - { - LLPlane plane(LLVector3(0,0, (F32) -water_clip), (F32) water_clip*region->getWaterHeight()); - camera.setUserClipPlane(plane); - } - else - { - camera.disableUserClipPlane(); - } for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) { @@ -2526,6 +2472,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if(vo_part) { bool do_occlusion_cull = can_use_occlusion && use_occlusion && !gUseWireframe && 0 > water_clip /* && !gViewerWindow->getProgressView()->getVisible()*/; + do_occlusion_cull &= !sReflectionRender; vo_part->cull(camera, do_occlusion_cull); } } @@ -2535,8 +2482,6 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl gOcclusionCubeProgram.unbind(); } - camera.disableUserClipPlane(); - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) @@ -2558,6 +2503,22 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl } + if (hasRenderType(LLPipeline::RENDER_TYPE_WL_SKY) && + gPipeline.canUseWindLightShaders() && + gSky.mVOWLSkyp.notNull() && + gSky.mVOWLSkyp->mDrawable.notNull()) + { + gSky.mVOWLSkyp->mDrawable->setVisible(camera); + sCull->pushDrawable(gSky.mVOWLSkyp->mDrawable); + } + + bool render_water = !sReflectionRender && (hasRenderType(LLPipeline::RENDER_TYPE_WATER) || hasRenderType(LLPipeline::RENDER_TYPE_VOIDWATER)); + + if (render_water) + { + LLWorld::getInstance()->precullWaterObjects(camera, sCull, render_water); + } + gGL.matrixMode(LLRender::MM_PROJECTION); gGL.popMatrix(); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -2570,7 +2531,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl if (to_texture) { - if (LLPipeline::sRenderDeferred) + if (LLPipeline::sRenderDeferred && can_use_occlusion) { mOcclusionDepth.flush(); } @@ -3432,7 +3393,8 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) group->setVisible(); for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - markVisible((LLDrawable*)(*i)->getDrawable(), camera); + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); + markVisible(drawablep, camera); } if (!sDelayVBUpdate) @@ -3520,7 +3482,8 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) { for (LLSpatialGroup::element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i) { - stateSort((LLDrawable*)(*i)->getDrawable(), camera); + LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable(); + stateSort(drawablep, camera); } if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) @@ -3549,6 +3512,14 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) return; } + // SL-11353 + // ignore our own geo when rendering spotlight shadowmaps... + // + if (RenderSpotLight && drawablep == RenderSpotLight) + { + return; + } + if (LLSelectMgr::getInstance()->mHideSelectedObjects) { if (drawablep->getVObj().notNull() && @@ -4062,6 +4033,7 @@ void LLPipeline::postSort(LLCamera& camera) void render_hud_elements() { + LL_RECORD_BLOCK_TIME(FTM_RENDER_UI); gPipeline.disableLights(); LLGLDisable fog(GL_FOG); @@ -4139,12 +4111,13 @@ void LLPipeline::renderHighlights() glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); - if (canUseVertexShaders()) + gGL.setColorMask(false, false); + + if (LLGLSLShader::sNoFixedFunction) { gHighlightProgram.bind(); } - gGL.setColorMask(false, false); for (std::set<HighlightItem>::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) { renderHighlight(iter->mItem->getVObj(), 1.f); @@ -4226,7 +4199,7 @@ void LLPipeline::renderHighlights() //gGL.setSceneBlendType(LLRender::BT_ALPHA); } - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightProgram.bind(); gGL.diffuseColor4f(1,1,1,0.5f); @@ -4273,7 +4246,7 @@ void LLPipeline::renderHighlights() // have touch-handlers. mHighlightFaces.clear(); - if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) + if (LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0) { gHighlightProgram.unbind(); } @@ -4282,7 +4255,7 @@ void LLPipeline::renderHighlights() if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::NORMAL_MAP)) { color.setVec(1.0f, 0.5f, 0.5f, 0.5f); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightNormalProgram.bind(); gGL.diffuseColor4f(1,1,1,0.5f); @@ -4303,7 +4276,7 @@ void LLPipeline::renderHighlights() facep->renderSelected(mFaceSelectImagep, color); } - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightNormalProgram.unbind(); } @@ -4312,7 +4285,7 @@ void LLPipeline::renderHighlights() if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED) && (sRenderHighlightTextureChannel == LLRender::SPECULAR_MAP)) { color.setVec(0.0f, 0.3f, 1.0f, 0.8f); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightSpecularProgram.bind(); gGL.diffuseColor4f(1,1,1,0.5f); @@ -4333,7 +4306,7 @@ void LLPipeline::renderHighlights() facep->renderSelected(mFaceSelectImagep, color); } - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + if ((LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) { gHighlightSpecularProgram.unbind(); } @@ -4560,6 +4533,7 @@ void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) // Render debugging beacons. gObjectList.renderObjectBeacons(); gObjectList.resetObjectBeacons(); + gSky.addSunMoonBeacons(); } else { @@ -4680,6 +4654,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(gGLModelView); gGL.setColorMask(true, false); @@ -4766,16 +4741,16 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera, bool do_occlusion) } gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(gGLModelView); if (occlude) { occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); LLGLSLShader::bindNoShader(); doOcclusion(camera); gGLLastMatrix = NULL; + gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.loadMatrix(gGLModelView); } } @@ -5990,6 +5965,12 @@ void LLPipeline::setupAvatarLights(bool for_edit) { assertInitialized(); + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + + bool sun_up = environment.getIsSunUp(); + + if (for_edit) { LLColor4 diffuse(1.f, 1.f, 1.f, 0.f); @@ -6003,13 +5984,6 @@ void LLPipeline::setupAvatarLights(bool for_edit) LLLightState* light = gGL.getLight(1); - if (LLPipeline::sRenderDeferred) - { - /*diffuse.mV[0] = powf(diffuse.mV[0], 2.2f); - diffuse.mV[1] = powf(diffuse.mV[1], 2.2f); - diffuse.mV[2] = powf(diffuse.mV[2], 2.2f);*/ - } - mHWLightColors[1] = diffuse; light->setDiffuse(diffuse); @@ -6024,12 +5998,14 @@ void LLPipeline::setupAvatarLights(bool for_edit) } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { - LLVector3 opposite_pos = -1.f * mSunDir; - LLVector3 orthog_light_pos = mSunDir % LLVector3::z_axis; + LLVector3 light_dir = sun_up ? LLVector3(mSunDir) : LLVector3(mMoonDir); + LLVector3 opposite_pos = -light_dir; + LLVector3 orthog_light_pos = light_dir % LLVector3::z_axis; LLVector4 backlight_pos = LLVector4(lerp(opposite_pos, orthog_light_pos, 0.3f), 0.0f); backlight_pos.normalize(); - LLColor4 light_diffuse = mSunDiffuse; + LLColor4 light_diffuse = sun_up ? mSunDiffuse : mMoonDiffuse; + LLColor4 backlight_diffuse(1.f - light_diffuse.mV[VRED], 1.f - light_diffuse.mV[VGREEN], 1.f - light_diffuse.mV[VBLUE], 1.f); F32 max_component = 0.001f; for (S32 i = 0; i < 3; i++) @@ -6040,7 +6016,7 @@ void LLPipeline::setupAvatarLights(bool for_edit) } } F32 backlight_mag; - if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) + if (LLEnvironment::instance().getIsSunUp()) { backlight_mag = BACKLIGHT_DAY_MAGNITUDE_OBJECT; } @@ -6050,13 +6026,6 @@ void LLPipeline::setupAvatarLights(bool for_edit) } backlight_diffuse *= backlight_mag / max_component; - if (LLPipeline::sRenderDeferred) - { - /*backlight_diffuse.mV[0] = powf(backlight_diffuse.mV[0], 2.2f); - backlight_diffuse.mV[1] = powf(backlight_diffuse.mV[1], 2.2f); - backlight_diffuse.mV[2] = powf(backlight_diffuse.mV[2], 2.2f);*/ - } - mHWLightColors[1] = backlight_diffuse; LLLightState* light = gGL.getLight(1); @@ -6249,26 +6218,31 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { assertInitialized(); - // Ambient + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t psky = environment.getCurrentSky(); + if (!LLGLSLShader::sNoFixedFunction) { gGL.syncMatrices(); - LLColor4 ambient = gSky.getTotalAmbientColor(); - gGL.setAmbientLightColor(ambient); } + // Ambient + LLColor4 ambient = psky->getTotalAmbient(); + gGL.setAmbientLightColor(ambient); + + bool sun_up = environment.getIsSunUp(); + bool moon_up = environment.getIsMoonUp(); + // Light 0 = Sun or Moon (All objects) { - if (gSky.getSunDirection().mV[2] >= LLSky::NIGHTTIME_ELEVATION_COS) - { - mSunDir.setVec(gSky.getSunDirection()); - mSunDiffuse.setVec(gSky.getSunDiffuseColor()); - } - else - { - mSunDir.setVec(gSky.getMoonDirection()); - mSunDiffuse.setVec(gSky.getMoonDiffuseColor()); - } + LLVector4 sun_dir(environment.getSunDirection(), 0.0f); + LLVector4 moon_dir(environment.getMoonDirection(), 0.0f); + + mSunDir.setVec(sun_dir); + mMoonDir.setVec(moon_dir); + + mSunDiffuse.setVec(psky->getSunlightColor()); + mMoonDiffuse.setVec(psky->getMoonlightColor()); F32 max_color = llmax(mSunDiffuse.mV[0], mSunDiffuse.mV[1], mSunDiffuse.mV[2]); if (max_color > 1.f) @@ -6277,22 +6251,33 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) } mSunDiffuse.clamp(); - LLVector4 light_pos(mSunDir, 0.0f); - LLColor4 light_diffuse = mSunDiffuse; + max_color = llmax(mMoonDiffuse.mV[0], mMoonDiffuse.mV[1], mMoonDiffuse.mV[2]); + if (max_color > 1.f) + { + mMoonDiffuse *= 1.f/max_color; + } + mMoonDiffuse.clamp(); - if (LLPipeline::sRenderDeferred) + // prevent underlighting from having neither lightsource facing us + if (!sun_up && !moon_up) { - /*light_diffuse.mV[0] = powf(light_diffuse.mV[0], 2.2f); - light_diffuse.mV[1] = powf(light_diffuse.mV[1], 2.2f); - light_diffuse.mV[2] = powf(light_diffuse.mV[2], 2.2f);*/ + mSunDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0)); + mMoonDiffuse.setVec(LLColor4(0.0, 0.0, 0.0, 1.0)); + mSunDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0)); + mMoonDir.setVec(LLVector4(0.0, 1.0, 0.0, 0.0)); } - mHWLightColors[0] = light_diffuse; + LLVector4 light_dir = sun_up ? mSunDir : mMoonDir; + + mHWLightColors[0] = sun_up ? mSunDiffuse : mMoonDiffuse; LLLightState* light = gGL.getLight(0); - light->setPosition(light_pos); - light->setDiffuse(light_diffuse); - light->setAmbient(LLColor4::black); + light->setPosition(light_dir); + + light->setSunPrimary(sun_up); + light->setDiffuse(mHWLightColors[0]); + light->setDiffuseB(mMoonDiffuse); + light->setAmbient(psky->getTotalAmbient()); light->setSpecular(LLColor4::black); light->setConstantAttenuation(1.f); light->setLinearAttenuation(0.f); @@ -6321,12 +6306,28 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { continue; } + + if (light->isAttachment()) + { + if (!sRenderAttachedLights) + { + continue; + } + } + + const LLViewerObject *vobj = drawable->getVObj(); + if(vobj && vobj->getAvatar() && vobj->getAvatar()->isInMuteList()) + { + continue; + } + if (drawable->isState(LLDrawable::ACTIVE)) { mLightMovingMask |= (1<<cur_light); } - LLColor4 light_color = light->getLightColor(); + //send linear light color to shader + LLColor4 light_color = light->getLightLinearColor(); light_color.mV[3] = 0.0f; F32 fade = iter->fade; @@ -6347,13 +6348,24 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_color *= fade; } + if (light_color.magVecSquared() < 0.001f) + { + continue; + } + LLVector3 light_pos(light->getRenderPosition()); LLVector4 light_pos_gl(light_pos, 1.0f); F32 light_radius = llmax(light->getLightRadius(), 0.001f); + F32 size = light_radius * (sRenderDeferred ? 1.5f : 1.0f); + + if (size <= 0.001f) + { + continue; + } - F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior. - float linatten = x / (light_radius); // % of brightness at radius + F32 x = (3.f * (1.f + (light->getLightFalloff() * 2.0f))); // why this magic? probably trying to match a historic behavior. + F32 linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; LLLightState* light_state = gGL.getLight(cur_light); @@ -6364,9 +6376,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setConstantAttenuation(0.f); if (sRenderDeferred) { - F32 size = light_radius*1.5f; light_state->setLinearAttenuation(size); - light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + light_state->setQuadraticAttenuation(light->getLightFalloff(DEFERRED_LIGHT_FALLOFF) + 1.f); // get falloff to match for forward deferred rendering lights } else { @@ -6386,7 +6397,9 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light_state->setSpotCutoff(90.f); light_state->setSpotExponent(2.f); - const LLColor4 specular(0.f, 0.f, 0.f, 0.f); + LLVector3 spotParams = light->getSpotLightParams(); + + const LLColor4 specular(0.f, 0.f, 0.f, spotParams[2]); light_state->setSpecular(specular); } else // omnidirectional (point) light @@ -6394,8 +6407,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) 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 LLColor4 specular(0.f, 0.f, 0.f, 1.f); + // we use specular.z = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight + const LLColor4 specular(0.f, 0.f, 1.f, 0.f); light_state->setSpecular(specular); } cur_light++; @@ -6409,7 +6422,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { mHWLightColors[cur_light] = LLColor4::black; LLLightState* light = gGL.getLight(cur_light); - + light->setSunPrimary(true); light->setDiffuse(LLColor4::black); light->setAmbient(LLColor4::black); light->setSpecular(LLColor4::black); @@ -6440,6 +6453,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) light->setPosition(light_pos_gl); light->setDiffuse(light_color); + light->setDiffuseB(light_color * 0.25f); light->setAmbient(LLColor4::black); light->setSpecular(LLColor4::black); light->setQuadraticAttenuation(0.f); @@ -6508,9 +6522,6 @@ void LLPipeline::enableLights(U32 mask) } mLightMask = mask; stop_glerror(); - - LLColor4 ambient = gSky.getTotalAmbientColor(); - gGL.setAmbientLightColor(ambient); } } @@ -6626,13 +6637,11 @@ void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) gGL.setAmbientLightColor(color); } -void LLPipeline::enableLightsFullbright(const LLColor4& color) +void LLPipeline::enableLightsFullbright() { assertInitialized(); U32 mask = 0x1000; // Non-0 mask, set ambient enableLights(mask); - - gGL.setAmbientLightColor(color); } void LLPipeline::disableLights() @@ -7458,6 +7467,15 @@ void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batc gGLLastMatrix = NULL; } +void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture) +{ + assertInitialized(); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; + mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + gGL.loadMatrix(gGLModelView); + gGLLastMatrix = NULL; +} void apply_cube_face_rotation(U32 face) { @@ -7550,7 +7568,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) LLGLDisable blend(GL_BLEND); LLGLDisable cull(GL_CULL_FACE); - enableLightsFullbright(LLColor4(1,1,1,1)); + enableLightsFullbright(); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.pushMatrix(); @@ -7589,10 +7607,10 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - mScreen.bindTexture(0, 0); + mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); gGL.color4f(1,1,1,1); - gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); + gPipeline.enableLightsFullbright(); gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); gGL.vertex2f(-1,-1); @@ -7906,14 +7924,6 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) if (channel > -1) { mScreen.bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); - } - - if (!LLViewerCamera::getInstance()->cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); - } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); } shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); @@ -7957,13 +7967,6 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) mScreen.bindTexture(0, channel); } - if (!LLViewerCamera::getInstance()->cameraUnderWater()) - { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 2.2); - } else { - shader->uniform1f(LLShaderMgr::GLOBAL_GAMMA, 1.0); - } - gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); gGL.vertex2f(-1,-1); @@ -8023,8 +8026,7 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); if (channel > -1) { - mFXAABuffer.bindTexture(0, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); } gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -8176,63 +8178,66 @@ void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 noise_map) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) { LL_RECORD_BLOCK_TIME(FTM_BIND_DEFERRED); - if (noise_map == 0xFFFFFFFF) - { - noise_map = mNoiseMap; - } + LLRenderTarget* deferred_target = &mDeferredScreen; + LLRenderTarget* deferred_depth_target = &mDeferredDepth; + LLRenderTarget* deferred_light_target = &mDeferredLight; shader.bind(); S32 channel = 0; - channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); if (channel > -1) { - mDeferredScreen.bindTexture(0,channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + deferred_target->bindTexture(0,channel, LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); if (channel > -1) { - mDeferredScreen.bindTexture(1, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + deferred_target->bindTexture(1, channel, LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NORMAL, deferred_target->getUsage()); if (channel > -1) { - mDeferredScreen.bindTexture(2, channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + deferred_target->bindTexture(2, channel, LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); + channel = shader.enableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); if (channel > -1) { - gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); + gGL.getTexUnit(channel)->bind(deferred_depth_target, TRUE); 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); - - stop_glerror(); - - glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f projection = get_current_projection(); glh::matrix4f inv_proj = projection.inverse(); + if (shader.getUniformLocation(LLShaderMgr::INVERSE_PROJECTION_MATRIX) != -1) + { shader.uniformMatrix4fv(LLShaderMgr::INVERSE_PROJECTION_MATRIX, 1, FALSE, inv_proj.m); + } + + if (shader.getUniformLocation(LLShaderMgr::VIEWPORT) != -1) + { shader.uniform4f(LLShaderMgr::VIEWPORT, (F32) gGLViewport[0], (F32) gGLViewport[1], (F32) gGLViewport[2], (F32) gGLViewport[3]); } + if (sReflectionRender && !shader.getUniformLocation(LLShaderMgr::MODELVIEW_MATRIX)) + { + shader.uniformMatrix4fv(LLShaderMgr::MODELVIEW_MATRIX, 1, FALSE, mReflectionModelView.m); + } + channel = shader.enableTexture(LLShaderMgr::DEFERRED_NOISE); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, noise_map); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } @@ -8244,18 +8249,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n stop_glerror(); - channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, mDeferredLight.getUsage()); + light_target = light_target ? light_target : deferred_light_target; + channel = shader.enableTexture(LLShaderMgr::DEFERRED_LIGHT, light_target->getUsage()); if (channel > -1) { - if (light_index > 0) - { - mScreen.bindTexture(0, channel); - } - else - { - mDeferredLight.bindTexture(0, channel); - } - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + light_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLShaderMgr::DEFERRED_BLOOM); @@ -8268,13 +8266,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n for (U32 i = 0; i < 4; i++) { + LLRenderTarget* shadow_target = getShadowTarget(i); + if (shadow_target) + { channel = shader.enableTexture(LLShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_TEXTURE); stop_glerror(); if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->bind(getShadowTarget(i), TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); @@ -8283,6 +8284,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n stop_glerror(); } } + } for (U32 i = 4; i < 6; i++) { @@ -8291,8 +8293,11 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + LLRenderTarget* shadow_target = getShadowTarget(i); + if (shadow_target) + { + gGL.getTexUnit(channel)->bind(shadow_target, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_ANISOTROPIC); gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); @@ -8301,6 +8306,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n stop_glerror(); } } + } stop_glerror(); @@ -8337,6 +8343,34 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n } } + if (gAtmosphere) + { + // bind precomputed textures necessary for calculating sun and sky luminance + channel = shader.enableTexture(LLShaderMgr::TRANSMITTANCE_TEX, LLTexUnit::TT_TEXTURE); + if (channel > -1) + { + shader.bindTexture(LLShaderMgr::TRANSMITTANCE_TEX, gAtmosphere->getTransmittance()); + } + + channel = shader.enableTexture(LLShaderMgr::SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); + if (channel > -1) + { + shader.bindTexture(LLShaderMgr::SCATTER_TEX, gAtmosphere->getScattering()); + } + + channel = shader.enableTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, LLTexUnit::TT_TEXTURE_3D); + if (channel > -1) + { + shader.bindTexture(LLShaderMgr::SINGLE_MIE_SCATTER_TEX, gAtmosphere->getMieScattering()); + } + + channel = shader.enableTexture(LLShaderMgr::ILLUMINANCE_TEX, LLTexUnit::TT_TEXTURE); + if (channel > -1) + { + shader.bindTexture(LLShaderMgr::ILLUMINANCE_TEX, gAtmosphere->getIlluminance()); + } + } + shader.uniform4fv(LLShaderMgr::DEFERRED_SHADOW_CLIP, 1, mSunClipPlanes.mV); shader.uniform1f(LLShaderMgr::DEFERRED_SUN_WASH, RenderDeferredSunWash); shader.uniform1f(LLShaderMgr::DEFERRED_SHADOW_NOISE, RenderShadowNoise); @@ -8361,26 +8395,35 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, U32 n //F32 shadow_offset_error = 1.f + RenderShadowOffsetError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); F32 shadow_bias_error = RenderShadowBiasError * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2])/3000.f; + F32 shadow_bias = RenderShadowBias + shadow_bias_error; - shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); + shader.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_target->getWidth(), deferred_target->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_SHADOW_BIAS, shadow_bias); 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.uniform3fv(LLShaderMgr::DEFERRED_MOON_DIR, 1, mTransformedMoonDir.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(LLShaderMgr::DEFERRED_NORM_MATRIX) >= 0) { - glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + glh::matrix4f norm_mat = get_current_modelview().inverse().transpose(); shader.uniformMatrix4fv(LLShaderMgr::DEFERRED_NORM_MATRIX, 1, FALSE, norm_mat.m); } + + shader.uniform4fv(LLShaderMgr::SUNLIGHT_COLOR, 1, mSunDiffuse.mV); + shader.uniform4fv(LLShaderMgr::MOONLIGHT_COLOR, 1, mMoonDiffuse.mV); + + LLEnvironment& environment = LLEnvironment::instance(); + LLSettingsSky::ptr_t sky = environment.getCurrentSky(); + + static_cast<LLSettingsVOSky*>(sky.get())->updateShader(&shader); } LLColor3 pow3f(LLColor3 v, F32 f) @@ -8411,21 +8454,24 @@ static LLTrace::BlockTimerStatHandle FTM_PROJECTORS("Projectors"); static LLTrace::BlockTimerStatHandle FTM_POST("Post"); -void LLPipeline::renderDeferredLighting() +void LLPipeline::renderDeferredLighting(LLRenderTarget* screen_target) { if (!sCull) { return; } + LLRenderTarget* deferred_target = &mDeferredScreen; + LLRenderTarget* deferred_depth_target = &mDeferredDepth; + LLRenderTarget* deferred_light_target = &mDeferredLight; + { LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); - LLViewerCamera* camera = LLViewerCamera::getInstance(); { LLGLDepthTest depth(GL_TRUE); - mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + deferred_depth_target->copyContents(*deferred_target, 0, 0, deferred_target->getWidth(), deferred_target->getHeight(), + 0, 0, deferred_depth_target->getWidth(), deferred_depth_target->getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); @@ -8448,7 +8494,7 @@ void LLPipeline::renderDeferredLighting() LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); - glh::matrix4f mat = glh_copy_matrix(gGLModelView); + glh::matrix4f mat = copy_matrix(gGLModelView); LLStrider<LLVector3> vert; mDeferredVB->getVertexStrider(vert); @@ -8457,13 +8503,15 @@ void LLPipeline::renderDeferredLighting() 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); + setupHWLights(NULL); //to set mSun/MoonDir; + + glh::vec4f tc(mSunDir.mV); mat.mult_matrix_vec(tc); mTransformedSunDir.set(tc.v); - } + + glh::vec4f tc_moon(mMoonDir.mV); + mat.mult_matrix_vec(tc_moon); + mTransformedMoonDir.set(tc_moon.v); gGL.pushMatrix(); gGL.loadIdentity(); @@ -8473,16 +8521,16 @@ void LLPipeline::renderDeferredLighting() if (RenderDeferredSSAO || RenderShadowDetail > 0) { - mDeferredLight.bindTarget(); + deferred_light_target->bindTarget(); { //paint shadow/SSAO light map (direct lighting lightmap) LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); - bindDeferredShader(gDeferredSunProgram, 0); + bindDeferredShader(gDeferredSunProgram, deferred_light_target); mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); glClearColor(1,1,1,1); - mDeferredLight.clear(GL_COLOR_BUFFER_BIT); + deferred_light_target->clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + glh::matrix4f inv_trans = get_current_modelview().inverse().transpose(); const U32 slice = 32; F32 offset[slice*3]; @@ -8502,7 +8550,7 @@ void LLPipeline::renderDeferredLighting() } gDeferredSunProgram.uniform3fv(sOffset, slice, offset); - gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); + gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, deferred_light_target->getWidth(), deferred_light_target->getHeight()); { LLGLDisable blend(GL_BLEND); @@ -8514,16 +8562,16 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSunProgram); } - mDeferredLight.flush(); + deferred_light_target->flush(); } if (RenderDeferredSSAO) { //soften direct lighting lightmap LL_RECORD_BLOCK_TIME(FTM_SOFTEN_SHADOW); //blur lightmap - mScreen.bindTarget(); + screen_target->bindTarget(); glClearColor(1,1,1,1); - mScreen.clear(GL_COLOR_BUFFER_BIT); + screen_target->clear(GL_COLOR_BUFFER_BIT); glClearColor(0,0,0,0); bindDeferredShader(gDeferredBlurLightProgram); @@ -8559,12 +8607,13 @@ void LLPipeline::renderDeferredLighting() stop_glerror(); } - mScreen.flush(); + screen_target->flush(); unbindDeferredShader(gDeferredBlurLightProgram); - bindDeferredShader(gDeferredBlurLightProgram, 1); + bindDeferredShader(gDeferredBlurLightProgram, screen_target); + mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredLight.bindTarget(); + deferred_light_target->bindTarget(); gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); @@ -8575,7 +8624,7 @@ void LLPipeline::renderDeferredLighting() mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); stop_glerror(); } - mDeferredLight.flush(); + deferred_light_target->flush(); unbindDeferredShader(gDeferredBlurLightProgram); } @@ -8587,15 +8636,22 @@ void LLPipeline::renderDeferredLighting() gGL.popMatrix(); stop_glerror(); - mScreen.bindTarget(); + screen_target->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); + screen_target->clear(GL_COLOR_BUFFER_BIT); if (RenderDeferredAtmospheric) { //apply sunlight contribution + LLGLSLShader& soften_shader = LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram; + LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); - bindDeferredShader(LLPipeline::sUnderWaterRender ? gDeferredSoftenWaterProgram : gDeferredSoftenProgram); + bindDeferredShader(soften_shader); + + LLEnvironment& environment = LLEnvironment::instance(); + soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + soften_shader.uniform4fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); + { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -8699,9 +8755,9 @@ void LLPipeline::renderDeferredLighting() { const LLViewerObject *root_obj = drawablep->getParent() ? drawablep->getParent()->getVObj() : vobj; if (root_obj && dist_vec(root_obj->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip) - { - continue; - } + { + continue; + } } } @@ -8710,7 +8766,8 @@ void LLPipeline::renderDeferredLighting() const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; - LLColor3 col = volume->getLightColor(); + //send light color to shader in linear space + LLColor3 col = volume->getLightLinearColor(); if (col.magVecSquared() < 0.001f) { @@ -8747,15 +8804,11 @@ void LLPipeline::renderDeferredLighting() continue; } - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ - LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); gGL.syncMatrices(); mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); @@ -8775,7 +8828,7 @@ void LLPipeline::renderDeferredLighting() mat.mult_matrix_vec(tc); fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); - light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF))); } } unbindDeferredShader(gDeferredLightProgram); @@ -8806,15 +8859,13 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredSpotLightProgram, drawablep); - LLColor3 col = volume->getLightColor(); - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ + //send light color to shader in linear space + LLColor3 col = volume->getLightLinearColor(); gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF)); gGL.syncMatrices(); mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); @@ -8855,12 +8906,7 @@ void LLPipeline::renderDeferredLighting() col[count] = light_colors.front(); light_colors.pop_front(); - /*col[count].mV[0] = powf(col[count].mV[0], 2.2f); - col[count].mV[1] = powf(col[count].mV[1], 2.2f); - col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ - far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); - //col[count] = pow4fsrgb(col[count], 2.2f); count++; if (count == max_count || fullscreen_lights.empty()) { @@ -8893,7 +8939,8 @@ void LLPipeline::renderDeferredLighting() LLVector3 center = drawablep->getPositionAgent(); F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; + F32 light_size_final = volume->getLightRadius()*1.5f; + F32 light_falloff_final = volume->getLightFalloff(DEFERRED_LIGHT_FALLOFF); sVisibleLightCount++; @@ -8902,16 +8949,13 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); - LLColor3 col = volume->getLightColor(); - - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ + //send light color to shader in linear space + LLColor3 col = volume->getLightLinearColor(); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); - gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); + gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); + gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final); mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); } @@ -8927,7 +8971,7 @@ void LLPipeline::renderDeferredLighting() gGL.setColorMask(true, true); } - mScreen.flush(); + screen_target->flush(); //gamma correct lighting gGL.matrixMode(LLRender::MM_PROJECTION); @@ -8941,22 +8985,21 @@ void LLPipeline::renderDeferredLighting() LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLVector2 tc1(0,0); - LLVector2 tc2((F32) mScreen.getWidth()*2, - (F32) mScreen.getHeight()*2); + LLVector2 tc2((F32) screen_target->getWidth()*2, + (F32) screen_target->getHeight()*2); - mScreen.bindTarget(); + screen_target->bindTarget(); // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); S32 channel = 0; - channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); + channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); if (channel > -1) { - mScreen.bindTexture(0,channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); } - gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mScreen.getWidth(), mScreen.getHeight()); + gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight()); F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); @@ -8974,9 +9017,9 @@ void LLPipeline::renderDeferredLighting() gGL.end(); - gGL.getTexUnit(channel)->unbind(mScreen.getUsage()); + gGL.getTexUnit(channel)->unbind(screen_target->getUsage()); gDeferredPostGammaCorrectProgram.unbind(); - mScreen.flush(); + screen_target->flush(); } gGL.matrixMode(LLRender::MM_PROJECTION); @@ -8984,7 +9027,7 @@ void LLPipeline::renderDeferredLighting() gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - mScreen.bindTarget(); + screen_target->bindTarget(); { //render non-deferred geometry (alpha, fullbright, glow) LLGLDisable blend(GL_BLEND); @@ -9032,542 +9075,11 @@ void LLPipeline::renderDeferredLighting() // Render debugging beacons. gObjectList.renderObjectBeacons(); gObjectList.resetObjectBeacons(); + gSky.addSunMoonBeacons(); } } - mScreen.flush(); - -} - -void LLPipeline::renderDeferredLightingToRT(LLRenderTarget* target) -{ - if (!sCull) - { - return; - } - - { - LL_RECORD_BLOCK_TIME(FTM_RENDER_DEFERRED); - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - - { - LLGLDepthTest depth(GL_TRUE); - mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - } - - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); - - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD); - } - - //ati doesn't seem to love actually using the stencil buffer on FBO's - LLGLDisable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - gGL.setColorMask(true, true); - - //draw a cube around every light - LLVertexBuffer::unbind(); - - LLGLEnable cull(GL_CULL_FACE); - LLGLEnable blend(GL_BLEND); - - glh::matrix4f mat = glh_copy_matrix(gGLModelView); - - LLStrider<LLVector3> vert; - mDeferredVB->getVertexStrider(vert); - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - - { - setupHWLights(NULL); //to set mSunDir; - LLVector4 dir(mSunDir, 0.f); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - mTransformedSunDir.set(tc.v); - } - - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - if (RenderDeferredSSAO || RenderShadowDetail > 0) - { - mDeferredLight.bindTarget(); - { //paint shadow/SSAO light map (direct lighting lightmap) - LL_RECORD_BLOCK_TIME(FTM_SUN_SHADOW); - bindDeferredShader(gDeferredSunProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - glClearColor(1,1,1,1); - mDeferredLight.clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) - { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } - } - - gDeferredSunProgram.uniform3fv(LLShaderMgr::DEFERRED_SHADOW_OFFSET, slice, offset); - gDeferredSunProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, mDeferredLight.getWidth(), mDeferredLight.getHeight()); - - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); - } - - unbindDeferredShader(gDeferredSunProgram); - } - mDeferredLight.flush(); - } - - stop_glerror(); - gGL.popMatrix(); - stop_glerror(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - stop_glerror(); - gGL.popMatrix(); - stop_glerror(); - - target->bindTarget(); - - //clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky - glClearColor(0,0,0,0); - target->clear(GL_COLOR_BUFFER_BIT); - - if (RenderDeferredAtmospheric) - { //apply sunlight contribution - LL_RECORD_BLOCK_TIME(FTM_ATMOSPHERICS); - bindDeferredShader(gDeferredSoftenProgram); - { - LLGLDepthTest depth(GL_FALSE); - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - - //full screen blit - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } - - unbindDeferredShader(gDeferredSoftenProgram); - } - - { //render non-deferred geometry (fullbright, alpha, etc) - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - - gPipeline.pushRenderTypeMask(); - - gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); - - - renderGeomPostDeferred(*LLViewerCamera::getInstance(), false); - gPipeline.popRenderTypeMask(); - } - - bool render_local = RenderLocalLights; - - if (render_local) - { - gGL.setSceneBlendType(LLRender::BT_ADD); - std::list<LLVector4> fullscreen_lights; - LLDrawable::drawable_list_t spot_lights; - LLDrawable::drawable_list_t fullscreen_spot_lights; - - for (U32 i = 0; i < 2; i++) - { - mTargetShadowSpotLight[i] = NULL; - } - - std::list<LLVector4> light_colors; - - LLVertexBuffer::unbind(); - - { - bindDeferredShader(gDeferredLightProgram); - - if (mCubeVB.isNull()) - { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW_ARB); - } - - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) - { - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - if (!volume) - { - continue; - } - - if (volume->isAttachment()) - { - if (!sRenderAttachedLights) - { - continue; - } - } - - - LLVector4a center; - center.load3(drawablep->getPositionAgent().mV); - const F32* c = center.getF32ptr(); - F32 s = volume->getLightRadius()*1.5f; - - LLColor3 col = volume->getLightColor(); - - if (col.magVecSquared() < 0.001f) - { - continue; - } - - if (s <= 0.001f) - { - continue; - } - - LLVector4a sa; - sa.splat(s); - if (camera->AABBInFrustumNoFarClip(center, sa) == 0) - { - continue; - } - - sVisibleLightCount++; - - if (camera->getOrigin().mV[0] > c[0] + s + 0.2f || - camera->getOrigin().mV[0] < c[0] - s - 0.2f || - camera->getOrigin().mV[1] > c[1] + s + 0.2f || - camera->getOrigin().mV[1] < c[1] - s - 0.2f || - camera->getOrigin().mV[2] > c[2] + s + 0.2f || - camera->getOrigin().mV[2] < c[2] - s - 0.2f) - { //draw box if camera is outside box - if (render_local) - { - if (volume->isLightSpotlight()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - spot_lights.push_back(drawablep); - continue; - } - - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ - - LL_RECORD_BLOCK_TIME(FTM_LOCAL_LIGHTS); - gDeferredLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); - gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); - gDeferredLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - gGL.syncMatrices(); - - mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); - stop_glerror(); - } - } - else - { - if (volume->isLightSpotlight()) - { - drawablep->getVOVolume()->updateSpotLightPriority(); - fullscreen_spot_lights.push_back(drawablep); - continue; - } - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s)); - light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); - } - } - unbindDeferredShader(gDeferredLightProgram); - } - - if (!spot_lights.empty()) - { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - bindDeferredShader(gDeferredSpotLightProgram); - - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - - for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) - { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - - LLVector4a center; - center.load3(drawablep->getPositionAgent().mV); - const F32* c = center.getF32ptr(); - F32 s = volume->getLightRadius()*1.5f; - - sVisibleLightCount++; - - setupSpotLight(gDeferredSpotLightProgram, drawablep); - - LLColor3 col = volume->getLightColor(); - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ - - gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); - gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); - gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - gGL.syncMatrices(); - - mCubeVB->drawRange(LLRender::TRIANGLE_FAN, 0, 7, 8, get_box_fan_indices(camera, center)); - } - gDeferredSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredSpotLightProgram); - } - - //reset mDeferredVB to fullscreen triangle - mDeferredVB->getVertexStrider(vert); - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - - { - LLGLDepthTest depth(GL_FALSE); - - //full screen blit - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - - U32 count = 0; - - const U32 max_count = LL_DEFERRED_MULTI_LIGHT_COUNT; - LLVector4 light[max_count]; - LLVector4 col[max_count]; - - F32 far_z = 0.f; - - while (!fullscreen_lights.empty()) - { - LL_RECORD_BLOCK_TIME(FTM_FULLSCREEN_LIGHTS); - light[count] = fullscreen_lights.front(); - fullscreen_lights.pop_front(); - col[count] = light_colors.front(); - light_colors.pop_front(); - - /*col[count].mV[0] = powf(col[count].mV[0], 2.2f); - col[count].mV[1] = powf(col[count].mV[1], 2.2f); - col[count].mV[2] = powf(col[count].mV[2], 2.2f);*/ - - far_z = llmin(light[count].mV[2]-light[count].mV[3], far_z); - //col[count] = pow4fsrgb(col[count], 2.2f); - count++; - if (count == max_count || fullscreen_lights.empty()) - { - U32 idx = count-1; - bindDeferredShader(gDeferredMultiLightProgram[idx]); - gDeferredMultiLightProgram[idx].uniform1i(LLShaderMgr::MULTI_LIGHT_COUNT, count); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT, count, (GLfloat*) light); - gDeferredMultiLightProgram[idx].uniform4fv(LLShaderMgr::MULTI_LIGHT_COL, count, (GLfloat*) col); - gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); - far_z = 0.f; - count = 0; - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - } - - unbindDeferredShader(gDeferredMultiLightProgram[0]); - - bindDeferredShader(gDeferredMultiSpotLightProgram); - - gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) - { - LL_RECORD_BLOCK_TIME(FTM_PROJECTORS); - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; - - sVisibleLightCount++; - - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); - - LLColor3 col = volume->getLightColor(); - - /*col.mV[0] = powf(col.mV[0], 2.2f); - col.mV[1] = powf(col.mV[1], 2.2f); - col.mV[2] = powf(col.mV[2], 2.2f);*/ - - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); - gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); - gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); - gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, volume->getLightFalloff()*0.5f); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - } - - gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); - unbindDeferredShader(gDeferredMultiSpotLightProgram); - - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - } - } - - gGL.setColorMask(true, true); - } - - /*target->flush(); - - //gamma correct lighting - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.pushMatrix(); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.pushMatrix(); - gGL.loadIdentity(); - - { - LLGLDepthTest depth(GL_FALSE, GL_FALSE); - - LLVector2 tc1(0,0); - LLVector2 tc2((F32) target->getWidth()*2, - (F32) target->getHeight()*2); - - target->bindTarget(); - // Apply gamma correction to the frame here. - gDeferredPostGammaCorrectProgram.bind(); - //mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - S32 channel = 0; - channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, target->getUsage()); - if (channel > -1) - { - target->bindTexture(0,channel); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - } - - gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, target->getWidth(), target->getHeight()); - - F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); - - gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f/2.2f)); - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,3); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(3,-1); - - gGL.end(); - - gGL.getTexUnit(channel)->unbind(target->getUsage()); - gDeferredPostGammaCorrectProgram.unbind(); - target->flush(); - } - - gGL.matrixMode(LLRender::MM_PROJECTION); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.popMatrix(); - - target->bindTarget();*/ - - { //render non-deferred geometry (alpha, fullbright, glow) - LLGLDisable blend(GL_BLEND); - LLGLDisable stencil(GL_STENCIL_TEST); - - pushRenderTypeMask(); - andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, - LLPipeline::RENDER_TYPE_FULLBRIGHT, - LLPipeline::RENDER_TYPE_VOLUME, - LLPipeline::RENDER_TYPE_GLOW, - LLPipeline::RENDER_TYPE_BUMP, - LLPipeline::RENDER_TYPE_PASS_SIMPLE, - LLPipeline::RENDER_TYPE_PASS_ALPHA, - LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_BUMP, - LLPipeline::RENDER_TYPE_PASS_POST_BUMP, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, - LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, - LLPipeline::RENDER_TYPE_PASS_GLOW, - LLPipeline::RENDER_TYPE_PASS_GRASS, - LLPipeline::RENDER_TYPE_PASS_SHINY, - LLPipeline::RENDER_TYPE_PASS_INVISIBLE, - LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, - LLPipeline::RENDER_TYPE_AVATAR, - LLPipeline::RENDER_TYPE_ALPHA_MASK, - LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK, - END_RENDER_TYPES); - - renderGeomPostDeferred(*LLViewerCamera::getInstance()); - popRenderTypeMask(); - } - - //target->flush(); + screen_target->flush(); } void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) @@ -9599,7 +9111,7 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); - glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; + glh::matrix4f light_to_screen = get_current_modelview() * light_to_agent; glh::matrix4f screen_to_light = light_to_screen.inverse(); @@ -9711,12 +9223,16 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { + LLRenderTarget* deferred_target = &mDeferredScreen; + LLRenderTarget* deferred_depth_target = &mDeferredDepth; + LLRenderTarget* deferred_light_target = &mDeferredLight; + stop_glerror(); - 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::DEFERRED_NORMAL, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_SPECULAR, deferred_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_DEPTH, deferred_depth_target->getUsage()); + shader.disableTexture(LLShaderMgr::DEFERRED_LIGHT, deferred_light_target->getUsage()); shader.disableTexture(LLShaderMgr::DIFFUSE_MAP); shader.disableTexture(LLShaderMgr::DEFERRED_BLOOM); @@ -9770,105 +9286,95 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) skip_avatar_update = true; } - if (!skip_avatar_update) - { - gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); - } - LLVertexBuffer::unbind(); + LLCamera camera = camera_in; - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); + camera.setFar(camera_in.getFar() * 0.75f); + + bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater(); - LLCamera camera = camera_in; - camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = true; gPipeline.pushRenderTypeMask(); - glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f projection = get_current_projection(); glh::matrix4f mat; - stop_glerror(); - LLPlane plane; + S32 detail = RenderReflectionDetail; + + F32 water_height = gAgent.getRegion()->getWaterHeight(); + F32 camera_height = camera_in.getOrigin().mV[VZ]; + F32 distance_to_water = (water_height < camera_height) ? (camera_height - water_height) : (water_height - camera_height); - F32 height = gAgent.getRegion()->getWaterHeight(); - F32 to_clip = fabsf(camera.getOrigin().mV[2]-height); - F32 pad = -to_clip*0.05f; //amount to "pad" clip plane by + LLVector3 reflection_offset = LLVector3(0, 0, distance_to_water * 2.0f); + LLVector3 camera_look_at = camera_in.getAtAxis(); + LLVector3 reflection_look_at = LLVector3(camera_look_at.mV[VX], camera_look_at.mV[VY], -camera_look_at.mV[VZ]); + LLVector3 reflect_origin = camera_in.getOrigin() - reflection_offset; + LLVector3 reflect_interest_point = reflect_origin + (reflection_look_at * 5.0f); + + camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point); //plane params + LLPlane plane; LLVector3 pnorm; - F32 pd; - S32 water_clip = 0; - if (!LLViewerCamera::getInstance()->cameraUnderWater()) + if (!camera_is_underwater) { //camera is above water, clip plane points up pnorm.setVec(0,0,1); - pd = -height; - plane.setVec(pnorm, pd); - water_clip = -1; + plane.setVec(pnorm, -water_height); + water_clip = 1; } else { //camera is below water, clip plane points down pnorm = LLVector3(0,0,-1); - pd = height; - plane.setVec(pnorm, pd); - water_clip = 1; + plane.setVec(pnorm, water_height); + water_clip = -1; } - bool materials_in_water = false; - -#if MATERIALS_IN_REFLECTIONS - materials_in_water = gSavedSettings.getS32("RenderWaterMaterials"); -#endif - - if (!LLViewerCamera::getInstance()->cameraUnderWater()) - { //generate planar reflection map + S32 occlusion = LLPipeline::sUseOcclusion; //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(); + glh::matrix4f current = get_current_modelview(); + + if (!camera_is_underwater) + { //generate planar reflection map LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; - gGL.setColorMask(true, true); - mWaterRef.clear(); - gGL.setColorMask(true, false); - mWaterRef.getViewport(gGLViewport); + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); - stop_glerror(); + glh::matrix4f mat; + camera.getOpenGLTransform(mat.m); - gGL.pushMatrix(); + glh::matrix4f scal; + scal.set_scale(glh::vec3f(1, 1, -1)); + mat = scal * mat; - mat.set_scale(glh::vec3f(1,1,-1)); - mat.set_translate(glh::vec3f(0,0,height*2.f)); + // convert from CFR to OGL coord sys... + mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; - glh::matrix4f current = glh_get_current_modelview(); + mReflectionModelView = mat; - mat = current * mat; - - glh_set_current_modelview(mat); + set_current_modelview(mat); gGL.loadMatrix(mat.m); LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE); - glh::matrix4f inv_mat = mat.inverse(); - - glh::vec3f origin(0,0,0); - inv_mat.mult_matrix_vec(origin); - - camera.setOrigin(origin.v); - glCullFace(GL_FRONT); - static LLCullResult ref_result; - if (LLDrawPoolWater::sNeedsReflectionUpdate) { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + glClearColor(0,0,0,0); + mWaterRef.bindTarget(); + + gGL.setColorMask(true, true); + mWaterRef.clear(); + gGL.setColorMask(true, false); + mWaterRef.getViewport(gGLViewport); + //initial sky pass (no user clip plane) { //mask out everything but the sky gPipeline.pushRenderTypeMask(); @@ -9877,31 +9383,13 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); - static LLCullResult result; - updateCull(camera, result); - stateSort(camera, result); - - if (LLPipeline::sRenderDeferred && materials_in_water) - { - mWaterRef.flush(); - - gPipeline.grabReferences(result); - gPipeline.mDeferredScreen.bindTarget(); - gGL.setColorMask(true, true); - glClearColor(0,0,0,0); - gPipeline.mDeferredScreen.clear(); - - renderGeomDeferred(camera); - } - else - { + updateCull(camera, mSky); + stateSort(camera, mSky); renderGeom(camera, TRUE); - } gPipeline.popRenderTypeMask(); } - gGL.setColorMask(true, false); gPipeline.pushRenderTypeMask(); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, @@ -9911,10 +9399,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::END_RENDER_TYPES); - 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); @@ -9928,63 +9414,46 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } - - LLGLUserClipPlane clip_plane(plane, mat, projection); + LLGLUserClipPlane clip_plane(plane, mReflectionModelView, projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, ref_result, -water_clip, &plane); - stateSort(camera, ref_result); - } - - if (LLDrawPoolWater::sNeedsDistortionUpdate) - { - if (RenderReflectionDetail > 0) - { - gPipeline.grabReferences(ref_result); - LLGLUserClipPlane clip_plane(plane, mat, projection); - - if (LLPipeline::sRenderDeferred && materials_in_water) - { - renderGeomDeferred(camera); - } - else - { + updateCull(camera, mReflectedObjects, -water_clip, &plane); + stateSort(camera, mReflectedObjects); renderGeom(camera); } - } - } - - if (LLPipeline::sRenderDeferred && materials_in_water) - { - gPipeline.mDeferredScreen.flush(); - renderDeferredLightingToRT(&mWaterRef); + gPipeline.popRenderTypeMask(); + mWaterRef.flush(); } - gPipeline.popRenderTypeMask(); - } glCullFace(GL_BACK); + gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.popMatrix(); - mWaterRef.flush(); - glh_set_current_modelview(current); - LLPipeline::sUseOcclusion = occlusion; + + set_current_modelview(current); } + //LLPipeline::sUseOcclusion = occlusion; + camera.setOrigin(camera_in.getOrigin()); //render distortion map static bool last_update = true; if (last_update) { + gPipeline.pushRenderTypeMask(); + camera.setFar(camera_in.getFar()); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_GROUND, END_RENDER_TYPES); - stop_glerror(); - LLPipeline::sUnderWaterRender = ! LLViewerCamera::getInstance()->cameraUnderWater(); + // intentionally inverted so that distortion map contents (objects under the water when we're above it) + // will properly include water fog effects + LLPipeline::sUnderWaterRender = !camera_is_underwater; if (LLPipeline::sUnderWaterRender) { - clearRenderTypeMask(LLPipeline::RENDER_TYPE_GROUND, + clearRenderTypeMask( + LLPipeline::RENDER_TYPE_GROUND, LLPipeline::RENDER_TYPE_SKY, LLPipeline::RENDER_TYPE_CLOUDS, LLPipeline::RENDER_TYPE_WL_SKY, @@ -9994,43 +9463,41 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLColor4& col = LLDrawPoolWater::sWaterFogColor; + if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate) + { + LLPipeline::sDistortionRender = true; + + LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); - mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; + mWaterDis.bindTarget(); 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(); - LLPlane plane(-pnorm, -(pd+pad)); + gGL.setColorMask(true, true); + mWaterDis.clear(); + gGL.setColorMask(true, false); + + F32 water_dist = water_height * LLPipeline::sDistortionWaterClipPlaneMargin; - LLGLUserClipPlane clip_plane(plane, mat, projection); - static LLCullResult result; - updateCull(camera, result, water_clip, &plane); - stateSort(camera, result); + //clip out geometry on the same side of water as the camera w/ enough margin to not include the water geo itself, + // but not so much as to clip out parts of avatars that should be seen under the water in the distortion map + LLPlane plane(-pnorm, water_dist); + LLGLUserClipPlane clip_plane(plane, current, projection); gGL.setColorMask(true, true); mWaterDis.clear(); - - gGL.setColorMask(true, false); - - if (LLPipeline::sRenderDeferred && materials_in_water) + // ignore clip plane if we're underwater and viewing distortion map of objects above waterline + if (camera_is_underwater) { - mWaterDis.flush(); - gPipeline.mDeferredScreen.bindTarget(); - gGL.setColorMask(true, true); - glClearColor(0,0,0,0); - gPipeline.mDeferredScreen.clear(); - gPipeline.grabReferences(result); - renderGeomDeferred(camera); + clip_plane.disable(); } - else - { + + updateCull(camera, mRefractedObjects, water_clip, &plane); + stateSort(camera, mRefractedObjects); renderGeom(camera); if (LLGLSLShader::sNoFixedFunction) @@ -10044,34 +9511,31 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { gUIProgram.unbind(); } - } - if (LLPipeline::sRenderDeferred && materials_in_water) - { - gPipeline.mDeferredScreen.flush(); - renderDeferredLightingToRT(&mWaterDis); - } + mWaterDis.flush(); } - mWaterDis.flush(); - LLPipeline::sUnderWaterRender = false; + LLPipeline::sDistortionRender = false; + gPipeline.popRenderTypeMask(); } last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate; + gPipeline.popRenderTypeMask(); + + LLPipeline::sUseOcclusion = occlusion; + LLPipeline::sUnderWaterRender = false; LLPipeline::sReflectionRender = false; + LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; + LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; + if (!LLRenderTarget::sUseFBO) { glClear(GL_DEPTH_BUFFER_BIT); } glClearColor(0.f, 0.f, 0.f, 0.f); gViewerWindow->setup3DViewport(); - gPipeline.popRenderTypeMask(); - LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; - LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; - LLPlane npnorm(-pnorm, -pd); - LLViewerCamera::getInstance()->setUserClipPlane(npnorm); LLGLState::checkStates(); @@ -10153,6 +9617,13 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) static LLTrace::BlockTimerStatHandle FTM_SHADOW_RENDER("Render Shadows"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA("Alpha Shadow"); static LLTrace::BlockTimerStatHandle FTM_SHADOW_SIMPLE("Simple Shadow"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_GEOM("Shadow Geom"); + +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_MASKED("Alpha Masked"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_BLEND("Alpha Blend"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_TREE("Alpha Tree"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_ALPHA_GRASS("Alpha Grass"); +static LLTrace::BlockTimerStatHandle FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED("Fullbright Alpha Masked"); void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, LLCullResult &result, bool use_shader, bool use_occlusion, U32 target_width) { @@ -10207,7 +9678,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera gGL.loadMatrix(proj.m); gGL.matrixMode(LLRender::MM_MODELVIEW); gGL.pushMatrix(); - gGL.loadMatrix(gGLModelView); + gGL.loadMatrix(view.m); stop_glerror(); gGLLastMatrix = NULL; @@ -10216,6 +9687,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera stop_glerror(); + LLEnvironment& environment = LLEnvironment::instance(); + LLVertexBuffer::unbind(); { @@ -10226,10 +9699,18 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera else { gDeferredShadowProgram.bind(); + gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); } gGL.diffuseColor4f(1,1,1,1); + + S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + + // if not using VSM, disable color writes + if (shadow_detail <= 2) + { gGL.setColorMask(false, false); + } LL_RECORD_BLOCK_TIME(FTM_SHADOW_SIMPLE); @@ -10247,41 +9728,69 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera if (use_shader) { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); + gDeferredShadowProgram.unbind(); renderGeomShadow(shadow_cam); gDeferredShadowProgram.bind(); + gDeferredShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); } else { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_GEOM); + renderGeomShadow(shadow_cam); } { LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA); + gDeferredShadowAlphaMaskProgram.bind(); gDeferredShadowAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + gDeferredShadowAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_MASKED); renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE); - renderMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + } + + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_BLEND); gDeferredShadowAlphaMaskProgram.setMinimumAlpha(0.598f); renderObjects(LLRenderPass::PASS_ALPHA, mask, TRUE, TRUE); + } + + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_FULLBRIGHT_ALPHA_MASKED); + gDeferredShadowFullbrightAlphaMaskProgram.bind(); + gDeferredShadowFullbrightAlphaMaskProgram.uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); + gDeferredShadowFullbrightAlphaMaskProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); + renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE); + } mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_TREE); gDeferredTreeShadowProgram.bind(); + gDeferredTreeShadowProgram.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, mask); renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, mask); renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, mask); renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, mask); + } + { + LL_RECORD_BLOCK_TIME(FTM_SHADOW_ALPHA_GRASS); gDeferredTreeShadowProgram.setMinimumAlpha(0.598f); renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); } + } //glCullFace(GL_BACK); @@ -10525,7 +10034,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) gGL.setColorMask(true, true); mHighlight.clear(); - if (canUseVertexShaders()) + if (LLGLSLShader::sNoFixedFunction) { gHighlightProgram.bind(); } @@ -10564,8 +10073,16 @@ void LLPipeline::generateHighlight(LLCamera& camera) } } +LLRenderTarget* LLPipeline::getShadowTarget(U32 i) +{ + return &mShadow[i]; +} static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW("Gen Sun Shadow"); +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SETUP("Sun Shadow Setup"); +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_RENDER_DIRECTIONAL("Render Dir"); +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_SETUP("Spot Shadow Setup"); +static LLTrace::BlockTimerStatHandle FTM_GEN_SUN_SHADOW_SPOT_RENDER("Spot Shadow Render"); void LLPipeline::generateSunShadow(LLCamera& camera) { @@ -10637,11 +10154,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) gGL.setColorMask(false, false); + LLEnvironment& environment = LLEnvironment::instance(); + //get sun view matrix //store current projection/modelview matrix - glh::matrix4f saved_proj = glh_get_current_projection(); - glh::matrix4f saved_view = glh_get_current_modelview(); + glh::matrix4f saved_proj = get_current_projection(); + glh::matrix4f saved_view = get_current_modelview(); glh::matrix4f inv_view = saved_view.inverse(); glh::matrix4f view[6]; @@ -10650,6 +10169,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) //clip contains parallel split distances for 3 splits LLVector3 clip = RenderShadowClipPlanes; + LLVector3 caster_dir(environment.getIsSunUp() ? mSunDir : mMoonDir); + //F32 slope_threshold = gSavedSettings.getF32("RenderShadowSlopeThreshold"); //far clip on last split is minimum of camera view distance and 128 @@ -10666,11 +10187,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPlane shadow_near_clip; { LLVector3 p = gAgent.getPositionAgent(); - p += mSunDir * RenderFarClip*2.f; - shadow_near_clip.setVec(p, mSunDir); + p += caster_dir * RenderFarClip*2.f; + shadow_near_clip.setVec(p, caster_dir); } - LLVector3 lightDir = -mSunDir; + LLVector3 lightDir = -caster_dir; lightDir.normVec(); glh::vec3f light_dir(lightDir.mV); @@ -10745,8 +10266,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) update_min_max(min, max, fp[i]); } - near_clip = -max.mV[2]; - F32 far_clip = -min.mV[2]*2.f; + near_clip = llclamp(-max.mV[2], 0.01f, 4.0f); + F32 far_clip = llclamp(-min.mV[2]*2.f, 16.0f, 512.0f); //far_clip = llmin(far_clip, 128.f); far_clip = llmin(far_clip, camera.getFar()); @@ -10798,8 +10319,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0+j); //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); LLVector3 eye = camera.getOrigin(); @@ -11112,8 +10633,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) shadow_cam.setOrigin(0,0,0); - glh_set_current_modelview(view[j]); - glh_set_current_projection(proj[j]); + set_current_modelview(view[j]); + set_current_projection(proj[j]); LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); @@ -11126,8 +10647,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) 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]); + set_current_modelview(view[j]); + set_current_projection(proj[j]); for (U32 i = 0; i < 16; i++) { @@ -11137,8 +10658,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowModelview[j] = view[j]; mShadowProjection[j] = proj[j]; - - mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; stop_glerror(); @@ -11151,15 +10670,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { static LLCullResult result[4]; - - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, TRUE, target_width); + renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width); } mShadow[j].flush(); if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { - LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); mShadowCamera[j+4] = shadow_cam; } } @@ -11206,8 +10723,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) for (S32 i = 0; i < 2; i++) { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); if (mShadowSpotLight[i].isNull()) { @@ -11267,8 +10784,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) 0.f, 0.f, 0.5f, 0.5f, 0.f, 0.f, 0.f, 1.f); - glh_set_current_modelview(view[i+4]); - glh_set_current_projection(proj[i+4]); + set_current_modelview(view[i+4]); + set_current_projection(proj[i+4]); mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; @@ -11299,8 +10816,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::sCurCameraID = (LLViewerCamera::eCameraID)(LLViewerCamera::CAMERA_SHADOW0 + i + 4); + RenderSpotLight = drawable; + renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE, target_width); + RenderSpotLight = nullptr; + mShadow[i+4].flush(); } } @@ -11312,13 +10833,13 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (!CameraOffset) { - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + set_current_modelview(saved_view); + set_current_projection(saved_proj); } else { - glh_set_current_modelview(view[1]); - glh_set_current_projection(proj[1]); + set_current_modelview(view[1]); + set_current_projection(proj[1]); gGL.loadMatrix(view[1].m); gGL.matrixMode(LLRender::MM_PROJECTION); gGL.loadMatrix(proj[1].m); @@ -11496,7 +11017,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; F32 aspect = tdim.mV[0]/tdim.mV[1]; glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); - glh_set_current_projection(persp); + set_current_projection(persp); gGL.loadMatrix(persp.m); gGL.matrixMode(LLRender::MM_MODELVIEW); @@ -11507,7 +11028,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) mat = glh::matrix4f((GLfloat*) OGL_TO_CFR_ROTATION) * mat; gGL.loadMatrix(mat.m); - glh_set_current_modelview(mat); + set_current_modelview(mat); glClearColor(0.0f,0.0f,0.0f,0.0f); gGL.setColorMask(true, true); |