diff options
Diffstat (limited to 'indra/newview/pipeline.cpp')
-rw-r--r-- | indra/newview/pipeline.cpp | 2248 |
1 files changed, 1394 insertions, 854 deletions
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 91c3805d3b..e74bf2a620 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -2,31 +2,25 @@ * @file pipeline.cpp * @brief Rendering pipeline. * - * $LicenseInfo:firstyear=2005&license=viewergpl$ - * - * Copyright (c) 2005-2009, Linden Research, Inc. - * + * $LicenseInfo:firstyear=2005&license=viewerlgpl$ * Second Life Viewer Source Code - * The source code in this file ("Source Code") is provided by Linden Lab - * to you under the terms of the GNU General Public License, version 2.0 - * ("GPL"), unless you have obtained a separate licensing agreement - * ("Other License"), formally executed by you and Linden Lab. Terms of - * the GPL can be found in doc/GPL-license.txt in this distribution, or - * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2 + * Copyright (C) 2010, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. * - * There are special exceptions to the terms and conditions of the GPL as - * it is applied to this Source Code. View the full text of the exception - * in the file doc/FLOSS-exception.txt in this software distribution, or - * online at - * http://secondlifegrid.net/programs/open_source/licensing/flossexception + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * By copying, modifying or distributing this software, you acknowledge - * that you have read and understood your obligations described above, - * and agree to abide by those obligations. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO - * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, - * COMPLETENESS OR PERFORMANCE. + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ @@ -70,6 +64,8 @@ #include "llfloaterreg.h" #include "llgldbg.h" #include "llhudmanager.h" +#include "llhudnametag.h" +#include "llhudtext.h" #include "lllightconstants.h" #include "llmeshrepository.h" #include "llresmgr.h" @@ -79,6 +75,7 @@ #include "lltool.h" #include "lltoolmgr.h" #include "llviewercamera.h" +#include "llviewermediafocus.h" #include "llviewertexturelist.h" #include "llviewerobject.h" #include "llviewerobjectlist.h" @@ -108,6 +105,26 @@ #include "llcurl.h" +void check_stack_depth(S32 stack_depth) +{ + if (gDebugGL || gDebugSession) + { + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth != stack_depth) + { + if (gDebugSession) + { + ll_fail("GL matrix stack corrupted."); + } + else + { + llerrs << "GL matrix stack corrupted!" << llendl; + } + } + } +} + #ifdef _DEBUG // Debug indices is disabled for now for debug performance - djs 4/24/02 //#define DEBUG_INDICES @@ -136,8 +153,6 @@ static S32 sDelayedVBOEnable = 0; BOOL gAvatarBacklight = FALSE; -BOOL gRenderForSelect = FALSE; - BOOL gDebugPipeline = FALSE; LLPipeline gPipeline; const LLMatrix4* gGLLastMatrix = NULL; @@ -177,19 +192,20 @@ std::string gPoolNames[] = // Correspond to LLDrawpool enum render type "NONE", "POOL_SIMPLE", - "POOL_TERRAIN", + "POOL_GROUND", + "POOL_FULLBRIGHT", "POOL_BUMP", - "POOL_TREE", + "POOL_TERRAIN," "POOL_SKY", "POOL_WL_SKY", - "POOL_GROUND", + "POOL_TREE", + "POOL_GRASS", "POOL_INVISIBLE", "POOL_AVATAR", + "POOL_VOIDWATER", "POOL_WATER", - "POOL_GRASS", - "POOL_FULLBRIGHT", "POOL_GLOW", - "POOL_ALPHA", + "POOL_ALPHA" }; void drawBox(const LLVector3& c, const LLVector3& r); @@ -224,6 +240,16 @@ 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, GLdouble* dst) { for (U32 i = 0; i < 16; i++) @@ -261,6 +287,7 @@ S32 LLPipeline::sCompiles = 0; BOOL LLPipeline::sPickAvatar = TRUE; BOOL LLPipeline::sDynamicLOD = TRUE; BOOL LLPipeline::sShowHUDAttachments = TRUE; +BOOL LLPipeline::sRenderMOAPBeacons = FALSE; BOOL LLPipeline::sRenderPhysicalBeacons = TRUE; BOOL LLPipeline::sRenderScriptedBeacons = FALSE; BOOL LLPipeline::sRenderScriptedTouchBeacons = TRUE; @@ -268,7 +295,7 @@ BOOL LLPipeline::sRenderParticleBeacons = FALSE; BOOL LLPipeline::sRenderSoundBeacons = FALSE; BOOL LLPipeline::sRenderBeacons = FALSE; BOOL LLPipeline::sRenderHighlight = TRUE; -BOOL LLPipeline::sForceOldBakedUpload = TRUE; +BOOL LLPipeline::sForceOldBakedUpload = FALSE; S32 LLPipeline::sUseOcclusion = 0; BOOL LLPipeline::sDelayVBUpdate = TRUE; BOOL LLPipeline::sAutoMaskAlphaDeferred = TRUE; @@ -290,7 +317,6 @@ BOOL LLPipeline::sRenderFrameTest = FALSE; BOOL LLPipeline::sRenderAttachedLights = TRUE; BOOL LLPipeline::sRenderAttachedParticles = TRUE; BOOL LLPipeline::sRenderDeferred = FALSE; -BOOL LLPipeline::sAllowRebuildPriorityGroup = FALSE ; S32 LLPipeline::sVisibleLightCount = 0; F32 LLPipeline::sMinRenderSize = 0.f; @@ -337,6 +363,8 @@ LLPipeline::LLPipeline() : mRenderDebugFeatureMask(0), mRenderDebugMask(0), mOldRenderDebugMask(0), + mGroupQ1Locked(false), + mGroupQ2Locked(false), mLastRebuildPool(NULL), mAlphaPool(NULL), mSkyPool(NULL), @@ -364,10 +392,12 @@ void LLPipeline::init() { LLMemType mt(LLMemType::MTYPE_PIPELINE_INIT); + gOctreeMaxCapacity = gSavedSettings.getU32("OctreeMaxNodeCapacity"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -402,6 +432,14 @@ void LLPipeline::init() toggleRenderType(RENDER_TYPE_GROUND); } + // make sure RenderPerformanceTest persists (hackity hack hack) + // disables non-object rendering (UI, sky, water, etc) + if (gSavedSettings.getBOOL("RenderPerformanceTest")) + { + gSavedSettings.setBOOL("RenderPerformanceTest", FALSE); + gSavedSettings.setBOOL("RenderPerformanceTest", TRUE); + } + mOldRenderDebugMask = mRenderDebugMask; mBackfaceCull = TRUE; @@ -535,13 +573,31 @@ void LLPipeline::resizeScreenTexture() } } +void LLPipeline::allocatePhysicsBuffer() +{ + GLuint resX = gViewerWindow->getWorldViewWidthRaw(); + GLuint resY = gViewerWindow->getWorldViewHeightRaw(); + + if (mPhysicsDisplay.getWidth() != resX || mPhysicsDisplay.getHeight() != resY) + { + mPhysicsDisplay.allocate(resX, resY, GL_RGBA, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } +} + void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { // remember these dimensions mScreenWidth = resX; mScreenHeight = resY; - U32 samples = gSavedSettings.getU32("RenderFSAASamples"); + //cap samples at 4 for render targets to avoid out of memory errors + U32 samples = gGLManager.getNumFBOFSAASamples(gSavedSettings.getU32("RenderFSAASamples")); + + if (gGLManager.mIsATI) + { //disable multisampling of render targets where ATI is involved + samples = 0; + } + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); if (res_mod > 1 && res_mod < resX && res_mod < resY) @@ -557,43 +613,105 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (LLPipeline::sRenderDeferred) { + S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); + BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO"); + bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED); + //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); + mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); addDeferredAttachments(mDeferredScreen); - // always set viewport to desired size, since allocate resets the viewport - - mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples); + +#if LL_DARWIN + // As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO + mEdgeMap.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +#else mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); +#endif - for (U32 i = 0; i < 3; i++) + if (shadow_detail > 0 || ssao) + { //only need mDeferredLight[0] for shadows OR ssao + mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } + else { - mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[0].release(); } - for (U32 i = 0; i < 2; i++) + if (ssao) + { //only need mDeferredLight[1] for ssao + mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); + } + else { - mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mDeferredLight[1].release(); + } + + if (gi) + { //only need mDeferredLight[2] and mGIMapPost for gi + mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, false); + for (U32 i = 0; i < 2; i++) + { +#if LL_DARWIN + // As of OS X 10.6.7, Apple doesn't support multiple color formats in a single FBO + mGIMapPost[i].allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +#else + mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +#endif + } + } + else + { + mDeferredLight[2].release(); + + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].release(); + } } F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); +#if LL_DARWIN + U32 shadow_fmt = 0; +#else //HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; +#endif - for (U32 i = 0; i < 4; i++) + if (shadow_detail > 0) + { //allocate 4 sun shadow maps + for (U32 i = 0; i < 4; i++) + { + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + } + else { - mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + for (U32 i = 0; i < 4; i++) + { + mShadow[i].release(); + } } - U32 width = nhpo2(U32(resX*scale))/2; U32 height = width; - for (U32 i = 4; i < 6; i++) + if (shadow_detail > 1) + { //allocate two spot shadow maps + for (U32 i = 4; i < 6; i++) + { + mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + } + } + else { - mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); + for (U32 i = 4; i < 6; i++) + { + mShadow[i].release(); + } } width = nhpo2(resX)/2; @@ -602,31 +720,30 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) } else { - mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - } - - - if (gGLManager.mHasFramebufferMultisample && samples > 1) - { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); - if (LLPipeline::sRenderDeferred) + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].release(); + } + for (U32 i = 0; i < 2; i++) { - addDeferredAttachments(mSampleBuffer); - mDeferredScreen.setSampleBuffer(&mSampleBuffer); + mGIMapPost[i].release(); } - - mScreen.setSampleBuffer(&mSampleBuffer); - - stop_glerror(); + for (U32 i = 0; i < 6; i++) + { + mShadow[i].release(); + } + mScreen.release(); + mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first + mDeferredDepth.release(); + mEdgeMap.release(); + mLuminanceMap.release(); + + mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); } if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 3; i++) - { //share stencil buffer with screen space lightmap to stencil out sky - mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); - } } gGL.getTexUnit(0)->disable(); @@ -638,14 +755,25 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) //static void LLPipeline::updateRenderDeferred() { - BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") && - LLRenderTarget::sUseFBO && - LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && - gSavedSettings.getBOOL("VertexShaderEnable") && - gSavedSettings.getBOOL("RenderAvatarVP") && - gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE; - - sRenderDeferred = deferred; + BOOL deferred = ((gSavedSettings.getBOOL("RenderDeferred") && + LLRenderTarget::sUseFBO && + LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && + gSavedSettings.getBOOL("VertexShaderEnable") && + gSavedSettings.getBOOL("RenderAvatarVP") && + gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) && + !gUseWireframe; + + sRenderDeferred = deferred; + if (deferred) + { //must render glow when rendering deferred since post effect pass is needed to present any lighting at all + sRenderGlow = TRUE; + } +} + +//static +void LLPipeline::refreshRenderDeferred() +{ + updateRenderDeferred(); } void LLPipeline::releaseGLBuffers() @@ -673,8 +801,8 @@ void LLPipeline::releaseGLBuffers() mWaterRef.release(); mWaterDis.release(); mScreen.release(); + mPhysicsDisplay.release(); mUIScreen.release(); - mSampleBuffer.releaseSampleBuffer(); mDeferredScreen.release(); mDeferredDepth.release(); for (U32 i = 0; i < 3; i++) @@ -699,6 +827,7 @@ void LLPipeline::releaseGLBuffers() mGlow[i].release(); } + gBumpImageList.destroyGL(); LLVOAvatar::resetImpostors(); } @@ -737,7 +866,6 @@ void LLPipeline::createGLBuffers() allocateScreenBuffer(resX,resY); mScreenWidth = 0; mScreenHeight = 0; - } if (sRenderDeferred) @@ -822,6 +950,8 @@ void LLPipeline::createGLBuffers() addDeferredAttachments(mGIMap); } } + + gBumpImageList.restoreGL(); } void LLPipeline::restoreGL() @@ -879,6 +1009,11 @@ BOOL LLPipeline::canUseWindLightShadersOnObjects() const && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT) > 0); } +BOOL LLPipeline::canUseAntiAliasing() const +{ + return TRUE; +} + void LLPipeline::unloadShaders() { LLMemType mt_us(LLMemType::MTYPE_PIPELINE_UNLOAD_SHADERS); @@ -914,24 +1049,21 @@ S32 LLPipeline::getMaxLightingDetail() const S32 LLPipeline::setLightingDetail(S32 level) { LLMemType mt_ld(LLMemType::MTYPE_PIPELINE_LIGHTING_DETAIL); - assertInitialized(); if (level < 0) { - level = gSavedSettings.getS32("RenderLightingDetail"); - } - level = llclamp(level, 0, getMaxLightingDetail()); - if (level != mLightingDetail) - { - gSavedSettings.setS32("RenderLightingDetail", level); - - mLightingDetail = level; - - if (mVertexShadersLoaded == 1) + if (gSavedSettings.getBOOL("RenderLocalLights")) { - LLViewerShaderMgr::instance()->setShaders(); + level = 1; + } + else + { + level = 0; } } + level = llclamp(level, 0, getMaxLightingDetail()); + mLightingDetail = level; + return mLightingDetail; } @@ -1240,10 +1372,6 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) U32 LLPipeline::addObject(LLViewerObject *vobj) { LLMemType mt_ao(LLMemType::MTYPE_PIPELINE_ADD_OBJECT); - if (gNoRender) - { - return 0; - } if (gSavedSettings.getBOOL("RenderDelayCreation")) { @@ -1508,11 +1636,214 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera return radius*radius * F_PI; } +//static +F32 LLPipeline::calcPixelArea(const LLVector4a& center, const LLVector4a& size, LLCamera &camera) +{ + LLVector4a origin; + origin.load3(camera.getOrigin().mV); + + LLVector4a lookAt; + lookAt.setSub(center, origin); + F32 dist = lookAt.getLength3().getF32(); + + //ramp down distance for nearby objects + //shrink dist by dist/16. + if (dist < 16.f) + { + dist /= 16.f; + dist *= dist; + dist *= 16.f; + } + + //get area of circle around node + F32 app_angle = atanf(size.getLength3().getF32()/dist); + F32 radius = app_angle*LLDrawable::sCurPixelAngle; + return radius*radius * F_PI; +} + void LLPipeline::grabReferences(LLCullResult& result) { sCull = &result; } +void LLPipeline::clearReferences() +{ + sCull = NULL; +} + +void check_references(LLSpatialGroup* group, LLDrawable* drawable) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + if (drawable == *i) + { + llerrs << "LLDrawable deleted while actively reference by LLPipeline." << llendl; + } + } +} + +void check_references(LLDrawable* drawable, LLFace* face) +{ + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + if (drawable->getFace(i) == face) + { + llerrs << "LLFace deleted while actively referenced by LLPipeline." << llendl; + } + } +} + +void check_references(LLSpatialGroup* group, LLFace* face) +{ + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = *i; + check_references(drawable, face); + } +} + +void LLPipeline::checkReferences(LLFace* face) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, face); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + LLDrawable* drawable = *iter; + check_references(drawable, face); + } + } +#endif +} + +void LLPipeline::checkReferences(LLDrawable* drawable) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, drawable); + } + + for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); iter != sCull->endVisibleList(); ++iter) + { + if (drawable == *iter) + { + llerrs << "LLDrawable deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + +void check_references(LLSpatialGroup* group, LLDrawInfo* draw_info) +{ + for (LLSpatialGroup::draw_map_t::iterator i = group->mDrawMap.begin(); i != group->mDrawMap.end(); ++i) + { + LLSpatialGroup::drawmap_elem_t& draw_vec = i->second; + for (LLSpatialGroup::drawmap_elem_t::iterator j = draw_vec.begin(); j != draw_vec.end(); ++j) + { + LLDrawInfo* params = *j; + if (params == draw_info) + { + llerrs << "LLDrawInfo deleted while actively referenced by LLPipeline." << llendl; + } + } + } +} + + +void LLPipeline::checkReferences(LLDrawInfo* draw_info) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + LLSpatialGroup* group = *iter; + check_references(group, draw_info); + } + } +#endif +} + +void LLPipeline::checkReferences(LLSpatialGroup* group) +{ +#if 0 + if (sCull) + { + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginAlphaGroups(); iter != sCull->endAlphaGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + + for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) + { + if (group == *iter) + { + llerrs << "LLSpatialGroup deleted while actively referenced by LLPipeline." << llendl; + } + } + } +#endif +} + + BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); @@ -1579,7 +1910,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& static LLFastTimer::DeclareTimer FTM_CULL("Object Culling"); -void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip) +void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip, LLPlane* planep) { LLFastTimer t(FTM_CULL); LLMemType mt_uc(LLMemType::MTYPE_PIPELINE_UPDATE_CULL); @@ -1599,6 +1930,11 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl mScreen.bindTarget(); } + if (sUseOcclusion > 1) + { + gGL.setColorMask(false, false); + } + glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadMatrixd(gGLLastProjection); @@ -1613,10 +1949,37 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDisable test(GL_ALPHA_TEST); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - if (sUseOcclusion > 1) + + //setup a clip plane in projection matrix for reflection renders (prevents flickering from occlusion culling) + LLViewerRegion* region = gAgent.getRegion(); + LLPlane plane; + + if (planep) { - gGL.setColorMask(false, false); + plane = *planep; } + else + { + if (region) + { + LLVector3 pnorm; + F32 height = region->getWaterHeight(); + if (water_clip < 0) + { //camera is above water, clip plane points up + pnorm.setVec(0,0,1); + plane.setVec(pnorm, -height); + } + else if (water_clip > 0) + { //camera is below water, clip plane points down + pnorm = LLVector3(0,0,-1); + plane.setVec(pnorm, height); + } + } + } + + glh::matrix4f modelview = glh_get_last_modelview(); + glh::matrix4f proj = glh_get_last_projection(); + LLGLUserClipPlane clip(plane, modelview, proj, water_clip != 0 && LLPipeline::sReflectionRender); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -1649,20 +2012,14 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl camera.disableUserClipPlane(); - if (gSky.mVOSkyp.notNull() && gSky.mVOSkyp->mDrawable.notNull()) - { - // Hack for sky - always visible. - if (hasRenderType(LLPipeline::RENDER_TYPE_SKY)) - { - gSky.mVOSkyp->mDrawable->setVisible(camera); - sCull->pushDrawable(gSky.mVOSkyp->mDrawable); - gSky.updateCull(); - stop_glerror(); - } - } - else + if (hasRenderType(LLPipeline::RENDER_TYPE_SKY) && + gSky.mVOSkyp.notNull() && + gSky.mVOSkyp->mDrawable.notNull()) { - llinfos << "No sky drawable!" << llendl; + gSky.mVOSkyp->mDrawable->setVisible(camera); + sCull->pushDrawable(gSky.mVOSkyp->mDrawable); + gSky.updateCull(); + stop_glerror(); } if (hasRenderType(LLPipeline::RENDER_TYPE_GROUND) && @@ -1714,7 +2071,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) } if (sMinRenderSize > 0.f && - llmax(llmax(group->mBounds[1].mV[0], group->mBounds[1].mV[1]), group->mBounds[1].mV[2]) < sMinRenderSize) + llmax(llmax(group->mBounds[1][0], group->mBounds[1][1]), group->mBounds[1][2]) < sMinRenderSize) { return; } @@ -1758,33 +2115,34 @@ void LLPipeline::markOccluder(LLSpatialGroup* group) void LLPipeline::doOcclusion(LLCamera& camera) { - LLVertexBuffer::unbind(); - - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + if (LLPipeline::sUseOcclusion > 1 && sCull->hasOcclusionGroups()) { - gGL.setColorMask(true, false, false, false); - } - else - { - gGL.setColorMask(false, false); - } - LLGLDisable blend(GL_BLEND); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_TRUE, GL_FALSE); + LLVertexBuffer::unbind(); - LLGLDisable cull(GL_CULL_FACE); - if (LLPipeline::sUseOcclusion > 1) - { + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) + { + gGL.setColorMask(true, false, false, false); + } + else + { + gGL.setColorMask(false, false); + } + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + + LLGLDisable cull(GL_CULL_FACE); + for (LLCullResult::sg_list_t::iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { LLSpatialGroup* group = *iter; group->doOcclusion(&camera); group->clearOcclusionState(LLSpatialGroup::ACTIVE_OCCLUSION); } + + gGL.setColorMask(true, false); } - - gGL.setColorMask(true, false); } BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) @@ -1811,12 +2169,6 @@ void LLPipeline::updateGL() void LLPipeline::rebuildPriorityGroups() { - if(!sAllowRebuildPriorityGroup) - { - return ; - } - sAllowRebuildPriorityGroup = FALSE ; - LLTimer update_timer; LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -1824,8 +2176,9 @@ void LLPipeline::rebuildPriorityGroups() gMeshRepo.notifyLoadedMeshes(); + mGroupQ1Locked = true; // Iterate through all drawables on the priority build queue, - for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -1834,11 +2187,18 @@ void LLPipeline::rebuildPriorityGroups() } mGroupQ1.clear(); + mGroupQ1Locked = false; } void LLPipeline::rebuildGroups() { + if (mGroupQ2.empty()) + { + return; + } + + mGroupQ2Locked = true; // Iterate through some drawables on the non-priority build queue S32 size = (S32) mGroupQ2.size(); S32 min_count = llclamp((S32) ((F32) (size * size)/4096*0.25f), 1, size); @@ -1848,33 +2208,30 @@ void LLPipeline::rebuildGroups() std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); LLSpatialGroup::sg_vector_t::iterator iter; + LLSpatialGroup::sg_vector_t::iterator last_iter = mGroupQ2.begin(); + for (iter = mGroupQ2.begin(); - iter != mGroupQ2.end(); ++iter) + iter != mGroupQ2.end() && count <= min_count; ++iter) { LLSpatialGroup* group = *iter; + last_iter = iter; - if (group->isDead()) + if (!group->isDead()) { - continue; + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } } - group->rebuildGeom(); - - if (group->mSpatialPartition->mRenderByGroup) - { - count++; - } - group->clearState(LLSpatialGroup::IN_BUILD_Q2); - - if (count > min_count) - { - ++iter; - break; - } } - mGroupQ2.erase(mGroupQ2.begin(), iter); + mGroupQ2.erase(mGroupQ2.begin(), ++last_iter); + + mGroupQ2Locked = false; updateMovedList(mMovedBridge); } @@ -1994,7 +2351,7 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; llassert(root); // trying to catch a bad assumption if (root && // // this test may not be needed, see above - root->getVObj()->isAttachment()) + root->getVObj()->isAttachment()) { LLDrawable* rootparent = root->getParent(); if (rootparent) // this IS sometimes NULL @@ -2100,6 +2457,9 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) glClear(GL_DEPTH_BUFFER_BIT); gDepthDirty = TRUE; + LLVector4a offseta; + offseta.load3(offset.mV); + for (LLDrawable::drawable_vector_t::iterator iter = mShiftList.begin(); iter != mShiftList.end(); iter++) { @@ -2108,7 +2468,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) { continue; } - drawablep->shiftPos(offset); + drawablep->shiftPos(offseta); drawablep->clearState(LLDrawable::ON_SHIFT_LIST); } mShiftList.resize(0); @@ -2122,12 +2482,13 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - part->shift(offset); + part->shift(offseta); } } } LLHUDText::shiftAll(offset); + LLHUDNameTag::shiftAll(offset); display_update_camera(); } @@ -2150,11 +2511,36 @@ void LLPipeline::markGLRebuild(LLGLUpdate* glu) } } +void LLPipeline::markPartitionMove(LLDrawable* drawable) +{ + if (!drawable->isState(LLDrawable::PARTITION_MOVE) && + !drawable->getPositionGroup().equals3(LLVector4a::getZero())) + { + drawable->setState(LLDrawable::PARTITION_MOVE); + mPartitionQ.push_back(drawable); + } +} + +void LLPipeline::processPartitionQ() +{ + for (LLDrawable::drawable_list_t::iterator iter = mPartitionQ.begin(); iter != mPartitionQ.end(); ++iter) + { + LLDrawable* drawable = *iter; + if (!drawable->isDead()) + { + drawable->updateBinRadius(); + drawable->movePartition(); + } + drawable->clearState(LLDrawable::PARTITION_MOVE); + } + + mPartitionQ.clear(); +} + void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - //assert_main_thread(); - + if (group && !group->isDead() && group->mSpatialPartition) { if (group->mSpatialPartition->mPartitionType == LLViewerRegion::PARTITION_HUD) @@ -2166,6 +2552,8 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) { if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) { + llassert_always(!mGroupQ1Locked); + mGroupQ1.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q1); @@ -2182,11 +2570,7 @@ void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) } else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) { - //llerrs << "Non-priority updates not yet supported!" << llendl; - if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) - { - llerrs << "WTF?" << llendl; - } + llassert_always(!mGroupQ2Locked); mGroupQ2.push_back(group); group->setState(LLSpatialGroup::IN_BUILD_Q2); @@ -2234,6 +2618,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_TREE, LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_WATER, LLPipeline::END_RENDER_TYPES)) { @@ -2248,7 +2633,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) //LLVertexBuffer::unbind(); grabReferences(result); - llpushcallstacks ; for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2266,7 +2650,42 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - llpushcallstacks ; + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { + LLSpatialGroup* last_group = NULL; + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLCullResult::bridge_list_t::iterator cur_iter = i; + LLSpatialBridge* bridge = *cur_iter; + LLSpatialGroup* group = bridge->getSpatialGroup(); + + if (last_group == NULL) + { + last_group = group; + } + + if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) + { + stateSort(bridge, camera); + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group != group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + + last_group = group; + } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD && + last_group && last_group->changeLOD()) + { + last_group->mLastUpdateDistance = last_group->mDistance; + } + } + for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; @@ -2282,21 +2701,6 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } - llpushcallstacks ; - if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) - { - for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLCullResult::bridge_list_t::iterator cur_iter = i; - LLSpatialBridge* bridge = *cur_iter; - LLSpatialGroup* group = bridge->getSpatialGroup(); - if (!bridge->isDead() && group && !group->isOcclusionState(LLSpatialGroup::OCCLUDED)) - { - stateSort(bridge, camera); - } - } - } - llpushcallstacks ; { LLFastTimer ftm(FTM_STATESORT_DRAWABLE); for (LLCullResult::drawable_list_t::iterator iter = sCull->beginVisibleList(); @@ -2309,14 +2713,12 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } - { LLFastTimer ftm(FTM_CLIENT_COPY); LLVertexBuffer::clientCopy(); } - - postSort(camera); - llpushcallstacks ; + + postSort(camera); } void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) @@ -2329,6 +2731,11 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) LLDrawable* drawablep = *i; stateSort(drawablep, camera); } + + if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) + { //avoid redundant stateSort calls + group->mLastUpdateDistance = group->mDistance; + } } } @@ -2336,7 +2743,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE_STATE_SORT); - if (!sShadowRender && bridge->getSpatialGroup()->changeLOD()) + if (bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2395,21 +2802,17 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) if (LLViewerCamera::sCurCameraID == LLViewerCamera::CAMERA_WORLD) { - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + //if (drawablep->isVisible()) isVisible() check here is redundant, if it wasn't visible, it wouldn't be here { - if (drawablep->isVisible()) + if (!drawablep->isActive()) { - if (!drawablep->isActive()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); - } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } + bool force_update = false; + drawablep->updateDistance(camera, force_update); + } + else if (drawablep->isAvatar()) + { + bool force_update = false; + drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() } } } @@ -2536,6 +2939,42 @@ void renderPhysicalBeacons(LLDrawable* drawablep) } } +void renderMOAPBeacons(LLDrawable* drawablep) +{ + LLViewerObject *vobj = drawablep->getVObj(); + + if(!vobj || vobj->isAvatar()) + return; + + BOOL beacon=FALSE; + U8 tecount=vobj->getNumTEs(); + for(int x=0;x<tecount;x++) + { + if(vobj->getTE(x)->hasMedia()) + { + beacon=TRUE; + break; + } + } + if(beacon==TRUE) + { + if (gPipeline.sRenderBeacons) + { + gObjectList.addDebugBeacon(vobj->getPositionAgent(), "", LLColor4(1.f, 1.f, 1.f, 0.5f), LLColor4(1.f, 1.f, 1.f, 0.5f), gSavedSettings.getS32("DebugBeaconLineWidth")); + } + + if (gPipeline.sRenderHighlight) + { + S32 face_id; + S32 count = drawablep->getNumFaces(); + for (face_id = 0; face_id < count; face_id++) + { + gPipeline.mHighlightFaces.push_back(drawablep->getFace(face_id) ); + } + } + } +} + void renderParticleBeacons(LLDrawable* drawablep) { // Look for attachments, objects, etc. @@ -2586,6 +3025,7 @@ void LLPipeline::postSort(LLCamera& camera) assertInitialized(); + llpushcallstacks ; //rebuild drawable geometry for (LLCullResult::sg_list_t::iterator i = sCull->beginDrawableGroups(); i != sCull->endDrawableGroups(); ++i) { @@ -2596,26 +3036,12 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } } - + llpushcallstacks ; //rebuild groups sCull->assertDrawMapsEmpty(); - /*LLSpatialGroup::sNoDelete = FALSE; - for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) - { - LLSpatialGroup* group = *i; - if (sUseOcclusion && - group->isState(LLSpatialGroup::OCCLUDED)) - { - continue; - } - - group->rebuildGeom(); - } - LLSpatialGroup::sNoDelete = TRUE;*/ - - rebuildPriorityGroups(); + llpushcallstacks ; const S32 bin_count = 1024*8; @@ -2659,8 +3085,10 @@ void LLPipeline::postSort(LLCamera& camera) { if (sMinRenderSize > 0.f) { - LLVector3 bounds = (*k)->mExtents[1]-(*k)->mExtents[0]; - if (llmax(llmax(bounds.mV[0], bounds.mV[1]), bounds.mV[2]) > sMinRenderSize) + LLVector4a bounds; + bounds.setSub((*k)->mExtents[1],(*k)->mExtents[0]); + + if (llmax(llmax(bounds[0], bounds[1]), bounds[2]) > sMinRenderSize) { sCull->pushDrawInfo(j->first, *k); } @@ -2717,7 +3145,7 @@ void LLPipeline::postSort(LLCamera& camera) std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater()); } - + llpushcallstacks ; // only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus if (LLFloaterReg::instanceVisible("beacons") && !sShadowRender) { @@ -2739,6 +3167,11 @@ void LLPipeline::postSort(LLCamera& camera) forAllVisibleDrawables(renderPhysicalBeacons); } + if(sRenderMOAPBeacons) + { + forAllVisibleDrawables(renderMOAPBeacons); + } + if (sRenderParticleBeacons) { forAllVisibleDrawables(renderParticleBeacons); @@ -2765,7 +3198,7 @@ void LLPipeline::postSort(LLCamera& camera) forAllVisibleDrawables(renderSoundHighlights); } } - + llpushcallstacks ; // If managing your telehub, draw beacons at telehub and currently selected spawnpoint. if (LLFloaterTelehub::renderBeacons()) { @@ -2795,6 +3228,7 @@ void LLPipeline::postSort(LLCamera& camera) } //LLSpatialGroup::sNoDelete = FALSE; + llpushcallstacks ; } @@ -2815,7 +3249,7 @@ void render_hud_elements() gGL.color4f(1,1,1,1); if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); gViewerWindow->renderSelections(FALSE, FALSE, FALSE); // For HUD version in render_ui_3d() // Draw the tracking overlays @@ -3029,6 +3463,13 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } } + S32 stack_depth = 0; + + if (gDebugGL) + { + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &stack_depth); + } + /////////////////////////////////////////// // // Sync and verify GL state @@ -3059,7 +3500,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glMatrixMode(GL_MODELVIEW); LLGLSPipeline gls_pipeline; - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); @@ -3153,19 +3594,10 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) } poolp->endRenderPass(i); LLVertexBuffer::unbind(); - if (gDebugGL || gDebugPipeline) + if (gDebugGL) { - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) - { - if (gDebugSession) - { - ll_fail("GL matrix stack corrupted."); - } - llerrs << "GL matrix stack corrupted!" << llendl; - } - std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); + check_stack_depth(stack_depth); + std::string msg = llformat("pass %d", i); LLGLState::checkStates(msg); LLGLState::checkTextureChannels(msg); LLGLState::checkClientArrays(msg); @@ -3187,11 +3619,11 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) iter1 = iter2; stop_glerror(); } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); - - LLVertexBuffer::unbind(); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); + + LLVertexBuffer::unbind(); + gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); @@ -3234,11 +3666,24 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::unbind(); - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) + { + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + gObjectList.resetObjectBeacons(); + } + else + { + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); + } + } + else { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); + // Make sure particle effects disappear + LLHUDObject::renderAllForTimer(); } LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); @@ -3286,7 +3731,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) } } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); LLVertexBuffer::unbind(); @@ -3375,7 +3820,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLGLEnable cull(GL_CULL_FACE); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); calcNearbyLights(camera); setupHWLights(NULL); @@ -3458,20 +3903,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); - renderHighlights(); - mHighlightFaces.clear(); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); - } - if (occlude) { occlude = FALSE; @@ -3574,6 +4005,59 @@ void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) } } +void LLPipeline::renderPhysicsDisplay() +{ + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + return; + } + + allocatePhysicsBuffer(); + + gGL.flush(); + mPhysicsDisplay.bindTarget(); + glClearColor(0,0,0,1); + gGL.setColorMask(true, true); + mPhysicsDisplay.clear(); + glClearColor(0,0,0,0); + + gGL.setColorMask(true, false); + + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + iter != LLWorld::getInstance()->getRegionList().end(); ++iter) + { + LLViewerRegion* region = *iter; + for (U32 i = 0; i < LLViewerRegion::NUM_PARTITIONS; i++) + { + LLSpatialPartition* part = region->getSpatialPartition(i); + if (part) + { + if (hasRenderType(part->mDrawableType)) + { + part->renderPhysicsShapes(); + } + } + } + } + + for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + glPushMatrix(); + glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderPhysicsShapes(); + glPopMatrix(); + } + } + + + gGL.flush(); + mPhysicsDisplay.flush(); +} + + void LLPipeline::renderDebug() { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -3586,6 +4070,39 @@ void LLPipeline::renderDebug() glLoadMatrixd(gGLModelView); gGL.setColorMask(true, false); + bool hud_only = hasRenderType(LLPipeline::RENDER_TYPE_HUD); + + if (!hud_only && !mDebugBlips.empty()) + { //render debug blips + glPointSize(8.f); + LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); + + gGL.begin(LLRender::POINTS); + for (std::list<DebugBlip>::iterator iter = mDebugBlips.begin(); iter != mDebugBlips.end(); ) + { + DebugBlip& blip = *iter; + + blip.mAge += gFrameIntervalSeconds; + if (blip.mAge > 2.f) + { + mDebugBlips.erase(iter++); + } + else + { + iter++; + } + + blip.mPosition.mV[2] += gFrameIntervalSeconds*2.f; + + gGL.color4fv(blip.mColor.mV); + gGL.vertex3fv(blip.mPosition.mV); + } + gGL.end(); + gGL.flush(); + glPointSize(1.f); + } + + // Debug stuff. for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -3596,7 +4113,8 @@ void LLPipeline::renderDebug() LLSpatialPartition* part = region->getSpatialPartition(i); if (part) { - if (hasRenderType(part->mDrawableType)) + if ( hud_only && (part->mDrawableType == RENDER_TYPE_HUD || part->mDrawableType == RENDER_TYPE_HUD_PARTICLES) || + !hud_only && hasRenderType(part->mDrawableType) ) { part->renderDebug(); } @@ -3604,6 +4122,18 @@ void LLPipeline::renderDebug() } } + for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + { + LLSpatialBridge* bridge = *i; + if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) + { + glPushMatrix(); + glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + bridge->renderDebug(); + glPopMatrix(); + } + } + if (gSavedSettings.getBOOL("DebugShowUploadCost")) { std::set<LLUUID> textures; @@ -3661,20 +4191,10 @@ void LLPipeline::renderDebug() gPipeline.mDebugMeshUploadCost = mesh_cost; } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) - { - LLSpatialBridge* bridge = *i; - if (!bridge->isDead() && hasRenderType(bridge->mDrawableType)) - { - glPushMatrix(); - glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); - bridge->renderDebug(); - glPopMatrix(); - } - } - if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLVertexBuffer::unbind(); + LLGLEnable blend(GL_BLEND); LLGLDepthTest depth(TRUE, FALSE); LLGLDisable cull(GL_CULL_FACE); @@ -3704,7 +4224,7 @@ void LLPipeline::renderDebug() if (i > 3) { //render shadow frusta as volumes if (mShadowFrustPoints[i-4].empty()) - { + { continue; } @@ -3737,22 +4257,22 @@ void LLPipeline::renderDebug() if (i < 4) { - - if (i == 0 || !mShadowFrustPoints[i].empty()) + + //if (i == 0 || !mShadowFrustPoints[i].empty()) { //render visible point cloud gGL.flush(); glPointSize(8.f); gGL.begin(LLRender::POINTS); - + F32* c = col+i*4; gGL.color3fv(c); for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) - { - gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + { + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); - } + } gGL.end(); gGL.flush(); @@ -3779,10 +4299,11 @@ void LLPipeline::renderDebug() gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); gGL.end(); } - } - /*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + /*gGL.flush(); + glLineWidth(16-i*2); + for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3797,7 +4318,9 @@ void LLPipeline::renderDebug() } } } - }*/ + } + gGL.flush(); + glLineWidth(1.f);*/ } } @@ -3837,13 +4360,19 @@ void LLPipeline::renderDebug() if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) { U32 count = 0; - U32 size = mBuildQ2.size(); + U32 size = mGroupQ2.size(); LLColor4 col; + LLVertexBuffer::unbind(); LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); LLGLDepthTest depth(GL_TRUE, GL_FALSE); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + gGL.pushMatrix(); + glLoadMatrixd(gGLModelView); + gGLLastMatrix = NULL; + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) { LLSpatialGroup* group = *iter; @@ -3865,7 +4394,7 @@ void LLPipeline::renderDebug() glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); } - F32 alpha = (F32) (size-count)/size; + F32 alpha = llclamp((F32) (size-count)/size, 0.f, 1.f); LLVector2 c(1.f-alpha, alpha); @@ -3873,7 +4402,7 @@ void LLPipeline::renderDebug() ++count; - col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.5f); group->drawObjectBox(col); if (bridge) @@ -3881,188 +4410,13 @@ void LLPipeline::renderDebug() gGL.popMatrix(); } } - } - - gGL.flush(); -} - -void LLPipeline::renderForSelect(std::set<LLViewerObject*>& objects, BOOL render_transparent, const LLRect& screen_rect) -{ - assertInitialized(); - - gGL.setColorMask(true, false); - gPipeline.resetDrawOrders(); - - LLViewerCamera* camera = LLViewerCamera::getInstance(); - for (std::set<LLViewerObject*>::iterator iter = objects.begin(); iter != objects.end(); ++iter) - { - stateSort((*iter)->mDrawable, *camera); - } - - LLMemType mt(LLMemType::MTYPE_PIPELINE_RENDER_SELECT); - - - - glMatrixMode(GL_MODELVIEW); - - LLGLSDefault gls_default; - LLGLSObjectSelect gls_object_select; - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest gls_depth(GL_TRUE,GL_TRUE); - disableLights(); - - LLVertexBuffer::unbind(); - - //for each drawpool - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - U32 last_type = 0; - - // If we don't do this, we crash something on changing graphics settings - // from Medium -> Low, because we unload all the shaders and the - // draw pools aren't aware. I don't know if this has to be a separate - // loop before actual rendering. JC - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (poolp->isFacePool() && hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (poolp->isFacePool() && hasRenderType(poolp->getType())) - { - LLFacePool* face_pool = (LLFacePool*) poolp; - face_pool->renderForSelect(); - LLVertexBuffer::unbind(); - gGLLastMatrix = NULL; - glLoadMatrixd(gGLModelView); - - if (poolp->getType() != last_type) - { - last_type = poolp->getType(); - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); - } - } - } - - LLGLEnable alpha_test(GL_ALPHA_TEST); - if (render_transparent) - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER_EQUAL, 0.f); - } - else - { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.2f); - } - - gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_VERT_COLOR); - gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA); - - U32 prim_mask = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0; - for (std::set<LLViewerObject*>::iterator i = objects.begin(); i != objects.end(); ++i) - { - LLViewerObject* vobj = *i; - LLDrawable* drawable = vobj->mDrawable; - if (vobj->isDead() || - vobj->isHUDAttachment() || - (LLSelectMgr::getInstance()->mHideSelectedObjects && vobj->isSelected()) || - drawable->isDead() || - !hasRenderType(drawable->getRenderType())) - { - continue; - } - - for (S32 j = 0; j < drawable->getNumFaces(); ++j) - { - LLFace* facep = drawable->getFace(j); - if (!facep->getPool()) - { - facep->renderForSelect(prim_mask); - } - } + gGL.popMatrix(); } - // pick HUD objects - if (isAgentAvatarValid() && sShowHUDAttachments) - { - glh::matrix4f save_proj(glh_get_current_projection()); - glh::matrix4f save_model(glh_get_current_modelview()); - - setup_hud_matrices(screen_rect); - for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); - iter != gAgentAvatarp->mAttachmentPoints.end(); ) - { - LLVOAvatar::attachment_map_t::iterator curiter = iter++; - LLViewerJointAttachment* attachment = curiter->second; - if (attachment->getIsHUDAttachment()) - { - for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); - attachment_iter != attachment->mAttachedObjects.end(); - ++attachment_iter) - { - if (LLViewerObject* attached_object = (*attachment_iter)) - { - LLDrawable* drawable = attached_object->mDrawable; - if (drawable->isDead()) - { - continue; - } - - for (S32 j = 0; j < drawable->getNumFaces(); ++j) - { - LLFace* facep = drawable->getFace(j); - if (!facep->getPool()) - { - facep->renderForSelect(prim_mask); - } - } - - //render child faces - LLViewerObject::const_child_list_t& child_list = attached_object->getChildren(); - for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); - iter != child_list.end(); iter++) - { - LLViewerObject* child = *iter; - LLDrawable* child_drawable = child->mDrawable; - for (S32 l = 0; l < child_drawable->getNumFaces(); ++l) - { - LLFace* facep = child_drawable->getFace(l); - if (!facep->getPool()) - { - facep->renderForSelect(prim_mask); - } - } - } - } - } - } - } - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(save_proj.m); - glh_set_current_projection(save_proj); - - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(save_model.m); - glh_set_current_modelview(save_model); - - - } + gGL.flush(); - gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); - - LLVertexBuffer::unbind(); - - gGL.setColorMask(true, true); + gPipeline.renderPhysicsDisplay(); } void LLPipeline::rebuildPools() @@ -4394,16 +4748,19 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) light_pos.normalize(); + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = diffuse; - glLightfv(GL_LIGHT1, GL_DIFFUSE, diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_POSITION, light_pos.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + light->setDiffuse(diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setPosition(light_pos); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { @@ -4434,22 +4791,28 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) backlight_diffuse *= backlight_mag / max_component; mHWLightColors[1] = backlight_diffuse; - glLightfv(GL_LIGHT1, GL_POSITION, backlight_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT1, GL_DIFFUSE, backlight_diffuse.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT1, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(1); + + light->setPosition(backlight_pos); + light->setDiffuse(backlight_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } else { + LLLightState* light = gGL.getLight(1); + mHWLightColors[1] = LLColor4::black; - glLightfv(GL_LIGHT1, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT1, GL_SPECULAR, LLColor4::black.mV); + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); } } @@ -4468,7 +4831,7 @@ static F32 calc_light_dist(LLVOVolume* light, const LLVector3& cam_pos, F32 max_ { return max_dist; } - F32 dist = fsqrtf(dist2); + F32 dist = (F32) sqrt(dist2); dist *= 1.f / inten; dist -= radius; if (selected) @@ -4630,15 +4993,17 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos(mSunDir, 0.0f); LLColor4 light_diffuse = mSunDiffuse; mHWLightColors[0] = light_diffuse; - glLightfv(GL_LIGHT0, GL_POSITION, light_pos.mV); // this is just sun/moon direction - glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse.mV); - glLightfv(GL_LIGHT0, GL_AMBIENT, LLColor4::black.mV); - glLightfv(GL_LIGHT0, GL_SPECULAR, LLColor4::black.mV); - glLightf (GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.0f); - glLightf (GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT0, GL_SPOT_CUTOFF, 180.0f); + + LLLightState* light = gGL.getLight(0); + light->setPosition(light_pos); + light->setDiffuse(light_diffuse); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setConstantAttenuation(1.f); + light->setLinearAttenuation(0.f); + light->setQuadraticAttenuation(0.f); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } // Light 1 = Backlight (for avatars) @@ -4696,35 +5061,45 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - if (light->isLightSpotlight()) // directional (spot-)light + LLLightState* light_state = gGL.getLight(cur_light); + + light_state->setPosition(light_pos_gl); + light_state->setDiffuse(light_color); + light_state->setAmbient(LLColor4::black); + light_state->setConstantAttenuation(0.f); + if (sRenderDeferred) + { + light_state->setLinearAttenuation(light_radius*1.5f); + light_state->setQuadraticAttenuation(light->getLightFalloff()*0.5f+1.f); + } + else + { + light_state->setLinearAttenuation(linatten); + light_state->setQuadraticAttenuation(0.f); + } + + if (light->isLightSpotlight() // directional (spot-)light + && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on { LLVector3 spotparams = light->getSpotLightParams(); LLQuaternion quat = light->getRenderRotation(); LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction at_axis *= quat; - //llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; - glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); - glLightf (gllight, GL_SPOT_EXPONENT, 2.0f); // 2.0 = good old dot product ^ 2 - glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere - const float specular[] = {0.f, 0.f, 0.f, 0.f}; - glLightfv(gllight, GL_SPECULAR, specular); + + light_state->setSpotDirection(at_axis); + light_state->setSpotCutoff(90.f); + light_state->setSpotExponent(2.f); + + light_state->setSpecular(LLColor4::black); } else // omnidirectional (point) light { - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); - + light_state->setSpotExponent(0.f); + light_state->setSpotCutoff(180.f); + // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const float specular[] = {0.f, 0.f, 0.f, 1.f}; - glLightfv(gllight, GL_SPECULAR, specular); - //llinfos << "boring light" << llendl; + const LLColor4 specular(0.f, 0.f, 0.f, 1.f); + light_state->setSpecular(specular); } cur_light++; if (cur_light >= 8) @@ -4736,10 +5111,11 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) for ( ; cur_light < 8 ; cur_light++) { mHWLightColors[cur_light] = LLColor4::black; - S32 gllight = GL_LIGHT0+cur_light; - glLightfv(gllight, GL_DIFFUSE, LLColor4::black.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); + LLLightState* light = gGL.getLight(cur_light); + + light->setDiffuse(LLColor4::black); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); } if (gAgentAvatarp && gAgentAvatarp->mSpecialRenderMode == 3) @@ -4752,27 +5128,28 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) F32 light_radius = 16.f; - F32 x = 3.f; + F32 x = 3.f; float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[2] = light_color; - S32 gllight = GL_LIGHT2; - glLightfv(gllight, GL_POSITION, light_pos_gl.mV); - glLightfv(gllight, GL_DIFFUSE, light_color.mV); - glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); - glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + LLLightState* light = gGL.getLight(2); + + light->setPosition(light_pos_gl); + light->setDiffuse(light_color); + light->setAmbient(LLColor4::black); + light->setSpecular(LLColor4::black); + light->setQuadraticAttenuation(0.f); + light->setConstantAttenuation(0.f); + light->setLinearAttenuation(linatten); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); } // Init GL state glDisable(GL_LIGHTING); - for (S32 gllight=GL_LIGHT0; gllight<=GL_LIGHT7; gllight++) + for (S32 i = 0; i < 8; ++i) { - glDisable(gllight); + gGL.getLight(i)->disable(); } mLightMask = 0; } @@ -4797,15 +5174,16 @@ void LLPipeline::enableLights(U32 mask) stop_glerror(); for (S32 i=0; i<8; i++) { + LLLightState* light = gGL.getLight(i); if (mask & (1<<i)) { - glEnable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, mHWLightColors[i].mV); + light->enable(); + light->setDiffuse(mHWLightColors[i]); } else { - glDisable(GL_LIGHT0 + i); - glLightfv(GL_LIGHT0 + i, GL_DIFFUSE, LLColor4::black.mV); + light->disable(); + light->setDiffuse(LLColor4::black); } } stop_glerror(); @@ -4829,7 +5207,6 @@ void LLPipeline::enableLightsStatic() if (mLightingDetail >= 2) { mask |= mLightMovingMask; // Hardware moving lights - glColor4f(0.f, 0.f, 0.f, 1.0f); // no local lighting by default } else { @@ -4843,11 +5220,7 @@ void LLPipeline::enableLightsDynamic() assertInitialized(); U32 mask = 0xff & (~2); // Local lights enableLights(mask); - if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - } - + if (isAgentAvatarValid() && getLightingDetail() <= 0) { if (gAgentAvatarp->mSpecialRenderMode == 0) // normal @@ -4868,6 +5241,65 @@ void LLPipeline::enableLightsAvatar() enableLights(mask); } +void LLPipeline::enableLightsPreview() +{ + disableLights(); + + glEnable(GL_LIGHTING); + LLColor4 ambient = gSavedSettings.getColor4("PreviewAmbientColor"); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambient.mV); + + + LLColor4 diffuse0 = gSavedSettings.getColor4("PreviewDiffuse0"); + LLColor4 specular0 = gSavedSettings.getColor4("PreviewSpecular0"); + LLColor4 diffuse1 = gSavedSettings.getColor4("PreviewDiffuse1"); + LLColor4 specular1 = gSavedSettings.getColor4("PreviewSpecular1"); + LLColor4 diffuse2 = gSavedSettings.getColor4("PreviewDiffuse2"); + LLColor4 specular2 = gSavedSettings.getColor4("PreviewSpecular2"); + + LLVector3 dir0 = gSavedSettings.getVector3("PreviewDirection0"); + LLVector3 dir1 = gSavedSettings.getVector3("PreviewDirection1"); + LLVector3 dir2 = gSavedSettings.getVector3("PreviewDirection2"); + + dir0.normVec(); + dir1.normVec(); + dir2.normVec(); + + LLVector4 light_pos(dir0, 0.0f); + + LLLightState* light = gGL.getLight(0); + + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse0); + light->setAmbient(LLColor4::black); + light->setSpecular(specular0); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir1, 0.f); + + light = gGL.getLight(1); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse1); + light->setAmbient(LLColor4::black); + light->setSpecular(specular1); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); + + light_pos = LLVector4(dir2, 0.f); + light = gGL.getLight(2); + light->enable(); + light->setPosition(light_pos); + light->setDiffuse(diffuse2); + light->setAmbient(LLColor4::black); + light->setSpecular(specular2); + light->setSpotExponent(0.f); + light->setSpotCutoff(180.f); +} + + void LLPipeline::enableLightsAvatarEdit(const LLColor4& color) { U32 mask = 0x2002; // Avatar backlight only, set ambient @@ -4884,16 +5316,11 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color) enableLights(mask); glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); - /*if (mLightingDetail >= 2) - { - glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default - }*/ } void LLPipeline::disableLights() { enableLights(0); // no lighting (full bright) - //glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default } //============================================================================ @@ -5084,6 +5511,10 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light) void LLPipeline::toggleRenderType(U32 type) { gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type]; + if (type == LLPipeline::RENDER_TYPE_WATER) + { + gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER] = !gPipeline.mRenderTypeEnabled[LLPipeline::RENDER_TYPE_VOIDWATER]; + } } //static @@ -5155,6 +5586,18 @@ BOOL LLPipeline::toggleRenderDebugFeatureControl(void* data) return gPipeline.hasRenderDebugFeatureMask(bit); } +void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value) +{ + if (value) + { + gPipeline.mRenderDebugFeatureMask |= bit; + } + else + { + gPipeline.mRenderDebugFeatureMask &= !bit; + } +} + // static void LLPipeline::setRenderScriptedBeacons(BOOL val) { @@ -5192,6 +5635,24 @@ BOOL LLPipeline::getRenderScriptedTouchBeacons(void*) } // static +void LLPipeline::setRenderMOAPBeacons(BOOL val) +{ + sRenderMOAPBeacons = val; +} + +// static +void LLPipeline::toggleRenderMOAPBeacons(void*) +{ + sRenderMOAPBeacons = !sRenderMOAPBeacons; +} + +// static +BOOL LLPipeline::getRenderMOAPBeacons(void*) +{ + return sRenderMOAPBeacons; +} + +// static void LLPipeline::setRenderPhysicalBeacons(BOOL val) { sRenderPhysicalBeacons = val; @@ -5406,7 +5867,8 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, ++iter) { LLVOAvatar* av = (LLVOAvatar*) *iter; - if (av->mNameText.notNull() && av->mNameText->lineSegmentIntersect(start, local_end, position)) + if (av->mNameText.notNull() + && av->mNameText->lineSegmentIntersect(start, local_end, position)) { drawable = av->mDrawable; local_end = position; @@ -5475,7 +5937,6 @@ LLSpatialPartition* LLPipeline::getSpatialPartition(LLViewerObject* vobj) return NULL; } - void LLPipeline::resetVertexBuffers(LLDrawable* drawable) { if (!drawable || drawable->isDead()) @@ -5486,19 +5947,12 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) for (S32 i = 0; i < drawable->getNumFaces(); i++) { LLFace* facep = drawable->getFace(i); - facep->mVertexBuffer = NULL; - facep->mLastVertexBuffer = NULL; + facep->clearVertexBuffer(); } } void LLPipeline::resetVertexBuffers() -{ - sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); - sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); - +{ for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { @@ -5538,8 +5992,16 @@ void LLPipeline::resetVertexBuffers() llwarns << "VBO name pool cleanup failed." << llendl; } - LLVertexBuffer::unbind(); - + LLVertexBuffer::unbind(); + + sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); + LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); + LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); + LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); + LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; + sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); + sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); } @@ -5554,24 +6016,6 @@ void LLPipeline::renderObjects(U32 type, U32 mask, BOOL texture) gGLLastMatrix = NULL; } -void LLPipeline::setUseVBO(BOOL use_vbo) -{ - if (use_vbo != LLVertexBuffer::sEnableVBOs) - { - if (use_vbo) - { - llinfos << "Enabling VBO." << llendl; - } - else - { - llinfos << "Disabling VBO." << llendl; - } - - resetVertexBuffers(); - LLVertexBuffer::initClass(use_vbo); - } -} - void apply_cube_face_rotation(U32 face) { switch (face) @@ -5603,21 +6047,21 @@ void apply_cube_face_rotation(U32 face) void validate_framebuffer_object() { GLenum status; - status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + status = glCheckFramebufferStatus(GL_FRAMEBUFFER_EXT); switch(status) { - case GL_FRAMEBUFFER_COMPLETE_EXT: + case GL_FRAMEBUFFER_COMPLETE: //framebuffer OK, no error. break; - case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Dimensions." << llendl; + llerrs << "Framebuffer Incomplete Missing Attachment." << llendl; break; - case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: // frame buffer not OK: probably means unsupported depth buffer format llerrs << "Framebuffer Incomplete Attachment." << llendl; break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + case GL_FRAMEBUFFER_UNSUPPORTED: /* choose different formats */ llerrs << "Framebuffer unsupported." << llendl; break; @@ -5638,7 +6082,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) { LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); if (!(gPipeline.canUseVertexShaders() && - sRenderGlow)) + sRenderGlow) || + (!sRenderDeferred && hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES))) { return; } @@ -5665,8 +6110,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) tc2 /= (F32) res_mod; } - gGL.setColorMask(true, true); - LLFastTimer ftm(FTM_RENDER_BLOOM); gGL.color4f(1,1,1,1); LLGLDepthTest depth(GL_FALSE); @@ -5686,60 +6129,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.setColorMask(true, true); glClearColor(0,0,0,0); - - if (for_snapshot) - { - gGL.getTexUnit(0)->bind(&mGlow[1]); - { - //LLGLEnable stencil(GL_STENCIL_TEST); - //glStencilFunc(GL_NOTEQUAL, 255, 0xFFFFFFFF); - //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - //LLGLDisable blend(GL_BLEND); - - // If the snapshot is constructed from tiles, calculate which - // tile we're in. - const S32 num_horizontal_tiles = llceil(zoom_factor); - const LLVector2 tile(subfield % num_horizontal_tiles, - (S32)(subfield / num_horizontal_tiles)); - llassert(zoom_factor > 0.0); // Non-zero, non-negative. - const F32 tile_size = 1.0/zoom_factor; - - tc1 = tile*tile_size; // Top left texture coordinates - tc2 = (tile+LLVector2(1,1))*tile_size; // Bottom right texture coordinates - - LLGLEnable blend(GL_BLEND); - gGL.setSceneBlendType(LLRender::BT_ADD); - - - gGL.begin(LLRender::TRIANGLE_STRIP); - gGL.color4f(1,1,1,1); - gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); - gGL.vertex2f(-1,-1); - - gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); - gGL.vertex2f(-1,1); - - gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); - gGL.vertex2f(1,-1); - - gGL.texCoord2f(tc2.mV[0], tc2.mV[1]); - gGL.vertex2f(1,1); - - gGL.end(); - - gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); - } - - gGL.flush(); - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - - return; - } - + { { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); @@ -5763,11 +6153,8 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->disable(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); - gGL.getTexUnit(0)->bind(&mScreen); - + mScreen.bindTexture(0, 0); + gGL.color4f(1,1,1,1); gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); gGL.begin(LLRender::TRIANGLE_STRIP); @@ -5782,7 +6169,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.end(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + gGL.getTexUnit(0)->unbind(mScreen.getUsage()); mGlow[2].flush(); } @@ -5810,7 +6197,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) for (S32 i = 0; i < kernel; i++) { - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); mGlow[i%2].bindTarget(); @@ -5855,7 +6241,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) if (LLRenderTarget::sUseFBO) { LLFastTimer ftm(FTM_RENDER_BLOOM_FBO); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glBindFramebuffer(GL_FRAMEBUFFER, 0); } gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; @@ -5871,16 +6257,148 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) LLVertexBuffer::unbind(); - if (LLPipeline::sRenderDeferred && LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + if (LLPipeline::sRenderDeferred) { + bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater(); + + LLGLSLShader* shader = &gDeferredPostProgram; + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) + { + shader = &gDeferredGIFinalProgram; + dof_enabled = false; + } + else if (!dof_enabled || LLToolMgr::getInstance()->inBuildMode() || !gSavedSettings.getBOOL("RenderDepthOfField")) + { //squish focal length when in build mode (or if DoF is disabled) so DoF doesn't make editing objects difficult + shader = &gDeferredPostNoDoFProgram; + dof_enabled = false; + } + + LLGLDisable blend(GL_BLEND); - bindDeferredShader(gDeferredGIFinalProgram); + bindDeferredShader(*shader); + + if (dof_enabled) + { + //depth of field focal plane calculations + + static F32 current_distance = 16.f; + static F32 start_distance = 16.f; + static F32 transition_time = 1.f; + + LLVector3 focus_point; + + LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); + if (obj && obj->mDrawable && obj->isSelected()) + { //focus on selected media object + S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); + if (obj && obj->mDrawable) + { + LLFace* face = obj->mDrawable->getFace(face_idx); + if (face) + { + focus_point = face->getPositionAgent(); + } + } + } + + if (focus_point.isExactlyZero()) + { + if (LLViewerJoystick::getInstance()->getOverrideCamera()) + { //focus on point under cursor + focus_point = gDebugRaycastIntersection; + } + else if (gAgentCamera.cameraMouselook()) + { //focus on point under mouselook crosshairs + gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, + NULL, + &focus_point); + } + else + { + LLViewerObject* obj = gAgentCamera.getFocusObject(); + if (obj) + { //focus on alt-zoom target + focus_point = LLVector3(gAgentCamera.getFocusGlobal()-gAgent.getRegion()->getOriginGlobal()); + } + else + { //focus on your avatar + focus_point = gAgent.getPositionAgent(); + } + } + } + + LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); + F32 target_distance = 16.f; + if (!focus_point.isExactlyZero()) + { + target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); + } + + if (transition_time >= 1.f && + fabsf(current_distance-target_distance)/current_distance > 0.01f) + { //large shift happened, interpolate smoothly to new target distance + transition_time = 0.f; + start_distance = current_distance; + } + else if (transition_time < 1.f) + { //currently in a transition, continue interpolating + transition_time += 1.f/gSavedSettings.getF32("CameraFocusTransitionTime")*gFrameIntervalSeconds; + transition_time = llmin(transition_time, 1.f); + + F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; + current_distance = start_distance + (target_distance-start_distance)*t; + } + else + { //small or no change, just snap to target distance + current_distance = target_distance; + } - S32 channel = gDeferredGIFinalProgram.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + //convert to mm + F32 subject_distance = current_distance*1000.f; + F32 fnumber = gSavedSettings.getF32("CameraFNumber"); + F32 default_focal_length = gSavedSettings.getF32("CameraFocalLength"); + + F32 fov = LLViewerCamera::getInstance()->getView(); + + const F32 default_fov = gSavedSettings.getF32("CameraFieldOfView") * F_PI/180.f; + //const F32 default_aspect_ratio = gSavedSettings.getF32("CameraAspectRatio"); + + //F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); + + F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); + //F32 dh = 2.f*default_focal_length * tanf(default_fov*default_aspect_ratio/2.f); + + F32 focal_length = dv/(2*tanf(fov/2.f)); + + //F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); + + // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) + // where N = fnumber + // s2 = dot distance + // s1 = subject distance + // f = focal length + // + + F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); + blur_constant /= 1000.f; //convert to meters for shader + F32 magnification = focal_length/(subject_distance-focal_length); + + shader->uniform1f("focal_distance", -subject_distance/1000.f); + shader->uniform1f("blur_constant", blur_constant); + shader->uniform1f("tan_pixel_angle", tanf(1.f/LLDrawable::sCurPixelAngle)); + shader->uniform1f("magnification", magnification); + } + + S32 channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); if (channel > -1) { mScreen.bindTexture(0, channel); } + //channel = shader->enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + //if (channel > -1) + //{ + //gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + //} gGL.begin(LLRender::TRIANGLE_STRIP); gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); @@ -5894,11 +6412,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.end(); - unbindDeferredShader(gDeferredGIFinalProgram); + unbindDeferredShader(*shader); } else { - if (res_mod > 1) { tc2 /= (F32) res_mod; @@ -5946,7 +6463,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.getTexUnit(1)->bind(&mScreen); gGL.getTexUnit(1)->activate(); - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); buff->setBuffer(mask); buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); @@ -5956,16 +6473,43 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + } - if (LLRenderTarget::sUseFBO) - { //copy depth buffer from mScreen to framebuffer - LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), - 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); - } + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - gGL.setSceneBlendType(LLRender::BT_ALPHA); + + if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) + { + gGL.setColorMask(true, false); + + LLVector2 tc1(0,0); + LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, + (F32) gViewerWindow->getWorldViewHeightRaw()*2); + + LLGLEnable blend(GL_BLEND); + gGL.color4f(1,1,1,0.75f); + + gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); + gGL.vertex2f(3,-1); + + gGL.end(); + gGL.flush(); + } + glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); @@ -5989,25 +6533,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen noise_map = mNoiseMap; } - LLGLState::checkTextureChannels(); - shader.bind(); S32 channel = 0; - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); @@ -6130,22 +6672,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); } } - - /*channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) - { - mDeferredScreen.bindTexture(3, channel); - }*/ + stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredDepth.getUsage()); if (channel > -1) { gGL.getTexUnit(channel)->bind(&mDeferredDepth, TRUE); - gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); stop_glerror(); - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); - glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + //glTexParameteri(LLTexUnit::getInternalType(mDeferredDepth.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); stop_glerror(); @@ -6174,7 +6710,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen stop_glerror(); - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[light_index].getUsage()); if (channel > -1) { mDeferredLight[light_index].bindTexture(0, channel); @@ -6348,6 +6884,7 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen shader.uniform2f("proj_shadow_res", mShadow[4].getWidth(), mShadow[4].getHeight()); shader.uniform1f("depth_cutoff", gSavedSettings.getF32("RenderEdgeDepthCutoff")); shader.uniform1f("norm_cutoff", gSavedSettings.getF32("RenderEdgeNormCutoff")); + if (shader.getUniformLocation("norm_mat") >= 0) { @@ -6385,7 +6922,7 @@ void LLPipeline::renderDeferredLighting() 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); } - LLGLEnable multisample(GL_MULTISAMPLE_ARB); + LLGLEnable multisample(gSavedSettings.getU32("RenderFSAASamples") > 0 ? GL_MULTISAMPLE_ARB : 0); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) { @@ -6393,9 +6930,9 @@ void LLPipeline::renderDeferredLighting() } //ati doesn't seem to love actually using the stencil buffer on FBO's - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + LLGLDisable stencil(GL_STENCIL_TEST); + //glStencilFunc(GL_EQUAL, 1, 0xFFFFFFFF); + //glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); @@ -6430,10 +6967,9 @@ void LLPipeline::renderDeferredLighting() glPushMatrix(); glLoadIdentity(); - mDeferredLight[0].bindTarget(); - if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) { + mDeferredLight[0].bindTarget(); { //paint shadow/SSAO light map (direct lighting lightmap) LLFastTimer ftm(FTM_SUN_SHADOW); bindDeferredShader(gDeferredSunProgram, 0); @@ -6474,20 +7010,13 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSunProgram); } + mDeferredLight[0].flush(); } - else - { - glClearColor(1,1,1,1); - mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); - glClearColor(0,0,0,0); - } - - mDeferredLight[0].flush(); - + { //global illumination specific block (still experimental) if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && - gSavedSettings.getBOOL("RenderDeferredGI")) - { + gSavedSettings.getBOOL("RenderDeferredGI")) + { LLFastTimer ftm(FTM_EDGE_DETECTION); //generate edge map LLGLDisable blend(GL_BLEND); @@ -6526,7 +7055,7 @@ void LLPipeline::renderDeferredLighting() mLuminanceMap.flush(); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); - glGenerateMipmapEXT(GL_TEXTURE_2D); + glGenerateMipmap(GL_TEXTURE_2D); } } @@ -6620,7 +7149,6 @@ void LLPipeline::renderDeferredLighting() gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); @@ -6666,11 +7194,15 @@ void LLPipeline::renderDeferredLighting() if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) { mDeferredLight[1].bindTarget(); - mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + // clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); + mScreen.clear(GL_COLOR_BUFFER_BIT); } else { mScreen.bindTarget(); + // clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky + glClearColor(0,0,0,0); mScreen.clear(GL_COLOR_BUFFER_BIT); } @@ -6719,10 +7251,8 @@ void LLPipeline::renderDeferredLighting() gPipeline.popRenderTypeMask(); } - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); - - + BOOL render_local = gSavedSettings.getBOOL("RenderLocalLights"); + if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2) { mDeferredLight[1].flush(); @@ -6730,7 +7260,7 @@ void LLPipeline::renderDeferredLighting() mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); } - if (render_local || render_fullscreen) + if (render_local) { gGL.setSceneBlendType(LLRender::BT_ADD); std::list<LLVector4> fullscreen_lights; @@ -6744,10 +7274,11 @@ void LLPipeline::renderDeferredLighting() std::list<LLVector4> light_colors; + LLVertexBuffer::unbind(); + F32 v[24]; glVertexPointer(3, GL_FLOAT, 0, v); - BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); - + { bindDeferredShader(gDeferredLightProgram); LLGLDepthTest depth(GL_TRUE, GL_FALSE); @@ -6770,8 +7301,9 @@ void LLPipeline::renderDeferredLighting() } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; LLColor3 col = volume->getLightColor(); @@ -6787,7 +7319,9 @@ void LLPipeline::renderDeferredLighting() continue; } - if (camera->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + LLVector4a sa; + sa.splat(s); + if (camera->AABBInFrustumNoFarClip(center, sa) == 0) { continue; } @@ -6831,11 +7365,11 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); stop_glerror(); } } - else if (render_fullscreen) + else { if (volume->isLightSpotlight()) { @@ -6865,8 +7399,9 @@ void LLPipeline::renderDeferredLighting() LLVOVolume* volume = drawablep->getVOVolume(); - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; + LLVector4a center; + center.load3(drawablep->getPositionAgent().mV); + const F32* c = center.getF32ptr(); F32 s = volume->getLightRadius()*1.5f; sVisibleLightCount++; @@ -6896,7 +7431,7 @@ void LLPipeline::renderDeferredLighting() glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawRangeElements(GL_TRIANGLE_FAN, 0, 7, 8, - GL_UNSIGNED_BYTE, get_box_fan_indices(camera, center)); + GL_UNSIGNED_BYTE, get_box_fan_indices_ptr(camera, center)); } gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); unbindDeferredShader(gDeferredSpotLightProgram); @@ -6938,9 +7473,7 @@ void LLPipeline::renderDeferredLighting() if (count == max_count || fullscreen_lights.empty()) { gDeferredMultiLightProgram.uniform1i("light_count", count); - gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); - gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); gDeferredMultiLightProgram.uniform1f("far_z", far_z); far_z = 0.f; @@ -7201,33 +7734,41 @@ void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) LLViewerTexture* img = volume->getLightTexture(); + if (img == NULL) + { + img = LLViewerFetchedTexture::sWhiteImagep; + } + S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); - if (channel > -1 && img) + if (channel > -1) { - gGL.getTexUnit(channel)->bind(img); + if (img) + { + gGL.getTexUnit(channel)->bind(img); - F32 lod_range = logf(img->getWidth())/logf(2.f); + F32 lod_range = logf(img->getWidth())/logf(2.f); - shader.uniform1f("proj_focus", focus); - shader.uniform1f("proj_lod", lod_range); - shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + shader.uniform1f("proj_focus", focus); + shader.uniform1f("proj_lod", lod_range); + shader.uniform1f("proj_ambient_lod", llclamp((proj_range-focus)/proj_range*lod_range, 0.f, 1.f)); + } } + } void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { stop_glerror(); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, mDeferredScreen.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, mDeferredLight[0].getUsage()); shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); - shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_EDGE, mEdgeMap.getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, mDeferredLight[1].getUsage()); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, mDeferredLight[2].getUsage()); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIP); @@ -7274,8 +7815,6 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.getTexUnit(0)->activate(); shader.unbind(); - - LLGLState::checkTextureChannels(); } inline float sgn(float a) @@ -7290,12 +7829,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate) { BOOL skip_avatar_update = FALSE; - if (gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) + if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK) { skip_avatar_update = TRUE; } - llpushcallstacks ; if (!skip_avatar_update) { gAgentAvatarp->updateAttachmentVisibility(CAMERA_MODE_THIRD_PERSON); @@ -7309,14 +7847,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLCamera camera = camera_in; camera.setFar(camera.getFar()*0.87654321f); LLPipeline::sReflectionRender = TRUE; - S32 occlusion = LLPipeline::sUseOcclusion; - - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; - - LLPipeline::sUseOcclusion = llmin(occlusion, 1); gPipeline.pushRenderTypeMask(); - + glh::matrix4f projection = glh_get_current_projection(); glh::matrix4f mat; @@ -7349,22 +7882,27 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) if (!LLViewerCamera::getInstance()->cameraUnderWater()) { //generate planar reflection map + + //disable occlusion culling for reflection map for now + S32 occlusion = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 0; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); glClearColor(0,0,0,0); mWaterRef.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0; gGL.setColorMask(true, true); mWaterRef.clear(); gGL.setColorMask(true, false); mWaterRef.getViewport(gGLViewport); - + stop_glerror(); glPushMatrix(); mat.set_scale(glh::vec3f(1,1,-1)); mat.set_translate(glh::vec3f(0,0,height*2.f)); - + glh::matrix4f current = glh_get_current_modelview(); mat = current * mat; @@ -7384,35 +7922,34 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glCullFace(GL_FRONT); static LLCullResult ref_result; - + if (LLDrawPoolWater::sNeedsDistortionUpdate) { //initial sky pass (no user clip plane) { //mask out everything but the sky gPipeline.pushRenderTypeMask(); gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_WL_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); + static LLCullResult result; updateCull(camera, result); - llpushcallstacks ; stateSort(camera, result); - andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::RENDER_TYPE_WL_SKY, - LLPipeline::END_RENDER_TYPES); renderGeom(camera, TRUE); + gPipeline.popRenderTypeMask(); } gPipeline.pushRenderTypeMask(); - + clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, - LLPipeline::RENDER_TYPE_GROUND, - LLPipeline::RENDER_TYPE_SKY, - LLPipeline::RENDER_TYPE_CLOUDS, - LLPipeline::END_RENDER_TYPES); + LLPipeline::RENDER_TYPE_VOIDWATER, + LLPipeline::RENDER_TYPE_GROUND, + LLPipeline::RENDER_TYPE_SKY, + LLPipeline::RENDER_TYPE_CLOUDS, + LLPipeline::END_RENDER_TYPES); S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); if (detail > 0) @@ -7432,11 +7969,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mat, projection); LLGLDisable cull(GL_CULL_FACE); - updateCull(camera, ref_result, 1); - llpushcallstacks ; + updateCull(camera, ref_result, -water_clip, &plane); stateSort(camera, ref_result); } - + if (LLDrawPoolWater::sNeedsDistortionUpdate) { if (gSavedSettings.getS32("RenderReflectionDetail") > 0) @@ -7445,7 +7981,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLUserClipPlane clip_plane(plane, mat, projection); renderGeom(camera); } - } + } gPipeline.popRenderTypeMask(); } @@ -7453,6 +7989,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) glPopMatrix(); mWaterRef.flush(); glh_set_current_modelview(current); + LLPipeline::sUseOcclusion = occlusion; } camera.setOrigin(camera_in.getOrigin()); @@ -7462,6 +7999,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { camera.setFar(camera_in.getFar()); clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_GROUND, END_RENDER_TYPES); stop_glerror(); @@ -7482,16 +8020,18 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLColor4& col = LLDrawPoolWater::sWaterFogColor; glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); mWaterDis.bindTarget(); + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1; mWaterDis.getViewport(gGLViewport); if (!LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsReflectionUpdate) { //clip out geometry on the same side of water as the camera mat = glh_get_current_modelview(); - LLGLUserClipPlane clip_plane(LLPlane(-pnorm, -(pd+pad)), mat, projection); + LLPlane plane(-pnorm, -(pd+pad)); + + LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; - updateCull(camera, result, water_clip); - llpushcallstacks ; + updateCull(camera, result, water_clip, &plane); stateSort(camera, result); gGL.setColorMask(true, true); @@ -7519,8 +8059,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) gPipeline.popRenderTypeMask(); LLDrawPoolWater::sNeedsReflectionUpdate = FALSE; LLDrawPoolWater::sNeedsDistortionUpdate = FALSE; - LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); - LLPipeline::sUseOcclusion = occlusion; + LLPlane npnorm(-pnorm, -pd); + LLViewerCamera::getInstance()->setUserClipPlane(npnorm); LLGLState::checkStates(); LLGLState::checkTextureChannels(); @@ -7530,7 +8070,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) { gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode()); } - llpushcallstacks ; + + LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; } } @@ -7633,14 +8174,14 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera glLoadMatrixf(proj.m); glMatrixMode(GL_MODELVIEW); glPushMatrix(); - glLoadMatrixf(view.m); + glLoadMatrixd(gGLModelView); stop_glerror(); gGLLastMatrix = NULL; { - LLGLDepthTest depth(GL_TRUE); - glClear(GL_DEPTH_BUFFER_BIT); + //LLGLDepthTest depth(GL_TRUE); + //glClear(GL_DEPTH_BUFFER_BIT); } gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); @@ -7653,6 +8194,8 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera //glCullFace(GL_FRONT); + LLVertexBuffer::unbind(); + { LLFastTimer ftm(FTM_SHADOW_SIMPLE); LLGLDisable test(GL_ALPHA_TEST); @@ -7720,14 +8263,13 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } //get set of planes on bounding box - std::vector<LLPlane> bp; - - bp.push_back(LLPlane(min, LLVector3(-1,0,0))); - bp.push_back(LLPlane(min, LLVector3(0,-1,0))); - bp.push_back(LLPlane(min, LLVector3(0,0,-1))); - bp.push_back(LLPlane(max, LLVector3(1,0,0))); - bp.push_back(LLPlane(max, LLVector3(0,1,0))); - bp.push_back(LLPlane(max, LLVector3(0,0,1))); + LLPlane bp[] = { + LLPlane(min, LLVector3(-1,0,0)), + LLPlane(min, LLVector3(0,-1,0)), + LLPlane(min, LLVector3(0,0,-1)), + LLPlane(max, LLVector3(1,0,0)), + LLPlane(max, LLVector3(0,1,0)), + LLPlane(max, LLVector3(0,0,1))}; //potential points std::vector<LLVector3> pp; @@ -7751,7 +8293,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector //bounding box line segments U32 bs[] = - { + { 0,1, 1,3, 3,2, @@ -7775,7 +8317,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLPlane& cp = camera.getAgentPlane(j); const LLVector3& v1 = pp[bs[i*2+0]]; const LLVector3& v2 = pp[bs[i*2+1]]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7791,7 +8334,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } } } - + //camera frustum line segments const U32 fs[] = { @@ -7804,7 +8347,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector 5,6, 6,7, 7,4, - + 0,4, 1,5, 2,6, @@ -7813,7 +8356,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector LLVector3 center = (max+min)*0.5f; LLVector3 size = (max-min)*0.5f; - + for (U32 i = 0; i < 12; i++) { for (U32 j = 0; j < 6; ++j) @@ -7821,7 +8364,8 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector const LLVector3& v1 = pp[fs[i*2+0]+8]; const LLVector3& v2 = pp[fs[i*2+1]+8]; const LLPlane& cp = bp[j]; - const LLVector3 n(cp.mV); + LLVector3 n; + cp.getVector3(n); LLVector3 line = v1-v2; @@ -7837,16 +8381,16 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector } } } - + LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), max+LLVector3(0.05f,0.05f,0.05f) }; for (U32 i = 0; i < pp.size(); ++i) { bool found = true; - - const F32* p = pp[i].mV; + const F32* p = pp[i].mV; + for (U32 j = 0; j < 3; ++j) { if (p[j] < ext[0].mV[j] || @@ -7856,24 +8400,24 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector break; } } - + for (U32 j = 0; j < 6; ++j) { const LLPlane& cp = camera.getAgentPlane(j); F32 dist = cp.dist(pp[i]); if (dist > 0.05f) //point is above some plane, not contained - { + { found = false; break; - } - } + } + } - if (found) - { + if (found) + { fp.push_back(pp[i]); } } - + if (fp.empty()) { return FALSE; @@ -7980,6 +8524,7 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L LLPipeline::RENDER_TYPE_TREE, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_PASS_SIMPLE, @@ -8163,6 +8708,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLPipeline::RENDER_TYPE_TREE, LLPipeline::RENDER_TYPE_TERRAIN, LLPipeline::RENDER_TYPE_WATER, + LLPipeline::RENDER_TYPE_VOIDWATER, LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, LLPipeline::RENDER_TYPE_PASS_SIMPLE, LLPipeline::RENDER_TYPE_PASS_BUMP, @@ -8280,7 +8826,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) near_clip = -max.mV[2]; F32 far_clip = -min.mV[2]*2.f; - far_clip = llmin(far_clip, 128.f); + //far_clip = llmin(far_clip, 128.f); far_clip = llmin(far_clip, camera.getFar()); F32 range = far_clip-near_clip; @@ -8570,11 +9116,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) fovx = acos(fovx); fovz = acos(fovz); - if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) - { - // llerrs << "WTF?" << llendl; - } - mShadowFOV.mV[j] = cutoff; } @@ -8630,7 +9171,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } - shadow_cam.setFar(128.f); + //shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); shadow_cam.setOrigin(0,0,0); @@ -8668,7 +9209,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[j].bindTarget(); mShadow[j].getViewport(gGLViewport); - + mShadow[j].clear(); + { static LLCullResult result[4]; @@ -8685,14 +9227,12 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } - + //hack to disable projector shadows - static bool clear = true; bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; - + if (gen_shadow) { - clear = true; F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); //update shadow targets @@ -8723,7 +9263,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } } - + for (S32 i = 0; i < 2; i++) { glh_set_current_modelview(saved_view); @@ -8811,6 +9351,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadow[i+4].bindTarget(); mShadow[i+4].getViewport(gGLViewport); + mShadow[i+4].clear(); static LLCullResult result[2]; @@ -8822,19 +9363,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } else - { - if (clear) - { - clear = false; - for (U32 i = 4; i < 6; i++) - { - mShadow[i].bindTarget(); - mShadow[i].clear(); - mShadow[i].flush(); - } - } + { //no spotlight shadows + mShadowSpotLight[0] = mShadowSpotLight[1] = NULL; } + if (!gSavedSettings.getBOOL("CameraOffset")) { glh_set_current_modelview(saved_view); @@ -8952,7 +9485,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) stateSort(*LLViewerCamera::getInstance(), result); - const LLVector3* ext = avatar->mDrawable->getSpatialExtents(); + const LLVector4a* ext = avatar->mDrawable->getSpatialExtents(); LLVector3 pos(avatar->getRenderPosition()+avatar->getImpostorOffset()); LLCamera camera = *viewer_camera; @@ -8961,25 +9494,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) LLVector2 tdim; - LLVector3 half_height = (ext[1]-ext[0])*0.5f; - LLVector3 left = camera.getLeftAxis(); - left *= left; - left.normalize(); + LLVector4a half_height; + half_height.setSub(ext[1], ext[0]); + half_height.mul(0.5f); + + LLVector4a left; + left.load3(camera.getLeftAxis().mV); + left.mul(left); + left.normalize3fast(); - LLVector3 up = camera.getUpAxis(); - up *= up; - up.normalize(); + LLVector4a up; + up.load3(camera.getUpAxis().mV); + up.mul(up); + up.normalize3fast(); - tdim.mV[0] = fabsf(half_height * left); - tdim.mV[1] = fabsf(half_height * up); + tdim.mV[0] = fabsf(half_height.dot3(left).getF32()); + tdim.mV[1] = fabsf(half_height.dot3(up).getF32()); glMatrixMode(GL_PROJECTION); glPushMatrix(); - //glh::matrix4f ortho = gl_ortho(-tdim.mV[0], tdim.mV[0], -tdim.mV[1], tdim.mV[1], 1.0, 256.0); + F32 distance = (pos-camera.getOrigin()).length(); F32 fov = atanf(tdim.mV[1]/distance)*2.f*RAD_TO_DEG; - F32 aspect = tdim.mV[0]/tdim.mV[1]; //128.f/256.f; + F32 aspect = tdim.mV[0]/tdim.mV[1]; glh::matrix4f persp = gl_perspective(fov, aspect, 1.f, 256.f); glh_set_current_projection(persp); glLoadMatrixf(persp.m); @@ -8996,9 +9534,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) glClearColor(0.0f,0.0f,0.0f,0.0f); gGL.setColorMask(true, true); - glStencilMask(0xFFFFFFFF); - glClearStencil(0); - + // get the number of pixels per angle F32 pa = gViewerWindow->getWindowHeightRaw() / (RAD_TO_DEG * viewer_camera->getView()); @@ -9009,7 +9545,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (!avatar->mImpostor.isComplete() || resX != avatar->mImpostor.getWidth() || resY != avatar->mImpostor.getHeight()) { - avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,TRUE); + avatar->mImpostor.allocate(resX,resY,GL_RGBA,TRUE,FALSE); if (LLPipeline::sRenderDeferred) { @@ -9021,43 +9557,30 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } - LLGLEnable stencil(GL_STENCIL_TEST); - glStencilMask(0xFFFFFFFF); - glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFF); - glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + avatar->mImpostor.bindTarget(); - { - LLGLEnable scissor(GL_SCISSOR_TEST); - glScissor(0, 0, resX, resY); - avatar->mImpostor.bindTarget(); - avatar->mImpostor.clear(); - } - if (LLPipeline::sRenderDeferred) { - stop_glerror(); + avatar->mImpostor.clear(); renderGeomDeferred(camera); renderGeomPostDeferred(camera); } else { + LLGLEnable scissor(GL_SCISSOR_TEST); + glScissor(0, 0, resX, resY); + avatar->mImpostor.clear(); renderGeom(camera); } - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - glStencilFunc(GL_EQUAL, 1, 0xFFFFFF); - - { //create alpha mask based on stencil buffer (grey out if muted) - LLVector3 left = camera.getLeftAxis()*tdim.mV[0]*2.f; - LLVector3 up = camera.getUpAxis()*tdim.mV[1]*2.f; - + { //create alpha mask based on depth buffer (grey out if muted) if (LLPipeline::sRenderDeferred) { - GLuint buff = GL_COLOR_ATTACHMENT0_EXT; + GLuint buff = GL_COLOR_ATTACHMENT0; glDrawBuffersARB(1, &buff); } - LLGLEnable blend(muted ? 0 : GL_BLEND); + LLGLDisable blend(GL_BLEND); if (muted) { @@ -9068,25 +9591,34 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) gGL.setColorMask(false, true); } - gGL.setSceneBlendType(LLRender::BT_ADD); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLDepthTest depth(GL_FALSE, GL_FALSE); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_GREATER); + + gGL.flush(); + + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + static const F32 clip_plane = 0.99999f; - gGL.color4f(1,1,1,1); gGL.color4ub(64,64,64,255); gGL.begin(LLRender::QUADS); - gGL.vertex3fv((pos+left-up).mV); - gGL.vertex3fv((pos-left-up).mV); - gGL.vertex3fv((pos-left+up).mV); - gGL.vertex3fv((pos+left+up).mV); + gGL.vertex3f(-1, -1, clip_plane); + gGL.vertex3f(1, -1, clip_plane); + gGL.vertex3f(1, 1, clip_plane); + gGL.vertex3f(-1, 1, clip_plane); gGL.end(); gGL.flush(); - gGL.setSceneBlendType(LLRender::BT_ALPHA); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); } - avatar->mImpostor.flush(); avatar->setImpostorDim(tdim); @@ -9139,7 +9671,10 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() BOOL LLPipeline::hasRenderType(const U32 type) const { - return mRenderTypeEnabled[type]; + // STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render" + // We then need to test that value here and return FALSE to prevent attachment to render (in mouselook for instance) + // TODO: reintroduce RENDER_TYPE_NONE in LLRenderTypeMask and initialize its mRenderTypeEnabled[RENDER_TYPE_NONE] to FALSE explicitely + return (type == 0 ? FALSE : mRenderTypeEnabled[type]); } void LLPipeline::setRenderTypeMask(U32 type, ...) @@ -9254,4 +9789,9 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...) } } +void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color) +{ + DebugBlip blip(position, color); + mDebugBlips.push_back(blip); +} |