From 087e15e89930d51c3964329befb273ae3b2d330d Mon Sep 17 00:00:00 2001 From: Armin Weatherwax Date: Tue, 7 Sep 2010 13:41:02 +0200 Subject: port of LL renderpipeline/Kirstens S19 pipeline for bridging to Viewer 2 texture system --- linden/indra/llmath/llbbox.cpp | 162 + linden/indra/llmath/llbbox.h | 103 + linden/indra/llmath/llcamera.cpp | 24 + linden/indra/llmath/llcamera.h | 16 +- linden/indra/llmath/llmath.h | 2 +- linden/indra/llmath/llmodularmath.cpp | 36 + linden/indra/llmath/llvolume.cpp | 14 +- linden/indra/llprimitive/CMakeLists.txt | 1 + linden/indra/llrender/CMakeLists.txt | 6 +- linden/indra/llrender/llcubemap.cpp | 17 +- linden/indra/llrender/llfont.cpp | 2 +- linden/indra/llrender/llfontgl.cpp | 6 +- linden/indra/llrender/llgl.cpp | 8 +- linden/indra/llrender/llgl.h | 31 + linden/indra/llrender/llglslshader.cpp | 2 +- linden/indra/llrender/llimagegl.cpp | 451 +-- linden/indra/llrender/llimagegl.h | 117 +- linden/indra/llrender/llrender.cpp | 64 +- linden/indra/llrender/llrendertarget.cpp | 57 +- linden/indra/llrender/llrendertarget.h | 1 + linden/indra/llrender/lltextureatlas.cpp | 411 +++ linden/indra/llrender/lltextureatlas.h | 92 + linden/indra/llrender/llvertexbuffer.cpp | 72 +- linden/indra/newview/CMakeLists.txt | 4 + linden/indra/newview/app_settings/settings.xml | 735 ++++- .../shaders/class1/deferred/alphaF.glsl | 24 +- .../shaders/class1/deferred/alphaV.glsl | 10 +- .../shaders/class1/deferred/avatarAlphaF.glsl | 2 +- .../shaders/class1/deferred/avatarF.glsl | 13 +- .../shaders/class1/deferred/avatarShadowF.glsl | 3 +- .../shaders/class1/deferred/avatarShadowV.glsl | 3 +- .../shaders/class1/deferred/avatarV.glsl | 2 - .../shaders/class1/deferred/blurLightF.glsl | 41 +- .../shaders/class1/deferred/bumpF.glsl | 8 +- .../shaders/class1/deferred/bumpV.glsl | 3 - .../shaders/class1/deferred/diffuseF.glsl | 6 +- .../shaders/class1/deferred/diffuseV.glsl | 5 +- .../shaders/class1/deferred/fullbrightF.glsl | 28 +- .../shaders/class1/deferred/fullbrightV.glsl | 2 +- .../app_settings/shaders/class1/deferred/giF.glsl | 165 + .../app_settings/shaders/class1/deferred/giV.glsl | 22 + .../shaders/class1/deferred/luminanceF.glsl | 15 + .../shaders/class1/deferred/luminanceV.glsl | 20 + .../shaders/class1/deferred/multiPointLightF.glsl | 62 +- .../shaders/class1/deferred/multiSpotLightF.glsl | 184 ++ .../shaders/class1/deferred/pointLightF.glsl | 61 +- .../shaders/class1/deferred/pointLightV.glsl | 6 +- .../shaders/class1/deferred/postDeferredF.glsl | 57 + .../shaders/class1/deferred/postDeferredV.glsl | 17 + .../shaders/class1/deferred/postgiF.glsl | 107 + .../shaders/class1/deferred/postgiV.glsl | 16 + .../shaders/class1/deferred/shadowF.glsl | 3 + .../shaders/class1/deferred/shadowV.glsl | 10 +- .../shaders/class1/deferred/softenLightF.glsl | 4 - .../shaders/class1/deferred/spotLightF.glsl | 199 ++ .../shaders/class1/deferred/sunLightF.glsl | 111 +- .../shaders/class1/deferred/terrainF.glsl | 6 +- .../shaders/class1/deferred/terrainV.glsl | 2 - .../shaders/class1/deferred/treeF.glsl | 4 +- .../shaders/class1/deferred/treeV.glsl | 3 - .../shaders/class1/deferred/waterF.glsl | 2 +- .../shaders/class1/effects/colorFilterF.glsl | 31 + .../shaders/class1/effects/drawQuadV.glsl | 14 + .../shaders/class1/effects/nightVisionF.glsl | 42 + .../shaders/class2/deferred/alphaF.glsl | 112 + .../shaders/class2/deferred/alphaV.glsl | 75 + .../shaders/class2/deferred/avatarAlphaF.glsl | 77 + .../shaders/class2/deferred/avatarAlphaV.glsl | 78 + .../shaders/class2/deferred/blurLightF.glsl | 71 + .../shaders/class2/deferred/blurLightV.glsl | 17 + .../shaders/class2/deferred/multiSpotLightF.glsl | 188 ++ .../shaders/class2/deferred/postDeferredF.glsl | 59 + .../shaders/class2/deferred/postDeferredV.glsl | 17 + .../shaders/class2/deferred/softenLightF.glsl | 294 ++ .../shaders/class2/deferred/softenLightV.glsl | 24 + .../shaders/class2/deferred/spotLightF.glsl | 199 ++ .../shaders/class2/deferred/sunLightF.glsl | 203 ++ .../shaders/class2/deferred/sunLightV.glsl | 25 + .../shaders/class2/deferred/waterF.glsl | 139 + .../shaders/class2/deferred/waterV.glsl | 76 + .../shaders/class3/deferred/avatarF.glsl | 18 + .../shaders/class3/deferred/bumpF.glsl | 27 + .../shaders/class3/deferred/diffuseF.glsl | 18 + .../shaders/class3/deferred/giDownsampleF.glsl | 84 + .../shaders/class3/deferred/giDownsampleV.glsl | 17 + .../app_settings/shaders/class3/deferred/giF.glsl | 219 ++ .../app_settings/shaders/class3/deferred/giV.glsl | 22 + .../shaders/class3/deferred/luminanceF.glsl | 16 + .../shaders/class3/deferred/luminanceV.glsl | 20 + .../shaders/class3/deferred/postDeferredF.glsl | 76 + .../shaders/class3/deferred/postDeferredV.glsl | 17 + .../shaders/class3/deferred/postgiF.glsl | 87 + .../shaders/class3/deferred/postgiV.glsl | 17 + .../shaders/class3/deferred/softenLightF.glsl | 312 ++ .../shaders/class3/deferred/softenLightV.glsl | 24 + .../shaders/class3/deferred/treeF.glsl | 18 + .../shaders/class3/deferred/waterF.glsl | 139 + .../app_settings/shaders/class3/effects/blurF.glsl | 31 + .../app_settings/shaders/class3/effects/blurV.glsl | 35 + .../shaders/class3/effects/colorFilterF.glsl | 31 + .../shaders/class3/effects/drawQuadV.glsl | 14 + .../shaders/class3/effects/extractF.glsl | 22 + .../shaders/class3/effects/nightVisionF.glsl | 42 + .../shaders/class3/effects/simpleF.glsl | 14 + linden/indra/newview/llagent.cpp | 3 +- linden/indra/newview/llagent.h | 1 + linden/indra/newview/llappviewer.cpp | 2 +- linden/indra/newview/llcolorswatch.cpp | 3 +- linden/indra/newview/llcompilequeue.cpp | 1 - linden/indra/newview/llconsole.cpp | 166 +- linden/indra/newview/llconsole.h | 47 +- linden/indra/newview/lldebugview.cpp | 24 +- linden/indra/newview/lldrawable.cpp | 76 +- linden/indra/newview/lldrawable.h | 3 +- linden/indra/newview/lldrawpool.h | 5 + linden/indra/newview/lldrawpoolalpha.cpp | 59 +- linden/indra/newview/lldrawpoolavatar.cpp | 69 +- linden/indra/newview/lldrawpoolbump.cpp | 25 +- linden/indra/newview/lldrawpoolsky.cpp | 68 +- linden/indra/newview/lldrawpoolsky.h | 4 + linden/indra/newview/lldrawpoolterrain.cpp | 6 +- linden/indra/newview/lldrawpooltree.cpp | 15 +- linden/indra/newview/lldrawpoolwater.cpp | 20 +- linden/indra/newview/lldynamictexture.cpp | 21 +- linden/indra/newview/lldynamictexture.h | 4 +- linden/indra/newview/llface.cpp | 445 +-- linden/indra/newview/llface.h | 38 +- linden/indra/newview/llfloaterassetbrowser.cpp | 18 +- linden/indra/newview/llfloaterchat.cpp | 3 +- linden/indra/newview/llfloaterhardwaresettings.cpp | 27 +- linden/indra/newview/llfloaterhardwaresettings.h | 4 + linden/indra/newview/llfloaterlagmeter.cpp | 2 +- linden/indra/newview/llfloaterpostprocess.cpp | 66 +- linden/indra/newview/llfloaterreporter.cpp | 3 +- linden/indra/newview/llhudeffect.cpp | 2 +- linden/indra/newview/llhudtext.cpp | 2 + linden/indra/newview/llmanip.cpp | 2 +- linden/indra/newview/llmaniptranslate.h | 2 +- linden/indra/newview/llmediactrl.cpp | 3 +- linden/indra/newview/lloverlaybar.cpp | 1 - linden/indra/newview/llpanelvolume.cpp | 117 + linden/indra/newview/llpanelvolume.h | 5 + linden/indra/newview/llpostprocess.cpp | 594 ++++ linden/indra/newview/llpostprocess.h | 274 ++ linden/indra/newview/llpreview.cpp | 1 + linden/indra/newview/llselectmgr.cpp | 22 +- linden/indra/newview/llselectmgr.h | 2 +- linden/indra/newview/llsky.cpp | 14 + linden/indra/newview/llspatialpartition.cpp | 390 ++- linden/indra/newview/llspatialpartition.h | 62 +- linden/indra/newview/llstartup.cpp | 2 +- linden/indra/newview/llsurface.cpp | 20 +- linden/indra/newview/llsurfacepatch.cpp | 34 +- linden/indra/newview/llsurfacepatch.h | 1 + linden/indra/newview/lltexlayer.cpp | 26 +- linden/indra/newview/lltexlayer.h | 4 +- linden/indra/newview/lltextureatlasmanager.cpp | 274 ++ linden/indra/newview/lltextureatlasmanager.h | 112 + linden/indra/newview/lltextureview.cpp | 238 +- linden/indra/newview/lltoolpie.h | 1 - linden/indra/newview/llviewercamera.cpp | 4 +- linden/indra/newview/llviewercontrol.cpp | 16 +- linden/indra/newview/llviewerdisplay.cpp | 27 +- linden/indra/newview/llviewerimage.cpp | 367 ++- linden/indra/newview/llviewerimage.h | 31 +- linden/indra/newview/llviewerimagelist.cpp | 50 +- linden/indra/newview/llviewerimagelist.h | 4 +- linden/indra/newview/llviewerjointmesh.cpp | 10 +- linden/indra/newview/llviewermedia.cpp | 4 +- linden/indra/newview/llviewermenu.cpp | 20 +- linden/indra/newview/llviewerobject.cpp | 35 +- linden/indra/newview/llviewerobject.h | 11 +- linden/indra/newview/llviewerobjectlist.cpp | 2 +- linden/indra/newview/llviewerobjectlist.h | 1 - linden/indra/newview/llviewerparceloverlay.cpp | 4 +- linden/indra/newview/llviewershadermgr.cpp | 106 +- linden/indra/newview/llviewershadermgr.h | 25 + linden/indra/newview/llviewerstats.h | 2 +- linden/indra/newview/llviewerwindow.cpp | 110 +- linden/indra/newview/llvlcomposition.cpp | 4 + linden/indra/newview/llvoavatar.cpp | 98 +- linden/indra/newview/llvoavatar.h | 10 +- linden/indra/newview/llvoclouds.cpp | 7 +- linden/indra/newview/llvoclouds.h | 2 +- linden/indra/newview/llvograss.cpp | 2 +- linden/indra/newview/llvograss.h | 2 +- linden/indra/newview/llvoground.cpp | 2 +- linden/indra/newview/llvoground.h | 2 +- linden/indra/newview/llvopartgroup.cpp | 20 +- linden/indra/newview/llvopartgroup.h | 2 +- linden/indra/newview/llvosky.cpp | 8 +- linden/indra/newview/llvosky.h | 4 +- linden/indra/newview/llvosurfacepatch.cpp | 18 +- linden/indra/newview/llvosurfacepatch.h | 3 +- linden/indra/newview/llvotextbubble.cpp | 2 +- linden/indra/newview/llvotextbubble.h | 2 +- linden/indra/newview/llvotree.cpp | 6 +- linden/indra/newview/llvotree.h | 2 +- linden/indra/newview/llvotreenew.h | 2 +- linden/indra/newview/llvovolume.cpp | 422 ++- linden/indra/newview/llvovolume.h | 23 +- linden/indra/newview/llvowater.cpp | 6 +- linden/indra/newview/llvowater.h | 2 +- linden/indra/newview/llwaterparammanager.cpp | 3 +- linden/indra/newview/llwlparammanager.cpp | 3 +- linden/indra/newview/llworld.h | 6 +- linden/indra/newview/pipeline.cpp | 3229 ++++++++++++++++---- linden/indra/newview/pipeline.h | 128 +- .../xui/en-us/floater_hardware_settings.xml | 30 +- .../skins/default/xui/en-us/floater_tools.xml | 44 +- 210 files changed, 12753 insertions(+), 2324 deletions(-) create mode 100644 linden/indra/llmath/llbbox.cpp create mode 100644 linden/indra/llmath/llbbox.h create mode 100644 linden/indra/llmath/llmodularmath.cpp create mode 100644 linden/indra/llrender/lltextureatlas.cpp create mode 100644 linden/indra/llrender/lltextureatlas.h create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl create mode 100644 linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl create mode 100644 linden/indra/newview/llpostprocess.cpp create mode 100644 linden/indra/newview/llpostprocess.h create mode 100644 linden/indra/newview/lltextureatlasmanager.cpp create mode 100644 linden/indra/newview/lltextureatlasmanager.h (limited to 'linden') diff --git a/linden/indra/llmath/llbbox.cpp b/linden/indra/llmath/llbbox.cpp new file mode 100644 index 0000000..f0ec010 --- /dev/null +++ b/linden/indra/llmath/llbbox.cpp @@ -0,0 +1,162 @@ +/** + * @file llbbox.cpp + * @brief General purpose bounding box class (Not axis aligned) + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, /linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// self include +#include "llbbox.h" + +// library includes +#include "m4math.h" + +void LLBBox::addPointLocal(const LLVector3& p) +{ + if (mEmpty) + { + mMinLocal = p; + mMaxLocal = p; + mEmpty = FALSE; + } + else + { + mMinLocal.mV[VX] = llmin( p.mV[VX], mMinLocal.mV[VX] ); + mMinLocal.mV[VY] = llmin( p.mV[VY], mMinLocal.mV[VY] ); + mMinLocal.mV[VZ] = llmin( p.mV[VZ], mMinLocal.mV[VZ] ); + mMaxLocal.mV[VX] = llmax( p.mV[VX], mMaxLocal.mV[VX] ); + mMaxLocal.mV[VY] = llmax( p.mV[VY], mMaxLocal.mV[VY] ); + mMaxLocal.mV[VZ] = llmax( p.mV[VZ], mMaxLocal.mV[VZ] ); + } +} + +void LLBBox::addPointAgent( LLVector3 p) +{ + p -= mPosAgent; + p.rotVec( ~mRotation ); + addPointLocal( p ); +} + + +void LLBBox::addBBoxAgent(const LLBBox& b) +{ + if (mEmpty) + { + mPosAgent = b.mPosAgent; + mRotation = b.mRotation; + mMinLocal.clearVec(); + mMaxLocal.clearVec(); + } + LLVector3 vertex[8]; + vertex[0].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[1].setVec( b.mMinLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[2].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[3].setVec( b.mMinLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[4].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[5].setVec( b.mMaxLocal.mV[VX], b.mMinLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + vertex[6].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMinLocal.mV[VZ] ); + vertex[7].setVec( b.mMaxLocal.mV[VX], b.mMaxLocal.mV[VY], b.mMaxLocal.mV[VZ] ); + + LLMatrix4 m( b.mRotation ); + m.translate( b.mPosAgent ); + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); + + for( S32 i=0; i<8; i++ ) + { + addPointLocal( vertex[i] * m ); + } +} + + +void LLBBox::expand( F32 delta ) +{ + mMinLocal.mV[VX] -= delta; + mMinLocal.mV[VY] -= delta; + mMinLocal.mV[VZ] -= delta; + mMaxLocal.mV[VX] += delta; + mMaxLocal.mV[VY] += delta; + mMaxLocal.mV[VZ] += delta; +} + +LLVector3 LLBBox::localToAgent(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + m.translate( mPosAgent ); + return v * m; +} + +LLVector3 LLBBox::agentToLocal(const LLVector3& v) const +{ + LLMatrix4 m; + m.translate( -mPosAgent ); + m.rotate( ~mRotation ); // inverse rotation + return v * m; +} + +LLVector3 LLBBox::localToAgentBasis(const LLVector3& v) const +{ + LLMatrix4 m( mRotation ); + return v * m; +} + +LLVector3 LLBBox::agentToLocalBasis(const LLVector3& v) const +{ + LLMatrix4 m( ~mRotation ); // inverse rotation + return v * m; +} + +BOOL LLBBox::containsPointLocal(const LLVector3& p) const +{ + if ( (p.mV[VX] < mMinLocal.mV[VX]) + ||(p.mV[VX] > mMaxLocal.mV[VX]) + ||(p.mV[VY] < mMinLocal.mV[VY]) + ||(p.mV[VY] > mMaxLocal.mV[VY]) + ||(p.mV[VZ] < mMinLocal.mV[VZ]) + ||(p.mV[VZ] > mMaxLocal.mV[VZ])) + { + return FALSE; + } + return TRUE; +} + +BOOL LLBBox::containsPointAgent(const LLVector3& p) const +{ + LLVector3 point_local = agentToLocal(p); + return containsPointLocal(point_local); +} + + +/* +LLBBox operator*(const LLBBox &a, const LLMatrix4 &b) +{ + return LLBBox( a.mMin * b, a.mMax * b ); +} +*/ diff --git a/linden/indra/llmath/llbbox.h b/linden/indra/llmath/llbbox.h new file mode 100644 index 0000000..3559284 --- /dev/null +++ b/linden/indra/llmath/llbbox.h @@ -0,0 +1,103 @@ +/** + * @file llbbox.h + * @brief General purpose bounding box class + * + * $LicenseInfo:firstyear=2001&license=viewergpl$ + * + * Copyright (c) 2001-2010, /linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL /linden LAB SOURCE CODE IS PROVIDED "AS IS." /linden LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_BBOX_H +#define LL_BBOX_H + +#include "v3math.h" +#include "llquaternion.h" + +// Note: "local space" for an LLBBox is defined relative to agent space in terms of +// a translation followed by a rotation. There is no scale term since the LLBBox's min and +// max are not necessarily symetrical and define their own extents. + +class LLBBox +{ +public: + LLBBox() {mEmpty = TRUE;} + LLBBox( const LLVector3& pos_agent, + const LLQuaternion& rot, + const LLVector3& min_local, + const LLVector3& max_local ) + : + mMinLocal( min_local ), mMaxLocal( max_local ), mPosAgent(pos_agent), mRotation( rot), mEmpty( TRUE ) + {} + + // Default copy constructor is OK. + + const LLVector3& getPositionAgent() const { return mPosAgent; } + const LLQuaternion& getRotation() const { return mRotation; } + + const LLVector3& getMinLocal() const { return mMinLocal; } + void setMinLocal( const LLVector3& min ) { mMinLocal = min; } + + const LLVector3& getMaxLocal() const { return mMaxLocal; } + void setMaxLocal( const LLVector3& max ) { mMaxLocal = max; } + + LLVector3 getCenterLocal() const { return (mMaxLocal - mMinLocal) * 0.5f + mMinLocal; } + LLVector3 getCenterAgent() const { return localToAgent( getCenterLocal() ); } + + LLVector3 getExtentLocal() const { return mMaxLocal - mMinLocal; } + + BOOL containsPointLocal(const LLVector3& p) const; + BOOL containsPointAgent(const LLVector3& p) const; + + void addPointAgent(LLVector3 p); + void addBBoxAgent(const LLBBox& b); + + void addPointLocal(const LLVector3& p); + void addBBoxLocal(const LLBBox& b) { addPointLocal( b.mMinLocal ); addPointLocal( b.mMaxLocal ); } + + void expand( F32 delta ); + + LLVector3 localToAgent( const LLVector3& v ) const; + LLVector3 agentToLocal( const LLVector3& v ) const; + + // Changes rotation but not position + LLVector3 localToAgentBasis(const LLVector3& v) const; + LLVector3 agentToLocalBasis(const LLVector3& v) const; + + +// friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b); + +private: + LLVector3 mMinLocal; + LLVector3 mMaxLocal; + LLVector3 mPosAgent; // Position relative to Agent's Region + LLQuaternion mRotation; + BOOL mEmpty; // Nothing has been added to this bbox yet +}; + +//LLBBox operator*(const LLBBox &a, const LLMatrix4 &b); + + +#endif // LL_BBOX_H diff --git a/linden/indra/llmath/llcamera.cpp b/linden/indra/llmath/llcamera.cpp index 0f343bc..0609e2f 100644 --- a/linden/indra/llmath/llcamera.cpp +++ b/linden/indra/llmath/llcamera.cpp @@ -246,6 +246,10 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius) for (U32 i = 0; i < mPlaneCount; i++) { mask = mAgentPlanes[i].mask; + if (mask == 0xff) + { + continue; + } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -294,6 +298,10 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r } mask = mAgentPlanes[i].mask; + if (mask == 0xff) + { + continue; + } LLPlane p = mAgentPlanes[i].p; LLVector3 n = LLVector3(p); float d = p.mV[3]; @@ -437,6 +445,11 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) int res = 2; for (int i = 0; i < 6; i++) { + if (mAgentPlanes[i].mask == 0xff) + { + continue; + } + float d = mAgentPlanes[i].p.dist(sphere_center); if (d > radius) @@ -622,6 +635,17 @@ U8 LLCamera::calcPlaneMask(const LLPlane& plane) return mask; } +void LLCamera::ignoreAgentFrustumPlane(S32 idx) +{ + if (idx < 0 || idx > (S32) mPlaneCount) + { + return; + } + + mAgentPlanes[idx].mask = 0xff; + mAgentPlanes[idx].p.clearVec(); +} + void LLCamera::calcAgentFrustumPlanes(LLVector3* frust) { diff --git a/linden/indra/llmath/llcamera.h b/linden/indra/llmath/llcamera.h index 23ee115..0c81067 100644 --- a/linden/indra/llmath/llcamera.h +++ b/linden/indra/llmath/llcamera.h @@ -93,6 +93,17 @@ public: PLANE_TOP_MASK = (1<generate(mParams.getPathParams(), sculpt_detail, 0, TRUE, requested_sizeS); - mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), sculpt_detail, 0, TRUE, requested_sizeT); + mPathp->generate(mParams.getPathParams(), mDetail, 0, TRUE, requested_sizeS); + mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(), mDetail, 0, TRUE, requested_sizeT); S32 sizeS = mPathp->mPath.size(); // we requested a specific size, now see what we really got S32 sizeT = mProfilep->mProfile.size(); // we requested a specific size, now see what we really got @@ -4274,7 +4268,7 @@ LLFaceID LLVolume::generateFaceMask() } break; default: - llerrs << "Unknown profile!" << llendl + llerrs << "Unknown profile!" << llendl; break; } diff --git a/linden/indra/llprimitive/CMakeLists.txt b/linden/indra/llprimitive/CMakeLists.txt index e7ee811..716b247 100755 --- a/linden/indra/llprimitive/CMakeLists.txt +++ b/linden/indra/llprimitive/CMakeLists.txt @@ -52,6 +52,7 @@ set_source_files_properties(${llprimitive_HEADER_FILES} list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES}) add_library (llprimitive ${llprimitive_SOURCE_FILES}) +add_dependencies(llprimitive prepare) #add unit tests INCLUDE(LLAddBuildTest) diff --git a/linden/indra/llrender/CMakeLists.txt b/linden/indra/llrender/CMakeLists.txt index 0bdb55f..e42f9ab 100644 --- a/linden/indra/llrender/CMakeLists.txt +++ b/linden/indra/llrender/CMakeLists.txt @@ -32,9 +32,9 @@ set(llrender_SOURCE_FILES llgldbg.cpp llglslshader.cpp llimagegl.cpp - llpostprocess.cpp llrendersphere.cpp llshadermgr.cpp + lltextureatlas.cpp llvertexbuffer.cpp ) @@ -53,10 +53,10 @@ set(llrender_HEADER_FILES llglstates.h llgltypes.h llimagegl.h - llpostprocess.h llrender.h llrendersphere.h llshadermgr.h + lltextureatlas.h llvertexbuffer.h ) @@ -81,6 +81,7 @@ if (SERVER AND NOT WINDOWS AND NOT DARWIN) ${llrender_SOURCE_FILES} ${server_SOURCE_FILES} ) + add_dependencies(llrenderheadless prepare) else (SERVER AND NOT WINDOWS AND NOT DARWIN) list(APPEND llrender_SOURCE_FILES llgl.cpp @@ -89,3 +90,4 @@ else (SERVER AND NOT WINDOWS AND NOT DARWIN) ) endif (SERVER AND NOT WINDOWS AND NOT DARWIN) add_library (llrender ${llrender_SOURCE_FILES}) +add_dependencies(llrender prepare) diff --git a/linden/indra/llrender/llcubemap.cpp b/linden/indra/llrender/llcubemap.cpp index a5c677d..e0923e4 100644 --- a/linden/indra/llrender/llcubemap.cpp +++ b/linden/indra/llrender/llcubemap.cpp @@ -4,7 +4,7 @@ * * $LicenseInfo:firstyear=2002&license=viewergpl$ * - * Copyright (c) 2002-2009, Linden Research, Inc. + * Copyright (c) 2002-2010, Linden Research, Inc. * * Second Life Viewer Source Code * The source code in this file ("Source Code") is provided by Linden Lab @@ -63,6 +63,12 @@ LLCubeMap::LLCubeMap() mTextureCoordStage(0), mMatrixStage(0) { + mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; + mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; + mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; + mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; + mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; } LLCubeMap::~LLCubeMap() @@ -75,13 +81,6 @@ void LLCubeMap::initGL() if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) { - mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB; - mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; - mTargets[2] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB; - mTargets[3] = GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB; - mTargets[4] = GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB; - mTargets[5] = GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB; - // Not initialized, do stuff. if (mImages[0].isNull()) { @@ -94,7 +93,7 @@ void LLCubeMap::initGL() mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE)); mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP); mRawImages[i] = new LLImageRaw(64, 64, 4); - mImages[i]->createGLTexture(0, mRawImages[i], texname, TRUE); + mImages[i]->createGLTexture(0, mRawImages[i], texname); gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname); mImages[i]->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/llrender/llfont.cpp b/linden/indra/llrender/llfont.cpp index dd33128..da5eda0 100644 --- a/linden/indra/llrender/llfont.cpp +++ b/linden/indra/llrender/llfont.cpp @@ -81,7 +81,7 @@ LLFontManager::LLFontManager() if (error) { // Clean up freetype libs. - llerrs << "Freetype initialization failure!" << llendl; + llwarns << "Freetype initialization failure!" << llendl; FT_Done_FreeType(gFTLibrary); } } diff --git a/linden/indra/llrender/llfontgl.cpp b/linden/indra/llrender/llfontgl.cpp index 5d3d6a7..9d1f1d4 100644 --- a/linden/indra/llrender/llfontgl.cpp +++ b/linden/indra/llrender/llfontgl.cpp @@ -121,7 +121,7 @@ LLFontGL::LLFontGL() LLFontGL::LLFontGL(const LLFontGL &source) { - llerrs << "Not implemented!" << llendl; + llwarns << "Not implemented!" << llendl; } LLFontGL::~LLFontGL() @@ -278,7 +278,7 @@ void LLFontGL::destroyGL() LLFontGL &LLFontGL::operator=(const LLFontGL &source) { - llerrs << "Not implemented" << llendl; + llwarns << "Not implemented" << llendl; return *this; } @@ -584,7 +584,7 @@ S32 LLFontGL::render(const LLWString &wstr, const LLFontGlyphInfo* fgi= getGlyphInfo(wch); if (!fgi) { - llerrs << "Missing Glyph Info" << llendl; + llwarns << "Missing Glyph Info" << llendl; break; } // Per-glyph bitmap texture. diff --git a/linden/indra/llrender/llgl.cpp b/linden/indra/llrender/llgl.cpp index 61194c4..be3ed96 100644 --- a/linden/indra/llrender/llgl.cpp +++ b/linden/indra/llrender/llgl.cpp @@ -59,11 +59,13 @@ BOOL gDebugGL = FALSE; BOOL gClothRipple = FALSE; BOOL gNoRender = FALSE; +BOOL gGLActive = FALSE; LLMatrix4 gGLObliqueProjectionInverse; #define LL_GL_NAME_POOLING 0 LLGLNamePool::pool_list_t LLGLNamePool::sInstances; +std::list LLGLUpdate::sGLQ; #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS // ATI prototypes @@ -1001,7 +1003,7 @@ void assert_glerror() if (quit) { - llerrs << "One or more unhandled GL errors." << llendl; + llwarns << "One or more unhandled GL errors." << llendl; } } @@ -1695,11 +1697,11 @@ void LLGLNamePool::release(GLuint name) } else { - llerrs << "Attempted to release a pooled name that is not in use!" << llendl; + llwarns << "Attempted to release a pooled name that is not in use!" << llendl; } } } - llerrs << "Attempted to release a non pooled name!" << llendl; + llwarns << "Attempted to release a non pooled name!" << llendl; #else releaseName(name); #endif diff --git a/linden/indra/llrender/llgl.h b/linden/indra/llrender/llgl.h index 00ff1e2..88552ce 100644 --- a/linden/indra/llrender/llgl.h +++ b/linden/indra/llrender/llgl.h @@ -358,6 +358,35 @@ protected: virtual void releaseName(GLuint name) = 0; }; +/* + Interface for objects that need periodic GL updates applied to them. + Used to synchronize GL updates with GL thread. +*/ +class LLGLUpdate +{ +public: + + static std::list sGLQ; + + BOOL mInQ; + LLGLUpdate() + : mInQ(FALSE) + { + } + virtual ~LLGLUpdate() + { + if (mInQ) + { + std::list::iterator iter = std::find(sGLQ.begin(), sGLQ.end(), this); + if (iter != sGLQ.end()) + { + sGLQ.erase(iter); + } + } + } + virtual void updateGL() = 0; +}; + extern LLMatrix4 gGLObliqueProjectionInverse; #include "llglstates.h" @@ -376,4 +405,6 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor extern BOOL gClothRipple; extern BOOL gNoRender; +extern BOOL gGLActive; + #endif // LL_LLGL_H diff --git a/linden/indra/llrender/llglslshader.cpp b/linden/indra/llrender/llglslshader.cpp index 08d6548..18974a7 100644 --- a/linden/indra/llrender/llglslshader.cpp +++ b/linden/indra/llrender/llglslshader.cpp @@ -408,7 +408,7 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode) { if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode) { - llerrs << "Texture channel " << index << " texture type corrupted." << llendl; + llwarns << "Texture channel " << index << " texture type corrupted." << llendl; } gGL.getTexUnit(index)->disable(); } diff --git a/linden/indra/llrender/llimagegl.cpp b/linden/indra/llrender/llimagegl.cpp index 7cd4dd7..1bddd49 100644 --- a/linden/indra/llrender/llimagegl.cpp +++ b/linden/indra/llrender/llimagegl.cpp @@ -43,6 +43,8 @@ #include "llmath.h" #include "llgl.h" #include "llrender.h" +#include "lltextureatlas.h" + //---------------------------------------------------------------------------- const F32 MIN_TEXTURE_LIFETIME = 10.f; @@ -56,19 +58,17 @@ S32 LLImageGL::sGlobalTextureMemoryInBytes = 0; S32 LLImageGL::sBoundTextureMemoryInBytes = 0; S32 LLImageGL::sCurBoundTextureMemory = 0; S32 LLImageGL::sCount = 0; +std::list LLImageGL::sDeadTextureList; BOOL LLImageGL::sGlobalUseAnisotropic = FALSE; F32 LLImageGL::sLastFrameTime = 0.f; -BOOL LLImageGL::sAllowReadBackRaw = FALSE ; +BOOL LLImageGL::sUseTextureAtlas = FALSE ; // render-pipeline KL std::set LLImageGL::sImageList; -//**************************************************************************************************** -//The below for texture auditing use only -//**************************************************************************************************** +#if !LL_RELEASE_FOR_DOWNLOAD //----------------------- //debug use -BOOL gAuditTexture = FALSE ; #define MAX_TEXTURE_LOG_SIZE 22 //2048 * 2048 std::vector LLImageGL::sTextureLoadedCounter(MAX_TEXTURE_LOG_SIZE + 1) ; std::vector LLImageGL::sTextureBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; @@ -76,15 +76,8 @@ std::vector LLImageGL::sTextureCurBoundCounter(MAX_TEXTURE_LOG_SIZE + 1) ; S32 LLImageGL::sCurTexSizeBar = -1 ; S32 LLImageGL::sCurTexPickSize = -1 ; LLPointer LLImageGL::sDefaultTexturep = NULL; -S32 LLImageGL::sMaxCatagories = 1 ; - -std::vector LLImageGL::sTextureMemByCategory; -std::vector LLImageGL::sTextureMemByCategoryBound ; -std::vector LLImageGL::sTextureCurMemByCategoryBound ; //------------------------ -//**************************************************************************************************** -//End for texture auditing use only -//**************************************************************************************************** +#endif //************************************************************************************** //below are functions for debug use @@ -110,9 +103,12 @@ void LLImageGL::checkTexSize() const { GLint texname; glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname); + BOOL error = FALSE; if (texname != mTexName) { - llerrs << "Invalid texture bound!" << llendl; + + llwarns << "Invalid texture bound!" << llendl; + } stop_glerror() ; LLGLint x = 0, y = 0 ; @@ -125,7 +121,15 @@ void LLImageGL::checkTexSize() const } if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel)) { - llerrs << "wrong texture size and discard level!" << llendl ; + error = TRUE; + + llwarns << "wrong texture size and discard level!" << llendl; + + } + + if (error) + { + llwarns << "LLImageGL::checkTexSize failed." << llendl; } } } @@ -133,20 +137,6 @@ void LLImageGL::checkTexSize() const //************************************************************************************** //---------------------------------------------------------------------------- -//static -void LLImageGL::initClass(S32 num_catagories) -{ - sMaxCatagories = num_catagories ; - - sTextureMemByCategory.resize(sMaxCatagories); - sTextureMemByCategoryBound.resize(sMaxCatagories) ; - sTextureCurMemByCategoryBound.resize(sMaxCatagories) ; -} - -//static -void LLImageGL::cleanupClass() -{ -} //static S32 LLImageGL::dataFormatBits(S32 dataformat) @@ -165,7 +155,7 @@ S32 LLImageGL::dataFormatBits(S32 dataformat) case GL_RGBA: return 32; case GL_BGRA: return 32; // Used for QuickTime media textures on the Mac default: - llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; + llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -200,7 +190,7 @@ S32 LLImageGL::dataFormatComponents(S32 dataformat) case GL_RGBA: return 4; case GL_BGRA: return 4; // Used for QuickTime media textures on the Mac default: - llerrs << "LLImageGL::Unknown format: " << dataformat << llendl; + llwarns << "LLImageGL::Unknown format: " << dataformat << llendl; return 0; } } @@ -214,43 +204,25 @@ void LLImageGL::updateStats(F32 current_time) sBoundTextureMemoryInBytes = sCurBoundTextureMemory; sCurBoundTextureMemory = 0; - if(gAuditTexture) +#if !LL_RELEASE_FOR_DOWNLOAD + for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) { - for(U32 i = 0 ; i < sTextureCurBoundCounter.size() ; i++) - { - sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; - sTextureCurBoundCounter[i] = 0 ; - } - for(U32 i = 0 ; i < sTextureCurMemByCategoryBound.size() ; i++) - { - sTextureMemByCategoryBound[i] = sTextureCurMemByCategoryBound[i] ; - sTextureCurMemByCategoryBound[i] = 0 ; - } + sTextureBoundCounter[i] = sTextureCurBoundCounter[i] ; + sTextureCurBoundCounter[i] = 0 ; } +#endif } //static -S32 LLImageGL::updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) -{ - if(gAuditTexture) - { - sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; - sTextureCurMemByCategoryBound[category] += delta ; - } - - LLImageGL::sCurBoundTextureMemory += delta ; - return LLImageGL::sCurBoundTextureMemory; -} - -S32 LLImageGL::updateBoundTexMem()const -{ - if(gAuditTexture) - { - sTextureCurBoundCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; - sTextureCurMemByCategoryBound[mCategory] += mTextureMemory ; - } - - LLImageGL::sCurBoundTextureMemory += mTextureMemory ; +//#if !LL_RELEASE_FOR_DOWNLOAD +//S32 LLImageGL::updateBoundTexMem(const S32 delta, const S32 size) +//{ +// sTextureCurBoundCounter[getTextureCounterIndex(size)]++ ; +//#else +S32 LLImageGL::updateBoundTexMem(const S32 delta) +{ +//#endif + LLImageGL::sCurBoundTextureMemory += delta; return LLImageGL::sCurBoundTextureMemory; } @@ -264,7 +236,6 @@ void LLImageGL::destroyGL(BOOL save_state) gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } - sAllowReadBackRaw = true ; for (std::set::iterator iter = sImageList.begin(); iter != sImageList.end(); iter++) { @@ -284,7 +255,7 @@ void LLImageGL::destroyGL(BOOL save_state) stop_glerror(); } } - sAllowReadBackRaw = false ; +// sAllowReadBackRaw = false ; } //static @@ -296,13 +267,13 @@ void LLImageGL::restoreGL() LLImageGL* glimage = *iter; if(glimage->getTexName()) { - llerrs << "tex name is not 0." << llendl ; + llwarns << "tex name is not 0." << llendl ; } if (glimage->mSaveData.notNull()) { if (glimage->getComponents() && glimage->mSaveData->getComponents()) { - glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData, 0, TRUE, glimage->getCategory()); + glimage->createGLTexture(glimage->mCurrentDiscardLevel, glimage->mSaveData); stop_glerror(); } glimage->mSaveData = NULL; // deletes data @@ -384,7 +355,7 @@ void LLImageGL::init(BOOL usemipmaps) mTextureState = NO_DELETE ; mTextureMemory = 0; mLastBindTime = 0.f; - + mTarget = GL_TEXTURE_2D; mBindTarget = LLTexUnit::TT_TEXTURE; mUseMipMaps = usemipmaps; @@ -411,9 +382,12 @@ void LLImageGL::init(BOOL usemipmaps) mHasExplicitFormat = FALSE; mGLTextureCreated = FALSE ; - mIsMask = FALSE; - mCategory = -1 ; +// mCategory = -1 ; + mCanAddToAtlas = TRUE ; + mDiscardLevelInAtlas = -1 ; + mTexelsInAtlas = 0 ; + mTexelsInGLTexture = 0 ; } void LLImageGL::cleanup() @@ -455,7 +429,7 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents) // Check if dimensions are a power of two! if (!checkSize(width,height)) { - llerrs << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; + llwarns << llformat("Texture has non power of two dimention: %dx%d",width,height) << llendl; } if (mTexName) @@ -513,10 +487,6 @@ void LLImageGL::dump() } //---------------------------------------------------------------------------- -void LLImageGL::forceUpdateBindStats(void) const -{ - mLastBindTime = sLastFrameTime; -} void LLImageGL::updateBindStats(void) const { @@ -530,8 +500,12 @@ void LLImageGL::updateBindStats(void) const { // we haven't accounted for this texture yet this frame sUniqueCount++; - - updateBoundTexMem(); + +//#if !LL_RELEASE_FOR_DOWNLOAD +// updateBoundTexMem(mTextureMemory, getWidth(mCurrentDiscardLevel) * getHeight(mCurrentDiscardLevel)) ; +//#else + updateBoundTexMem(mTextureMemory); +//#endif mLastBindTime = sLastFrameTime; } } @@ -544,7 +518,7 @@ bool LLImageGL::bindError(const S32 stage) const } //virtual -bool LLImageGL::bindDefaultImage(const S32 stage) +bool LLImageGL::bindDefaultImage(const S32 stage) const { return false; } @@ -583,6 +557,7 @@ void LLImageGL::setImage(const LLImageRaw* imageraw) void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) { // LLFastTimer t1(LLFastTimer::FTM_TEMP1); + llpushcallstacks ; bool is_compressed = false; if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) { @@ -590,7 +565,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } // LLFastTimer t2(LLFastTimer::FTM_TEMP2); - gGL.getTexUnit(0)->bind(this); + llverify(gGL.getTexUnit(0)->bind(this, false, true)); if (mUseMipMaps) { @@ -753,7 +728,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } else { - llerrs << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; + llwarns << "Compressed Image has mipmaps but data does not (can not auto generate compressed mips)" << llendl; } mHasMipMaps = true; } @@ -795,10 +770,63 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips) } stop_glerror(); mGLTextureCreated = true; + llpushcallstacks ; +} + +BOOL LLImageGL::canAddToAtlas() +{ + return sUseTextureAtlas && mCanAddToAtlas ; +} + +BOOL LLImageGL::addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) +{ + if(!atlasp) + { + return FALSE ; + } + + preAddToAtlas(raw_image->getWidth()) ; + LLGLuint tex_name = atlasp->insertSubTexture(raw_image, slot_col, slot_row); + postAddToAtlas() ; + + if(tex_name > 0) //successfully added to atlas + { + //gGL.getTexUnit(0)->setHasMipMaps(mHasMipMaps); + //gGL.getTexUnit(0)->setTextureAddressMode(mAddressMode); + gGL.getTexUnit(0)->setTextureFilteringOption(mFilterOption); + return TRUE ; + } + + return FALSE ; +} + +void LLImageGL::preAddToAtlas(S32 data_width) +{ + glPixelStorei(GL_UNPACK_ROW_LENGTH, data_width); + stop_glerror(); + + if(mFormatSwapBytes) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 1); + stop_glerror(); + } } -BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +void LLImageGL::postAddToAtlas() { + if(mFormatSwapBytes) + { + glPixelStorei(GL_UNPACK_SWAP_BYTES, 0); + stop_glerror(); + } + + glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + stop_glerror(); +} + +BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height) +{ + llpushcallstacks ; if (!width || !height) { return TRUE; @@ -814,8 +842,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 return FALSE; } - // HACK: allow the caller to explicitly force the fast path (i.e. using glTexSubImage2D here instead of calling setImage) even when updating the full texture. - if (!force_fast_update && x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) + if (x_pos == 0 && y_pos == 0 && width == getWidth() && height == getHeight() && data_width == width && data_height == height) { setImage(datap, FALSE); } @@ -824,7 +851,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 if (mUseMipMaps) { dump(); - llerrs << "setSubImage called with mipmapped image (not supported)" << llendl; + llwarns << "setSubImage called with mipmapped image (not supported)" << llendl; } llassert_always(mCurrentDiscardLevel == 0); llassert_always(x_pos >= 0 && y_pos >= 0); @@ -833,7 +860,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > getHeight()) { dump(); - llerrs << "Subimage not wholly in target image!" + llwarns << "Subimage not wholly in target image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -847,7 +874,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 (y_pos + height) > data_height) { dump(); - llerrs << "Subimage not wholly in source image!" + llwarns << "Subimage not wholly in source image!" << " x_pos " << x_pos << " y_pos " << y_pos << " width " << width @@ -870,7 +897,7 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 datap += (y_pos * data_width + x_pos) * getComponents(); // Update the GL texture BOOL res = gGL.getTexUnit(0)->bindManual(mBindTarget, mTexName); - if (!res) llerrs << "LLImageGL::setSubImage(): bindTexture failed" << llendl; + if (!res) llwarns << "LLImageGL::setSubImage(): bindTexture failed" << llendl; stop_glerror(); glTexSubImage2D(mTarget, 0, x_pos, y_pos, @@ -888,12 +915,13 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3 stop_glerror(); mGLTextureCreated = true; } + llpushcallstacks ; return TRUE; } -BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update) +BOOL LLImageGL::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height) { - return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height, force_fast_update); + return setSubImage(imageraw->getData(), imageraw->getWidth(), imageraw->getHeight(), x_pos, y_pos, width, height); } // Copy sub image from frame buffer @@ -901,7 +929,6 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_ { if (gGL.getTexUnit(0)->bind(this, false, true)) { - //checkTexSize() ; glCopyTexSubImage2D(GL_TEXTURE_2D, 0, fb_x, fb_y, x_pos, y_pos, width, height); mGLTextureCreated = true; stop_glerror(); @@ -922,13 +949,17 @@ void LLImageGL::generateTextures(S32 numTextures, U32 *textures) // static void LLImageGL::deleteTextures(S32 numTextures, U32 *textures) { - glDeleteTextures(numTextures, (GLuint*)textures); + for (S32 i = 0; i < numTextures; i++) + { + sDeadTextureList.push_back(textures[i]); + } } // static void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels) { glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels); + stop_glerror(); } //create an empty GL texture: just create a texture name @@ -955,21 +986,26 @@ BOOL LLImageGL::createGLTexture() stop_glerror(); if (!mTexName) { - llerrs << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; + llwarns << "LLImageGL::createGLTexture failed to make an empty texture" << llendl; } return TRUE ; } -BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category) +BOOL LLImageGL::createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) { + if(!sUseTextureAtlas) + { + return FALSE ; + } + if (gGLManager.mIsDisabled) { llwarns << "Trying to create a texture while GL is disabled!" << llendl; return FALSE; } - mGLTextureCreated = false ; + // mGLTextureCreated = false ; // KL not in SD llassert(gGLManager.mInited); stop_glerror(); @@ -981,10 +1017,8 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); // Actual image width/height = raw image width/height * 2^discard_level - S32 raw_w = imageraw->getWidth() ; - S32 raw_h = imageraw->getHeight() ; - S32 w = raw_w << discard_level; - S32 h = raw_h << discard_level; + S32 w = imageraw->getWidth() << discard_level; + S32 h = imageraw->getHeight() << discard_level; // setSize may call destroyGLTexture if the size does not match setSize(w, h, imageraw->getComponents()); @@ -1016,27 +1050,87 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S mFormatType = GL_UNSIGNED_BYTE; break; default: - LL_DEBUGS("Openjpeg") << "Bad number of components for texture: " << (U32)getComponents() << LL_ENDL; - to_create = false; - break; + llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; } } - if(!to_create) //not create a gl texture + if(addToAtlas(imageraw, atlasp, slot_col, slot_row)) { - destroyGLTexture(); + // destroyGLTexture(); mCurrentDiscardLevel = discard_level; + mDiscardLevelInAtlas = discard_level; + mTexelsInAtlas = imageraw->getWidth() * imageraw->getHeight() ; mLastBindTime = sLastFrameTime; + mGLTextureCreated = false ; return TRUE ; } + return FALSE ; +} + +BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/) +{ + if (gGLManager.mIsDisabled) + { + llwarns << "Trying to create a texture while GL is disabled!" << llendl; + return FALSE; + } + + mGLTextureCreated = false ; + llassert(gGLManager.mInited); + stop_glerror(); + + if (discard_level < 0) + { + llassert(mCurrentDiscardLevel >= 0); + discard_level = mCurrentDiscardLevel; + } + discard_level = llclamp(discard_level, 0, (S32)mMaxDiscardLevel); + + // Actual image width/height = raw image width/height * 2^discard_level + S32 w = imageraw->getWidth() << discard_level; + S32 h = imageraw->getHeight() << discard_level; + + // setSize may call destroyGLTexture if the size does not match + setSize(w, h, imageraw->getComponents()); + + if( !mHasExplicitFormat ) + { + switch (mComponents) + { + case 1: + // Use luminance alpha (for fonts) + mFormatInternal = GL_LUMINANCE8; + mFormatPrimary = GL_LUMINANCE; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 2: + // Use luminance alpha (for fonts) + mFormatInternal = GL_LUMINANCE8_ALPHA8; + mFormatPrimary = GL_LUMINANCE_ALPHA; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 3: + mFormatInternal = GL_RGB8; + mFormatPrimary = GL_RGB; + mFormatType = GL_UNSIGNED_BYTE; + break; + case 4: + mFormatInternal = GL_RGBA8; + mFormatPrimary = GL_RGBA; + mFormatType = GL_UNSIGNED_BYTE; + break; + default: + llwarns << "Bad number of components for texture: " << (U32)getComponents() << llendl; + } + } - mCategory = category ; const U8* rawdata = imageraw->getData(); return createGLTexture(discard_level, rawdata, FALSE, usename); } BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename) { + llpushcallstacks ; llassert(data_in); if (discard_level < 0) @@ -1073,7 +1167,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ } if (!mTexName) { - llerrs << "LLImageGL::createGLTexture failed to make texture" << llendl; + llwarns << "LLImageGL::createGLTexture failed to make texture" << llendl; } if (mUseMipMaps) @@ -1104,30 +1198,30 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (old_name != 0) { sGlobalTextureMemoryInBytes -= mTextureMemory; - - if(gAuditTexture) - { - decTextureCounter() ; - } +#if !LL_RELEASE_FOR_DOWNLOAD + decTextureCounter(mTextureMemory / mComponents) ; +#endif LLImageGL::deleteTextures(1, &old_name); - stop_glerror(); } mTextureMemory = getMipBytes(discard_level); sGlobalTextureMemoryInBytes += mTextureMemory; + mTexelsInGLTexture = getWidth() * getHeight() ; + +#if !LL_RELEASE_FOR_DOWNLOAD + incTextureCounter(mTextureMemory / mComponents) ; +#endif setActive() ; - if(gAuditTexture) - { - incTextureCounter() ; - } // mark this as bound at this point, so we don't throw it out immediately mLastBindTime = sLastFrameTime; + + llpushcallstacks ; return TRUE; } -#if 0 + BOOL LLImageGL::setDiscardLevel(S32 discard_level) { llassert(discard_level >= 0); @@ -1149,7 +1243,7 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { // larger image dump(); - llerrs << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; + llwarns << "LLImageGL::setDiscardLevel() called with larger discard level; use createGLTexture()" << llendl; return FALSE; } else if (mUseMipMaps) @@ -1174,19 +1268,30 @@ BOOL LLImageGL::setDiscardLevel(S32 discard_level) { #if !LL_LINUX && !LL_SOLARIS // *FIX: This should not be skipped for the linux client. - llerrs << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; + llwarns << "LLImageGL::setDiscardLevel() called on image without mipmaps" << llendl; #endif return FALSE; } } -#endif + +BOOL LLImageGL::isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) +{ + assert_glerror(); + S32 gl_discard = discard_level - mCurrentDiscardLevel; + LLGLint glwidth = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_WIDTH, (GLint*)&glwidth); + LLGLint glheight = 0; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_HEIGHT, (GLint*)&glheight); + LLGLint glcomponents = 0 ; + glGetTexLevelParameteriv(mTarget, gl_discard, GL_TEXTURE_INTERNAL_FORMAT, (GLint*)&glcomponents); + assert_glerror(); + + return glwidth >= image_width && glheight >= image_height && (GL_RGB8 == glcomponents || GL_RGBA8 == glcomponents) ; +} BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok) { - // VWR-13505 : Merov : Allow gl texture read back so save texture works again (temporary) - //llassert_always(sAllowReadBackRaw) ; - //llerrs << "should not call this function!" << llendl ; - + llpushcallstacks ; if (discard_level < 0) { discard_level = mCurrentDiscardLevel; @@ -1291,41 +1396,48 @@ BOOL LLImageGL::readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compre return FALSE ; } //----------------------------------------------------------------------------------------------- - + llpushcallstacks ; return TRUE ; } -void LLImageGL::destroyGLTexture() +void LLImageGL::deleteDeadTextures() { - if (mTexName != 0) + while (!sDeadTextureList.empty()) { - stop_glerror(); - + GLuint tex = sDeadTextureList.front(); + sDeadTextureList.pop_front(); for (int i = 0; i < gGLManager.mNumTextureUnits; i++) { - if (sCurrentBoundTextures[i] == mTexName) + if (sCurrentBoundTextures[i] == tex) { gGL.getTexUnit(i)->unbind(LLTexUnit::TT_TEXTURE); stop_glerror(); } } - + + glDeleteTextures(1, &tex); + stop_glerror(); + } +} + +void LLImageGL::destroyGLTexture() +{ + if (mTexName != 0) + { if(mTextureMemory) { - if(gAuditTexture) - { - decTextureCounter() ; - } +#if !LL_RELEASE_FOR_DOWNLOAD + decTextureCounter(mTextureMemory / mComponents) ; +#endif sGlobalTextureMemoryInBytes -= mTextureMemory; mTextureMemory = 0; } - + LLImageGL::deleteTextures(1, &mTexName); - mTextureState = DELETED ; + mTextureState = DELETED ; mTexName = 0; mCurrentDiscardLevel = -1 ; //invalidate mCurrentDiscardLevel. mGLTextureCreated = FALSE ; - stop_glerror(); } } @@ -1354,12 +1466,12 @@ void LLImageGL::setFilteringOption(LLTexUnit::eTextureFilterOptions option) mFilterOption = option; } - if (gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) + if (mTexName != 0 && gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->getCurrTexture() == mTexName) { gGL.getTexUnit(gGL.getCurrentTexUnitIndex())->setTextureFilteringOption(option); mTexOptionsDirty = false; + stop_glerror(); } - stop_glerror(); } BOOL LLImageGL::getIsResident(BOOL test_now) @@ -1435,11 +1547,6 @@ S32 LLImageGL::getMipBytes(S32 discard_level) const return res; } -BOOL LLImageGL::isJustBound() const -{ - return (BOOL)(sLastFrameTime - mLastBindTime < 0.5f); -} - BOOL LLImageGL::getBoundRecently() const { return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME); @@ -1601,7 +1708,7 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in) U32 pick_offset = pick_bit%8; if (pick_idx >= mPickMaskSize) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } mPickMask[pick_idx] |= 1 << pick_offset; @@ -1627,7 +1734,7 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) if (u < 0.f || u > 1.f || v < 0.f || v > 1.f) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; // WTF really useful info NOT } S32 x = (S32)(u * width); @@ -1650,24 +1757,8 @@ BOOL LLImageGL::getMask(const LLVector2 &tc) return res; } -void LLImageGL::setCategory(S32 category) -{ - if(!gAuditTexture) - { - return ; - } - if(mCategory != category) - { - if(mCategory > -1) - { - sTextureMemByCategory[mCategory] -= mTextureMemory ; - } - sTextureMemByCategory[category] += mTextureMemory ; - - mCategory = category; - } -} - +//---------------------------------------------------------------------------- +#if !LL_RELEASE_FOR_DOWNLOAD //for debug use //val is a "power of two" number S32 LLImageGL::getTextureCounterIndex(U32 val) @@ -1691,38 +1782,18 @@ S32 LLImageGL::getTextureCounterIndex(U32 val) return ret ; } } -void LLImageGL::incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) +void LLImageGL::incTextureCounter(U32 val) { sTextureLoadedCounter[getTextureCounterIndex(val)]++ ; - sTextureMemByCategory[category] += (S32)val * ncomponents ; } -void LLImageGL::decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) +void LLImageGL::decTextureCounter(U32 val) { sTextureLoadedCounter[getTextureCounterIndex(val)]-- ; - sTextureMemByCategory[category] += (S32)val * ncomponents ; -} -void LLImageGL::incTextureCounter() -{ - sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]++ ; - sTextureMemByCategory[mCategory] += mTextureMemory ; -} -void LLImageGL::decTextureCounter() -{ - sTextureLoadedCounter[getTextureCounterIndex(mTextureMemory / mComponents)]-- ; - sTextureMemByCategory[mCategory] -= mTextureMemory ; } -void LLImageGL::setCurTexSizebar(S32 index, BOOL set_pick_size) +void LLImageGL::setCurTexSizebar(S32 index) { sCurTexSizeBar = index ; - - if(set_pick_size) - { - sCurTexPickSize = (1 << index) ; - } - else - { - sCurTexPickSize = -1 ; - } + sCurTexPickSize = (1 << index) ; } void LLImageGL::resetCurTexSizebar() { @@ -1730,9 +1801,7 @@ void LLImageGL::resetCurTexSizebar() sCurTexPickSize = -1 ; } //---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- - +#endif // Manual Mip Generation /* diff --git a/linden/indra/llrender/llimagegl.h b/linden/indra/llrender/llimagegl.h index c7114c3..56f79ff 100644 --- a/linden/indra/llrender/llimagegl.h +++ b/linden/indra/llrender/llimagegl.h @@ -45,18 +45,23 @@ #define BYTES_TO_MEGA_BYTES(x) ((x) >> 20) #define MEGA_BYTES_TO_BYTES(x) ((x) << 20) +class LLTextureAtlas ; //============================================================================ + class LLImageGL : public LLRefCount { friend class LLTexUnit; public: + static std::list sDeadTextureList; + + static void deleteDeadTextures(); + // Size calculation static S32 dataFormatBits(S32 dataformat); static S32 dataFormatBytes(S32 dataformat, S32 width, S32 height); static S32 dataFormatComponents(S32 dataformat); void updateBindStats(void) const; - void forceUpdateBindStats(void) const; // needs to be called every frame static void updateStats(F32 current_time); @@ -65,10 +70,12 @@ public: static void destroyGL(BOOL save_state = TRUE); static void restoreGL(); - // Sometimes called externally for textures not using LLImageGL (should go away...) - static S32 updateBoundTexMemStatic(const S32 delta, const S32 size, S32 category) ; - S32 updateBoundTexMem()const; - + // Sometimes called externally for textures not using LLImageGL (should go away...) +//#if !LL_RELEASE_FOR_DOWNLOAD +// static S32 updateBoundTexMem(const S32 delta, const S32 size) ; +//#else + static S32 updateBoundTexMem(const S32 delta); +//#endif static bool checkSize(S32 width, S32 height); // Not currently necessary for LLImageGL, but required in some derived classes, @@ -90,7 +97,7 @@ protected: public: virtual void dump(); // debugging info to llinfos virtual bool bindError(const S32 stage = 0) const; - virtual bool bindDefaultImage(const S32 stage = 0) ; + virtual bool bindDefaultImage(const S32 stage = 0) const; virtual void forceImmediateUpdate() ; void setSize(S32 width, S32 height, S32 ncomponents); @@ -102,15 +109,14 @@ public: static void setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels); BOOL createGLTexture() ; - BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, - S32 category = sMaxCatagories - 1); + BOOL createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0); BOOL createGLTexture(S32 discard_level, const U8* data, BOOL data_hasmips = FALSE, S32 usename = 0); void setImage(const LLImageRaw* imageraw); void setImage(const U8* data_in, BOOL data_hasmips = FALSE); - BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); - BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height, BOOL force_fast_update = FALSE); + BOOL setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height); + BOOL setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height); BOOL setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_pos, S32 width, S32 height); - + BOOL setDiscardLevel(S32 discard_level); // Read back a raw image for this discard level, if it exists BOOL readBackRaw(S32 discard_level, LLImageRaw* imageraw, bool compressed_ok); void destroyGLTexture(); @@ -130,7 +136,7 @@ public: S32 getBytes(S32 discard_level = -1) const; S32 getMipBytes(S32 discard_level = -1) const; BOOL getBoundRecently() const; - BOOL isJustBound() const; + //BOOL isJustBound() const; LLGLenum getPrimaryFormat() const { return mFormatPrimary; } BOOL getHasGLTexture() const { return mTexName != 0; } @@ -151,6 +157,8 @@ public: BOOL getUseDiscard() const { return mUseMipMaps && !mDontDiscard; } BOOL getDontDiscard() const { return mDontDiscard; } + BOOL isValidForSculpt(S32 discard_level, S32 image_width, S32 image_height, S32 ncomponents) ; + void updatePickMask(S32 width, S32 height, const U8* data_in); BOOL getMask(const LLVector2 &tc); @@ -176,8 +184,20 @@ public: void setActive() ; void forceActive() ; void setNoDelete() ; + + BOOL canAddToAtlas() ; + BOOL createGLTextureInAtlas(S32 discard_level, const LLImageRaw* imageraw, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row); + BOOL addToAtlas(const LLImageRaw* raw_image, LLTextureAtlas* atlasp, S16 slot_col, S16 slot_row) ; + + LLGLenum getTexTarget()const { return mTarget ;} + S8 getDiscardLevelInAtlas()const {return mDiscardLevelInAtlas;} + U32 getTexelsInAtlas()const { return mTexelsInAtlas ;} + U32 getTexelsInGLTexture()const {return mTexelsInGLTexture;} - void setTextureSize(S32 size) {mTextureMemory = size;} +private: + void preAddToAtlas(S32 data_width) ; + void postAddToAtlas() ; + protected: void init(BOOL usemipmaps); virtual void cleanup(); // Clean up the LLImageGL so it can be reinitialized. Be careful when using this in derived class destructors @@ -186,7 +206,7 @@ public: // Various GL/Rendering options S32 mTextureMemory; mutable F32 mLastBindTime; // last time this was bound, by discard level - + private: LLPointer mSaveData; // used for destroyGL/restoreGL U8* mPickMask; //downsampled bitmap approximation of alpha channel. NULL if no alpha channel @@ -202,8 +222,15 @@ private: U16 mWidth; U16 mHeight; S8 mCurrentDiscardLevel; - + + S8 mDiscardLevelInAtlas; + U32 mTexelsInAtlas ; + U32 mTexelsInGLTexture; + protected: + + BOOL mCanAddToAtlas ; + LLGLenum mTarget; // Normally GL_TEXTURE2D, sometimes something else (ex. cube maps) LLTexUnit::eTextureType mBindTarget; // Normally TT_TEXTURE, sometimes something else (ex. cube maps) bool mHasMipMaps; @@ -241,42 +268,18 @@ public: static S32 sCount; static F32 sLastFrameTime; - + static LLGLuint sCurrentBoundTextures[MAX_GL_TEXTURE_UNITS]; // Currently bound texture ID // Global memory statistics static S32 sGlobalTextureMemoryInBytes; // Tracks main memory texmem - static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame + static S32 sBoundTextureMemoryInBytes; // Tracks bound texmem for last completed frame static S32 sCurBoundTextureMemory; // Tracks bound texmem for current frame static U32 sBindCount; // Tracks number of texture binds for current frame static U32 sUniqueCount; // Tracks number of unique texture binds for current frame static BOOL sGlobalUseAnisotropic; -#if DEBUG_MISS - BOOL mMissed; // Missed on last bind? - BOOL getMissed() const { return mMissed; }; -#else - BOOL getMissed() const { return FALSE; }; -#endif - -public: - static void initClass(S32 num_catagories) ; - static void cleanupClass() ; -private: - static S32 sMaxCatagories ; - - //the flag to allow to call readBackRaw(...). - //can be removed if we do not use that function at all. - static BOOL sAllowReadBackRaw ; -// -//**************************************************************************************************** -//The below for texture auditing use only -//**************************************************************************************************** -private: - S32 mCategory ; -public: - void setCategory(S32 category) ; - S32 getCategory()const {return mCategory ;} - + static BOOL sUseTextureAtlas ; +#if !LL_RELEASE_FOR_DOWNLOAD //for debug use: show texture size distribution //---------------------------------------- static LLPointer sDefaultTexturep; //default texture to replace normal textures @@ -287,27 +290,19 @@ public: static S32 sCurTexPickSize ; static S32 getTextureCounterIndex(U32 val) ; - static void incTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; - static void decTextureCounterStatic(U32 val, S32 ncomponents, S32 category) ; - static void setCurTexSizebar(S32 index, BOOL set_pick_size = TRUE) ; + static void incTextureCounter(U32 val) ; + static void decTextureCounter(U32 val) ; + static void setCurTexSizebar(S32 index) ; static void resetCurTexSizebar(); - - void incTextureCounter() ; - void decTextureCounter() ; //---------------------------------------- +#endif - //for debug use: show texture category distribution - //---------------------------------------- - - static std::vector sTextureMemByCategory; - static std::vector sTextureMemByCategoryBound ; - static std::vector sTextureCurMemByCategoryBound ; - //---------------------------------------- -//**************************************************************************************************** -//End of definitions for texture auditing use only -//**************************************************************************************************** - +#if DEBUG_MISS + BOOL mMissed; // Missed on last bind? + BOOL getMissed() const { return mMissed; }; +#else + BOOL getMissed() const { return FALSE; }; +#endif }; -extern BOOL gAuditTexture; #endif // LL_LLIMAGEGL_H diff --git a/linden/indra/llrender/llrender.cpp b/linden/indra/llrender/llrender.cpp index b1fe153..07ba9f1 100644 --- a/linden/indra/llrender/llrender.cpp +++ b/linden/indra/llrender/llrender.cpp @@ -47,7 +47,7 @@ F64 gGLLastModelView[16]; F64 gGLProjection[16]; S32 gGLViewport[4]; -static const U32 LL_NUM_TEXTURE_LAYERS = 8; +static const U32 LL_NUM_TEXTURE_LAYERS = 16; // KL was 8 ( keep a track on this ) 16 in render-pipeline static GLenum sGLTextureType[] = { @@ -192,24 +192,25 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) if (!texture->getTexName()) //if texture does not exist { - if (texture->isDeleted()) - { - // This will re-generate the texture immediately. - texture->forceImmediateUpdate() ; - } + //if deleted, will re-generate it immediately + texture->forceImmediateUpdate() ; - texture->forceUpdateBindStats() ; return texture->bindDefaultImage(mIndex); } - if(gAuditTexture && for_rendering && LLImageGL::sCurTexPickSize > 0) +#if !LL_RELEASE_FOR_DOWNLOAD + if(for_rendering) { - if(texture->getWidth() * texture->getHeight() == LLImageGL::sCurTexPickSize) + int w = texture->getWidth(texture->getDiscardLevel()) ; + int h = texture->getHeight(texture->getDiscardLevel()) ; + + if(w * h == LLImageGL::sCurTexPickSize) { texture->updateBindStats(); return bind(LLImageGL::sDefaultTexturep.get()); } } +#endif if ((mCurrTexture != texture->getTexName()) || forceBind) { @@ -227,7 +228,6 @@ bool LLTexUnit::bind(LLImageGL* texture, bool for_rendering, bool forceBind) setTextureFilteringOption(texture->mFilterOption); } } - return true; } @@ -280,6 +280,11 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) if (bindDepth) { + if (renderTarget->hasStencil()) + { + llwarns << "Cannot bind a render buffer for sampling. Allocate render target without a stencil buffer if sampling of depth buffer is required." << llendl; + } + bindManual(renderTarget->getUsage(), renderTarget->getDepth()); } else @@ -293,15 +298,18 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth) bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips) { - if (mIndex < 0 || mCurrTexture == texture) return false; - - gGL.flush(); + if (mIndex < 0) return false; - activate(); - enable(type); - mCurrTexture = texture; - glBindTexture(sGLTextureType[type], texture); - mHasMipMaps = hasMips; + if(mCurrTexture != texture) + { + gGL.flush(); + + activate(); + enable(type); + mCurrTexture = texture; + glBindTexture(sGLTextureType[type], texture); + mHasMipMaps = hasMips; + } return true; } @@ -414,7 +422,7 @@ void LLTexUnit::setTextureBlendType(eTextureBlendType type) glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); break; default: - llerrs << "Unknown Texture Blend Type: " << type << llendl; + llwarns << "Unknown Texture Blend Type: " << type << llendl; break; } setColorScale(scale_amount); @@ -809,7 +817,7 @@ void LLRender::setSceneBlendType(eBlendType type) glBlendFunc(GL_ONE, GL_ZERO); break; default: - llerrs << "Unknown Scene Blend Type: " << type << llendl; + llwarns << "Unknown Scene Blend Type: " << type << llendl; break; } } @@ -883,7 +891,7 @@ void LLRender::begin(const GLuint& mode) } else if (mCount != 0) { - llerrs << "gGL.begin() called redundantly." << llendl; + llwarns << "gGL.begin() called redundantly." << llendl; } mMode = mode; @@ -914,22 +922,22 @@ void LLRender::flush() #if 0 if (!glIsEnabled(GL_VERTEX_ARRAY)) { - llerrs << "foo 1" << llendl; + llwarns << "foo 1" << llendl; } if (!glIsEnabled(GL_COLOR_ARRAY)) { - llerrs << "foo 2" << llendl; + llwarns << "foo 2" << llendl; } if (!glIsEnabled(GL_TEXTURE_COORD_ARRAY)) { - llerrs << "foo 3" << llendl; + llwarns << "foo 3" << llendl; } if (glIsEnabled(GL_NORMAL_ARRAY)) { - llerrs << "foo 7" << llendl; + llwarns << "foo 7" << llendl; } GLvoid* pointer; @@ -937,19 +945,19 @@ void LLRender::flush() glGetPointerv(GL_VERTEX_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].v)) { - llerrs << "foo 4" << llendl; + llwarns << "foo 4" << llendl; } glGetPointerv(GL_COLOR_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].c)) { - llerrs << "foo 5" << llendl; + llwarns << "foo 5" << llendl; } glGetPointerv(GL_TEXTURE_COORD_ARRAY_POINTER, &pointer); if (pointer != &(mBuffer[0].uv)) { - llerrs << "foo 6" << llendl; + llwarns << "foo 6" << llendl; } #endif diff --git a/linden/indra/llrender/llrendertarget.cpp b/linden/indra/llrender/llrendertarget.cpp index 4cf8451..151b761 100644 --- a/linden/indra/llrender/llrendertarget.cpp +++ b/linden/indra/llrender/llrendertarget.cpp @@ -47,10 +47,10 @@ void check_framebuffer_status() case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; break; default: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } } } @@ -139,9 +139,9 @@ void LLRenderTarget::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments!" << llendl; // KL } U32 tex; @@ -203,7 +203,7 @@ void LLRenderTarget::allocateDepth() gGL.getTexUnit(0)->bindManual(mUsage, mDepth); U32 internal_type = LLTexUnit::getInternalType(mUsage); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); - LLImageGL::setManualImage(internal_type, 0, GL_DEPTH24_STENCIL8_EXT, mResX, mResY, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL); + LLImageGL::setManualImage(internal_type, 0, GL_DEPTH_COMPONENT, mResX, mResY, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL); } } @@ -211,7 +211,7 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target) { if (!mFBO || !target.mFBO) { - llerrs << "Cannot share depth buffer between non FBO render targets." << llendl; + llwarns << "Cannot share depth buffer between non FBO render targets." << llendl; } if (mDepth) @@ -349,16 +349,16 @@ U32 LLRenderTarget::getTexture(U32 attachment) const { if (attachment > mTex.size()-1) { - llerrs << "Invalid attachment index." << llendl; + llwarns << "Invalid attachment index [getTexture]." << llendl; // lets not crash KL its a pain in the ass! } return mTex[attachment]; } void LLRenderTarget::bindTexture(U32 index, S32 channel) { - if (index > mTex.size()-1) + if (index > 6)//mTex.size()-1) // KL yeah i know its a bit arbitary but make the number big enough as some unused render defer elements cause this to go wild { - llerrs << "Invalid attachment index." << llendl; + llwarns << "Invalid attachment index [bindtexture]." << llendl; } gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); } @@ -440,7 +440,7 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, #if !LL_DARWIN if (!source.mFBO || !mFBO) { - llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl; + llwarns << "Cannot copy framebuffer contents for non FBO render targets." << llendl; } if (mSampleBuffer) @@ -449,12 +449,27 @@ void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, } else { - glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); - glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); - - glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + if (mask == GL_DEPTH_BUFFER_BIT && source.mStencil != mStencil) + { + source.bindTarget(); + gGL.getTexUnit(0)->bind(this, true); - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glCopyTexSubImage2D(LLTexUnit::getInternalType(mUsage), 0, srcX0, srcY0, dstX0, dstY0, dstX1, dstY1); + source.flush(); + } + else + { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mFBO); + stop_glerror(); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, mFBO); + stop_glerror(); + check_framebuffer_status(); + stop_glerror(); + glBlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter); + stop_glerror(); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + stop_glerror(); + } } #endif } @@ -553,14 +568,14 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth if (!gGLManager.mHasFramebufferMultisample) { - llerrs << "Attempting to allocate unsupported render target type!" << llendl; + llwarns << "Attempting to allocate unsupported render target type!" << llendl; } mSamples = samples; if (mSamples <= 1) { - llerrs << "Cannot create a multisample buffer with less than 2 samples." << llendl; + llwarns << "Cannot create a multisample buffer with less than 2 samples." << llendl; } stop_glerror(); @@ -608,9 +623,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) U32 offset = mTex.size(); if (offset >= 4 || - (offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers))) + offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers)) { - llerrs << "Too many color attachments!" << llendl; + llwarns << "Too many color attachments!" << llendl; } U32 tex; @@ -631,10 +646,10 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt) case GL_FRAMEBUFFER_COMPLETE_EXT: break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; break; default: - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); diff --git a/linden/indra/llrender/llrendertarget.h b/linden/indra/llrender/llrendertarget.h index d5d809b..69af1ea 100644 --- a/linden/indra/llrender/llrendertarget.h +++ b/linden/indra/llrender/llrendertarget.h @@ -121,6 +121,7 @@ public: U32 getTexture(U32 attachment = 0) const; U32 getDepth(void) const { return mDepth; } + BOOL hasStencil() const { return mStencil; } void bindTexture(U32 index, S32 channel); diff --git a/linden/indra/llrender/lltextureatlas.cpp b/linden/indra/llrender/lltextureatlas.cpp new file mode 100644 index 0000000..c0f5419 --- /dev/null +++ b/linden/indra/llrender/lltextureatlas.cpp @@ -0,0 +1,411 @@ +/** + * @file lltextureatlas.cpp + * @brief LLTextureAtlas class implementation. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "linden_common.h" +#include "llerror.h" +#include "llimage.h" +#include "llmath.h" +#include "llgl.h" +#include "llrender.h" +#include "lltextureatlas.h" + +//------------------- +S16 LLTextureAtlas::sMaxSubTextureSize = 64 ; +S16 LLTextureAtlas::sSlotSize = 32 ; + +#ifndef DEBUG_ATLAS +#define DEBUG_ATLAS 0 +#endif + +#ifndef DEBUG_USAGE_BITS +#define DEBUG_USAGE_BITS 0 +#endif +//************************************************************************************************************** +LLTextureAtlas::LLTextureAtlas(U8 ncomponents, S16 atlas_dim) : LLImageGL(), + mAtlasDim(atlas_dim) +{ + setComponents(ncomponents) ; + + mCanAddToAtlas = FALSE ;//do not add one atlas to another. + mNumSlotsReserved = 0 ; + mMaxSlotsInAtlas = mAtlasDim * mAtlasDim ; + + generateEmptyUsageBits() ; + + //generate an empty texture + S32 dim = mAtlasDim * sSlotSize ; //number of pixels per dimension + LLPointer image_raw = new LLImageRaw(dim, dim, getComponents()); + createGLTexture(0, image_raw, 0); + image_raw = NULL; + dontDiscard(); +} + +LLTextureAtlas::~LLTextureAtlas() +{ + if(mSpatialGroupList.size() > 0) + { + llwarns << "Not clean up the spatial groups!" << llendl ; + } + releaseUsageBits() ; +} + +void LLTextureAtlas::getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yoffset) +{ +#if !DEBUG_ATLAS + xoffset = (F32)col / mAtlasDim ; + yoffset = (F32)row / mAtlasDim ; +#endif +} + +void LLTextureAtlas::getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) +{ +#if !DEBUG_ATLAS + xscale = (F32)w / (mAtlasDim * sSlotSize) ; + yscale = (F32)h / (mAtlasDim * sSlotSize) ; +#endif +} + +//insert a texture piece into the atlas +LLGLuint LLTextureAtlas::insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) +{ + S32 w = raw_image->getWidth() ; + S32 h = raw_image->getHeight() ; + if(w < 8 || w > sMaxSubTextureSize || h < 8 || h > sMaxSubTextureSize) + { + //size overflow + return 0 ; + } + + BOOL res = gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, getTexName()); + if (!res) llwarns << "bindTexture failed" << llendl; + stop_glerror(); + + GLint xoffset = sSlotSize * slot_col ; + GLint yoffset = sSlotSize * slot_row ; + + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP_SGIS, TRUE); + glTexSubImage2D(GL_TEXTURE_2D, 0, xoffset, yoffset, + w, h, mFormatPrimary, mFormatType, raw_image->getData()); + + return getTexName(); +} + +//release a sub-texture slot from the atlas +void LLTextureAtlas::releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width) +{ + unmarkUsageBits(slot_width, slot_col, slot_row) ; + mNumSlotsReserved -= slot_width * slot_width ; +} + +BOOL LLTextureAtlas::isEmpty() const +{ + return !mNumSlotsReserved ; +} + +BOOL LLTextureAtlas::isFull(S8 to_be_reserved) const +{ + return mNumSlotsReserved + to_be_reserved > mMaxSlotsInAtlas ; +} +F32 LLTextureAtlas::getFullness() const +{ + return (F32)mNumSlotsReserved / mMaxSlotsInAtlas ; +} + +void LLTextureAtlas::addSpatialGroup(LLSpatialGroup* groupp) +{ + if(groupp && !hasSpatialGroup(groupp)) + { + mSpatialGroupList.push_back(groupp); + } +} + +void LLTextureAtlas::removeSpatialGroup(LLSpatialGroup* groupp) +{ + if(groupp) + { + mSpatialGroupList.remove(groupp); + } +} + +void LLTextureAtlas::clearSpatialGroup() +{ + mSpatialGroupList.clear(); +} +void LLTextureAtlas::removeLastSpatialGroup() +{ + mSpatialGroupList.pop_back() ; +} + +LLSpatialGroup* LLTextureAtlas::getLastSpatialGroup() +{ + if(mSpatialGroupList.size() > 0) + { + return mSpatialGroupList.back() ; + } + return NULL ; +} + +BOOL LLTextureAtlas::hasSpatialGroup(LLSpatialGroup* groupp) +{ + for(std::list::iterator iter = mSpatialGroupList.begin(); iter != mSpatialGroupList.end() ; ++iter) + { + if(*iter == groupp) + { + return TRUE ; + } + } + return FALSE ; +} + +//-------------------------------------------------------------------------------------- +//private +void LLTextureAtlas::generateEmptyUsageBits() +{ + S32 col_len = (mAtlasDim + 7) >> 3 ; + mUsageBits = new U8*[mAtlasDim] ; + *mUsageBits = new U8[mAtlasDim * col_len] ; + + mUsageBits[0] = *mUsageBits ; + for(S32 i = 1 ; i < mAtlasDim ; i++) + { + mUsageBits[i] = mUsageBits[i-1] + col_len ; + + for(S32 j = 0 ; j < col_len ; j++) + { + //init by 0 for all bits. + mUsageBits[i][j] = 0 ; + } + } + + //do not forget mUsageBits[0]! + for(S32 j = 0 ; j < col_len ; j++) + { + //init by 0 for all bits. + mUsageBits[0][j] = 0 ; + } + + mTestBits = NULL ; +#if DEBUG_USAGE_BITS + //------------ + //test + mTestBits = new U8*[mAtlasDim] ; + *mTestBits = new U8[mAtlasDim * mAtlasDim] ; + mTestBits[0] = *mTestBits ; + for(S32 i = 1 ; i < mAtlasDim ; i++) + { + mTestBits[i] = mTestBits[i-1] + mAtlasDim ; + + for(S32 j = 0 ; j < mAtlasDim ; j++) + { + //init by 0 for all bits. + mTestBits[i][j] = 0 ; + } + } + + for(S32 j = 0 ; j < mAtlasDim ; j++) + { + //init by 0 for all bits. + mTestBits[0][j] = 0 ; + } +#endif +} + +void LLTextureAtlas::releaseUsageBits() +{ + if(mUsageBits) + { + delete[] *mUsageBits ; + delete[] mUsageBits ; + } + mUsageBits = NULL ; + + //test + if( mTestBits) + { + delete[] *mTestBits; + delete[] mTestBits; + } + mTestBits = NULL ; +} + +void LLTextureAtlas::markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) +{ + S16 x = col >> 3 ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + mUsageBits[row + i][x] |= mask ; + } + +#if DEBUG_USAGE_BITS + //test + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + mTestBits[i][j] = 1 ; + } + } +#endif +} + +void LLTextureAtlas::unmarkUsageBits(S8 bits_len, S16 col, S16 row) +{ + S16 x = col >> 3 ; + U8 mask = 1 ; + for(S8 i = 1 ; i < bits_len ; i++) + { + mask |= (1 << i) ; + } + mask <<= (col & 7) ; + mask = ~mask ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + mUsageBits[row + i][x] &= mask ; + } + +#if DEBUG_USAGE_BITS + //test + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + mTestBits[i][j] = 0 ; + } + } +#endif +} + +//return true if any of bits in the range marked. +BOOL LLTextureAtlas::areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) +{ + BOOL ret = FALSE ; + S16 x = col >> 3 ; + + for(S8 i = 0 ; i < bits_len ; i++) + { + if(mUsageBits[row + i][x] & mask) + { + ret = TRUE ; + break ; + //return TRUE ; + } + } + +#if DEBUG_USAGE_BITS + //test + BOOL ret2 = FALSE ; + for(S8 i = row ; i < row + bits_len ; i++) + { + for(S8 j = col ; j < col + bits_len ; j++) + { + if(mTestBits[i][j]) + { + ret2 = TRUE ; + } + } + } + + if(ret != ret2) + { + llwarns << "bits map corrupted." << llendl ; + } +#endif + return ret ;//FALSE ; +} + +//---------------------------------------------------------------------- +// +//index order: Z order, i.e.: +// |-----|-----|-----|-----| +// | 10 | 11 | 14 | 15 | +// |-----|-----|-----|-----| +// | 8 | 9 | 12 | 13 | +// |-----|-----|-----|-----| +// | 2 | 3 | 6 | 7 | +// |-----|-----|-----|-----| +// | 0 | 1 | 4 | 5 | +// |-----|-----|-----|-----| +void LLTextureAtlas::getPositionFromIndex(S16 index, S16& col, S16& row) +{ + col = 0 ; + row = 0 ; + + S16 index_copy = index ; + for(S16 i = 0 ; index_copy && i < 16 ; i += 2) + { + col |= ((index & (1 << i)) >> i) << (i >> 1) ; + row |= ((index & (1 << (i + 1))) >> (i + 1)) << (i >> 1) ; + index_copy >>= 2 ; + } +} +void LLTextureAtlas::getIndexFromPosition(S16 col, S16 row, S16& index) +{ + index = 0 ; + S16 col_copy = col ; + S16 row_copy = row ; + for(S16 i = 0 ; (col_copy || row_copy) && i < 16 ; i++) + { + index |= ((col & 1 << i) << i) | ((row & 1 << i) << ( i + 1)) ; + col_copy >>= 1 ; + row_copy >>= 1 ; + } +} +//---------------------------------------------------------------------- +//return TRUE if succeeds. +BOOL LLTextureAtlas::getNextAvailableSlot(S8 bits_len, S16& col, S16& row) +{ + S16 index_step = bits_len * bits_len ; + + U8 mask = 1 ; + for(S8 i = 1 ; i < bits_len ; i++) + { + mask |= (1 << i) ; + } + + U8 cur_mask ; + for(S16 index = 0 ; index < mMaxSlotsInAtlas ; index += index_step) + { + getPositionFromIndex(index, col, row) ; + + cur_mask = mask << (col & 7) ; + if(!areUsageBitsMarked(bits_len, cur_mask, col, row)) + { + markUsageBits(bits_len, cur_mask, col, row) ; + mNumSlotsReserved += bits_len * bits_len ; + + return TRUE ; + } + } + + return FALSE ; +} diff --git a/linden/indra/llrender/lltextureatlas.h b/linden/indra/llrender/lltextureatlas.h new file mode 100644 index 0000000..4922175 --- /dev/null +++ b/linden/indra/llrender/lltextureatlas.h @@ -0,0 +1,92 @@ +/** + * @file lltextureatlas.h + * @brief LLTextureAtlas base class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef LL_TEXTUREATLAS_H +#define LL_TEXTUREATLAS_H + +#include "llimagegl.h" +class LLSpatialGroup ; + +class LLTextureAtlas : public LLImageGL +{ +public: + LLTextureAtlas(U8 ncomponents, S16 atlas_dim = 16) ; + ~LLTextureAtlas() ; + + LLGLuint insertSubTexture(const LLImageRaw* raw_image, S16 slot_col, S16 slot_row) ; + void releaseSlot(S16 slot_col, S16 slot_row, S8 slot_width); + + BOOL getNextAvailableSlot(S8 bits_len, S16& col, S16& row) ; + void getTexCoordOffset(S16 col, S16 row, F32& xoffset, F32& yOffset) ; + void getTexCoordScale(S32 w, S32 h, F32& xscale, F32& yscale) ; + + BOOL isEmpty() const ; + BOOL isFull(S8 to_be_reserved = 1) const ; + F32 getFullness() const ; + + void addSpatialGroup(LLSpatialGroup* groupp) ; + void removeSpatialGroup(LLSpatialGroup* groupp) ; + LLSpatialGroup* getLastSpatialGroup() ; + void removeLastSpatialGroup() ; + BOOL hasSpatialGroup(LLSpatialGroup* groupp) ; + void clearSpatialGroup() ; + std::list* getSpatialGroupList() {return &mSpatialGroupList;} +private: + void generateEmptyUsageBits() ; + void releaseUsageBits() ; + + void markUsageBits(S8 bits_len, U8 mask, S16 col, S16 row) ; + void unmarkUsageBits(S8 bits_len, S16 col, S16 row) ; + + void getPositionFromIndex(S16 index, S16& col, S16& row) ; + void getIndexFromPosition(S16 col, S16 row, S16& index) ; + BOOL areUsageBitsMarked(S8 bits_len, U8 mask, S16 col, S16 row) ; + +private: + S16 mAtlasDim ; //number of slots per edge, i.e, there are "mAtlasDim * mAtlasDim" total slots in the atlas. + S16 mNumSlotsReserved ; + S16 mMaxSlotsInAtlas ; + U8 **mUsageBits ; + std::list mSpatialGroupList ; + +public: + //debug use only + U8 **mTestBits ; + +public: + static S16 sMaxSubTextureSize ; + static S16 sSlotSize ; +}; + +#endif + diff --git a/linden/indra/llrender/llvertexbuffer.cpp b/linden/indra/llrender/llvertexbuffer.cpp index 461edbe..31c2d75 100644 --- a/linden/indra/llrender/llvertexbuffer.cpp +++ b/linden/indra/llrender/llvertexbuffer.cpp @@ -96,7 +96,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { /*if (LLGLImmediate::sStarted) { - llerrs << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; + llwarns << "Cannot use LLGLImmediate and LLVertexBuffer simultaneously!" << llendl; }*/ if (sLastMask != data_mask) @@ -129,7 +129,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) { //needs to be enabled, make sure it was (DEBUG TEMPORARY) if (i > 0 && !glIsEnabled(array[i])) { - llerrs << "Bad client state! " << array[i] << " disabled." << llendl; + llwarns << "Bad client state! " << array[i] << " disabled." << llendl; } } } @@ -141,7 +141,7 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask) } else if (gDebugGL && glIsEnabled(array[i])) { //needs to be disabled, make sure it was (DEBUG TEMPORARY) - llerrs << "Bad client state! " << array[i] << " enabled." << llendl; + llwarns << "Bad client state! " << array[i] << " enabled." << llendl; } } } @@ -197,28 +197,28 @@ void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indi if (start >= (U32) mRequestedNumVerts || end >= (U32) mRequestedNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; + llwarns << "Bad vertex buffer draw range: [" << start << ", " << end << "]" << llendl; } if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llerrs << "Wrong index buffer bound." << llendl; + llwarns << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -233,22 +233,22 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const if (indices_offset >= (U32) mRequestedNumIndices || indices_offset + count > (U32) mRequestedNumIndices) { - llerrs << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; + llwarns << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << llendl; } if (mGLIndices != sGLRenderIndices) { - llerrs << "Wrong index buffer bound." << llendl; + llwarns << "Wrong index buffer bound." << llendl; } if (mGLBuffer != sGLRenderBuffer) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -263,17 +263,17 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const if (first >= (U32) mRequestedNumVerts || first + count > (U32) mRequestedNumVerts) { - llerrs << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; + llwarns << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << llendl; } if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) { - llerrs << "Wrong vertex buffer bound." << llendl; + llwarns << "Wrong vertex buffer bound." << llendl; } if (mode > LLRender::NUM_MODES) { - llerrs << "Invalid draw mode: " << mode << llendl; + llwarns << "Invalid draw mode: " << mode << llendl; return; } @@ -530,7 +530,7 @@ void LLVertexBuffer::destroyGLBuffer() { if (mMappedData || mMappedIndexData) { - llerrs << "Vertex buffer destroyed while mapped!" << llendl; + llwarns << "Vertex buffer destroyed while mapped!" << llendl; } releaseBuffer(); } @@ -557,7 +557,7 @@ void LLVertexBuffer::destroyGLIndices() { if (mMappedData || mMappedIndexData) { - llerrs << "Vertex buffer destroyed while mapped." << llendl; + llwarns << "Vertex buffer destroyed while mapped." << llendl; } releaseIndices(); } @@ -634,7 +634,7 @@ void LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) if (mMappedData) { - llerrs << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; + llwarns << "LLVertexBuffer::allocateBuffer() called redundantly." << llendl; } if (create && (nverts || nindices)) { @@ -782,11 +782,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mFinal) { - llerrs << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; + llwarns << "LLVertexBuffer::mapBuffer() called on a finalized buffer." << llendl; } if (!useVBOs() && !mMappedData && !mMappedIndexData) { - llerrs << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; + llwarns << "LLVertexBuffer::mapBuffer() called on unallocated buffer." << llendl; } if (!mLocked && useVBOs()) @@ -813,11 +813,11 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } - llerrs << "glMapBuffer returned NULL (no vertex data)" << llendl; + llwarns << "glMapBuffer returned NULL (no vertex data)" << llendl; } if (!mMappedIndexData) @@ -826,10 +826,10 @@ U8* LLVertexBuffer::mapBuffer(S32 access) glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); if (buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } - llerrs << "glMapBuffer returned NULL (no index data)" << llendl; + llwarns << "glMapBuffer returned NULL (no index data)" << llendl; } sMappedCount++; @@ -908,7 +908,7 @@ template struct VertexBufferStrider } else { - llerrs << "VertexBufferStrider could not find valid vertex data." << llendl; + llwarns << "VertexBufferStrider could not find valid vertex data." << llendl; } return FALSE; } @@ -965,7 +965,7 @@ void LLVertexBuffer::setStride(S32 type, S32 new_stride) LLMemType mt(LLMemType::MTYPE_VERTEX_DATA); if (mNumVerts) { - llerrs << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; + llwarns << "LLVertexBuffer::setOffset called with mNumVerts = " << mNumVerts << llendl; } // This code assumes that setStride() will only be called once per VBO per type. S32 delta = new_stride - sTypeOffsets[type]; @@ -1020,15 +1020,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLBuffer) + if ((GLuint)buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLIndices) + if ((GLuint)buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1038,15 +1038,15 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { GLint buff; glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLBuffer) + if ((GLuint)buff != mGLBuffer) { - llerrs << "Invalid GL vertex buffer bound: " << buff << llendl; + llwarns << "Invalid GL vertex buffer bound: " << buff << llendl; } glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); - if (buff != mGLIndices) + if ((GLuint)buff != mGLIndices) { - llerrs << "Invalid GL index buffer bound: " << buff << llendl; + llwarns << "Invalid GL index buffer bound: " << buff << llendl; } } @@ -1068,7 +1068,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (data_mask != 0) { - llerrs << "Buffer set for rendering before being filled after resize." << llendl; + llwarns << "Buffer set for rendering before being filled after resize." << llendl; } } @@ -1129,7 +1129,7 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) const if ((data_mask & mTypeMask) != data_mask) { - llerrs << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; + llwarns << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << llendl; } if (data_mask & MAP_NORMAL) diff --git a/linden/indra/newview/CMakeLists.txt b/linden/indra/newview/CMakeLists.txt index e0c6c61..6fd259a 100644 --- a/linden/indra/newview/CMakeLists.txt +++ b/linden/indra/newview/CMakeLists.txt @@ -329,6 +329,7 @@ set(viewer_SOURCE_FILES llpolymesh.cpp llpolymorph.cpp llprefsadvanced.cpp + llpostprocess.cpp llprefschat.cpp llprefsim.cpp llprefsvoice.cpp @@ -359,6 +360,7 @@ set(viewer_SOURCE_FILES llsurface.cpp llsurfacepatch.cpp lltexlayer.cpp + lltextureatlasmanager.cpp lltexturecache.cpp lltexturectrl.cpp lltexturefetch.cpp @@ -777,6 +779,7 @@ set(viewer_HEADER_FILES llpolymesh.h llpolymorph.h llprefsadvanced.h + llpostprocess.h llprefschat.h llprefsim.h llprefsvoice.h @@ -809,6 +812,7 @@ set(viewer_HEADER_FILES llsurfacepatch.h lltable.h lltexlayer.h + lltextureatlasmanager.h lltexturecache.h lltexturectrl.h lltexturefetch.h diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index f70c0fc..c7f8d36 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml @@ -5097,6 +5097,21 @@ Value 1 + + + EnableTextureAtlas + + Comment + Whether to use texture atlas or not + Persist + 1 + Type + Boolean + Value + 0 + + + EnableVoiceChat Comment @@ -8928,11 +8943,74 @@ Vector3 Value + 1.0 + 12.0 + 32.0 + + + RenderShadowSplitExponent + + Comment + Near clip plane split distances for shadow map frusta (x=perspective, y=ortho, z=transition rate). + Persist + 1 + Type + Vector3 + Value + + 3.0 + 3.0 + 2.0 + + + RenderShadowOrthoClipPlanes + + Comment + Near clip plane split distances for orthographic shadow map frusta. + Persist + 1 + Type + Vector3 + Value + 4.0 8.0 24.0 + RenderShadowProjOffset + + Comment + Amount to scale distance to virtual origin of shadow perspective projection. + Persist + 1 + Type + F32 + Value + 2.0 + + RenderShadowSlopeThreshold + + Comment + Cutoff slope value for points to affect perspective shadow generation + Persist + 1 + Type + F32 + Value + 0.0 + + RenderShadowProjExponent + + Comment + Exponent applied to transition between ortho and perspective shadow projections based on viewing angle and light vector. + Persist + 1 + Type + F32 + Value + 0.5 + RenderSSAOScale Comment @@ -9092,6 +9170,184 @@ Value 0 + + RenderGILightRadius + + Comment + Distance of ambiant bounce lighting from sun. + Persist + 1 + Type + F32 + Value + 8 + + + RenderGISamples + + Comment + Number of samples to take for GI. + Persist + 1 + Type + U32 + Value + 64 + + + RenderGIRange + + Comment + Distance to cut off GI effect. + Persist + 1 + Type + F32 + Value + 128 + + + + RenderGIDirectionWeight + + Comment + Weight of reflected light vector in GI angular attenuation. + Persist + 1 + Type + F32 + Value + 0.5 + + + RenderGILightOffset + + Comment + Amount to offset light from point of impact in gi map (scaled by light radius). + Persist + 1 + Type + F32 + Value + 0.0 + + + RenderGIColorCurve + + Comment + Global illumination color correction curve parameters. + Persist + 1 + Type + Vector3 + Value + + 0.0 + 0.2 + 0.02 + + + + RenderLuminanceColorCurve + + Comment + Luminance color correction curve parameters. + Persist + 1 + Type + Vector3 + Value + + 0.30 + 0.0 + 0.04 + + + + RenderGILuminanceColorCurve + + Comment + Luminance color correction curve parameters. + Persist + 1 + Type + Vector3 + Value + + 0.4 + 0.0 + 0.05 + + + + RenderSunLuminanceColorCurve + + Comment + Luminance color correction curve parameters. + Persist + 1 + Type + Vector3 + Value + + 0.6 + 0.0 + -0.3 + + + + RenderLuminanceDetail + + Comment + Mipmap level to use for luminance + Persist + 1 + Type + F32 + Value + 8.0 + + + RenderLuminanceFade + + Comment + Scaler for speed of luminance adjustment + Persist + 1 + Type + F32 + Value + 0.05 + + + RenderGISpecularCurve + + Comment + Global illumination specular color correction curve parameters. + Persist + 1 + Type + Vector3 + Value + + 0.1 + 0.0 + 0.9 + + + + RenderGIIntensity + + Comment + Distance of ambiant bounce lighting from sun. + Persist + 1 + Type + F32 + Value + 0.2f + + RenderDeferredAlphaSoften Comment @@ -9114,89 +9370,472 @@ Value 4 - RenderDeferred + RenderDeferredSpotShadowBias Comment - Use deferred rendering pipeline. + Bias value for spot shadows (prevent shadow acne). Persist 1 Type - Boolean + F32 Value - 0 + -64.0 - RenderDeferredSunShadow + RenderDeferredSpotShadowOffset Comment - Generate shadows from the sun. + Offset value for spot shadows (prevent shadow acne). Persist 1 Type - Boolean + F32 Value + 0.8 + + + RenderShadowBias + + Comment + Bias value for shadows (prevent shadow acne). + Persist 1 + Type + F32 + Value + 0.001 - RenderDeferredSunWash + RenderShadowOffset Comment - Amount local lights are washed out by sun. + Offset value for shadows (prevent shadow acne). Persist 1 Type F32 Value - 0.5 + 0.6 - RenderShadowNoise + + RenderShadowResolutionScale Comment - Magnitude of noise on shadow samples. + Scale of shadow map resolution vs. screen resolution Persist 1 Type F32 Value - -0.0001 + 1.0 - RenderShadowBlurSize + + + + RenderDeferredTreeShadowBias Comment - Scale of shadow softening kernel. + Bias value for tree shadows (prevent shadow acne). Persist 1 Type F32 Value - 0.7 + 1.0 - RenderShadowBlurSamples + RenderDeferredTreeShadowOffset Comment - Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1. + Offset value for tree shadows (prevent shadow acne). Persist 1 Type - U32 + F32 Value - 5 + 1.0 - RenderDynamicLOD - - Comment - Dynamically adjust level of detail. - Persist - 1 - Type - Boolean - Value - 1 - - RenderFSAASamples - - Comment - Number of samples to use for FSAA (0 = no AA). - Persist - 1 + + RenderHighlightFadeTime + + Comment + Transition time for mouseover highlights. + Persist + 1 + Type + F32 + Value + 0.2 + + + RenderHighlightBrightness + + Comment + Brightness of mouseover highlights. + Persist + 1 + Type + F32 + Value + 4.0 + + + RenderHighlightThickness + + Comment + Thickness of mouseover highlights. + Persist + 1 + Type + F32 + Value + 0.6 + + + RenderHighlightColor + + Comment + Brightness of mouseover highlights. + Persist + 1 + Type + Color4 + Value + + 0.4 + 0.98 + 0.93 + 1.0 + + + + RenderSpecularResX + + Comment + Spec map resolution. + Persist + 1 + Type + U32 + Value + 128 + + + RenderSpecularResY + + Comment + Spec map resolution. + Persist + 1 + Type + U32 + Value + 128 + + + RenderSpecularExponent + + Comment + Specular exponent for generating spec map + Persist + 1 + Type + F32 + Value + 1 + + + RenderDeferred + + Comment + Use deferred rendering pipeline. + Persist + 1 + Type + Boolean + Value + 0 + + + RenderDeferredShadow + + Comment + Enable shadows in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredGI + + Comment + Enable GI in deferred renderer. + Persist + 1 + Type + Boolean + Value + 0 + + + RenderDeferredSunShadow + + Comment + Generate shadows from the sun. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredSun + + Comment + Execute sunlight shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredAtmospheric + + Comment + Execute atmospheric shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredBlurLight + + Comment + Execute shadow softening shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredLocalLights + + Comment + Execute local lighting shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredFullscreenLights + + Comment + Execute local lighting shader in deferred renderer. + Persist + 1 + Type + Boolean + Value + 1 + + + RenderDeferredSunWash + + Comment + Amount local lights are washed out by sun. + Persist + 1 + Type + F32 + Value + 0.5 + + RenderShadowNoise + + Comment + Magnitude of noise on shadow samples. + Persist + 1 + Type + F32 + Value + -0.0001 + + RenderShadowErrorCutoff + + Comment + Cutoff error value to use ortho instead of perspective projection. + Persist + 1 + Type + F32 + Value + 5.0 + + RenderShadowFOVCutoff + + Comment + Cutoff FOV to use ortho instead of perspective projection. + Persist + 1 + Type + F32 + Value + 1.1 + + + RenderShadowGaussian + + Comment + Gaussian coefficients for the two shadow/SSAO blurring passes (z component unused). + Persist + 1 + Type + Vector3 + Value + + 3.0 + 2.0 + 0.0 + + + + RenderShadowBlurSize + + Comment + Scale of shadow softening kernel. + Persist + 1 + Type + F32 + Value + 0.8 + + RenderShadowBlurSamples + + Comment + Number of samples to take for each pass of shadow blur (value range 1-16). Actual number of samples is value * 2 - 1. + Persist + 1 + Type + U32 + Value + 4 + + RenderShadowBlurDistFactor + + Comment + Distance scaler for shadow blur. + Persist + 1 + Type + F32 + Value + 0.1 + + + RenderGIBlurColorCurve + + Comment + Color curve for GI softening kernel + Persist + 1 + Type + Vector3 + Value + + 1.0 + 0.6 + 0.1 + + + + RenderGIGaussian + + Comment + Gaussian coefficient for the two GI blurring passes. + Persist + 1 + Type + F32 + Value + 64 + + + RenderGIBlurPasses + + Comment + Scale of GI softening kernel. + Persist + 1 + Type + U32 + Value + 2 + + + RenderGIBlurSize + + Comment + Scale of GI softening kernel. + Persist + 1 + Type + F32 + Value + 3.0 + + RenderGIBlurSamples + + Comment + Number of samples to take for each pass of GI blur (value range 1-16). Actual number of samples is value * 2 - 1. + Persist + 1 + Type + U32 + Value + 6 + + RenderGIBlurDistFactor + + Comment + Distance scaler for GI blur. + Persist + 1 + Type + F32 + Value + 0.0 + + + RenderDynamicLOD + + Comment + Dynamically adjust level of detail. + Persist + 1 + Type + Boolean + Value + 1 + + RenderFSAASamples + + Comment + Number of samples to use for FSAA (0 = no AA). + Persist + 1 Type U32 Value @@ -9430,6 +10069,17 @@ Value 0 + RenderHighlightSelections + + Comment + Show selection outlines on objects + Persist + 1 + Type + Boolean + Value + 1 + RenderHiddenSelections Comment @@ -9738,6 +10388,17 @@ Value 0 + RenderUIBuffer + + Comment + Cache ui render in a screen aligned buffer. + Persist + 1 + Type + Boolean + Value + 0 + RenderUnloadedAvatar Comment diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index a91e9fa..f90d91f 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -13,9 +13,9 @@ uniform sampler2DShadow shadowMap1; uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -26,15 +26,31 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_light; uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; + vec3 samp_pos = getPosition(frag).xyz; float shadow = 1.0; vec4 pos = vec4(vary_position, 1.0); @@ -82,7 +98,7 @@ void main() //gl_FragColor = gl_Color; gl_FragColor = color; - //gl_FragColor = vec4(1,0,1,1); + //gl_FragColor = vec4(1,0,1,1)*shadow; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index b496bd6..48baf77 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -20,8 +20,11 @@ varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_fragcoord; varying vec3 vary_position; +varying vec3 vary_light; uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; void main() { @@ -32,8 +35,9 @@ void main() vec4 pos = (gl_ModelViewMatrix * gl_Vertex); vec3 norm = normalize(gl_NormalMatrix * gl_Normal); - vary_position = pos.xyz; - + // KL this works around ATI not compiling the shader but maintains shadow offset and bias vec3 not vec4 + vary_position = pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias); + calcAtmospherics(pos.xyz); //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); @@ -54,6 +58,8 @@ void main() col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); col.rgb = scaleDownLight(col.rgb); + vary_light = gl_LightSource[0].position.xyz; + vary_ambient = col.rgb*gl_Color.rgb; vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl index 6c94f5c..ff64a6b 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaF.glsl @@ -12,7 +12,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; vec3 atmosLighting(vec3 light); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 58aa5a9..4b9cca2 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -8,13 +8,18 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { - gl_FragData[0] = gl_Color * texture2D(diffuseMap, gl_TexCoord[0].xy); + vec4 diff = gl_Color*texture2D(diffuseMap, gl_TexCoord[0].xy); + // Viewer 2.0 uses 0.2 but for KL's viewer if i want a complete avatar need this to be 0.0 for now. + if (diff.a < 0.0) + { + discard; + } + + gl_FragData[0] = vec4(diff.rgb, 1.0); gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 27c09db..00083eb 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -10,6 +10,7 @@ uniform sampler2D diffuseMap; void main() { - gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy)); + gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); + //gl_FragColor = vec4(1,1,1,1); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl index 14da6b1..8c8489d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarShadowV.glsl @@ -28,8 +28,7 @@ void main() norm = normalize(norm); pos = gl_ProjectionMatrix * pos; - //smash geometry against near clip plane - pos.z = max(pos.z, -1.0); + pos.z = max(pos.z, -pos.w+0.01); gl_Position = pos; gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl index 12a7ff7..471a1f0 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/avatarV.glsl @@ -10,7 +10,6 @@ mat4 getSkinnedTransform(); attribute vec4 weight; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -30,7 +29,6 @@ void main() norm.z = dot(trans[2].xyz, gl_Normal); norm = normalize(norm); - vary_position = pos; vary_normal = norm; gl_Position = gl_ProjectionMatrix * pos; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index 3c6700a..1713fe9 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -7,10 +7,11 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; +uniform sampler2DRect depthMap; uniform sampler2DRect normalMap; uniform sampler2DRect lightMap; +uniform float dist_factor; uniform float blur_size; uniform vec2 delta; uniform vec3 kern[32]; @@ -19,30 +20,52 @@ uniform float kern_scale; varying vec2 vary_fragcoord; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { - vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; - vec3 pos = texture2DRect(positionMap, vary_fragcoord.xy).xyz; - vec2 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rg; + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + dlt /= max(-pos.z*dist_factor, 1.0); + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' - vec2 col = defined_weight * ccol; + vec4 col = defined_weight.xyxx * ccol; for (int i = 1; i < kern_length; i++) { vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; - vec3 samppos = texture2DRect(positionMap, tc).xyz; + vec3 samppos = getPosition(tc).xyz; float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane if (d*d <= 0.003) { - col += texture2DRect(lightMap, tc).rg*kern[i].xy; + col += texture2DRect(lightMap, tc)*kern[i].xyxx; defined_weight += kern[i].xy; } } - col /= defined_weight; - gl_FragColor = vec4(col.r, col.g, 0.0, 1.0); + + col /= defined_weight.xyxx; + + gl_FragColor = col; + + //gl_FragColor = ccol; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index a8712bc..1c29dae 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -11,7 +11,6 @@ uniform sampler2D bumpMap; varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { @@ -22,8 +21,7 @@ void main() dot(norm,vary_mat1), dot(norm,vary_mat2)); - gl_FragData[0].rgb = gl_Color.rgb*col; - gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(tnorm), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(col*gl_Color.a, gl_Color.a); + gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl index ba18092..9589912 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/bumpV.glsl @@ -8,7 +8,6 @@ varying vec3 vary_mat0; varying vec3 vary_mat1; varying vec3 vary_mat2; -varying vec4 vary_position; void main() { @@ -16,8 +15,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vec3 n = normalize(gl_NormalMatrix * gl_Normal); vec3 b = normalize(gl_NormalMatrix * gl_MultiTexCoord2.xyz); vec3 t = cross(b, n); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index f2ba2df..919dd5d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -8,13 +8,11 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; - gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); + gl_FragData[0] = vec4(gl_Color.rgb*col, 1.0); // KL viewer 2.0 has 0.0 but this is not working right yet besides i like to see my eyes :) gl_FragData[1] = vec4(col*(gl_Color.a*1.5), gl_Color.a); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl index 3413a7f..44468cd 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/diffuseV.glsl @@ -6,16 +6,13 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 2a811c5..e518bdd 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -8,14 +8,9 @@ #extension GL_ARB_texture_rectangle : enable uniform sampler2D diffuseMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRect depthMap; uniform sampler2D noiseMap; -uniform sampler2DRect positionMap; -uniform mat4 shadow_matrix[4]; uniform vec4 shadow_clip; uniform vec2 screen_res; @@ -30,12 +25,27 @@ varying vec3 vary_fragcoord; uniform float alpha_soften; +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; frag *= screen_res; - vec3 samp_pos = texture2DRect(positionMap, frag).xyz; + vec3 samp_pos = getPosition(frag).xyz; float shadow = 1.0; vec4 pos = vary_position; @@ -46,10 +56,10 @@ void main() color.rgb = fullbrightScaleSoftClip(color.rgb); - if (samp_pos.z != 0.0) + if (samp_pos.z != 0.0 && color.a < 1.0) { float dist_factor = alpha_soften; - float a = gl_Color.a; + float a = color.a; a *= a; dist_factor *= 1.0/(1.0-a); color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl index 6381a1c..aff5117 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/fullbrightV.glsl @@ -12,12 +12,12 @@ vec3 atmosAffectDirectionalLight(float lightIntensity); vec3 scaleDownLight(vec3 light); vec3 scaleUpLight(vec3 light); -varying vec4 vary_position; varying vec3 vary_ambient; varying vec3 vary_directional; varying vec3 vary_normal; varying vec3 vary_fragcoord; uniform float near_clip; +varying vec4 vary_position; void main() { diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl new file mode 100644 index 0000000..b351eec --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -0,0 +1,165 @@ +/** + * @file giF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform int gi_samples; +uniform vec2 gi_kern[25]; +uniform vec2 gi_scale; +uniform vec3 gi_quad; +uniform vec3 gi_spec; +uniform float gi_direction_weight; +uniform float gi_light_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz/eye_pos.w); + + //vec3 eye_dir = vec3(0,0,-1); + //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; + //eye_dir = normalize(eye_dir); + + //float round_x = gi_scale.x; + //float round_y = gi_scale.y; + + vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb*0.5+0.5; + debug.xz = vec2(0.0,0.0); + //debug = fract(debug); + + float round_x = 1.0/64.0; + float round_y = 1.0/64.0; + + //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; + //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; + + float fda = 0.0; + vec3 fdiff = vec3(0,0,0); + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + for (int i = -1; i < 2; i+=2 ) + { + for (int j = -1; j < 2; j+=2) + { + vec2 tc = vec2(i, j)*0.75; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; + //tc += gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc /= gi_samples; + tc += gi_c.xy; + + vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = dot(at,at); + float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); + + if (da > 0.0) + { + //add angular attenuation + vec3 ldir = at; + float ang_atten = clamp(dot(ldir, gi_norm), 0.0, 1.0); + + float ld = -dot(ldir, lnorm); + + if (ang_atten > 0.0 && ld < 0.0) + { + vec3 diff = texture2D(diffuseGIMap, tc.xy).xyz; + da = da*ang_atten; + fda += da; + fdiff += diff*da; + } + } + } + } + + fdiff /= max(gi_spec.y*fda, gi_quad.z); + fdiff = clamp(fdiff, vec3(0), vec3(1)); + + vec3 ret = fda*fdiff; + //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; + + //fda *= nz.z; + + //rcol.rgb *= gi_intensity; + //return rcol.rgb+vary_AmblitColor.rgb*0.25; + //return vec4(debug, 0.0); + //return vec4(fda*fdiff, 0.0); + return clamp(ret,vec3(0.0), vec3(1.0)); + //return debug.xyz; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + + gl_FragData[0].xyz = giAmbient(pos, norm); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl new file mode 100644 index 0000000..71dcea9 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/giV.glsl @@ -0,0 +1,22 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl new file mode 100644 index 0000000..e8b53b0 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -0,0 +1,15 @@ +/** + * @file luminanceF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; + +varying vec2 vary_fragcoord; + +void main() +{ + gl_FragColor = texture2DRect(diffuseMap, vary_fragcoord.xy); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl new file mode 100644 index 0000000..db8775f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/luminanceV.glsl @@ -0,0 +1,20 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 3689d12..ce0494c 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -7,13 +7,15 @@ #extension GL_ARB_texture_rectangle : enable +uniform sampler2DRect depthMap; uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + uniform vec3 env_mat[3]; uniform float sun_wash; @@ -23,24 +25,48 @@ uniform int light_count; uniform vec4 light[16]; uniform vec4 light_col[16]; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform float far_z; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { vec2 frag = (vary_fragcoord.xy*0.5+0.5)*screen_res; - vec3 pos = texture2DRect(positionMap, frag.xy).xyz; - vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz); + vec3 pos = getPosition(frag.xy).xyz; + if (pos.z < far_z) + { + discard; + } + + vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0); vec4 spec = texture2DRect(specularRect, frag.xy); vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb; float noise = texture2D(noiseMap, frag.xy/128.0).b; vec3 out_col = vec3(0,0,0); + vec3 npos = normalize(-pos); for (int i = 0; i < light_count; ++i) { vec3 lv = light[i].xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > light[i].w) + dist2 /= light[i].w; + if (dist2 > 1.0) { continue; } @@ -55,29 +81,41 @@ void main() da = dot(norm, lv); float fa = light_col[i].a+1.0; - float dist_atten = clamp(1.0-(dist2-light[i].w*(1.0-fa))/(light[i].w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); dist_atten *= noise; float lit = da * dist_atten; vec3 col = light_col[i].rgb*lit*diff; + //vec3 col = vec3(dist2, light_col[i].a, lit); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*light_col[i].rgb*spec.rgb; + //vec3 ref = dot(pos+lv, norm); + + float sa = dot(normalize(lv+npos),norm); + + if (sa > 0) + { + sa = texture2D(lightFunc,vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*light_col[i].rgb*spec.rgb; + } } out_col += col; } + if (dot(out_col, out_col) <= 0.0) + { + discard; + } + //attenuate point light contribution by SSAO component out_col *= texture2DRect(lightMap, frag.xy).g; gl_FragColor.rgb = out_col; gl_FragColor.a = 0.0; + + //gl_FragColor = vec4(0.1, 0.025, 0.025/4.0, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl new file mode 100644 index 0000000..021e8a2 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -0,0 +1,184 @@ +/** + * @file multiSpotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 52bad1f..d8ccfd4 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -9,33 +9,54 @@ uniform sampler2DRect diffuseRect; uniform sampler2DRect specularRect; -uniform sampler2DRect positionMap; uniform sampler2DRect normalMap; uniform samplerCube environmentMap; uniform sampler2DRect lightMap; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2DRect depthMap; uniform vec3 env_mat[3]; uniform float sun_wash; varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; +uniform mat4 inv_proj; +uniform vec4 viewport; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = (pos_screen.xy-viewport.xy)*2.0; + sc /= viewport.zw; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + void main() { - vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; - frag *= screen_res; - vec3 pos = texture2DRect(positionMap, frag).xyz; + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; vec3 lv = vary_light.xyz-pos; float dist2 = dot(lv,lv); - if (dist2 > vary_light.w) + dist2 /= vary_light.w; + if (dist2 > 1.0) { discard; } - vec3 norm = texture2DRect(normalMap, frag).xyz; + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; float da = dot(norm, lv); if (da < 0.0) { @@ -46,24 +67,30 @@ void main() lv = normalize(lv); da = dot(norm, lv); - float noise = texture2D(noiseMap, frag/128.0).b; + float noise = texture2D(noiseMap, frag.xy/128.0).b; - vec3 col = texture2DRect(diffuseRect, frag).rgb; + vec3 col = texture2DRect(diffuseRect, frag.xy).rgb; float fa = gl_Color.a+1.0; - float dist_atten = clamp(1.0-(dist2-vary_light.w*(1.0-fa))/(vary_light.w*fa), 0.0, 1.0); + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); float lit = da * dist_atten * noise; col = gl_Color.rgb*lit*col; - vec4 spec = texture2DRect(specularRect, frag); + vec4 spec = texture2DRect(specularRect, frag.xy); if (spec.a > 0.0) { - vec3 ref = reflect(normalize(pos), norm); - float sa = dot(ref,lv); - sa = max(sa, 0.0); - sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); - sa *= noise; - col += da*sa*gl_Color.rgb*spec.rgb; + float sa = dot(normalize(lv-normalize(pos)),norm); + if (sa > 0.0) + { + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*gl_Color.rgb*spec.rgb; + } + } + + if (dot(col, col) <= 0.0) + { + discard; } //attenuate point light contribution by SSAO component diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl index a4edb88..e815ca2 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/pointLightV.glsl @@ -6,7 +6,7 @@ */ varying vec4 vary_light; -varying vec3 vary_fragcoord; +varying vec4 vary_fragcoord; uniform vec2 screen_res; uniform float near_clip; @@ -14,10 +14,10 @@ uniform float near_clip; void main() { //transform vertex - gl_Position = ftransform(); + gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + vary_fragcoord = pos; vec4 tex = gl_MultiTexCoord0; tex.w = 1.0; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl new file mode 100644 index 0000000..71de036 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredF.glsl @@ -0,0 +1,57 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + float luminance = lum.r; + luminance = luminance*lum_quad.y+lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + sun_col *= 1.0/min(luminance, 1.0); + gi_col *= 1.0/luminance; + + vec3 col = sun_col.rgb+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + col.rgb = max(col.rgb-vec3(1.0,1.0,1.0), vec3(0.0, 0.0, 0.0)); + + gl_FragColor.a = 0.0; // max(dot(col.rgb,col.rgb)*lum_quad.x, sun_col.a); + + //gl_FragColor.rgb = vec3(lum_lod); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl new file mode 100644 index 0000000..9819232 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl new file mode 100644 index 0000000..3556c7b --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -0,0 +1,107 @@ +/** + * @file postgiF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; +uniform sampler2D diffuseMap; + +uniform sampler2D lastDiffuseGIMap; +uniform sampler2D lastNormalGIMap; +uniform sampler2D lastMinpGIMap; +uniform sampler2D lastMaxpGIMap; + +uniform float gi_blend; + +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform vec2 gi_kern[16]; +uniform vec2 gi_scale; + + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + + +void main() +{ + vec2 c_tc = gl_TexCoord[0].xy; + + vec3 diff = vec3(0,0,0); + vec3 minp = vec3(1024,1024,1024); + vec3 maxp = vec3(-1024,-1024,-1024); + vec3 norm = vec3(0,0,0); + + float dweight = 0.0; + + vec3 cnorm = normalize(texture2D(normalGIMap, c_tc).rgb*2.0-1.0); + + vec3 cpos = vec3(0,0,0); + float tweight = 0.0; + + for (int i = 0; i < 8; ++i) + { + for (int j = 0; j < 8; ++j) + { + vec2 tc = vec2(i-4+0.5, j-4+0.5); + float weight = 1.0-length(tc)/6.0; + tc *= 1.0/(256.0); + tc += c_tc; + + vec3 n = texture2D(normalGIMap, tc).rgb*2.0-1.0; + tweight += weight; + + diff += weight*texture2D(diffuseGIMap, tc).rgb; + + norm += n*weight; + + dweight += dot(n, cnorm); + + vec3 pos = getGIPosition(tc).xyz; + cpos += pos*weight; + + minp = min(pos, minp); + maxp = max(pos, maxp); + } + } + + dweight = abs(1.0-dweight/64.0); + float mind = min(sqrt(dweight+0.5), 1.0); + + dweight *= dweight; + + cpos /= tweight; + + diff = clamp(diff/tweight, vec3(1.0/2.2), vec3(1,1,1)); + norm = normalize(norm); + maxp = cpos; + minp = vec3(dweight, mind, cpos.z-minp.z); + + //float blend = 1.0; + //diff = mix(texture2D(lastDiffuseGIMap, c_tc).rgb, diff, blend); + //norm = mix(texture2D(lastNormalGIMap, c_tc).rgb, norm, blend); + //maxp = mix(texture2D(lastMaxpGIMap, c_tc).rgb, maxp, blend); + //minp = mix(texture2D(lastMinpGIMap, c_tc).rgb, minp, blend); + + gl_FragData[0].rgb = diff; + gl_FragData[2].xyz = normalize(norm); + gl_FragData[1].xyz = maxp; + gl_FragData[3].xyz = minp; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl new file mode 100644 index 0000000..5a8eb65 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/postgiV.glsl @@ -0,0 +1,16 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec3 vary_normal; + +void main() +{ + //transform vertex + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + gl_Position = pos; + gl_TexCoord[0].xy = pos.xy*0.5+0.5; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl index b3758c3..b0b31fd 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowF.glsl @@ -7,8 +7,11 @@ uniform sampler2D diffuseMap; +varying vec4 post_pos; void main() { gl_FragColor = vec4(1,1,1,texture2D(diffuseMap, gl_TexCoord[0].xy).a * gl_Color.a); + + gl_FragDepth = max(post_pos.z/post_pos.w*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl index aae1bee..7214d24 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/shadowV.glsl @@ -5,13 +5,17 @@ * $License$ */ +varying vec4 post_pos; + void main() { //transform vertex vec4 pos = gl_ModelViewProjectionMatrix*gl_Vertex; - //smash geometry against the near clip plane (great for ortho projections) - pos.z = max(pos.z, -1.0); - gl_Position = pos; + + post_pos = pos; + + gl_Position = vec4(pos.x, pos.y, pos.w*0.5, pos.w); + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; gl_FrontColor = gl_Color; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index d5671a6..64e263a 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -272,8 +272,4 @@ void main() gl_FragColor.rgb = col; gl_FragColor.a = 0.0; - //gl_FragColor.rg = scol_ambocc.rg; - //gl_FragColor.rgb = norm.rgb*0.5+0.5; - //gl_FragColor.rgb = vec3(ambocc); - //gl_FragColor.rgb = vec3(scol); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl new file mode 100644 index 0000000..d653408 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -0,0 +1,199 @@ +/** + * @file spotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + if (da > 0.0) + { + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + /*if (spec.a > 0.0) + { + //vec3 ref = reflect(normalize(pos), norm); + float sa = dot(normalize(lv-normalize(pos)),norm);; + //sa = max(sa, 0.0); + //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*lcol*spec.rgb; + }*/ + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index d43fe6c..22bdd2c 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -7,17 +7,21 @@ #extension GL_ARB_texture_rectangle : enable -uniform sampler2DRect positionMap; -uniform sampler2DRect normalMap; uniform sampler2DRect depthMap; -uniform sampler2DShadow shadowMap0; -uniform sampler2DShadow shadowMap1; -uniform sampler2DShadow shadowMap2; -uniform sampler2DShadow shadowMap3; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRectShadow shadowMap4; +uniform sampler2DRectShadow shadowMap5; uniform sampler2D noiseMap; +uniform sampler2D lightFunc; + + // Inputs -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform float ssao_radius; uniform float ssao_max_radius; @@ -27,6 +31,25 @@ uniform float ssao_factor_inv; varying vec2 vary_fragcoord; varying vec4 vary_light; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + //calculate decreases in ambient lighting when crowded out (SSAO) float calcAmbientOcclusion(vec4 pos, vec3 norm) { @@ -54,7 +77,7 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) for (int i = 0; i < 8; i++) { vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); - vec3 samppos_world = texture2DRect(positionMap, samppos_screen).xyz; + vec3 samppos_world = getPosition(samppos_screen).xyz; vec3 diff = pos_world - samppos_world; float dist2 = dot(diff, diff); @@ -74,14 +97,18 @@ float calcAmbientOcclusion(vec4 pos, vec3 norm) angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); - return 1.0 - (float(points != 0) * angle_hidden); + return (1.0 - (float(points != 0) * angle_hidden)); } void main() { vec2 pos_screen = vary_fragcoord.xy; - vec4 pos = vec4(texture2DRect(positionMap, pos_screen).xyz, 1.0); - vec3 norm = texture2DRect(normalMap, pos_screen).xyz; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL { @@ -90,35 +117,45 @@ void main() }*/ float shadow = 1.0; - float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + //vec3 debug = vec3(0,0,0); + if (dp_directional_light == 0.0) { // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup shadow = 0.0; } - else if (pos.z > -shadow_clip.w) + else if (spos.z > -shadow_clip.w) { - if (pos.z < -shadow_clip.z) + vec4 lpos; + + if (spos.z < -shadow_clip.z) { - vec4 lpos = shadow_matrix[3]*pos; - shadow = shadow2DProj(shadowMap3, lpos).x; + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); } - else if (pos.z < -shadow_clip.y) + else if (spos.z < -shadow_clip.y) { - vec4 lpos = shadow_matrix[2]*pos; - shadow = shadow2DProj(shadowMap2, lpos).x; + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; } - else if (pos.z < -shadow_clip.x) + else if (spos.z < -shadow_clip.x) { - vec4 lpos = shadow_matrix[1]*pos; - shadow = shadow2DProj(shadowMap1, lpos).x; + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; } else { - vec4 lpos = shadow_matrix[0]*pos; - shadow = shadow2DProj(shadowMap0, lpos).x; + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; } // take the most-shadowed value out of these two: @@ -126,6 +163,17 @@ void main() // * an unblurred dot product between the sun and this norm // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting shadow = min(shadow, dp_directional_light); + + /*debug.r = lpos.y / (lpos.w*screen_res.y); + + lpos.xy /= lpos.w*32.0; + if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + { + debug.gb = vec2(0.5, 0.5); + } + + debug += (1.0-shadow)*0.5;*/ + } else { @@ -135,5 +183,18 @@ void main() gl_FragColor[0] = shadow; gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - //gl_FragColor[2] is unused as of August 2008, may be used for debugging + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + lpos.xy *= screen_res; + gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + lpos.xy *= screen_res; + gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; + //gl_FragColor.rgb = debug; } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 211b2e0..308b9b1 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -12,7 +12,6 @@ uniform sampler2D detail_3; uniform sampler2D alpha_ramp; varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -28,9 +27,8 @@ void main() float alphaFinal = texture2D(alpha_ramp, gl_TexCoord[1].zw).a; vec4 outColor = mix( mix(color3, color2, alpha2), mix(color1, color0, alpha1), alphaFinal ); - gl_FragData[0] = vec4(outColor.rgb, 1.0); + gl_FragData[0] = vec4(outColor.rgb, 0.0); // Kl 0.0 looks fine atm however check grass above waterline when GI enabled in future releases! gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl index e9d6dca..3038b14 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/terrainV.glsl @@ -6,7 +6,6 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; vec4 texgen_object(vec4 vpos, vec4 tc, mat4 mat, vec4 tp0, vec4 tp1) { @@ -27,7 +26,6 @@ void main() //transform vertex gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; - vary_position = gl_ModelViewMatrix * gl_Vertex; vary_normal = normalize(gl_NormalMatrix * gl_Normal); // Transform and pass tex coords diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index bc2c981..49c65f1 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -8,13 +8,11 @@ uniform sampler2D diffuseMap; varying vec3 vary_normal; -varying vec4 vary_position; void main() { vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); gl_FragData[0] = gl_Color*col; gl_FragData[1] = vec4(0,0,0,0); - gl_FragData[2] = vec4(normalize(vary_normal), 0.0); - gl_FragData[3] = vary_position; + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); } diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl index 9131d7c..6b9dc2d 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/treeV.glsl @@ -6,7 +6,6 @@ */ varying vec3 vary_normal; -varying vec4 vary_position; void main() { @@ -14,8 +13,6 @@ void main() gl_Position = ftransform(); gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; - vary_position = gl_ModelViewMatrix * gl_Vertex; - vary_normal = normalize(gl_NormalMatrix * gl_Normal); gl_FrontColor = gl_Color; diff --git a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index 0a1f019..6eea656 100644 --- a/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/linden/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -17,7 +17,7 @@ uniform sampler2DShadow shadowMap2; uniform sampler2DShadow shadowMap3; uniform sampler2D noiseMap; -uniform mat4 shadow_matrix[4]; +uniform mat4 shadow_matrix[6]; uniform vec4 shadow_clip; uniform float sunAngle; diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl new file mode 100644 index 0000000..623ef7a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/colorFilterF.glsl @@ -0,0 +1,31 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float brightness; +uniform float contrast; +uniform vec3 contrastBase; +uniform float saturation; +uniform vec3 lumWeights; + +const float gamma = 2.0; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Modulate brightness + color *= brightness; + + /// Modulate contrast + color = mix(contrastBase, color, contrast); + + /// Modulate saturation + color = mix(vec3(dot(color, lumWeights)), color, saturation); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl new file mode 100644 index 0000000..29c2a09 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/drawQuadV.glsl @@ -0,0 +1,14 @@ +/** + * @file drawQuadV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main(void) +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; +} diff --git a/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl new file mode 100644 index 0000000..271d5cf --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class1/effects/nightVisionF.glsl @@ -0,0 +1,42 @@ +/** + * @file nightVisionF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform sampler2D NoiseTexture; +uniform float brightMult; +uniform float noiseStrength; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = luminance(color) * brightMult; + + /// Convert into night vision color space + /// Newer NVG colors (crisper and more saturated) + vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); + + /// Add noise + float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; + noiseValue = (noiseValue - 0.5) * noiseStrength; + + /// Older NVG colors (more muted) + // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); + + outColor += noiseValue; + + gl_FragColor = vec4(outColor, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl new file mode 100644 index 0000000..0055a73 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -0,0 +1,112 @@ +/** + * @file alphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; +uniform sampler2DRect depthMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_light; + +uniform float alpha_soften; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; + frag *= screen_res; + + vec3 samp_pos = getPosition(frag).xyz; + + float shadow = 1.0; + vec4 pos = vec4(vary_position, 1.0); + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + } + + vec4 col = vec4(vary_ambient + vary_directional.rgb*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + if (samp_pos.z != 0.0) + { + float dist_factor = alpha_soften; + float a = gl_Color.a; + a *= a; + dist_factor *= 1.0/(1.0-a); + color.a *= min((pos.z-samp_pos.z)*dist_factor, 1.0); + } + + //gl_FragColor = gl_Color; + gl_FragColor = color; + //gl_FragColor = vec4(1,0,1,1)*shadow; + +} + diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl new file mode 100644 index 0000000..ab60b65 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -0,0 +1,75 @@ +/** + * @file alphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_fragcoord; +varying vec3 vary_position; +varying vec3 vary_light; + +uniform float near_clip; +uniform float shadow_offset; +uniform float shadow_bias; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + + gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0; + + vec4 pos = (gl_ModelViewMatrix * gl_Vertex); + vec3 norm = normalize(gl_NormalMatrix * gl_Normal); + + vary_position = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_light = gl_LightSource[0].position.xyz; + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional.rgb = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + + pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord.xyz = pos.xyz + vec3(0,0,near_clip); + +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl new file mode 100644 index 0000000..fe83c3c --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaF.glsl @@ -0,0 +1,77 @@ +/** + * @file avatarAlphaF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform vec2 screen_res; + +vec3 atmosLighting(vec3 light); +vec3 scaleSoftClip(vec3 light); + +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec4 vary_position; +varying vec3 vary_normal; + +void main() +{ + float shadow = 1.0; + vec4 pos = vary_position; + vec3 norm = normalize(vary_normal); + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + + vec4 spos = pos; + + if (spos.z > -shadow_clip.w) + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + } + + + vec4 col = vec4(vary_ambient + vary_directional*shadow, gl_Color.a); + vec4 color = texture2D(diffuseMap, gl_TexCoord[0].xy) * col; + + color.rgb = atmosLighting(color.rgb); + + color.rgb = scaleSoftClip(color.rgb); + + gl_FragColor = color; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl new file mode 100644 index 0000000..c1988d3 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -0,0 +1,78 @@ +/** + * @file avatarAlphaV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec4 calcLighting(vec3 pos, vec3 norm, vec4 color, vec4 baseCol); +mat4 getSkinnedTransform(); +void calcAtmospherics(vec3 inPositionEye); + +float calcDirectionalLight(vec3 n, vec3 l); +float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); + +vec3 atmosAmbient(vec3 light); +vec3 atmosAffectDirectionalLight(float lightIntensity); +vec3 scaleDownLight(vec3 light); +vec3 scaleUpLight(vec3 light); + +varying vec4 vary_position; +varying vec3 vary_ambient; +varying vec3 vary_directional; +varying vec3 vary_normal; + +void main() +{ + gl_TexCoord[0] = gl_MultiTexCoord0; + + vec4 pos; + vec3 norm; + + mat4 trans = getSkinnedTransform(); + pos.x = dot(trans[0], gl_Vertex); + pos.y = dot(trans[1], gl_Vertex); + pos.z = dot(trans[2], gl_Vertex); + pos.w = 1.0; + + norm.x = dot(trans[0].xyz, gl_Normal); + norm.y = dot(trans[1].xyz, gl_Normal); + norm.z = dot(trans[2].xyz, gl_Normal); + norm = normalize(norm); + + gl_Position = gl_ProjectionMatrix * pos; + vary_position = pos; + vary_normal = norm; + + calcAtmospherics(pos.xyz); + + //vec4 color = calcLighting(pos.xyz, norm, gl_Color, vec4(0.)); + vec4 col; + col.a = gl_Color.a; + + // Add windlight lights + col.rgb = atmosAmbient(vec3(0.)); + col.rgb = scaleUpLight(col.rgb); + + // Collect normal lights (need to be divided by two, as we later multiply by 2) + col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); + col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); + col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); + col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); + col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); + col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz); + col.rgb = scaleDownLight(col.rgb); + + vary_ambient = col.rgb*gl_Color.rgb; + vary_directional = gl_Color.rgb*atmosAffectDirectionalLight(max(calcDirectionalLight(norm, gl_LightSource[0].position.xyz), (1.0-gl_Color.a)*(1.0-gl_Color.a))); + + col.rgb = min(col.rgb*gl_Color.rgb, 1.0); + + gl_FrontColor = col; + + gl_FogFragCoord = pos.z; + +} + + diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl new file mode 100644 index 0000000..1713fe9 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl @@ -0,0 +1,71 @@ +/** + * @file blurLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; + +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform vec3 kern[32]; +uniform int kern_length; +uniform float kern_scale; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + vec3 pos = getPosition(vary_fragcoord.xy).xyz; + vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; + + vec2 dlt = kern_scale * delta / (1.0+norm.xy*norm.xy); + + dlt /= max(-pos.z*dist_factor, 1.0); + + vec2 defined_weight = kern[0].xy; // special case the first (centre) sample's weight in the blur; we have to sample it anyway so we get it for 'free' + vec4 col = defined_weight.xyxx * ccol; + + for (int i = 1; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].z*dlt; + vec3 samppos = getPosition(tc).xyz; + float d = dot(norm.xyz, samppos.xyz-pos.xyz);// dist from plane + if (d*d <= 0.003) + { + col += texture2DRect(lightMap, tc)*kern[i].xyxx; + defined_weight += kern[i].xy; + } + } + + + + col /= defined_weight.xyxx; + + gl_FragColor = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl new file mode 100644 index 0000000..b7f07e5 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/blurLightV.glsl @@ -0,0 +1,17 @@ +/** + * @file blurLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl new file mode 100644 index 0000000..6519594 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -0,0 +1,188 @@ +/** + * @file multiSpotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambient_lod; +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = min(1.0-(dist2-1.0*(1.0-fa))/fa, 1.0); + if (dist_atten <= 0.0) + { + discard; + } + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + float amb_da = proj_ambiance; + + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + //float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0)); + + if (stc.z > 0.0) + { + stc.xy /= stc.w; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl new file mode 100644 index 0000000..ee0e9d6 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredF.glsl @@ -0,0 +1,59 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; + +uniform vec3 gi_lum_quad; +uniform vec3 sun_lum_quad; +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 gi_col = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + gi_col = gi_col*gi_col*gi_quad.x + gi_col*gi_quad.y+gi_quad.z*ambocc*ambient.rgb; + gi_col *= diff; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + float sun_lum = 1.0-lum; + sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; + + float gi_lum = lum; + gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; + gi_col *= 1.0/gi_lum; + + vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); + + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl new file mode 100644 index 0000000..9819232 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl new file mode 100644 index 0000000..52b79e3 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -0,0 +1,294 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform vec3 gi_quad; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform sampler2DRect depthMap; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 pos = getPosition(tc).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + float da = max(dot(norm.xyz, vary_light.xyz), 0.0); + + vec4 diffuse = texture2DRect(diffuseRect, tc); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = atmosAmbient(vec3(0)); + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)); + + col *= diffuse.rgb; + + if (spec.a > 0.0) + { + vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(ref, vary_light.xyz); + col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; + } + + col = atmosLighting(col); + col = scaleSoftClip(col); + + gl_FragColor.rgb = col; + + //gl_FragColor.rgb = gi_col.rgb; + gl_FragColor.a = 0.0; + + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl new file mode 100644 index 0000000..ad8af47 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/softenLightV.glsl @@ -0,0 +1,24 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl new file mode 100644 index 0000000..d653408 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -0,0 +1,199 @@ +/** + * @file spotLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#version 120 + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform samplerCube environmentMap; +uniform sampler2DRect lightMap; +uniform sampler2D noiseMap; +uniform sampler2D lightFunc; +uniform sampler2D projectionMap; + +uniform mat4 proj_mat; //screen space to light space +uniform float proj_near; //near clip for projection +uniform vec3 proj_p; //plane projection is emitting from (in screen space) +uniform vec3 proj_n; +uniform float proj_focus; //distance from plane to begin blurring +uniform float proj_lod; //(number of mips in proj map) +uniform float proj_range; //range between near clip and far clip plane of projection +uniform float proj_ambiance; +uniform float near_clip; +uniform float far_clip; + +uniform vec3 proj_origin; //origin of projection to be used for angular attenuation +uniform float sun_wash; +uniform int proj_shadow_idx; +uniform float shadow_fade; + +varying vec4 vary_light; + +varying vec4 vary_fragcoord; +uniform vec2 screen_res; + +uniform mat4 inv_proj; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +void main() +{ + vec4 frag = vary_fragcoord; + frag.xyz /= frag.w; + frag.xyz = frag.xyz*0.5+0.5; + frag.xy *= screen_res; + + float shadow = 1.0; + + if (proj_shadow_idx >= 0) + { + vec4 shd = texture2DRect(lightMap, frag.xy); + float sh[2]; + sh[0] = shd.b; + sh[1] = shd.a; + shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0); + } + + vec3 pos = getPosition(frag.xy).xyz; + vec3 lv = vary_light.xyz-pos.xyz; + float dist2 = dot(lv,lv); + dist2 /= vary_light.w; + if (dist2 > 1.0) + { + discard; + } + + vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; + + norm = normalize(norm); + float l_dist = -dot(lv, proj_n); + + vec4 proj_tc = (proj_mat * vec4(pos.xyz, 1.0)); + if (proj_tc.z < 0.0) + { + discard; + } + + proj_tc.xyz /= proj_tc.w; + + float fa = gl_Color.a+1.0; + float dist_atten = clamp(1.0-(dist2-1.0*(1.0-fa))/fa, 0.0, 1.0); + + lv = proj_origin-pos.xyz; + lv = normalize(lv); + float da = dot(norm, lv); + + vec3 col = vec3(0,0,0); + + vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb; + + float noise = texture2D(noiseMap, frag.xy/128.0).b; + if (proj_tc.z > 0.0 && + proj_tc.x < 1.0 && + proj_tc.y < 1.0 && + proj_tc.x > 0.0 && + proj_tc.y > 0.0) + { + float lit = 0.0; + if (da > 0.0) + { + float diff = clamp((l_dist-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + + vec4 plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + + vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; + + lit = da * dist_atten * noise; + + col = lcol*lit*diff_tex*shadow; + } + + float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); + float lod = diff * proj_lod; + vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, lod); + //float amb_da = mix(proj_ambiance, proj_ambiance*max(-da, 0.0), max(da, 0.0)); + float amb_da = proj_ambiance; + if (da > 0.0) + { + amb_da += (da*0.5)*(1.0-shadow)*proj_ambiance; + } + + amb_da += (da*da*0.5+0.5)*proj_ambiance; + + amb_da *= dist_atten * noise; + + amb_da = min(amb_da, 1.0-lit); + + col += amb_da*gl_Color.rgb*diff_tex.rgb*amb_plcol.rgb*amb_plcol.a; + } + + + vec4 spec = texture2DRect(specularRect, frag.xy); + if (spec.a > 0.0) + { + vec3 ref = reflect(normalize(pos), norm); + + //project from point pos in direction ref to plane proj_p, proj_n + vec3 pdelta = proj_p-pos; + float ds = dot(ref, proj_n); + + if (ds < 0.0) + { + vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; + + vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; + + if (stc.z > 0.0) + { + stc.xy /= stc.z+proj_near; + + if (stc.x < 1.0 && + stc.y < 1.0 && + stc.x > 0.0 && + stc.y > 0.0) + { + vec4 scol = texture2DLod(projectionMap, stc.xy, proj_lod-spec.a*proj_lod); + col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb*shadow; + } + } + } + } + + /*if (spec.a > 0.0) + { + //vec3 ref = reflect(normalize(pos), norm); + float sa = dot(normalize(lv-normalize(pos)),norm);; + //sa = max(sa, 0.0); + //sa = pow(sa, 128.0 * spec.a*spec.a/dist_atten)*min(dist_atten*4.0, 1.0); + sa = texture2D(lightFunc, vec2(sa, spec.a)).a * min(dist_atten*4.0, 1.0); + sa *= noise; + col += da*sa*lcol*spec.rgb; + }*/ + + //attenuate point light contribution by SSAO component + col *= texture2DRect(lightMap, frag.xy).g; + + + gl_FragColor.rgb = col; + gl_FragColor.a = 0.0; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl new file mode 100644 index 0000000..8ced94e --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -0,0 +1,203 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DRectShadow shadowMap4; +uniform sampler2DRectShadow shadowMap5; +uniform sampler2D noiseMap; + +uniform sampler2D lightFunc; + + +// Inputs +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; +uniform float ssao_radius; +uniform float ssao_max_radius; +uniform float ssao_factor; +uniform float ssao_factor_inv; + +varying vec2 vary_fragcoord; +varying vec4 vary_light; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +//calculate decreases in ambient lighting when crowded out (SSAO) +float calcAmbientOcclusion(vec4 pos, vec3 norm) +{ + vec2 kern[8]; + // exponentially (^2) distant occlusion samples spread around origin + kern[0] = vec2(-1.0, 0.0) * 0.125*0.125; + kern[1] = vec2(1.0, 0.0) * 0.250*0.250; + kern[2] = vec2(0.0, 1.0) * 0.375*0.375; + kern[3] = vec2(0.0, -1.0) * 0.500*0.500; + kern[4] = vec2(0.7071, 0.7071) * 0.625*0.625; + kern[5] = vec2(-0.7071, -0.7071) * 0.750*0.750; + kern[6] = vec2(-0.7071, 0.7071) * 0.875*0.875; + kern[7] = vec2(0.7071, -0.7071) * 1.000*1.000; + + vec2 pos_screen = vary_fragcoord.xy; + vec3 pos_world = pos.xyz; + vec2 noise_reflect = texture2D(noiseMap, vary_fragcoord.xy/128.0).xy; + + float angle_hidden = 0.0; + int points = 0; + + float scale = min(ssao_radius / -pos_world.z, ssao_max_radius); + + // it was found that keeping # of samples a constant was the fastest, probably due to compiler optimizations (unrolling?) + for (int i = 0; i < 8; i++) + { + vec2 samppos_screen = pos_screen + scale * reflect(kern[i], noise_reflect); + vec3 samppos_world = getPosition(samppos_screen).xyz; + + vec3 diff = pos_world - samppos_world; + float dist2 = dot(diff, diff); + + // assume each sample corresponds to an occluding sphere with constant radius, constant x-sectional area + // --> solid angle shrinking by the square of distance + //radius is somewhat arbitrary, can approx with just some constant k * 1 / dist^2 + //(k should vary inversely with # of samples, but this is taken care of later) + + //if (dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) // -0.05*norm to shift sample point back slightly for flat surfaces + // angle_hidden += min(1.0/dist2, ssao_factor_inv); // dist != 0 follows from conditional. max of 1.0 (= ssao_factor_inv * ssao_factor) + angle_hidden = angle_hidden + float(dot((samppos_world - 0.05*norm - pos_world), norm) > 0.0) * min(1.0/dist2, ssao_factor_inv); + + // 'blocked' samples (significantly closer to camera relative to pos_world) are "no data", not "no occlusion" + points = points + int(diff.z > -1.0); + } + + angle_hidden = min(ssao_factor*angle_hidden/float(points), 1.0); + + return (1.0 - (float(points != 0) * angle_hidden)); +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + + //try doing an unproject here + + vec4 pos = getPosition(pos_screen); + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + + /*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL + { + gl_FragColor = vec4(0.0); // doesn't matter + return; + }*/ + + float shadow = 1.0; + float dp_directional_light = max(0.0, dot(norm, vary_light.xyz)); + + vec4 spos = vec4(pos.xyz + norm.xyz * (-pos.z/64.0*shadow_offset+shadow_bias), 1.0); + + //vec3 debug = vec3(0,0,0); + + if (spos.z > -shadow_clip.w) + { + if (dp_directional_light == 0.0) + { + // if we know this point is facing away from the sun then we know it's in shadow without having to do a squirrelly shadow-map lookup + shadow = 0.0; + } + else + { + vec4 lpos; + + if (spos.z < -shadow_clip.z) + { + lpos = shadow_matrix[3]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap3, lpos).x; + shadow += max((pos.z+shadow_clip.z)/(shadow_clip.z-shadow_clip.w)*2.0-1.0, 0.0); + } + else if (spos.z < -shadow_clip.y) + { + lpos = shadow_matrix[2]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap2, lpos).x; + } + else if (spos.z < -shadow_clip.x) + { + lpos = shadow_matrix[1]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap1, lpos).x; + } + else + { + lpos = shadow_matrix[0]*spos; + lpos.xy *= screen_res; + shadow = shadow2DRectProj(shadowMap0, lpos).x; + } + + // take the most-shadowed value out of these two: + // * the blurred sun shadow in the light (shadow) map + // * an unblurred dot product between the sun and this norm + // the goal is to err on the side of most-shadow to fill-in shadow holes and reduce artifacting + shadow = min(shadow, dp_directional_light); + } + + /*debug.r = lpos.y / (lpos.w*screen_res.y); + + lpos.xy /= lpos.w*32.0; + if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) + { + debug.gb = vec2(0.5, 0.5); + } + + debug += (1.0-shadow)*0.5;*/ + + } + else + { + // more distant than the shadow map covers + shadow = 1.0; + } + + gl_FragColor[0] = shadow; + gl_FragColor[1] = calcAmbientOcclusion(pos, norm); + + //spotlight shadow 1 + vec4 lpos = shadow_matrix[4]*spos; + lpos.xy *= screen_res; + gl_FragColor[2] = shadow2DRectProj(shadowMap4, lpos).x; + + //spotlight shadow 2 + lpos = shadow_matrix[5]*spos; + lpos.xy *= screen_res; + gl_FragColor[3] = shadow2DRectProj(shadowMap5, lpos).x; + + //gl_FragColor.rgb = pos.xyz; + //gl_FragColor.b = shadow; + //gl_FragColor.rgb = debug; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl new file mode 100644 index 0000000..5081485 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/sunLightV.glsl @@ -0,0 +1,25 @@ +/** + * @file sunLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl new file mode 100644 index 0000000..7342186 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/waterF.glsl @@ -0,0 +1,139 @@ +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); + +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; + +uniform float sunAngle; +uniform float sunAngle2; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; +uniform vec2 screen_res; +uniform mat4 norm_mat; //region space to screen space + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; +varying vec4 vary_position; + +void main() +{ + vec4 color; + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); + + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + //wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + vec2 refvec4 = distort+refdistort4/dmod; + float dweight = min(dist2*blurMultiplier, 1.0); + vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); + + //get specular component + //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + //spec = pow(spec, 128.0); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + + float shadow = 1.0; + vec4 pos = vary_position; + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + vec4 spos = pos; + + //spec *= shadow; + //color.rgb += spec * specular; + + //color.rgb = atmosTransport(color.rgb); + //color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; + + //wavef.z *= 0.1f; + wavef = normalize(wavef); + wavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.75); + gl_FragData[1] = vec4(1,1,1, 0.8); + gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); +} diff --git a/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl b/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl new file mode 100644 index 0000000..b45e5c5 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class2/deferred/waterV.glsl @@ -0,0 +1,76 @@ +/** + * @file waterV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void calcAtmospherics(vec3 inPositionEye); + +uniform vec2 d1; +uniform vec2 d2; +uniform float time; +uniform vec3 eyeVec; +uniform float waterHeight; + +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; + +varying vec4 vary_position; + +float wave(vec2 v, float t, float f, vec2 d, float s) +{ + return (dot(d, v)*f + t*s)*f; +} + +void main() +{ + //transform vertex + vec4 position = gl_Vertex; + mat4 modelViewProj = gl_ModelViewProjectionMatrix; + + vec4 oPosition; + + //get view vector + vec3 oEyeVec; + oEyeVec.xyz = position.xyz-eyeVec; + + float d = length(oEyeVec.xy); + float ld = min(d, 2560.0); + + position.xy = eyeVec.xy + oEyeVec.xy/d*ld; + view.xyz = oEyeVec; + + d = clamp(ld/1536.0-0.5, 0.0, 1.0); + d *= d; + + oPosition = position; + oPosition.z = mix(oPosition.z, max(eyeVec.z*0.75, 0.0), d); + vary_position = gl_ModelViewMatrix * oPosition; + oPosition = modelViewProj * oPosition; + + refCoord.xyz = oPosition.xyz + vec3(0,0,0.2); + + //get wave position parameter (create sweeping horizontal waves) + vec3 v = position.xyz; + v.x += (cos(v.x*0.08/*+time*0.01*/)+sin(v.y*0.02))*6.0; + + //push position for further horizon effect. + position.xyz = oEyeVec.xyz*(waterHeight/oEyeVec.z); + position.w = 1.0; + position = position*gl_ModelViewMatrix; + + calcAtmospherics((gl_ModelViewMatrix * gl_Vertex).xyz); + + + //pass wave parameters to pixel shader + vec2 bigWave = (v.xy) * vec2(0.04,0.04) + d1 * time * 0.055; + //get two normal map (detail map) texture coordinates + littleWave.xy = (v.xy) * vec2(0.45, 0.9) + d2 * time * 0.13; + littleWave.zw = (v.xy) * vec2(0.1, 0.2) + d1 * time * 0.1; + view.w = bigWave.y; + refCoord.w = bigWave.x; + + gl_Position = oPosition; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl new file mode 100644 index 0000000..9cc71a7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/avatarF.glsl @@ -0,0 +1,18 @@ +/** + * @file avatarF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + gl_FragData[0] = vec4(gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb, 0.0); + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} + diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl new file mode 100644 index 0000000..6eb4a51 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/bumpF.glsl @@ -0,0 +1,27 @@ +/** + * @file bumpF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; +uniform sampler2D bumpMap; + +varying vec3 vary_mat0; +varying vec3 vary_mat1; +varying vec3 vary_mat2; + +void main() +{ + vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + vec3 norm = texture2D(bumpMap, gl_TexCoord[0].xy).rgb * 2.0 - 1.0; + + vec3 tnorm = vec3(dot(norm,vary_mat0), + dot(norm,vary_mat1), + dot(norm,vary_mat2)); + + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); + gl_FragData[2] = vec4(normalize(tnorm)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl new file mode 100644 index 0000000..c9f75f7 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/diffuseF.glsl @@ -0,0 +1,18 @@ +/** + * @file diffuseF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; + gl_FragData[0] = vec4(gl_Color.rgb*col, 0.0); + gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl new file mode 100644 index 0000000..7325825 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -0,0 +1,84 @@ +/** + * @file giDownsampleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect giLightMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + float depth = getDepth(vary_fragcoord.xy); + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); + dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); + float defined_weight = kern[0].x; + vec3 col = ccol*kern[0].x; + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.5) + { + float sampdepth = getDepth(tc.xy); + sampdepth -= depth; + if (sampdepth*sampdepth < blur_quad.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*blur_quad.y; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl new file mode 100644 index 0000000..6adcda8 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giDownsampleV.glsl @@ -0,0 +1,17 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl new file mode 100644 index 0000000..43da836 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -0,0 +1,219 @@ +/** + * @file giF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect specularRect; + +uniform sampler2D noiseMap; + +uniform sampler2D diffuseGIMap; +uniform sampler2D specularGIMap; +uniform sampler2D normalGIMap; +uniform sampler2D depthGIMap; + +uniform sampler2D lightFunc; + +// Inputs +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +uniform vec4 sunlight_color; + +uniform mat4 inv_proj; +uniform mat4 gi_mat; //gPipeline.mGIMatrix - eye space to sun space +uniform mat4 gi_mat_proj; //gPipeline.mGIMatrixProj - eye space to projected sun space +uniform mat4 gi_norm_mat; //gPipeline.mGINormalMatrix - eye space normal to sun space normal matrix +uniform mat4 gi_inv_proj; //gPipeline.mGIInvProj - projected sun space to sun space +uniform float gi_radius; +uniform float gi_intensity; +uniform int gi_samples; +uniform vec2 gi_kern[25]; +uniform vec2 gi_scale; +uniform vec3 gi_quad; +uniform vec3 gi_spec; +uniform float gi_direction_weight; +uniform float gi_light_offset; +uniform float gi_range; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec4 getGIPosition(vec2 gi_tc) +{ + float depth = texture2D(depthGIMap, gi_tc).a; + vec2 sc = gi_tc*2.0; + sc -= vec2(1.0, 1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = gi_inv_proj*ndc; + pos.xyz /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 giAmbient(vec3 pos, vec3 norm) +{ + vec4 gi_c = gi_mat_proj * vec4(pos, 1.0); + gi_c.xyz /= gi_c.w; + + vec4 gi_pos = gi_mat*vec4(pos,1.0); + vec3 gi_norm = (gi_norm_mat*vec4(norm,1.0)).xyz; + gi_norm = normalize(gi_norm); + + vec4 c_spec = texture2DRect(specularRect, vary_fragcoord.xy); + gi_pos.xyz += (texture2D(noiseMap, vary_fragcoord.xy/128.0).x)*gi_spec.z*gi_norm.xyz; + vec2 tcx = gi_norm.xy; + vec2 tcy = gi_norm.yx; + + vec4 eye_pos = gi_mat*vec4(0,0,0,1.0); + + vec3 eye_dir = normalize(gi_pos.xyz-eye_pos.xyz); + vec3 eye_ref = reflect(eye_dir, gi_norm); + + //vec3 eye_dir = vec3(0,0,-1); + //eye_dir = (gi_norm_mat*vec4(eye_dir, 1.0)).xyz; + //eye_dir = normalize(eye_dir); + + //float round_x = gi_scale.x; + //float round_y = gi_scale.y; + + vec3 debug = texture2D(normalGIMap, gi_c.xy).rgb; + //debug.xz = vec2(0.0,0.0); + //debug = fract(debug); + + float round_x = 1.0/64.0; + float round_y = 1.0/64.0; + + //gi_c.x = floor(gi_c.x/round_x+0.5)*round_x; + //gi_c.y = floor(gi_c.y/round_y+0.5)*round_y; + + float da = texture2DRect(lightMap, vary_fragcoord.xy).r; + + vec3 fdiff = vec3(da); + + if (da > 0.0) + { + vec3 ha = -eye_dir; + ha.z += 1.0; + ha = normalize(ha); + + float sa = dot(ha,gi_norm); + da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); + fdiff += da*(c_spec.rgb*c_spec.a*2.0); + } + + float fda = da; + + vec3 rcol = vec3(0,0,0); + + float fsa = 0.0; + + + for (int i = -1; i <= 1; i += 1 ) + { + for (int j = -1; j <= 1; j+= 1) + { + vec2 tc = vec2(i, j)*0.75+gi_norm.xy; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0+tc*0.5).xyz; + tc += gi_norm.xy*nz.z; + tc += nz.xy*2.0; + tc /= gi_samples; + tc += gi_c.xy; + + vec3 lnorm = -normalize(texture2D(normalGIMap, tc.xy).xyz*2.0-1.0); + vec3 lpos = getGIPosition(tc.xy).xyz; + + vec3 at = lpos-gi_pos.xyz; + float dist = dot(at,at); + float da = clamp(1.0/(gi_spec.x*dist), 0.0, 1.0); + + + if (da > 0.01) + { //possible contribution of indirect light to this surface + vec3 ldir = at; + + float ld = -dot(ldir, lnorm); + + if (ld < 0.0) + { + float ang_atten = dot(ldir, gi_norm); + + if (ang_atten > 0.0) + { + vec4 spec = texture2D(specularGIMap, tc.xy); + at = normalize(at); + vec3 diff; + + { //contribution from indirect source to visible pixel + vec3 ha = at; + ha.z -= 1.0; + ha = normalize(ha); + float sa = dot(ha,lnorm); + da = min(da, texture2D(lightFunc, vec2(sa, spec.a)).a); + + diff = texture2D(diffuseGIMap, tc.xy).rgb+spec.rgb*spec.a*2.0; + } + + if (da > 0.0) + { //contribution from visible pixel to eye + vec3 ha = normalize(at-eye_dir); + float sa = dot(ha, gi_norm); + da = min(da, texture2D(lightFunc, vec2(sa, c_spec.a)).a); + fda += da; + fdiff += da*(c_spec.rgb*c_spec.a*2.0+vec3(1,1,1))*diff.rgb; + } + } + } + } + } + } + + //fdiff /= max(gi_spec.y*fda, gi_quad.z); + //fdiff = clamp(fdiff, vec3(0), vec3(1)); + fdiff *= 64.0; + fdiff *= sunlight_color.rgb; + + vec3 ret = fda*fdiff; + //ret = ret*ret*gi_quad.x+ret*gi_quad.y+gi_quad.z; + + //fda *= nz.z; + + //rcol.rgb *= gi_intensity; + //return rcol.rgb+vary_AmblitColor.rgb*0.25; + //return vec4(debug, 0.0); + //return vec4(fda*fdiff, 0.0); + return clamp(ret,vec3(0.0), vec3(1.0)); + //return debug.xyz; +} + +void main() +{ + vec2 pos_screen = vary_fragcoord.xy; + vec4 pos = getPosition(pos_screen); + + float rad = gi_range*0.5; + + vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; + float dist = max(length(pos.xyz)-rad, 0.0); + + float da = clamp(1.0-dist/rad, 0.0, 1.0); + gl_FragData[0].xyz = da > 0.0 ? giAmbient(pos, norm)*da : vec3(0,0,0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl new file mode 100644 index 0000000..71dcea9 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/giV.glsl @@ -0,0 +1,22 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl new file mode 100644 index 0000000..0de0d11 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceF.glsl @@ -0,0 +1,16 @@ +/** + * @file luminanceF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseMap; + +varying vec2 vary_fragcoord; +uniform float fade; +void main() +{ + gl_FragColor.rgb = texture2DRect(diffuseMap, vary_fragcoord.xy).rgb; + gl_FragColor.a = fade; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl new file mode 100644 index 0000000..db8775f --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/luminanceV.glsl @@ -0,0 +1,20 @@ +/** + * @file giV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; + +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy * 0.5 + 0.5)*screen_res; + + gl_FrontColor = gl_Color; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl new file mode 100644 index 0000000..609fb1d --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredF.glsl @@ -0,0 +1,76 @@ +/** + * @file postDeferredF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect localLightMap; +uniform sampler2DRect sunLightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D luminanceMap; +uniform sampler2DRect lightMap; +uniform sampler2D lightFunc; + + +uniform vec3 gi_lum_quad; +uniform vec3 sun_lum_quad; +uniform vec3 lum_quad; +uniform float lum_lod; +uniform vec4 ambient; + +uniform vec3 gi_quad; + +uniform vec2 screen_res; +varying vec2 vary_fragcoord; + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 lcol = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + float lum = sqrt(lcol.r)*lum_quad.x+lcol.r*lcol.r*lum_quad.y+lcol.r*lum_quad.z; + + vec4 diff = texture2DRect(diffuseRect, vary_fragcoord.xy); + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + float ambocc = texture2DRect(lightMap, vary_fragcoord.xy).g; + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec3 gi_col = ccol; + /*for (int i = -1; i <= 1; i+=1) + { + for (int j = -1; j <= 1; j+=1) + { + vec2 tc = vec2(i,j); + float wght = 1.0/(length(tc)+1.0); + gi_col += texture2DRect(giLightMap, vary_fragcoord.xy+vec2(i,j)).rgb * wght; + } + }*/ + + //gi_col *= 1.0+spec.a*4.0; + gi_col = (sqrt(gi_col)*gi_quad.x + gi_col*gi_quad.y)*(diff.rgb+spec.rgb*spec.a)+gi_quad.z*ambocc*ambient.rgb*diff.rgb; + + vec4 sun_col = texture2DRect(sunLightMap, vary_fragcoord.xy); + + vec3 local_col = texture2DRect(localLightMap, vary_fragcoord.xy).rgb; + + + float sun_lum = 1.0-lum; + sun_lum = sun_lum*sun_lum*sun_lum_quad.x + sun_lum*sun_lum_quad.y+sun_lum_quad.z; + + float gi_lum = lum; + gi_lum = gi_lum*gi_lum*gi_lum_quad.x+gi_lum*gi_lum_quad.y+gi_lum_quad.z; + gi_col *= 1.0/gi_lum; + + + vec3 col = sun_col.rgb*(1.0+max(sun_lum,0.0))+gi_col+local_col; + + gl_FragColor.rgb = col.rgb; + gl_FragColor.a = max(sun_lum*min(sun_col.r+sun_col.g+sun_col.b, 1.0), sun_col.a); + + //gl_FragColor.rgb = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = vec3(texture2D(lightFunc, vary_fragcoord.xy/512.0-vec2(0.5, 0.5)).a); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl new file mode 100644 index 0000000..9819232 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postDeferredV.glsl @@ -0,0 +1,17 @@ +/** + * @file postDeferredV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl new file mode 100644 index 0000000..12a5f39 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiF.glsl @@ -0,0 +1,87 @@ +/** + * @file postgiF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; + +uniform vec2 kern[32]; +uniform float dist_factor; +uniform float blur_size; +uniform vec2 delta; +uniform int kern_length; +uniform float kern_scale; +uniform vec3 blur_quad; + +varying vec2 vary_fragcoord; + +uniform mat4 inv_proj; +uniform vec2 screen_res; + +vec4 getPosition(vec2 pos_screen) +{ + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +float getDepth(vec2 pos_screen) +{ + float z = texture2DRect(depthMap, pos_screen.xy).a; + z = z*2.0-1.0; + vec4 ndc = vec4(0.0, 0.0, z, 1.0); + vec4 p = inv_proj*ndc; + return p.z/p.w; +} + +void main() +{ + vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; + float depth = getDepth(vary_fragcoord.xy); + + vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; + vec2 dlt = kern_scale * delta/(vec2(1.0,1.0)+norm.xy*norm.xy); + dlt /= clamp(-depth*blur_quad.x, 1.0, 3.0); + float defined_weight = kern[0].x; + vec3 col = ccol*kern[0].x; + + for (int i = 0; i < kern_length; i++) + { + vec2 tc = vary_fragcoord.xy + kern[i].y*dlt; + vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz*2.0-1.0; + + float d = dot(norm.xyz, sampNorm); + + if (d > 0.5) + { + float sampdepth = getDepth(tc.xy); + sampdepth -= depth; + if (sampdepth*sampdepth < blur_quad.z) + { + col += texture2DRect(giLightMap, tc).rgb*kern[i].x; + defined_weight += kern[i].x; + } + } + } + + col /= defined_weight; + + //col = ccol; + + col = col*blur_quad.y; + + gl_FragData[0].xyz = col; + + //gl_FragColor = ccol; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl new file mode 100644 index 0000000..6adcda8 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/postgiV.glsl @@ -0,0 +1,17 @@ +/** + * @file postgiV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +varying vec2 vary_fragcoord; +uniform vec2 screen_res; + +void main() +{ + //transform vertex + gl_Position = ftransform(); + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl new file mode 100644 index 0000000..654b182 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -0,0 +1,312 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +uniform sampler2DRect diffuseRect; +uniform sampler2DRect specularRect; +uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap; +uniform sampler2DRect giLightMap; +uniform sampler2D noiseMap; +uniform samplerCube environmentMap; +uniform sampler2D lightFunc; +uniform sampler2D luminanceMap; + +uniform vec3 gi_quad; +uniform vec3 lum_quad; +uniform float lum_lod; + +uniform float blur_size; +uniform float blur_fidelity; + +// Inputs +uniform vec4 morphFactor; +uniform vec3 camPosLocal; +//uniform vec4 camPosWorld; +uniform vec4 gamma; +uniform vec4 lightnorm; +uniform vec4 sunlight_color; +uniform vec4 ambient; +uniform vec4 blue_horizon; +uniform vec4 blue_density; +uniform vec4 haze_horizon; +uniform vec4 haze_density; +uniform vec4 cloud_shadow; +uniform vec4 density_multiplier; +uniform vec4 distance_multiplier; +uniform vec4 max_y; +uniform vec4 glow; +uniform float scene_light_strength; +uniform vec3 env_mat[3]; +uniform vec4 shadow_clip; +uniform mat3 ssao_effect_mat; + +uniform sampler2DRect depthMap; +uniform mat4 inv_proj; +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; + +vec3 vary_PositionEye; + +vec3 vary_SunlitColor; +vec3 vary_AmblitColor; +vec3 vary_AdditiveColor; +vec3 vary_AtmosAttenuation; + +vec4 getPosition(vec2 pos_screen) +{ //get position in screen space (world units) given window coordinate and depth map + float depth = texture2DRect(depthMap, pos_screen.xy).a; + vec2 sc = pos_screen.xy*2.0; + sc /= screen_res; + sc -= vec2(1.0,1.0); + vec4 ndc = vec4(sc.x, sc.y, 2.0*depth-1.0, 1.0); + vec4 pos = inv_proj * ndc; + pos /= pos.w; + pos.w = 1.0; + return pos; +} + +vec3 getPositionEye() +{ + return vary_PositionEye; +} +vec3 getSunlitColor() +{ + return vary_SunlitColor; +} +vec3 getAmblitColor() +{ + return vary_AmblitColor; +} +vec3 getAdditiveColor() +{ + return vary_AdditiveColor; +} +vec3 getAtmosAttenuation() +{ + return vary_AtmosAttenuation; +} + + +void setPositionEye(vec3 v) +{ + vary_PositionEye = v; +} + +void setSunlitColor(vec3 v) +{ + vary_SunlitColor = v; +} + +void setAmblitColor(vec3 v) +{ + vary_AmblitColor = v; +} + +void setAdditiveColor(vec3 v) +{ + vary_AdditiveColor = v; +} + +void setAtmosAttenuation(vec3 v) +{ + vary_AtmosAttenuation = v; +} + +void calcAtmospherics(vec3 inPositionEye, float ambFactor) { + + vec3 P = inPositionEye; + setPositionEye(P); + + //(TERRAIN) limit altitude + if (P.y > max_y.x) P *= (max_y.x / P.y); + if (P.y < -max_y.x) P *= (-max_y.x / P.y); + + vec3 tmpLightnorm = lightnorm.xyz; + + vec3 Pn = normalize(P); + float Plen = length(P); + + vec4 temp1 = vec4(0); + vec3 temp2 = vec3(0); + vec4 blue_weight; + vec4 haze_weight; + vec4 sunlight = sunlight_color; + vec4 light_atten; + + //sunlight attenuation effect (hue and brightness) due to atmosphere + //this is used later for sunlight modulation at various altitudes + light_atten = (blue_density * 1.0 + vec4(haze_density.r) * 0.25) * (density_multiplier.x * max_y.x); + //I had thought blue_density and haze_density should have equal weighting, + //but attenuation due to haze_density tends to seem too strong + + temp1 = blue_density + vec4(haze_density.r); + blue_weight = blue_density / temp1; + haze_weight = vec4(haze_density.r) / temp1; + + //(TERRAIN) compute sunlight from lightnorm only (for short rays like terrain) + temp2.y = max(0.0, tmpLightnorm.y); + temp2.y = 1. / temp2.y; + sunlight *= exp( - light_atten * temp2.y); + + // main atmospheric scattering line integral + temp2.z = Plen * density_multiplier.x; + + // Transparency (-> temp1) + // ATI Bugfix -- can't store temp1*temp2.z*distance_multiplier.x in a variable because the ati + // compiler gets confused. + temp1 = exp(-temp1 * temp2.z * distance_multiplier.x); + + //final atmosphere attenuation factor + setAtmosAttenuation(temp1.rgb); + + //compute haze glow + //(can use temp2.x as temp because we haven't used it yet) + temp2.x = dot(Pn, tmpLightnorm.xyz); + temp2.x = 1. - temp2.x; + //temp2.x is 0 at the sun and increases away from sun + temp2.x = max(temp2.x, .03); //was glow.y + //set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot) + temp2.x *= glow.x; + //higher glow.x gives dimmer glow (because next step is 1 / "angle") + temp2.x = pow(temp2.x, glow.z); + //glow.z should be negative, so we're doing a sort of (1 / "angle") function + + //add "minimum anti-solar illumination" + temp2.x += .25; + + //increase ambient when there are more clouds + vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5; + + /* decrease value and saturation (that in HSV, not HSL) for occluded areas + * // for HSV color/geometry used here, see http://gimp-savvy.com/BOOK/index.html?node52.html + * // The following line of code performs the equivalent of: + * float ambAlpha = tmpAmbient.a; + * float ambValue = dot(vec3(tmpAmbient), vec3(0.577)); // projection onto <1/rt(3), 1/rt(3), 1/rt(3)>, the neutral white-black axis + * vec3 ambHueSat = vec3(tmpAmbient) - vec3(ambValue); + * tmpAmbient = vec4(RenderSSAOEffect.valueFactor * vec3(ambValue) + RenderSSAOEffect.saturationFactor *(1.0 - ambFactor) * ambHueSat, ambAlpha); + */ + tmpAmbient = vec4(mix(ssao_effect_mat * tmpAmbient.rgb, tmpAmbient.rgb, ambFactor), tmpAmbient.a); + + //haze color + setAdditiveColor( + vec3(blue_horizon * blue_weight * (sunlight*(1.-cloud_shadow.x) + tmpAmbient) + + (haze_horizon.r * haze_weight) * (sunlight*(1.-cloud_shadow.x) * temp2.x + + tmpAmbient))); + + //brightness of surface both sunlight and ambient + setSunlitColor(vec3(sunlight * .5)); + setAmblitColor(vec3(tmpAmbient * .25)); + setAdditiveColor(getAdditiveColor() * vec3(1.0 - temp1)); +} + +vec3 atmosLighting(vec3 light) +{ + light *= getAtmosAttenuation().r; + light += getAdditiveColor(); + return (2.0 * light); +} + +vec3 atmosTransport(vec3 light) { + light *= getAtmosAttenuation().r; + light += getAdditiveColor() * 2.0; + return light; +} +vec3 atmosGetDiffuseSunlightColor() +{ + return getSunlitColor(); +} + +vec3 scaleDownLight(vec3 light) +{ + return (light / scene_light_strength ); +} + +vec3 scaleUpLight(vec3 light) +{ + return (light * scene_light_strength); +} + +vec3 atmosAmbient(vec3 light) +{ + return getAmblitColor() + light / 2.0; +} + +vec3 atmosAffectDirectionalLight(float lightIntensity) +{ + return getSunlitColor() * lightIntensity; +} + +vec3 scaleSoftClip(vec3 light) +{ + //soft clip effect: + light = 1. - clamp(light, vec3(0.), vec3(1.)); + light = 1. - pow(light, gamma.xxx); + + return light; +} + +void main() +{ + vec2 tc = vary_fragcoord.xy; + vec3 pos = getPosition(tc).xyz; + vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; + vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz; + + vec3 at = normalize(pos); + + vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); + + vec3 lum = texture2DLod(luminanceMap, tc/screen_res, lum_lod).rgb; + + vec3 ha = normalize(vary_light.xyz-at); + + float da = dot(ha, norm.xyz); + da = texture2D(lightFunc, vec2(da, spec.a)).a; + + vec4 diffuse = texture2DRect(diffuseRect, tc); + + vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg; + float scol = max(scol_ambocc.r, diffuse.a); + float ambocc = scol_ambocc.g; + + calcAtmospherics(pos.xyz, ambocc); + + vec3 col = vec3(0,0,0); + + col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a)*(1.0+spec.a)); + + col *= diffuse.rgb; + + col += da*spec.rgb*spec.a*vary_SunlitColor*scol_ambocc.r; + + /*if (spec.a > 0.0) + { + vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); + float sa = dot(ref, vary_light.xyz); + col.rgb += vary_SunlitColor*scol*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; + }*/ + + col = atmosLighting(col); + col = scaleSoftClip(col); + + col = col*vec3(1.0+1.0/2.2); + + gl_FragColor.rgb = col; + //gl_FragColor.rgb = lum; + + gl_FragColor.a = 0.0; + + //gl_FragColor.rg = scol_ambocc.rg; + //gl_FragColor.rgb = texture2DRect(lightMap, vary_fragcoord.xy).rgb; + //gl_FragColor.rgb = norm.rgb*0.5+0.5; + //gl_FragColor.rgb = vec3(ambocc); + //gl_FragColor.rgb = vec3(scol); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl new file mode 100644 index 0000000..ad8af47 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/softenLightV.glsl @@ -0,0 +1,24 @@ +/** + * @file softenLightF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 screen_res; + +varying vec4 vary_light; +varying vec2 vary_fragcoord; +void main() +{ + //transform vertex + gl_Position = ftransform(); + + vec4 pos = gl_ModelViewProjectionMatrix * gl_Vertex; + vary_fragcoord = (pos.xy*0.5+0.5)*screen_res; + + vec4 tex = gl_MultiTexCoord0; + tex.w = 1.0; + + vary_light = gl_MultiTexCoord0; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl new file mode 100644 index 0000000..258acee --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -0,0 +1,18 @@ +/** + * @file treeF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2D diffuseMap; + +varying vec3 vary_normal; + +void main() +{ + vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); + gl_FragData[0] = vec4(gl_Color.rgb*col.rgb, col.a <= 0.5 ? 0.0 : 0.005); + gl_FragData[1] = vec4(0,0,0,0); + gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl b/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl new file mode 100644 index 0000000..bea1515 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/deferred/waterF.glsl @@ -0,0 +1,139 @@ +/** + * @file waterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +vec3 scaleSoftClip(vec3 inColor); +vec3 atmosTransport(vec3 inColor); + +uniform sampler2D bumpMap; +uniform sampler2D screenTex; +uniform sampler2D refTex; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2D noiseMap; + +uniform mat4 shadow_matrix[6]; +uniform vec4 shadow_clip; + +uniform float sunAngle; +uniform float sunAngle2; +uniform vec3 lightDir; +uniform vec3 specular; +uniform float lightExp; +uniform float refScale; +uniform float kd; +uniform vec2 screenRes; +uniform vec3 normScale; +uniform float fresnelScale; +uniform float fresnelOffset; +uniform float blurMultiplier; +uniform vec2 screen_res; +uniform mat4 norm_mat; //region space to screen space + +//bigWave is (refCoord.w, view.w); +varying vec4 refCoord; +varying vec4 littleWave; +varying vec4 view; +varying vec4 vary_position; + +void main() +{ + vec4 color; + float dist = length(view.xy); + + //normalize view vector + vec3 viewVec = normalize(view.xyz); + + //get wave normals + vec3 wave1 = texture2D(bumpMap, vec2(refCoord.w, view.w)).xyz*2.0-1.0; + vec3 wave2 = texture2D(bumpMap, littleWave.xy).xyz*2.0-1.0; + vec3 wave3 = texture2D(bumpMap, littleWave.zw).xyz*2.0-1.0; + //get base fresnel components + + vec3 df = vec3( + dot(viewVec, wave1), + dot(viewVec, (wave2 + wave3) * 0.5), + dot(viewVec, wave3) + ) * fresnelScale + fresnelOffset; + df *= df; + + vec2 distort = (refCoord.xy/refCoord.z) * 0.5 + 0.5; + + float dist2 = dist; + dist = max(dist, 5.0); + + float dmod = sqrt(dist); + + vec2 dmod_scale = vec2(dmod*dmod, dmod); + + //get reflected color + vec2 refdistort1 = wave1.xy*normScale.x; + vec2 refvec1 = distort+refdistort1/dmod_scale; + vec4 refcol1 = texture2D(refTex, refvec1); + + vec2 refdistort2 = wave2.xy*normScale.y; + vec2 refvec2 = distort+refdistort2/dmod_scale; + vec4 refcol2 = texture2D(refTex, refvec2); + + vec2 refdistort3 = wave3.xy*normScale.z; + vec2 refvec3 = distort+refdistort3/dmod_scale; + vec4 refcol3 = texture2D(refTex, refvec3); + + vec4 refcol = refcol1 + refcol2 + refcol3; + float df1 = df.x + df.y + df.z; + refcol *= df1 * 0.333; + + vec3 wavef = (wave1 + wave2 * 0.4 + wave3 * 0.6) * 0.5; + //wavef.z *= max(-viewVec.z, 0.1); + wavef = normalize(wavef); + + float df2 = dot(viewVec, wavef) * fresnelScale+fresnelOffset; + + vec2 refdistort4 = wavef.xy*0.125; + refdistort4.y -= abs(refdistort4.y); + vec2 refvec4 = distort+refdistort4/dmod; + float dweight = min(dist2*blurMultiplier, 1.0); + vec4 baseCol = texture2D(refTex, refvec4); + refcol = mix(baseCol*df2, refcol, dweight); + + //get specular component + //float spec = clamp(dot(lightDir, (reflect(viewVec,wavef))),0.0,1.0); + + //harden specular + //spec = pow(spec, 128.0); + + //figure out distortion vector (ripply) + vec2 distort2 = distort+wavef.xy*refScale/max(dmod*df1, 1.0); + + vec4 fb = texture2D(screenTex, distort2); + + //mix with reflection + // Note we actually want to use just df1, but multiplying by 0.999999 gets around and nvidia compiler bug + color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999); + + float shadow = 1.0; + vec4 pos = vary_position; + + vec3 nz = texture2D(noiseMap, gl_FragCoord.xy/128.0).xyz; + vec4 spos = pos; + + //spec *= shadow; + //color.rgb += spec * specular; + + //color.rgb = atmosTransport(color.rgb); + //color.rgb = scaleSoftClip(color.rgb); + //color.a = spec * sunAngle2; + + //wavef.z *= 0.1f; + wavef = normalize(wavef); + wavef = (norm_mat*vec4(wavef, 1.0)).xyz; + + gl_FragData[0] = vec4(color.rgb, 0.5); + gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); + gl_FragData[2] = vec4(wavef*0.5+0.5, 0.f); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl new file mode 100644 index 0000000..9443320 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/blurF.glsl @@ -0,0 +1,31 @@ +/** + * @file blurf.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float bloomStrength; + +varying vec4 gl_TexCoord[gl_MaxTextureCoords]; +void main(void) +{ + float blurWeights[7]; + blurWeights[0] = 0.05; + blurWeights[1] = 0.1; + blurWeights[2] = 0.2; + blurWeights[3] = 0.3; + blurWeights[4] = 0.2; + blurWeights[5] = 0.1; + blurWeights[6] = 0.05; + + vec3 color = vec3(0,0,0); + for (int i = 0; i < 7; i++){ + color += vec3(texture2DRect(RenderTexture, gl_TexCoord[i].st)) * blurWeights[i]; + } + + color *= bloomStrength; + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl new file mode 100644 index 0000000..ba65b16 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/blurV.glsl @@ -0,0 +1,35 @@ +/** + * @file blurV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform vec2 texelSize; +uniform vec2 blurDirection; +uniform float blurWidth; + +void main(void) +{ + // Transform vertex + gl_Position = ftransform(); + + vec2 blurDelta = texelSize * blurDirection * vec2(blurWidth, blurWidth); + vec2 s = gl_MultiTexCoord0.st - (blurDelta * 3.0); + + // for (int i = 0; i < 7; i++) { + // gl_TexCoord[i].st = s + (i * blurDelta); + // } + + // MANUALLY UNROLL + gl_TexCoord[0].st = s; + gl_TexCoord[1].st = s + blurDelta; + gl_TexCoord[2].st = s + (2. * blurDelta); + gl_TexCoord[3].st = s + (3. * blurDelta); + gl_TexCoord[4].st = s + (4. * blurDelta); + gl_TexCoord[5].st = s + (5. * blurDelta); + gl_TexCoord[6].st = s + (6. * blurDelta); + + // gl_TexCoord[0].st = s; + // gl_TexCoord[1].st = blurDelta; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl new file mode 100644 index 0000000..623ef7a --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/colorFilterF.glsl @@ -0,0 +1,31 @@ +/** + * @file colorFilterF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float brightness; +uniform float contrast; +uniform vec3 contrastBase; +uniform float saturation; +uniform vec3 lumWeights; + +const float gamma = 2.0; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Modulate brightness + color *= brightness; + + /// Modulate contrast + color = mix(contrastBase, color, contrast); + + /// Modulate saturation + color = mix(vec3(dot(color, lumWeights)), color, saturation); + + gl_FragColor = vec4(color, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl new file mode 100644 index 0000000..29c2a09 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/drawQuadV.glsl @@ -0,0 +1,14 @@ +/** + * @file drawQuadV.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +void main(void) +{ + //transform vertex + gl_Position = ftransform(); + gl_TexCoord[0] = gl_MultiTexCoord0; + gl_TexCoord[1] = gl_MultiTexCoord1; +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl new file mode 100644 index 0000000..a1583b1 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/extractF.glsl @@ -0,0 +1,22 @@ +/** + * @file extractF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform float extractLow; +uniform float extractHigh; +uniform vec3 lumWeights; + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = smoothstep(extractLow, extractHigh, dot(color, lumWeights)); + + gl_FragColor = vec4(vec3(lum), 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl new file mode 100644 index 0000000..271d5cf --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/nightVisionF.glsl @@ -0,0 +1,42 @@ +/** + * @file nightVisionF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; +uniform sampler2D NoiseTexture; +uniform float brightMult; +uniform float noiseStrength; + +float luminance(vec3 color) +{ + /// CALCULATING LUMINANCE (Using NTSC lum weights) + /// http://en.wikipedia.org/wiki/Luma_%28video%29 + return dot(color, vec3(0.299, 0.587, 0.114)); +} + +void main(void) +{ + /// Get scene color + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + + /// Extract luminance and scale up by night vision brightness + float lum = luminance(color) * brightMult; + + /// Convert into night vision color space + /// Newer NVG colors (crisper and more saturated) + vec3 outColor = (lum * vec3(0.91, 1.21, 0.9)) + vec3(-0.07, 0.1, -0.12); + + /// Add noise + float noiseValue = texture2D(NoiseTexture, gl_TexCoord[1].st).r; + noiseValue = (noiseValue - 0.5) * noiseStrength; + + /// Older NVG colors (more muted) + // vec3 outColor = (lum * vec3(0.82, 0.75, 0.83)) + vec3(0.05, 0.32, -0.11); + + outColor += noiseValue; + + gl_FragColor = vec4(outColor, 1.0); +} diff --git a/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl b/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl new file mode 100644 index 0000000..e55d278 --- /dev/null +++ b/linden/indra/newview/app_settings/shaders/class3/effects/simpleF.glsl @@ -0,0 +1,14 @@ +/** + * @file simpleF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +uniform sampler2DRect RenderTexture; + +void main(void) +{ + vec3 color = vec3(texture2DRect(RenderTexture, gl_TexCoord[0].st)); + gl_FragColor = vec4(1.0 - color, 1.0); +} diff --git a/linden/indra/newview/llagent.cpp b/linden/indra/newview/llagent.cpp index 5bcffdb..4342e60 100644 --- a/linden/indra/newview/llagent.cpp +++ b/linden/indra/newview/llagent.cpp @@ -223,6 +223,7 @@ LLAgent gAgent; // Statics // BOOL LLAgent::sPhantom = FALSE; +BOOL LLAgent::sDebugDisplayTarget = FALSE; const F32 LLAgent::TYPING_TIMEOUT_SECS = 5.f; @@ -6618,7 +6619,7 @@ void LLAgent::saveWearable( EWearableType type, BOOL send_update ) return; } - getAvatarObject()->wearableUpdated( type ); + // getAvatarObject()->wearableUpdated( type ); if( send_update ) { diff --git a/linden/indra/newview/llagent.h b/linden/indra/newview/llagent.h index 3a39448..d3c16c5 100644 --- a/linden/indra/newview/llagent.h +++ b/linden/indra/newview/llagent.h @@ -765,6 +765,7 @@ public: BOOL mInitialized; + static BOOL sDebugDisplayTarget; S32 mNumPendingQueries; S32* mActiveCacheQueries; diff --git a/linden/indra/newview/llappviewer.cpp b/linden/indra/newview/llappviewer.cpp index 86c83b9..a9a6052 100644 --- a/linden/indra/newview/llappviewer.cpp +++ b/linden/indra/newview/llappviewer.cpp @@ -447,7 +447,7 @@ static void settings_modify() LLVOSurfacePatch::sLODFactor *= LLVOSurfacePatch::sLODFactor; //square lod factor to get exponential range of [1,4] gDebugGL = gSavedSettings.getBOOL("RenderDebugGL"); gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline"); - gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); +// gAuditTexture = gSavedSettings.getBOOL("AuditTexture"); #if LL_VECTORIZE if (gSysCPU.hasAltivec()) { diff --git a/linden/indra/newview/llcolorswatch.cpp b/linden/indra/newview/llcolorswatch.cpp index 5905bb0..3222c0d 100644 --- a/linden/indra/newview/llcolorswatch.cpp +++ b/linden/indra/newview/llcolorswatch.cpp @@ -219,11 +219,12 @@ void LLColorSwatchCtrl::draw() gl_rect_2d(interior, mColor, TRUE); LLColor4 opaque_color = mColor; opaque_color.mV[VALPHA] = 1.f; + gGL.color4fv(opaque_color.mV); if (mAlphaGradientImage.notNull()) { gGL.pushMatrix(); { - mAlphaGradientImage->draw(interior, opaque_color); + mAlphaGradientImage->draw(interior, mColor); } gGL.popMatrix(); } diff --git a/linden/indra/newview/llcompilequeue.cpp b/linden/indra/newview/llcompilequeue.cpp index ed18a10..a81972d 100644 --- a/linden/indra/newview/llcompilequeue.cpp +++ b/linden/indra/newview/llcompilequeue.cpp @@ -58,7 +58,6 @@ #include "llfloaterchat.h" #include "llviewerstats.h" #include "lluictrlfactory.h" -#include "llselectmgr.h" ///---------------------------------------------------------------------------- /// Local function declarations, constants, enums, and typedefs diff --git a/linden/indra/newview/llconsole.cpp b/linden/indra/newview/llconsole.cpp index 2379da3..a8554a0 100644 --- a/linden/indra/newview/llconsole.cpp +++ b/linden/indra/newview/llconsole.cpp @@ -63,17 +63,25 @@ const S32 CONSOLE_GUTTER_LEFT = 14; const S32 CONSOLE_GUTTER_RIGHT = 15; -LLConsole::LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, +LLConsole::LLConsole(const std::string& name, const LLRect &rect, S32 font_size_index, F32 persist_time ) - : - LLFixedBuffer(max_lines), - LLView(name, rect, FALSE) + : LLFixedBuffer(), + LLView(name, rect, FALSE), + mLinePersistTime(persist_time), + mFadeTime(persist_time - FADE_DURATION), + mFont(LLFontGL::getFontSansSerif()), + mConsoleWidth(0), + mConsoleHeight(0), + mQueueMutex(NULL) { - mLinePersistTime = persist_time; // seconds - mFadeTime = persist_time - FADE_DURATION; + mTimer.reset(); - setFontSize( font_size_index ); - setMaxLines(gSavedSettings.getS32("ConsoleMaxLines")); + setFontSize( font_size_index ); +} + +LLConsole::~LLConsole() +{ + clear(); } void LLConsole::setLinePersistTime(F32 seconds) @@ -98,10 +106,10 @@ void LLConsole::reshape(S32 width, S32 height, BOOL called_from_parent) mConsoleHeight= new_height; LLView::reshape(new_width, new_height, called_from_parent); - + for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -126,7 +134,7 @@ void LLConsole::setFontSize(S32 size_index) for(paragraph_t::iterator paragraph_it = mParagraphs.begin(); paragraph_it != mParagraphs.end(); paragraph_it++) { - (*paragraph_it).updateLines((F32)getRect().getWidth(), mFont, true); + (*paragraph_it)->updateLines((F32)getRect().getWidth(), mFont, true); } } @@ -134,35 +142,49 @@ void LLConsole::draw() { LLGLSUIDefault gls_ui; - // skip lines added more than mLinePersistTime ago - F32 cur_time = mTimer.getElapsedTimeF32(); - - F32 skip_time = cur_time - mLinePersistTime; - F32 fade_time = cur_time - mFadeTime; - - updateBuffer() ; + { + LLMutexLock lock(&mQueueMutex); + for(paragraph_t::iterator paragraph_it = mNewParagraphs.begin(); paragraph_it != mNewParagraphs.end(); paragraph_it++) + { + Paragraph* paragraph = *paragraph_it; + mParagraphs.push_back(paragraph); + paragraph->updateLines((F32)getRect().getWidth(), mFont); + } + mNewParagraphs.clear(); + } if (mParagraphs.empty()) //No text to draw. { return; } + // skip lines added more than mLinePersistTime ago + F32 cur_time = mTimer.getElapsedTimeF32(); + + F32 skip_time = cur_time - mLinePersistTime; + F32 fade_time = cur_time - mFadeTime; + + U32 max_lines = gSavedSettings.getS32("ConsoleMaxLines"); U32 num_lines=0; paragraph_t::reverse_iterator paragraph_it; paragraph_it = mParagraphs.rbegin(); U32 paragraph_num=mParagraphs.size(); - + while (!mParagraphs.empty() && paragraph_it != mParagraphs.rend()) { - num_lines += (*paragraph_it).mLines.size(); - if(num_lines > mMaxLines - || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) + num_lines += (*paragraph_it)->mLines.size(); + if(num_lines > max_lines + || ( (mLinePersistTime > (F32)0.f) && ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime) <= (F32)0.f)) { //All lines above here are done. Lose them. for (U32 i=0;imLines.size() * line_height + message_spacing); + S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); bkg_height+= target_height; if (target_width > bkg_width) @@ -203,7 +225,7 @@ void LLConsole::draw() } // Why is this not using llfloor as above? - y_pos += ((*paragraph_it).mLines.size()) * line_height; + y_pos += ((*paragraph_it)->mLines.size()) * line_height; y_pos += message_spacing; //Extra spacing between messages. } imagep->drawSolid(-CONSOLE_GUTTER_LEFT, (S32)(y_pos + line_height - bkg_height - message_spacing), bkg_width, bkg_height, color); @@ -213,10 +235,10 @@ void LLConsole::draw() for(paragraph_it = mParagraphs.rbegin(); paragraph_it != mParagraphs.rend(); paragraph_it++) { //080813 Spatters: Dainty per-message block boxes -// S32 target_height = llfloor( (*paragraph_it).mLines.size() * line_height + 8); - S32 target_width = llfloor( (*paragraph_it).mMaxWidth + CONSOLE_GUTTER_RIGHT); +// S32 target_height = llfloor( (*paragraph_it)->mLines.size() * line_height + 8); + S32 target_width = llfloor( (*paragraph_it)->mMaxWidth + CONSOLE_GUTTER_RIGHT); - y_pos += ((*paragraph_it).mLines.size()) * line_height; + y_pos += ((*paragraph_it)->mLines.size()) * line_height; //080813 Spatters: Dainty per-message block boxes // imagep->drawSolid(-14, (S32)(y_pos + line_height - target_height), target_width, target_height, color); @@ -224,9 +246,9 @@ void LLConsole::draw() F32 alpha; - if ((mLinePersistTime > 0.f) && ((*paragraph_it).mAddTime < fade_time)) + if ((mLinePersistTime > 0.f) && ((*paragraph_it)->mAddTime < fade_time)) { - alpha = ((*paragraph_it).mAddTime - skip_time)/(mLinePersistTime - mFadeTime); + alpha = ((*paragraph_it)->mAddTime - skip_time)/(mLinePersistTime - mFadeTime); } else { @@ -235,12 +257,12 @@ void LLConsole::draw() if( alpha > 0.f ) { - for (lines_t::iterator line_it=(*paragraph_it).mLines.begin(); - line_it != (*paragraph_it).mLines.end(); + for (lines_t::iterator line_it=(*paragraph_it)->mLines.begin(); + line_it != (*paragraph_it)->mLines.end(); line_it ++) { - for (line_color_segments_t::iterator seg_it = (*line_it).mLineColorSegments.begin(); - seg_it != (*line_it).mLineColorSegments.end(); + for (line_color_segments_t::iterator seg_it = (*line_it).begin(); + seg_it != (*line_it).end(); seg_it++) { mFont->render((*seg_it).mText, 0, (*seg_it).mXPosition - 8, y_pos - y_off, @@ -263,21 +285,34 @@ void LLConsole::draw() } } -void LLConsole::addLine(const std::string& utf8line) +//virtual +void LLConsole::clear() { - LLWString wline = utf8str_to_wstring(utf8line); - addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); + mTimer.reset(); + LLMutexLock lock(&mQueueMutex); + std::for_each(mParagraphs.begin(), mParagraphs.end(), DeletePointer()); + mParagraphs.clear(); + std::for_each(mNewParagraphs.begin(), mNewParagraphs.end(), DeletePointer()); + mNewParagraphs.clear(); } -void LLConsole::addLine(const LLWString& wline) +//virtual +void LLConsole::addLine(const std::string& utf8line) { - addLine(wline, 0.f, LLColor4(1.f, 1.f, 1.f, 1.f)); + addConsoleLine(utf8line, LLColor4(1.f, 1.f, 1.f, 1.f)); } -void LLConsole::addLine(const std::string& utf8line, F32 size, const LLColor4 &color) +void LLConsole::addConsoleLine(const std::string& utf8line, const LLColor4 &color) { LLWString wline = utf8str_to_wstring(utf8line); - addLine(wline, size, color); + addConsoleLine(wline, color); +} + +void LLConsole::addConsoleLine(const LLWString& wline, const LLColor4 &color) +{ + Paragraph* paragraph = new Paragraph(wline, color, mTimer.getElapsedTimeF32()); + LLMutexLock lock(&mQueueMutex); + mNewParagraphs.push_back ( paragraph ); } //Generate highlight color segments for this paragraph. Pass in default color of paragraph. @@ -359,7 +394,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo F32 x_position = 0; //Screen X position of text. mMaxWidth = llmax( mMaxWidth, (F32)font->getWidth( mParagraphText.substr( paragraph_offset, drawable ).c_str() ) ); - Line line; + line_color_segments_t line; U32 left_to_draw = drawable; U32 drawn = 0; @@ -368,7 +403,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo && current_color != mParagraphColorSegments.end() ) { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, current_color_length ); - line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. + line.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -389,7 +424,7 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo { LLWString color_text = mParagraphText.substr( paragraph_offset + drawn, left_to_draw ); - line.mLineColorSegments.push_back( LineColorSegment( color_text, //Append segment to line. + line.push_back( LineColorSegment( color_text, //Append segment to line. (*current_color).mColor, x_position ) ); @@ -407,50 +442,9 @@ void LLConsole::Paragraph::updateLines(F32 screen_width, LLFontGL* font, bool fo } //Pass in the string and the default color for this block of text. -LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width) +LLConsole::Paragraph::Paragraph (LLWString str, const LLColor4 &color, F32 add_time) : mParagraphText(str), mAddTime(add_time), mMaxWidth(-1) { makeParagraphColorSegments(color); - updateLines( screen_width, font ); } -void LLConsole::addLine(const LLWString& wline, F32 size, const LLColor4 &color) -{ - Paragraph paragraph(wline, color, mTimer.getElapsedTimeF32(), mFont, (F32)getRect().getWidth() ); - - mParagraphs.push_back ( paragraph ); - -#if LL_WINDOWS && LL_LCD_COMPILE - // add to LCD screen - AddNewDebugConsoleToLCD(wline); -#endif -} - -// -//check if there are some messages stored in the buffer -//if yes, output them. -// -void LLConsole::updateBuffer() -{ - BOOL need_clear = FALSE ; - - mMutex.lock() ; - if(!mLines.empty()) - { - S32 end = mLines.size() ; - LLColor4 color(1.f, 1.f, 1.f, 1.f) ; - for(S32 i = 0 ; i < end ; i++) - { - Paragraph paragraph(mLines[i], color, mAddTimes[i], mFont, (F32)getRect().getWidth() ); - mParagraphs.push_back ( paragraph ); - } - - need_clear = TRUE ; - } - mMutex.unlock() ; - - if(need_clear) - { - clear() ; - } -} diff --git a/linden/indra/newview/llconsole.h b/linden/indra/newview/llconsole.h index 2915c48..578670e 100644 --- a/linden/indra/newview/llconsole.h +++ b/linden/indra/newview/llconsole.h @@ -33,7 +33,8 @@ #ifndef LL_LLCONSOLE_H #define LL_LLCONSOLE_H -#include "llfixedbuffer.h" +#include "llerrorcontrol.h" // For LLLineBuffer +#include "llthread.h" #include "llview.h" #include "v4color.h" #include @@ -47,10 +48,10 @@ private: F32 mLinePersistTime; // Age at which to stop drawing. F32 mFadeTime; // Age at which to start fading LLFontGL* mFont; - S32 mLastBoxHeight; - S32 mLastBoxWidth; S32 mConsoleWidth; S32 mConsoleHeight; + LLMutex mQueueMutex; + LLTimer mTimer; public: //A paragraph color segment defines the color of text in a line @@ -80,14 +81,7 @@ public: typedef std::list line_color_segments_t; - //A line is composed of one or more color segments. - class Line - { - public: - line_color_segments_t mLineColorSegments; - }; - - typedef std::list lines_t; + typedef std::list lines_t; typedef std::list paragraph_color_segments_t; //A paragraph is a processed element containing the entire text of the @@ -98,7 +92,7 @@ public: class Paragraph { public: - Paragraph (LLWString str, const LLColor4 &color, F32 add_time, LLFontGL* font, F32 screen_width); + Paragraph (LLWString str, const LLColor4 &color, F32 add_time); void makeParagraphColorSegments ( const LLColor4 &color); void updateLines ( F32 screen_width, LLFontGL* font, bool force_resize=false ); public: @@ -111,35 +105,32 @@ public: }; //The console contains a deque of paragraphs which represent the individual messages. - typedef std::deque paragraph_t; + typedef std::deque paragraph_t; paragraph_t mParagraphs; + paragraph_t mNewParagraphs; // Font size: // -1 = monospace, 0 means small, font size = 1 means big - LLConsole(const std::string& name, const U32 max_lines, const LLRect &rect, - S32 font_size_index, F32 persist_time ); - ~LLConsole(){}; + LLConsole(const std::string& name, const LLRect &rect, + S32 font_size_index, F32 persist_time ); + ~LLConsole(); // each line lasts this long after being added - void setLinePersistTime(F32 seconds); + void setLinePersistTime(F32 seconds); - void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); // -1 = monospace, 0 means small, font size = 1 means big - void setFontSize(S32 size_index); + void setFontSize(S32 size_index); - void addLine(const std::string& utf8line, F32 size, const LLColor4 &color); - void addLine(const LLWString& wline, F32 size, const LLColor4 &color); + // From LLLineBuffer + /*virtual*/ void clear(); + /*virtual*/ void addLine(const std::string& utf8line); + void addConsoleLine(const std::string& utf8line, const LLColor4 &color); + void addConsoleLine(const LLWString& wline, const LLColor4 &color); // Overrides /*virtual*/ void draw(); - - //do not make these two "virtual" - void addLine(const std::string& utf8line); - void addLine(const LLWString& line); - -private: - void updateBuffer() ; }; extern LLConsole* gConsole; diff --git a/linden/indra/newview/lldebugview.cpp b/linden/indra/newview/lldebugview.cpp index 40f5202..a6d6f2d 100644 --- a/linden/indra/newview/lldebugview.cpp +++ b/linden/indra/newview/lldebugview.cpp @@ -62,7 +62,7 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) LLRect r; r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100); - mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f ); + mDebugConsolep = new LLConsole("debug console", r, -1, 0.f ); mDebugConsolep->setFollowsBottom(); mDebugConsolep->setFollowsLeft(); mDebugConsolep->setVisible( FALSE ); @@ -98,6 +98,27 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect) addChild(gTextureView); //gTextureView->reshape(r.getWidth(), r.getHeight(), TRUE); +/* +//there seems to be some debug code, we don't have +#if !LL_RELEASE_FOR_DOWNLOAD + r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureLoadedCounter.size() * 30, 100); + gTextureSizeView = new LLTextureSizeView("gTextureSizeView"); + gTextureSizeView->setRect(r); + gTextureSizeView->setFollowsBottom(); + gTextureSizeView->setFollowsLeft(); + addChild(gTextureSizeView); + + + r.set(150, rect.getHeight() - 50, 900 + LLImageGL::sTextureMemByCategory.size() * 30, 100); + gTextureCategoryView = new LLTextureSizeView("gTextureCategoryView"); + gTextureCategoryView->setRect(r); + gTextureCategoryView->setFollowsBottom(); + gTextureCategoryView->setFollowsLeft(); + gTextureCategoryView->setType(LLTextureSizeView::TEXTURE_MEM_OVER_CATEGORY); + addChild(gTextureCategoryView); +#endif +*/ + const S32 VELOCITY_LEFT = 10; // 370; const S32 VELOCITY_WIDTH = 500; const S32 VELOCITY_TOP = 140; @@ -115,5 +136,6 @@ LLDebugView::~LLDebugView() // These have already been deleted. Fix the globals appropriately. gDebugView = NULL; gTextureView = NULL; + gTextureSizeView = NULL; } diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp index 14aa38a..99577e3 100644 --- a/linden/indra/newview/lldrawable.cpp +++ b/linden/indra/newview/lldrawable.cpp @@ -102,7 +102,7 @@ void LLDrawable::init() mVObjp = NULL; // mFaces mSpatialGroupp = NULL; - mVisible = sCurVisible - 2;//invisible for the current frame and the last frame. + mVisible = 0; mRadius = 0.f; mGeneration = -1; @@ -125,7 +125,7 @@ void LLDrawable::destroy() if (LLSpatialGroup::sNoDelete) { - llerrs << "Illegal deletion of LLDrawable!" << llendl; + llwarns << "Illegal deletion of LLDrawable!" << llendl; } std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); @@ -234,7 +234,7 @@ LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep) LLMemType mt(LLMemType::MTYPE_DRAWABLE); LLFace *face = new LLFace(this, mVObjp); - if (!face) llerrs << "Allocating new Face: " << mFaces.size() << llendl; + if (!face) llwarns << "Allocating new Face: " << mFaces.size() << llendl; if (face) { @@ -346,7 +346,7 @@ void LLDrawable::deleteFaces(S32 offset, S32 count) void LLDrawable::update() { - llerrs << "Shouldn't be called!" << llendl; + llwarns << "Shouldn't be called!" << llendl; } @@ -368,7 +368,7 @@ void LLDrawable::makeActive() pcode == LLViewerObject::LL_VO_GROUND || pcode == LLViewerObject::LL_VO_SKY) { - llerrs << "Static viewer object has active drawable!" << llendl; + llwarns << "Static viewer object has active drawable!" << llendl; } } #endif @@ -692,19 +692,22 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update) pos += volume->getRegion()->getOriginAgent(); } - for (S32 i = 0; i < getNumFaces(); i++) + if (isState(LLDrawable::HAS_ALPHA)) { - LLFace* facep = getFace(i); - if (force_update || facep->getPoolType() == LLDrawPool::POOL_ALPHA) + for (S32 i = 0; i < getNumFaces(); i++) { - LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; - LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); - LLVector3 at = camera.getAtAxis(); - for (U32 j = 0; j < 3; j++) + LLFace* facep = getFace(i); + if (facep->getPoolType() == LLDrawPool::POOL_ALPHA) { - v.mV[j] -= box.mV[j] * at.mV[j]; + LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f; + LLVector3 v = (facep->mCenterLocal-camera.getOrigin()); + const LLVector3& at = camera.getAtAxis(); + for (U32 j = 0; j < 3; j++) + { + v.mV[j] -= box.mV[j] * at.mV[j]; + } + facep->mDistance = v * camera.getAtAxis(); } - facep->mDistance = v * camera.getAtAxis(); } } } @@ -736,7 +739,11 @@ void LLDrawable::updateTexture() if (getVOVolume()) { - if (isActive()) + if (!isActive()) + { + //gPipeline.markMoved(this); + } + else { if (isRoot()) { @@ -1003,8 +1010,8 @@ BOOL LLDrawable::isVisible() const // Spatial Partition Bridging Drawable //======================================= -LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask) -: LLSpatialPartition(data_mask, FALSE) +LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask) // KL Sd version +: LLSpatialPartition(data_mask, render_by_group, FALSE) { mDrawable = root; root->setSpatialBridge(this); @@ -1134,26 +1141,26 @@ void LLDrawable::setVisible(LLCamera& camera, std::vector* results, { if (isActive() && !mParent->isActive()) { - llerrs << "Active drawable has static parent!" << llendl; + llwarns << "Active drawable has static parent!" << llendl; } if (isStatic() && !mParent->isStatic()) { - llerrs << "Static drawable has active parent!" << llendl; + llwarns << "Static drawable has active parent!" << llendl; } if (mSpatialBridge) { - llerrs << "Child drawable has spatial bridge!" << llendl; + llwarns << "Child drawable has spatial bridge!" << llendl; } } else if (isActive() && !mSpatialBridge) { - llerrs << "Active root drawable has no spatial bridge!" << llendl; + llwarns << "Active root drawable has no spatial bridge!" << llendl; } else if (isStatic() && mSpatialBridge.notNull()) { - llerrs << "Static drawable has spatial bridge!" << llendl; + llwarns << "Static drawable has spatial bridge!" << llendl; } } #endif @@ -1277,12 +1284,25 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) return; } - LLCamera camera = transformCamera(camera_in); + if (mDrawable->getVObj()) + { + if (mDrawable->getVObj()->isAttachment()) + { + LLDrawable* parent = mDrawable->getParent(); + if (parent && parent->getVObj()) + { + LLVOAvatar* av = parent->getVObj()->asAvatar(); + if (av && av->isImpostor()) + { + return; + } + } + } + + LLCamera camera = transformCamera(camera_in); mDrawable->updateDistance(camera, force_update); - if (mDrawable->getVObj()) - { LLViewerObject::const_child_list_t& child_list = mDrawable->getVObj()->getChildren(); for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin(); iter != child_list.end(); iter++) @@ -1304,7 +1324,7 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update) void LLSpatialBridge::makeActive() { //it is an error to make a spatial bridge active (it's already active) - llerrs << "makeActive called on spatial bridge" << llendl; + llwarns << "makeActive called on spatial bridge" << llendl; } void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL immediate) @@ -1420,9 +1440,9 @@ void LLDrawable::updateFaceSize(S32 idx) } LLBridgePartition::LLBridgePartition() -: LLSpatialPartition(0, TRUE) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + //mRenderByGroup = FALSE; // KL mDrawableType = LLPipeline::RENDER_TYPE_AVATAR; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; mLODPeriod = 16; diff --git a/linden/indra/newview/lldrawable.h b/linden/indra/newview/lldrawable.h index 71b75dc..e6753b5 100644 --- a/linden/indra/newview/lldrawable.h +++ b/linden/indra/newview/lldrawable.h @@ -267,7 +267,8 @@ public: BUILT = 0x08000000, FORCE_INVISIBLE = 0x10000000, // stay invis until CLEAR_INVISIBLE is set (set of orphaned) CLEAR_INVISIBLE = 0x20000000, // clear FORCE_INVISIBLE next draw frame - REBUILD_SHADOW = 0x40000000 + REBUILD_SHADOW = 0x40000000, + HAS_ALPHA = 0x80000000, } EDrawableFlags; LLXformMatrix mXform; diff --git a/linden/indra/newview/lldrawpool.h b/linden/indra/newview/lldrawpool.h index 87c3cca..9052710 100644 --- a/linden/indra/newview/lldrawpool.h +++ b/linden/indra/newview/lldrawpool.h @@ -67,6 +67,11 @@ public: POOL_GLOW, POOL_ALPHA, NUM_POOL_TYPES, + // * invisiprims work by rendering to the depth buffer but not the color buffer, occluding anything rendered after them + // - and the LLDrawPool types enum controls what order things are rendered in + // - so, it has absolute control over what invisprims block + // ...invisiprims being rendered in pool_invisible + // ...shiny/bump mapped objects in rendered in POOL_BUMP }; LLDrawPool(const U32 type); diff --git a/linden/indra/newview/lldrawpoolalpha.cpp b/linden/indra/newview/lldrawpoolalpha.cpp index 4b552ac..c9c06f4 100644 --- a/linden/indra/newview/lldrawpoolalpha.cpp +++ b/linden/indra/newview/lldrawpoolalpha.cpp @@ -88,7 +88,12 @@ void LLDrawPoolAlpha::beginDeferredPass(S32 pass) void LLDrawPoolAlpha::endDeferredPass(S32 pass) { - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.4f); + +} + +void LLDrawPoolAlpha::renderDeferred(S32 pass) +{ + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.f); { LLFastTimer t(LLFastTimer::FTM_RENDER_GRASS); gDeferredTreeProgram.bind(); @@ -99,11 +104,6 @@ void LLDrawPoolAlpha::endDeferredPass(S32 pass) gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); } -void LLDrawPoolAlpha::renderDeferred(S32 pass) -{ - -} - S32 LLDrawPoolAlpha::getNumPostDeferredPasses() { @@ -261,6 +261,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { BOOL initialized_lighting = FALSE; BOOL light_enabled = TRUE; + S32 diffuse_channel = 0; + //BOOL is_particle = FALSE; BOOL use_shaders = (LLPipeline::sUnderWaterRender && gPipeline.canUseVertexShaders()) || gPipeline.canUseWindLightShadersOnObjects(); @@ -291,19 +293,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) LLRenderPass::applyModelMatrix(params); - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->bind(params.mTexture.get()); - - if (params.mTextureMatrix) - { - glMatrixMode(GL_TEXTURE); - glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); - gPipeline.mTextureMatrixOps++; - } - } - if (params.mFullbright) { // Turn off lighting if it hasn't already been so. @@ -344,11 +333,13 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) if (deferred_render && current_shader != NULL) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } current_shader = target_shader; if (deferred_render) { gPipeline.bindDeferredShader(*current_shader); + diffuse_channel = current_shader->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); } else { @@ -357,11 +348,12 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } else if (!use_shaders && current_shader != NULL) { - LLGLSLShader::bindNoShader(); if (deferred_render) { gPipeline.unbindDeferredShader(*current_shader); + diffuse_channel = 0; } + LLGLSLShader::bindNoShader(); current_shader = NULL; } @@ -369,6 +361,24 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) { params.mGroup->rebuildMesh(); } + + + if (params.mTexture.notNull()) + { + gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get(), TRUE, TRUE); + if(params.mViewerTexture.notNull()) + { + params.mViewerTexture->addTextureStats(params.mVSize); + } + if (params.mTextureMatrix) + { + gGL.getTexUnit(0)->activate(); + glMatrixMode(GL_TEXTURE); + glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); + gPipeline.mTextureMatrixOps++; + } + } + params.mVertexBuffer->setBuffer(mask); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); gPipeline.addTrianglesDrawn(params.mCount/3); @@ -383,6 +393,15 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask) } } + if (deferred_render && current_shader != NULL) + { + gPipeline.unbindDeferredShader(*current_shader); + LLVertexBuffer::unbind(); + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); + } + if (!light_enabled) { gPipeline.enableLightsDynamic(); diff --git a/linden/indra/newview/lldrawpoolavatar.cpp b/linden/indra/newview/lldrawpoolavatar.cpp index 80c7d73..af7b5e3 100644 --- a/linden/indra/newview/lldrawpoolavatar.cpp +++ b/linden/indra/newview/lldrawpoolavatar.cpp @@ -94,6 +94,7 @@ BOOL gAvatarEmbossBumpMap = FALSE; static BOOL sRenderingSkinned = FALSE; S32 normal_channel = -1; S32 specular_channel = -1; +S32 diffuse_channel = -1; LLDrawPoolAvatar::LLDrawPoolAvatar() : LLFacePool(POOL_AVATAR) @@ -447,7 +448,8 @@ void LLDrawPoolAvatar::beginDeferredImpostor() normal_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); specular_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::SPECULAR_MAP); - + diffuse_channel = sVertexProgram->enableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD + sVertexProgram->bind(); } @@ -456,6 +458,7 @@ void LLDrawPoolAvatar::endDeferredImpostor() sShaderLevel = mVertexShaderLevel; sVertexProgram->disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL); sVertexProgram->disableTexture(LLViewerShaderMgr::SPECULAR_MAP); + sVertexProgram->disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); // KL SD sVertexProgram->unbind(); gGL.getTexUnit(0)->activate(); } @@ -699,7 +702,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) avatarp->mImpostor.bindTexture(1, specular_channel); } } - avatarp->renderImpostor(); + // avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel); // KL SD + avatarp->renderImpostor(); } else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) { @@ -752,6 +756,67 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass) if( !single_avatar || (avatarp == single_avatar) ) { + if (LLVOAvatar::sShowCollisionVolumes) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + avatarp->renderCollisionVolumes(); + } + + if (avatarp->isSelf() && LLAgent::sDebugDisplayTarget) + { + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + LLVector3 pos = avatarp->getPositionAgent(); + + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mDrawable->getPositionAgent(); + gGL.color4f(1.0f, 0.0f, 0.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mRoot.getWorldPosition(); + gGL.color4f(1.0f, 1.0f, 1.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + pos = avatarp->mPelvisp->getWorldPosition(); + gGL.color4f(0.0f, 0.0f, 1.0f, 0.8f); + gGL.begin(LLRender::LINES); + { + gGL.vertex3fv((pos - LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.2f, 0.f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.2f, 0.f)).mV); + gGL.vertex3fv((pos - LLVector3(0.f, 0.f, 0.2f)).mV); + gGL.vertex3fv((pos + LLVector3(0.f, 0.f, 0.2f)).mV); + }gGL.end(); + + color.setColor(1.0f, 1.0f, 1.0f, 1.0f); + } + avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE); } } diff --git a/linden/indra/newview/lldrawpoolbump.cpp b/linden/indra/newview/lldrawpoolbump.cpp index fb7a213..dcaa742 100644 --- a/linden/indra/newview/lldrawpoolbump.cpp +++ b/linden/indra/newview/lldrawpoolbump.cpp @@ -140,7 +140,7 @@ void LLStandardBumpmap::restoreGL() return; } - llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; +// llinfos << "Loading bumpmap: " << bump_file << " from viewerart" << llendl; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label; gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = gImageList.getImageFromFile(bump_file, @@ -309,8 +309,8 @@ void LLDrawPoolBump::endRenderPass(S32 pass) void LLDrawPoolBump::beginShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -384,8 +384,8 @@ void LLDrawPoolBump::beginShiny(bool invisible) void LLDrawPoolBump::renderShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -411,8 +411,8 @@ void LLDrawPoolBump::renderShiny(bool invisible) void LLDrawPoolBump::endShiny(bool invisible) { LLFastTimer t(LLFastTimer::FTM_RENDER_SHINY); - if ((!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY))|| - (invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY))) + if (!invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_SHINY)|| + invisible && !gPipeline.hasRenderBatches(LLRenderPass::PASS_INVISI_SHINY)) { return; } @@ -572,7 +572,11 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) LLImageGL* bump = NULL; U8 bump_code = params.mBump; - LLViewerImage* tex = params.mTexture; + LLViewerImage* tex = params.mViewerTexture; + if(!tex) + { + return FALSE ; + } switch( bump_code ) { @@ -1226,7 +1230,10 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture) if (params.mTexture.notNull()) { gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); - //params.mTexture->addTextureStats(params.mVSize); + if(params.mViewerTexture.notNull()) + { + params.mViewerTexture->addTextureStats(params.mVSize); + } } else { diff --git a/linden/indra/newview/lldrawpoolsky.cpp b/linden/indra/newview/lldrawpoolsky.cpp index f0ed380..7f21adc 100644 --- a/linden/indra/newview/lldrawpoolsky.cpp +++ b/linden/indra/newview/lldrawpoolsky.cpp @@ -61,8 +61,8 @@ LLDrawPool *LLDrawPoolSky::instancePool() void LLDrawPoolSky::prerender() { - mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); - gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); + mVertexShaderLevel = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT); +// gSky.mVOSkyp->updateGeometry(gSky.mVOSkyp->mDrawable); } void LLDrawPoolSky::render(S32 pass) @@ -97,6 +97,7 @@ void LLDrawPoolSky::render(S32 pass) } + LLVOSky *voskyp = gSky.mVOSkyp; LLGLSPipelineSkyBox gls_skybox; LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); @@ -119,9 +120,43 @@ void LLDrawPoolSky::render(S32 pass) { renderSkyCubeFace(i); } + + LLFace *hbfaces[3]; + hbfaces[0] = NULL; + hbfaces[1] = NULL; + hbfaces[2] = NULL; + for (S32 curr_face = 0; curr_face < face_count; curr_face++) + { + LLFace* facep = mDrawFace[curr_face]; + if (voskyp->isSameFace(LLVOSky::FACE_SUN, facep)) + { + hbfaces[0] = facep; + } + if (voskyp->isSameFace(LLVOSky::FACE_MOON, facep)) + { + hbfaces[1] = facep; + } + if (voskyp->isSameFace(LLVOSky::FACE_BLOOM, facep)) + { + hbfaces[2] = facep; + } + } LLGLEnable blend(GL_BLEND); + if (hbfaces[2]) + { + // renderSunHalo(hbfaces[2]); + } + if (hbfaces[0]) + { + // renderHeavenlyBody(0, hbfaces[0]); + } + if (hbfaces[1]) + { + // renderHeavenlyBody(1, hbfaces[1]); + } + glPopMatrix(); } @@ -146,6 +181,35 @@ void LLDrawPoolSky::renderSkyCubeFace(U8 side) } } +void LLDrawPoolSky::renderHeavenlyBody(U8 hb, LLFace* face) +{ + if ( !mHB[hb]->getDraw() ) return; + if (! face->getGeomCount()) return; + + LLImageGL* tex = face->getTexture(); + gGL.getTexUnit(0)->bind(tex); + LLColor4 color(mHB[hb]->getInterpColor()); + LLOverrideFaceColor override(this, color); + face->renderIndexed(); +} + + + +void LLDrawPoolSky::renderSunHalo(LLFace* face) +{ + if (! mHB[0]->getDraw()) return; + if (! face->getGeomCount()) return; + + LLImageGL* tex = face->getTexture(); + gGL.getTexUnit(0)->bind(tex); + LLColor4 color(mHB[0]->getInterpColor()); + color.mV[3] = llclamp(mHB[0]->getHaloBrighness(), 0.f, 1.f); + + LLOverrideFaceColor override(this, color); + face->renderIndexed(); +} + + void LLDrawPoolSky::renderForSelect() { } diff --git a/linden/indra/newview/lldrawpoolsky.h b/linden/indra/newview/lldrawpoolsky.h index 8595d73..f35b114 100644 --- a/linden/indra/newview/lldrawpoolsky.h +++ b/linden/indra/newview/lldrawpoolsky.h @@ -36,12 +36,14 @@ #include "lldrawpool.h" class LLSkyTex; +class LLHeavenBody; class LLGLSLShader; class LLDrawPoolSky : public LLFacePool { private: LLSkyTex *mSkyTex; + LLHeavenBody *mHB[2]; // Sun and Moon LLGLSLShader *mShader; public: @@ -67,6 +69,8 @@ public: /*virtual*/ void renderForSelect(); /*virtual*/ void endRenderPass(S32 pass); void setSkyTex(LLSkyTex* const st) { mSkyTex = st; } + void setSun(LLHeavenBody* sun_flag) { mHB[0] = sun_flag; } + void setMoon(LLHeavenBody* moon) { mHB[1] = moon; } void renderSkyCubeFace(U8 side); void renderHeavenlyBody(U8 hb, LLFace* face); diff --git a/linden/indra/newview/lldrawpoolterrain.cpp b/linden/indra/newview/lldrawpoolterrain.cpp index cac5162..3ee955a 100644 --- a/linden/indra/newview/lldrawpoolterrain.cpp +++ b/linden/indra/newview/lldrawpoolterrain.cpp @@ -73,19 +73,19 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerImage *texturep) : TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb")); - gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(mAlphaRampImagep.get()); mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); m2DAlphaRampImagep = gImageList.getImageFromFile("alpha_gradient_2d.j2c", TRUE, TRUE, GL_ALPHA8, GL_ALPHA, LLUUID("38b86f85-2575-52a9-a531-23108d8da837")); - gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); + //gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get()); m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP); mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_TERRAIN); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + //gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); } LLDrawPoolTerrain::~LLDrawPoolTerrain() diff --git a/linden/indra/newview/lldrawpooltree.cpp b/linden/indra/newview/lldrawpooltree.cpp index 46cd2d5..873f0f6 100644 --- a/linden/indra/newview/lldrawpooltree.cpp +++ b/linden/indra/newview/lldrawpooltree.cpp @@ -52,7 +52,7 @@ LLDrawPoolTree::LLDrawPoolTree(LLViewerImage *texturep) : LLFacePool(POOL_TREE), mTexturep(texturep) { - gGL.getTexUnit(0)->bind(mTexturep.get()); +// gGL.getTexUnit(0)->bind(mTexturep.get()); mTexturep->setAddressMode(LLTexUnit::TAM_WRAP); } @@ -108,7 +108,7 @@ void LLDrawPoolTree::render(S32 pass) } else { - gGL.getTexUnit(sDiffTex)->bind(mTexturep); + gGL.getTexUnit(sDiffTex)->bind(mTexturep, TRUE); for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) @@ -138,7 +138,7 @@ void LLDrawPoolTree::endRenderPass(S32 pass) void LLDrawPoolTree::beginDeferredPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_RENDER_TREES); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); // KL Render-pipeline has this set at 0.f ... NOOOOOO! make shitty trees :) shader = &gDeferredTreeProgram; shader->bind(); @@ -164,6 +164,9 @@ void LLDrawPoolTree::beginShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f); + glPolygonOffset(gSavedSettings.getF32("RenderDeferredTreeShadowOffset"), + gSavedSettings.getF32("RenderDeferredTreeShadowBias")); + gDeferredShadowProgram.bind(); } @@ -176,7 +179,11 @@ void LLDrawPoolTree::endShadowPass(S32 pass) { LLFastTimer t(LLFastTimer::FTM_SHADOW_TREE); gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); - gDeferredShadowProgram.unbind(); + + glPolygonOffset(gSavedSettings.getF32("RenderDeferredSpotShadowOffset"), + gSavedSettings.getF32("RenderDeferredSpotShadowBias")); + + //gDeferredShadowProgram.unbind(); } diff --git a/linden/indra/newview/lldrawpoolwater.cpp b/linden/indra/newview/lldrawpoolwater.cpp index ce3425d..5c0363e 100644 --- a/linden/indra/newview/lldrawpoolwater.cpp +++ b/linden/indra/newview/lldrawpoolwater.cpp @@ -98,7 +98,7 @@ void LLDrawPoolWater::restoreGL() LLDrawPool *LLDrawPoolWater::instancePool() { - llerrs << "Should never be calling instancePool on a water pool!" << llendl; + llwarns << "Should never be calling instancePool on a water pool!" << llendl; return NULL; } @@ -401,6 +401,15 @@ void LLDrawPoolWater::shade() shader = &gWaterProgram; } + if (deferred_render) + { + gPipeline.bindDeferredShader(*shader); + } + else + { + shader->bind(); + } + sTime = (F32)LLFrameTimer::getElapsedSeconds()*0.5f; S32 reftex = shader->enableTexture(LLViewerShaderMgr::WATER_REFTEX); @@ -436,15 +445,6 @@ void LLDrawPoolWater::shade() S32 screentex = shader->enableTexture(LLViewerShaderMgr::WATER_SCREENTEX); - if (deferred_render) - { - gPipeline.bindDeferredShader(*shader); - } - else - { - shader->bind(); - } - if (screentex > -1) { shader->uniform4fv(LLViewerShaderMgr::WATER_FOGCOLOR, 1, sWaterFogColor.mV); diff --git a/linden/indra/newview/lldynamictexture.cpp b/linden/indra/newview/lldynamictexture.cpp index 61f5a89..e219d4b 100644 --- a/linden/indra/newview/lldynamictexture.cpp +++ b/linden/indra/newview/lldynamictexture.cpp @@ -41,6 +41,7 @@ #include "llvertexbuffer.h" #include "llviewerdisplay.h" #include "llrender.h" +#include "pipeline.h" // static LLDynamicTexture::instance_list_t LLDynamicTexture::sInstances[ LLDynamicTexture::ORDER_COUNT ]; @@ -58,9 +59,14 @@ LLDynamicTexture::LLDynamicTexture(S32 width, S32 height, S32 components, EOrder mClamp(clamp) { llassert((1 <= components) && (components <= 4)); - - generateGLTexture(); - + if(!LLPipeline::sRenderDeferred) + { + generateGLTexture(); + } + else + { + gPipeline.markGLRebuild(this); // KL SD well for this to work its either gotta be one or the other so lets slap in the if/else can't do any harm. + } llassert( 0 <= order && order < ORDER_COUNT ); LLDynamicTexture::sInstances[ order ].insert(this); } @@ -77,6 +83,11 @@ LLDynamicTexture::~LLDynamicTexture() } } +void LLDynamicTexture::updateGL() +{ + generateGLTexture(); +} + //----------------------------------------------------------------------------- // releaseGLTexture() //----------------------------------------------------------------------------- @@ -101,7 +112,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima { if (mComponents < 1 || mComponents > 4) { - llerrs << "Bad number of components in dynamic texture: " << mComponents << llendl; + llwarns << "Bad number of components in dynamic texture: " << mComponents << llendl; } releaseGLTexture(); LLPointer raw_image = new LLImageRaw(mWidth, mHeight, mComponents); @@ -111,7 +122,7 @@ void LLDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum prima mTexture->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes); } // llinfos << "ALLOCATING " << (mWidth*mHeight*mComponents)/1024 << "K" << llendl; - mTexture->createGLTexture(0, raw_image, 0, TRUE, LLViewerImageBoostLevel::DYNAMIC_TEX); + mTexture->createGLTexture(0, raw_image); mTexture->setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP); mTexture->setGLTextureCreated(false); } diff --git a/linden/indra/newview/lldynamictexture.h b/linden/indra/newview/lldynamictexture.h index 5a20eae..1480799 100644 --- a/linden/indra/newview/lldynamictexture.h +++ b/linden/indra/newview/lldynamictexture.h @@ -37,7 +37,7 @@ #include "llcoord.h" #include "llimagegl.h" -class LLDynamicTexture +class LLDynamicTexture : public LLGLUpdate { public: enum EOrder { ORDER_FIRST = 0, ORDER_MIDDLE = 1, ORDER_LAST = 2, ORDER_RESET = 3, ORDER_COUNT = 4 }; @@ -49,6 +49,8 @@ public: BOOL clamp); virtual ~LLDynamicTexture(); + void updateGL(); + S32 getOriginX() { return mOrigin.mX; } S32 getOriginY() { return mOrigin.mY; } S32 getWidth() { return mWidth; } diff --git a/linden/indra/newview/llface.cpp b/linden/indra/newview/llface.cpp index aa8cd15..ae57a3c 100644 --- a/linden/indra/newview/llface.cpp +++ b/linden/indra/newview/llface.cpp @@ -176,8 +176,8 @@ void LLFace::init(LLDrawable* drawablep, LLViewerObject* objp) mLastIndicesCount = mIndicesCount; mLastIndicesIndex = mIndicesIndex; - mImportanceToCamera = 0.f ; - mBoundingSphereRadius = 0.0f ; + mAtlasInfop = NULL ; + mUsingAtlas = FALSE ; } @@ -205,12 +205,14 @@ void LLFace::destroy() if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, TRUE); } } } setDrawInfo(NULL); + removeAtlas(); mDrawablep = NULL; mVObjp = NULL; } @@ -223,7 +225,7 @@ void LLFace::initClass() void LLFace::setWorldMatrix(const LLMatrix4 &mat) { - llerrs << "Faces on this drawable are not independently modifiable\n" << llendl; + llwarns << "Faces on this drawable are not independently modifiable\n" << llendl; } void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) @@ -232,7 +234,7 @@ void LLFace::setPool(LLFacePool* new_pool, LLViewerImage *texturep) if (!new_pool) { - llerrs << "Setting pool to null!" << llendl; + llwarns << "Setting pool to null!" << llendl; } if (new_pool != mDrawPoolp) @@ -270,6 +272,7 @@ void LLFace::setTexture(LLViewerImage* tex) if(mTexture.notNull()) { mTexture->removeFace(this) ; + removeAtlas() ; } mTexture = tex ; @@ -453,8 +456,15 @@ void LLFace::renderForSelect(U32 data_mask) void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) { - if(mDrawablep.isNull() || mVertexBuffer.isNull() || mDrawablep->getSpatialGroup() == NULL || - mDrawablep->getSpatialGroup()->isState(LLSpatialGroup::GEOM_DIRTY)) + if (mDrawablep->getSpatialGroup() == NULL) + { + return; + } + + mDrawablep->getSpatialGroup()->rebuildGeom(); + mDrawablep->getSpatialGroup()->rebuildMesh(); + + if(mDrawablep.isNull() || mVertexBuffer.isNull()) { return; } @@ -473,17 +483,10 @@ void LLFace::renderSelected(LLImageGL *imagep, const LLColor4& color) glMultMatrixf((GLfloat*)mDrawablep->getRegion()->mRenderMatrix.mMatrix); } - setFaceColor(color); - renderSetColor(); - + glColor4fv(color.mV); mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); -#if !LL_RELEASE_FOR_DOWNLOAD - LLGLState::checkClientArrays("", LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); -#endif mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); - unsetFaceColor(); - unsetFaceColor(); gGL.popMatrix(); } } @@ -727,8 +730,8 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f, } mCenterLocal = (newMin+newMax)*0.5f; - LLVector3 tmp = (newMin - newMax) ; - mBoundingSphereRadius = tmp.length() * 0.5f ; + // LLVector3 tmp = (newMin - newMax) ; + // mBoundingSphereRadius = tmp.length() * 0.5f ; updateCenterAgent(); } @@ -963,6 +966,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getBinormalStrider(binormals, mGeomIndex); } + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + BOOL in_atlas = FALSE ; + if (rebuild_tcoord) { mVertexBuffer->getTexCoord0Strider(tex_coords, mGeomIndex); @@ -970,6 +979,18 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, { mVertexBuffer->getTexCoord1Strider(tex_coords2, mGeomIndex); } + + in_atlas = isAtlasInUse() ; + if(in_atlas) + { + const LLVector2* tmp = getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; + + tmp = getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } } if (rebuild_color) { @@ -1057,7 +1078,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, 0.75f }; - if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderBump && tep->getShiny()))) + if (getPoolType() != LLDrawPool::POOL_ALPHA && (LLPipeline::sRenderDeferred || LLPipeline::sRenderBump && tep->getShiny())) { color.mV[3] = U8 (alpha[tep->getShiny()] * 255); } @@ -1179,6 +1200,93 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, xform(tc, cos_ang, sin_ang, os, ot, ms, mt); } + if(in_atlas) + { + // + //manually calculate tex-coord per vertex for varying address modes. + //should be removed if shader can handle this. + // + + S32 int_part = 0 ; + switch(mTexture->getAddressMode()) + { + case LLTexUnit::TAM_CLAMP: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 0.f ; + } + else if(tc.mV[0] > 1.f) + { + tc.mV[0] = 1.f; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 0.f ; + } + else if(tc.mV[1] > 1.f) + { + tc.mV[1] = 1.f; + } + break; + case LLTexUnit::TAM_MIRROR: + if(tc.mV[0] < 0.f) + { + tc.mV[0] = -tc.mV[0] ; + } + int_part = (S32)tc.mV[0] ; + if(int_part & 1) //odd number + { + tc.mV[0] = int_part + 1 - tc.mV[0] ; + } + else //even number + { + tc.mV[0] -= int_part ; + } + + if(tc.mV[1] < 0.f) + { + tc.mV[1] = -tc.mV[1] ; + } + int_part = (S32)tc.mV[1] ; + if(int_part & 1) //odd number + { + tc.mV[1] = int_part + 1 - tc.mV[1] ; + } + else //even number + { + tc.mV[1] -= int_part ; + } + break; + case LLTexUnit::TAM_WRAP: + if(tc.mV[0] > 1.f) + tc.mV[0] -= (S32)(tc.mV[0] - 0.00001f) ; + else if(tc.mV[0] < -1.f) + tc.mV[0] -= (S32)(tc.mV[0] + 0.00001f) ; + + if(tc.mV[1] > 1.f) + tc.mV[1] -= (S32)(tc.mV[1] - 0.00001f) ; + else if(tc.mV[1] < -1.f) + tc.mV[1] -= (S32)(tc.mV[1] + 0.00001f) ; + + if(tc.mV[0] < 0.f) + { + tc.mV[0] = 1.0f + tc.mV[0] ; + } + if(tc.mV[1] < 0.f) + { + tc.mV[1] = 1.0f + tc.mV[1] ; + } + break; + default: + break; + } + + tc.mV[0] = tcoord_xoffset + tcoord_xscale * tc.mV[0] ; + tc.mV[1] = tcoord_yoffset + tcoord_yscale * tc.mV[1] ; + } + + *tex_coords++ = tc; if (bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) @@ -1245,159 +1353,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return TRUE; } -const F32 LEAST_IMPORTANCE = 0.05f ; -const F32 LEAST_IMPORTANCE_FOR_LARGE_IMAGE = 0.3f ; - -F32 LLFace::getTextureVirtualSize() -{ - F32 radius; - F32 cos_angle_to_view_dir; - mPixelArea = calcPixelArea(cos_angle_to_view_dir, radius); - - if (mPixelArea <= 0) - { - return 0.f; - } - - //get area of circle in texture space - LLVector2 tdim = mTexExtents[1] - mTexExtents[0]; - F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; - if (texel_area <= 0) - { - // Probably animated, use default - texel_area = 1.f; - } - - F32 face_area; - if (mVObjp->isSculpted() && texel_area > 1.f) - { - //sculpts can break assumptions about texel area - face_area = mPixelArea; - } - else - { - //apply texel area to face area to get accurate ratio - //face_area /= llclamp(texel_area, 1.f/64.f, 16.f); - face_area = mPixelArea / llclamp(texel_area, 0.015625f, 1024.f); - } - - if(face_area > LLViewerImage::sMaxSmallImageSize) - { - if(mImportanceToCamera < LEAST_IMPORTANCE) //if the face is not important, do not load hi-res. - { - face_area = LLViewerImage::sMaxSmallImageSize ; - } - else if(face_area > LLViewerImage::sMinLargeImageSize) //if is large image, shrink face_area by considering the partial overlapping. - { - if(mImportanceToCamera < LEAST_IMPORTANCE_FOR_LARGE_IMAGE)//if the face is not important, do not load hi-res. - { - face_area = LLViewerImage::sMinLargeImageSize ; - } - else if(mTexture.notNull() && mTexture->isLargeImage()) - { - face_area *= adjustPartialOverlapPixelArea(cos_angle_to_view_dir, radius ); - } - } - } - - return face_area; -} - -F32 LLFace::calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) -{ - //get area of circle around face - LLVector3 center = getPositionAgent(); - LLVector3 size = (mExtents[1] - mExtents[0]) * 0.5f; - - LLVector3 lookAt = center - LLViewerCamera::getInstance()->getOrigin(); - F32 dist = lookAt.normVec() ; - - //get area of circle around node - F32 app_angle = atanf(size.length()/dist); - radius = app_angle*LLDrawable::sCurPixelAngle; - F32 face_area = radius*radius * 3.14159f; - - if(dist < mBoundingSphereRadius) //camera is very close - { - cos_angle_to_view_dir = 1.0f ; - mImportanceToCamera = 1.0f ; - } - else - { - cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - mImportanceToCamera = LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist) ; - } - - return face_area ; -} - -//the projection of the face partially overlaps with the screen -F32 LLFace::adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ) -{ - F32 screen_radius = (F32)llmax(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()) ; - F32 center_angle = acosf(cos_angle_to_view_dir) ; - F32 d = center_angle * LLDrawable::sCurPixelAngle ; - - if(d + radius > screen_radius + 5.f) - { - //---------------------------------------------- - //calculate the intersection area of two circles - //F32 radius_square = radius * radius ; - //F32 d_square = d * d ; - //F32 screen_radius_square = screen_radius * screen_radius ; - //face_area = - // radius_square * acosf((d_square + radius_square - screen_radius_square)/(2 * d * radius)) + - // screen_radius_square * acosf((d_square + screen_radius_square - radius_square)/(2 * d * screen_radius)) - - // 0.5f * sqrtf((-d + radius + screen_radius) * (d + radius - screen_radius) * (d - radius + screen_radius) * (d + radius + screen_radius)) ; - //---------------------------------------------- - - //the above calculation is too expensive - //the below is a good estimation: bounding box of the bounding sphere: - F32 alpha = 0.5f * (radius + screen_radius - d) / radius ; - alpha = llclamp(alpha, 0.f, 1.f) ; - return alpha * alpha ; - } - return 1.0f ; -} - -const S8 FACE_IMPORTANCE_LEVEL = 4 ; -const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL][2] = //{distance, importance_weight} - {{16.1f, 1.0f}, {32.1f, 0.5f}, {48.1f, 0.2f}, {96.1f, 0.05f} } ; -const F32 FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[FACE_IMPORTANCE_LEVEL][2] = //{cos(angle), importance_weight} - {{0.985f /*cos(10 degrees)*/, 1.0f}, {0.94f /*cos(20 degrees)*/, 0.8f}, {0.866f /*cos(30 degrees)*/, 0.64f}, {0.0f, 0.36f}} ; - -//static -F32 LLFace::calcImportanceToCamera(F32 cos_angle_to_view_dir, F32 dist) -{ - F32 importance = 0.f ; - - if(cos_angle_to_view_dir > LLViewerCamera::getInstance()->getCosHalfFov() && - dist < FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[FACE_IMPORTANCE_LEVEL - 1][0]) - { - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - - if(camera_moving_speed > 10.0f || camera_angular_speed > 1.0f) - { - //if camera moves or rotates too fast, ignore the importance factor - return 0.f ; - } - - //F32 camera_relative_speed = camera_moving_speed * (lookAt * LLViewerCamera::getInstance()->getVelocityDir()) ; - - S32 i = 0 ; - for(i = 0; i < FACE_IMPORTANCE_LEVEL && dist > FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][0]; ++i); - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - F32 dist_factor = FACE_IMPORTANCE_TO_CAMERA_OVER_DISTANCE[i][1] ; - - for(i = 0; i < FACE_IMPORTANCE_LEVEL && cos_angle_to_view_dir < FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][0] ; ++i) ; - i = llmin(i, FACE_IMPORTANCE_LEVEL - 1) ; - importance = dist_factor * FACE_IMPORTANCE_TO_CAMERA_OVER_ANGLE[i][1] ; - } - - return importance ; -} - BOOL LLFace::verify(const U32* indices_array) const { BOOL ok = TRUE; @@ -1586,3 +1541,153 @@ LLVector3 LLFace::getPositionAgent() const return mCenterLocal * getRenderMatrix(); } } + +// +//atlas +// +void LLFace::removeAtlas() +{ + setAtlasInUse(FALSE) ; + mAtlasInfop = NULL ; +} + +const LLTextureAtlas* LLFace::getAtlas()const +{ + if(mAtlasInfop) + { + return mAtlasInfop->getAtlas() ; + } + return NULL ; +} + +const LLVector2* LLFace::getTexCoordOffset()const +{ + if(isAtlasInUse()) + { + return mAtlasInfop->getTexCoordOffset() ; + } + return NULL ; +} +const LLVector2* LLFace::getTexCoordScale() const +{ + if(isAtlasInUse()) + { + return mAtlasInfop->getTexCoordScale() ; + } + return NULL ; +} + +BOOL LLFace::isAtlasInUse()const +{ + return mUsingAtlas ; +} + +BOOL LLFace::canUseAtlas()const +{ + //no drawable or no spatial group, do not use atlas + if(!mDrawablep || !mDrawablep->getSpatialGroup()) + { + return FALSE ; + } + + //if bump face, do not use atlas + if(getTextureEntry() && getTextureEntry()->getBumpmap()) + { + return FALSE ; + } + + //if animated texture, do not use atlas + if(isState(TEXTURE_ANIM)) + { + return FALSE ; + } + + return TRUE ; +} + +void LLFace::setAtlasInUse(BOOL flag) +{ + //no valid atlas to use. + if(flag && (!mAtlasInfop || !mAtlasInfop->isValid())) + { + flag = FALSE ; + } + + if(!flag && !mUsingAtlas) + { + return ; + } + + // + //at this stage (flag || mUsingAtlas) is always true. + // + + //rebuild the tex coords + if(mDrawablep) + { + gPipeline.markRebuild(mDrawablep, LLDrawable::REBUILD_TCOORD); + mUsingAtlas = flag ; + } + else + { + mUsingAtlas = FALSE ; + } +} + +LLTextureAtlasSlot* LLFace::getAtlasInfo() +{ + return mAtlasInfop ; +} + +void LLFace::setAtlasInfo(LLTextureAtlasSlot* atlasp) +{ + if(mAtlasInfop != atlasp) + { + if(mAtlasInfop) + { + //llwarns << "Atlas slot changed!" << llendl ; + } + mAtlasInfop = atlasp ; + } +} + +LLImageGL* LLFace::getGLTexture() const +{ + if(isAtlasInUse()) + { + return (LLImageGL*)mAtlasInfop->getAtlas() ; + } + + return (LLImageGL*)mTexture ; +} + +//switch to atlas or switch back to gl texture +//return TRUE if using atlas. +BOOL LLFace::switchTexture() +{ + //no valid atlas or texture + if(!mAtlasInfop || !mAtlasInfop->isValid() || !mTexture) + { + return FALSE ; + } + + if(mTexture->getTexelsInAtlas() >= (U32)mVSize || mTexture->getTexelsInAtlas() >= mTexture->getTexelsInGLTexture()) + { + //switch to use atlas + //atlas resolution is qualified, use it. + if(!mUsingAtlas) + { + setAtlasInUse(TRUE) ; + } + } + else //if atlas not qualified. + { + //switch back to GL texture + if(mUsingAtlas && mTexture->isGLTextureCreated() && mTexture->getDiscardLevel() < mTexture->getDiscardLevelInAtlas()) + { + setAtlasInUse(FALSE) ; + } + } + + return mUsingAtlas ; +} diff --git a/linden/indra/newview/llface.h b/linden/indra/newview/llface.h index 4893e82..9f76d6b 100644 --- a/linden/indra/newview/llface.h +++ b/linden/indra/newview/llface.h @@ -48,6 +48,7 @@ #include "llviewerimage.h" #include "llstat.h" #include "lldrawable.h" +#include "lltextureatlasmanager.h" class LLFacePool; class LLVolume; @@ -56,6 +57,7 @@ class LLTextureEntry; class LLVertexProgram; class LLViewerImage; class LLGeometryManager; +class LLTextureAtlasSlot; const F32 MIN_ALPHA_SIZE = 1024.f; const F32 MIN_TEX_ANIM_SIZE = 512.f; @@ -189,14 +191,18 @@ public: void setIndicesIndex(S32 idx) { mIndicesIndex = idx; } void setDrawInfo(LLDrawInfo* draw_info); - F32 getTextureVirtualSize() ; - F32 getImportanceToCamera()const {return mImportanceToCamera ;} - -private: - F32 adjustPartialOverlapPixelArea(F32 cos_angle_to_view_dir, F32 radius ); - F32 calcPixelArea(F32& cos_angle_to_view_dir, F32& radius) ; -public: - static F32 calcImportanceToCamera(F32 to_view_dir, F32 dist); + // KL was atlas S19 + LLImageGL* getGLTexture() const; + LLTextureAtlasSlot* getAtlasInfo() ; + void setAtlasInUse(BOOL flag); + void setAtlasInfo(LLTextureAtlasSlot* atlasp); + BOOL isAtlasInUse()const; + BOOL canUseAtlas() const; + const LLVector2* getTexCoordScale() const ; + const LLVector2* getTexCoordOffset()const; + const LLTextureAtlas* getAtlas()const ; + void removeAtlas() ; + BOOL switchTexture() ; public: @@ -212,7 +218,7 @@ public: LLMatrix4* mTextureMatrix; LLDrawInfo* mDrawInfo; -private: +protected: friend class LLGeometryManager; friend class LLVolumeGeometryManager; @@ -242,12 +248,10 @@ private: F32 mVSize; F32 mPixelArea; - //importance factor, in the range [0, 1.0]. - //1.0: the most important. - //based on the distance from the face to the view point and the angle from the face center to the view direction. - F32 mImportanceToCamera ; - F32 mBoundingSphereRadius ; - + //atlas + LLPointer mAtlasInfop ; + BOOL mUsingAtlas ; + protected: static BOOL sSafeRenderSelect; @@ -275,9 +279,9 @@ public: const LLTextureEntry* lte = lhs->getTextureEntry(); const LLTextureEntry* rte = rhs->getTextureEntry(); - if (lhs->getTexture() != rhs->getTexture()) + if(lhs->getGLTexture() != rhs->getGLTexture()) // KL SD get GL { - return lhs->getTexture() < rhs->getTexture(); + return lhs->getGLTexture() < rhs->getGLTexture(); // not getTexture? } else if (lte->getBumpShinyFullbright() != rte->getBumpShinyFullbright()) { diff --git a/linden/indra/newview/llfloaterassetbrowser.cpp b/linden/indra/newview/llfloaterassetbrowser.cpp index af81c4a..9b41390 100644 --- a/linden/indra/newview/llfloaterassetbrowser.cpp +++ b/linden/indra/newview/llfloaterassetbrowser.cpp @@ -63,7 +63,7 @@ LLFloaterAssetBrowser::~LLFloaterAssetBrowser() mTextureAssets.clear(); mMaxIndex = 0; mFirstIndex = 0; - mMouseOverIndex = 0; + mMouseOverIndex = NULL; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -79,7 +79,7 @@ void LLFloaterAssetBrowser::initialize() mAssetInfoIndex = 0; mFloaterHeight = getRect().getHeight(); mFloaterWidth = getRect().getWidth(); - mMouseOverIndex = 0; + mMouseOverIndex = NULL; mMouseOverUUID = LLUUID::null; mMouseOverAssetUUID = LLUUID::null; mFloaterTitle = ""; @@ -122,7 +122,7 @@ void LLFloaterAssetBrowser::createThumbnails() temp.mUUID = itemp->getUUID(); temp.mName = itemp->getName(); temp.mTexturep = NULL; - temp.mAssetRect = LLRect::null; + temp.mAssetRect = NULL; mTextureAssets.push_back(temp); } @@ -131,14 +131,14 @@ void LLFloaterAssetBrowser::createThumbnails() { mTextureAssets[i].mTexturep = gImageList.getImage(mTextureAssets[i].mAssetUUID, MIPMAP_YES, IMMEDIATE_NO); mTextureAssets[i].mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); - //mTextureAssets[i].mTexturep->processTextureStats(); + mTextureAssets[i].mTexturep->processTextureStats(); } //Generate the asset info text - /*for(S32 i = 0; i < items.count(); i++) + for(S32 i = 0; i < items.count(); i++) { - LLString asset_info; - LLString dimensions; + std::string asset_info; + std::string dimensions; asset_info.append(mTextureAssets[i].mName); @@ -151,7 +151,7 @@ void LLFloaterAssetBrowser::createThumbnails() asset_info.append(dimensions); mTextureAssets[i].mAssetInfo = asset_info; - }*/ + } mFloaterTitle = llformat("Asset Browser (%d assets fetched)", mTextureAssets.size()); setTitle(mFloaterTitle); @@ -288,7 +288,7 @@ void LLFloaterAssetBrowser::draw() if(mImageAssetID.notNull()) { mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO); - //mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW); + mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW); mTexturep->processTextureStats(); mTextureAssets[i].mWidth = mTexturep->mFullWidth; mTextureAssets[i].mHeight = mTexturep->mFullHeight; diff --git a/linden/indra/newview/llfloaterchat.cpp b/linden/indra/newview/llfloaterchat.cpp index 2daa5aa..5f43406 100644 --- a/linden/indra/newview/llfloaterchat.cpp +++ b/linden/indra/newview/llfloaterchat.cpp @@ -582,7 +582,8 @@ void LLFloaterChat::addChat(const LLChat& chat, // We display anything if it's not an IM. If it's an IM, check pref... if ( !from_instant_message || gSavedSettings.getBOOL("IMInChatConsole") ) { - gConsole->addLine(chat.mText, size, text_color); + gConsole->addConsoleLine(chat.mText, text_color); + } } diff --git a/linden/indra/newview/llfloaterhardwaresettings.cpp b/linden/indra/newview/llfloaterhardwaresettings.cpp index 7886e39..8c91f5a 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.cpp +++ b/linden/indra/newview/llfloaterhardwaresettings.cpp @@ -68,6 +68,7 @@ void LLFloaterHardwareSettings::onClickHelp(void* data) void LLFloaterHardwareSettings::initCallbacks(void) { + childSetCommitCallback("fbo", refreshState); } // menu maintenance functions @@ -83,7 +84,8 @@ void LLFloaterHardwareSettings::refresh() mVideoCardMem = gSavedSettings.getS32("TextureMemory"); mFogRatio = gSavedSettings.getF32("RenderFogRatio"); mProbeHardwareOnStartup = gSavedSettings.getBOOL("ProbeHardwareOnStartup"); - + mRenderDeferred = gSavedSettings.getBOOL("RenderDeferred"); + mRenderUseFBO = gSavedSettings.getBOOL("RenderUseFBO"); childSetValue("fsaa", (LLSD::Integer) mFSAASamples); refreshEnabledState(); } @@ -101,6 +103,20 @@ void LLFloaterHardwareSettings::refreshEnabledState() childSetEnabled("vbo", FALSE); } + if (!gGLManager.mHasFramebufferObject) + { + childSetEnabled("fbo", FALSE); + } + + if (!gGLManager.mHasDrawBuffers || !gSavedSettings.getBOOL("RenderUseFBO")) + { + childSetEnabled("deferred", FALSE); + } + else + { + childSetEnabled("deferred", TRUE); + } + // if no windlight shaders, turn off nighttime brightness, gamma, and fog distance childSetEnabled("gamma", !gPipeline.canUseWindLightShaders()); childSetEnabled("(brightness, lower is brighter)", !gPipeline.canUseWindLightShaders()); @@ -108,6 +124,12 @@ void LLFloaterHardwareSettings::refreshEnabledState() } +//static +void LLFloaterHardwareSettings::refreshState(LLUICtrl*, void*) +{ + LLFloaterHardwareSettings::instance()->refreshEnabledState(); +} + // static instance of it LLFloaterHardwareSettings* LLFloaterHardwareSettings::instance() { @@ -202,7 +224,8 @@ void LLFloaterHardwareSettings::cancel() gSavedSettings.setS32("TextureMemory", mVideoCardMem); gSavedSettings.setF32("RenderFogRatio", mFogRatio); gSavedSettings.setBOOL("ProbeHardwareOnStartup", mProbeHardwareOnStartup ); - + gSavedSettings.setBOOL("RenderUseFBO", mRenderUseFBO); + gSavedSettings.setBOOL("RenderDeferred", mRenderDeferred); close(); } diff --git a/linden/indra/newview/llfloaterhardwaresettings.h b/linden/indra/newview/llfloaterhardwaresettings.h index 04a33f6..e564e1c 100644 --- a/linden/indra/newview/llfloaterhardwaresettings.h +++ b/linden/indra/newview/llfloaterhardwaresettings.h @@ -61,6 +61,8 @@ public: /// OK button static void onBtnOK( void* userdata ); + static void refreshState(LLUICtrl*, void*); + //// menu management /// show off our menu @@ -88,6 +90,8 @@ protected: LLSliderCtrl* mCtrlVideoCardMem; BOOL mUseVBO; + BOOL mRenderUseFBO; + BOOL mRenderDeferred; BOOL mUseAniso; U32 mFSAASamples; F32 mGamma; diff --git a/linden/indra/newview/llfloaterlagmeter.cpp b/linden/indra/newview/llfloaterlagmeter.cpp index 8fe455f..2ae2e32 100644 --- a/linden/indra/newview/llfloaterlagmeter.cpp +++ b/linden/indra/newview/llfloaterlagmeter.cpp @@ -180,7 +180,7 @@ void LLFloaterLagMeter::determineClient() { mClientCause->setText( getString("client_texture_loading_cause_msg", mStringArgs) ); } - else if((BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes)) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) + else if((LLViewerImage::sBoundTextureMemoryInBytes >> 20) > LLViewerImage::sMaxBoundTextureMemInMegaBytes) { mClientCause->setText( getString("client_texture_memory_cause_msg", mStringArgs) ); } diff --git a/linden/indra/newview/llfloaterpostprocess.cpp b/linden/indra/newview/llfloaterpostprocess.cpp index de9b598..c5b2018 100644 --- a/linden/indra/newview/llfloaterpostprocess.cpp +++ b/linden/indra/newview/llfloaterpostprocess.cpp @@ -52,28 +52,29 @@ LLFloaterPostProcess::LLFloaterPostProcess() : LLFloater(std::string("Post-Proce LLUICtrlFactory::getInstance()->buildFloater(this, "floater_post_process.xml"); /// Color Filter Callbacks - childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + //childSetCommitCallback("ColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); + childSetCommitCallback("wmiColorFilterToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_color_filter"); //childSetCommitCallback("ColorFilterGamma", &LLFloaterPostProcess::onFloatControlMoved, &(gPostProcess->tweaks.gamma())); - childSetCommitCallback("ColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); - childSetCommitCallback("ColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); - childSetCommitCallback("ColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); + childSetCommitCallback("wmiColorFilterBrightness", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness"); + childSetCommitCallback("wmiColorFilterSaturation", &LLFloaterPostProcess::onFloatControlMoved, (char*)"saturation"); + childSetCommitCallback("wmiColorFilterContrast", &LLFloaterPostProcess::onFloatControlMoved, (char*)"contrast"); - childSetCommitCallback("ColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); - childSetCommitCallback("ColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseR", &LLFloaterPostProcess::onColorControlRMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseG", &LLFloaterPostProcess::onColorControlGMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseB", &LLFloaterPostProcess::onColorControlBMoved, (char*)"contrast_base"); + childSetCommitCallback("wmiColorFilterBaseI", &LLFloaterPostProcess::onColorControlIMoved, (char*)"contrast_base"); /// Night Vision Callbacks - childSetCommitCallback("NightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); - childSetCommitCallback("NightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); - childSetCommitCallback("NightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); - childSetCommitCallback("NightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); + childSetCommitCallback("wmiNightVisionToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_night_vision"); + childSetCommitCallback("wmiNightVisionBrightMult", &LLFloaterPostProcess::onFloatControlMoved, (char*)"brightness_multiplier"); + childSetCommitCallback("wmiNightVisionNoiseSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_size"); + childSetCommitCallback("wmiNightVisionNoiseStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"noise_strength"); /// Bloom Callbacks - childSetCommitCallback("BloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); - childSetCommitCallback("BloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); - childSetCommitCallback("BloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); - childSetCommitCallback("BloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); + childSetCommitCallback("wmiBloomToggle", &LLFloaterPostProcess::onBoolToggle, (char*)"enable_bloom"); + childSetCommitCallback("wmiBloomExtract", &LLFloaterPostProcess::onFloatControlMoved, (char*)"extract_low"); + childSetCommitCallback("wmiBloomSize", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_width"); + childSetCommitCallback("wmiBloomStrength", &LLFloaterPostProcess::onFloatControlMoved, (char*)"bloom_strength"); // Effect loading and saving. LLComboBox* comboBox = getChild("PPEffectsCombo"); @@ -113,6 +114,7 @@ void LLFloaterPostProcess::onBoolToggle(LLUICtrl* ctrl, void* userData) // check the bool LLCheckBoxCtrl* cbCtrl = static_cast(ctrl); gPostProcess->tweaks[boolVariableName] = cbCtrl->getValue(); + } // Float Moved @@ -247,25 +249,25 @@ void LLFloaterPostProcess::syncMenu() comboBox->selectByValue(gPostProcess->getSelectedEffect()); /// Sync Color Filter Menu - childSetValue("ColorFilterToggle", gPostProcess->tweaks.useColorFilter()); + childSetValue("wmiColorFilterToggle", gPostProcess->tweaks.useColorFilter()); //childSetValue("ColorFilterGamma", gPostProcess->tweaks.gamma()); - childSetValue("ColorFilterBrightness", gPostProcess->tweaks.brightness()); - childSetValue("ColorFilterSaturation", gPostProcess->tweaks.saturation()); - childSetValue("ColorFilterContrast", gPostProcess->tweaks.contrast()); - childSetValue("ColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); - childSetValue("ColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); - childSetValue("ColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); - childSetValue("ColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); + childSetValue("wmiColorFilterBrightness", gPostProcess->tweaks.brightness()); + childSetValue("wmiColorFilterSaturation", gPostProcess->tweaks.saturation()); + childSetValue("wmiColorFilterContrast", gPostProcess->tweaks.contrast()); + childSetValue("wmiColorFilterBaseR", gPostProcess->tweaks.contrastBaseR()); + childSetValue("wmiColorFilterBaseG", gPostProcess->tweaks.contrastBaseG()); + childSetValue("wmiColorFilterBaseB", gPostProcess->tweaks.contrastBaseB()); + childSetValue("wmiColorFilterBaseI", gPostProcess->tweaks.contrastBaseIntensity()); /// Sync Night Vision Menu - childSetValue("NightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); - childSetValue("NightVisionBrightMult", gPostProcess->tweaks.brightMult()); - childSetValue("NightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); - childSetValue("NightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); + childSetValue("wmiNightVisionToggle", gPostProcess->tweaks.useNightVisionShader()); + childSetValue("wmiNightVisionBrightMult", gPostProcess->tweaks.brightMult()); + childSetValue("wmiNightVisionNoiseSize", gPostProcess->tweaks.noiseSize()); + childSetValue("wmiNightVisionNoiseStrength", gPostProcess->tweaks.noiseStrength()); /// Sync Bloom Menu - childSetValue("BloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); - childSetValue("BloomExtract", gPostProcess->tweaks.extractLow()); - childSetValue("BloomSize", gPostProcess->tweaks.bloomWidth()); - childSetValue("BloomStrength", gPostProcess->tweaks.bloomStrength()); + childSetValue("wmiBloomToggle", LLSD(gPostProcess->tweaks.useBloomShader())); + childSetValue("wmiBloomExtract", gPostProcess->tweaks.extractLow()); + childSetValue("wmiBloomSize", gPostProcess->tweaks.bloomWidth()); + childSetValue("wmiBloomStrength", gPostProcess->tweaks.bloomStrength()); } diff --git a/linden/indra/newview/llfloaterreporter.cpp b/linden/indra/newview/llfloaterreporter.cpp index a7f41ea..9209f41 100644 --- a/linden/indra/newview/llfloaterreporter.cpp +++ b/linden/indra/newview/llfloaterreporter.cpp @@ -952,7 +952,8 @@ void LLFloaterReporter::takeScreenshot() // store in the image list so it doesn't try to fetch from the server LLPointer image_in_list = new LLViewerImage(mResourceDatap->mAssetInfo.mUuid); - image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + image_in_list->createGLTexture(0, raw); + gImageList.addImage(image_in_list); // the texture picker then uses that texture diff --git a/linden/indra/newview/llhudeffect.cpp b/linden/indra/newview/llhudeffect.cpp index c1d46f9..20bbb32 100644 --- a/linden/indra/newview/llhudeffect.cpp +++ b/linden/indra/newview/llhudeffect.cpp @@ -78,7 +78,7 @@ void LLHUDEffect::unpackData(LLMessageSystem *mesgsys, S32 blocknum) void LLHUDEffect::render() { - llerrs << "Never call this!" << llendl; + llwarns << "Never call this!" << llendl; // Then why the &*^&*^ is it here? } void LLHUDEffect::setID(const LLUUID &id) diff --git a/linden/indra/newview/llhudtext.cpp b/linden/indra/newview/llhudtext.cpp index 661a786..b170337 100644 --- a/linden/indra/newview/llhudtext.cpp +++ b/linden/indra/newview/llhudtext.cpp @@ -1111,6 +1111,8 @@ void LLHUDText::renderAllHUD() LLVertexBuffer::unbind(); + LLVertexBuffer::unbind(); // KL not entirely sure why but render pipeline has this twice? + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); diff --git a/linden/indra/newview/llmanip.cpp b/linden/indra/newview/llmanip.cpp index 45550fc..0c88c47 100644 --- a/linden/indra/newview/llmanip.cpp +++ b/linden/indra/newview/llmanip.cpp @@ -60,7 +60,7 @@ #include "llglheaders.h" // Local constants... -const S32 VERTICAL_OFFSET = 50; +const S32 VERTICAL_OFFSET = 100; // KL adjusted to compensate for toolbars move to the top of the screen! F32 LLManip::sHelpTextVisibleTime = 2.f; F32 LLManip::sHelpTextFadeTime = 2.f; diff --git a/linden/indra/newview/llmaniptranslate.h b/linden/indra/newview/llmaniptranslate.h index 77f12ff..25ff35c 100644 --- a/linden/indra/newview/llmaniptranslate.h +++ b/linden/indra/newview/llmaniptranslate.h @@ -116,7 +116,7 @@ private: LLVector3d mDragCursorStartGlobal; LLVector3d mDragSelectionStartGlobal; LLTimer mUpdateTimer; - typedef std::multiset minpulator_list_t; + typedef std::set minpulator_list_t; minpulator_list_t mProjectedManipulators; LLVector4 mManipulatorVertices[18]; F32 mSnapOffsetMeters; diff --git a/linden/indra/newview/llmediactrl.cpp b/linden/indra/newview/llmediactrl.cpp index 1530598..a517332 100644 --- a/linden/indra/newview/llmediactrl.cpp +++ b/linden/indra/newview/llmediactrl.cpp @@ -1012,8 +1012,7 @@ BOOL LLWebBrowserTexture::render() x_pos, y_pos, width, - height, - TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) + height); } media_plugin->resetDirty(); diff --git a/linden/indra/newview/lloverlaybar.cpp b/linden/indra/newview/lloverlaybar.cpp index db4422d..e903df7 100644 --- a/linden/indra/newview/lloverlaybar.cpp +++ b/linden/indra/newview/lloverlaybar.cpp @@ -491,7 +491,6 @@ void LLOverlayBar::toggleMusicPlay(void*) // if ( gAudiop->isInternetStreamPlaying() == 0 ) { gAudiop->startInternetStream(parcel->getMusicURL()); -//awfixme sTitleObserver.init(parcel->getMusicURL()); } } } diff --git a/linden/indra/newview/llpanelvolume.cpp b/linden/indra/newview/llpanelvolume.cpp index 6d014a2..4270f0b 100644 --- a/linden/indra/newview/llpanelvolume.cpp +++ b/linden/indra/newview/llpanelvolume.cpp @@ -53,6 +53,7 @@ #include "llbutton.h" #include "llcheckboxctrl.h" #include "llcolorswatch.h" +#include "lltexturectrl.h" #include "llcombobox.h" #include "llfirstuse.h" #include "llfocusmgr.h" @@ -111,12 +112,28 @@ BOOL LLPanelVolume::postBuild() LightColorSwatch->setOnSelectCallback(onLightSelectColor); childSetCommitCallback("colorswatch",onCommitLight,this); } + + LLTextureCtrl* LightTexPicker = getChild("light texture control"); + if (LightTexPicker) + { + LightTexPicker->setOnCancelCallback(onLightCancelTexture); + LightTexPicker->setOnSelectCallback(onLightSelectTexture); + childSetCommitCallback("light texture control", onCommitLight, this); + } + childSetCommitCallback("Light Intensity",onCommitLight,this); childSetValidate("Light Intensity",precommitValidate); childSetCommitCallback("Light Radius",onCommitLight,this); childSetValidate("Light Radius",precommitValidate); childSetCommitCallback("Light Falloff",onCommitLight,this); childSetValidate("Light Falloff",precommitValidate); + + childSetCommitCallback("Light FOV", onCommitLight, this); + childSetValidate("Light FOV", precommitValidate); + childSetCommitCallback("Light Focus", onCommitLight, this); + childSetValidate("Light Focus", precommitValidate); + childSetCommitCallback("Light Ambiance", onCommitLight, this); + childSetValidate("Light Ambiance", precommitValidate); } // Start with everyone disabled @@ -221,14 +238,32 @@ void LLPanelVolume::getState( ) LightColorSwatch->setValid( TRUE ); LightColorSwatch->set(volobjp->getLightBaseColor()); } + + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(TRUE); + LightTextureCtrl->setValid(TRUE); + LightTextureCtrl->setImageAssetID(volobjp->getLightTextureID()); + } + childSetEnabled("Light Intensity",true); childSetEnabled("Light Radius",true); childSetEnabled("Light Falloff",true); + childSetEnabled("Light FOV", true); + childSetEnabled("Light Focus", true); + childSetEnabled("Light Ambiance", true); + childSetValue("Light Intensity",volobjp->getLightIntensity()); childSetValue("Light Radius",volobjp->getLightRadius()); childSetValue("Light Falloff",volobjp->getLightFalloff()); + LLVector3 params = volobjp->getSpotLightParams(); + childSetValue("Light FOV", params.mV[0]); + childSetValue("Light Focus", params.mV[1]); + childSetValue("Light Ambiance", params.mV[2]); + mLightSavedColor = volobjp->getLightColor(); } else @@ -244,9 +279,20 @@ void LLPanelVolume::getState( ) LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setEnabled(FALSE); + LightTextureCtrl->setValid(FALSE); + } + childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); + + childSetEnabled("Light FOV",false); + childSetEnabled("Light Focus",false); + childSetEnabled("Light Ambiance",false); } // Flexible properties @@ -362,6 +408,13 @@ void LLPanelVolume::clearCtrls() LightColorSwatch->setEnabled( FALSE ); LightColorSwatch->setValid( FALSE ); } + LLTextureCtrl* LightTextureCtrl = getChild("light texture control"); + if(LightTextureCtrl) + { + LightTextureCtrl->setEnabled( FALSE ); + LightTextureCtrl->setValid( FALSE ); + } + childSetEnabled("Light Intensity",false); childSetEnabled("Light Radius",false); childSetEnabled("Light Falloff",false); @@ -438,6 +491,16 @@ void LLPanelVolume::onLightCancelColor(LLUICtrl* ctrl, void* userdata) onLightSelectColor(NULL, userdata); } +void LLPanelVolume::onLightCancelTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if (LightTextureCtrl) + { + LightTextureCtrl->setImageAssetID(self->mLightSavedTexture); + } +} + void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) { LLPanelVolume* self = (LLPanelVolume*) userdata; @@ -459,6 +522,25 @@ void LLPanelVolume::onLightSelectColor(LLUICtrl* ctrl, void* userdata) } } +void LLPanelVolume::onLightSelectTexture(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*) userdata; + LLViewerObject* objectp = self->mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume *volobjp = (LLVOVolume *)objectp; + + + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + volobjp->setLightTextureID(id); + self->mLightSavedTexture = id; + } +} // static void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) { @@ -474,12 +556,47 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) volobjp->setLightIntensity((F32)self->childGetValue("Light Intensity").asReal()); volobjp->setLightRadius((F32)self->childGetValue("Light Radius").asReal()); volobjp->setLightFalloff((F32)self->childGetValue("Light Falloff").asReal()); + LLColorSwatchCtrl* LightColorSwatch = self->getChild("colorswatch"); if(LightColorSwatch) { LLColor4 clr = LightColorSwatch->get(); volobjp->setLightColor(LLColor3(clr)); } + + LLTextureCtrl* LightTextureCtrl = self->getChild("light texture control"); + if(LightTextureCtrl) + { + LLUUID id = LightTextureCtrl->getImageAssetID(); + if (id.notNull()) + { + if (volobjp->getLightTextureID().isNull()) + { //this commit is making this a spot light, set UI to default params + volobjp->setLightTextureID(id); + LLVector3 spot_params = volobjp->getSpotLightParams(); + self->childSetValue("Light FOV", spot_params.mV[0]); + self->childSetValue("Light Focus", spot_params.mV[1]); + self->childSetValue("Light Ambiance", spot_params.mV[2]); + } + else + { //modifying existing params + LLVector3 spot_params; + spot_params.mV[0] = (F32) self->childGetValue("Light FOV").asReal(); + spot_params.mV[1] = (F32) self->childGetValue("Light Focus").asReal(); + spot_params.mV[2] = (F32) self->childGetValue("Light Ambiance").asReal(); + volobjp->setSpotLightParams(spot_params); + } + } + else if (volobjp->getLightTextureID().notNull()) + { //no longer a spot light + volobjp->setLightTextureID(id); + //self->childDisable("Light FOV"); + //self->childDisable("Light Focus"); + //self->childDisable("Light Ambiance"); + } + } + + } // static diff --git a/linden/indra/newview/llpanelvolume.h b/linden/indra/newview/llpanelvolume.h index 841880b..5d206fc 100644 --- a/linden/indra/newview/llpanelvolume.h +++ b/linden/indra/newview/llpanelvolume.h @@ -74,6 +74,10 @@ public: static void onLightCancelColor(LLUICtrl* ctrl, void* userdata); static void onLightSelectColor(LLUICtrl* ctrl, void* userdata); + static void onLightCancelTexture(LLUICtrl* ctrl, void* userdata); + static void onLightSelectTexture(LLUICtrl* ctrl, void* userdata); + + protected: void getState(); @@ -99,6 +103,7 @@ protected: */ LLColor4 mLightSavedColor; + LLUUID mLightSavedTexture; LLPointer mObject; LLPointer mRootObject; }; diff --git a/linden/indra/newview/llpostprocess.cpp b/linden/indra/newview/llpostprocess.cpp new file mode 100644 index 0000000..c7d5dad --- /dev/null +++ b/linden/indra/newview/llpostprocess.cpp @@ -0,0 +1,594 @@ +/** + * @file llpostprocess.cpp + * @brief LLPostProcess class implementation + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "linden_common.h" + +#include "llpostprocess.h" +#include "llglslshader.h" +#include "llsdserialize.h" +#include "llrender.h" + +#include "llviewershadermgr.h" // KL throwing some includes at postprocess see if we can get the bastard working! +#include "pipeline.h" +#include "llimagegl.h" + + + +LLPostProcess * gPostProcess = NULL; + + +static const unsigned int NOISE_SIZE = 512; + +/// CALCULATING LUMINANCE (Using NTSC lum weights) +/// http://en.wikipedia.org/wiki/Luma_%28video%29 +static const float LUMINANCE_R = 0.299f; +static const float LUMINANCE_G = 0.587f; +static const float LUMINANCE_B = 0.114f; + +static const char * const XML_FILENAME = "postprocesseffects.xml"; + +LLPostProcess::LLPostProcess(void) : + initialized(false), + mAllEffects(LLSD::emptyMap()), + screenW(1), screenH(1) +{ + mSceneRenderTexture = NULL ; + mNoiseTexture = NULL ; + mTempBloomTexture = NULL ; + + // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + LL_DEBUGS2("AppInit", "Shaders") << "Loading PostProcess Effects settings from " << pathName << LL_ENDL; + + llifstream effectsXML(pathName); + + if (effectsXML) + { + LLPointer parser = new LLSDXMLParser(); + + parser->parse(effectsXML, mAllEffects, LLSDSerialize::SIZE_UNLIMITED); + } + + if (!mAllEffects.has("default")) + { + LLSD & defaultEffect = (mAllEffects["default"] = LLSD::emptyMap()); + + defaultEffect["enable_night_vision"] = LLSD::Boolean(false); + defaultEffect["enable_bloom"] = LLSD::Boolean(false); + defaultEffect["enable_color_filter"] = LLSD::Boolean(false); + + /// NVG Defaults + defaultEffect["brightness_multiplier"] = 3.0; + defaultEffect["noise_size"] = 25.0; + defaultEffect["noise_strength"] = 0.4; + + // TODO BTest potentially add this to tweaks? + noiseTextureScale = 1.0f; + + /// Bloom Defaults + defaultEffect["extract_low"] = 0.95; + defaultEffect["extract_high"] = 1.0; + defaultEffect["bloom_width"] = 2.25; + defaultEffect["bloom_strength"] = 1.5; + + /// Color Filter Defaults + defaultEffect["brightness"] = 1.0; + defaultEffect["contrast"] = 1.0; + defaultEffect["saturation"] = 1.0; + + LLSD& contrastBase = (defaultEffect["contrast_base"] = LLSD::emptyArray()); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(1.0); + contrastBase.append(0.5); + } + + setSelectedEffect("default"); + +} + +LLPostProcess::~LLPostProcess(void) +{ + invalidate() ; +} + +// static +void LLPostProcess::initClass(void) +{ + //this will cause system to crash at second time login + //if first time login fails due to network connection --- bao + //***llassert_always(gPostProcess == NULL); + //replaced by the following line: + if(gPostProcess) + return ; + + + gPostProcess = new LLPostProcess(); +} + +// static +void LLPostProcess::cleanupClass() +{ + delete gPostProcess; + gPostProcess = NULL; +} + +void LLPostProcess::setSelectedEffect(std::string const & effectName) +{ + mSelectedEffectName = effectName; + static_cast(tweaks) = mAllEffects[effectName]; +} + +void LLPostProcess::saveEffect(std::string const & effectName) +{ + // Do nothing. Needs to be updated to use our current shader system, and to work with the move into llrender. + mAllEffects[effectName] = tweaks; + + std::string pathName(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", XML_FILENAME)); + //llinfos << "Saving PostProcess Effects settings to " << pathName << llendl; + + llofstream effectsXML(pathName); + + LLPointer formatter = new LLSDXMLFormatter(); + + formatter->format(mAllEffects, effectsXML); + +} +void LLPostProcess::invalidate() +{ + mSceneRenderTexture = NULL ; + mNoiseTexture = NULL ; + mTempBloomTexture = NULL ; + initialized = FALSE ; +} + +void LLPostProcess::apply(unsigned int width, unsigned int height) +{ + if (!initialized || width != screenW || height != screenH){ + initialize(width, height); + } + if (shadersEnabled()){ + doEffects(); + } +} + +void LLPostProcess::initialize(unsigned int width, unsigned int height) +{ + screenW = width; + screenH = height; + createTexture(mSceneRenderTexture, screenW, screenH); + initialized = true; + + checkError(); + createNightVisionShader(); + createBloomShader(); + createColorFilterShader(); + checkError(); +} + +inline bool LLPostProcess::shadersEnabled(void) +{ + return (tweaks.useColorFilter().asBoolean() || + tweaks.useNightVisionShader().asBoolean() || + tweaks.useBloomShader().asBoolean() ); + +} + +void LLPostProcess::applyShaders(void) +{ + if (tweaks.useColorFilter()){ + applyColorFilterShader(); + checkError(); + } + if (tweaks.useNightVisionShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter()) + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + applyNightVisionShader(); + checkError(); + } + if (tweaks.useBloomShader()){ + /// If any of the above shaders have been called update the frame buffer; + if (tweaks.useColorFilter().asBoolean() || tweaks.useNightVisionShader().asBoolean()) + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + applyBloomShader(); + checkError(); + } +} + +void LLPostProcess::applyColorFilterShader(void) +{ + // Do nothing. moved back to newview work in progress KL + gPostColorFilterProgram.bind(); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); + + U32 tex = mSceneRenderTexture->getTexName() ; // KL + + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, tex); + + getShaderUniforms(colorFilterUniforms, gPostColorFilterProgram.mProgramObject); + glUniform1iARB(colorFilterUniforms["RenderTexture"], 0); + glUniform1fARB(colorFilterUniforms["brightness"], tweaks.getBrightness()); + glUniform1fARB(colorFilterUniforms["contrast"], tweaks.getContrast()); + float baseI = (tweaks.getContrastBaseR() + tweaks.getContrastBaseG() + tweaks.getContrastBaseB()) / 3.0f; + baseI = tweaks.getContrastBaseIntensity() / ((baseI < 0.001f) ? 0.001f : baseI); + float baseR = tweaks.getContrastBaseR() * baseI; + float baseG = tweaks.getContrastBaseG() * baseI; + float baseB = tweaks.getContrastBaseB() * baseI; + glUniform3fARB(colorFilterUniforms["contrastBase"], baseR, baseG, baseB); + glUniform1fARB(colorFilterUniforms["saturation"], tweaks.getSaturation()); + glUniform3fARB(colorFilterUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NORMAL); + gPostColorFilterProgram.unbind(); + +} + +void LLPostProcess::createColorFilterShader(void) +{ + /// Define uniform names + colorFilterUniforms["RenderTexture"] = 0; + colorFilterUniforms["brightness"] = 0; + colorFilterUniforms["contrast"] = 0; + colorFilterUniforms["contrastBase"] = 0; + colorFilterUniforms["saturation"] = 0; + colorFilterUniforms["lumWeights"] = 0; +} + +void LLPostProcess::applyNightVisionShader(void) +{ + // KL re-enabled and moved back to newview + gPostNightVisionProgram.bind(); + + gGL.getTexUnit(0)->activate(); + gGL.getTexUnit(0)->enable(LLTexUnit::TT_RECT_TEXTURE); + + getShaderUniforms(nightVisionUniforms, gPostNightVisionProgram.mProgramObject); + U32 sceneRenderTexture = mSceneRenderTexture->getTexName() ; // KL + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, sceneRenderTexture); + glUniform1iARB(nightVisionUniforms["RenderTexture"], 0); + + gGL.getTexUnit(1)->activate(); + gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); + U32 noiseTexture = mNoiseTexture->getTexName(); //KL + gGL.getTexUnit(1)->bindManual(LLTexUnit::TT_TEXTURE, noiseTexture); + glUniform1iARB(nightVisionUniforms["NoiseTexture"], 1); + + + glUniform1fARB(nightVisionUniforms["brightMult"], tweaks.getBrightMult()); + glUniform1fARB(nightVisionUniforms["noiseStrength"], tweaks.getNoiseStrength()); + noiseTextureScale = 0.01f + ((101.f - tweaks.getNoiseSize()) / 100.f); + noiseTextureScale *= (screenH / NOISE_SIZE); + + + glUniform3fARB(nightVisionUniforms["lumWeights"], LUMINANCE_R, LUMINANCE_G, LUMINANCE_B); + + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_REPLACE); + LLGLDepthTest depth(GL_FALSE); + + /// Draw a screen space quad + drawOrthoQuad(screenW, screenH, QUAD_NOISE); + gPostNightVisionProgram.unbind(); + gGL.getTexUnit(0)->activate(); + +} + +void LLPostProcess::createNightVisionShader(void) +{ + /// Define uniform names + nightVisionUniforms["RenderTexture"] = 0; + nightVisionUniforms["NoiseTexture"] = 0; + nightVisionUniforms["brightMult"] = 0; + nightVisionUniforms["noiseStrength"] = 0; + nightVisionUniforms["lumWeights"] = 0; + + createNoiseTexture(mNoiseTexture); +} + +void LLPostProcess::applyBloomShader(void) +{ + +} + +void LLPostProcess::createBloomShader(void) +{ + createTexture(mTempBloomTexture, unsigned(screenW * 0.5), unsigned(screenH * 0.5)); + + /// Create Bloom Extract Shader + bloomExtractUniforms["RenderTexture"] = 0; + bloomExtractUniforms["extractLow"] = 0; + bloomExtractUniforms["extractHigh"] = 0; + bloomExtractUniforms["lumWeights"] = 0; + + /// Create Bloom Blur Shader + bloomBlurUniforms["RenderTexture"] = 0; + bloomBlurUniforms["bloomStrength"] = 0; + bloomBlurUniforms["texelSize"] = 0; + bloomBlurUniforms["blurDirection"] = 0; + bloomBlurUniforms["blurWidth"] = 0; +} + +void LLPostProcess::getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog) +{ + /// Find uniform locations and insert into map + std::map::iterator i; + for (i = uniforms.begin(); i != uniforms.end(); ++i){ + i->second = glGetUniformLocationARB(prog, i->first); + } +} + +void LLPostProcess::doEffects(void) +{ + /// Save GL State + glPushAttrib(GL_ALL_ATTRIB_BITS); + glPushClientAttrib(GL_ALL_ATTRIB_BITS); + + /// Copy the screen buffer to the render texture + { + U32 tex = mSceneRenderTexture->getTexName() ; + copyFrameBuffer(tex, screenW, screenH); + } + + /// Clear the frame buffer. + glClearColor(0.0f, 0.0f, 0.0f, 1.0f); + glClear(GL_COLOR_BUFFER_BIT); + + /// Change to an orthogonal view + viewOrthogonal(screenW, screenH); + + checkError(); + applyShaders(); + + LLGLSLShader::bindNoShader(); + checkError(); + + /// Change to a perspective view + viewPerspective(); + + /// Reset GL State + glPopClientAttrib(); + glPopAttrib(); + checkError(); +} + +void LLPostProcess::copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height) +{ + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture); + glCopyTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA, 0, 0, width, height, 0); +} + +void LLPostProcess::drawOrthoQuad(unsigned int width, unsigned int height, QuadType type) +{ + + float noiseX = 0.f; + float noiseY = 0.f; + float screenRatio = 1.0f; + + if (type == QUAD_NOISE){ + noiseX = ((float) rand() / (float) RAND_MAX); + noiseY = ((float) rand() / (float) RAND_MAX); + screenRatio = (float) width / (float) height; + } + + + glBegin(GL_QUADS); + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, (GLfloat) height * 0.5f); + } + glVertex2f(0.f, (GLfloat) screenH - height); + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.f, 0.f); + } + glVertex2f(0.f, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, 0.f); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, 0.f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, 0.f); + } + glVertex2f((GLfloat) width, (GLfloat) height + (screenH - height)); + + + if (type != QUAD_BLOOM_EXTRACT){ + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width, (GLfloat) height); + } else { + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, (GLfloat) width * 2.0f, (GLfloat) height * 2.0f); + } + if (type == QUAD_NOISE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, + screenRatio * noiseTextureScale + noiseX, + noiseTextureScale + noiseY); + } else if (type == QUAD_BLOOM_COMBINE){ + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, (GLfloat) width * 0.5f, (GLfloat) height * 0.5f); + } + glVertex2f((GLfloat) width, (GLfloat) screenH - height); + glEnd(); + +} + +void LLPostProcess::viewOrthogonal(unsigned int width, unsigned int height) +{ + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho( 0.f, (GLdouble) width , (GLdouble) height , 0.f, -1.f, 1.f ); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); +} + +void LLPostProcess::viewPerspective(void) +{ + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + glPopMatrix(); +} + +void LLPostProcess::changeOrthogonal(unsigned int width, unsigned int height) +{ + viewPerspective(); + viewOrthogonal(width, height); +} + +void LLPostProcess::createTexture(LLPointer& texture, unsigned int width, unsigned int height) +{ + std::vector data(width * height * 4, 0) ; + + texture = new LLImageGL(FALSE) ; + if(texture->createGLTexture()) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_RECT_TEXTURE, texture->getTexName()); + glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 4, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + } +} + +void LLPostProcess::createNoiseTexture(LLPointer& texture) +{ + std::vector buffer(NOISE_SIZE * NOISE_SIZE); + for (unsigned int i = 0; i < NOISE_SIZE; i++){ + for (unsigned int k = 0; k < NOISE_SIZE; k++){ + buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); + } + } + + texture = new LLImageGL(FALSE) ; + if(texture->createGLTexture()) + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, texture->getTexName()); + LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_LUMINANCE, NOISE_SIZE, NOISE_SIZE, GL_LUMINANCE, GL_UNSIGNED_BYTE, &buffer[0]); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP); + } +} + +bool LLPostProcess::checkError(void) +{ + GLenum glErr; + bool retCode = false; + + glErr = glGetError(); + while (glErr != GL_NO_ERROR) + { + // shaderErrorLog << (const char *) gluErrorString(glErr) << std::endl; + char const * err_str_raw = (const char *) gluErrorString(glErr); + + if(err_str_raw == NULL) + { + std::ostringstream err_builder; + err_builder << "unknown error number " << glErr; + mShaderErrorString = err_builder.str(); + } + else + { + mShaderErrorString = err_str_raw; + } + + retCode = true; + glErr = glGetError(); + } + return retCode; +} + +void LLPostProcess::checkShaderError(GLhandleARB shader) +{ + GLint infologLength = 0; + GLint charsWritten = 0; + GLchar *infoLog; + + checkError(); // Check for OpenGL errors + + glGetObjectParameterivARB(shader, GL_OBJECT_INFO_LOG_LENGTH_ARB, &infologLength); + + checkError(); // Check for OpenGL errors + + if (infologLength > 0) + { + infoLog = (GLchar *)malloc(infologLength); + if (infoLog == NULL) + { + /// Could not allocate infolog buffer + return; + } + glGetInfoLogARB(shader, infologLength, &charsWritten, infoLog); + // shaderErrorLog << (char *) infoLog << std::endl; + mShaderErrorString = (char *) infoLog; + free(infoLog); + } + checkError(); // Check for OpenGL errors +} \ No newline at end of file diff --git a/linden/indra/newview/llpostprocess.h b/linden/indra/newview/llpostprocess.h new file mode 100644 index 0000000..d6926e4 --- /dev/null +++ b/linden/indra/newview/llpostprocess.h @@ -0,0 +1,274 @@ +/** + * @file llpostprocess.h + * @brief LLPostProcess class definition + * + * $LicenseInfo:firstyear=2007&license=viewergpl$ + * + * Copyright (c) 2007-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_POSTPROCESS_H +#define LL_POSTPROCESS_H + +#include +#include +#include "llgl.h" +#include "llglheaders.h" + +class LLPostProcess +{ +public: + + typedef enum _QuadType { + QUAD_NORMAL, + QUAD_NOISE, + QUAD_BLOOM_EXTRACT, + QUAD_BLOOM_COMBINE + } QuadType; + + /// GLSL Shader Encapsulation Struct + typedef std::map glslUniforms; + + struct PostProcessTweaks : public LLSD { + inline PostProcessTweaks() : LLSD(LLSD::emptyMap()) + { + } + + inline LLSD & brightMult() { + return (*this)["brightness_multiplier"]; + } + + inline LLSD & noiseStrength() { + return (*this)["noise_strength"]; + } + + inline LLSD & noiseSize() { + return (*this)["noise_size"]; + } + + inline LLSD & extractLow() { + return (*this)["extract_low"]; + } + + inline LLSD & extractHigh() { + return (*this)["extract_high"]; + } + + inline LLSD & bloomWidth() { + return (*this)["bloom_width"]; + } + + inline LLSD & bloomStrength() { + return (*this)["bloom_strength"]; + } + + inline LLSD & brightness() { + return (*this)["brightness"]; + } + + inline LLSD & contrast() { + return (*this)["contrast"]; + } + + inline LLSD & contrastBaseR() { + return (*this)["contrast_base"][0]; + } + + inline LLSD & contrastBaseG() { + return (*this)["contrast_base"][1]; + } + + inline LLSD & contrastBaseB() { + return (*this)["contrast_base"][2]; + } + + inline LLSD & contrastBaseIntensity() { + return (*this)["contrast_base"][3]; + } + + inline LLSD & saturation() { + return (*this)["saturation"]; + } + + inline LLSD & useNightVisionShader() { + return (*this)["enable_night_vision"]; + } + + inline LLSD & useBloomShader() { + return (*this)["enable_bloom"]; + } + + inline LLSD & useColorFilter() { + return (*this)["enable_color_filter"]; + } + + + inline F32 getBrightMult() const { + return F32((*this)["brightness_multiplier"].asReal()); + } + + inline F32 getNoiseStrength() const { + return F32((*this)["noise_strength"].asReal()); + } + + inline F32 getNoiseSize() const { + return F32((*this)["noise_size"].asReal()); + } + + inline F32 getExtractLow() const { + return F32((*this)["extract_low"].asReal()); + } + + inline F32 getExtractHigh() const { + return F32((*this)["extract_high"].asReal()); + } + + inline F32 getBloomWidth() const { + return F32((*this)["bloom_width"].asReal()); + } + + inline F32 getBloomStrength() const { + return F32((*this)["bloom_strength"].asReal()); + } + + inline F32 getBrightness() const { + return F32((*this)["brightness"].asReal()); + } + + inline F32 getContrast() const { + return F32((*this)["contrast"].asReal()); + } + + inline F32 getContrastBaseR() const { + return F32((*this)["contrast_base"][0].asReal()); + } + + inline F32 getContrastBaseG() const { + return F32((*this)["contrast_base"][1].asReal()); + } + + inline F32 getContrastBaseB() const { + return F32((*this)["contrast_base"][2].asReal()); + } + + inline F32 getContrastBaseIntensity() const { + return F32((*this)["contrast_base"][3].asReal()); + } + + inline F32 getSaturation() const { + return F32((*this)["saturation"].asReal()); + } + + }; + + bool initialized; + PostProcessTweaks tweaks; + + // the map of all availible effects + LLSD mAllEffects; + +private: + LLPointer mSceneRenderTexture ; + LLPointer mNoiseTexture ; + LLPointer mTempBloomTexture ; + + + +public: + LLPostProcess(void); + + ~LLPostProcess(void); + + void apply(unsigned int width, unsigned int height); + void invalidate() ; + + /// Perform global initialization for this class. + static void initClass(void); + + // Cleanup of global data that's only inited once per class. + static void cleanupClass(); + + void setSelectedEffect(std::string const & effectName); + + inline std::string const & getSelectedEffect(void) const { + return mSelectedEffectName; + } + + void saveEffect(std::string const & effectName); + +private: + /// read in from file + std::string mShaderErrorString; + unsigned int screenW; + unsigned int screenH; + + float noiseTextureScale; + + /// Shader Uniforms + glslUniforms nightVisionUniforms; + glslUniforms bloomExtractUniforms; + glslUniforms bloomBlurUniforms; + glslUniforms colorFilterUniforms; + + // the name of currently selected effect in mAllEffects + //invariant: tweaks == mAllEffects[mSelectedEffectName] + std::string mSelectedEffectName; + + /// General functions + void initialize(unsigned int width, unsigned int height); + void doEffects(void); + void applyShaders(void); + bool shadersEnabled(void); + + /// Night Vision Functions + void createNightVisionShader(void); + void applyNightVisionShader(void); + + /// Bloom Functions + void createBloomShader(void); + void applyBloomShader(void); + + /// Color Filter Functions + void createColorFilterShader(void); + void applyColorFilterShader(void); + + /// OpenGL Helper Functions + void getShaderUniforms(glslUniforms & uniforms, GLhandleARB & prog); + void createTexture(LLPointer& texture, unsigned int width, unsigned int height); + void copyFrameBuffer(U32 & texture, unsigned int width, unsigned int height); + void createNoiseTexture(LLPointer& texture); + bool checkError(void); + void checkShaderError(GLhandleARB shader); + void drawOrthoQuad(unsigned int width, unsigned int height, QuadType type); + void viewOrthogonal(unsigned int width, unsigned int height); + void changeOrthogonal(unsigned int width, unsigned int height); + void viewPerspective(void); +}; + +extern LLPostProcess * gPostProcess; + + +#endif // LL_POSTPROCESS_H diff --git a/linden/indra/newview/llpreview.cpp b/linden/indra/newview/llpreview.cpp index f679a75..019bd5f 100644 --- a/linden/indra/newview/llpreview.cpp +++ b/linden/indra/newview/llpreview.cpp @@ -641,6 +641,7 @@ void LLPreview::setAssetId(const LLUUID& asset_id) LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(NULL == object) { + llwarns << "LLPreview::setAssetId() called on unrecognized object, UUID : " << mObjectUUID << llendl; return; } object->updateViewerInventoryAsset(item, asset_id); diff --git a/linden/indra/newview/llselectmgr.cpp b/linden/indra/newview/llselectmgr.cpp index b2904b9..0fa8285 100644 --- a/linden/indra/newview/llselectmgr.cpp +++ b/linden/indra/newview/llselectmgr.cpp @@ -764,7 +764,7 @@ void LLSelectMgr::addAsIndividual(LLViewerObject *objectp, S32 face, BOOL undoab } else { - llerrs << "LLSelectMgr::add face " << face << " out-of-range" << llendl; + llwarns << "LLSelectMgr::add face " << face << " out-of-range" << llendl; return; } @@ -1187,7 +1187,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) } else { - llerrs << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; + llwarns << "LLSelectMgr::remove - tried to remove TE " << te << " that wasn't selected" << llendl; return; } @@ -1210,7 +1210,7 @@ void LLSelectMgr::remove(LLViewerObject *objectp, S32 te, BOOL undoable) else { // ...out of range face - llerrs << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; + llwarns << "LLSelectMgr::remove - TE " << te << " out of range" << llendl; } updateSelectionCenter(); @@ -1709,7 +1709,7 @@ void LLSelectMgr::selectionSetFullbright(U8 fullbright) } sendfunc(fullbright); getSelection()->applyToObjects(&sendfunc); } - +/* void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& media_url) { U8 media_flags = LLTextureEntry::MF_NONE; @@ -1752,7 +1752,7 @@ void LLSelectMgr::selectionSetMediaTypeAndURL(U8 media_type, const std::string& } sendfunc(media_type, media_url); getSelection()->applyToObjects(&sendfunc); } - +*/ void LLSelectMgr::selectionSetGlow(F32 glow) { struct f1 : public LLSelectedTEFunctor @@ -3344,7 +3344,7 @@ void LLSelectMgr::packPermissionsHead(void* user_data) /* void LLSelectMgr::sendSelect() { - llerrs << "Not implemented" << llendl; + llwarns << "Not implemented" << llendl; } */ @@ -4156,7 +4156,7 @@ void LLSelectMgr::sendListToRegions(const std::string& message_name, break; default: - llerrs << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; + llwarns << "Bad send type " << send_type << " passed to SendListToRegions()" << llendl; } // bail if nothing selected @@ -4563,11 +4563,6 @@ extern LLGLdouble gGLModelView[16]; void LLSelectMgr::updateSilhouettes() { - if (!mRenderSilhouettes || !LLSelectMgr::sRenderSelectionHighlights) - { - return; - } - S32 num_sils_genned = 0; LLVector3d cameraPos = gAgent.getCameraPositionGlobal(); @@ -5781,8 +5776,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove()) || - (gSavedSettings.getBOOL("SelectCopyableOnly") && !object->permCopy())) + (gSavedSettings.getBOOL("SelectMovableOnly") && !object->permMove())) { // only select my own objects return FALSE; diff --git a/linden/indra/newview/llselectmgr.h b/linden/indra/newview/llselectmgr.h index 6278049..b565770 100644 --- a/linden/indra/newview/llselectmgr.h +++ b/linden/indra/newview/llselectmgr.h @@ -503,7 +503,7 @@ public: void selectionSetTexGen( U8 texgen ); void selectionSetShiny( U8 shiny ); void selectionSetFullbright( U8 fullbright ); - void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); +// void selectionSetMediaTypeAndURL( U8 media_type, const std::string& media_url ); void selectionSetClickAction(U8 action); void selectionSetIncludeInSearch(bool include_in_search); void selectionSetGlow(const F32 glow); diff --git a/linden/indra/newview/llsky.cpp b/linden/indra/newview/llsky.cpp index ac7e865..b779aa0 100644 --- a/linden/indra/newview/llsky.cpp +++ b/linden/indra/newview/llsky.cpp @@ -422,6 +422,20 @@ void LLSky::updateFog(const F32 distance) void LLSky::updateCull() { + /*if (mVOSkyp.notNull() && mVOSkyp->mDrawable.notNull()) + { + gPipeline.markVisible(mVOSkyp->mDrawable); + } + else + { + llinfos << "No sky drawable!" << llendl; + }*/ + + /*if (mVOGroundp.notNull() && mVOGroundp->mDrawable.notNull()) + { + gPipeline.markVisible(mVOGroundp->mDrawable); + }*/ + // *TODO: do culling for wl sky properly -Brad } diff --git a/linden/indra/newview/llspatialpartition.cpp b/linden/indra/newview/llspatialpartition.cpp index 31b537c..114d3b5 100644 --- a/linden/indra/newview/llspatialpartition.cpp +++ b/linden/indra/newview/llspatialpartition.cpp @@ -48,6 +48,7 @@ #include "llrender.h" #include "lloctree.h" #include "llvoavatar.h" +#include "lltextureatlas.h" const F32 SG_OCCLUSION_FUDGE = 0.25f; #define SG_DISCARD_TOLERANCE 0.01f @@ -95,7 +96,7 @@ void sg_assert(BOOL expr) #if LL_OCTREE_PARANOIA_CHECK if (!expr) { - llerrs << "Octree invalid!" << llendl; + llwarns << "Octree invalid!" << llendl; } #endif } @@ -281,10 +282,10 @@ S32 LLSphereAABB(const LLVector3& center, const LLVector3& size, const LLVector3 LLSpatialGroup::~LLSpatialGroup() { - if (sNoDelete) + /*if (sNoDelete) { - llerrs << "Illegal deletion of LLSpatialGroup!" << llendl; - } + llwarns << "Illegal deletion of LLSpatialGroup!" << llendl; + }*/ if (isState(DEAD)) { @@ -302,6 +303,129 @@ LLSpatialGroup::~LLSpatialGroup() LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); clearDrawMap(); + clearAtlasList() ; +} + +BOOL LLSpatialGroup::hasAtlas(LLTextureAtlas* atlasp) +{ + S8 type = atlasp->getComponents() - 1 ; + for(std::list::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) + { + if(atlasp == *iter) + { + return TRUE ; + } + } + return FALSE ; +} + +void LLSpatialGroup::addAtlas(LLTextureAtlas* atlasp, S8 recursive_level) +{ + if(!hasAtlas(atlasp)) + { + mAtlasList[atlasp->getComponents() - 1].push_back(atlasp) ; + atlasp->addSpatialGroup(this) ; + } + + --recursive_level; + if(recursive_level)//levels propagating up. + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + parent->addAtlas(atlasp, recursive_level) ; + } + } +} + +void LLSpatialGroup::removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group, S8 recursive_level) +{ + mAtlasList[atlasp->getComponents() - 1].remove(atlasp) ; + if(remove_group) + { + atlasp->removeSpatialGroup(this) ; + } + + --recursive_level; + if(recursive_level)//levels propagating up. + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + parent->removeAtlas(atlasp, recursive_level) ; + } + } +} + +void LLSpatialGroup::clearAtlasList() +{ + std::list::iterator iter ; + for(S8 i = 0 ; i < 4 ; i++) + { + if(mAtlasList[i].size() > 0) + { + for(iter = mAtlasList[i].begin(); iter != mAtlasList[i].end() ; ++iter) + { + ((LLTextureAtlas*)*iter)->removeSpatialGroup(this) ; + } + mAtlasList[i].clear() ; + } + } +} + +LLTextureAtlas* LLSpatialGroup::getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level) +{ + S8 type = ncomponents - 1 ; + if(mAtlasList[type].size() > 0) + { + for(std::list::iterator iter = mAtlasList[type].begin(); iter != mAtlasList[type].end() ; ++iter) + { + if(!((LLTextureAtlas*)*iter)->isFull(to_be_reserved)) + { + return *iter ; + } + } + } + + --recursive_level; + if(recursive_level) + { + LLSpatialGroup* parent = getParent() ; + if(parent) + { + return parent->getAtlas(ncomponents, to_be_reserved, recursive_level) ; + } + } + return NULL ; +} + +void LLSpatialGroup::setCurUpdatingSlot(LLTextureAtlasSlot* slotp) +{ + mCurUpdatingSlotp = slotp; + + //if(!hasAtlas(mCurUpdatingSlotp->getAtlas())) + //{ + // addAtlas(mCurUpdatingSlotp->getAtlas()) ; + //} +} + +LLTextureAtlasSlot* LLSpatialGroup::getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level) +{ + if(gFrameCount && mCurUpdatingTime == gFrameCount && mCurUpdatingTexture == imagep) + { + return mCurUpdatingSlotp ; + } + + //--recursive_level ; + //if(recursive_level) + //{ + // LLSpatialGroup* parent = getParent() ; + // if(parent) + // { + // return parent->getCurUpdatingSlot(imagep, recursive_level) ; + // } + //} + return NULL ; } void LLSpatialGroup::clearDrawMap() @@ -348,7 +472,7 @@ void LLSpatialGroup::validate() LLSpatialPartition* part = drawable->asPartition(); if (!part) { - llerrs << "Drawable reports it is a spatial bridge but not a partition." << llendl; + llwarns << "Drawable reports it is a spatial bridge but not a partition." << llendl; } LLSpatialGroup* group = (LLSpatialGroup*) part->mOctree->getListener(0); group->validate(); @@ -411,7 +535,7 @@ public: if (mInheritedMask && !group->isState(mInheritedMask)) { - llerrs << "Spatial group failed inherited mask test." << llendl; + llwarns << "Spatial group failed inherited mask test." << llendl; } if (group->isState(LLSpatialGroup::DIRTY)) @@ -427,7 +551,7 @@ public: { if (!parent->isState(state)) { - llerrs << "Spatial group failed parent state check." << llendl; + llwarns << "Spatial group failed parent state check." << llendl; } parent = parent->getParent(); } @@ -448,39 +572,39 @@ void validate_draw_info(LLDrawInfo& params) #if LL_OCTREE_PARANOIA_CHECK if (params.mVertexBuffer.isNull()) { - llerrs << "Draw batch has no vertex buffer." << llendl; + llwarns << "Draw batch has no vertex buffer." << llendl; } //bad range if (params.mStart >= params.mEnd) { - llerrs << "Draw batch has invalid range." << llendl; + llwarns << "Draw batch has invalid range." << llendl; } if (params.mEnd >= (U32) params.mVertexBuffer->getNumVerts()) { - llerrs << "Draw batch has buffer overrun error." << llendl; + llwarns << "Draw batch has buffer overrun error." << llendl; } if (params.mOffset + params.mCount > (U32) params.mVertexBuffer->getNumIndices()) { - llerrs << "Draw batch has index buffer ovverrun error." << llendl; + llwarns << "Draw batch has index buffer ovverrun error." << llendl; } //bad indices - U32* indicesp = (U32*) params.mVertexBuffer->getIndicesPointer(); + U16* indicesp = (U16*) params.mVertexBuffer->getIndicesPointer(); // KL 16 indices for SD not 32 if (indicesp) { for (U32 i = params.mOffset; i < params.mOffset+params.mCount; i++) { - if (indicesp[i] < params.mStart) + if (indicesp[i] < (U16)params.mStart) //KL { - llerrs << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; + llwarns << "Draw batch has vertex buffer index out of range error (index too low)." << llendl; } - if (indicesp[i] > params.mEnd) + if (indicesp[i] > (U16)params.mEnd) // KL { - llerrs << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; + llwarns << "Draw batch has vertex buffer index out of range error (index too high)." << llendl; } } } @@ -540,6 +664,7 @@ BOOL LLSpatialGroup::addObject(LLDrawable *drawablep, BOOL add_all, BOOL from_oc drawablep->setSpatialGroup(this); validate_drawable(drawablep); setState(OBJECT_DIRTY | GEOM_DIRTY | DISCARD_QUERY); + gPipeline.markRebuild(this, TRUE); if (drawablep->isSpatialBridge()) { mBridgeList.push_back((LLSpatialBridge*) drawablep); @@ -572,22 +697,23 @@ void LLSpatialGroup::rebuildMesh() void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) { - if (!gPipeline.hasRenderType(mDrawableType)) + /*if (!gPipeline.hasRenderType(mDrawableType)) { return; - } - - if (!LLPipeline::sSkipUpdate && group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; - } + }*/ if (group->isDead() || !group->isState(LLSpatialGroup::GEOM_DIRTY)) { + /*if (!group->isState(LLSpatialGroup::GEOM_DIRTY) && mRenderByGroup) + { + llwarns << "WTF?" << llendl; + }*/ return; } + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); group->clearDrawMap(); @@ -625,6 +751,7 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->clearState(LLSpatialGroup::GEOM_DIRTY); } + void LLSpatialPartition::rebuildMesh(LLSpatialGroup* group) { @@ -663,8 +790,11 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO drawablep = *i; minMax = drawablep->getSpatialExtents(); + update_min_max(newMin, newMax, minMax[0]); + update_min_max(newMin, newMax, minMax[1]); + //bin up the object - for (U32 i = 0; i < 3; i++) + /*for (U32 i = 0; i < 3; i++) { if (minMax[0].mV[i] < newMin.mV[i]) { @@ -674,7 +804,7 @@ BOOL LLSpatialGroup::boundObjects(BOOL empty, LLVector3& minOut, LLVector3& maxO { newMax.mV[i] = minMax[1].mV[i]; } - } + }*/ } mObjectBounds[0] = (newMin + newMax) * 0.5f; @@ -738,6 +868,10 @@ LLSpatialGroup* LLSpatialGroup::getParent() return NULL; } + if(!mOctreeNode) + { + return NULL; + } OctreeNode* parent = mOctreeNode->getOctParent(); if (parent) @@ -763,6 +897,8 @@ BOOL LLSpatialGroup::removeObject(LLDrawable *drawablep, BOOL from_octree) { drawablep->setSpatialGroup(NULL); setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); + if (drawablep->isSpatialBridge()) { for (bridge_list_t::iterator i = mBridgeList.begin(); i != mBridgeList.end(); ++i) @@ -799,6 +935,7 @@ void LLSpatialGroup::shift(const LLVector3 &offset) //if (!mSpatialPartition->mRenderByGroup) { setState(GEOM_DIRTY); + gPipeline.markRebuild(this, TRUE); } if (mOcclusionVerts) @@ -948,7 +1085,11 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : mLastUpdateDistance(-1.f), mLastUpdateTime(gFrameTimeSeconds), mViewAngle(0.f), - mLastUpdateViewAngle(-1.f) + mLastUpdateViewAngle(-1.f), + mAtlasList(4), + mCurUpdatingTime(0), + mCurUpdatingSlotp(NULL), + mCurUpdatingTexture (NULL) { sNodeCount++; LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); @@ -956,6 +1097,7 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : sg_assert(mOctreeNode->getListenerCount() == 0); mOctreeNode->addListener(this); setState(SG_INITIAL_STATE_MASK); + gPipeline.markRebuild(this, TRUE); mBounds[0] = LLVector3(node->getCenter()); mBounds[1] = LLVector3(node->getSize()); @@ -975,7 +1117,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) #if !LL_RELEASE_FOR_DOWNLOAD if (isState(LLSpatialGroup::OBJECT_DIRTY)) { - llerrs << "Spatial group dirty on distance update." << llendl; + llwarns << "Spatial group dirty on distance update." << llendl; } #endif if (!getData().empty() && !LLSpatialPartition::sFreezeState) @@ -1014,6 +1156,7 @@ F32 LLSpatialPartition::calcDistance(LLSpatialGroup* group, LLCamera& camera) //NOTE: If there is a trivial way to detect that alpha sorting here would not change the render order, //not setting this node to dirty would be a very good thing group->setState(LLSpatialGroup::ALPHA_DIRTY); + gPipeline.markRebuild(group, FALSE); } } } @@ -1050,6 +1193,18 @@ F32 LLSpatialPartition::calcPixelArea(LLSpatialGroup* group, LLCamera& camera) return LLPipeline::calcPixelArea(group->mObjectBounds[0], group->mObjectBounds[1], camera); } +F32 LLSpatialGroup::getUpdateUrgency() const +{ + if (!isVisible()) + { + return 0.f; + } + else + { + return (gFrameTimeSeconds - mLastUpdateTime+4.f)/mDistance; + } +} + BOOL LLSpatialGroup::needsUpdate() { return (LLDrawable::getCurrentFrame()%mSpatialPartition->mLODPeriod == mLODHash) ? TRUE : FALSE; @@ -1157,6 +1312,8 @@ void LLSpatialGroup::handleChildRemoval(const OctreeNode* parent, const OctreeNo void LLSpatialGroup::destroyGL() { setState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::IMAGE_DIRTY); + gPipeline.markRebuild(this, TRUE); + mLastUpdateTime = gFrameTimeSeconds; mVertexBuffer = NULL; mBufferMap.clear(); @@ -1339,7 +1496,8 @@ void LLSpatialGroup::doOcclusion(LLCamera* camera) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage) +: mRenderByGroup(render_by_group) { LLMemType mt(LLMemType::MTYPE_SPACE_PARTITION); mOcclusionEnabled = TRUE; @@ -1351,7 +1509,7 @@ LLSpatialPartition::LLSpatialPartition(U32 data_mask, U32 buffer_usage) mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; - mRenderByGroup = TRUE; + //mRenderByGroup = TRUE; mInfiniteFarClip = FALSE; LLGLNamePool::registerPool(&sQueryPool); @@ -1647,13 +1805,76 @@ public: return false; } + virtual void traverse(const LLSpatialGroup::TreeNode* n) + { + LLSpatialGroup* group = (LLSpatialGroup*) n->getListener(0); + + if (earlyFail(group)) + { + return; + } + + if (mRes == 2) + { + //fully in, don't traverse further (won't effect extents + } + else if (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) + { //don't need to do frustum check + LLSpatialGroup::OctreeTraveler::traverse(n); + } + else + { + mRes = frustumCheck(group); + + if (mRes) + { //at least partially in, run on down + LLSpatialGroup::OctreeTraveler::traverse(n); + } + + mRes = 0; + } + } + virtual void processGroup(LLSpatialGroup* group) { - if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) - { //megaprims and water edge patches be damned! + if (group->isState(LLSpatialGroup::DIRTY) || group->getData().empty()) + { + llwarns << "WTF?" << llendl; + } + + if (mRes < 2) + { + + if (mCamera->AABBInFrustum(group->mObjectBounds[0], group->mObjectBounds[1]) == 2) + { + mEmpty = FALSE; + update_min_max(mMin, mMax, group->mObjectExtents[0]); + update_min_max(mMin, mMax, group->mObjectExtents[1]); + } + else + { + if (group->mObjectBounds[1].magVecSquared() < 256.f * 256.f) + { //megaprims and water edge patches be damned! + for (LLSpatialGroup::element_iter i = group->getData().begin(); i != group->getData().end(); ++i) + { + LLDrawable* drawable = i->get(); + const LLVector3* ext = drawable->getSpatialExtents(); + + if (mCamera->AABBInFrustum((ext[1]+ext[0])*0.5f, (ext[1]-ext[0])*0.5f)) + { + mEmpty = FALSE; + update_min_max(mMin, mMax, ext[0]); + update_min_max(mMin, mMax, ext[1]); + } + } + } + } + } + else + { mEmpty = FALSE; - update_min_max(mMin, mMax, group->mObjectExtents[0]); - update_min_max(mMin, mMax, group->mObjectExtents[1]); + update_min_max(mMin, mMax, group->mExtents[0]); + update_min_max(mMin, mMax, group->mExtents[1]); } } @@ -2431,6 +2652,39 @@ void renderBatchSize(LLDrawInfo* params) pushVerts(params, LLVertexBuffer::MAP_VERTEX); } +void renderShadowFrusta(LLDrawInfo* params) +{ + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ADD); + + LLVector3 center = (params->mExtents[1]+params->mExtents[0])*0.5f; + LLVector3 size = (params->mExtents[1]-params->mExtents[0])*0.5f; + + if (gPipeline.mShadowCamera[4].AABBInFrustum(center, size)) + { + glColor3f(1,0,0); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[5].AABBInFrustum(center, size)) + { + glColor3f(0,1,0); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[6].AABBInFrustum(center, size)) + { + glColor3f(0,0,1); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + if (gPipeline.mShadowCamera[7].AABBInFrustum(center, size)) + { + glColor3f(1,0,1); + pushVerts(params, LLVertexBuffer::MAP_VERTEX); + } + + gGL.setSceneBlendType(LLRender::BT_ALPHA); +} + + void renderLights(LLDrawable* drawablep) { if (!drawablep->isLight()) @@ -2566,6 +2820,9 @@ public: //draw tight fit bounding boxes for spatial group if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE)) { + group->rebuildGeom(); + group->rebuildMesh(); + renderOctree(group); stop_glerror(); } @@ -2573,6 +2830,9 @@ public: //render visibility wireframe if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCCLUSION)) { + group->rebuildGeom(); + group->rebuildMesh(); + gGL.flush(); glPushMatrix(); gGLLastMatrix = NULL; @@ -2598,6 +2858,19 @@ public: LLVector3 nodeCenter = group->mBounds[0]; LLVector3 octCenter = LLVector3(group->mOctreeNode->getCenter()); + group->rebuildGeom(); + group->rebuildMesh(); + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BBOXES)) + { + if (!group->getData().empty()) + { + gGL.color3f(0,0,1); + drawBoxOutline(group->mObjectBounds[0], + group->mObjectBounds[1]); + } + } + for (LLSpatialGroup::OctreeNode::const_element_iter i = branch->getData().begin(); i != branch->getData().end(); ++i) { LLDrawable* drawable = *i; @@ -2607,6 +2880,16 @@ public: renderBoundingBox(drawable); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_BUILD_QUEUE)) + { + if (drawable->isState(LLDrawable::IN_REBUILD_Q2)) + { + gGL.color4f(0.6f, 0.6f, 0.1f, 1.f); + const LLVector3* ext = drawable->getSpatialExtents(); + drawBoxOutline((ext[0]+ext[1])*0.5f, (ext[1]-ext[0])*0.5f); + } + } + if (drawable->getVOVolume() && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)) { renderTexturePriority(drawable); @@ -2627,9 +2910,9 @@ public: renderRaycast(drawable); } - LLVOAvatar* avatar = dynamic_cast(drawable->getVObj().get()); + // LLVOAvatar* avatar = dynamic_cast(drawable->getVObj().get()); - if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) + /* if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)) { renderAvatarCollisionVolumes(avatar); } @@ -2637,7 +2920,7 @@ public: if (avatar && gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_AGENT_TARGET)) { renderAgentTarget(avatar); - } + } */ } @@ -2655,6 +2938,10 @@ public: { renderBatchSize(draw_info); } + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + renderShadowFrusta(draw_info); + } } } } @@ -2705,7 +2992,7 @@ void LLSpatialPartition::renderIntersectingBBoxes(LLCamera* camera) pusher.traverse(mOctree); } -void LLSpatialPartition::renderDebug() +void LLSpatialPartition::renderDebug() // KL SD version { if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_OCTREE | LLPipeline::RENDER_DEBUG_OCCLUSION | @@ -2716,8 +3003,8 @@ void LLSpatialPartition::renderDebug() LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY | LLPipeline::RENDER_DEBUG_TEXTURE_ANIM | LLPipeline::RENDER_DEBUG_RAYCAST | - LLPipeline::RENDER_DEBUG_AVATAR_VOLUME | - LLPipeline::RENDER_DEBUG_AGENT_TARGET)) + LLPipeline::RENDER_DEBUG_BUILD_QUEUE | + LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { return; } @@ -2752,6 +3039,12 @@ void LLSpatialPartition::renderDebug() render_debug.traverse(mOctree); } +void LLSpatialGroup::drawObjectBox(LLColor4 col) +{ + gGL.color4fv(col.mV); + drawBox(mObjectBounds[0], mObjectBounds[1]*1.01f+LLVector3(0.001f, 0.001f, 0.001f)); +} + BOOL LLSpatialPartition::isVisible(const LLVector3& v) { @@ -2896,11 +3189,12 @@ LLDrawable* LLSpatialPartition::lineSegmentIntersect(const LLVector3& start, con } LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* texture, LLVertexBuffer* buffer, + LLImageGL* gl_texture, LLViewerImage* texture, LLVertexBuffer* buffer, BOOL fullbright, U8 bump, BOOL particle, F32 part_size) : mVertexBuffer(buffer), - mTexture(texture), + mTexture(gl_texture), + mViewerTexture(texture), mTextureMatrix(NULL), mModelMatrix(NULL), mStart(start), @@ -2920,22 +3214,22 @@ LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, if (mStart >= mVertexBuffer->getRequestedVerts() || mEnd >= mVertexBuffer->getRequestedVerts()) { - llerrs << "Invalid draw info vertex range." << llendl; + llwarns << "Invalid draw info vertex range." << llendl; } if (mOffset >= (U32) mVertexBuffer->getRequestedIndices() || mOffset + mCount > (U32) mVertexBuffer->getRequestedIndices()) { - llerrs << "Invalid draw info index range." << llendl; + llwarns << "Invalid draw info index range." << llendl; } } LLDrawInfo::~LLDrawInfo() { - if (LLSpatialGroup::sNoDelete) + /*if (LLSpatialGroup::sNoDelete) { - llerrs << "LLDrawInfo deleted illegally!" << llendl; - } + llwarns << "LLDrawInfo deleted illegally!" << llendl; + }*/ if (mFace) { @@ -3140,7 +3434,7 @@ void LLCullResult::assertDrawMapsEmpty() { if (mRenderMapSize[i] != 0) { - llerrs << "Stale LLDrawInfo's in LLCullResult!" << llendl; + llwarns << "Stale LLDrawInfo's in LLCullResult!" << llendl; } } } diff --git a/linden/indra/newview/llspatialpartition.h b/linden/indra/newview/llspatialpartition.h index df96152..8af5222 100644 --- a/linden/indra/newview/llspatialpartition.h +++ b/linden/indra/newview/llspatialpartition.h @@ -52,6 +52,8 @@ class LLSpatialPartition; class LLSpatialBridge; class LLSpatialGroup; +class LLTextureAtlas; +class LLTextureAtlasSlot; S32 AABBSphereIntersect(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &rad); S32 AABBSphereIntersectR2(const LLVector3& min, const LLVector3& max, const LLVector3 &origin, const F32 &radius_squared); @@ -66,12 +68,13 @@ protected: public: LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerImage* image, LLVertexBuffer* buffer, + LLImageGL* gl_image, LLViewerImage* image, LLVertexBuffer* buffer, BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); LLPointer mVertexBuffer; - LLPointer mTexture; + LLPointer mTexture; + LLPointer mViewerTexture; LLColor4U mGlowColor; S32 mDebugColor; const LLMatrix4* mTextureMatrix; @@ -159,11 +162,13 @@ public: typedef std::vector > sg_vector_t; typedef std::set > sg_set_t; + typedef std::list > sg_list_t; typedef std::vector > bridge_list_t; typedef std::vector > drawmap_elem_t; typedef std::map draw_map_t; typedef std::vector > buffer_list_t; - typedef std::map, buffer_list_t> buffer_texture_map_t; + typedef std::map, buffer_list_t> buffer_texture_map_t; // KL render-pipeline +// typedef std::map, buffer_list_t> buffer_texture_map_t; // KL standard typedef std::map buffer_map_t; typedef LLOctreeListener BaseType; @@ -183,6 +188,14 @@ public: } }; + struct CompareUpdateUrgency + { + bool operator()(const LLPointer lhs, const LLPointer rhs) + { + return lhs->getUpdateUrgency() > rhs->getUpdateUrgency(); + } + }; + struct CompareDepthGreater { bool operator()(const LLSpatialGroup* const& lhs, const LLSpatialGroup* const& rhs) @@ -209,6 +222,10 @@ public: IMAGE_DIRTY = 0x00004000, OCCLUSION_DIRTY = 0x00008000, MESH_DIRTY = 0x00010000, + NEW_DRAWINFO = 0x00020000, + IN_BUILD_Q1 = 0x00040000, + IN_BUILD_Q2 = 0x00080000, + } eSpatialState; typedef enum @@ -252,6 +269,7 @@ public: void updateDistance(LLCamera& camera); BOOL needsUpdate(); + F32 getUpdateUrgency() const; BOOL changeLOD(); void rebuildGeom(); void rebuildMesh(); @@ -261,6 +279,8 @@ public: element_list& getData() { return mOctreeNode->getData(); } U32 getElementCount() const { return mOctreeNode->getElementCount(); } + void drawObjectBox(LLColor4 col); + //LISTENER FUNCTIONS virtual void handleInsertion(const TreeNode* node, LLDrawable* face); virtual void handleRemoval(const TreeNode* node, LLDrawable* face); @@ -269,6 +289,36 @@ public: virtual void handleChildAddition(const OctreeNode* parent, OctreeNode* child); virtual void handleChildRemoval(const OctreeNode* parent, const OctreeNode* child); +//------------------- +//for atlas use +//------------------- + //atlas + void setCurUpdatingTime(U32 t) {mCurUpdatingTime = t ;} + U32 getCurUpdatingTime() const { return mCurUpdatingTime ;} + + void setCurUpdatingSlot(LLTextureAtlasSlot* slotp) ; + LLTextureAtlasSlot* getCurUpdatingSlot(LLViewerImage* imagep, S8 recursive_level = 3) ; + + void setCurUpdatingTexture(LLViewerImage* tex){ mCurUpdatingTexture = tex ;} + LLViewerImage* getCurUpdatingTexture() const { return mCurUpdatingTexture ;} + + BOOL hasAtlas(LLTextureAtlas* atlasp) ; + LLTextureAtlas* getAtlas(S8 ncomponents, S8 to_be_reserved, S8 recursive_level = 3) ; + void addAtlas(LLTextureAtlas* atlasp, S8 recursive_level = 3) ; + void removeAtlas(LLTextureAtlas* atlasp, BOOL remove_group = TRUE, S8 recursive_level = 3) ; + void clearAtlasList() ; +private: + U32 mCurUpdatingTime ; + //do not make the below two to use LLPointer + //because mCurUpdatingTime invalidates them automatically. + LLTextureAtlasSlot* mCurUpdatingSlotp ; + LLViewerImage* mCurUpdatingTexture ; + + std::vector< std::list > mAtlasList ; +//------------------- +//end for atlas use +//------------------- + protected: virtual ~LLSpatialGroup(); @@ -327,7 +377,7 @@ class LLSpatialPartition: public LLGeometryManager public: static BOOL sFreezeState; //if true, no spatialgroup state updates will be made - LLSpatialPartition(U32 data_mask, U32 mBufferUsage = GL_STATIC_DRAW_ARB); + LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -373,7 +423,7 @@ public: BOOL mOcclusionEnabled; // if TRUE, occlusion culling is performed BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane U32 mBufferUsage; - BOOL mRenderByGroup; + const BOOL mRenderByGroup; U32 mLODSeed; U32 mLODPeriod; //number of frames between LOD updates for a given spatial group (staggered by mLODSeed) U32 mVertexDataMask; @@ -392,7 +442,7 @@ protected: public: typedef std::vector > bridge_vector_t; - LLSpatialBridge(LLDrawable* root, U32 data_mask); + LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask); virtual BOOL isSpatialBridge() const { return TRUE; } diff --git a/linden/indra/newview/llstartup.cpp b/linden/indra/newview/llstartup.cpp index 87d48c8..237a967 100644 --- a/linden/indra/newview/llstartup.cpp +++ b/linden/indra/newview/llstartup.cpp @@ -3723,7 +3723,7 @@ void init_start_screen(S32 location_id) } raw->expandToPowerOfTwo(); - gStartImageGL->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + gStartImageGL->createGLTexture(0, raw); } diff --git a/linden/indra/newview/llsurface.cpp b/linden/indra/newview/llsurface.cpp index a27f0e2..2e20ace 100644 --- a/linden/indra/newview/llsurface.cpp +++ b/linden/indra/newview/llsurface.cpp @@ -149,7 +149,7 @@ LLSurface::~LLSurface() } else { - llerrs << "Terrain pool not empty!" << llendl; + llwarns << "Terrain pool not empty!" << llendl; } } @@ -238,6 +238,7 @@ void LLSurface::createSTexture() if (!mSTexturep) { // Fill with dummy gray data. + // GL NOT ACTIVE HERE LLPointer raw = new LLImageRaw(sTextureSize, sTextureSize, 3); U8 *default_texture = raw->getData(); for (S32 i = 0; i < sTextureSize; i++) @@ -255,6 +256,7 @@ void LLSurface::createSTexture() gGL.getTexUnit(0)->bind(mSTexturep.get()); mSTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mSTexturep); + } } @@ -275,9 +277,10 @@ void LLSurface::createWaterTexture() *(default_texture + (i*sTextureSize/2 + j)*4 + 3) = MAX_WATER_COLOR.mV[3]; } } - mWaterTexturep = new LLViewerImage(raw, FALSE); + + mWaterTexturep = new LLViewerImage(sTextureSize/2, sTextureSize/2, 4, FALSE); mWaterTexturep->dontDiscard(); - gGL.getTexUnit(0)->bind(mWaterTexturep.get()); + gGL.getTexUnit(0)->bind(mWaterTexturep); mWaterTexturep->setAddressMode(LLTexUnit::TAM_CLAMP); gImageList.addImage(mWaterTexturep); } @@ -629,6 +632,8 @@ void LLSurface::updatePatchVisibilities(LLAgent &agent) BOOL LLSurface::idleUpdate(F32 max_update_time) { +//SG2: LLMemType mt_ius(LLMemType::MTYPE_IDLE_UPDATE_SURFACE); + if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TERRAIN)) { return FALSE; @@ -1133,12 +1138,12 @@ LLSurfacePatch *LLSurface::getPatch(const S32 x, const S32 y) const { if ((x < 0) || (x >= mPatchesPerEdge)) { - llerrs << "Asking for patch out of bounds" << llendl; + llwarns << "Asking for patch out of bounds" << llendl; return NULL; } if ((y < 0) || (y >= mPatchesPerEdge)) { - llerrs << "Asking for patch out of bounds" << llendl; + llwarns << "Asking for patch out of bounds" << llendl; return NULL; } @@ -1277,6 +1282,11 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y, } } + if (!mWaterTexturep->getHasGLTexture()) + { + mWaterTexturep->createGLTexture(0, raw); + } + mWaterTexturep->setSubImage(raw, x_begin, y_begin, x_end - x_begin, y_end - y_begin); return TRUE; } diff --git a/linden/indra/newview/llsurfacepatch.cpp b/linden/indra/newview/llsurfacepatch.cpp index 5fac5fd..04b732a 100644 --- a/linden/indra/newview/llsurfacepatch.cpp +++ b/linden/indra/newview/llsurfacepatch.cpp @@ -712,17 +712,7 @@ BOOL LLSurfacePatch::updateTexture() if (mVObjp) { mVObjp->dirtyGeom(); - } - updateCompositionStats(); - F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; - if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], - tex_patch_size, tex_patch_size)) - { - mSTexUpdate = FALSE; - - // Also generate the water texture - mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], - tex_patch_size, tex_patch_size); + gPipeline.markGLRebuild(mVObjp); return TRUE; } } @@ -735,6 +725,28 @@ BOOL LLSurfacePatch::updateTexture() } } +void LLSurfacePatch::updateGL() // KL SD +{ + F32 meters_per_grid = getSurface()->getMetersPerGrid(); + F32 grids_per_patch_edge = (F32)getSurface()->getGridsPerPatchEdge(); + + LLViewerRegion *regionp = getSurface()->getRegion(); + LLVector3d origin_region = getOriginGlobal() - getSurface()->getOriginGlobal(); + + LLVLComposition* comp = regionp->getComposition(); + + updateCompositionStats(); + F32 tex_patch_size = meters_per_grid*grids_per_patch_edge; + if (comp->generateTexture((F32)origin_region[VX], (F32)origin_region[VY], + tex_patch_size, tex_patch_size)) + { + mSTexUpdate = FALSE; + + // Also generate the water texture + mSurfacep->generateWaterTexture((F32)origin_region.mdV[VX], (F32)origin_region.mdV[VY], + tex_patch_size, tex_patch_size); + } +} // KL void LLSurfacePatch::dirtyZ() { diff --git a/linden/indra/newview/llsurfacepatch.h b/linden/indra/newview/llsurfacepatch.h index 7e84f7f..1f9658d 100644 --- a/linden/indra/newview/llsurfacepatch.h +++ b/linden/indra/newview/llsurfacepatch.h @@ -90,6 +90,7 @@ public: void updateCameraDistanceRegion( const LLVector3 &pos_region); void updateVisibility(); + void updateGL(); void dirtyZ(); // Dirty the z values of this patch void setHasReceivedData(); diff --git a/linden/indra/newview/lltexlayer.cpp b/linden/indra/newview/lltexlayer.cpp index 5175cbb..fb5be84 100644 --- a/linden/indra/newview/lltexlayer.cpp +++ b/linden/indra/newview/lltexlayer.cpp @@ -813,14 +813,19 @@ void LLTexLayerSet::requestUpdate() if( mUpdatesEnabled ) { createComposite(); - mComposite->requestUpdate(); + if (mComposite) + { + mComposite->requestUpdate(); + } } } void LLTexLayerSet::requestUpload() { - createComposite(); - mComposite->requestUpload(); + if (mComposite) + { + mComposite->requestUpload(); + } } void LLTexLayerSet::cancelUpload() @@ -835,6 +840,15 @@ void LLTexLayerSet::createComposite() { if( !mComposite ) { + gPipeline.markGLRebuild(this); + } + //updateGL(); // KL +} + +void LLTexLayerSet::updateGL() +{ + if (!mComposite) + { S32 width = mInfo->mWidth; S32 height = mInfo->mHeight; // Composite other avatars at reduced resolution @@ -865,7 +879,7 @@ void LLTexLayerSet::setUpdatesEnabled( BOOL b ) void LLTexLayerSet::updateComposite() { createComposite(); - mComposite->updateImmediate(); + //mComposite->updateImmediate(); //KL exception here this needs fixing for S19 } LLTexLayerSetBuffer* LLTexLayerSet::getComposite() @@ -2104,7 +2118,7 @@ BOOL LLTexLayerParamAlpha::render( S32 x, S32 y, S32 width, S32 height ) // Create the GL texture, and then hang onto it for future use. if( mNeedsCreateTexture ) { - mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0, TRUE, LLViewerImageBoostLevel::TEXLAYER_CACHE); + mCachedProcessedImageGL->createGLTexture(0, mStaticImageRaw, 0); mNeedsCreateTexture = FALSE; gGL.getTexUnit(0)->bind(mCachedProcessedImageGL); mCachedProcessedImageGL->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -2560,7 +2574,7 @@ LLImageGL* LLTexStaticImageList::getImageGL(const std::string& file_name, BOOL i image_gl->setExplicitFormat( GL_ALPHA8, GL_ALPHA ); } - image_gl->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + image_gl->createGLTexture(0, image_raw, 0); gGL.getTexUnit(0)->bind(image_gl); image_gl->setAddressMode(LLTexUnit::TAM_CLAMP); diff --git a/linden/indra/newview/lltexlayer.h b/linden/indra/newview/lltexlayer.h index 020ba86..b841fa3 100644 --- a/linden/indra/newview/lltexlayer.h +++ b/linden/indra/newview/lltexlayer.h @@ -249,7 +249,7 @@ private: // LLTexLayerSet // An ordered set of texture layers that get composited into a single texture. //----------------------------------------------------------------------------- -class LLTexLayerSet +class LLTexLayerSet : public LLGLUpdate { friend class LLTexLayerSetBuffer; public: @@ -284,7 +284,7 @@ public: LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; } void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; } BOOL isVisible() const { return mIsVisible; } - + /*virtual*/ void updateGL(); public: static BOOL sHasCaches; diff --git a/linden/indra/newview/lltextureatlasmanager.cpp b/linden/indra/newview/lltextureatlasmanager.cpp new file mode 100644 index 0000000..df6a39d --- /dev/null +++ b/linden/indra/newview/lltextureatlasmanager.cpp @@ -0,0 +1,274 @@ +/** + * @file lltextureatlasmanager.cpp + * @brief LLTextureAtlasManager class implementation. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ +#include "llviewerprecompiledheaders.h" +#include "linden_common.h" +#include "llerror.h" +#include "llmath.h" +#include "lltextureatlas.h" +#include "lltextureatlasmanager.h" +#include "llspatialpartition.h" + +const S8 MAX_NUM_EMPTY_ATLAS = 2 ; +const F32 MIN_ATLAS_FULLNESS = 0.6f ; + +//********************************************************************************************* +//implementation of class LLTextureAtlasInfo +//********************************************************************************************* +LLTextureAtlasSlot::LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) : + mAtlasp(atlasp), + mGroupp(groupp), + mCol(col), + mRow(row), + mReservedSlotWidth(slot_width), + mValid(FALSE), + mUpdatedTime(0), + mTexCoordOffset(xoffset, yoffset), + mTexCoordScale(1.f, 1.f) +{ + llassert_always(mAtlasp || mGroupp || mReservedSlotWidth) ; +} + +LLTextureAtlasSlot::~LLTextureAtlasSlot() +{ + if(mAtlasp) + { + mAtlasp->releaseSlot(mCol, mRow, mReservedSlotWidth) ; + if(mAtlasp->isEmpty()) + { + LLTextureAtlasManager::getInstance()->releaseAtlas(mAtlasp) ; + } + mAtlasp = NULL ; + } +} + +//void LLTextureAtlasSlot::setAtlas(LLTextureAtlas* atlasp) +//{ +// mAtlasp = atlasp ; +//} +//void LLTextureAtlasSlot::setSlotPos(S16 col, S16 row) +//{ +// mCol = col ; +// mRow = row ; +//} +//void LLTextureAtlasSlot::setSlotWidth(S8 width) +//{ +// //slot is a square with each edge length a power-of-two number +// mReservedSlotWidth = width ; +//} +//void LLTextureAtlasSlot::setTexCoordOffset(F32 xoffset, F32 yoffset) +//{ +// mTexCoordOffset.mV[0] = xoffset ; +// mTexCoordOffset.mV[1] = yoffset ; +//} + +void LLTextureAtlasSlot::setSpatialGroup(LLSpatialGroup* groupp) +{ + mGroupp = groupp ; +} +void LLTextureAtlasSlot::setTexCoordScale(F32 xscale, F32 yscale) +{ + mTexCoordScale.mV[0] = xscale ; + mTexCoordScale.mV[1] = yscale ; +} +//********************************************************************************************* +//END of implementation of class LLTextureAtlasInfo +//********************************************************************************************* + +//********************************************************************************************* +//implementation of class LLTextureAtlasManager +//********************************************************************************************* +LLTextureAtlasManager::LLTextureAtlasManager() : + mAtlasMap(4), + mEmptyAtlasMap(4) +{ +} + +LLTextureAtlasManager::~LLTextureAtlasManager() +{ + for(S32 i = 0 ; i < 4 ; i++) + { + for(ll_texture_atlas_list_t::iterator j = mAtlasMap[i].begin() ; j != mAtlasMap[i].end() ; ++j) + { + *j = NULL ; + } + for(ll_texture_atlas_list_t::iterator j = mEmptyAtlasMap[i].begin() ; j != mEmptyAtlasMap[i].end() ; ++j) + { + *j = NULL ; + } + + mAtlasMap[i].clear() ; + mEmptyAtlasMap[i].clear() ; + } + mAtlasMap.clear() ; + mEmptyAtlasMap.clear() ; +} + +//return TRUE if qualified +BOOL LLTextureAtlasManager::canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) +{ + if(ncomponents < 1 || ncomponents > 4) + { + return FALSE ; + } + //only support GL_TEXTURE_2D + if(GL_TEXTURE_2D != target) + { + return FALSE ; + } + //real image size overflows + if(w < 8 || w > LLTextureAtlas::sMaxSubTextureSize || h < 8 || h > LLTextureAtlas::sMaxSubTextureSize) + { + return FALSE ; + } + + //if non-power-of-two number + if((w & (w - 1)) || (h & (h - 1))) + { + return FALSE ; + } + + return TRUE ; +} + +void LLTextureAtlasManager::releaseAtlas(LLTextureAtlas* atlasp) +{ + LLSpatialGroup* groupp = atlasp->getLastSpatialGroup() ; + while(groupp) + { + groupp->removeAtlas(atlasp, FALSE) ; + atlasp->removeLastSpatialGroup() ; + + groupp = atlasp->getLastSpatialGroup() ; + } + + S8 type = atlasp->getComponents() - 1 ; + //insert to the empty list + if(mEmptyAtlasMap[type].size() < MAX_NUM_EMPTY_ATLAS) + { + mEmptyAtlasMap[type].push_back(atlasp) ; + } + + //delete the atlasp + mAtlasMap[type].remove(atlasp) ; +} + +// +//this function reserves an appropriate slot from atlas pool for an image. +//return non-NULL if succeeds. +//Note: +//1, this function does not check if the image this slot assigned for qualifies for atlas or not, +// call LLTextureAtlasManager::canAddToAtlas(...) to do the check before calling this function. +//2, this function also dose not check if the image is already in atlas. It always assigns a new slot anyway. +//3, this function tries to group sub-textures from same spatial group into ONE atlas to improve render batching. +// +LLPointer LLTextureAtlasManager::reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, + LLSpatialGroup* groupp, LLViewerImage* imagep) +{ + if(!groupp) + { + //do not insert to atlas if does not have a group. + return NULL ; + } + + //bits_len must <= 8 and is a power of two number, i.e.: must be one of these numbers: 1, 2, 4, 8. + if(sub_texture_size > LLTextureAtlas::sMaxSubTextureSize) + { + sub_texture_size = LLTextureAtlas::sMaxSubTextureSize ; + } + S8 bits_len = sub_texture_size / LLTextureAtlas::sSlotSize ; + if(bits_len < 1) + { + bits_len = 1 ; + } + + S16 col = -1, row = -1; + S8 total_bits = bits_len * bits_len ; + + //insert to the atlas reserved by the same spatial group + LLPointer atlasp = groupp->getAtlas(ncomponents, total_bits) ; + if(atlasp.notNull()) + { + if(!atlasp->getNextAvailableSlot(bits_len, col, row)) + { + //failed + atlasp = NULL ; + } + } + + //search an atlas to fit for 'size' + if(!atlasp) + { + S8 atlas_index = ncomponents - 1 ; + ll_texture_atlas_list_t::iterator iter = mAtlasMap[atlas_index].begin() ; + for(; iter != mAtlasMap[atlas_index].end(); ++iter) + { + LLTextureAtlas* cur = (LLTextureAtlas*)*iter ; + if(cur->getFullness() < MIN_ATLAS_FULLNESS)//this atlas is empty enough for this group to insert more sub-textures later if necessary. + { + if(cur->getNextAvailableSlot(bits_len, col, row)) + { + atlasp = cur ; + groupp->addAtlas(atlasp) ; + break ; + } + } + } + } + + //create a new atlas if necessary + if(!atlasp) + { + if(mEmptyAtlasMap[ncomponents - 1].size() > 0) + { + //there is an empty one + atlasp = mEmptyAtlasMap[ncomponents - 1].back() ; + mEmptyAtlasMap[ncomponents - 1].pop_back() ; + } + else + { + atlasp = new LLTextureAtlas(ncomponents, 16) ; + } + mAtlasMap[ncomponents - 1].push_back(atlasp) ; + atlasp->getNextAvailableSlot(bits_len, col, row) ; + groupp->addAtlas(atlasp) ; + } + + F32 xoffset, yoffset ; + atlasp->getTexCoordOffset(col, row, xoffset, yoffset) ; + LLPointer slot_infop = new LLTextureAtlasSlot(atlasp, groupp, col, row, xoffset, yoffset, bits_len) ; + + return slot_infop ; +} + +//********************************************************************************************* +//END of implementation of class LLTextureAtlasManager +//********************************************************************************************* diff --git a/linden/indra/newview/lltextureatlasmanager.h b/linden/indra/newview/lltextureatlasmanager.h new file mode 100644 index 0000000..70689bf --- /dev/null +++ b/linden/indra/newview/lltextureatlasmanager.h @@ -0,0 +1,112 @@ +/** + * @file lltextureatlasmanager.h + * @brief LLTextureAtlasManager base class. + * + * $LicenseInfo:firstyear=2002&license=viewergpl$ + * + * Copyright (c) 2002-2009, Linden Research, Inc. + * + * 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 + * + * 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 + * + * 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. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + + +#ifndef LL_TEXTUREATLASMANAGER_H +#define LL_TEXTUREATLASMANAGER_H + +#include "llmemory.h" + +class LLSpatialGroup ; +class LLViewerImage ; + +//just use it as a structure. +class LLTextureAtlasSlot : public LLRefCount +{ +public: + LLTextureAtlasSlot(LLTextureAtlas* atlasp, LLSpatialGroup* groupp, S16 col, S16 row, F32 xoffset, F32 yoffset, S8 slot_width) ; + +protected: + virtual ~LLTextureAtlasSlot(); + +public: + + // + //do not allow to change those values + // + //void setAtlas(LLTextureAtlas* atlasp) ; + //void setSlotPos(S16 col, S16 row) ; + //void setSlotWidth(S8 width) ; + //void setTexCoordOffset(F32 xoffser, F32 yoffset) ; + // + + void setSpatialGroup(LLSpatialGroup* groupp) ; + void setTexCoordScale(F32 xscale, F32 yscale) ; + void setValid() {mValid = TRUE ;} + + LLTextureAtlas* getAtlas()const {return mAtlasp;} + LLSpatialGroup* getSpatialGroup() const {return mGroupp ;} + S16 getSlotCol()const {return mCol;} + S16 getSlotRow()const {return mRow;} + S8 getSlotWidth()const{return mReservedSlotWidth;} + BOOL isValid()const { return mValid;} + const LLVector2* getTexCoordOffset()const {return &mTexCoordOffset;} + const LLVector2* getTexCoordScale() const {return &mTexCoordScale;} + + void setUpdatedTime(U32 t) {mUpdatedTime = t;} + U32 getUpdatedTime()const {return mUpdatedTime;} + +private: + LLTextureAtlas* mAtlasp; + S16 mCol ;//col of the slot + S16 mRow ;//row of the slot + S8 mReservedSlotWidth ; //slot is a square with each edge length a power-of-two number + LLSpatialGroup* mGroupp ; + BOOL mValid ; + + LLVector2 mTexCoordOffset ; + LLVector2 mTexCoordScale ; + + U32 mUpdatedTime ; +} ; + +class LLTextureAtlasManager : public LLSingleton +{ +private: + typedef std::list > ll_texture_atlas_list_t ; + +public: + LLTextureAtlasManager(); + ~LLTextureAtlasManager(); + + LLPointer reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, + LLSpatialGroup* groupp, LLViewerImage* imagep) ; + void releaseAtlas(LLTextureAtlas* atlasp); + + BOOL canAddToAtlas(S32 w, S32 h, S8 ncomponents, LLGLenum target) ; + +private: + std::vector mAtlasMap ; + std::vector mEmptyAtlasMap ; //delay some empty atlases deletion to avoid possible creation of new atlas immediately. +}; + +#endif diff --git a/linden/indra/newview/lltextureview.cpp b/linden/indra/newview/lltextureview.cpp index 04cebf5..903a6e5 100644 --- a/linden/indra/newview/lltextureview.cpp +++ b/linden/indra/newview/lltextureview.cpp @@ -57,14 +57,16 @@ extern F32 texmem_lower_bound_scale; LLTextureView *gTextureView = NULL; +LLTextureSizeView *gTextureSizeView = NULL; +LLTextureSizeView *gTextureCategoryView = NULL; //static std::set LLTextureView::sDebugImages; //////////////////////////////////////////////////////////////////////////// -static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download] pk/max"); -static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download] pk/max"); +static std::string title_string1a("Tex UUID Area DDis(Req) DecodePri(Fetch) [download]"); +static std::string title_string1b("Tex UUID Area DDis(Req) Fetch(DecodePri) [download]"); static std::string title_string2("State"); static std::string title_string3("Pkt Bnd"); static std::string title_string4(" W x H (Dis) Mem"); @@ -201,13 +203,14 @@ void LLTextureBar::draw() } else { - tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x)", + tex_str = llformat("%s %7.0f %d(%d) %8.0f(0x%08x) %1.2f", uuid_str.c_str(), mImagep->mMaxVirtualSize, mImagep->mDesiredDiscardLevel, mImagep->mRequestedDiscardLevel, mImagep->getDecodePriority(), - mImagep->mFetchPriority); + mImagep->mFetchPriority, + mImagep->mDownloadProgress); } LLFontGL::getFontMonospace()->renderUTF8(tex_str, 0, title_x1, getRect().getHeight(), @@ -253,7 +256,7 @@ void LLTextureBar::draw() // Draw the progress bar. S32 bar_width = 100; - S32 bar_left = 260; + S32 bar_left = 330; left = bar_left; right = left + bar_width; @@ -262,7 +265,7 @@ void LLTextureBar::draw() F32 data_progress = mImagep->mDownloadProgress; - if (data_progress > 0.0f) + if (data_progress > 0.0f && data_progress <= 1.0f) { // Downloaded bytes right = left + llfloor(data_progress * (F32)bar_width); @@ -272,6 +275,16 @@ void LLTextureBar::draw() gl_rect_2d(left, top, right, bottom); } } + else if (data_progress > 1.0f) + { + // Small cached textures generate this oddity. SNOW-168 + right = left + bar_width; + if (right > left) + { + gGL.color4f(0.f, 0.33f, 0.f, 0.75f); + gl_rect_2d(left, top, right, bottom); + } + } S32 pip_width = 6; S32 pip_space = 14; @@ -386,9 +399,9 @@ private: void LLGLTexMemBar::draw() { - S32 bound_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sBoundTextureMemoryInBytes); + S32 bound_mem = (LLViewerImage::sBoundTextureMemoryInBytes >> 20); S32 max_bound_mem = LLViewerImage::sMaxBoundTextureMemInMegaBytes; - S32 total_mem = BYTES_TO_MEGA_BYTES(LLViewerImage::sTotalTextureMemoryInBytes); + S32 total_mem = (LLViewerImage::sTotalTextureMemoryInBytes >> 20); S32 max_total_mem = LLViewerImage::sMaxTotalTextureMemInMegaBytes; F32 discard_bias = LLViewerImage::sDesiredDiscardBias; S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -478,28 +491,25 @@ void LLGLTexMemBar::draw() #endif //---------------------------------------------------------------------------- - text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d", + text = llformat("Textures: %d Fetch: %d(%d) Pkts:%d(%d) Cache R/W: %d/%d LFS:%d IW:%d RAW:%d HTP:%d BW: %.0f/%.0f", gImageList.getNumImages(), - LLAppViewer::getTextureFetch()->getNumRequests(), LLAppViewer::getTextureFetch()->getNumDeletes(), - LLAppViewer::getTextureFetch()->mPacketCount, LLAppViewer::getTextureFetch()->mBadPacketCount, - LLAppViewer::getTextureCache()->getNumReads(), LLAppViewer::getTextureCache()->getNumWrites(), + LLAppViewer::getTextureFetch()->getNumRequests(), + LLAppViewer::getTextureFetch()->getNumDeletes(), + LLAppViewer::getTextureFetch()->mPacketCount, + LLAppViewer::getTextureFetch()->mBadPacketCount, + LLAppViewer::getTextureCache()->getNumReads(), + LLAppViewer::getTextureCache()->getNumWrites(), LLLFSThread::sLocal->getPending(), LLAppViewer::getImageDecodeThread()->getPending(), LLImageRaw::sRawImageCount, - LLAppViewer::getTextureFetch()->getNumHTTPRequests()); + LLAppViewer::getTextureFetch()->getNumHTTPRequests(), + LLAppViewer::getTextureFetch()->getTextureBandwidth(), + gSavedSettings.getF32("ThrottleBandwidthKBPS")); LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, line_height*2, text_color, LLFontGL::LEFT, LLFontGL::TOP); - - left = 550; - F32 bandwidth = LLAppViewer::getTextureFetch()->getTextureBandwidth(); - F32 max_bandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS"); - color = bandwidth > max_bandwidth ? LLColor4::red : bandwidth > max_bandwidth*.75f ? LLColor4::yellow : text_color; - color[VALPHA] = text_color[VALPHA]; - text = llformat("BW:%.0f/%.0f",bandwidth, max_bandwidth); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left, line_height*2, - color, LLFontGL::LEFT, LLFontGL::TOP); + left = 600; S32 dx1 = 0; if (LLAppViewer::getTextureFetch()->mDebugPause) @@ -566,7 +576,7 @@ public: void setTop(S32 loaded, S32 bound, F32 scale) {mTopLoaded = loaded ; mTopBound = bound; mScale = scale ;} void draw(); - BOOL handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) ; + BOOL handleHover(S32 x, S32 y, MASK mask) ; private: S32 mIndex ; @@ -579,16 +589,19 @@ private: F32 mScale ; }; -BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask, BOOL set_pick_size) +BOOL LLGLTexSizeBar::handleHover(S32 x, S32 y, MASK mask) { +#if !LL_RELEASE_FOR_DOWNLOAD if(y > mBottom && (y < mBottom + (S32)(mTopLoaded * mScale) || y < mBottom + (S32)(mTopBound * mScale))) { - LLImageGL::setCurTexSizebar(mIndex, set_pick_size); + LLImageGL::setCurTexSizebar(mIndex); } +#endif return TRUE ; } void LLGLTexSizeBar::draw() { +#if !LL_RELEASE_FOR_DOWNLOAD LLGLSUIDefault gls_ui; if(LLImageGL::sCurTexSizeBar == mIndex) @@ -609,6 +622,7 @@ void LLGLTexSizeBar::draw() F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ; gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ; +#endif } //////////////////////////////////////////////////////////////////////////// @@ -913,31 +927,7 @@ LLTextureSizeView::~LLTextureSizeView() } void LLTextureSizeView::draw() { - if(mType == TEXTURE_MEM_OVER_SIZE) - { - drawTextureSizeGraph(); - } - else - { - drawTextureCategoryGraph() ; - } - - LLView::draw(); -} - -BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) -{ - if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) - { - mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask, (mType == TEXTURE_MEM_OVER_SIZE)) ; - } - - return TRUE ; -} - -//draw real-time texture mem bar over size -void LLTextureSizeView::drawTextureSizeGraph() -{ +#if !LL_RELEASE_FOR_DOWNLOAD if(mTextureSizeBar.size() == 0) { S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); @@ -958,16 +948,29 @@ void LLTextureSizeView::drawTextureSizeGraph() mTextureSizeBar[i]->draw() ; } LLImageGL::resetCurTexSizebar(); + + LLView::draw(); +#endif +} + +BOOL LLTextureSizeView::handleHover(S32 x, S32 y, MASK mask) +{ + if(x > mTextureSizeBarRect.mLeft && x < mTextureSizeBarRect.mRight) + { + mTextureSizeBar[(x - mTextureSizeBarRect.mLeft) / mTextureSizeBarWidth]->handleHover(x, y, mask) ; + } + + return TRUE ; } //draw background of texture size bar graph F32 LLTextureSizeView::drawTextureSizeDistributionGraph() { - //scale F32 scale = 1.0f ; - +#if !LL_RELEASE_FOR_DOWNLOAD LLGLSUIDefault gls_ui; + //scale { S32 count = 0 ; for(U32 i = 0 ; i < LLImageGL::sTextureLoadedCounter.size() ; i++) @@ -1057,136 +1060,7 @@ F32 LLTextureSizeView::drawTextureSizeDistributionGraph() text = llformat("Texture Size Distribution") ; LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, text_color, LLFontGL::LEFT, LLFontGL::TOP); - return scale ; -} - -//draw real-time texture mem bar over category -void LLTextureSizeView::drawTextureCategoryGraph() -{ - if(mTextureSizeBar.size() == 0) - { - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - mTextureSizeBar.resize(LLImageGL::sTextureMemByCategory.size()) ; - mTextureSizeBarRect.set(700, line_height * 2 + 400, 700 + mTextureSizeBar.size() * mTextureSizeBarWidth, line_height * 2) ; - - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i] = new LLGLTexSizeBar(i, mTextureSizeBarRect.mLeft + i * mTextureSizeBarWidth , - line_height * 2, mTextureSizeBarRect.mLeft + (i + 1) * mTextureSizeBarWidth, line_height) ; - } - } - - F32 size_bar_scale = drawTextureCategoryDistributionGraph() ; - for(U32 i = 0 ; i < mTextureSizeBar.size() ; i++) - { - mTextureSizeBar[i]->setTop(LLImageGL::sTextureMemByCategory[i] >> 20, LLImageGL::sTextureMemByCategoryBound[i] >> 20, size_bar_scale) ; - mTextureSizeBar[i]->draw() ; - } - LLImageGL::resetCurTexSizebar(); -} - -//draw background for TEXTURE_MEM_OVER_CATEGORY -F32 LLTextureSizeView::drawTextureCategoryDistributionGraph() -{ - //scale - F32 scale = 4.0f ; - - LLGLSUIDefault gls_ui; - - { - S32 count = 0 ; - for(U32 i = 0 ; i < LLImageGL::sTextureMemByCategory.size() ; i++) - { - S32 tmp = LLImageGL::sTextureMemByCategory[i] >> 20 ; - if(tmp > count) - { - count = tmp ; - } - } - if(count > mTextureSizeBarRect.getHeight() * 0.25f) - { - scale = (F32)mTextureSizeBarRect.getHeight() * 0.25f / count ; - } - } - - S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f); - S32 left = mTextureSizeBarRect.mLeft ; - S32 bottom = mTextureSizeBarRect.mBottom ; - S32 right = mTextureSizeBarRect.mRight ; - S32 top = mTextureSizeBarRect.mTop ; - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - //background rect - gl_rect_2d(left - 25, top + 30, right + 100, bottom - 25, LLColor4(0.0f, 0.0f, 0.0f, 0.25f)) ; - - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.75f); - gl_line_2d(left, bottom, right, bottom) ; //x axis - gl_line_2d(left, bottom, left, top) ; //y axis - - //ruler - //-------------------------------------------------- - gGL.color4f(1.0f, 0.5f, 0.5f, 0.5f); - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - gl_line_2d(left, i, right, i) ; - } - - //texts - //-------------------------------------------------- - F32 text_color[] = {1.f, 1.f, 1.f, 0.75f}; - std::string text; - - //------- - //x axis: size label - static char category[LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY][4] = - {"Non", "Bak", "Av", "Cld", "Scp", "Hi", "Trn", "Slt", "Hud", "Bsf", "UI", "Pvw", "Map", "Mvs", "Slf", "Tbp", "Scr", "Fnt", "Bmp", "Dyn", "Tlc", "Mdi", "ALT", "Oth" } ; - - text = llformat("%s", category[0]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - for(U32 i = 1 ; i < mTextureSizeBar.size() ; i++) - { - text = llformat("%s", category[i]) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + i * mTextureSizeBarWidth + 12, bottom - line_height / 2, - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - //------- - - //y axis: number label - for(S32 i = bottom + 50 ; i <= top ; i += 50) - { - text = llformat("%d", (S32)((i - bottom) / scale)) ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - LLFontGL::getFontMonospace()->renderUTF8(text, 0, right + 5, i + line_height / 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - } - - text = llformat("MB") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left - 20, top + line_height * 2 , - text_color, LLFontGL::LEFT, LLFontGL::TOP); - //-------------------------------------------------- - F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 70, top + line_height * 2, left + 90, top + line_height, loaded_color) ; - text = llformat("Loaded") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 100, top + line_height * 2, - loaded_color, - LLFontGL::LEFT, LLFontGL::TOP); - - F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f}; - gl_rect_2d(left + 170, top + line_height * 2, left + 190, top + line_height, bound_color) ; - text = llformat("Bound") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 200, top + line_height * 2, - bound_color, LLFontGL::LEFT, LLFontGL::TOP); - - //-------------------------------------------------- - - //title - text = llformat("Texture Category Distribution") ; - LLFontGL::getFontMonospace()->renderUTF8(text, 0, left + 250, top + line_height * 3, - text_color, LLFontGL::LEFT, LLFontGL::TOP); +#endif return scale ; } diff --git a/linden/indra/newview/lltoolpie.h b/linden/indra/newview/lltoolpie.h index 001886f..54bf409 100644 --- a/linden/indra/newview/lltoolpie.h +++ b/linden/indra/newview/lltoolpie.h @@ -86,7 +86,6 @@ private: LLPickInfo mPick; U8 mClickAction; LLSafeHandle mLeftClickSelection; -protected: LLPointer mClickActionObject; }; diff --git a/linden/indra/newview/llviewercamera.cpp b/linden/indra/newview/llviewercamera.cpp index dade65f..6cef2af 100644 --- a/linden/indra/newview/llviewercamera.cpp +++ b/linden/indra/newview/llviewercamera.cpp @@ -769,8 +769,8 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts) BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0; - if (( !in_frustum && all_verts) || - (in_frustum && !all_verts)) + if ( !in_frustum && all_verts || + in_frustum && !all_verts) { return !all_verts; } diff --git a/linden/indra/newview/llviewercontrol.cpp b/linden/indra/newview/llviewercontrol.cpp index 1531e6c..4c9c098 100644 --- a/linden/indra/newview/llviewercontrol.cpp +++ b/linden/indra/newview/llviewercontrol.cpp @@ -90,7 +90,7 @@ std::string gCurrentVersion; extern BOOL gResizeScreenTexture; extern BOOL gDebugGL; -extern BOOL gAuditTexture; +//extern BOOL gAuditTexture; //////////////////////////////////////////////////////////////////////////// // Listeners @@ -418,12 +418,12 @@ static bool handleRenderUseImpostorsChanged(const LLSD& newvalue) LLVOAvatar::sUseImpostors = newvalue.asBoolean(); return true; } - +/* static bool handleAuditTextureChanged(const LLSD& newvalue) { gAuditTexture = newvalue.asBoolean(); return true; -} +}*/ static bool handleRenderDebugGLChanged(const LLSD& newvalue) { @@ -528,6 +528,11 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAnimateTrees")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _1)); gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + + gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); + gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _1)); gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); gSavedSettings.getControl("EnableRippleWater")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); @@ -539,6 +544,9 @@ void settings_setup_listeners() gSavedSettings.getControl("RenderAvatarInvisible")->getSignal()->connect(boost::bind(&handleSetSelfInvisible, _1)); gSavedSettings.getControl("RenderVolumeLODFactor")->getSignal()->connect(boost::bind(&handleVolumeLODChanged, _1)); gSavedSettings.getControl("RenderAvatarLODFactor")->getSignal()->connect(boost::bind(&handleAvatarLODChanged, _1)); + gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _1)); + gSavedSettings.getControl("RenderTerrainLODFactor")->getSignal()->connect(boost::bind(&handleTerrainLODChanged, _1)); gSavedSettings.getControl("RenderTreeLODFactor")->getSignal()->connect(boost::bind(&handleTreeLODChanged, _1)); gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1)); @@ -584,7 +592,7 @@ void settings_setup_listeners() gSavedSettings.getControl("AudioLevelDoppler")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioLevelRolloff")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("AudioStreamingMusic")->getSignal()->connect(boost::bind(&handleAudioStreamMusicChanged, _1)); - gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); +// gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _1)); gSavedSettings.getControl("MuteAudio")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMusic")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); gSavedSettings.getControl("MuteMedia")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _1)); diff --git a/linden/indra/newview/llviewerdisplay.cpp b/linden/indra/newview/llviewerdisplay.cpp index ad186d5..8e066c8 100644 --- a/linden/indra/newview/llviewerdisplay.cpp +++ b/linden/indra/newview/llviewerdisplay.cpp @@ -128,6 +128,11 @@ void display_startup() return; } + gPipeline.updateGL(); + + // Update images? + gImageList.updateImages(0.01f); + LLGLSDefault gls_default; // Required for HTML update in login screen @@ -599,6 +604,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.updateGeom(max_geom_update_time); stop_glerror(); + gPipeline.updateGL(); + stop_glerror(); + gFrameStats.start(LLFrameStats::UPDATE_CULL); S32 water_clip = 0; if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_ENVIRONMENT) > 1) && @@ -688,6 +696,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gPipeline.generateSunShadow(*LLViewerCamera::getInstance()); } + LLVertexBuffer::unbind(); // KL + LLGLState::checkStates(); LLGLState::checkTextureChannels(); LLGLState::checkClientArrays(); @@ -718,6 +728,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) { LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery"); gPipeline.generateWaterReflection(*LLViewerCamera::getInstance()); + gPipeline.generateHighlight(*LLViewerCamera::getInstance()); } ////////////////////////////////////// @@ -742,6 +753,9 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) const F32 max_image_decode_time = llmin(0.005f, 0.005f*10.f*gFrameIntervalSeconds); // 50 ms/second decode time (no more than 5ms/frame) gImageList.updateImages(max_image_decode_time); + + //remove dead textures from GL KL is it req? + LLImageGL::deleteDeadTextures(); stop_glerror(); } llpushcallstacks ; @@ -896,7 +910,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) /// and then display it again with compositor effects. /// Using render to texture would be faster/better, but I don't have a /// grasp of their full display stack just yet. - // gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + gPostProcess->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); // KL if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender) { @@ -912,6 +926,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) render_ui(); } + gPipeline.rebuildGroups(); + LLSpatialGroup::sNoDelete = FALSE; } @@ -998,6 +1014,15 @@ void render_hud_attachments() gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_VOLUME); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_ALPHA); gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_BUMP); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_SHINY); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISIBLE); + gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); gPipeline.stateSort(hud_cam, result); diff --git a/linden/indra/newview/llviewerimage.cpp b/linden/indra/newview/llviewerimage.cpp index 400fb2f..93c17a2 100644 --- a/linden/indra/newview/llviewerimage.cpp +++ b/linden/indra/newview/llviewerimage.cpp @@ -60,6 +60,8 @@ #include "pipeline.h" #include "llappviewer.h" #include "llface.h" +#include "lltextureatlas.h" +#include "lltextureatlasmanager.h" #include "llviewercamera.h" /////////////////////////////////////////////////////////////////////////////// @@ -102,7 +104,7 @@ void LLViewerImage::initClass() sNullImagep = new LLImageGL(1,1,3,TRUE); LLPointer raw = new LLImageRaw(1,1,3); raw->clear(0x77, 0x77, 0x77, 0xFF); - sNullImagep->createGLTexture(0, raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + sNullImagep->createGLTexture(0, raw); #if 1 LLPointer imagep = new LLViewerImage(IMG_DEFAULT); @@ -131,7 +133,7 @@ void LLViewerImage::initClass() } } } - imagep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + imagep->createGLTexture(0, image_raw); image_raw = NULL; gImageList.addImage(imagep); imagep->dontDiscard(); @@ -141,48 +143,48 @@ void LLViewerImage::initClass() sSmokeImagep = gImageList.getImage(IMG_SMOKE, TRUE, TRUE); sSmokeImagep->setNoDelete() ; - if(gAuditTexture) +#if !LL_RELEASE_FOR_DOWNLOAD + sDefaultTexturep = new LLImageGL() ; + image_raw = new LLImageRaw(dim,dim,3); + data = image_raw->getData(); + for (S32 i = 0; igetData(); - for (S32 i = 0; i=(dim-border) || j>=(dim-border)) { - const S32 border = 2; - if (i=(dim-border) || j>=(dim-border)) - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0xff; - } - else - { - *data++ = 0xff; - *data++ = 0xff; - *data++ = 0x00; - } + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0xff; + } + else + { + *data++ = 0xff; + *data++ = 0xff; + *data++ = 0x00; } } - sDefaultTexturep->createGLTexture(0, image_raw, 0, TRUE, LLViewerImageBoostLevel::OTHER); - image_raw = NULL; - sDefaultTexturep->dontDiscard(); } + sDefaultTexturep->createGLTexture(0, image_raw); + image_raw = NULL; + sDefaultTexturep->dontDiscard(); +#endif } // static void LLViewerImage::cleanupClass() { stop_glerror(); - LLImageGL::cleanupClass() ; - sNullImagep = NULL; sDefaultImagep = NULL; sSmokeImagep = NULL; sMissingAssetImagep = NULL; - sWhiteImagep = NULL; - sDefaultTexturep = NULL ; + sWhiteImagep = NULL; + +#if !LL_RELEASE_FOR_DOWNLOAD + LLImageGL::sDefaultTexturep = NULL ; +#endif } // tuning params @@ -231,12 +233,7 @@ void LLViewerImage::updateClass(const F32 velocity, const F32 angular_velocity) } sDesiredDiscardBias = llclamp(sDesiredDiscardBias, sDesiredDiscardBiasMin, sDesiredDiscardBiasMax); - F32 camera_moving_speed = LLViewerCamera::getInstance()->getAverageSpeed() ; - F32 camera_angular_speed = LLViewerCamera::getInstance()->getAverageAngularSpeed(); - sCameraMovingDiscardBias = (S8)llmax(0.2f * camera_moving_speed, 2.0f * camera_angular_speed - 1) ; - - LLViewerImage::sFreezeImageScalingDown = (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) < 0.75f * sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) < 0.75f * sMaxTotalTextureMemInMegaBytes * texmem_middle_bound_scale) ; + LLImageGL::sUseTextureAtlas = gSavedSettings.getBOOL("EnableTextureAtlas") ; } // static @@ -382,6 +379,7 @@ LLViewerImage::~LLViewerImage() void LLViewerImage::cleanup() { mFaceList.clear() ; + for(callback_list_t::iterator iter = mLoadedCallbackList.begin(); iter != mLoadedCallbackList.end(); ) { @@ -411,6 +409,192 @@ void LLViewerImage::reinit(BOOL usemipmaps /* = TRUE */) setSize(0,0,0); } +void LLViewerImage::resetFaceAtlas() +{ + //Nothing should be done here. +} + +//invalidate all atlas slots for this image. +void LLViewerImage::invalidateAtlas(BOOL rebuild_geom) +{ + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) + { + if(*iter) + { + LLFace* facep = (LLFace*)*iter ; + facep->removeAtlas() ; + if(rebuild_geom && facep->getDrawable() && facep->getDrawable()->getSpatialGroup()) + { + facep->getDrawable()->getSpatialGroup()->setState(LLSpatialGroup::GEOM_DIRTY); + } + } + } +} + +BOOL LLViewerImage::insertToAtlas() +{ + if(mFaceList.size() < 1) + { + return FALSE ; + } + if(!canAddToAtlas()) + { + return FALSE ; + } + if(getDiscardLevelInAtlas() > 0 && mRawDiscardLevel >= getDiscardLevelInAtlas()) + { + return FALSE ; + } + if(!LLTextureAtlasManager::getInstance()->canAddToAtlas(mRawImage->getWidth(), mRawImage->getHeight(), mRawImage->getComponents(), getTexTarget())) + { + return FALSE ; + } + + BOOL ret = TRUE ;//if ret is set to false, will generate a gl texture for this image. + S32 raw_w = mRawImage->getWidth() ; + S32 raw_h = mRawImage->getHeight() ; + F32 xscale = 1.0f, yscale = 1.0f ; + LLPointer slot_infop; + LLTextureAtlasSlot* cur_slotp ;//no need to be smart pointer. + LLSpatialGroup* groupp ; + LLFace* facep; + + //if the atlas slot pointers for some faces are null, process them later. + ll_face_list_t waiting_list ; + + for(ll_face_list_t::iterator iter = mFaceList.begin(); iter != mFaceList.end(); ++iter) + { + if(*iter) + { + facep = (LLFace*)*iter ; + + //face can not use atlas. + if(!facep->canUseAtlas()) + { + if(facep->getAtlasInfo()) + { + facep->removeAtlas() ; + } + ret = FALSE ; + continue ; + } + + //the atlas slot is updated + slot_infop = facep->getAtlasInfo() ; + groupp = facep->getDrawable()->getSpatialGroup() ; + + if(slot_infop) + { + if(slot_infop->getSpatialGroup() != groupp) + { + if((cur_slotp = groupp->getCurUpdatingSlot(this))) //switch slot + { + facep->setAtlasInfo(cur_slotp) ; + facep->setAtlasInUse(TRUE) ; + continue ; + } + else //do not forget to update slot_infop->getSpatialGroup(). + { + LLSpatialGroup* gp = slot_infop->getSpatialGroup() ; + gp->setCurUpdatingTime(gFrameCount) ; + gp->setCurUpdatingTexture(this) ; + gp->setCurUpdatingSlot(slot_infop) ; + } + } + else //same group + { + if(gFrameCount && slot_infop->getUpdatedTime() == gFrameCount)//slot is just updated + { + facep->setAtlasInUse(TRUE) ; + continue ; + } + } + } + else + { + //if the slot is null, wait to process them later. + waiting_list.push_back(facep) ; + continue ; + } + + //---------- + //insert to atlas + if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) + { + //the texture does not qualify to add to atlas, do not bother to try for other faces. + //invalidateAtlas(); + return FALSE ; + } + + //update texture scale + slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; + slot_infop->setTexCoordScale(xscale, yscale) ; + slot_infop->setValid() ; + slot_infop->setUpdatedTime(gFrameCount) ; + + //update spatial group atlas info + groupp->setCurUpdatingTime(gFrameCount) ; + groupp->setCurUpdatingTexture(this) ; + groupp->setCurUpdatingSlot(slot_infop) ; + + //make the face to switch to the atlas. + facep->setAtlasInUse(TRUE) ; + } + } + + //process the waiting_list + for(ll_face_list_t::iterator iter = waiting_list.begin(); iter != waiting_list.end(); ++iter) + { + facep = (LLFace*)*iter ; + groupp = facep->getDrawable()->getSpatialGroup() ; + + //check if this texture already inserted to atlas for this group + if((cur_slotp = groupp->getCurUpdatingSlot(this))) + { + facep->setAtlasInfo(cur_slotp) ; + facep->setAtlasInUse(TRUE) ; + continue ; + } + + //need to reserve a slot from atlas + slot_infop = LLTextureAtlasManager::getInstance()->reserveAtlasSlot(llmax(mFullWidth, mFullHeight), getComponents(), groupp, this) ; + + facep->setAtlasInfo(slot_infop) ; + + groupp->setCurUpdatingTime(gFrameCount) ; + groupp->setCurUpdatingTexture(this) ; + groupp->setCurUpdatingSlot(slot_infop) ; + + //slot allocation failed. + if(!slot_infop || !slot_infop->getAtlas()) + { + ret = FALSE ; + facep->setAtlasInUse(FALSE) ; + continue ; + } + + //insert to atlas + if(!LLImageGL::createGLTextureInAtlas(mRawDiscardLevel, mRawImage, slot_infop->getAtlas(), slot_infop->getSlotCol(), slot_infop->getSlotRow())) + { + //the texture does not qualify to add to atlas, do not bother to try for other faces. + ret = FALSE ; + //invalidateAtlas(); + break ; + } + + //update texture scale + slot_infop->getAtlas()->getTexCoordScale(raw_w, raw_h, xscale, yscale) ; + slot_infop->setTexCoordScale(xscale, yscale) ; + slot_infop->setValid() ; + slot_infop->setUpdatedTime(gFrameCount) ; + + //make the face to switch to the atlas. + facep->setAtlasInUse(TRUE) ; + } + + return ret ; +} + /////////////////////////////////////////////////////////////////////////////// // ONLY called from LLViewerImageList void LLViewerImage::destroyTexture() @@ -432,7 +616,7 @@ void LLViewerImage::addToCreateTexture() if(isForSculptOnly()) { //just update some variables, not to create a real GL texture. - createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE) ; + createGLTexture(mRawDiscardLevel, mRawImage, 0) ; mNeedsCreateTexture = FALSE ; destroyRawImage(); } @@ -495,7 +679,7 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mNeedsCreateTexture = FALSE; if (mRawImage.isNull()) { - llerrs << "LLViewerImage trying to create texture with no Raw Image" << llendl; + llwarns << "LLViewerImage trying to create texture with no Raw Image" << llendl; } // llinfos << llformat("IMAGE Creating (%d) [%d x %d] Bytes: %d ", // mRawDiscardLevel, @@ -519,32 +703,25 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) mOrigHeight = mFullHeight; } - bool size_okay = true; - - U32 raw_width = mRawImage->getWidth() << mRawDiscardLevel; - U32 raw_height = mRawImage->getHeight() << mRawDiscardLevel; - if( raw_width > MAX_IMAGE_SIZE || raw_height > MAX_IMAGE_SIZE ) + if (LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) { - llinfos << "Width or height is greater than " << MAX_IMAGE_SIZE << ": (" << raw_width << "," << raw_height << ")" << llendl; - size_okay = false; + if(!(res = insertToAtlas())) + { + res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); + resetFaceAtlas() ; + } } - if (!LLImageGL::checkSize(mRawImage->getWidth(), mRawImage->getHeight())) + else { // A non power-of-two image was uploaded (through a non standard client) - llinfos << "Non power of two width or height: (" << mRawImage->getWidth() << "," << mRawImage->getHeight() << ")" << llendl; - size_okay = false; - } - - if( !size_okay ) - { - // An inappropriately-sized image was uploaded (through a non standard client) // We treat these images as missing assets which causes them to // be renderd as 'missing image' and to stop requesting data setIsMissingAsset(); destroyRawImage(); return FALSE; } + if (mRawImage->getComponents()>4) { LL_DEBUGS("Openjpeg")<<"broken raw image" << LL_ENDL; @@ -553,7 +730,6 @@ BOOL LLViewerImage::createTexture(S32 usename/*= 0*/) return FALSE; } - res = LLImageGL::createGLTexture(mRawDiscardLevel, mRawImage, usename); } // @@ -655,6 +831,7 @@ void LLViewerImage::processTextureStats() S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT); S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT); mTexelsPerImage = (F32)fullwidth * fullheight; + F32 discard_level = 0.f; // If we know the output width and height, we can force the discard @@ -662,7 +839,8 @@ void LLViewerImage::processTextureStats() // data than we need to. if (mBoostLevel == LLViewerImageBoostLevel::BOOST_UI || mBoostLevel == LLViewerImageBoostLevel::BOOST_PREVIEW || - mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF) // JAMESDEBUG what about AVATAR_BAKED_SELF? + mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_SELF || + mBoostLevel == LLViewerImageBoostLevel::BOOST_AVATAR_BAKED_SELF) { discard_level = 0; // full res } @@ -677,12 +855,6 @@ void LLViewerImage::processTextureStats() } else { - if(isLargeImage() && !isJustBound() && mAdditionalDecodePriority < 1.0f) - { - //if is a big image and not being used recently, nor close to the view point, do not load hi-res data. - mMaxVirtualSize = llmin(mMaxVirtualSize, (F32)LLViewerImage::sMinLargeImageSize) ; - } - if ((mCalculatedDiscardLevel >= 0.f) && (llabs(mMaxVirtualSize - mDiscardVirtualSize) < mMaxVirtualSize*.20f)) { @@ -705,6 +877,7 @@ void LLViewerImage::processTextureStats() discard_level += sCameraMovingDiscardBias ; } discard_level = floorf(discard_level); +// discard_level -= (gImageList.mVideoMemorySetting>>1); // more video ram = higher detail F32 min_discard = 0.f; if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT) @@ -726,15 +899,12 @@ void LLViewerImage::processTextureStats() if ((sDesiredDiscardBias > 0.0f) && (current_discard >= 0 && mDesiredDiscardLevel >= current_discard)) { - // Limit the amount of GL memory bound each frame - if ( (BYTES_TO_MEGA_BYTES(sBoundTextureMemoryInBytes) > sMaxBoundTextureMemInMegaBytes * texmem_middle_bound_scale) && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) + if ( (sBoundTextureMemoryInBytes >> 20) > sMaxBoundTextureMemInMegaBytes*texmem_middle_bound_scale) { scaleDown() ; } // Only allow GL to have 2x the video card memory - else if ( (BYTES_TO_MEGA_BYTES(sTotalTextureMemoryInBytes) > sMaxTotalTextureMemInMegaBytes*texmem_middle_bound_scale) && - (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel)) + else if (!getBoundRecently() || mDesiredDiscardLevel >= mCachedRawDiscardLevel) { scaleDown() ; } @@ -756,7 +926,7 @@ void LLViewerImage::updateVirtualSize() if(facep->getDrawable()->isRecentlyVisible()) { addTextureStats(facep->getVirtualSize()) ; - setAdditionalDecodePriority(facep->getImportanceToCamera()) ; + //setAdditionalDecodePriority(facep->getImportanceToCamera()) ; } } } @@ -796,6 +966,7 @@ void LLViewerImage::switchToCachedImage() mNeedsCreateTexture = TRUE; } } + //============================================================================ F32 LLViewerImage::calcDecodePriority() @@ -817,13 +988,6 @@ F32 LLViewerImage::calcDecodePriority() } S32 cur_discard = getDiscardLevel(); - - //no need to update if the texture reaches its highest res and the memory is sufficient. - //if(LLViewerImage::sFreezeImageScalingDown && !cur_discard) - //{ - // return -5.0f ; - //} - bool have_all_data = (cur_discard >= 0 && (cur_discard <= mDesiredDiscardLevel)); F32 pixel_priority = fsqrtf(mMaxVirtualSize); const S32 MIN_NOT_VISIBLE_FRAMES = 30; // NOTE: this function is not called every frame @@ -842,14 +1006,6 @@ F32 LLViewerImage::calcDecodePriority() { priority = -1.0f ; } - else if (!isJustBound() && mCachedRawImageReady) - { - priority = -1.0f; - } - else if(mCachedRawDiscardLevel > -1 && mDesiredDiscardLevel >= mCachedRawDiscardLevel) - { - priority = -1.0f; - } else if (mDesiredDiscardLevel > mMaxDiscardLevel) { // Don't decode anything we don't need @@ -910,7 +1066,6 @@ F32 LLViewerImage::calcDecodePriority() ddiscard-=2; } ddiscard = llclamp(ddiscard, 0, 4); - priority = ddiscard*100000.f; } if (priority > 0.0f) @@ -942,7 +1097,7 @@ F32 LLViewerImage::calcDecodePriority() //static F32 LLViewerImage::maxDecodePriority() { - return 6000000.f; + return 6000000.f; // KL 2000000 in render pipeline } void LLViewerImage::setDecodePriority(F32 priority) @@ -969,10 +1124,7 @@ void LLViewerImage::setBoostLevel(S32 level) { mBoostLevel = level; - if(gAuditTexture) - { - setCategory(mBoostLevel); - } + if(mBoostLevel != LLViewerImageBoostLevel::BOOST_NONE) { @@ -1022,11 +1174,15 @@ bool LLViewerImage::updateFetch() return false; // process any raw image data in callbacks before replacing } + mFetchState = 0; + mFetchPriority = 0; + mFetchDeltaTime = 999999.f; + mRequestDeltaTime = 999999.f; S32 current_discard = getDiscardLevel(); S32 desired_discard = getDesiredDiscardLevel(); F32 decode_priority = getDecodePriority(); decode_priority = llmax(decode_priority, 0.0f); - decode_priority = llmin(decode_priority, maxDecodePriority()); + //decode_priority = llmin(decode_priority, maxDecodePriority()); if (mIsFetching) { @@ -1059,7 +1215,6 @@ bool LLViewerImage::updateFetch() if (mRawImage.notNull()) { mRawDiscardLevel = fetch_discard; - if ((mRawImage->getDataSize() > 0 && mRawDiscardLevel >= 0) && (current_discard < 0 || mRawDiscardLevel < current_discard)) { @@ -1178,10 +1333,6 @@ bool LLViewerImage::updateFetch() { make_request = false; } - else if (!isJustBound() && mCachedRawImageReady) - { - make_request = false; - } else { if (mIsFetching) @@ -1216,14 +1367,13 @@ bool LLViewerImage::updateFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; mRequestedDiscardLevel = desired_discard; - mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, - mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); - } + mFetchPriority, mFetchDeltaTime, mRequestDeltaTime); + } // if createRequest() failed, we're finishing up a request for this UUID, // wait for it to complete @@ -1295,12 +1445,12 @@ BOOL LLViewerImage::forceFetch() w, h, c, desired_discard, needsAux()); if (fetch_request_created) - { + { mHasFetcher = TRUE; mIsFetching = TRUE; // Set the image's decode priority to maxDecodePriority() too, or updateFetch() will set // the request priority to 0 and terminate the fetch before we even started (SNOW-203). - gImageList.bumpToMaxDecodePriority(this); + // gImageList.bumpToMaxDecodePriority(this); // Kl force immediate update?? mRequestedDiscardLevel = desired_discard ; mFetchState = LLAppViewer::getTextureFetch()->getFetchState(mID, mDownloadProgress, mRequestedDownloadPriority, @@ -1473,8 +1623,8 @@ bool LLViewerImage::doLoadedCallbacks() destroyRawImage(); readBackRawImage(gl_discard); - llassert_always(mRawImage.notNull()); - llassert_always(!mNeedsAux || mAuxRawImage.notNull()); + //llassert_always(mRawImage.notNull()); + //llassert_always(!mNeedsAux || mAuxRawImage.notNull()); } // @@ -1636,7 +1786,18 @@ bool LLViewerImage::bindDefaultImage(S32 stage) //virtual void LLViewerImage::forceImmediateUpdate() { - gImageList.bumpToMaxDecodePriority(this) ; + //only immediately update a deleted texture which is now being re-used. + if(!isDeleted()) + { + return ; + } + //if already called forceImmediateUpdate() + if(mInImageList && mDecodePriority == LLViewerImage::maxDecodePriority()) + { + return ; + } + + gImageList.forceImmediateUpdate(this) ; return ; } @@ -1647,7 +1808,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) llassert_always(mComponents > 0); if (mRawImage.notNull()) { - llerrs << "called with existing mRawImage" << llendl; + llwarns << "called with existing mRawImage" << llendl; mRawImage = NULL; } @@ -1665,7 +1826,7 @@ LLImageRaw* LLViewerImage::readBackRawImage(S8 discard_level) sRawCount++; mIsRawImageValid = TRUE; - + return mRawImage; } diff --git a/linden/indra/newview/llviewerimage.h b/linden/indra/newview/llviewerimage.h index c82b68b..7d646be 100644 --- a/linden/indra/newview/llviewerimage.h +++ b/linden/indra/newview/llviewerimage.h @@ -41,11 +41,13 @@ #include #include -class LLFace; + #define MIN_VIDEO_RAM_IN_MEGA_BYTES 32 #define MAX_VIDEO_RAM_IN_MEGA_BYTES 512 // 512MB max for performance reasons. class LLViewerImage; +class LLTextureAtlas ; +class LLFace ; typedef void (*loaded_callback_func)( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); @@ -261,8 +263,29 @@ public: void setMinDiscardLevel(S32 discard) { mMinDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel,(S8)discard); } // Host we think might have this image, used for baked av textures. + void setTargetHost(LLHost host) { mTargetHost = host; } LLHost getTargetHost() const { return mTargetHost; } + enum + { + BOOST_NONE = 0, + BOOST_AVATAR_BAKED = 1, + BOOST_AVATAR = 2, + BOOST_CLOUDS = 3, + BOOST_SCULPTED = 4, + + BOOST_HIGH = 10, + BOOST_TERRAIN = 11, // has to be high priority for minimap / low detail + BOOST_SELECTED = 12, + BOOST_HUD = 13, + BOOST_AVATAR_BAKED_SELF = 14, + BOOST_UI = 15, + BOOST_PREVIEW = 16, + BOOST_MAP = 17, + BOOST_MAP_LAYER = 18, + BOOST_AVATAR_SELF = 19, // needed for baking avatar + BOOST_MAX_LEVEL + }; void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } @@ -295,6 +318,10 @@ public: S32 getOriginalWidth() { return mOrigWidth; } S32 getOriginalHeight() { return mOrigHeight; } + BOOL insertToAtlas() ; + void resetFaceAtlas() ; + void invalidateAtlas(BOOL rebuild_geom = FALSE); + BOOL isForSculptOnly() const ; void setForSculpt(); @@ -313,6 +340,7 @@ public: void addFace(LLFace* facep) ; void removeFace(LLFace* facep) ; + BOOL isReferenced()const {return mFaceList.size() > 0 ; } friend class LocalBitmap; // tag: vaa emerald local_asset_browser @@ -418,6 +446,7 @@ private: typedef std::list ll_face_list_t ; ll_face_list_t mFaceList ; //reverse pointer pointing to the faces using this image as texture + BOOL mInCreationList ; public: static const U32 sCurrentFileVersion; // Default textures diff --git a/linden/indra/newview/llviewerimagelist.cpp b/linden/indra/newview/llviewerimagelist.cpp index 29c630b..f795de6 100644 --- a/linden/indra/newview/llviewerimagelist.cpp +++ b/linden/indra/newview/llviewerimagelist.cpp @@ -199,7 +199,6 @@ static std::string get_texture_list_name() void LLViewerImageList::doPrefetchImages() { -#if 1 if (LLAppViewer::instance()->getPurgeCache()) { // cache was purged, no point @@ -227,7 +226,7 @@ void LLViewerImageList::doPrefetchImages() image->addTextureStats((F32)pixel_area); } } -#endif + } @@ -486,7 +485,7 @@ void LLViewerImageList::removeImageFromList(LLViewerImage *image) { llinfos << "Image is not in mUUIDMap!" << llendl ; } - llerrs << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; + llwarns << "LLViewerImageList::removeImageFromList - Image not in list" << llendl; } llverify(mImageList.erase(image) == 1); image->mInImageList = FALSE; @@ -535,7 +534,8 @@ void LLViewerImageList::deleteImage(LLViewerImage *image) void LLViewerImageList::dirtyImage(LLViewerImage *image) { - mDirtyTextureList.insert(image); + //mDirtyTextureList.insert(image); + image->invalidateAtlas(TRUE) ; // KL } //////////////////////////////////////////////////////////////////////////// @@ -547,25 +547,21 @@ void LLViewerImageList::updateImages(F32 max_time) sNumImagesStat.addValue(sNumImages); sNumRawImagesStat.addValue(LLImageRaw::sRawImageCount); - sGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes)); - sGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes)); - sRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory)); - sFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory)); - + sGLTexMemStat.addValue((F32)(LLImageGL::sGlobalTextureMemoryInBytes >> 20)); + sGLBoundMemStat.addValue((F32)(LLImageGL::sBoundTextureMemoryInBytes >> 20)); + sRawMemStat.addValue((F32)(LLImageRaw::sGlobalRawMemory >> 20)); + sFormattedMemStat.addValue((F32)(LLImageFormatted::sGlobalFormattedMemory >> 20)); + llpushcallstacks ; - updateImagesDecodePriorities(); - llpushcallstacks ; - F32 total_max_time = max_time; max_time -= updateImagesFetchTextures(max_time); - llpushcallstacks ; - max_time = llmax(max_time, total_max_time*.25f); // at least 25% of max_time + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); max_time -= updateImagesCreateTextures(max_time); - llpushcallstacks ; - + max_time = llmin(llmax(max_time, 0.001f*10.f*gFrameIntervalSeconds), 0.001f); + llpushcallstacks ; if (!mDirtyTextureList.empty()) { LLFastTimer t(LLFastTimer::FTM_IMAGE_MARK_DIRTY); @@ -739,7 +735,7 @@ F32 LLViewerImageList::updateImagesCreateTextures(F32 max_time) return create_timer.getElapsedTimeF32(); } -void LLViewerImageList::bumpToMaxDecodePriority(LLViewerImage* imagep) +void LLViewerImageList::forceImmediateUpdate(LLViewerImage* imagep) { if(!imagep) { @@ -747,11 +743,6 @@ void LLViewerImageList::bumpToMaxDecodePriority(LLViewerImage* imagep) } if(imagep->mInImageList) { - if (imagep->getDecodePriority() == LLViewerImage::maxDecodePriority()) - { - // Already at maximum. - return; - } removeImageFromList(imagep); } @@ -1028,13 +1019,16 @@ LLPointer LLViewerImageList::convertToUploadFile(LLPointer> 20); //min texture mem sets to 64M if total physical mem is more than 1.5GB - return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM_IN_MEGA_BYTES ; + return (system_ram > 1500) ? 64 : MIN_VIDEO_RAM; } //static @@ -1061,14 +1055,14 @@ S32 LLViewerImageList::getMaxVideoRamSetting(bool get_recommended) llwarns << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << llendl; } - S32 system_ram = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()); // In MB + S32 system_ram = (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20); // In MB //llinfos << "*** DETECTED " << system_ram << " MB of system memory." << llendl; if (get_recommended) max_texmem = llmin(max_texmem, (S32)(system_ram/2)); else max_texmem = llmin(max_texmem, (S32)(system_ram)); - max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM_IN_MEGA_BYTES); + max_texmem = llclamp(max_texmem, getMinVideoRamSetting(), MAX_VIDEO_RAM); return max_texmem; } @@ -1113,9 +1107,9 @@ void LLViewerImageList::updateMaxResidentTexMem(S32 mem) mMaxTotalTextureMemInMegaBytes -= (mMaxResidentTexMemInMegaBytes >> 2); } - if (mMaxTotalTextureMemInMegaBytes > (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128) + if (mMaxTotalTextureMemInMegaBytes > (S32)(gSysMemory.getPhysicalMemoryClamped() >> 20) - 128) { - mMaxTotalTextureMemInMegaBytes = (S32)BYTES_TO_MEGA_BYTES(gSysMemory.getPhysicalMemoryClamped()) - 128 ; + mMaxTotalTextureMemInMegaBytes = (gSysMemory.getPhysicalMemoryClamped() >> 20) - 128 ; } llinfos << "Total Video Memory set to: " << vb_mem << " MB" << llendl; diff --git a/linden/indra/newview/llviewerimagelist.h b/linden/indra/newview/llviewerimagelist.h index 561e8e5..f82d9f3 100644 --- a/linden/indra/newview/llviewerimagelist.h +++ b/linden/indra/newview/llviewerimagelist.h @@ -112,7 +112,7 @@ public: LLGLenum primary_format = 0, const LLUUID& force_id = LLUUID::null ); - + // Request image from a specific host, used for baked avatar textures. // Implemented in header in case someone changes default params above. JC LLViewerImage* getImageFromHost(const LLUUID& image_id, LLHost host) @@ -129,7 +129,7 @@ public: // Using image stats, determine what images are necessary, and perform image updates. void updateImages(F32 max_time); - void bumpToMaxDecodePriority(LLViewerImage* imagep) ; + void forceImmediateUpdate(LLViewerImage* imagep) ; // Decode and create textures for all images currently in list. void decodeAllImages(F32 max_decode_time); diff --git a/linden/indra/newview/llviewerjointmesh.cpp b/linden/indra/newview/llviewerjointmesh.cpp index b6f0daf..dc08bcd 100644 --- a/linden/indra/newview/llviewerjointmesh.cpp +++ b/linden/indra/newview/llviewerjointmesh.cpp @@ -523,9 +523,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) //---------------------------------------------------------------- if (!gRenderForSelect) { - if (is_dummy) + /* if (is_dummy) glColor4fv(LLVOAvatar::getDummyColor().mV); - else + else */ glColor4fv(mColor.mV); } @@ -557,7 +557,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { if( mLayerSet->hasComposite() ) { - gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture()); + gGL.getTexUnit(0)->bind(mLayerSet->getComposite()->getTexture(), TRUE); // KL SD } else { @@ -565,7 +565,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) // Ignore the warning if that's the case. if (!gSavedSettings.getBOOL("RenderUnloadedAvatar")) { - llwarns << "Layerset without composite" << llendl; + //llwarns << "Layerset without composite" << llendl; } gGL.getTexUnit(0)->bind(gImageList.getImage(IMG_DEFAULT)); } @@ -574,7 +574,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) if ( !is_dummy && mTexture.notNull() ) { old_mode = mTexture->getAddressMode(); - gGL.getTexUnit(0)->bind(mTexture.get()); + gGL.getTexUnit(0)->bind(mTexture.get(), TRUE); // KL SD gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); } else diff --git a/linden/indra/newview/llviewermedia.cpp b/linden/indra/newview/llviewermedia.cpp index 8c5cf6a..8857170 100644 --- a/linden/indra/newview/llviewermedia.cpp +++ b/linden/indra/newview/llviewermedia.cpp @@ -938,9 +938,7 @@ void LLViewerMediaImpl::update() x_pos, y_pos, width, - height, - TRUE); // force a fast update (i.e. don't call analyzeAlpha, etc.) - + height); } mMediaSource->resetDirty(); diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp index 7266dbc..314fc94 100644 --- a/linden/indra/newview/llviewermenu.cpp +++ b/linden/indra/newview/llviewermenu.cpp @@ -1408,14 +1408,14 @@ void init_debug_avatar_menu(LLMenuGL* menu) //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints)); //diabling collision plane due to DEV-14477 -brad //menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane)); - menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", + /*menu->append(new LLMenuItemCheckGL("Show Collision Skeleton", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, (void*)LLPipeline::RENDER_DEBUG_AVATAR_VOLUME)); menu->append(new LLMenuItemCheckGL("Display Agent Target", &LLPipeline::toggleRenderDebug, NULL, &LLPipeline::toggleRenderDebugControl, - (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET)); + (void*)LLPipeline::RENDER_DEBUG_AGENT_TARGET));*/ menu->append(new LLMenuItemToggleGL( "Debug Rotation", &LLVOAvatar::sDebugAvatarRotation)); menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments)); menu->append(new LLMenuItemCallGL("Refresh Appearance", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL )); @@ -10436,7 +10436,7 @@ class LLAdvancedCheckShowCollisionPlane : public view_listener_t // SHOW COLLISION SKELETON // ///////////////////////////// - +/* class LLAdvancedToggleShowCollisionSkeleton : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -10457,13 +10457,13 @@ class LLAdvancedCheckShowCollisionSkeleton : public view_listener_t } }; - +*/ ////////////////////////// // DISPLAY AGENT TARGET // ////////////////////////// - +/* class LLAdvancedToggleDisplayAgentTarget : public view_listener_t { bool handleEvent(LLPointer event, const LLSD& userdata) @@ -10484,7 +10484,7 @@ class LLAdvancedCheckDisplayAgentTarget : public view_listener_t } }; - +*/ /////////////////////////// // DEBUG AVATAR ROTATION // @@ -11350,10 +11350,10 @@ void initialize_menus() addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis"); // addMenu(new LLAdvancedToggleShowCollisionPlane(), "Advanced.ToggleShowCollisionPlane"); // addMenu(new LLAdvancedCheckShowCollisionPlane(), "Advanced.CheckShowCollisionPlane"); - addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); - addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); - addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); - addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); +// addMenu(new LLAdvancedToggleShowCollisionSkeleton(), "Advanced.ToggleShowCollisionSkeleton"); +// addMenu(new LLAdvancedCheckShowCollisionSkeleton(), "Advanced.CheckShowCollisionSkeleton"); +// addMenu(new LLAdvancedToggleDisplayAgentTarget(), "Advanced.ToggleDisplayAgentTarget"); +// addMenu(new LLAdvancedCheckDisplayAgentTarget(), "Advanced.CheckDisplayAgentTarget"); addMenu(new LLAdvancedToggleDebugAvatarRotation(), "Advanced.ToggleDebugAvatarRotation"); addMenu(new LLAdvancedCheckDebugAvatarRotation(), "Advanced.CheckDebugAvatarRotation"); addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments"); diff --git a/linden/indra/newview/llviewerobject.cpp b/linden/indra/newview/llviewerobject.cpp index b40d4e0..2a6fafa 100644 --- a/linden/indra/newview/llviewerobject.cpp +++ b/linden/indra/newview/llviewerobject.cpp @@ -2785,6 +2785,11 @@ BOOL LLViewerObject::updateGeometry(LLDrawable *drawable) return TRUE; } +void LLViewerObject::updateGL() +{ + +} + void LLViewerObject::updateFaceSize(S32 idx) { @@ -2889,7 +2894,7 @@ F32 LLViewerObject::getMidScale() const } -void LLViewerObject::updateTextures() +void LLViewerObject::updateTextures(LLAgent &agent) { } @@ -3734,6 +3739,7 @@ S32 LLViewerObject::setTEColor(const U8 te, const LLColor4& color) else if (color != tep->getColor()) { retval = LLPrimitive::setTEColor(te, color); + //setChanged(TEXTURE); if (mDrawable.notNull() && retval) { // These should only happen on updates which are not the initial update. @@ -3972,7 +3978,7 @@ LLViewerImage *LLViewerObject::getTEImage(const U8 face) const } } - llerrs << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; + llwarns << llformat("Requested Image from invalid face: %d/%d",face,getNumTEs()) << llendl; return NULL; } @@ -4158,6 +4164,11 @@ void LLViewerObject::updateText() } } +LLVOAvatar* LLViewerObject::asAvatar() +{ + return NULL; +} + BOOL LLViewerObject::isParticleSource() const { return !mPartSourcep.isNull() && !mPartSourcep->isDead(); @@ -4372,7 +4383,14 @@ void LLViewerObject::setAttachedSound(const LLUUID &audio_uuid, const LLUUID& ow gAudiop->cleanupAudioSource(mAudioSourcep); mAudioSourcep = NULL; } - +/* + if (mAudioSourcep && mAudioSourcep->isMuted() && + mAudioSourcep->getCurrentData() && mAudioSourcep->getCurrentData()->getID() == audio_uuid) + { + //llinfos << "Already having this sound as muted sound, ignoring" << llendl; + return; + } +*/ getAudioSource(owner_id); if (mAudioSourcep) @@ -4466,7 +4484,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para new_block = new LLSculptParams(); break; } - + case LLNetworkData::PARAMS_LIGHT_IMAGE: + { + new_block = new LLLightImageParams(); + break; + } default: { llinfos << "Unknown param type." << llendl; @@ -4557,7 +4579,7 @@ bool LLViewerObject::setParameterEntry(U16 param_type, const LLNetworkData& new_ bool LLViewerObject::setParameterEntryInUse(U16 param_type, BOOL in_use, bool local_origin) { ExtraParameter* param = getExtraParameterEntryCreate(param_type); - if (param->in_use != in_use) + if (param && param->in_use != in_use) { param->in_use = in_use; parameterChanged(param_type, param->data, in_use, local_origin); @@ -4973,7 +4995,7 @@ U32 LLViewerObject::getPartitionType() const return LLViewerRegion::PARTITION_NONE; } -void LLViewerObject::dirtySpatialGroup() const +void LLViewerObject::dirtySpatialGroup(BOOL priority) const { if (mDrawable) { @@ -4981,6 +5003,7 @@ void LLViewerObject::dirtySpatialGroup() const if (group) { group->dirtyGeom(); + gPipeline.markRebuild(group, priority); } } } diff --git a/linden/indra/newview/llviewerobject.h b/linden/indra/newview/llviewerobject.h index 7f8bd63..41c406a 100644 --- a/linden/indra/newview/llviewerobject.h +++ b/linden/indra/newview/llviewerobject.h @@ -74,6 +74,7 @@ class LLViewerPartSourceScript; class LLViewerRegion; class LLViewerObjectMedia; class LLVOInventoryListener; +class LLVOAvatar; typedef enum e_object_update_type { @@ -116,7 +117,7 @@ public: //============================================================================ -class LLViewerObject : public LLPrimitive, public LLRefCount +class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate { protected: ~LLViewerObject(); // use unref() @@ -143,6 +144,8 @@ public: BOOL isOrphaned() const { return mOrphaned; } BOOL isParticleSource() const; + virtual LLVOAvatar* asAvatar(); + static void initVOClasses(); static void cleanupVOClasses(); @@ -189,11 +192,12 @@ public: S32 getNumFaces() const { return mNumFaces; } // Graphical stuff for objects - maybe broken out into render class later? - virtual void updateTextures(); + virtual void updateTextures(LLAgent &agent); virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object virtual LLDrawable* createDrawable(LLPipeline *pipeline); virtual BOOL updateGeometry(LLDrawable *drawable); + virtual void updateGL(); virtual void updateFaceSize(S32 idx); virtual BOOL updateLOD(); virtual BOOL setDrawableParent(LLDrawable* parentp); @@ -218,6 +222,7 @@ public: virtual BOOL isFlexible() const { return FALSE; } virtual BOOL isSculpted() const { return FALSE; } + virtual BOOL hasLightTexture() const { return FALSE; } // This method returns true if the object is over land owned by // the agent. @@ -468,7 +473,7 @@ public: virtual S32 getLOD() const { return 3; } virtual U32 getPartitionType() const; - virtual void dirtySpatialGroup() const; + virtual void dirtySpatialGroup(BOOL priority = FALSE) const; virtual void dirtyMesh(); virtual LLNetworkData* getParameterEntry(U16 param_type) const; diff --git a/linden/indra/newview/llviewerobjectlist.cpp b/linden/indra/newview/llviewerobjectlist.cpp index bfb248b..a289570 100644 --- a/linden/indra/newview/llviewerobjectlist.cpp +++ b/linden/indra/newview/llviewerobjectlist.cpp @@ -629,7 +629,7 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent) // Update distance & gpw objectp->setPixelAreaAndAngle(agent); // Also sets the approx. pixel area - objectp->updateTextures(); // Update the image levels of textures for this object. + objectp->updateTextures(agent); // Update the image levels of textures for this object. } } diff --git a/linden/indra/newview/llviewerobjectlist.h b/linden/indra/newview/llviewerobjectlist.h index 07920cb..a77c33d 100644 --- a/linden/indra/newview/llviewerobjectlist.h +++ b/linden/indra/newview/llviewerobjectlist.h @@ -44,7 +44,6 @@ // project includes #include "llviewerobject.h" -class LLCamera; class LLNetMap; class LLDebugBeacon; diff --git a/linden/indra/newview/llviewerparceloverlay.cpp b/linden/indra/newview/llviewerparceloverlay.cpp index 0bcd8f3..935e3e6 100644 --- a/linden/indra/newview/llviewerparceloverlay.cpp +++ b/linden/indra/newview/llviewerparceloverlay.cpp @@ -71,7 +71,7 @@ LLViewerParcelOverlay::LLViewerParcelOverlay(LLViewerRegion* region, F32 region_ // Use mipmaps = FALSE, clamped, NEAREST filter, for sharp edges mTexture = new LLImageGL(FALSE); mImageRaw = new LLImageRaw(mParcelGridsPerEdge, mParcelGridsPerEdge, OVERLAY_IMG_COMPONENTS); - mTexture->createGLTexture(0, mImageRaw, 0, TRUE, LLViewerImageBoostLevel::OTHER); + mTexture->createGLTexture(0, mImageRaw, 0); gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->bind(mTexture); mTexture->setAddressMode(LLTexUnit::TAM_CLAMP); @@ -593,7 +593,7 @@ void LLViewerParcelOverlay::addPropertyLine( break; default: - llerrs << "Invalid edge in addPropertyLine" << llendl; + llwarns << "Invalid edge in addPropertyLine" << llendl; return; } diff --git a/linden/indra/newview/llviewershadermgr.cpp b/linden/indra/newview/llviewershadermgr.cpp index 69f7bd8..8648271 100644 --- a/linden/indra/newview/llviewershadermgr.cpp +++ b/linden/indra/newview/llviewershadermgr.cpp @@ -113,6 +113,8 @@ LLGLSLShader gDeferredAvatarProgram; LLGLSLShader gDeferredAvatarAlphaProgram; LLGLSLShader gDeferredLightProgram; LLGLSLShader gDeferredMultiLightProgram; +LLGLSLShader gDeferredSpotLightProgram; +LLGLSLShader gDeferredMultiSpotLightProgram; LLGLSLShader gDeferredSunProgram; LLGLSLShader gDeferredBlurLightProgram; LLGLSLShader gDeferredSoftenProgram; @@ -120,6 +122,12 @@ LLGLSLShader gDeferredShadowProgram; LLGLSLShader gDeferredAvatarShadowProgram; LLGLSLShader gDeferredAlphaProgram; LLGLSLShader gDeferredFullbrightProgram; +LLGLSLShader gDeferredGIProgram; +LLGLSLShader gDeferredPostGIProgram; +LLGLSLShader gDeferredPostProgram; + +LLGLSLShader gLuminanceGatherProgram; + //current avatar shader parameter pointer GLint gAvatarMatrixParam; @@ -151,6 +159,9 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredMultiLightProgram); mShaderList.push_back(&gDeferredAlphaProgram); mShaderList.push_back(&gDeferredFullbrightProgram); + mShaderList.push_back(&gDeferredPostGIProgram); + mShaderList.push_back(&gDeferredPostProgram); + mShaderList.push_back(&gDeferredGIProgram); mShaderList.push_back(&gDeferredWaterProgram); mShaderList.push_back(&gDeferredAvatarAlphaProgram); } @@ -220,13 +231,32 @@ void LLViewerShaderMgr::initAttribsAndUniforms(void) mReservedUniforms.push_back("shadowMap1"); mReservedUniforms.push_back("shadowMap2"); mReservedUniforms.push_back("shadowMap3"); + mReservedUniforms.push_back("shadowMap4"); + mReservedUniforms.push_back("shadowMap5"); + mReservedUniforms.push_back("normalMap"); mReservedUniforms.push_back("positionMap"); mReservedUniforms.push_back("diffuseRect"); mReservedUniforms.push_back("specularRect"); mReservedUniforms.push_back("noiseMap"); + mReservedUniforms.push_back("lightFunc"); mReservedUniforms.push_back("lightMap"); - + mReservedUniforms.push_back("luminanceMap"); + mReservedUniforms.push_back("giLightMap"); + mReservedUniforms.push_back("sunLightMap"); + mReservedUniforms.push_back("localLightMap"); + mReservedUniforms.push_back("projectionMap"); + mReservedUniforms.push_back("diffuseGIMap"); + mReservedUniforms.push_back("specularGIMap"); + mReservedUniforms.push_back("normalGIMap"); + mReservedUniforms.push_back("minpGIMap"); + mReservedUniforms.push_back("maxpGIMap"); + mReservedUniforms.push_back("depthGIMap"); + mReservedUniforms.push_back("lastDiffuseGIMap"); + mReservedUniforms.push_back("lastNormalGIMap"); + mReservedUniforms.push_back("lastMinpGIMap"); + mReservedUniforms.push_back("lastMaxpGIMap"); + mWLUniforms.push_back("camPosLocal"); mTerrainUniforms.reserve(5); @@ -754,9 +784,9 @@ BOOL LLViewerShaderMgr::loadShadersEffects() } } -#if 0 - // disabling loading of postprocess shaders until we fix - // ATI sampler2DRect compatibility. + + // KL enabling loading of postprocess shaders until we fix + // ATI may still have issues //load Color Filter Shader if (success) @@ -797,7 +827,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() gPostNightVisionProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT]; success = gPostNightVisionProgram.createShader(NULL, &shaderUniforms); } - #endif + return success; @@ -814,6 +844,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTerrainProgram.unload(); gDeferredLightProgram.unload(); gDeferredMultiLightProgram.unload(); + gDeferredSpotLightProgram.unload(); + gDeferredMultiSpotLightProgram.unload(); gDeferredSunProgram.unload(); gDeferredBlurLightProgram.unload(); gDeferredSoftenProgram.unload(); @@ -823,6 +855,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaProgram.unload(); gDeferredAlphaProgram.unload(); gDeferredFullbrightProgram.unload(); + gDeferredPostGIProgram.unload(); + gDeferredPostProgram.unload(); + gLuminanceGatherProgram.unload(); + gDeferredGIProgram.unload(); gDeferredWaterProgram.unload(); return FALSE; } @@ -893,6 +929,26 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredSpotLightProgram.mName = "Deferred SpotLight Shader"; + gDeferredSpotLightProgram.mShaderFiles.clear(); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredSpotLightProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredMultiSpotLightProgram.mName = "Deferred MultiSpotLight Shader"; + gDeferredMultiSpotLightProgram.mShaderFiles.clear(); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/pointLightV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderFiles.push_back(make_pair("deferred/multiSpotLightF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredMultiSpotLightProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredMultiSpotLightProgram.createShader(NULL, NULL); + } + + if (success) + { gDeferredSunProgram.mName = "Deferred Sun Shader"; gDeferredSunProgram.mShaderFiles.clear(); gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); @@ -942,6 +998,36 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() if (success) { + gDeferredPostGIProgram.mName = "Deferred Post GI Shader"; + gDeferredPostGIProgram.mShaderFiles.clear(); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostGIProgram.mShaderFiles.push_back(make_pair("deferred/postgiF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostGIProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredPostProgram.mName = "Deferred Post Shader"; + gDeferredPostProgram.mShaderFiles.clear(); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredPostProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredPostProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredPostProgram.createShader(NULL, NULL); + } + + if (success) + { + gDeferredGIProgram.mName = "Deferred GI Shader"; + gDeferredGIProgram.mShaderFiles.clear(); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giV.glsl", GL_VERTEX_SHADER_ARB)); + gDeferredGIProgram.mShaderFiles.push_back(make_pair("deferred/giF.glsl", GL_FRAGMENT_SHADER_ARB)); + gDeferredGIProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gDeferredGIProgram.createShader(NULL, NULL); + } + + if (success) + { // load water shader gDeferredWaterProgram.mName = "Deferred Water Shader"; gDeferredWaterProgram.mFeatures.calculatesAtmospherics = true; @@ -1022,6 +1108,16 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() success = gDeferredAvatarAlphaProgram.createShader(&mAvatarAttribs, &mAvatarUniforms); } + if (success) + { + gLuminanceGatherProgram.mName = "Luminance Gather Shader"; + gLuminanceGatherProgram.mShaderFiles.clear(); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceV.glsl", GL_VERTEX_SHADER_ARB)); + gLuminanceGatherProgram.mShaderFiles.push_back(make_pair("deferred/luminanceF.glsl", GL_FRAGMENT_SHADER_ARB)); + gLuminanceGatherProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED]; + success = gLuminanceGatherProgram.createShader(NULL, NULL); + } + return success; } diff --git a/linden/indra/newview/llviewershadermgr.h b/linden/indra/newview/llviewershadermgr.h index a743966..bb50779 100644 --- a/linden/indra/newview/llviewershadermgr.h +++ b/linden/indra/newview/llviewershadermgr.h @@ -116,12 +116,30 @@ public: DEFERRED_SHADOW1, DEFERRED_SHADOW2, DEFERRED_SHADOW3, + DEFERRED_SHADOW4, + DEFERRED_SHADOW5, DEFERRED_NORMAL, DEFERRED_POSITION, DEFERRED_DIFFUSE, DEFERRED_SPECULAR, DEFERRED_NOISE, + DEFERRED_LIGHTFUNC, DEFERRED_LIGHT, + DEFERRED_LUMINANCE, + DEFERRED_GI_LIGHT, + DEFERRED_SUN_LIGHT, + DEFERRED_LOCAL_LIGHT, + DEFERRED_PROJECTION, + DEFERRED_GI_DIFFUSE, + DEFERRED_GI_SPECULAR, + DEFERRED_GI_NORMAL, + DEFERRED_GI_MIN_POS, + DEFERRED_GI_MAX_POS, + DEFERRED_GI_DEPTH, + DEFERRED_GI_LAST_DIFFUSE, + DEFERRED_GI_LAST_NORMAL, + DEFERRED_GI_LAST_MIN_POS, + DEFERRED_GI_LAST_MAX_POS, END_RESERVED_UNIFORMS } eGLSLReservedUniforms; @@ -326,16 +344,23 @@ extern LLGLSLShader gDeferredTerrainProgram; extern LLGLSLShader gDeferredTreeProgram; extern LLGLSLShader gDeferredLightProgram; extern LLGLSLShader gDeferredMultiLightProgram; +extern LLGLSLShader gDeferredSpotLightProgram; +extern LLGLSLShader gDeferredMultiSpotLightProgram; extern LLGLSLShader gDeferredSunProgram; +extern LLGLSLShader gDeferredGIProgram; extern LLGLSLShader gDeferredBlurLightProgram; extern LLGLSLShader gDeferredAvatarProgram; extern LLGLSLShader gDeferredSoftenProgram; extern LLGLSLShader gDeferredShadowProgram; +extern LLGLSLShader gDeferredPostGIProgram; +extern LLGLSLShader gDeferredPostProgram; extern LLGLSLShader gDeferredAvatarShadowProgram; extern LLGLSLShader gDeferredAlphaProgram; extern LLGLSLShader gDeferredFullbrightProgram; extern LLGLSLShader gDeferredAvatarAlphaProgram; +extern LLGLSLShader gLuminanceGatherProgram; + //current avatar shader parameter pointer extern GLint gAvatarMatrixParam; diff --git a/linden/indra/newview/llviewerstats.h b/linden/indra/newview/llviewerstats.h index b176632..9107ad6 100644 --- a/linden/indra/newview/llviewerstats.h +++ b/linden/indra/newview/llviewerstats.h @@ -196,7 +196,7 @@ private: F64 mLastTimeDiff; // used for time stat updates }; -static const F32 SEND_STATS_PERIOD = 300.0f; +static const F32 SEND_STATS_PERIOD = 3000.0f; // The following are from (older?) statistics code found in appviewer. void init_statistics(); diff --git a/linden/indra/newview/llviewerwindow.cpp b/linden/indra/newview/llviewerwindow.cpp index f7713c2..6f1b54c 100644 --- a/linden/indra/newview/llviewerwindow.cpp +++ b/linden/indra/newview/llviewerwindow.cpp @@ -471,6 +471,27 @@ public: ypos += y_inc; + { + std::ostringstream ostr; + ostr << "Shadow error: " << gPipeline.mShadowError; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + + { + std::ostringstream ostr; + ostr << "Shadow FOV: " << gPipeline.mShadowFOV; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + + { + std::ostringstream ostr; + ostr << "Shadow Splits: " << gPipeline.mSunClipPlanes; + addText(xpos, ypos, ostr.str()); + ypos += y_inc; + } + LLVertexBuffer::sBindCount = LLImageGL::sBindCount = LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; @@ -1321,7 +1342,6 @@ LLViewerWindow::LLViewerWindow( // Init the image list. Must happen after GL is initialized and before the images that // LLViewerWindow needs are requested. - LLImageGL::initClass(LLViewerImageBoostLevel::MAX_GL_IMAGE_CATEGORY) ; gImageList.init(); LLViewerImage::initClass(); gBumpImageList.init(); @@ -1434,7 +1454,7 @@ void LLViewerWindow::initBase() llassert( !gConsole ); gConsole = new LLConsole( "console", - gSavedSettings.getS32("ConsoleBufferSize"), + //gSavedSettings.getS32("ConsoleBufferSize"), getChatConsoleRect(), gSavedSettings.getS32("ChatFontSize"), gSavedSettings.getF32("ChatPersistTime") ); @@ -2515,7 +2535,6 @@ BOOL LLViewerWindow::handlePerFrameHover() mMouseInWindow = TRUE; } - S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]); S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]); @@ -2538,7 +2557,7 @@ BOOL LLViewerWindow::handlePerFrameHover() mCurrentMouseDelta.set(dx, dy); mouse_vel.setVec((F32) dx, (F32) dy); } - + mMouseVelocityStat.addValue(mouse_vel.magVec()); if (gNoRender) @@ -2727,8 +2746,8 @@ BOOL LLViewerWindow::handlePerFrameHover() { mToolTip->setVisible( tooltip_vis ); } - } - + } + if (tool && tool != gToolNull && tool != LLToolCompInspect::getInstance() && tool != LLToolDragAndDrop::getInstance() && !gSavedSettings.getBOOL("FreezeTime")) { LLMouseHandler *captor = gFocusMgr.getMouseCapture(); @@ -2798,37 +2817,41 @@ BOOL LLViewerWindow::handlePerFrameHover() gFloaterView->setRect(floater_rect); } - // snap floaters to top of chat bar/button strip - LLView* chatbar_and_buttons = gOverlayBar->getChild("chatbar_and_buttons", TRUE); - // find top of chatbar and state buttons, if either are visible - if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) { - // convert top/left corner of chatbar/buttons container to gFloaterView-relative coordinates + // snap floaters to top of chat bar/button strip + LLView* chatbar_and_buttons = gOverlayBar->getChild("chatbar_and_buttons", TRUE); S32 top, left; - chatbar_and_buttons->localPointToOtherView( - chatbar_and_buttons->getLocalBoundingRect().mLeft, - chatbar_and_buttons->getLocalBoundingRect().mTop, - &left, - &top, - gFloaterView); - gFloaterView->setSnapOffsetBottom(top); - } - else if (gToolBar->getVisible()) - { - S32 top, left; - gToolBar->localPointToOtherView( - gToolBar->getLocalBoundingRect().mLeft, - gToolBar->getLocalBoundingRect().mTop, - &left, - &top, - gFloaterView); - gFloaterView->setSnapOffsetBottom(top); - } - else - { - gFloaterView->setSnapOffsetBottom(0); + S32 chatbar_and_buttons_x = chatbar_and_buttons->getLocalBoundingRect().mLeft; + S32 chatbar_and_buttons_y = chatbar_and_buttons->getLocalBoundingRect().mTop; + + // find top of chatbar and state buttons, if either are visible + if (chatbar_and_buttons && !chatbar_and_buttons->getLocalBoundingRect().isNull()) + { + // convert top/left corner of chatbar/buttons container to + // gFloaterView-relative coordinates + chatbar_and_buttons->localPointToOtherView( + chatbar_and_buttons_x, + chatbar_and_buttons_y, + &left, + &top, + gFloaterView); + gFloaterView->setSnapOffsetBottom(top); + } + else if (gToolBar->getVisible()) + { + gToolBar->localPointToOtherView( + chatbar_and_buttons_x, + chatbar_and_buttons_y, + &left, + &top, + gFloaterView); + gFloaterView->setSnapOffsetBottom(top); + } + else + { + gFloaterView->setSnapOffsetBottom(0); + } } - // Always update console LLRect console_rect = getChatConsoleRect(); console_rect.mBottom = gHUDView->getRect().mBottom + getChatConsoleBottomPad(); @@ -2836,8 +2859,8 @@ BOOL LLViewerWindow::handlePerFrameHover() gConsole->setRect(console_rect); } - mLastMousePoint = mCurrentMousePoint; + mLastMousePoint = mCurrentMousePoint; // last ditch force of edit menu to selection manager if (LLEditMenuHandler::gEditMenuHandler == NULL && LLSelectMgr::getInstance()->getSelection()->getObjectCount()) { @@ -2900,7 +2923,6 @@ BOOL LLViewerWindow::handlePerFrameHover() &gDebugRaycastBinormal); } - // per frame picking - for tooltips and changing cursor over interactive objects static S32 previous_x = -1; static S32 previous_y = -1; @@ -2943,7 +2965,6 @@ BOOL LLViewerWindow::handlePerFrameHover() previous_x = x; previous_y = y; - return handled; } @@ -4041,7 +4062,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei { if(image_width > window_width || image_height > window_height) //need to enlarge the scene { - if (gGLManager.mHasFramebufferObject && !show_ui) + if (!LLPipeline::sRenderDeferred && gGLManager.mHasFramebufferObject && !show_ui) { GLint max_size = 0; glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size); @@ -4130,9 +4151,16 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei else { const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor)); - display(do_rebuild, scale_factor, subfield, TRUE); - // Required for showing the GUI in snapshots? See DEV-16350 for details. JC - render_ui(scale_factor, subfield); + if (LLPipeline::sRenderDeferred) + { + display(do_rebuild, scale_factor, subfield, FALSE); + } + else + { + display(do_rebuild, scale_factor, subfield, TRUE); + // Required for showing the GUI in snapshots? See DEV-16350 for details. JC + render_ui(scale_factor, subfield); + } } S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width); diff --git a/linden/indra/newview/llvlcomposition.cpp b/linden/indra/newview/llvlcomposition.cpp index 535c504..f96665b 100644 --- a/linden/indra/newview/llvlcomposition.cpp +++ b/linden/indra/newview/llvlcomposition.cpp @@ -460,6 +460,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } } + if (!texturep->getHasGLTexture()) + { + texturep->createGLTexture(0, raw); + } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); LLSurface::sTextureUpdateTime += gen_timer.getElapsedTimeF32(); LLSurface::sTexelsUpdated += (tex_x_end - tex_x_begin) * (tex_y_end - tex_y_begin); diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp index 14b8d3e..3b62c63 100644 --- a/linden/indra/newview/llvoavatar.cpp +++ b/linden/indra/newview/llvoavatar.cpp @@ -704,6 +704,7 @@ BOOL LLVOAvatar::sDebugInvisible = FALSE; BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; BOOL LLVOAvatar::sShowAnimationDebug = FALSE; BOOL LLVOAvatar::sShowFootPlane = FALSE; +BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; F32 LLVOAvatar::sLODFactor = 1.f; BOOL LLVOAvatar::sUseImpostors = FALSE; @@ -740,6 +741,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mTyping(FALSE), mMeshValid(FALSE), mVisible(FALSE), + mMeshTexturesDirty(FALSE), mWindFreq(0.f), mRipplePhase( 0.f ), mBelowWater(FALSE), @@ -800,7 +802,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mBakedTextureData[i].mLastTextureIndex = IMG_DEFAULT_AVATAR; mBakedTextureData[i].mTexLayerSet = NULL; mBakedTextureData[i].mIsLoaded = false; - mBakedTextureData[i].mIsUsed = false; + //mBakedTextureData[i].mIsUsed = false; // KL SG mBakedTextureData[i].mMaskTexName = 0; mBakedTextureData[i].mTextureIndex = getTextureIndex((EBakedTextureIndex)i); } @@ -856,9 +858,11 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id, mRippleTimeLast = 0.f; mShadowImagep = gImageList.getImageFromFile("foot_shadow.j2c"); - gGL.getTexUnit(0)->bind(mShadowImagep.get()); - mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); - + + // GL NOT ACTIVE HERE + //gGL.getTexUnit(0)->bind(mShadowImagep.get()); + //mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); + mInAir = FALSE; mStepOnLand = TRUE; @@ -1295,7 +1299,7 @@ void LLVOAvatar::resetImpostors() // static void LLVOAvatar::deleteCachedImages(bool clearAll) { -if(gAuditTexture) +/* if(gAuditTexture) { S32 total_tex_size = sScratchTexBytes ; S32 tex_size = SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT ; @@ -1337,7 +1341,7 @@ if(gAuditTexture) total_tex_size -= 4 * tex_size ; } } - +*/ if (LLTexLayerSet::sHasCaches) { lldebugs << "Deleting layer set caches" << llendl; @@ -1862,6 +1866,11 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info) return TRUE; } +LLVOAvatar* LLVOAvatar::asAvatar() // KL SD +{ + return this; +} + //----------------------------------------------------------------------------- // LLVOAvatar::startDefaultMotions() //----------------------------------------------------------------------------- @@ -1924,7 +1933,7 @@ void LLVOAvatar::buildCharacter() LLTimer timer; BOOL status = loadAvatar(); - stop_glerror(); + // stop_glerror(); if (gNoRender) { @@ -2034,7 +2043,7 @@ void LLVOAvatar::buildCharacter() processAnimationStateChanges(); mIsBuilt = TRUE; - stop_glerror(); +// stop_glerror(); //------------------------------------------------------------------------- // build the attach and detach menus @@ -5022,7 +5031,7 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color) //------------------------------------------------------------------------ // LLVOAvatar::updateTextures() //------------------------------------------------------------------------ -void LLVOAvatar::updateTextures() +void LLVOAvatar::updateTextures(LLAgent &agent) // KL SD version { BOOL render_avatar = TRUE; @@ -5041,6 +5050,7 @@ void LLVOAvatar::updateTextures() } std::vector layer_baked; + // GL NOT ACTIVE HERE - *TODO for (U32 i = 0; i < mBakedTextureData.size(); i++) { layer_baked.push_back(isTextureDefined(mBakedTextureData[i].mTextureIndex)); @@ -5123,12 +5133,6 @@ void LLVOAvatar::updateTextures() if (texture_dict->mIsLocalTexture) { addLocalTextureStats((ETextureIndex)index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]); - // SNOW-8 : temporary snowglobe1.0 fix for baked textures - if (render_avatar && !gGLManager.mIsDisabled ) - { - // bind the texture so that its boost level won't be slammed - gGL.getTexUnit(0)->bind(imagep); - } } else if (texture_dict->mIsBakedTexture) { @@ -5375,7 +5379,7 @@ void LLVOAvatar::processAnimationStateChanges() } } - stop_glerror(); + //stop_glerror(); } @@ -6360,6 +6364,15 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) } +void LLVOAvatar::updateGL() +{ + if (mMeshTexturesDirty) + { + updateMeshTextures(); + mMeshTexturesDirty = FALSE; + } +} + //----------------------------------------------------------------------------- // updateGeometry() //----------------------------------------------------------------------------- @@ -7396,12 +7409,20 @@ BOOL LLVOAvatar::bindScratchTexture( LLGLenum format ) if( *last_bind_time != LLImageGL::sLastFrameTime ) { *last_bind_time = LLImageGL::sLastFrameTime; - LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; +// #if !LL_RELEASE_FOR_DOWNLOAD +// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; +// #else + LLImageGL::updateBoundTexMem(texture_bytes); +// #endif } } else { - LLImageGL::updateBoundTexMemStatic(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; +// #if !LL_RELEASE_FOR_DOWNLOAD +// LLImageGL::updateBoundTexMem(texture_bytes, SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT) ; +// #else + LLImageGL::updateBoundTexMem(texture_bytes); +// #endif LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); } @@ -7423,7 +7444,8 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) { case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; - case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; +// Support for GL_EXT_paletted_texture is deprecated +// case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; case GL_RGB: components = 3; internal_format = GL_RGB8; break; case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; @@ -7465,11 +7487,11 @@ LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) LLVOAvatar::sScratchTexBytes += *texture_bytes; LLImageGL::sGlobalTextureMemoryInBytes += *texture_bytes; - +/* if(gAuditTexture) { LLImageGL::incTextureCounterStatic(SCRATCH_TEX_WIDTH * SCRATCH_TEX_HEIGHT, components, LLViewerImageBoostLevel::AVATAR_SCRATCH_TEX) ; - } + }*/ return name; } @@ -7572,6 +7594,7 @@ void LLVOAvatar::updateMeshTextures() use_lkg_baked_layer[i] = (!is_layer_baked[i] && (mBakedTextureData[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) && mBakedTextureData[i].mTexLayerSet + && mBakedTextureData[i].mTexLayerSet->getComposite() // KL SD && !mBakedTextureData[i].mTexLayerSet->getComposite()->isInitialized()); if (use_lkg_baked_layer[i]) { @@ -7605,7 +7628,7 @@ void LLVOAvatar::updateMeshTextures() if (use_lkg_baked_layer[i] && !self_customizing ) { LLViewerImage* baked_img = gImageList.getImageFromHost( mBakedTextureData[i].mLastTextureIndex, target_host ); - mBakedTextureData[i].mIsUsed = TRUE; + //mBakedTextureData[i].mIsUsed = TRUE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setTexture( baked_img ); @@ -7635,7 +7658,7 @@ void LLVOAvatar::updateMeshTextures() { mBakedTextureData[i].mTexLayerSet->createComposite(); mBakedTextureData[i].mTexLayerSet->setUpdatesEnabled( TRUE ); - mBakedTextureData[i].mIsUsed = FALSE; + // mBakedTextureData[i].mIsUsed = FALSE; for (U32 k=0; k < mBakedTextureData[i].mMeshes.size(); k++) { mBakedTextureData[i].mMeshes[k]->setLayerSet( mBakedTextureData[i].mTexLayerSet ); @@ -7656,9 +7679,13 @@ void LLVOAvatar::updateMeshTextures() mBakedTextureData[BAKED_HAIR].mMeshes[i]->setTexture( hair_img ); } mHasBakedHair = FALSE; - } - else + } + else { + for (U32 i = 0; i < mBakedTextureData[BAKED_HAIR].mMeshes.size(); i++) + { + mBakedTextureData[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f ); + } mHasBakedHair = TRUE; } @@ -7790,7 +7817,7 @@ void LLVOAvatar::clearChat() S32 LLVOAvatar::getLocalDiscardLevel( ETextureIndex index ) { // If the texture is not local, we don't care and treat it as fully loaded - if (!isIndexLocalTexture(index)) return 0; + if (!isIndexLocalTexture(index)) return FALSE; // KL SD version LocalTextureData &local_tex_data = mLocalTextureData[index]; if (index >= 0 @@ -7932,7 +7959,7 @@ bool LLVOAvatar::hasPendingBakedUploads() { for (U32 i = 0; i < mBakedTextureData.size(); i++) { - bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); + bool upload_pending = (mBakedTextureData[i].mTexLayerSet && mBakedTextureData[i].mTexLayerSet->getComposite() && mBakedTextureData[i].mTexLayerSet->getComposite()->uploadPending()); if (upload_pending) { return true; @@ -8467,7 +8494,8 @@ void LLVOAvatar::onFirstTEMessageReceived() } } - updateMeshTextures(); + mMeshTexturesDirty = TRUE; // updateMeshTextures(); + gPipeline.markGLRebuild(this); } } @@ -8530,20 +8558,22 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) // (isTextureDefined(TEX_SKIRT_BAKED) ? "SKIRT " : "skirt " ) << (getTEImage(TEX_SKIRT_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_HAIR_BAKED) ? "HAIR" : "hair " ) << (getTEImage(TEX_HAIR_BAKED)->getID()) << std::endl << // (isTextureDefined(TEX_EYES_BAKED) ? "EYES" : "eyes" ) << (getTEImage(TEX_EYES_BAKED)->getID()) << llendl ; - + if( !mFirstTEMessageReceived ) { onFirstTEMessageReceived(); } setCompositeUpdatesEnabled( FALSE ); + mMeshTexturesDirty = TRUE; + gPipeline.markGLRebuild(this); // KL SD needing work in S19? if (!mIsSelf) { releaseUnnecessaryTextures(); } - - updateMeshTextures(); // enables updates for laysets without baked textures. + + //updateMeshTextures(); // enables updates for laysets without baked textures. // parse visual params S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); @@ -8829,7 +8859,7 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id ) if (id == image_baked->getID()) { mBakedTextureData[i].mIsLoaded = true; - mBakedTextureData[i].mIsUsed = true; + //mBakedTextureData[i].mIsUsed = true; mBakedTextureData[i].mLastTextureIndex = id; for (U32 k = 0; k < mBakedTextureData[i].mMeshes.size(); k++) { @@ -9738,9 +9768,9 @@ BOOL LLVOAvatar::updateLOD() LLFace* facep = mDrawable->getFace(0); if (facep->mVertexBuffer.isNull() || - LLVertexBuffer::sEnableVBOs && + (LLVertexBuffer::sEnableVBOs && ((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != - (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE))) + (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) { mDirtyMesh = TRUE; } diff --git a/linden/indra/newview/llvoavatar.h b/linden/indra/newview/llvoavatar.h index 0c32244..ff07d81 100644 --- a/linden/indra/newview/llvoavatar.h +++ b/linden/indra/newview/llvoavatar.h @@ -88,6 +88,8 @@ public: /*virtual*/ void markDead(); void startDefaultMotions(); + /*virtual*/ LLVOAvatar* asAvatar(); // KL SD + static void updateImpostors(); //-------------------------------------------------------------------- @@ -137,7 +139,7 @@ public: LLVector3* bi_normal = NULL // return the surface bi-normal at the intersection point ); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); // KL SD // If setting a baked texture, need to request it from a non-local sim. /*virtual*/ S32 setTETexture(const U8 te, const LLUUID& uuid); /*virtual*/ void onShift(const LLVector3& shift_vector); @@ -155,6 +157,8 @@ public: /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); + /*virtual*/ void updateGL(); + /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); BOOL updateJointLODs(); @@ -474,6 +478,7 @@ private: LLFrameTimer mTypingTimer; //-------------------------------------------------------------------- + BOOL mMeshTexturesDirty; // wind rippling in clothes //-------------------------------------------------------------------- public: @@ -570,6 +575,7 @@ public: static BOOL sShowAnimationDebug; // show animation debug info static BOOL sUseImpostors; //use impostors for far away avatars static BOOL sShowFootPlane; // show foot collision plane reported by server + static BOOL sShowCollisionVolumes; // show skeletal collision volumes // KL SD static BOOL sVisibleInFirstPerson; static S32 sNumLODChangesThisFrame; static S32 sNumVisibleChatBubbles; @@ -771,7 +777,7 @@ private: LLUUID mLastTextureIndex; LLTexLayerSet* mTexLayerSet; bool mIsLoaded; - bool mIsUsed; + //bool mIsUsed; // KL SG LLVOAvatarDefines::ETextureIndex mTextureIndex; U32 mMaskTexName; // Stores pointers to the joint meshes that this baked texture deals with diff --git a/linden/indra/newview/llvoclouds.cpp b/linden/indra/newview/llvoclouds.cpp index a489f91..019b6b4 100644 --- a/linden/indra/newview/llvoclouds.cpp +++ b/linden/indra/newview/llvoclouds.cpp @@ -101,7 +101,7 @@ void LLVOClouds::setPixelAreaAndAngle(LLAgent &agent) mPixelArea = 1500*100; } -void LLVOClouds::updateTextures() +void LLVOClouds::updateTextures(LLAgent &agent) { getTEImage(0)->addTextureStats(mPixelArea); } @@ -123,7 +123,10 @@ BOOL LLVOClouds::updateGeometry(LLDrawable *drawable) return TRUE; } - dirtySpatialGroup(); + if (drawable->isVisible()) + { + dirtySpatialGroup(TRUE); + } LLFace *facep; diff --git a/linden/indra/newview/llvoclouds.h b/linden/indra/newview/llvoclouds.h index 52e5a68..f70ea5b 100644 --- a/linden/indra/newview/llvoclouds.h +++ b/linden/indra/newview/llvoclouds.h @@ -65,7 +65,7 @@ public: /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. F32 getPartSize(S32 idx); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area void updateFaceSize(S32 idx) { } diff --git a/linden/indra/newview/llvograss.cpp b/linden/indra/newview/llvograss.cpp index 08f2717..c56d676 100644 --- a/linden/indra/newview/llvograss.cpp +++ b/linden/indra/newview/llvograss.cpp @@ -331,7 +331,7 @@ void LLVOGrass::setPixelAreaAndAngle(LLAgent &agent) // BUG could speed this up by caching the relative_position and range calculations -void LLVOGrass::updateTextures() +void LLVOGrass::updateTextures(LLAgent &agent) { if (getTEImage(0)) { diff --git a/linden/indra/newview/llvograss.h b/linden/indra/newview/llvograss.h index 682fbdb..c55c59b 100644 --- a/linden/indra/newview/llvograss.h +++ b/linden/indra/newview/llvograss.h @@ -72,7 +72,7 @@ public: LLStrider& indicesp); void updateFaceSize(S32 idx) { } - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ BOOL updateLOD(); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area diff --git a/linden/indra/newview/llvoground.cpp b/linden/indra/newview/llvoground.cpp index 0ef0196..fe19e18 100644 --- a/linden/indra/newview/llvoground.cpp +++ b/linden/indra/newview/llvoground.cpp @@ -71,7 +71,7 @@ BOOL LLVOGround::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOGround::updateTextures() +void LLVOGround::updateTextures(LLAgent &agent) { } diff --git a/linden/indra/newview/llvoground.h b/linden/indra/newview/llvoground.h index b58ebae..f485bd0 100644 --- a/linden/indra/newview/llvoground.h +++ b/linden/indra/newview/llvoground.h @@ -51,7 +51,7 @@ public: // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvopartgroup.cpp b/linden/indra/newview/llvopartgroup.cpp index a0f8068..b040366 100644 --- a/linden/indra/newview/llvopartgroup.cpp +++ b/linden/indra/newview/llvopartgroup.cpp @@ -108,7 +108,7 @@ void LLVOPartGroup::setPixelAreaAndAngle(LLAgent &agent) } } -void LLVOPartGroup::updateTextures() +void LLVOPartGroup::updateTextures(LLAgent &agent) { // Texture stats for particles need to be updated in a different way... } @@ -154,6 +154,11 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) group = drawable->getSpatialGroup(); } + if (group && group->isVisible()) + { + dirtySpatialGroup(TRUE); + } + if (!num_parts) { if (group && drawable->getNumFaces()) @@ -186,13 +191,12 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable) S32 count=0; mDepth = 0.f; S32 i = 0 ; - LLVector3 camera_agent = getCameraPosition(); for (i = 0 ; i < (S32)mViewerPartGroupp->mParticles.size(); i++) { const LLViewerPart *part = mViewerPartGroupp->mParticles[i]; LLVector3 part_pos_agent(part->mPosAgent); - LLVector3 at(part_pos_agent - camera_agent); + LLVector3 at(part_pos_agent - LLViewerCamera::getInstance()->getOrigin()); F32 camera_dist_squared = at.lengthSquared(); F32 inv_camera_dist_squared; @@ -315,7 +319,7 @@ void LLVOPartGroup::getGeometry(S32 idx, up *= 0.5f*part.mScale.mV[1]; - LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis(); + const LLVector3& normal = -LLViewerCamera::getInstance()->getXAxis(); *verticesp++ = part_pos_agent + up - right; *verticesp++ = part_pos_agent - up - right; @@ -352,12 +356,12 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition() -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; mPartitionType = LLViewerRegion::PARTITION_PARTICLE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; + // mBufferUsage = GL_DYNAMIC_DRAW_ARB; // KL SD hybrid code mSlopRatio = 0.f; mLODPeriod = 1; } @@ -481,7 +485,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); - LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), buffer, fullbright); + LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), + facep->getTexture(), + buffer, fullbright); info->mExtents[0] = group->mObjectExtents[0]; info->mExtents[1] = group->mObjectExtents[1]; info->mVSize = vsize; diff --git a/linden/indra/newview/llvopartgroup.h b/linden/indra/newview/llvopartgroup.h index 18583b4..3dc3292 100644 --- a/linden/indra/newview/llvopartgroup.h +++ b/linden/indra/newview/llvopartgroup.h @@ -61,7 +61,7 @@ public: virtual U32 getPartitionType() const; /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosky.cpp b/linden/indra/newview/llvosky.cpp index d15a2dc..2200c02 100644 --- a/linden/indra/newview/llvosky.cpp +++ b/linden/indra/newview/llvosky.cpp @@ -289,7 +289,7 @@ void LLSkyTex::create(const F32 brightness) void LLSkyTex::createGLImage(S32 which) { - mImageGL[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerImageBoostLevel::OTHER); + mImageGL[which]->createGLTexture(0, mImageRaw[which]); mImageGL[which]->setAddressMode(LLTexUnit::TAM_CLAMP); } @@ -1095,10 +1095,10 @@ BOOL LLVOSky::updateSky() mLastTotalAmbient.mV[2] - mTotalAmbient.mV[2]); if ( mForceUpdate - || ((dot_lighting < LIGHT_DIRECTION_THRESHOLD) + || (((dot_lighting < LIGHT_DIRECTION_THRESHOLD) || (delta_color.length() > COLOR_CHANGE_THRESHOLD) || !mInitialized) - && !direction.isExactlyZero()) + && !direction.isExactlyZero())) { mLastLightingDirection = direction; mLastTotalAmbient = mTotalAmbient; @@ -1180,7 +1180,7 @@ BOOL LLVOSky::updateSky() return TRUE; } -void LLVOSky::updateTextures() +void LLVOSky::updateTextures(LLAgent &agent) { if (mSunTexturep) { diff --git a/linden/indra/newview/llvosky.h b/linden/indra/newview/llvosky.h index dabf5b1..5e23065 100644 --- a/linden/indra/newview/llvosky.h +++ b/linden/indra/newview/llvosky.h @@ -147,7 +147,7 @@ protected: static S32 getResolution() { return sResolution; } static S32 getCurrent() { return sCurrent; } - static S32 stepCurrent() { sCurrent++; sCurrent&=1; return sCurrent; } + static S32 stepCurrent() { return (sCurrent = ++sCurrent % 2); } static S32 getNext() { return ((sCurrent+1) % 2); } static S32 getWhich(const BOOL curr) { return curr ? sCurrent : getNext(); } @@ -492,7 +492,7 @@ public: // Graphical stuff for objects - maybe broken out into render class // later? - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvosurfacepatch.cpp b/linden/indra/newview/llvosurfacepatch.cpp index d86f758..a6fc125 100644 --- a/linden/indra/newview/llvosurfacepatch.cpp +++ b/linden/indra/newview/llvosurfacepatch.cpp @@ -134,7 +134,7 @@ void LLVOSurfacePatch::setPixelAreaAndAngle(LLAgent &agent) } -void LLVOSurfacePatch::updateTextures() +void LLVOSurfacePatch::updateTextures(LLAgent &agent) { } @@ -177,11 +177,19 @@ LLDrawable *LLVOSurfacePatch::createDrawable(LLPipeline *pipeline) } +void LLVOSurfacePatch::updateGL() +{ + if (mPatchp) + { + mPatchp->updateGL(); + } +} + BOOL LLVOSurfacePatch::updateGeometry(LLDrawable *drawable) { LLFastTimer ftm(LLFastTimer::FTM_UPDATE_TERRAIN); - dirtySpatialGroup(); + dirtySpatialGroup(TRUE); S32 min_comp, max_comp, range; min_comp = lltrunc(mPatchp->getMinComposition()); @@ -1013,12 +1021,12 @@ U32 LLVOSurfacePatch::getPartitionType() const } LLTerrainPartition::LLTerrainPartition() -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW_ARB) { mOcclusionEnabled = FALSE; - mRenderByGroup = FALSE; + //mRenderByGroup = FALSE; // KL not for SD hybrid code mInfiniteFarClip = TRUE; - mBufferUsage = GL_DYNAMIC_DRAW_ARB; + //mBufferUsage = GL_DYNAMIC_DRAW_ARB; // and here too! mDrawableType = LLPipeline::RENDER_TYPE_TERRAIN; mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } diff --git a/linden/indra/newview/llvosurfacepatch.h b/linden/indra/newview/llvosurfacepatch.h index d3b1447..aaf4d41 100644 --- a/linden/indra/newview/llvosurfacepatch.h +++ b/linden/indra/newview/llvosurfacepatch.h @@ -64,6 +64,7 @@ public: virtual U32 getPartitionType() const; /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); + /*virtual*/ void updateGL(); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); /*virtual*/ void updateFaceSize(S32 idx); @@ -74,7 +75,7 @@ public: LLStrider &texCoords1p, LLStrider &indicesp); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); diff --git a/linden/indra/newview/llvotextbubble.cpp b/linden/indra/newview/llvotextbubble.cpp index 5943f9b..de69aac 100644 --- a/linden/indra/newview/llvotextbubble.cpp +++ b/linden/indra/newview/llvotextbubble.cpp @@ -116,7 +116,7 @@ BOOL LLVOTextBubble::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) } -void LLVOTextBubble::updateTextures() +void LLVOTextBubble::updateTextures(LLAgent &agent) { // Update the image levels of all textures... diff --git a/linden/indra/newview/llvotextbubble.h b/linden/indra/newview/llvotextbubble.h index 7f84dbf..45d4df2 100644 --- a/linden/indra/newview/llvotextbubble.h +++ b/linden/indra/newview/llvotextbubble.h @@ -44,7 +44,7 @@ public: /*virtual*/ BOOL isActive() const; // Whether this object needs to do an idleUpdate. /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ BOOL updateLOD(); diff --git a/linden/indra/newview/llvotree.cpp b/linden/indra/newview/llvotree.cpp index 208086f..89d6491 100644 --- a/linden/indra/newview/llvotree.cpp +++ b/linden/indra/newview/llvotree.cpp @@ -480,7 +480,7 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent) #endif } -void LLVOTree::updateTextures() +void LLVOTree::updateTextures(LLAgent &agent) { if (mTreeImagep) { @@ -1316,9 +1316,9 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + // mRenderByGroup = FALSE; // SD hybrid mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; mSlopRatio = 0.f; diff --git a/linden/indra/newview/llvotree.h b/linden/indra/newview/llvotree.h index 855c612..7804ab3 100644 --- a/linden/indra/newview/llvotree.h +++ b/linden/indra/newview/llvotree.h @@ -69,7 +69,7 @@ public: // Graphical stuff for objects - maybe broken out into render class later? /*virtual*/ void render(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvotreenew.h b/linden/indra/newview/llvotreenew.h index 4960d90..02f6d3a 100644 --- a/linden/indra/newview/llvotreenew.h +++ b/linden/indra/newview/llvotreenew.h @@ -156,7 +156,7 @@ public: /*virtual*/ BOOL idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time); /*virtual*/ void render(LLAgent &agent); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline); /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp index 385dbe0..d4c4020 100644 --- a/linden/indra/newview/llvovolume.cpp +++ b/linden/indra/newview/llvovolume.cpp @@ -54,6 +54,7 @@ #include "llspatialpartition.h" #include "llhudmanager.h" #include "llflexibleobject.h" + #include "llsky.h" #include "lltexturefetch.h" #include "llviewercamera.h" @@ -67,6 +68,9 @@ const S32 MIN_QUIET_FRAMES_COALESCE = 30; const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; +const F32 MAX_LOD_DISTANCE = 24.f; +const S32 MAX_SCULPT_REZ = 128; + BOOL gAnimateTextures = TRUE; extern BOOL gHideSelectedObjects; @@ -91,6 +95,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re mNumFaces = 0; mLODChanged = FALSE; mSculptChanged = FALSE; + mSpotLightPriority = 0.f; } LLVOVolume::~LLVOVolume() @@ -214,7 +219,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, std::string mask; mask = gDirUtilp->getDirDelimiter() + "*.slc"; gDirUtilp->deleteFilesInDir(gDirUtilp->getExpandedFilename(LL_PATH_CACHE,""), mask); -// llerrs << "Bogus TE data in " << getID() << ", crashing!" << llendl; +// llwarns << "Bogus TE data in " << getID() << ", crashing!" << llendl; llwarns << "Bogus TE data in " << getID() << llendl; } else if (res2 & (TEM_CHANGE_TEXTURE|TEM_CHANGE_COLOR)) @@ -314,11 +319,6 @@ void LLVOVolume::animateTextures() te->getScale(&scale_s, &scale_t); } - LLVector3 scale(scale_s, scale_t, 1.f); - LLVector3 trans(off_s+0.5f, off_t+0.5f, 0.f); - LLQuaternion quat; - quat.setQuat(rot, 0, 0, -1.f); - if (!facep->mTextureMatrix) { facep->mTextureMatrix = new LLMatrix4(); @@ -326,7 +326,43 @@ void LLVOVolume::animateTextures() LLMatrix4& tex_mat = *facep->mTextureMatrix; tex_mat.setIdentity(); - tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + LLVector3 trans ; + + if(facep->isAtlasInUse()) + { + // + //if use atlas for animated texture + //apply the following transform to the animation matrix. + // + + F32 tcoord_xoffset = 0.f ; + F32 tcoord_yoffset = 0.f ; + F32 tcoord_xscale = 1.f ; + F32 tcoord_yscale = 1.f ; + if(facep->isAtlasInUse()) + { + const LLVector2* tmp = facep->getTexCoordOffset() ; + tcoord_xoffset = tmp->mV[0] ; + tcoord_yoffset = tmp->mV[1] ; + + tmp = facep->getTexCoordScale() ; + tcoord_xscale = tmp->mV[0] ; + tcoord_yscale = tmp->mV[1] ; + } + trans.set(LLVector3(tcoord_xoffset + tcoord_xscale * (off_s+0.5f), tcoord_yoffset + tcoord_yscale * (off_t+0.5f), 0.f)); + + tex_mat.translate(LLVector3(-(tcoord_xoffset + tcoord_xscale * 0.5f), -(tcoord_yoffset + tcoord_yscale * 0.5f), 0.f)); + } + else //non atlas + { + trans.set(LLVector3(off_s+0.5f, off_t+0.5f, 0.f)); + tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); + } + + LLVector3 scale(scale_s, scale_t, 1.f); + LLQuaternion quat; + quat.setQuat(rot, 0, 0, -1.f); + tex_mat.rotate(quat); LLMatrix4 mat; @@ -403,30 +439,28 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) return TRUE; } -void LLVOVolume::updateTextures() +void LLVOVolume::updateTextures(LLAgent &agent) // KL sd { const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds - if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) + if (mDrawable.notNull() && mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) { - updateTextureVirtualSize(); + if (mDrawable->isVisible()) + { + updateTextures(); + } } } -void LLVOVolume::updateTextureVirtualSize() +void LLVOVolume::updateTextures() { // Update the pixel area of all faces - if(mDrawable.isNull() || !mDrawable->isVisible()) - { - return ; - } - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_SIMPLE)) { return; } - if (LLViewerImage::sDontLoadVolumeTextures || LLAppViewer::getTextureFetch()->mDebugPause) + if (LLViewerImage::sDontLoadVolumeTextures || mDrawable.isNull()) // || !mDrawable->isVisible()) { return; } @@ -443,15 +477,14 @@ void LLVOVolume::updateTextureVirtualSize() LLFace* face = mDrawable->getFace(i); const LLTextureEntry *te = face->getTextureEntry(); LLViewerImage *imagep = face->getTexture(); - if (!imagep || !te || + if (!imagep || !te || face->mExtents[0] == face->mExtents[1]) { continue; } F32 vsize; - F32 old_size = face->getVirtualSize(); - + if (isHUDAttachment()) { F32 area = (F32) LLViewerCamera::getInstance()->getScreenPixelArea(); @@ -461,21 +494,24 @@ void LLVOVolume::updateTextureVirtualSize() } else { - vsize = face->getTextureVirtualSize(); + vsize = getTextureVirtualSize(face); } - mPixelArea = llmax(mPixelArea, face->getPixelArea()); + mPixelArea = llmax(mPixelArea, face->getPixelArea()); + + F32 old_size = face->getVirtualSize(); if (face->mTextureMatrix != NULL) { - if ((vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE) || - (vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)) + if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE || + vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE); } } face->setVirtualSize(vsize); + // imagep->addTextureStats(vsize); if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { if (vsize < min_vsize) min_vsize = vsize; @@ -503,46 +539,46 @@ void LLVOVolume::updateTextureVirtualSize() mSculptTexture = gImageList.getImage(id); if (mSculptTexture.notNull()) { + S32 lod = llmin(mLOD, 3); + F32 lodf = ((F32)(lod + 1.0f)/4.f); + F32 tex_size = lodf * MAX_SCULPT_REZ; + mSculptTexture->addTextureStats(2.f * tex_size * tex_size); mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(), (S32)LLViewerImageBoostLevel::BOOST_SCULPTED)); - mSculptTexture->setForSculpt() ; - - if(!mSculptTexture->isCachedRawImageReady()) - { - S32 lod = llmin(mLOD, 3); - F32 lodf = ((F32)(lod + 1.0f)/4.f); - F32 tex_size = lodf * LLViewerImage::sMaxSculptRez ; - mSculptTexture->addTextureStats(2.f * tex_size * tex_size, FALSE); - - //if the sculpty very close to the view point, load first - { - LLVector3 lookAt = getPositionAgent() - LLViewerCamera::getInstance()->getOrigin(); - F32 dist = lookAt.normVec() ; - F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ; - mSculptTexture->setAdditionalDecodePriority(0.8f * LLFace::calcImportanceToCamera(cos_angle_to_view_dir, dist)) ; - } - } - - S32 texture_discard = mSculptTexture->getCachedRawImageLevel(); //try to match the texture - S32 current_discard = mSculptLevel; + } - if (texture_discard >= 0 && //texture has some data available - (texture_discard < current_discard || //texture has more data than last rebuild - current_discard < 0)) //no previous rebuild - { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); - mSculptChanged = TRUE; - } + S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture + S32 current_discard = mSculptLevel; - if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) + if (texture_discard >= 0 && //texture has some data available + (texture_discard < current_discard || //texture has more data than last rebuild + current_discard < 0)) //no previous rebuild + { + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); + mSculptChanged = TRUE; + } + + if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SCULPTED)) { setDebugText(llformat("T%d C%d V%d\n%dx%d", - texture_discard, current_discard, getVolume()->getSculptLevel(), - mSculptTexture->getHeight(), mSculptTexture->getWidth())); + texture_discard, current_discard, getVolume()->getSculptLevel(), + mSculptTexture->getHeight(), mSculptTexture->getWidth())); } - } } + if (getLightTextureID().notNull()) + { + LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + LLUUID id = params->getLightTexture(); + mLightTexture = gImageList.getImage(id); + if (mLightTexture.notNull()) + { + F32 rad = getLightRadius(); + mLightTexture->addTextureStats(gPipeline.calcPixelArea(getPositionAgent(), + LLVector3(rad,rad,rad), + *LLViewerCamera::getInstance())); + } + } if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) { @@ -563,6 +599,36 @@ void LLVOVolume::updateTextureVirtualSize() } } +F32 LLVOVolume::getTextureVirtualSize(LLFace* face) +{ + //get area of circle around face + LLVector3 center = face->getPositionAgent(); + LLVector3 size = (face->mExtents[1] - face->mExtents[0]) * 0.5f; + + F32 face_area = LLPipeline::calcPixelArea(center, size, *LLViewerCamera::getInstance()); + + face->setPixelArea(face_area); + + if (face_area <= 0) + { + return 0.f; + } + + //get area of circle in texture space + LLVector2 tdim = face->mTexExtents[1] - face->mTexExtents[0]; + F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f; + if (texel_area <= 0) + { + // Probably animated, use default + texel_area = 1.f; + } + + //apply texel area to face area to get accurate ratio + face_area /= llclamp(texel_area, 1.f/64.f, 16.f); + + return face_area; +} + BOOL LLVOVolume::isActive() const { return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); @@ -699,21 +765,31 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail // sculpt replaces generate() for sculpted surfaces void LLVOVolume::sculpt() -{ +{ + U16 sculpt_height = 0; + U16 sculpt_width = 0; + S8 sculpt_components = 0; + const U8* sculpt_data = NULL; + if (mSculptTexture.notNull()) - { - U16 sculpt_height = 0; - U16 sculpt_width = 0; - S8 sculpt_components = 0; - const U8* sculpt_data = NULL; - - S32 discard_level = mSculptTexture->getCachedRawImageLevel() ; - LLImageRaw* raw_image = mSculptTexture->getCachedRawImage() ; + { + S32 discard_level; + S32 desired_discard = 0; // lower discard levels have MUCH less resolution + + discard_level = desired_discard; S32 max_discard = mSculptTexture->getMaxDiscardLevel(); if (discard_level > max_discard) discard_level = max_discard; // clamp to the best we can do + S32 best_discard = mSculptTexture->getDiscardLevel(); + if (discard_level < best_discard) + discard_level = best_discard; // clamp to what we have + + if (best_discard == -1) + discard_level = -1; // and if we have nothing, set to nothing + + S32 current_discard = getVolume()->getSculptLevel(); if(current_discard < -2) { @@ -735,17 +811,28 @@ void LLVOVolume::sculpt() if (current_discard == discard_level) // no work to do here return; - if(!raw_image) + LLPointer raw_image = new LLImageRaw(); + BOOL is_valid = mSculptTexture->readBackRaw(discard_level, raw_image, FALSE); + + sculpt_height = raw_image->getHeight(); + sculpt_width = raw_image->getWidth(); + sculpt_components = raw_image->getComponents(); + + if(is_valid) + { + is_valid = mSculptTexture->isValidForSculpt(discard_level, sculpt_width, sculpt_height, sculpt_components) ; + } + if(!is_valid) { sculpt_width = 0; sculpt_height = 0; sculpt_data = NULL ; } else - { - sculpt_height = raw_image->getHeight(); - sculpt_width = raw_image->getWidth(); - sculpt_components = raw_image->getComponents(); + { + if (raw_image->getDataSize() < sculpt_height * sculpt_width * sculpt_components) + llwarns << "Sculpt: image data size = " << raw_image->getDataSize() + << " < " << sculpt_height << " x " << sculpt_width << " x " <getData(); } @@ -777,7 +864,7 @@ BOOL LLVOVolume::calcLOD() } //update face texture sizes on lod calculation - updateTextureVirtualSize(); + // updateTextureVirtualSize(); S32 cur_detail = 0; @@ -1231,28 +1318,15 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) { - S32 retval = 0; - const LLTextureEntry *tep = getTE(te); - if (!tep) + S32 res = LLViewerObject::setTEColor(te, color); + if (res && mDrawable.notNull()) { - llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl; + //gPipeline.markTextured(mDrawable); + mDrawable->setState(LLDrawable::REBUILD_COLOR); + dirtyMesh(); + //mFaceMappingChanged = TRUE; } - else if (color != tep->getColor()) - { - if (color.mV[3] != tep->getColor().mV[3]) - { - gPipeline.markTextured(mDrawable); - } - retval = LLPrimitive::setTEColor(te, color); - if (mDrawable.notNull() && retval) - { - // These should only happen on updates which are not the initial update. - mDrawable->setState(LLDrawable::REBUILD_COLOR); - dirtyMesh(); - } - } - - return retval; + return res; } S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) @@ -1318,7 +1392,7 @@ S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump) gPipeline.markTextured(mDrawable); mFaceMappingChanged = TRUE; } - return res; + return res; } S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) @@ -1387,6 +1461,40 @@ void LLVOVolume::updateTEData() //---------------------------------------------------------------------------- +void LLVOVolume::setLightTextureID(LLUUID id) +{ + if (id.notNull()) + { + if (!hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, TRUE, true); + } + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getLightTexture() != id) + { + param_block->setLightTexture(id); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } + } + else + { + if (hasLightTexture()) + { + setParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE, FALSE, true); + } + } +} + +void LLVOVolume::setSpotLightParams(LLVector3 params) +{ + LLLightImageParams* param_block = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block && param_block->getParams() != params) + { + param_block->setParams(params); + parameterChanged(LLNetworkData::PARAMS_LIGHT_IMAGE, true); + } +} + void LLVOVolume::setIsLight(BOOL is_light) { if (is_light != getIsLight()) @@ -1513,6 +1621,77 @@ LLColor3 LLVOVolume::getLightColor() const } } +LLUUID LLVOVolume::getLightTextureID() const +{ + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getLightTexture(); + } + + return LLUUID::null; +} + + +LLVector3 LLVOVolume::getSpotLightParams() const +{ + const LLLightImageParams *param_block = (const LLLightImageParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); + if (param_block) + { + return param_block->getParams(); + } + + return LLVector3(); +} + +F32 LLVOVolume::getSpotLightPriority() const +{ + return mSpotLightPriority; +} + +void LLVOVolume::updateSpotLightPriority() +{ + LLVector3 pos = mDrawable->getPositionAgent(); + LLVector3 at(0,0,-1); + at *= getRenderRotation(); + + F32 r = getLightRadius()*0.5f; + + pos += at * r; + + at = LLViewerCamera::getInstance()->getAtAxis(); + + pos -= at * r; + + mSpotLightPriority = gPipeline.calcPixelArea(pos, LLVector3(r,r,r), *LLViewerCamera::getInstance()); + // KL needed for S19? + if (mLightTexture.notNull()) + { + mLightTexture->addTextureStats(mSpotLightPriority); + mLightTexture->setBoostLevel(LLViewerImageBoostLevel::BOOST_CLOUDS); + } +} + + +LLViewerImage* LLVOVolume::getLightTexture() +{ + LLUUID id = getLightTextureID(); + + if (id.notNull()) + { + if (mLightTexture.isNull() || id != mLightTexture->getID()) + { + mLightTexture = gImageList.getImage(id); + } + } + else + { + mLightTexture = NULL; + } + + return mLightTexture; +} + F32 LLVOVolume::getLightIntensity() const { const LLLightParams *param_block = (const LLLightParams *)getParameterEntry(LLNetworkData::PARAMS_LIGHT); @@ -1604,6 +1783,16 @@ BOOL LLVOVolume::isSculpted() const return FALSE; } +BOOL LLVOVolume::hasLightTexture() const +{ + if (getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT_IMAGE)) + { + return TRUE; + } + + return FALSE; +} + BOOL LLVOVolume::isVolumeGlobal() const { if (mVolumeImpl) @@ -2056,9 +2245,9 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition() -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, FALSE) +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW_ARB) // KL { - mLODPeriod = 16; + mLODPeriod = 32; // KL 32 in SD mDepthMask = FALSE; mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_VOLUME; @@ -2067,10 +2256,10 @@ LLVolumePartition::LLVolumePartition() } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep) -: LLSpatialBridge(drawablep, LLVOVolume::VERTEX_DATA_MASK) +: LLSpatialBridge(drawablep, TRUE, LLVOVolume::VERTEX_DATA_MASK) // KL SD { mDepthMask = FALSE; - mLODPeriod = 16; + mLODPeriod = 32; // KL 32 in SD mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; @@ -2125,7 +2314,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); - LLViewerImage* tex = facep->getTexture(); + LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD U8 glow = 0; @@ -2136,7 +2325,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (facep->mVertexBuffer.isNull()) { - llerrs << "WTF?" << llendl; + llwarns << "WTF?" << llendl; } if (idx >= 0 && @@ -2167,6 +2356,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLPointer draw_info = new LLDrawInfo(start,end,count,offset,tex, + (LLImageGL*)facep->getTexture() == tex ? facep->getTexture() : NULL, facep->mVertexBuffer, fullbright, bump); draw_info->mGroup = group; draw_info->mVSize = facep->getVirtualSize(); @@ -2254,9 +2444,11 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) LLVOVolume* vobj = drawablep->getVOVolume(); llassert_always(vobj); - vobj->updateTextureVirtualSize(); + vobj->updateTextures(); vobj->preRebuild(); + drawablep->clearState(LLDrawable::HAS_ALPHA); // KL SD + //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -2325,6 +2517,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { + drawablep->setState(LLDrawable::HAS_ALPHA); // KL SD alpha_faces.push_back(facep); } } @@ -2348,7 +2541,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } else { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + //facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2358,14 +2551,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) { //needs normal + binormal bump_faces.push_back(facep); } - else if ((te->getShiny() && LLPipeline::sRenderBump) || + else if (te->getShiny() && LLPipeline::sRenderBump || !te->getFullbright()) { //needs normal simple_faces.push_back(facep); } else { //doesn't need normal - facep->setState(LLFace::FULLBRIGHT); + // facep->setState(LLFace::FULLBRIGHT); fullbright_faces.push_back(facep); } } @@ -2413,7 +2606,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (LLPipeline::sDelayVBUpdate) { - group->setState(LLSpatialGroup::MESH_DIRTY); + group->setState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD } mFaceList.clear(); @@ -2421,7 +2614,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) { - if (group->isState(LLSpatialGroup::MESH_DIRTY)) + if (group->isState(LLSpatialGroup::MESH_DIRTY) && !group->isState(LLSpatialGroup::GEOM_DIRTY)) // KL SD { S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ; @@ -2499,7 +2692,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) } } - group->clearState(LLSpatialGroup::MESH_DIRTY); + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); // KL SD } } @@ -2524,7 +2717,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: LLSpatialGroup::buffer_map_t buffer_map; - LLViewerImage* last_tex = NULL; + LLImageGL* last_tex = NULL;// LLViewerImage* last_tex = NULL; // KL SD S32 buffer_index = 0; if (distance_sort) @@ -2536,7 +2729,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: { //pull off next face LLFace* facep = *face_iter; - LLViewerImage* tex = facep->getTexture(); + LLImageGL* tex = facep->getGLTexture(); // LLViewerImage* tex = facep->getTexture(); // KL SD if (distance_sort) { @@ -2561,7 +2754,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: ++i; while (i != faces.end() && - (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex))) + (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getGLTexture() == tex))) // KL SD getTexture { facep = *i; @@ -2644,6 +2837,11 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); + if ((mask & LLVertexBuffer::MAP_NORMAL) == 0) // KL SD + { //paranoia check to make sure GL doesn't try to read non-existant normals + fullbright = TRUE; + } + const LLTextureEntry* te = facep->getTextureEntry(); BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; @@ -2695,7 +2893,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - llassert(mask & LLVertexBuffer::MAP_NORMAL); + // llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2726,7 +2924,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: } else { - llassert(mask & LLVertexBuffer::MAP_NORMAL); + // llassert(mask & LLVertexBuffer::MAP_NORMAL); registerFace(group, facep, LLRenderPass::PASS_SIMPLE); } } @@ -2739,8 +2937,8 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std:: if (!is_alpha && !LLPipeline::sRenderDeferred) { - llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); - facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); + // llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); + facep->setPoolType(LLDrawPool::POOL_SIMPLE); // facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE); if (!force_simple && te->getBumpmap()) { @@ -2819,7 +3017,7 @@ LLHUDPartition::LLHUDPartition() mPartitionType = LLViewerRegion::PARTITION_HUD; mDrawableType = LLPipeline::RENDER_TYPE_HUD; mSlopRatio = 0.f; - mLODPeriod = 1; + mLODPeriod = 32; // KL 32 in SD } void LLHUDPartition::shift(const LLVector3 &offset) diff --git a/linden/indra/newview/llvovolume.h b/linden/indra/newview/llvovolume.h index a78aa37..4c6ad9a 100644 --- a/linden/indra/newview/llvovolume.h +++ b/linden/indra/newview/llvovolume.h @@ -130,7 +130,7 @@ public: BOOL getVolumeChanged() const { return mVolumeChanged; } - + F32 getTextureVirtualSize(LLFace* face); /*virtual*/ F32 getRadius() const { return mVObjRadius; }; const LLMatrix4& getWorldMatrix(LLXformMatrix* xform) const; @@ -158,14 +158,14 @@ public: /*virtual*/ S32 setTEBumpmap(const U8 te, const U8 bump); /*virtual*/ S32 setTEShiny(const U8 te, const U8 shiny); /*virtual*/ S32 setTEFullbright(const U8 te, const U8 fullbright); - /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); + /*virtual*/ S32 setTEBumpShinyFullbright(const U8 te, const U8 bump); // KL S19? /*virtual*/ S32 setTEMediaFlags(const U8 te, const U8 media_flags); /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEScale(const U8 te, const F32 s, const F32 t); /*virtual*/ S32 setTEScaleS(const U8 te, const F32 s); /*virtual*/ S32 setTEScaleT(const U8 te, const F32 t); /*virtual*/ S32 setTETexGen(const U8 te, const U8 texgen); - /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); + /*virtual*/ S32 setTEMediaTexGen(const U8 te, const U8 media); // KL S19 /*virtual*/ BOOL setMaterial(const U8 material); void setTexture(const S32 face); @@ -177,8 +177,8 @@ public: /*virtual*/ void updateFaceSize(S32 idx); /*virtual*/ BOOL updateLOD(); void updateRadius(); - /*virtual*/ void updateTextures(); - void updateTextureVirtualSize(); + /*virtual*/ void updateTextures(LLAgent &agent); + void updateTextures(); void updateFaceFlags(); void regenFaces(); @@ -196,9 +196,18 @@ public: void setLightRadius(F32 radius); void setLightFalloff(F32 falloff); void setLightCutoff(F32 cutoff); + void setLightTextureID(LLUUID id); + void setSpotLightParams(LLVector3 params); + BOOL getIsLight() const; LLColor3 getLightBaseColor() const; // not scaled by intensity LLColor3 getLightColor() const; // scaled by intensity + LLUUID getLightTextureID() const; + LLVector3 getSpotLightParams() const; + void updateSpotLightPriority(); + F32 getSpotLightPriority() const; + + LLViewerImage* getLightTexture(); F32 getLightIntensity() const; F32 getLightRadius() const; F32 getLightFalloff() const; @@ -208,6 +217,8 @@ public: U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; virtual BOOL isSculpted() const; + virtual BOOL hasLightTexture() const; + BOOL isVolumeGlobal() const; BOOL canBeFlexible() const; BOOL setIsFlexible(BOOL is_flexible); @@ -233,12 +244,14 @@ private: BOOL mLODChanged; S32 mSculptLevel; BOOL mSculptChanged; + F32 mSpotLightPriority; LLMatrix4 mRelativeXform; LLMatrix3 mRelativeXformInvTrans; BOOL mVolumeChanged; F32 mVObjRadius; LLVolumeInterface *mVolumeImpl; LLPointer mSculptTexture; + LLPointer mLightTexture; // statics public: diff --git a/linden/indra/newview/llvowater.cpp b/linden/indra/newview/llvowater.cpp index 5b6a949..25960de 100644 --- a/linden/indra/newview/llvowater.cpp +++ b/linden/indra/newview/llvowater.cpp @@ -101,7 +101,7 @@ void LLVOWater::setPixelAreaAndAngle(LLAgent &agent) // virtual -void LLVOWater::updateTextures() +void LLVOWater::updateTextures(LLAgent &agent) { } @@ -276,9 +276,9 @@ U32 LLVOWater::getPartitionType() const } LLWaterPartition::LLWaterPartition() -: LLSpatialPartition(0) +: LLSpatialPartition(0, FALSE, 0) { - mRenderByGroup = FALSE; + // mRenderByGroup = FALSE; // KL specified const SG branch not req here mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; mPartitionType = LLViewerRegion::PARTITION_WATER; diff --git a/linden/indra/newview/llvowater.h b/linden/indra/newview/llvowater.h index 9c33e74..cdda48f 100644 --- a/linden/indra/newview/llvowater.h +++ b/linden/indra/newview/llvowater.h @@ -68,7 +68,7 @@ public: /*virtual*/ BOOL updateGeometry(LLDrawable *drawable); /*virtual*/ void updateSpatialExtents(LLVector3& newMin, LLVector3& newMax); - /*virtual*/ void updateTextures(); + /*virtual*/ void updateTextures(LLAgent &agent); /*virtual*/ void setPixelAreaAndAngle(LLAgent &agent); // generate accurate apparent angle and area virtual U32 getPartitionType() const; diff --git a/linden/indra/newview/llwaterparammanager.cpp b/linden/indra/newview/llwaterparammanager.cpp index e01506e..8ef11be 100644 --- a/linden/indra/newview/llwaterparammanager.cpp +++ b/linden/indra/newview/llwaterparammanager.cpp @@ -407,8 +407,7 @@ void LLWaterParamManager::update(LLViewerCamera * cam) LLFloaterWater::instance()->syncMenu(); } - stop_glerror(); - + //stop_glerror(); // only do this if we're dealing with shaders if(gPipeline.canUseVertexShaders()) { diff --git a/linden/indra/newview/llwlparammanager.cpp b/linden/indra/newview/llwlparammanager.cpp index 31471d7..09f7d01 100644 --- a/linden/indra/newview/llwlparammanager.cpp +++ b/linden/indra/newview/llwlparammanager.cpp @@ -539,8 +539,7 @@ void LLWLParamManager::update(LLViewerCamera * cam) F32 camYaw = cam->getYaw(); - stop_glerror(); - + //stop_glerror(); // *TODO: potential optimization - this block may only need to be // executed some of the time. For example for water shaders only. { diff --git a/linden/indra/newview/llworld.h b/linden/indra/newview/llworld.h index 46aefd9..9abb565 100644 --- a/linden/indra/newview/llworld.h +++ b/linden/indra/newview/llworld.h @@ -2,7 +2,7 @@ * @file llworld.h * @brief Collection of viewer regions in the vacinity of the user. * - * Represents the whole world, so far as 3D functionality is conserned. + * Represents the whole world, so far as 3D functionality is concerned. * Always contains the region that the user's avatar is in along with * neighboring regions. As the user crosses region boundaries, new * regions are added to the world and distant ones are rolled up. @@ -151,7 +151,8 @@ public: public: typedef std::list region_list_t; - const region_list_t& getRegionList() const { return mActiveRegionList; } + region_list_t mActiveRegionList; // KL SD branch public not private + region_list_t& getRegionList() { return mActiveRegionList; } // Returns lists of avatar IDs and their world-space positions within a given distance of a point. // All arguments are optional. Given containers will be emptied and then filled. @@ -162,7 +163,6 @@ public: const LLVector3d& relative_to = LLVector3d(), F32 radius = FLT_MAX) const; private: - region_list_t mActiveRegionList; region_list_t mRegionList; region_list_t mVisibleRegionList; region_list_t mCulledRegionList; diff --git a/linden/indra/newview/pipeline.cpp b/linden/indra/newview/pipeline.cpp index 72da3c6..4bf53af 100644 --- a/linden/indra/newview/pipeline.cpp +++ b/linden/indra/newview/pipeline.cpp @@ -159,6 +159,8 @@ std::string gPoolNames[] = "POOL_ALPHA", }; +void drawBox(const LLVector3& c, const LLVector3& r); + U32 nhpo2(U32 v) { U32 r = 1; @@ -267,11 +269,11 @@ static const U32 gl_cube_face[] = void validate_framebuffer_object(); + void addDeferredAttachments(LLRenderTarget& target) { - target.addColorAttachment(GL_RGBA16F_ARB); //specular - target.addColorAttachment(GL_RGBA16F_ARB); //normal+z - target.addColorAttachment(GL_RGBA16F_ARB); //position + target.addColorAttachment(GL_RGBA); //specular //target.addColorAttachment(GL_RGBA16F_ARB); //specular // KL + target.addColorAttachment(GL_RGBA); //normal+z //target.addColorAttachment(GL_RGBA16F_ARB); //normal+z } LLPipeline::LLPipeline() : @@ -313,6 +315,8 @@ LLPipeline::LLPipeline() : mLightingDetail(0) { mNoiseMap = 0; + //mTrueNoiseMap = 0; // KL SD + mLightFunc = 0; // KL SD } void LLPipeline::init() @@ -362,6 +366,11 @@ void LLPipeline::init() LLViewerShaderMgr::instance()->setShaders(); stop_glerror(); + + for (U32 i = 0; i < 2; ++i) + { + mSpotLightFade[i] = 1.f; + } } LLPipeline::~LLPipeline() @@ -373,6 +382,9 @@ void LLPipeline::cleanup() { assertInitialized(); + mGroupQ1.clear() ; + mGroupQ2.clear() ; + for(pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ) { @@ -469,33 +481,69 @@ void LLPipeline::resizeScreenTexture() GLuint resX = gViewerWindow->getWindowDisplayWidth(); GLuint resY = gViewerWindow->getWindowDisplayHeight(); - U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); - if (res_mod > 1 && res_mod < resX && res_mod < resY) - { - resX /= res_mod; - resY /= res_mod; - } - allocateScreenBuffer(resX,resY); - - llinfos << "RESIZED SCREEN TEXTURE: " << resX << "x" << resY << llendl; } } void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) { + U32 samples = gSavedSettings.getU32("RenderFSAASamples"); + U32 res_mod = gSavedSettings.getU32("RenderResolutionDivisor"); + + if (res_mod > 1 && res_mod < resX && res_mod < resY) + { + resX /= res_mod; + resY /= res_mod; + } + + if (gSavedSettings.getBOOL("RenderUIBuffer")) + { + //mUIScreen.allocate(resX,resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + } + if (LLPipeline::sRenderDeferred) { //allocate deferred rendering color buffers - mDeferredScreen.allocate(resX, resY, GL_RGBA16F_ARB, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + mDeferredDepth.allocate(resX, resY, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); addDeferredAttachments(mDeferredScreen); - mScreen.allocate(resX, resY, GL_RGBA16F_ARB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); - + + // always set viewport to desired size, since allocate resets the viewport + + mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); + + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + for (U32 i = 0; i < 2; i++) { - mDeferredLight[i].allocate(resX, resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); + } + + F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); + + for (U32 i = 0; i < 4; i++) + { + mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); } + + + U32 width = nhpo2(U32(resX*scale))/2; + U32 height = width; + + for (U32 i = 4; i < 6; i++) + { + mShadow[i].allocate(width, height, 0, TRUE, FALSE); + } + + + + width = nhpo2(resX)/2; + height = nhpo2(resY)/2; + mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); } else { @@ -505,25 +553,23 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY) if (gGLManager.mHasFramebufferMultisample && samples > 1) { + mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); if (LLPipeline::sRenderDeferred) { - mSampleBuffer.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); addDeferredAttachments(mSampleBuffer); mDeferredScreen.setSampleBuffer(&mSampleBuffer); } - else - { - mSampleBuffer.allocate(resX,resY,GL_RGBA,TRUE,TRUE,LLTexUnit::TT_RECT_TEXTURE,FALSE,samples); - } mScreen.setSampleBuffer(&mSampleBuffer); + stop_glerror(); } - else if (LLPipeline::sRenderDeferred) + + if (LLPipeline::sRenderDeferred) { //share depth buffer between deferred targets mDeferredScreen.shareDepthBuffer(mScreen); - for (U32 i = 0; i < 2; i++) - { + for (U32 i = 0; i < 3; i++) + { //share stencil buffer with screen space lightmap to stencil out sky mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); } } @@ -556,17 +602,40 @@ void LLPipeline::releaseGLBuffers() mNoiseMap = 0; } +/* if (mTrueNoiseMap) + { + LLImageGL::deleteTextures(1, &mTrueNoiseMap); + mTrueNoiseMap = 0; + } +*/ + if (mLightFunc) + { + LLImageGL::deleteTextures(1, &mLightFunc); + mLightFunc = 0; + } + mWaterRef.release(); mWaterDis.release(); mScreen.release(); mSampleBuffer.releaseSampleBuffer(); mDeferredScreen.release(); + mDeferredDepth.release(); + for (U32 i = 0; i < 3; i++) + { + mDeferredLight[i].release(); + } + + mGIMap.release(); + mGIMapPost[0].release(); + mGIMapPost[1].release(); + mHighlight.release(); +// mLuminanceMap.release(); - - for (U32 i = 0; i < 4; i++) + for (U32 i = 0; i < 6; i++) // KL 6 in SD { - mSunShadow[i].release(); + mShadow[i].release(); } + for (U32 i = 0; i < 3; i++) { mGlow[i].release(); @@ -589,9 +658,13 @@ void LLPipeline::createGLBuffers() mWaterDis.allocate(res,res,GL_RGBA,TRUE,FALSE); } + mHighlight.allocate(256,256,GL_RGBA, FALSE, FALSE); stop_glerror(); + GLuint resX = gViewerWindow->getWindowDisplayWidth(); + GLuint resY = gViewerWindow->getWindowDisplayHeight(); + if (LLPipeline::sRenderGlow) { //screen space glow buffers const U32 glow_res = llmax(1, @@ -601,20 +674,13 @@ void LLPipeline::createGLBuffers() { mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); } - } - GLuint resX = gViewerWindow->getWindowDisplayWidth(); - GLuint resY = gViewerWindow->getWindowDisplayHeight(); - - allocateScreenBuffer(resX,resY); + allocateScreenBuffer(resX,resY); + } + if (sRenderDeferred) { - mSunShadow[0].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[1].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[2].allocate(1024,1024, 0, TRUE, FALSE); - mSunShadow[3].allocate(1024,1024, 0, TRUE, FALSE); - if (!mNoiseMap) { const U32 noiseRes = 128; @@ -634,7 +700,83 @@ void LLPipeline::createGLBuffers() LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB, GL_FLOAT, noise); gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - } + +/* if (!mTrueNoiseMap) + { + const U32 noiseRes = 128; + F32 noise[noiseRes*noiseRes*3]; + for (U32 i = 0; i < noiseRes*noiseRes*3; i++) + { + noise[i] = ll_frand()*2.0-1.0; + } + + LLImageGL::generateTextures(1, &mTrueNoiseMap); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mTrueNoiseMap); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGB16F_ARB, noiseRes, noiseRes, GL_RGB,GL_FLOAT, noise); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } +*/ + if (!mLightFunc) + { + U32 lightResX = gSavedSettings.getU32("RenderSpecularResX"); + U32 lightResY = gSavedSettings.getU32("RenderSpecularResY"); + U8* lg = new U8[lightResX*lightResY]; + + for (U32 y = 0; y < lightResY; ++y) + { + for (U32 x = 0; x < lightResX; ++x) + { + //spec func + F32 sa = (F32) x/(lightResX-1); + F32 spec = (F32) y/(lightResY-1); + //lg[y*lightResX+x] = (U8) (powf(sa, 128.f*spec*spec)*255); + + //F32 sp = acosf(sa)/(1.f-spec); + + sa = powf(sa, gSavedSettings.getF32("RenderSpecularExponent")); + F32 a = acosf(sa*0.25f+0.75f); + F32 m = llmax(0.5f-spec*0.5f, 0.001f); + F32 t2 = tanf(a)/m; + t2 *= t2; + + F32 c4a = (3.f+4.f*cosf(2.f*a)+cosf(4.f*a))/8.f; + F32 bd = 1.f/(4.f*m*m*c4a)*powf(F_E, -t2); + + lg[y*lightResX+x] = (U8) (llclamp(bd, 0.f, 1.f)*255); + } + } + + LLImageGL::generateTextures(1, &mLightFunc); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); + LLImageGL::setManualImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_ALPHA, lightResX, lightResY, GL_ALPHA, GL_UNSIGNED_BYTE, lg); + gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + + delete [] lg; +/* } + + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { */ + mGIMap.allocate(1024,1024,GL_RGBA, TRUE, FALSE); + addDeferredAttachments(mGIMap); + + { + LLGLDepthTest depth(GL_TRUE); + gGL.setColorMask(true, true); + for (U32 i = 0; i < 2; i++) + { + mGIMapPost[i].allocate(128,128,GL_RGB16F_ARB, FALSE, FALSE); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + mGIMapPost[i].addColorAttachment(GL_RGB16F_ARB); + + mGIMapPost[i].bindTarget(); + mGIMapPost[i].clear(); + mGIMapPost[i].flush(); + } + } + } + } //mLuminanceMap.allocate(128,128, GL_RGBA, FALSE, FALSE); } void LLPipeline::restoreGL() @@ -646,7 +788,7 @@ void LLPipeline::restoreGL() LLViewerShaderMgr::instance()->setShaders(); } - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -700,7 +842,7 @@ void LLPipeline::unloadShaders() void LLPipeline::assertInitializedDoError() { - llerrs << "LLPipeline used when uninitialized." << llendl; + llwarns << "LLPipeline used when uninitialized." << llendl; } //============================================================================ @@ -763,7 +905,7 @@ public: for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { LLDrawInfo* params = *j; - if (mTextures.find(params->mTexture) != mTextures.end()) + if (mTextures.find(params->mViewerTexture) != mTextures.end()) { group->setState(LLSpatialGroup::GEOM_DIRTY); } @@ -797,7 +939,7 @@ void LLPipeline::dirtyPoolObjectTextures(const std::set& texture } LLOctreeDirtyTexture dirty(textures); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -876,7 +1018,7 @@ LLDrawPool *LLPipeline::findPool(const U32 type, LLViewerImage *tex0) default: llassert(0); - llerrs << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; + llwarns << "Invalid Pool Type in LLPipeline::findPool() type=" << type << llendl; break; } @@ -991,7 +1133,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) #ifdef LL_RELEASE_FOR_DOWNLOAD llwarns << "Couldn't remove object from spatial group!" << llendl; #else - llerrs << "Couldn't remove object from spatial group!" << llendl; + llwarns << "Couldn't remove object from spatial group!" << llendl; #endif } } @@ -1006,6 +1148,31 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) break; } } + + { + HighlightItem item(drawablep); + mHighlightSet.erase(item); + + if (mHighlightObject == drawablep) + { + mHighlightObject = NULL; + } + } + + for (U32 i = 0; i < 2; ++i) + { + if (mShadowSpotLight[i] == drawablep) + { + mShadowSpotLight[i] = NULL; + } + + if (mTargetShadowSpotLight[i] == drawablep) + { + mTargetShadowSpotLight[i] = NULL; + } + } + + } U32 LLPipeline::addObject(LLViewerObject *vobj) @@ -1062,7 +1229,7 @@ void LLPipeline::createObject(LLViewerObject* vobj) } else { - llerrs << "Redundant drawable creation!" << llendl; + llwarns << "Redundant drawable creation!" << llendl; } llassert(drawablep); @@ -1123,7 +1290,7 @@ void LLPipeline::updateMoveDampedAsync(LLDrawable* drawablep) } if (!drawablep) { - llerrs << "updateMove called with NULL drawablep" << llendl; + llwarns << "updateMove called with NULL drawablep" << llendl; return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) @@ -1153,7 +1320,8 @@ void LLPipeline::updateMoveNormalAsync(LLDrawable* drawablep) } if (!drawablep) { - llerrs << "updateMove called with NULL drawablep" << llendl; + llwarns << "updateMove called with NULL drawablep" << llendl; + return; } if (drawablep->isState(LLDrawable::EARLY_MOVE)) { @@ -1245,7 +1413,7 @@ void LLPipeline::updateMove() { LLFastTimer ot(LLFastTimer::FTM_OCTREE_BALANCE); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1272,7 +1440,6 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera F32 dist = lookAt.length(); //ramp down distance for nearby objects - //shrink dist by dist/16. if (dist < 16.f) { dist /= 16.f; @@ -1293,7 +1460,7 @@ void LLPipeline::grabReferences(LLCullResult& result) BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera) { - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1325,7 +1492,7 @@ BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& BOOL res = TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1388,7 +1555,7 @@ void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, S32 water_cl LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1465,7 +1632,7 @@ void LLPipeline::markNotCulled(LLSpatialGroup* group, LLCamera& camera) group->setVisible(); - if (!sSkipUpdate) + if (!sSkipUpdate) // && !sShadowRender) KL? { group->updateDistance(camera); } @@ -1556,6 +1723,78 @@ BOOL LLPipeline::updateDrawableGeom(LLDrawable* drawablep, BOOL priority) return update_complete; } +void LLPipeline::updateGL() // KL SD +{ + while (!LLGLUpdate::sGLQ.empty()) + { + LLGLUpdate* glu = LLGLUpdate::sGLQ.front(); + glu->updateGL(); + glu->mInQ = FALSE; + LLGLUpdate::sGLQ.pop_front(); + } +} // KL updateGL SD + +void LLPipeline::rebuildPriorityGroups() +{ + LLTimer update_timer; + LLMemType mt(LLMemType::MTYPE_PIPELINE); + + assertInitialized(); + + // Iterate through all drawables on the priority build queue, + for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); + iter != mGroupQ1.end(); ++iter) + { + LLSpatialGroup* group = *iter; + group->rebuildGeom(); + group->clearState(LLSpatialGroup::IN_BUILD_Q1); + } + + mGroupQ1.clear(); +} + +void LLPipeline::rebuildGroups() +{ + // 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); + + S32 count = 0; + + std::sort(mGroupQ2.begin(), mGroupQ2.end(), LLSpatialGroup::CompareUpdateUrgency()); // KL + + LLSpatialGroup::sg_vector_t::iterator iter; + for (iter = mGroupQ2.begin(); + iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + + if (group->isDead()) + { + continue; + } + + group->rebuildGeom(); + + if (group->mSpatialPartition->mRenderByGroup) + { + count++; + } + + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + + if (count > min_count) + { + ++iter; + break; + } + } + + mGroupQ2.erase(mGroupQ2.begin(), iter); + + updateMovedList(mMovedBridge); +} + void LLPipeline::updateGeom(F32 max_dtime) { LLTimer update_timer; @@ -1670,6 +1909,16 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera) if (drawablep->isSpatialBridge()) { + LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; + + if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) + { + LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); + if (av->isImpostor()) + { + return; + } + } sCull->pushBridge((LLSpatialBridge*) drawablep); } else @@ -1686,7 +1935,7 @@ void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) if (!drawablep) { - //llerrs << "Sending null drawable to moved list!" << llendl; + //llwarns << "Sending null drawable to moved list!" << llendl; return; } @@ -1771,7 +2020,7 @@ void LLPipeline::shiftObjects(const LLVector3 &offset) } mShiftList.resize(0); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -1799,6 +2048,54 @@ void LLPipeline::markTextured(LLDrawable *drawablep) } } +void LLPipeline::markGLRebuild(LLGLUpdate* glu) +{ + if (glu && !glu->mInQ) + { + LLGLUpdate::sGLQ.push_back(glu); + glu->mInQ = TRUE; + } +} + +void LLPipeline::markRebuild(LLSpatialGroup* group, BOOL priority) +{ + LLMemType mt(LLMemType::MTYPE_PIPELINE); + //assert_main_thread(); + + if (group && !group->isDead() && group->mSpatialPartition) + { + if (priority) + { + if (!group->isState(LLSpatialGroup::IN_BUILD_Q1)) + { + mGroupQ1.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q1); + + if (group->isState(LLSpatialGroup::IN_BUILD_Q2)) + { + LLSpatialGroup::sg_vector_t::iterator iter = std::find(mGroupQ2.begin(), mGroupQ2.end(), group); + if (iter != mGroupQ2.end()) + { + mGroupQ2.erase(iter); + } + group->clearState(LLSpatialGroup::IN_BUILD_Q2); + } + } + } + else if (!group->isState(LLSpatialGroup::IN_BUILD_Q2 | LLSpatialGroup::IN_BUILD_Q1)) + { + //llwarns << "Non-priority updates not yet supported!" << llendl; + if (std::find(mGroupQ2.begin(), mGroupQ2.end(), group) != mGroupQ2.end()) + { + llwarns << "WTF?" << llendl; + } + mGroupQ2.push_back(group); + group->setState(LLSpatialGroup::IN_BUILD_Q2); + + } + } +} + void LLPipeline::markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag, BOOL priority) { LLMemType mt(LLMemType::MTYPE_PIPELINE); @@ -1853,12 +2150,13 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) grabReferences(result); + //if (!LLPipeline::sShadowRender) { for (LLCullResult::sg_list_t::iterator iter = sCull->beginDrawableGroups(); iter != sCull->endDrawableGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -1871,12 +2169,15 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } } + } + if (!LLPipeline::sShadowRender) + { for (LLCullResult::sg_list_t::iterator iter = sCull->beginVisibleGroups(); iter != sCull->endVisibleGroups(); ++iter) { LLSpatialGroup* group = *iter; group->checkOcclusion(); - if (sUseOcclusion && group->isState(LLSpatialGroup::OCCLUDED)) + if (sUseOcclusion > 1 && group->isState(LLSpatialGroup::OCCLUDED)) { markOccluder(group); } @@ -1888,6 +2189,7 @@ void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result) } } + if (!LLPipeline::sShadowRender) { for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { @@ -1939,7 +2241,7 @@ void LLPipeline::stateSort(LLSpatialGroup* group, LLCamera& camera) void LLPipeline::stateSort(LLSpatialBridge* bridge, LLCamera& camera) { LLMemType mt(LLMemType::MTYPE_PIPELINE); - if (!sSkipUpdate && bridge->getSpatialGroup()->changeLOD()) + if (!sSkipUpdate && !sShadowRender && bridge->getSpatialGroup()->changeLOD()) { bool force_update = false; bridge->updateDistance(camera, force_update); @@ -2001,41 +2303,46 @@ void LLPipeline::stateSort(LLDrawable* drawablep, LLCamera& camera) } } - LLSpatialGroup* group = drawablep->getSpatialGroup(); - if (!group || group->changeLOD()) + if (!sShadowRender) { - if (drawablep->isVisible() && !sSkipUpdate) + LLSpatialGroup* group = drawablep->getSpatialGroup(); + if (!group || group->changeLOD()) { - if (!drawablep->isActive()) + if (drawablep->isVisible() && !sSkipUpdate) { - bool force_update = false; - drawablep->updateDistance(camera, force_update); + if (!drawablep->isActive()) + { + drawablep->updateDistance(camera, TRUE); + } + else if (drawablep->isAvatar()) + { + drawablep->updateDistance(camera, TRUE); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() + } } - else if (drawablep->isAvatar()) - { - bool force_update = false; - drawablep->updateDistance(camera, force_update); // calls vobj->updateLOD() which calls LLVOAvatar::updateVisibility() - } } } - for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); - iter != drawablep->mFaces.end(); iter++) + if (!drawablep->getVOVolume()) { - LLFace* facep = *iter; - - if (facep->hasGeometry()) + for (LLDrawable::face_list_t::iterator iter = drawablep->mFaces.begin(); + iter != drawablep->mFaces.end(); iter++) { - if (facep->getPool()) - { - facep->getPool()->enqueue(facep); - } - else + LLFace* facep = *iter; + + if (facep->hasGeometry()) { - break; + if (facep->getPool()) + { + facep->getPool()->enqueue(facep); + } + else + { + break; + } } } } + mNumVisibleFaces += drawablep->getNumFaces(); } @@ -2201,7 +2508,7 @@ void LLPipeline::postSort(LLCamera& camera) //rebuild groups sCull->assertDrawMapsEmpty(); - LLSpatialGroup::sNoDelete = FALSE; + /*LLSpatialGroup::sNoDelete = FALSE; for (LLCullResult::sg_list_t::iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { LLSpatialGroup* group = *i; @@ -2213,8 +2520,10 @@ void LLPipeline::postSort(LLCamera& camera) group->rebuildGeom(); } - LLSpatialGroup::sNoDelete = TRUE; + LLSpatialGroup::sNoDelete = TRUE;*/ + + rebuildPriorityGroups(); const S32 bin_count = 1024*8; @@ -2240,39 +2549,51 @@ void LLPipeline::postSort(LLCamera& camera) { continue; } - + + if (group->isState(LLSpatialGroup::NEW_DRAWINFO) && group->isState(LLSpatialGroup::GEOM_DIRTY)) + { //no way this group is going to be drawable without a rebuild + group->rebuildGeom(); + } + for (LLSpatialGroup::draw_map_t::iterator j = group->mDrawMap.begin(); j != group->mDrawMap.end(); ++j) { LLSpatialGroup::drawmap_elem_t& src_vec = j->second; - + if (!hasRenderType(j->first)) + { + continue; + } + for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { sCull->pushDrawInfo(j->first, *k); } } - LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); - - if (alpha != group->mDrawMap.end()) - { //store alpha groups for sorting - LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); - if (!sSkipUpdate) - { - if (bridge) + if (hasRenderType(LLPipeline::RENDER_TYPE_PASS_ALPHA)) + { + LLSpatialGroup::draw_map_t::iterator alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA); + + if (alpha != group->mDrawMap.end()) + { //store alpha groups for sorting + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + if (!sSkipUpdate) { - LLCamera trans_camera = bridge->transformCamera(camera); - group->updateDistance(trans_camera); + if (bridge) + { + LLCamera trans_camera = bridge->transformCamera(camera); + group->updateDistance(trans_camera); + } + else + { + group->updateDistance(camera); + } } - else + + if (hasRenderType(LLDrawPool::POOL_ALPHA)) { - group->updateDistance(camera); + sCull->pushAlphaGroup(group); } } - - if (hasRenderType(LLDrawPool::POOL_ALPHA)) - { - sCull->pushAlphaGroup(group); - } } } @@ -2370,7 +2691,7 @@ void LLPipeline::postSort(LLCamera& camera) } } - LLSpatialGroup::sNoDelete = FALSE; + //LLSpatialGroup::sNoDelete = FALSE; } @@ -2431,21 +2752,118 @@ void LLPipeline::renderHighlights() LLGLEnable color_mat(GL_COLOR_MATERIAL); disableLights(); - if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) - { - gHighlightProgram.bind(); - gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); - } - - if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) - { - // Make sure the selection image gets downloaded and decoded - if (!mFaceSelectImagep) + if (!hasRenderType(LLPipeline::RENDER_TYPE_HUD) && !mHighlightSet.empty()) + { //draw blurry highlight image over screen + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + LLGLDisable test(GL_ALPHA_TEST); + + LLGLEnable stencil(GL_STENCIL_TEST); + gGL.flush(); + glStencilMask(0xFFFFFFFF); + glClearStencil(1); + glClear(GL_STENCIL_BUFFER_BIT); + + glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); + glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE); + + gGL.setColorMask(false, false); + for (std::set::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ++iter) { - // Load the select texture texture from file -- MC - mFaceSelectImagep = gImageList.getImageFromFile(IMG_FACE_SELECT.asString()+".j2c", TRUE, TRUE); /*gImageList.getImage(IMG_FACE_SELECT);*/ + renderHighlight(iter->mItem->getVObj(), 1.f); } - mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); + gGL.setColorMask(true, false); + + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); + + //gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + + gGL.pushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + gGL.pushMatrix(); + glLoadIdentity(); + + gGL.getTexUnit(0)->bind(&mHighlight); + + LLVector2 tc1; + LLVector2 tc2; + + tc1.setVec(0,0); + tc2.setVec(2,2); + + gGL.begin(LLRender::TRIANGLES); + + F32 scale = gSavedSettings.getF32("RenderHighlightBrightness"); + LLColor4 color = gSavedSettings.getColor4("RenderHighlightColor"); + F32 thickness = gSavedSettings.getF32("RenderHighlightThickness"); + + for (S32 pass = 0; pass < 2; ++pass) + { + if (pass == 0) + { + gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); + } + else + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + for (S32 i = 0; i < 8; ++i) + { + for (S32 j = 0; j < 8; ++j) + { + LLVector2 tc(i-4+0.5f, j-4+0.5f); + + F32 dist = 1.f-(tc.length()/sqrtf(32.f)); + dist *= scale/64.f; + + tc *= thickness; + tc.mV[0] = (tc.mV[0])/mHighlight.getWidth(); + tc.mV[1] = (tc.mV[1])/mHighlight.getHeight(); + + gGL.color4f(color.mV[0], + color.mV[1], + color.mV[2], + color.mV[3]*dist); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc2.mV[1]); + gGL.vertex2f(-1,3); + + gGL.texCoord2f(tc.mV[0]+tc1.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(-1,-1); + + gGL.texCoord2f(tc.mV[0]+tc2.mV[0], tc.mV[1]+tc1.mV[1]); + gGL.vertex2f(3,-1); + } + } + } + + gGL.end(); + + gGL.popMatrix(); + glMatrixMode(GL_MODELVIEW); + gGL.popMatrix(); + + //gGL.setSceneBlendType(LLRender::BT_ALPHA); + } + + if ((LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_INTERFACE) > 0)) + { + gHighlightProgram.bind(); + gHighlightProgram.vertexAttrib4f(LLViewerShaderMgr::MATERIAL_COLOR,1,1,1,0.5f); + } + + if (hasRenderDebugFeatureMask(RENDER_DEBUG_FEATURE_SELECTED)) + { + // Make sure the selection image gets downloaded and decoded + if (!mFaceSelectImagep) + { + // Load the select texture texture from file -- MC + mFaceSelectImagep = gImageList.getImageFromFile(IMG_FACE_SELECT.asString()+".j2c", TRUE, TRUE); /*gImageList.getImage(IMG_FACE_SELECT);*/ + } + mFaceSelectImagep->addTextureStats((F32)MAX_IMAGE_AREA); U32 count = mSelectedFaces.size(); for (U32 i = 0; i < count; i++) @@ -2453,7 +2871,7 @@ void LLPipeline::renderHighlights() LLFace *facep = mSelectedFaces[i]; if (!facep || facep->getDrawable()->isDead()) { - llerrs << "Bad face on selection" << llendl; + llwarns << "Bad face on selection" << llendl; return; } @@ -2526,7 +2944,7 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) { if (!verify()) { - llerrs << "Pipeline verification failed!" << llendl; + llwarns << "Pipeline verification failed!" << llendl; } } @@ -2575,6 +2993,9 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) stop_glerror(); LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); + LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDeferred"); + for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) { LLDrawPool *poolp = *iter; @@ -2586,7 +3007,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PICKING)) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderForSelect"); gObjectList.renderObjectsForSelect(camera, gViewerWindow->getVirtualWindowRect()); } else @@ -2650,7 +3070,8 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); if (depth > 3) { - llerrs << "GL matrix stack corrupted!" << llendl; + + llwarns << "GL matrix stack corrupted!" << llendl; } std::string msg = llformat("%s pass %d", gPoolNames[cur_type].c_str(), i); LLGLState::checkStates(msg); @@ -2721,20 +3142,12 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) LLVertexBuffer::unbind(); - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) + if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); - gObjectList.resetObjectBeacons(); - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); + gObjectList.resetObjectBeacons(); } LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); @@ -2758,7 +3171,6 @@ void LLPipeline::renderGeom(LLCamera& camera, BOOL forceVBOUpdate) void LLPipeline::renderGeomDeferred(LLCamera& camera) { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); LLFastTimer t(LLFastTimer::FTM_RENDER_GEOMETRY); LLFastTimer t2(LLFastTimer::FTM_POOLS); @@ -2825,15 +3237,18 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera) poolp->endDeferredPass(i); LLVertexBuffer::unbind(); - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) + if (gDebugGL || gDebugPipeline) { - llerrs << "GL matrix stack corrupted!" << llendl; + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llwarns << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); } - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } else @@ -2915,15 +3330,18 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) poolp->endPostDeferredPass(i); LLVertexBuffer::unbind(); - GLint depth; - glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); - if (depth > 3) + if (gDebugGL || gDebugPipeline) { - llerrs << "GL matrix stack corrupted!" << llendl; + GLint depth; + glGetIntegerv(GL_MODELVIEW_STACK_DEPTH, &depth); + if (depth > 3) + { + llwarns << "GL matrix stack corrupted!" << llendl; + } + LLGLState::checkStates(); + LLGLState::checkTextureChannels(); + LLGLState::checkClientArrays(); } - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - LLGLState::checkClientArrays(); } } else @@ -2959,11 +3377,6 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) LLHUDObject::renderAll(); gObjectList.resetObjectBeacons(); } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } if (occlude) { @@ -3067,7 +3480,7 @@ void LLPipeline::renderDebug() gGL.setColorMask(true, false); // Debug stuff. - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -3084,7 +3497,7 @@ void LLPipeline::renderDebug() } } - for (LLCullResult::bridge_list_t::const_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) + for (LLCullResult::bridge_list_t::iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i) { LLSpatialBridge* bridge = *i; if (!bridge->isDead() && !bridge->isState(LLSpatialGroup::OCCLUDED) && hasRenderType(bridge->mDrawableType)) @@ -3098,93 +3511,88 @@ void LLPipeline::renderDebug() if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { + LLGLEnable blend(GL_BLEND); // kl sd + LLGLDepthTest depth(TRUE, FALSE); + LLGLDisable cull(GL_CULL_FACE); // kl + gGL.color4f(1,1,1,1); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + F32 a = 0.1f; + F32 col[] = { - 1,1,0, - 0,1,1, - 1,0,1, - 1,1,1, - 1,0,0, - 0,1,0, - 0,0,1, - 0,0,0 + 1,0,0,a, + 0,1,0,a, + 0,0,1,a, + 1,0,1,a, + + 1,1,0,a, + 0,1,1,a, + 1,1,1,a, + 1,0,1,a, }; for (U32 i = 0; i < 8; i++) { - gGL.color3fv(col+i*3); - - gGL.begin(LLRender::LINES); - - LLVector3* frust = mShadowCamera[i].mAgentFrustum; - - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[1].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[2].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[3].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[0].mV); - - gGL.vertex3fv(frust[4].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[5].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[6].mV); gGL.vertex3fv(frust[7].mV); - gGL.vertex3fv(frust[7].mV); gGL.vertex3fv(frust[4].mV); - - gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); - gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); - gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); - gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + if (i > 3) + { + gGL.color4fv(col+(i-4)*4); + LLVector3* frust = mShadowCamera[i].mAgentFrustum; + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[1].mV); gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[2].mV); gGL.vertex3fv(frust[6].mV); + gGL.vertex3fv(frust[3].mV); gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[0].mV); gGL.vertex3fv(frust[4].mV); + gGL.end(); + + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[0].mV); + gGL.vertex3fv(frust[1].mV); + gGL.vertex3fv(frust[3].mV); + gGL.vertex3fv(frust[2].mV); + gGL.end(); + + gGL.begin(LLRender::TRIANGLE_STRIP); + gGL.vertex3fv(frust[4].mV); + gGL.vertex3fv(frust[5].mV); + gGL.vertex3fv(frust[7].mV); + gGL.vertex3fv(frust[6].mV); + gGL.end(); + } + + if (i < 4) { - LLVector3* ext = mShadowExtents[i]; + gGL.begin(LLRender::LINES); - LLVector3 box[] = + F32* c = col+i*4; + for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) { - LLVector3(ext[0][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[0][1], ext[0][2]), - LLVector3(ext[1][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[1][1], ext[0][2]), - LLVector3(ext[0][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[0][1], ext[1][2]), - LLVector3(ext[1][0], ext[1][1], ext[1][2]), - LLVector3(ext[0][0], ext[1][1], ext[1][2]), - }; - gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[1].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[2].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[3].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[0].mV); - - gGL.vertex3fv(box[4].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[5].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[6].mV); gGL.vertex3fv(box[7].mV); - gGL.vertex3fv(box[7].mV); gGL.vertex3fv(box[4].mV); - - gGL.vertex3fv(box[0].mV); gGL.vertex3fv(box[4].mV); - gGL.vertex3fv(box[1].mV); gGL.vertex3fv(box[5].mV); - gGL.vertex3fv(box[2].mV); gGL.vertex3fv(box[6].mV); - gGL.vertex3fv(box[3].mV); gGL.vertex3fv(box[7].mV); - } + gGL.color3fv(c); - gGL.end(); - - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); - iter != LLWorld::getInstance()->getRegionList().end(); ++iter) - { - LLViewerRegion* region = *iter; - for (U32 j = 0; j < LLViewerRegion::NUM_PARTITIONS; j++) - { - LLSpatialPartition* part = region->getSpatialPartition(j); - if (part) + for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k) { - if (hasRenderType(part->mDrawableType)) + if (j != k) { - part->renderIntersectingBBoxes(&mShadowCamera[i]); + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + gGL.vertex3fv(mShadowFrustPoints[i][k].mV); } } + + if (!mShadowFrustOrigin[i].isExactlyZero()) + { + gGL.vertex3fv(mShadowFrustPoints[i][j].mV); + gGL.color4f(1,1,1,1); + gGL.vertex3fv(mShadowFrustOrigin[i].mV); + } } + gGL.end(); } } } @@ -3222,6 +3630,55 @@ void LLPipeline::renderDebug() } } + if (mRenderDebugMask & LLPipeline::RENDER_DEBUG_BUILD_QUEUE) + { + U32 count = 0; + U32 size = mBuildQ2.size(); + LLColor4 col; + + LLGLEnable blend(GL_BLEND); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); + + for (LLSpatialGroup::sg_vector_t::iterator iter = mGroupQ2.begin(); iter != mGroupQ2.end(); ++iter) + { + LLSpatialGroup* group = *iter; + if (group->isDead()) + { + continue; + } + + LLSpatialBridge* bridge = group->mSpatialPartition->asBridge(); + + if (bridge && (!bridge->mDrawable || bridge->mDrawable->isDead())) + { + continue; + } + + if (bridge) + { + gGL.pushMatrix(); + glMultMatrixf((F32*)bridge->mDrawable->getRenderMatrix().mMatrix); + } + + F32 alpha = (F32) (size-count)/size; + + + LLVector2 c(1.f-alpha, alpha); + c.normVec(); + + + ++count; + col.set(c.mV[0], c.mV[1], 0, alpha*0.5f+0.1f); + group->drawObjectBox(col); + + if (bridge) + { + gGL.popMatrix(); + } + } + } + gGL.flush(); } @@ -4650,7 +5107,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, sPickAvatar = FALSE; //LLToolMgr::getInstance()->inBuildMode() ? FALSE : TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4707,7 +5164,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector3& start, //check against avatars sPickAvatar = TRUE; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4784,7 +5241,7 @@ LLViewerObject* LLPipeline::lineSegmentIntersectInHUD(const LLVector3& start, co { LLDrawable* drawable = NULL; - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4847,7 +5304,7 @@ void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); - for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); + for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) { LLViewerRegion* region = *iter; @@ -4958,18 +5415,18 @@ void validate_framebuffer_object() break; case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Dimensions." << llendl; + llwarns << "Framebuffer Incomplete Dimensions." << llendl; break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: // frame buffer not OK: probably means unsupported depth buffer format - llerrs << "Framebuffer Incomplete Attachment." << llendl; + llwarns << "Framebuffer Incomplete Attachment." << llendl; break; case GL_FRAMEBUFFER_UNSUPPORTED_EXT: /* choose different formats */ - llerrs << "Framebuffer unsupported." << llendl; + llwarns << "Framebuffer unsupported." << llendl; break; default: - llerrs << "Unknown framebuffer status." << llendl; + llwarns << "Unknown framebuffer status." << llendl; break; } } @@ -5287,46 +5744,202 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) } -void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) +void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post) //, U32 noise_map) { +/* if (noise_map == 0xFFFFFFFF) + { + noise_map = mNoiseMap; + } +*/ + LLFastTimer ftm(LLFastTimer::FTM_TEMP3); + LLGLState::checkTextureChannels(); + shader.bind(); S32 channel = 0; channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DIFFUSE, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(0,channel); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { mDeferredScreen.bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } - channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); - if (channel > -1) + if (gi_source) { - mDeferredScreen.bindTexture(3, channel); + BOOL has_gi = FALSE; + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + gi_source->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(2, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(1, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + if (channel > -1) + { + has_gi = TRUE; + last_gi_post->bindTexture(3, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + if (channel > -1) + { + has_gi = TRUE; + gGL.getTexUnit(channel)->bind(gi_source, TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + stop_glerror(); + + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + glTexParameteri(LLTexUnit::getInternalType(mGIMap.getUsage()), GL_DEPTH_TEXTURE_MODE_ARB, GL_ALPHA); + + stop_glerror(); + } + + if (has_gi) + { + U32 gi_samples = llclamp(gSavedSettings.getU32("RenderGISamples"), (U32) 1, (U32) 8); + + F32 range_x = llmin(mGIRange.mV[0], 1.f); + F32 range_y = llmin(mGIRange.mV[1], 1.f); + + LLVector2 scale(range_x,range_y); + + LLVector2 kern[25]; + + for (S32 i = 0; i < 5; ++i) + { + for (S32 j = 0; j < 5; ++j) + { + S32 idx = i*5+j; + kern[idx].mV[0] = (i-2)*0.5f; + kern[idx].mV[1] = (j-2)*0.5f; + kern[idx].scaleVec(scale); + } + } + + F32 gi_radius = mGILightRadius; //gSavedSettings.getF32("RenderGILightRadius"); + + shader.uniform2f("gi_scale", scale.mV[0], scale.mV[1]); + shader.uniform2fv("gi_kern", 25, (F32*) kern); + shader.uniformMatrix4fv("gi_mat", 1, FALSE, mGIMatrix.m); + shader.uniformMatrix4fv("gi_mat_proj", 1, FALSE, mGIMatrixProj.m); + shader.uniformMatrix4fv("gi_inv_proj", 1, FALSE, mGIInvProj.m); + shader.uniformMatrix4fv("gi_norm_mat", 1, FALSE, mGINormalMatrix.m); + shader.uniform1f("gi_radius", gi_radius); + shader.uniform1i("gi_samples", (GLint) gSavedSettings.getU32("RenderGISamples")); + shader.uniform1f("gi_intensity", gSavedSettings.getF32("RenderGIIntensity")/(gi_samples*gi_samples)); + shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); + shader.uniform3fv("gi_spec", 1, gSavedSettings.getVector3("RenderGISpecularCurve").mV); + shader.uniform1f("gi_direction_weight", gSavedSettings.getF32("RenderGIDirectionWeight")); + shader.uniform1f("gi_light_offset", gSavedSettings.getF32("RenderGILightOffset")); + shader.uniform1f("gi_blend", gFrameIntervalSeconds); + } } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); if (channel > -1) { - gGL.getTexUnit(channel)->bind(&mDeferredScreen, TRUE); + 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); + + stop_glerror(); + + glh::matrix4f projection = glh_get_current_projection(); + glh::matrix4f inv_proj = projection.inverse(); + + shader.uniformMatrix4fv("inv_proj", 1, FALSE, inv_proj.m); + shader.uniform4f("viewport", (F32) gGLViewport[0], + (F32) gGLViewport[1], + (F32) gGLViewport[2], + (F32) gGLViewport[3]); } channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_NOISE); if (channel > -1) { - gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mNoiseMap); // was noise_map KL + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLightFunc); } stop_glerror(); @@ -5335,19 +5948,68 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) if (channel > -1) { mDeferredLight[light_index].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + if (channel > -1) + { + gGL.getTexUnit(channel)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + gi_source->bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[1].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); + } + + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + if (channel > -1) + { + mDeferredLight[2].bindTexture(0, channel); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_POINT); } + stop_glerror(); for (U32 i = 0; i < 4; i++) { + channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE); + stop_glerror(); + if (channel > -1) + { + stop_glerror(); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); + gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); + stop_glerror(); + + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL); + stop_glerror(); + } + } + + for (U32 i = 4; i < 6; i++) + { channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i); stop_glerror(); if (channel > -1) { stop_glerror(); - gGL.getTexUnit(channel)->bind(&mSunShadow[i], TRUE); + gGL.getTexUnit(channel)->bind(&mShadow[i], TRUE); gGL.getTexUnit(channel)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR); + gGL.getTexUnit(channel)->setTextureAddressMode(LLTexUnit::TAM_CLAMP); stop_glerror(); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB); @@ -5358,17 +6020,19 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) stop_glerror(); - F32 mat[64]; + F32 mat[16*6]; for (U32 i = 0; i < 16; i++) { mat[i] = mSunShadowMatrix[0].m[i]; mat[i+16] = mSunShadowMatrix[1].m[i]; mat[i+32] = mSunShadowMatrix[2].m[i]; mat[i+48] = mSunShadowMatrix[3].m[i]; + mat[i+64] = mSunShadowMatrix[4].m[i]; + mat[i+80] = mSunShadowMatrix[5].m[i]; } - shader.uniformMatrix4fv("shadow_matrix[0]", 4, FALSE, mat); - shader.uniformMatrix4fv("shadow_matrix", 4, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix[0]", 6, FALSE, mat); + shader.uniformMatrix4fv("shadow_matrix", 6, FALSE, mat); stop_glerror(); @@ -5417,8 +6081,23 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index) shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); + shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")); + shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")); +/* shader.uniform3fv("gi_quad", 1, gSavedSettings.getVector3("RenderGIColorCurve").mV); + shader.uniform3fv("lum_quad", 1, gSavedSettings.getVector3("RenderLuminanceColorCurve").mV); + shader.uniform3fv("gi_lum_quad", 1, gSavedSettings.getVector3("RenderGILuminanceColorCurve").mV); + shader.uniform3fv("sun_lum_quad", 1, gSavedSettings.getVector3("RenderSunLuminanceColorCurve").mV); + shader.uniform1f("lum_lod", gSavedSettings.getF32("RenderLuminanceDetail")); + shader.uniform1f("gi_range", gSavedSettings.getF32("RenderGIRange")); + + if (shader.getUniformLocation("norm_mat") >= 0) + { + glh::matrix4f norm_mat = glh_get_current_modelview().inverse().transpose(); + shader.uniformMatrix4fv("norm_mat", 1, FALSE, norm_mat.m); + } */ } +// KL The Deffered Pipeline begins here! void LLPipeline::renderDeferredLighting() { if (!sCull) @@ -5426,6 +6105,12 @@ void LLPipeline::renderDeferredLighting() return; } + { + LLGLDepthTest depth(GL_TRUE); + mDeferredDepth.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), + 0, 0, mDeferredDepth.getWidth(), mDeferredDepth.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } + LLGLEnable multisample(GL_MULTISAMPLE_ARB); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) @@ -5439,16 +6124,10 @@ void LLPipeline::renderDeferredLighting() glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); gGL.setColorMask(true, true); - - mDeferredLight[0].bindTarget(); - - //mDeferredLight[0].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); //draw a cube around every light LLVertexBuffer::unbind(); - glBlendFunc(GL_ONE, GL_ONE); LLGLEnable cull(GL_CULL_FACE); LLGLEnable blend(GL_BLEND); @@ -5460,126 +6139,271 @@ void LLPipeline::renderDeferredLighting() -1,-3, 3,1, }; - - bindDeferredShader(gDeferredSunProgram); - - glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); - - const U32 slice = 32; - F32 offset[slice*3]; - for (U32 i = 0; i < 4; i++) + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); + //Set mSunDir KL This makes sense to have it here. Still calculated EVEN if Deferred Sun is FALSE! { - for (U32 j = 0; j < 8; j++) - { - glh::vec3f v; - v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); - v.normalize(); - inv_trans.mult_matrix_vec(v); - v.normalize(); - offset[(i*8+j)*3+0] = v.v[0]; - offset[(i*8+j)*3+1] = v.v[2]; - offset[(i*8+j)*3+2] = v.v[1]; - } + setupHWLights(NULL); //to set mSunDir; + LLVector4 dir(mSunDir, 0.f); + glh::vec4f tc(dir.mV); + mat.mult_matrix_vec(tc); + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); } - gDeferredSunProgram.uniform3fv("offset", slice, offset); - gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); - - setupHWLights(NULL); //to set mSunDir; - - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + if (gSavedSettings.getBOOL("RenderDeferredShadow")) + { + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - LLVector4 dir(mSunDir, 0.f); + mDeferredLight[0].bindTarget(); +// KL Bind to 0 next section Deferred Sun ! + if (gSavedSettings.getBOOL("RenderDeferredSun")) + { //paint shadow/SSAO light map (direct lighting lightmap) + bindDeferredShader(gDeferredSunProgram, 0); - glh::vec4f tc(dir.mV); - mat.mult_matrix_vec(tc); - glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0); - glColor3f(1,1,1); + glClearColor(1,1,1,1); + mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); - glVertexPointer(2, GL_FLOAT, 0, vert); + glh::matrix4f inv_trans = glh_get_current_modelview().inverse().transpose(); + + const U32 slice = 32; + F32 offset[slice*3]; + for (U32 i = 0; i < 4; i++) + { + for (U32 j = 0; j < 8; j++) + { + glh::vec3f v; + v.set_value(sinf(6.284f/8*j), cosf(6.284f/8*j), -(F32) i); + v.normalize(); + inv_trans.mult_matrix_vec(v); + v.normalize(); + offset[(i*8+j)*3+0] = v.v[0]; + offset[(i*8+j)*3+1] = v.v[2]; + offset[(i*8+j)*3+2] = v.v[1]; + } + } + + gDeferredSunProgram.uniform3fv("offset", slice, offset); + gDeferredSunProgram.uniform2f("screenRes", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + unbindDeferredShader(gDeferredSunProgram); + } + else { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); + mDeferredLight[0].clear(); } - - unbindDeferredShader(gDeferredSunProgram); - mDeferredLight[0].flush(); + mDeferredLight[0].flush(); + mDeferredLight[1].bindTarget(); + } +// KL Bind to 1 next section GI +/* if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + { //get luminance map from previous frame's light map + LLGLEnable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); - //blur lightmap - mDeferredLight[1].bindTarget(); + //static F32 fade = 1.f; - //mDeferredLight[1].copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), - // 0, 0, mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - - bindDeferredShader(gDeferredBlurLightProgram); + F32 fade = gSavedSettings.getF32("RenderLuminanceFade"); + { + gGL.setSceneBlendType(LLRender::BT_ALPHA); + gLuminanceGatherProgram.bind(); + gLuminanceGatherProgram.uniform2f("screen_res", mDeferredLight[0].getWidth(), mDeferredLight[0].getHeight()); + gLuminanceGatherProgram.uniform1f("fade", llclamp(fade, 0.f, 1.f)); + mLuminanceMap.bindTarget(); + gGL.getTexUnit(0)->bind(&mDeferredLight[0]); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + gLuminanceGatherProgram.unbind(); + mLuminanceMap.flush(); + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mLuminanceMap.getTexture(), true); + gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_TRILINEAR); + glGenerateMipmapEXT(GL_TEXTURE_2D); + } - LLVector3 gauss[32]; // xweight, yweight, offset + } - LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); - U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; - F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + { //paint noisy GI map (bounce lighting lightmap) + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable test(GL_ALPHA_TEST); - // sample symmetrically with the middle sample falling exactly on 0.0 - F32 x = -(kern_length/2.0f) + 0.5f; + mGIMapPost[0].bindTarget(); - for (U32 i = 0; i < kern_length; i++) - { - gauss[i].mV[0] = llgaussian(x, go.mV[0]); - gauss[i].mV[1] = llgaussian(x, go.mV[1]); - gauss[i].mV[2] = x; - x += 1.f; - } - /* swap the x=0 position to the start of gauss[] so we can - treat it specially as an optimization. */ - LLVector3 swap; - swap = gauss[kern_length/2]; - gauss[kern_length/2] = gauss[0]; - gauss[0] = swap; - llassert(gauss[0].mV[2] == 0.0f); + bindDeferredShader(gDeferredGIProgram, 0, &mGIMap, 0);//, mTrueNoiseMap); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + unbindDeferredShader(gDeferredGIProgram); + mGIMapPost[0].flush(); - gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); - stop_glerror(); - } - - mDeferredLight[1].flush(); - unbindDeferredShader(gDeferredBlurLightProgram); + } - bindDeferredShader(gDeferredBlurLightProgram, 1); - mDeferredLight[0].bindTarget(); + U32 pass_count = 0; + if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) + { + pass_count = llclamp(gSavedSettings.getU32("RenderGIBlurPasses"), (U32) 1, (U32) 128); + } - gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); - gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); - gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); - gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + for (U32 i = 0; i < pass_count; ++i) + { //gather/soften indirect lighting map + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[0], NULL); //, mTrueNoiseMap); - { - LLGLDisable blend(GL_BLEND); - LLGLDepthTest depth(GL_FALSE); - stop_glerror(); - glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - stop_glerror(); - } + LLVector2 gauss[32]; // xweight, yweight, offset + + F32 sc = 1.f; + + F32 go = gSavedSettings.getF32("RenderGIGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderGIBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderGIBlurSize")*sc; + F32 dist_factor = gSavedSettings.getF32("RenderGIBlurDistFactor"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go); + gauss[i].mV[1] = x; + x += 1.f; + } + // swap the x=0 position to the start of gauss[] so we can + // treat it specially as an optimization. + LLVector2 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + gDeferredPostGIProgram.uniform2f("delta", 1.f, 0.f); + gDeferredPostGIProgram.uniform1f("dist_factor", dist_factor); + gDeferredPostGIProgram.uniform2fv("kern[0]", kern_length, gauss[0].mV); + gDeferredPostGIProgram.uniform2fv("kern", kern_length, gauss[0].mV); + gDeferredPostGIProgram.uniform1i("kern_length", kern_length); + gDeferredPostGIProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + gDeferredPostGIProgram.uniform3fv("blur_quad", 1, gSavedSettings.getVector3("RenderGIBlurColorCurve").mV); + + mGIMapPost[1].bindTarget(); + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mGIMapPost[1].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + + bindDeferredShader(gDeferredPostGIProgram, 0, &mGIMapPost[1], NULL);//, mTrueNoiseMap); + mGIMapPost[0].bindTarget(); + + gDeferredPostGIProgram.uniform2f("delta", 0.f, 1.f); + gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); + gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); + gDeferredBlurLightProgram.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + stop_glerror(); + } + mGIMapPost[0].flush(); + unbindDeferredShader(gDeferredPostGIProgram); + } + } */ + + if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) + { //soften direct lighting lightmap + //blur lightmap + mDeferredLight[1].bindTarget(); + + glClearColor(1,1,1,1); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + glClearColor(0,0,0,0); + + bindDeferredShader(gDeferredBlurLightProgram); + + LLVector3 gauss[32]; // xweight, yweight, offset + + LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); + U32 kern_length = llclamp(gSavedSettings.getU32("RenderShadowBlurSamples"), (U32) 1, (U32) 16)*2 - 1; + F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); + F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); + + // sample symmetrically with the middle sample falling exactly on 0.0 + F32 x = -(kern_length/2.0f) + 0.5f; + + for (U32 i = 0; i < kern_length; i++) + { + gauss[i].mV[0] = llgaussian(x, go.mV[0]); + gauss[i].mV[1] = llgaussian(x, go.mV[1]); + gauss[i].mV[2] = x; + x += 1.f; + } + /* swap the x=0 position to the start of gauss[] so we can + treat it specially as an optimization. */ + LLVector3 swap; + swap = gauss[kern_length/2]; + gauss[kern_length/2] = gauss[0]; + gauss[0] = swap; + llassert(gauss[0].mV[2] == 0.0f); + + 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.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + stop_glerror(); + } + + mDeferredLight[1].flush(); + unbindDeferredShader(gDeferredBlurLightProgram); + + bindDeferredShader(gDeferredBlurLightProgram, 1); + mDeferredLight[0].bindTarget(); + + gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.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.uniform1i("kern_length", kern_length); + gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); + + { + LLGLDisable blend(GL_BLEND); + LLGLDepthTest depth(GL_FALSE); + stop_glerror(); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); // KL 4? + stop_glerror(); + } mDeferredLight[0].flush(); unbindDeferredShader(gDeferredBlurLightProgram); + } stop_glerror(); glPopMatrix(); @@ -5588,15 +6412,26 @@ void LLPipeline::renderDeferredLighting() stop_glerror(); glPopMatrix(); stop_glerror(); +// } //copy depth and stencil from deferred screen //mScreen.copyContents(mDeferredScreen, 0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight(), // 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); - mScreen.bindTarget(); - mScreen.clear(GL_COLOR_BUFFER_BIT); - - bindDeferredShader(gDeferredSoftenProgram); +/* if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + mDeferredLight[1].bindTarget(); + mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); + } + else + { */ + mScreen.bindTarget(); + mScreen.clear(GL_COLOR_BUFFER_BIT); +// } + + if (gSavedSettings.getBOOL("RenderDeferredAtmospheric")) + { //apply sunlight contribution + bindDeferredShader(gDeferredSoftenProgram, 0, &mGIMapPost[0]); // may not be using GI but still need this KL { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); @@ -5619,130 +6454,330 @@ void LLPipeline::renderDeferredLighting() } unbindDeferredShader(gDeferredSoftenProgram); + } +// KL this code is a tad buggered atm it obliterates local lights...... +/* { //render sky/water/hair/skirts + LLGLDisable blend(GL_BLEND); + LLGLDisable stencil(GL_STENCIL_TEST); + gGL.setSceneBlendType(LLRender::BT_ALPHA); - bindDeferredShader(gDeferredLightProgram); - - std::list fullscreen_lights; - std::list light_colors; + U32 render_mask = mRenderTypeMask; + mRenderTypeMask = mRenderTypeMask & + ((1 << LLPipeline::RENDER_TYPE_SKY) | + (1 << LLPipeline::RENDER_TYPE_CLOUDS) | + (1 << LLPipeline::RENDER_TYPE_WL_SKY) | + (1 << LLPipeline::RENDER_TYPE_AVATAR) | + (1 << LLPipeline::RENDER_TYPE_WATER)); + + renderGeomPostDeferred(*LLViewerCamera::getInstance()); + mRenderTypeMask = render_mask; + } */ - F32 v[24]; - glVertexPointer(3, GL_FLOAT, 0, v); + BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); + BOOL render_fullscreen = gSavedSettings.getBOOL("RenderDeferredFullscreenLights"); + +/* + if (gSavedSettings.getBOOL("RenderDeferredGI")) { - LLGLDepthTest depth(GL_TRUE, GL_FALSE); - for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) + mDeferredLight[1].flush(); + mDeferredLight[2].bindTarget(); + mDeferredLight[2].clear(GL_COLOR_BUFFER_BIT); + } +*/ + if (render_local || render_fullscreen) + { + gGL.setSceneBlendType(LLRender::BT_ADD); + std::list fullscreen_lights; + LLDrawable::drawable_list_t spot_lights; + LLDrawable::drawable_list_t fullscreen_spot_lights; + + for (U32 i = 0; i < 2; i++) { - LLDrawable* drawablep = *iter; - - LLVOVolume* volume = drawablep->getVOVolume(); - if (!volume) + mTargetShadowSpotLight[i] = NULL; + } + + std::list light_colors; + + F32 v[24]; + glVertexPointer(3, GL_FLOAT, 0, v); + BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); + + { + bindDeferredShader(gDeferredLightProgram); + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + for (LLDrawable::drawable_set_t::iterator iter = mLights.begin(); iter != mLights.end(); ++iter) { - continue; + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + if (!volume) + { + continue; + } + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + if (col.magVecSquared() < 0.001f) + { + continue; + } + + if (s <= 0.001f) + { + continue; + } + + if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + { + continue; + } + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 + + if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || + LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) + { //draw box if camera is outside box + if (render_local) + { + if (volume->getLightTexture()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + spot_lights.push_back(drawablep); + continue; + } + + 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(LLViewerCamera::getInstance(), center)); + } + } + else if (render_fullscreen) + { + if (volume->getLightTexture()) + { + drawablep->getVOVolume()->updateSpotLightPriority(); + fullscreen_spot_lights.push_back(drawablep); + continue; + } + + fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); + light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + } } + unbindDeferredShader(gDeferredLightProgram); + } - LLVector3 center = drawablep->getPositionAgent(); - F32* c = center.mV; - F32 s = volume->getLightRadius()*1.5f; + if (!spot_lights.empty()) + { + LLGLDepthTest depth(GL_TRUE, GL_FALSE); + bindDeferredShader(gDeferredSpotLightProgram); - if (LLViewerCamera::getInstance()->AABBInFrustumNoFarClip(center, LLVector3(s,s,s)) == 0) + gDeferredSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = spot_lights.begin(); iter != spot_lights.end(); ++iter) { - continue; - } + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + //vertex positions are encoded so the 3 bits of their vertex index + //correspond to their axis facing, with bit position 3,2,1 matching + //axis facing x,y,z, bit set meaning positive facing, bit clear + //meaning negative facing + v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 + v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 + v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 + v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 + + v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 + v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 + v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 + v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - sVisibleLightCount++; - glh::vec3f tc(c); - mat.mult_matrix_vec(tc); - - LLColor3 col = volume->getLightColor(); - col *= volume->getLightIntensity(); - - //vertex positions are encoded so the 3 bits of their vertex index - //correspond to their axis facing, with bit position 3,2,1 matching - //axis facing x,y,z, bit set meaning positive facing, bit clear - //meaning negative facing - v[0] = c[0]-s; v[1] = c[1]-s; v[2] = c[2]-s; // 0 - 0000 - v[3] = c[0]-s; v[4] = c[1]-s; v[5] = c[2]+s; // 1 - 0001 - v[6] = c[0]-s; v[7] = c[1]+s; v[8] = c[2]-s; // 2 - 0010 - v[9] = c[0]-s; v[10] = c[1]+s; v[11] = c[2]+s; // 3 - 0011 - - v[12] = c[0]+s; v[13] = c[1]-s; v[14] = c[2]-s; // 4 - 0100 - v[15] = c[0]+s; v[16] = c[1]-s; v[17] = c[2]+s; // 5 - 0101 - v[18] = c[0]+s; v[19] = c[1]+s; v[20] = c[2]-s; // 6 - 0110 - v[21] = c[0]+s; v[22] = c[1]+s; v[23] = c[2]+s; // 7 - 0111 - - if (LLViewerCamera::getInstance()->getOrigin().mV[0] > c[0] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[0] < c[0] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] > c[1] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[1] < c[1] - s - 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] > c[2] + s + 0.2f || - LLViewerCamera::getInstance()->getOrigin().mV[2] < c[2] - s - 0.2f) - { //draw box if camera is outside box 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(LLViewerCamera::getInstance(), center)); - } - else - { - fullscreen_lights.push_back(LLVector4(tc.v[0], tc.v[1], tc.v[2], s*s)); - light_colors.push_back(LLVector4(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f)); + GL_UNSIGNED_BYTE, get_box_fan_indices(LLViewerCamera::getInstance(), center)); } + gDeferredSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredSpotLightProgram); } - } - unbindDeferredShader(gDeferredLightProgram); + { + bindDeferredShader(gDeferredMultiLightProgram); + + LLGLDepthTest depth(GL_FALSE); - if (!fullscreen_lights.empty()) - { - bindDeferredShader(gDeferredMultiLightProgram); - LLGLDepthTest depth(GL_FALSE); + //full screen blit + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); - //full screen blit - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); + U32 count = 0; - U32 count = 0; + const U32 max_count = 8; // KL poss 16? + LLVector4 light[max_count]; + LLVector4 col[max_count]; - LLVector4 light[16]; - LLVector4 col[16]; + glVertexPointer(2, GL_FLOAT, 0, vert); - glVertexPointer(2, GL_FLOAT, 0, vert); + F32 far_z = 0.f; - while (!fullscreen_lights.empty()) - { - light[count] = fullscreen_lights.front(); - fullscreen_lights.pop_front(); - col[count] = light_colors.front(); - light_colors.pop_front(); + while (!fullscreen_lights.empty()) + { + light[count] = fullscreen_lights.front(); + fullscreen_lights.pop_front(); + col[count] = light_colors.front(); + light_colors.pop_front(); - count++; - if (count == 16 || fullscreen_lights.empty()) + far_z = llmin(light[count].mV[2]-sqrtf(light[count].mV[3]), far_z); + + count++; + if (count == max_count || fullscreen_lights.empty()) + { + gDeferredMultiLightProgram.uniform1i("light_count", count); + gDeferredMultiLightProgram.uniform4fv("light[0]", count, (GLfloat*) light); + gDeferredMultiLightProgram.uniform4fv("light", count, (GLfloat*) light); + gDeferredMultiLightProgram.uniform4fv("light_col[0]", count, (GLfloat*) col); + gDeferredMultiLightProgram.uniform4fv("light_col", count, (GLfloat*) col); + gDeferredMultiLightProgram.uniform1f("far_z", far_z); + far_z = 0.f; + count = 0; + glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); + } + } + + unbindDeferredShader(gDeferredMultiLightProgram); + + bindDeferredShader(gDeferredMultiSpotLightProgram); + + gDeferredMultiSpotLightProgram.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { - 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); - count = 0; + LLDrawable* drawablep = *iter; + + LLVOVolume* volume = drawablep->getVOVolume(); + + LLVector3 center = drawablep->getPositionAgent(); + F32* c = center.mV; + F32 s = volume->getLightRadius()*1.5f; + + sVisibleLightCount++; + + glh::vec3f tc(c); + mat.mult_matrix_vec(tc); + + setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); + + LLColor3 col = volume->getLightColor(); + col *= volume->getLightIntensity(); + + glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], s*s); + glColor4f(col.mV[0], col.mV[1], col.mV[2], volume->getLightFalloff()*0.5f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); } - } - - - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - unbindDeferredShader(gDeferredMultiLightProgram); + gDeferredMultiSpotLightProgram.disableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + unbindDeferredShader(gDeferredMultiSpotLightProgram); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } } + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + gGL.setColorMask(true, true); +/* + if (gSavedSettings.getBOOL("RenderDeferredGI")) + { + mDeferredLight[2].flush(); + mScreen.bindTarget(); + mScreen.clear(GL_COLOR_BUFFER_BIT); + + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + { //mix various light maps (local, sun, gi) + LLGLDisable blend(GL_BLEND); + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + LLGLDisable stencil(GL_STENCIL_TEST); + + gViewerWindow->setupViewport(); + + bindDeferredShader(gDeferredPostProgram, 0, &mGIMapPost[0]); + + gDeferredPostProgram.bind(); + + LLVertexBuffer::unbind(); + + glVertexPointer(2, GL_FLOAT, 0, vert); + glColor3f(1,1,1); - { //render non-deferred geometry + glPushMatrix(); + glLoadIdentity(); + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + + glDrawArrays(GL_TRIANGLES, 0, 3); + + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + + unbindDeferredShader(gDeferredPostProgram); + } + } +*/ + { //render non-deferred geometry (alpha, fullbright, glow) KL issues with render pipeline merge needs work.. here LLGLDisable blend(GL_BLEND); LLGLDisable stencil(GL_STENCIL_TEST); - + gGL.setSceneBlendType(LLRender::BT_ALPHA); U32 render_mask = mRenderTypeMask; mRenderTypeMask = mRenderTypeMask & ((1 << LLPipeline::RENDER_TYPE_SKY) | @@ -5754,18 +6789,161 @@ void LLPipeline::renderDeferredLighting() (1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | (1 << LLPipeline::RENDER_TYPE_VOLUME) | (1 << LLPipeline::RENDER_TYPE_GLOW) | - (1 << LLPipeline::RENDER_TYPE_BUMP)); + (1 << LLPipeline::RENDER_TYPE_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | + (1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK) | + (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_GLOW) | + (1 << LLPipeline::RENDER_TYPE_PASS_GRASS) | + (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | + (1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY)); renderGeomPostDeferred(*LLViewerCamera::getInstance()); mRenderTypeMask = render_mask; } - mScreen.flush(); + mScreen.flush(); // We are FLUSHED alright ! end of deferred render YAY! } +void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) +{ + //construct frustum + LLVOVolume* volume = drawablep->getVOVolume(); + LLVector3 params = volume->getSpotLightParams(); + + F32 fov = params.mV[0]; + F32 focus = params.mV[1]; + + LLVector3 pos = drawablep->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + LLVector3 scale = volume->getScale(); + + //get near clip plane + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = pos+at_axis; + at_axis.normVec(); + + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + + LLVector3 origin = np - at_axis*dist; + + //matrix from volume space to agent space + LLMatrix4 light_mat(quat, LLVector4(origin,1.f)); + + glh::matrix4f light_to_agent((F32*) light_mat.mMatrix); + glh::matrix4f light_to_screen = glh_get_current_modelview() * light_to_agent; + + glh::matrix4f screen_to_light = light_to_screen.inverse(); + + F32 s = volume->getLightRadius()*1.5f; + F32 near_clip = dist; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = s+dist-scale.mV[VZ]; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; + + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + glh::vec3f p1(0, 0, -(near_clip+0.01f)); + glh::vec3f p2(0, 0, -(near_clip+1.f)); + + glh::vec3f screen_origin(0, 0, 0); + + light_to_screen.mult_matrix_vec(p1); + light_to_screen.mult_matrix_vec(p2); + light_to_screen.mult_matrix_vec(screen_origin); + + glh::vec3f n = p2-p1; + n.normalize(); + + F32 proj_range = far_clip - near_clip; + glh::matrix4f light_proj = gl_perspective(fovy, aspect, near_clip, far_clip); + screen_to_light = trans * light_proj * screen_to_light; + shader.uniformMatrix4fv("proj_mat", 1, FALSE, screen_to_light.m); + shader.uniform1f("proj_near", near_clip); + shader.uniform3fv("proj_p", 1, p1.v); + shader.uniform3fv("proj_n", 1, n.v); + shader.uniform3fv("proj_origin", 1, screen_origin.v); + shader.uniform1f("proj_range", proj_range); + shader.uniform1f("proj_ambiance", params.mV[2]); + S32 s_idx = -1; + + for (U32 i = 0; i < 2; i++) + { + if (mShadowSpotLight[i] == drawablep) + { + s_idx = i; + } + } + + shader.uniform1i("proj_shadow_idx", s_idx); + + if (s_idx >= 0) + { + shader.uniform1f("shadow_fade", 1.f-mSpotLightFade[s_idx]); + } + else + { + shader.uniform1f("shadow_fade", 1.f); + } + + { + LLDrawable* potential = drawablep; + //determine if this is a good light for casting shadows + F32 m_pri = volume->getSpotLightPriority(); + + for (U32 i = 0; i < 2; i++) + { + F32 pri = 0.f; + + if (mTargetShadowSpotLight[i].notNull()) + { + pri = mTargetShadowSpotLight[i]->getVOVolume()->getSpotLightPriority(); + } + + if (m_pri > pri) + { + LLDrawable* temp = mTargetShadowSpotLight[i]; + mTargetShadowSpotLight[i] = potential; + potential = temp; + m_pri = pri; + } + } + } + + LLViewerImage* img = volume->getLightTexture(); + + S32 channel = shader.enableTexture(LLViewerShaderMgr::DEFERRED_PROJECTION); + + if (channel > -1 && img) + { + gGL.getTexUnit(channel)->bind(img); + + 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)); + } +} + void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) { + LLFastTimer ftm(LLFastTimer::FTM_TEMP4); stop_glerror(); shader.disableTexture(LLViewerShaderMgr::DEFERRED_POSITION, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_NORMAL, LLTexUnit::TT_RECT_TEXTURE); @@ -5773,14 +6951,40 @@ void LLPipeline::unbindDeferredShader(LLGLSLShader &shader) shader.disableTexture(LLViewerShaderMgr::DEFERRED_SPECULAR, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_DEPTH, LLTexUnit::TT_RECT_TEXTURE); shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_SUN_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LOCAL_LIGHT, LLTexUnit::TT_RECT_TEXTURE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LUMINANCE); + shader.disableTexture(LLViewerShaderMgr::DIFFUSE_MAP); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_SPECULAR); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_DEPTH); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_MAX_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_NORMAL); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_DIFFUSE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MIN_POS); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_GI_LAST_MAX_POS); + for (U32 i = 0; i < 4; i++) { + if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i, LLTexUnit::TT_RECT_TEXTURE) > -1) + { + glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); + } + } + + for (U32 i = 4; i < 6; i++) + { if (shader.disableTexture(LLViewerShaderMgr::DEFERRED_SHADOW0+i) > -1) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE); } } + shader.disableTexture(LLViewerShaderMgr::DEFERRED_NOISE); + shader.disableTexture(LLViewerShaderMgr::DEFERRED_LIGHTFUNC); S32 channel = shader.disableTexture(LLViewerShaderMgr::ENVIRONMENT_MAP, LLTexUnit::TT_CUBE_MAP); if (channel > -1) @@ -5794,6 +6998,8 @@ 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) @@ -5932,15 +7138,15 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) } } - LLSpatialPartition::sFreezeState = TRUE; - LLPipeline::sSkipUpdate = TRUE; + //LLSpatialPartition::sFreezeState = TRUE; + //LLPipeline::sSkipUpdate = TRUE; LLGLUserClipPlane clip_plane(plane, mat, projection); static LLCullResult result; updateCull(camera, result, 1); stateSort(camera, result); renderGeom(camera); - LLSpatialPartition::sFreezeState = FALSE; - LLPipeline::sSkipUpdate = FALSE; + //LLSpatialPartition::sFreezeState = FALSE; + //LLPipeline::sSkipUpdate = FALSE; } } glCullFace(GL_BACK); @@ -6039,7 +7245,6 @@ glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up) dirN = dir; dirN.normVec(); - ret.m[ 0] = lftN[0]; ret.m[ 1] = upN[0]; @@ -6087,17 +7292,468 @@ glh::matrix4f scale_translate_to_fit(const LLVector3 min, const LLVector3 max) ret.m[11] = 0; ret.m[15] = 1; - return ret; -} + return ret; +} + +void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& shadow_cam, BOOL use_shader) +{ + LLFastTimer t(LLFastTimer::FTM_SHADOW_RENDER); + + //clip out geometry on the same side of water as the camera + static LLCullResult result; + S32 occlude = LLPipeline::sUseOcclusion; + LLPipeline::sUseOcclusion = 1; + LLPipeline::sShadowRender = TRUE; + + updateCull(shadow_cam, result); + stateSort(shadow_cam, result); + + U32 types[] = { LLRenderPass::PASS_SIMPLE, LLRenderPass::PASS_FULLBRIGHT, LLRenderPass::PASS_SHINY, LLRenderPass::PASS_BUMP }; + LLGLEnable cull(GL_CULL_FACE); + + //generate shadow map + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadMatrixf(proj.m); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadMatrixf(view.m); + + stop_glerror(); + gGLLastMatrix = NULL; + + gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); + + glColor4f(1,1,1,1); + + stop_glerror(); + + gGL.setColorMask(false, false); + + if (use_shader) + { + gDeferredShadowProgram.bind(); + } + + //glCullFace(GL_FRONT); + + { + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); + LLGLDisable test(GL_ALPHA_TEST); + gGL.getTexUnit(0)->disable(); + for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) + { + renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); + } + gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + } + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + renderGeomShadow(shadow_cam); + gDeferredShadowProgram.bind(); + } + else + { + renderGeomShadow(shadow_cam); + } + + { + LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); + LLGLEnable test(GL_ALPHA_TEST); + gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); + renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); + glColor4f(1,1,1,1); + renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + } + + //glCullFace(GL_BACK); + + if (use_shader) + { + gDeferredShadowProgram.unbind(); + } + + gGL.setColorMask(true, true); + + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + gGLLastMatrix = NULL; + + LLPipeline::sUseOcclusion = occlude; + LLPipeline::sShadowRender = FALSE; +} + + +BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector& fp, LLVector3 light_dir) +{ + LLFastTimer ftm(LLFastTimer::FTM_TEMP2); + //get point cloud of intersection of frust and min, max + + //get set of planes + std::vector ps; + + if (getVisibleExtents(camera, min, max)) + { + return FALSE; + } + + ps.push_back(LLPlane(min, LLVector3(-1,0,0))); + ps.push_back(LLPlane(min, LLVector3(0,-1,0))); + ps.push_back(LLPlane(min, LLVector3(0,0,-1))); + ps.push_back(LLPlane(max, LLVector3(1,0,0))); + ps.push_back(LLPlane(max, LLVector3(0,1,0))); + ps.push_back(LLPlane(max, LLVector3(0,0,1))); + + if (!light_dir.isExactlyZero()) + { + LLPlane ucp; + LLPlane mcp; + + F32 maxd = -1.f; + F32 mind = 1.f; + + for (U32 i = 0; i < ps.size(); ++i) + { //pick the plane most aligned to lightDir for user clip plane + LLVector3 n(ps[i].mV); + F32 da = n*light_dir; + if (da > maxd) + { + maxd = da; + ucp = ps[i]; + } + + if (da < mind) + { + mind = da; + mcp = ps[i]; + } + } + + camera.setUserClipPlane(ucp); + + ps.clear(); + ps.push_back(ucp); + ps.push_back(mcp); + } + + for (U32 i = 0; i < 6; i++) + { + ps.push_back(camera.getAgentPlane(i)); + } + + //get set of points where planes intersect and points are not above any plane + fp.clear(); + + for (U32 i = 0; i < ps.size(); ++i) + { + for (U32 j = 0; j < ps.size(); ++j) + { + for (U32 k = 0; k < ps.size(); ++k) + { + if (i == j || + i == k || + k == j) + { + continue; + } + + LLVector3 n1,n2,n3; + F32 d1,d2,d3; + + n1.setVec(ps[i].mV); + n2.setVec(ps[j].mV); + n3.setVec(ps[k].mV); + + d1 = ps[i].mV[3]; + d2 = ps[j].mV[3]; + d3 = ps[k].mV[3]; + + //get point of intersection of 3 planes "p" + LLVector3 p = (-d1*(n2%n3)-d2*(n3%n1)-d3*(n1%n2))/(n1*(n2%n3)); + + if (llround(p*n1+d1, 0.0001f) == 0.f && + llround(p*n2+d2, 0.0001f) == 0.f && + llround(p*n3+d3, 0.0001f) == 0.f) + { //point is on all three planes + BOOL found = TRUE; + for (U32 l = 0; l < ps.size() && found; ++l) + { + if (llround(ps[l].dist(p), 0.0001f) > 0.0f) + { //point is above some plane, not contained + found = FALSE; + } + } + + if (found) + { + fp.push_back(p); + } + } + } + } + } + + if (fp.empty()) + { + return FALSE; + } + + return TRUE; +} + +void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector& vpc) +{ +/* if (!gSavedSettings.getBOOL("RenderDeferredGI")) + { + return; + } */ + + LLVector3 up; + + if (lightDir.mV[2] > 0.5f) + { + up = LLVector3(1,0,0); + } + else + { + up = LLVector3(0, 0, 1); + } + + + F32 lrad = gSavedSettings.getF32("RenderGILightRadius"); + + F32 samples = (F32) gSavedSettings.getU32("RenderGISamples"); + + F32 gi_range = gSavedSettings.getF32("RenderGIRange"); + + U32 res = 1024; + + lrad = samples*gi_range/(res-samples)*0.5f; + + F32 lrange = lrad+gi_range*0.5f; + + LLVector3 pad(lrange,lrange,lrange); + + glh::matrix4f view = look(LLVector3(128.f,128.f,128.f), lightDir, up); + + LLVector3 cp = camera.getOrigin()+camera.getAtAxis()*(gi_range*0.5f); + + glh::vec3f scp(cp.mV); + view.mult_matrix_vec(scp); + cp.setVec(scp.v); + + F32 pix_width = lrange/(res*0.5f); + + //lrad = llround(lrad, pix_width); + + //move cp to the nearest pix_width + for (U32 i = 0; i < 3; i++) + { + cp.mV[i] = llround(cp.mV[i], pix_width); + } + + LLVector3 min = cp-pad; + LLVector3 max = cp+pad; + + //set mGIRange to range in tc space[0,1] that covers texture block of intersecting lights around a point + mGIRange.mV[0] = (max.mV[0]-min.mV[0])/res; + mGIRange.mV[1] = (max.mV[1]-min.mV[1])/res; + mGILightRadius = lrad; + + glh::matrix4f proj = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + + LLCamera sun_cam = camera; + + glh::matrix4f eye_view = glh_get_current_modelview(); + + //get eye space to camera space matrix + mGIMatrix = view*eye_view.inverse(); + mGINormalMatrix = mGIMatrix.inverse().transpose(); + mGIInvProj = proj.inverse(); + mGIMatrixProj = proj*mGIMatrix; + + //translate and scale to [0,1] + glh::matrix4f trans(.5f, 0.f, 0.f, .5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); + + mGIMatrixProj = trans*mGIMatrixProj; + + glh_set_current_modelview(view); + glh_set_current_projection(proj); + + LLViewerCamera::updateFrustumPlanes(sun_cam, TRUE, FALSE, TRUE); + + sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); + static LLCullResult result; + + U32 type_mask = mRenderTypeMask; + + mRenderTypeMask = type_mask & ((1<getVolume()) + { + for (LLViewerObject::child_list_t::const_iterator iter = obj->getChildren().begin(); iter != obj->getChildren().end(); ++iter) + { + renderHighlight(*iter, fade); + } + + LLDrawable* drawable = obj->mDrawable; + if (drawable) + { + for (S32 i = 0; i < drawable->getNumFaces(); ++i) + { + LLFace* face = drawable->getFace(i); + if (face) + { + face->renderSelected(LLViewerImage::sNullImagep, LLColor4(1,1,1,fade)); + } + } + } + } +} + +void LLPipeline::generateHighlight(LLCamera& camera) +{ + if (!gSavedSettings.getBOOL("renderhighlights")) // KL need this to make the mouseover Highlights toggle ^^ + { + return; + } + //render highlighted object as white into offscreen render target + + if (mHighlightObject.notNull()) + { + mHighlightSet.insert(HighlightItem(mHighlightObject)); + } + + if (!mHighlightSet.empty()) + { + F32 transition = gFrameIntervalSeconds/gSavedSettings.getF32("RenderHighlightFadeTime"); + + LLGLDisable test(GL_ALPHA_TEST); + LLGLDepthTest depth(GL_FALSE); + mHighlight.bindTarget(); + disableLights(); + gGL.setColorMask(true, true); + mHighlight.clear(); + + gGL.getTexUnit(0)->bind(LLViewerImage::sWhiteImagep); + for (std::set::iterator iter = mHighlightSet.begin(); iter != mHighlightSet.end(); ) + { + std::set::iterator cur_iter = iter++; + + if (cur_iter->mItem.isNull()) + { + mHighlightSet.erase(cur_iter); + continue; + } + + if (cur_iter->mItem == mHighlightObject) + { + cur_iter->incrFade(transition); + } + else + { + cur_iter->incrFade(-transition); + if (cur_iter->mFade <= 0.f) + { + mHighlightSet.erase(cur_iter); + continue; + } + } + + renderHighlight(cur_iter->mItem->getVObj(), cur_iter->mFade); + } + + mHighlight.flush(); + gGL.setColorMask(true, false); + gViewerWindow->setupViewport(); + } +} + void LLPipeline::generateSunShadow(LLCamera& camera) { - if (!sRenderDeferred) { return; } + LLFastTimer ftm(LLFastTimer::FTM_TEMP1); + //temporary hack to disable shadows but keep local lights static BOOL clear = TRUE; BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); @@ -6106,98 +7762,162 @@ void LLPipeline::generateSunShadow(LLCamera& camera) if (clear) { clear = FALSE; - for (U32 i = 0; i < 4; i++) + for (U32 i = 0; i < 6; i++) { - mSunShadow[i].bindTarget(); - mSunShadow[i].clear(); - mSunShadow[i].flush(); + mShadow[i].bindTarget(); + mShadow[i].clear(); + mShadow[i].flush(); } } return; } clear = TRUE; + U32 type_mask = mRenderTypeMask; + mRenderTypeMask = type_mask & ((1<getLastPick(); - - if (!pick_info.mPosGlobal.isExactlyZero()) - { //squish nearest frustum based on alt-zoom (tighten up nearest frustum when focusing on tiny object - F32 focus_dist = (F32) (pick_info.mPosGlobal + LLVector3d(pick_info.mObjectOffset) - gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin())).magVec(); - mSunClipPlanes.mV[0] = llclamp(focus_dist*focus_dist, 2.f, mSunClipPlanes.mV[0]); - } - - // convenience array of 4 near clip plane distances - F32 dist[] = { 0.1f, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + clip = gSavedSettings.getVector3("RenderShadowOrthoClipPlanes"); + mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); //currently used for amount to extrude frusta corners for constructing shadow frusta LLVector3 n = gSavedSettings.getVector3("RenderShadowNearDist"); - F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; + //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; - for (S32 j = 0; j < 4; j++) - { - //restore render matrices - glh_set_current_modelview(saved_view); - glh_set_current_projection(saved_proj); + LLVector3 lightDir = -mSunDir; + lightDir.normVec(); - //get center of far clip plane (for point of interest later) - LLVector3 center = camera.getOrigin() + camera.getAtAxis() * range; + glh::vec3f light_dir(lightDir.mV); - LLVector3 eye = camera.getOrigin(); + //create light space camera matrix + + LLVector3 at = lightDir; - //camera used for shadow cull/render - LLCamera shadow_cam; - - // perspective shadow map - glh::vec3f p[16]; //point cloud to be contained by shadow projection (light camera space) - glh::vec3f wp[16]; //point cloud to be contained by shadow projection (world space) - - LLVector3 lightDir = -mSunDir; - glh::vec3f light_dir(lightDir.mV); + LLVector3 up = camera.getAtAxis(); + + if (fabsf(up*lightDir) > 0.75f) + { + up = camera.getUpAxis(); + } - //create light space camera matrix - LLVector3 at; - F32 dl = camera.getLeftAxis() * lightDir; - F32 du = camera.getUpAxis() * lightDir; + /*LLVector3 left = up%at; + up = at%left;*/ - //choose an at axis such that up will be most aligned with lightDir - if (dl*dl < du*du) + up.normVec(); + at.normVec(); + + + F32 near_clip = 0.f; + { + //get visible point cloud + std::vector fp; + + LLVector3 min,max; + getVisiblePointCloud(camera,min,max,fp); + + if (fp.empty()) { - at = lightDir%camera.getLeftAxis(); + mRenderTypeMask = type_mask; + return; } - else + + generateGI(camera, lightDir, fp); + + //get good split distances for frustum + for (U32 i = 0; i < fp.size(); ++i) { - at = lightDir%camera.getUpAxis(); + glh::vec3f v(fp[i].mV); + saved_view.mult_matrix_vec(v); + fp[i].setVec(v.v); } - if (at * camera.getAtAxis() < 0) + min = fp[0]; + max = fp[0]; + + //get camera space bounding box + for (U32 i = 1; i < fp.size(); ++i) { - at = -at; + update_min_max(min, max, fp[i]); } + + 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, camera.getFar()); + + F32 range = far_clip-near_clip; + + LLVector3 split_exp = gSavedSettings.getVector3("RenderShadowSplitExponent"); + + F32 da = 1.f-llmax( fabsf(lightDir*up), fabsf(lightDir*camera.getLeftAxis()) ); - LLVector3 left = lightDir%at; - up = left%lightDir; - up.normVec(); + da = powf(da, split_exp.mV[2]); + + + F32 sxp = split_exp.mV[1] + (split_exp.mV[0]-split_exp.mV[1])*da; + + + for (U32 i = 0; i < 4; ++i) + { + F32 x = (F32)(i+1)/4.f; + x = powf(x, sxp); + mSunClipPlanes.mV[i] = near_clip+range*x; + } + } + + // convenience array of 4 near clip plane distances + F32 dist[] = { near_clip, mSunClipPlanes.mV[0], mSunClipPlanes.mV[1], mSunClipPlanes.mV[2], mSunClipPlanes.mV[3] }; + + for (S32 j = 0; j < 4; j++) + { + if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustPoints[j].clear(); + } + + //restore render matrices + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); + + LLVector3 eye = camera.getOrigin(); + //camera used for shadow cull/render + LLCamera shadow_cam; + //create world space camera frustum for this split shadow_cam = camera; shadow_cam.setFar(16.f); @@ -6208,8 +7928,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLVector3 pn = shadow_cam.getAtAxis(); - LLVector3 frust_center; - LLVector3 min, max; //construct 8 corners of split frustum section @@ -6220,21 +7938,19 @@ void LLPipeline::generateSunShadow(LLCamera& camera) F32 dp = delta*pn; frust[i] = eye + (delta*dist[j])/dp; frust[i+4] = eye + (delta*dist[j+1])/dp; - frust_center += frust[i] + frust[i+4]; } - - //get frustum center - frust_center /= 8.f; shadow_cam.calcAgentFrustumPlanes(frust); - + shadow_cam.mFrustumCornerDist = 0.f; if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) { mShadowCamera[j] = shadow_cam; } - if (gPipeline.getVisibleExtents(shadow_cam, min, max)) + std::vector fp; + + if (!gPipeline.getVisiblePointCloud(shadow_cam, min, max, fp, lightDir)) { //no possible shadow receivers if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) @@ -6244,6 +7960,16 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mShadowCamera[j+4] = shadow_cam; } + mShadow[j].bindTarget(); + { + LLGLDepthTest depth(GL_TRUE); + mShadow[j].clear(); + } + mShadow[j].flush(); + + mShadowError.mV[j] = 0.f; + mShadowFOV.mV[j] = 0.f; + continue; } @@ -6251,42 +7977,252 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { mShadowExtents[j][0] = min; mShadowExtents[j][1] = max; + mShadowFrustPoints[j] = fp; } - view[j] = look(frust_center-lightDir*nearDist[j], lightDir, up); - F32 shadow_dist = nearDist[j]; - for (U32 i = 0; i < 8; i++) + //find a good origin for shadow projection + LLVector3 origin; + + //get a temporary view projection + view[j] = look(camera.getOrigin(), lightDir, -up); + + std::vector wpf; + + for (U32 i = 0; i < fp.size(); i++) { - //points in worldspace (wp) and light camera space (p) - //that must be included in shadow generation - wp[i] = glh::vec3f(frust[i].mV); - wp[i+8] = wp[i] - light_dir*shadow_dist; - view[j].mult_matrix_vec(wp[i], p[i]); - view[j].mult_matrix_vec(wp[i+8], p[i+8]); + glh::vec3f p = glh::vec3f(fp[i].mV); + view[j].mult_matrix_vec(p); + wpf.push_back(LLVector3(p.v)); } - - min = LLVector3(p[0].v); - max = LLVector3(p[0].v); - LLVector3 fmin = min; - LLVector3 fmax = max; + min = wpf[0]; + max = wpf[0]; - for (U32 i = 1; i < 16; i++) - { //find camera space AABB of frustum in light camera space - update_min_max(min, max, LLVector3(p[i].v)); - if (i < 8) - { - update_min_max(fmin, fmax, LLVector3(p[i].v)); + for (U32 i = 0; i < fp.size(); ++i) + { //get AABB in camera space + update_min_max(min, max, wpf[i]); + } + + // Construct a perspective transform with perspective along y-axis that contains + // points in wpf + //Known: + // - far clip plane + // - near clip plane + // - points in frustum + //Find: + // - origin + + //get some "interesting" points of reference + LLVector3 center = (min+max)*0.5f; + LLVector3 size = (max-min)*0.5f; + LLVector3 near_center = center; + near_center.mV[1] += size.mV[1]*2.f; + + + //put all points in wpf in quadrant 0, reletive to center of min/max + //get the best fit line using least squares + F32 bfm = 0.f; + F32 bfb = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + wpf[i] -= center; + wpf[i].mV[0] = fabsf(wpf[i].mV[0]); + wpf[i].mV[2] = fabsf(wpf[i].mV[2]); + } + + if (!wpf.empty()) + { + F32 sx = 0.f; + F32 sx2 = 0.f; + F32 sy = 0.f; + F32 sxy = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + sx += wpf[i].mV[0]; + sx2 += wpf[i].mV[0]*wpf[i].mV[0]; + sy += wpf[i].mV[1]; + sxy += wpf[i].mV[0]*wpf[i].mV[1]; } + + bfm = (sy*sx-wpf.size()*sxy)/(sx*sx-wpf.size()*sx2); + bfb = (sx*sxy-sy*sx2)/(sx*sx-bfm*sx2); } + + { + // best fit line is y=bfm*x+bfb + + //find point that is furthest to the right of line + F32 off_x = -1.f; + LLVector3 lp; + + for (U32 i = 0; i < wpf.size(); ++i) + { + //y = bfm*x+bfb + //x = (y-bfb)/bfm + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + + lx = wpf[i].mV[0]-lx; + + if (off_x < lx) + { + off_x = lx; + lp = wpf[i]; + } + } + + //get line with slope bfm through lp + // bfb = y-bfm*x + bfb = lp.mV[1]-bfm*lp.mV[0]; + + //calculate error + mShadowError.mV[j] = 0.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + F32 lx = (wpf[i].mV[1]-bfb)/bfm; + mShadowError.mV[j] += fabsf(wpf[i].mV[0]-lx); + } + + mShadowError.mV[j] /= wpf.size(); + mShadowError.mV[j] /= size.mV[0]; + + if (mShadowError.mV[j] > gSavedSettings.getF32("RenderShadowErrorCutoff")) + { //just use ortho projection + mShadowFOV.mV[j] = -1.f; + origin.clearVec(); + proj[j] = gl_ortho(min.mV[0], max.mV[0], + min.mV[1], max.mV[1], + -max.mV[2], -min.mV[2]); + } + else + { + //origin is where line x = 0; + origin.setVec(0,bfb,0); + + F32 fovz = 1.f; + F32 fovx = 1.f; + + LLVector3 zp; + LLVector3 xp; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + if (fovz > -atz.mV[1]) + { + zp = wpf[i]; + fovz = -atz.mV[1]; + } + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + if (fovx > -atx.mV[1]) + { + fovx = -atx.mV[1]; + xp = wpf[i]; + } + } + + fovx = acos(fovx); + fovz = acos(fovz); + + F32 cutoff = llmin(gSavedSettings.getF32("RenderShadowFOVCutoff"), 1.4f); + + mShadowFOV.mV[j] = fovx; + + if (fovx < cutoff && fovz > cutoff) + { + //x is a good fit, but z is too big, move away from zp enough so that fovz matches cutoff + F32 d = zp.mV[2]/tan(cutoff); + F32 ny = zp.mV[1] + fabsf(d); + + origin.mV[1] = ny; + + fovz = 1.f; + fovx = 1.f; + + for (U32 i = 0; i < wpf.size(); ++i) + { + LLVector3 atz = wpf[i]-origin; + atz.mV[0] = 0.f; + atz.normVec(); + fovz = llmin(fovz, -atz.mV[1]); + + LLVector3 atx = wpf[i]-origin; + atx.mV[2] = 0.f; + atx.normVec(); + fovx = llmin(fovx, -atx.mV[1]); + } - //generate perspective matrix that contains frustum - //proj[j] = matrix_perspective(min, max); - proj[j] = gl_ortho(min.mV[0], max.mV[0], + fovx = acos(fovx); + fovz = acos(fovz); + + if (fovx > cutoff || llround(fovz, 0.01f) > cutoff) + { + // llwarns << "WTF?" << llendl; + } + + mShadowFOV.mV[j] = cutoff; + } + + + origin += center; + + F32 ynear = -(max.mV[1]-origin.mV[1]); + F32 yfar = -(min.mV[1]-origin.mV[1]); + + if (ynear < 0.1f) //keep a sensible near clip plane + { + F32 diff = 0.1f-ynear; + origin.mV[1] += diff; + ynear += diff; + yfar += diff; + } + + if (fovx > cutoff) + { //just use ortho projection + origin.clearVec(); + mShadowError.mV[j] = -1.f; + proj[j] = gl_ortho(min.mV[0], max.mV[0], min.mV[1], max.mV[1], -max.mV[2], -min.mV[2]); - + } + else + { + //get perspective projection + view[j] = view[j].inverse(); + + glh::vec3f origin_agent(origin.mV); + + //translate view to origin + view[j].mult_matrix_vec(origin_agent); + + eye = LLVector3(origin_agent.v); + + if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA)) + { + mShadowFrustOrigin[j] = eye; + } + + view[j] = look(LLVector3(origin_agent.v), lightDir, -up); + + F32 fx = 1.f/tanf(fovx); + F32 fz = 1.f/tanf(fovz); + + proj[j] = glh::matrix4f(-fx, 0, 0, 0, + 0, (yfar+ynear)/(ynear-yfar), 0, (2.f*yfar*ynear)/(ynear-yfar), + 0, 0, -fz, 0, + 0, -1.f, 0, 0); + } + } + } + shadow_cam.setFar(128.f); shadow_cam.setOriginAndLookAt(eye, up, center); @@ -6295,9 +8231,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); - proj[j] = gl_ortho(fmin.mV[0], fmax.mV[0], - fmin.mV[1], fmax.mV[1], - -fmax.mV[2], -fmin.mV[2]); + shadow_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR); //translate and scale to from [-1, 1] to [0, 1] glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, @@ -6310,111 +8244,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera) mSunShadowMatrix[j] = trans*proj[j]*view[j]*inv_view; - U32 type_mask = mRenderTypeMask; - mRenderTypeMask = type_mask & ((1<unbind(LLTexUnit::TT_TEXTURE); - - glColor4f(1,1,1,1); - - glCullFace(GL_FRONT); + F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); - stop_glerror(); + //update shadow targets + for (U32 i = 0; i < 2; i++) + { //for each current shadow + if (mShadowSpotLight[i].notNull() && + (mShadowSpotLight[i] == mTargetShadowSpotLight[0] || + mShadowSpotLight[i] == mTargetShadowSpotLight[1])) + { //keep this spotlight + mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); + } + else + { //fade out this light + mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); + + if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) + { //faded out, grab one of the pending spots (whichever one isn't already taken) + if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) + { + mShadowSpotLight[i] = mTargetShadowSpotLight[0]; + } + else + { + mShadowSpotLight[i] = mTargetShadowSpotLight[1]; + } + } + } + } - gGL.setColorMask(false, false); + for (S32 i = 0; i < 2; i++) + { + glh_set_current_modelview(saved_view); + glh_set_current_projection(saved_proj); - gDeferredShadowProgram.bind(); + if (mShadowSpotLight[i].isNull()) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_SIMPLE); - LLGLDisable test(GL_ALPHA_TEST); - gGL.getTexUnit(0)->disable(); - for (U32 i = 0; i < sizeof(types)/sizeof(U32); ++i) - { - renderObjects(types[i], LLVertexBuffer::MAP_VERTEX, FALSE); - } - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); + continue; } - + + LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); + + if (!volume) { - LLFastTimer ftm(LLFastTimer::FTM_SHADOW_ALPHA); - LLGLEnable test(GL_ALPHA_TEST); - gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.6f); - renderObjects(LLRenderPass::PASS_ALPHA_SHADOW, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR, TRUE); - glColor4f(1,1,1,1); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); - gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT); + mShadowSpotLight[i] = NULL; + continue; } + + LLDrawable* drawable = mShadowSpotLight[i]; + + LLVector3 params = volume->getSpotLightParams(); + F32 fov = params.mV[0]; + + //get agent->light space matrix (modelview) + LLVector3 center = drawable->getPositionAgent(); + LLQuaternion quat = volume->getRenderRotation(); + + //get near clip plane + LLVector3 scale = volume->getScale(); + LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); + at_axis *= quat; + + LLVector3 np = center+at_axis; + at_axis.normVec(); + + //get origin that has given fov for plane np, at_axis, and given scale + F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); + + LLVector3 origin = np - at_axis*dist; + + LLMatrix4 mat(quat, LLVector4(origin, 1.f)); + + view[i+4] = glh::matrix4f((F32*) mat.mMatrix); + + view[i+4] = view[i+4].inverse(); + + //get perspective matrix + F32 near_clip = dist+0.01f; + F32 width = scale.mV[VX]; + F32 height = scale.mV[VY]; + F32 far_clip = dist+volume->getLightRadius()*1.5f; + + F32 fovy = fov * RAD_TO_DEG; + F32 aspect = width/height; - gDeferredShadowProgram.unbind(); + proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); - renderGeomShadow(shadow_cam); + //translate and scale to from [-1, 1] to [0, 1] + glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, + 0.f, 0.5f, 0.f, 0.5f, + 0.f, 0.f, 0.5f, 0.5f, + 0.f, 0.f, 0.f, 1.f); - gGL.setColorMask(true, true); + glh_set_current_modelview(view[i+4]); + glh_set_current_projection(proj[i+4]); - glCullFace(GL_BACK); - LLPipeline::sUseOcclusion = occlude; - LLPipeline::sShadowRender = FALSE; - mRenderTypeMask = type_mask; + mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; - glMatrixMode(GL_PROJECTION); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - glPopMatrix(); - gGLLastMatrix = NULL; + LLCamera shadow_cam = camera; + shadow_cam.setFar(far_clip); + shadow_cam.setOrigin(origin); - mSunShadow[j].flush(); - } + LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + + shadow_cam.setOrigin(camera.getOrigin()); + + stop_glerror(); + + mShadow[i+4].bindTarget(); + mShadow[i+4].getViewport(gGLViewport); + + { + LLGLDepthTest depth(GL_TRUE); + mShadow[i+4].clear(); + } + + renderShadow(view[i+4], proj[i+4], shadow_cam, FALSE); + + mShadow[i+4].flush(); + } if (!gSavedSettings.getBOOL("CameraOffset")) { @@ -6431,6 +8409,8 @@ void LLPipeline::generateSunShadow(LLCamera& camera) glMatrixMode(GL_MODELVIEW); } gGL.setColorMask(true, false); + + mRenderTypeMask = type_mask; } void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -6470,7 +8450,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (muted) { - mask = 1 << LLPipeline::RENDER_TYPE_AVATAR; + mask = 1 << LLPipeline::RENDER_TYPE_INVISIBLE; // Peachy ;) } else { @@ -6481,7 +8461,16 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) (1<mDrawable, *LLViewerCamera::getInstance()); @@ -6570,7 +8560,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) if (LLPipeline::sRenderDeferred) { avatar->mImpostor.allocate(resX,resY,GL_RGBA16F_ARB,TRUE,TRUE); - addDeferredAttachments(avatar->mImpostor); + //addDeferredAttachments(avatar->mImpostor); } else { @@ -6649,6 +8639,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar) sUseOcclusion = occlusion; sReflectionRender = FALSE; sImpostorRender = FALSE; + sShadowRender = FALSE; gPipeline.mRenderTypeMask = saved_mask; glMatrixMode(GL_PROJECTION); diff --git a/linden/indra/newview/pipeline.h b/linden/indra/newview/pipeline.h index 1a32b30..a85877d 100644 --- a/linden/indra/newview/pipeline.h +++ b/linden/indra/newview/pipeline.h @@ -129,6 +129,8 @@ public: void markMoved(LLDrawable *drawablep, BOOL damped_motion = FALSE); void markShift(LLDrawable *drawablep); void markTextured(LLDrawable *drawablep); + void markGLRebuild(LLGLUpdate* glu); + void markRebuild(LLSpatialGroup* group, BOOL priority = FALSE); void markRebuild(LLDrawable *drawablep, LLDrawable::EDrawableFlags flag = LLDrawable::REBUILD_ALL, BOOL priority = FALSE); //get the object between start and end that's closest to start. @@ -179,10 +181,14 @@ public: void updateMove(); BOOL visibleObjectsInFrustum(LLCamera& camera); BOOL getVisibleExtents(LLCamera& camera, LLVector3 &min, LLVector3& max); + BOOL getVisiblePointCloud(LLCamera& camera, LLVector3 &min, LLVector3& max, std::vector& fp, LLVector3 light_dir = LLVector3(0,0,0)); void updateCull(LLCamera& camera, LLCullResult& result, S32 water_clip = 0); //if water_clip is 0, ignore water plane, 1, cull to above plane, -1, cull to below plane void createObjects(F32 max_dtime); void createObject(LLViewerObject* vobj); void updateGeom(F32 max_dtime); + void updateGL(); + void rebuildPriorityGroups(); + void rebuildGroups(); //calculate pixel area of given box from vantage point of given camera static F32 calcPixelArea(LLVector3 center, LLVector3 size, LLCamera& camera); @@ -203,12 +209,21 @@ public: void renderGeomDeferred(LLCamera& camera); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); - void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0); + void bindDeferredShader(LLGLSLShader& shader, U32 light_index = 0, LLRenderTarget* gi_source = NULL, LLRenderTarget* last_gi_post = NULL); + void setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep); + void unbindDeferredShader(LLGLSLShader& shader); void renderDeferredLighting(); void generateWaterReflection(LLCamera& camera); void generateSunShadow(LLCamera& camera); + void generateHighlight(LLCamera& camera); + void renderHighlight(const LLViewerObject* obj, F32 fade); + void setHighlightObject(LLDrawable* obj) { mHighlightObject = obj; } + + + void renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera& camera, BOOL use_shader = TRUE); + void generateGI(LLCamera& camera, LLVector3& lightDir, std::vector& vpc); // KL sd void renderHighlights(); void renderDebug(); @@ -303,27 +318,39 @@ public: enum LLRenderTypeMask { // Following are pool types (some are also object types) - RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, - RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, - RENDER_TYPE_GROUND = LLDrawPool::POOL_GROUND, - RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, - RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, - RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, - RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, - RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, - RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, - RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, - RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, - RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, - RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, - RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, - + RENDER_TYPE_SKY = LLDrawPool::POOL_SKY, + RENDER_TYPE_WL_SKY = LLDrawPool::POOL_WL_SKY, + RENDER_TYPE_GROUND = LLDrawPool::POOL_GROUND, + RENDER_TYPE_TERRAIN = LLDrawPool::POOL_TERRAIN, + RENDER_TYPE_SIMPLE = LLDrawPool::POOL_SIMPLE, + RENDER_TYPE_GRASS = LLDrawPool::POOL_GRASS, + RENDER_TYPE_FULLBRIGHT = LLDrawPool::POOL_FULLBRIGHT, + RENDER_TYPE_BUMP = LLDrawPool::POOL_BUMP, + RENDER_TYPE_AVATAR = LLDrawPool::POOL_AVATAR, + RENDER_TYPE_TREE = LLDrawPool::POOL_TREE, + RENDER_TYPE_INVISIBLE = LLDrawPool::POOL_INVISIBLE, + RENDER_TYPE_WATER = LLDrawPool::POOL_WATER, + RENDER_TYPE_ALPHA = LLDrawPool::POOL_ALPHA, + RENDER_TYPE_GLOW = LLDrawPool::POOL_GLOW, + RENDER_TYPE_PASS_SIMPLE = LLRenderPass::PASS_SIMPLE, + RENDER_TYPE_PASS_GRASS = LLRenderPass::PASS_GRASS, + RENDER_TYPE_PASS_FULLBRIGHT = LLRenderPass::PASS_FULLBRIGHT, + RENDER_TYPE_PASS_INVISIBLE = LLRenderPass::PASS_INVISIBLE, + RENDER_TYPE_PASS_INVISI_SHINY = LLRenderPass::PASS_INVISI_SHINY, + RENDER_TYPE_PASS_FULLBRIGHT_SHINY = LLRenderPass::PASS_FULLBRIGHT_SHINY, + RENDER_TYPE_PASS_SHINY = LLRenderPass::PASS_SHINY, + RENDER_TYPE_PASS_BUMP = LLRenderPass::PASS_BUMP, + RENDER_TYPE_PASS_GLOW = LLRenderPass::PASS_GLOW, + RENDER_TYPE_PASS_ALPHA = LLRenderPass::PASS_ALPHA, + RENDER_TYPE_PASS_ALPHA_MASK = LLRenderPass::PASS_ALPHA_MASK, + RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK = LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, + RENDER_TYPE_PASS_ALPHA_SHADOW = LLRenderPass::PASS_ALPHA_SHADOW, // Following are object types (only used in drawable mRenderType) - RENDER_TYPE_HUD = LLDrawPool::NUM_POOL_TYPES, + RENDER_TYPE_HUD = LLRenderPass::NUM_RENDER_TYPES, RENDER_TYPE_VOLUME, RENDER_TYPE_PARTICLES, RENDER_TYPE_CLOUDS, - RENDER_TYPE_HUD_PARTICLES + RENDER_TYPE_HUD_PARTICLES // KL S19? }; enum LLRenderDebugFeatureMask @@ -361,8 +388,7 @@ public: RENDER_DEBUG_SHAME = 0x0020000, RENDER_DEBUG_SHADOW_FRUSTA = 0x0040000, RENDER_DEBUG_SCULPTED = 0x0080000, - RENDER_DEBUG_AVATAR_VOLUME = 0x0100000, - RENDER_DEBUG_AGENT_TARGET = 0x0200000, + RENDER_DEBUG_BUILD_QUEUE = 0x0100000, }; public: @@ -421,15 +447,36 @@ public: //screen texture LLRenderTarget mScreen; LLRenderTarget mDeferredScreen; - LLRenderTarget mDeferredLight[2]; + LLRenderTarget mDeferredDepth; + LLRenderTarget mDeferredLight[3]; LLMultisampleBuffer mSampleBuffer; + LLRenderTarget mGIMap; + LLRenderTarget mGIMapPost[2]; + LLRenderTarget mLuminanceMap; + LLRenderTarget mHighlight; //sun shadow map - LLRenderTarget mSunShadow[4]; + LLRenderTarget mShadow[6]; + std::vector mShadowFrustPoints[4]; + LLVector4 mShadowError; + LLVector4 mShadowFOV; + LLVector3 mShadowFrustOrigin[4]; LLCamera mShadowCamera[8]; LLVector3 mShadowExtents[4][2]; - glh::matrix4f mSunShadowMatrix[4]; + glh::matrix4f mSunShadowMatrix[6]; + glh::matrix4f mGIMatrix; + glh::matrix4f mGIMatrixProj; + glh::matrix4f mGINormalMatrix; + glh::matrix4f mGIInvProj; + LLVector2 mGIRange; + F32 mGILightRadius; + + LLPointer mShadowSpotLight[2]; + F32 mSpotLightFade[2]; + LLPointer mTargetShadowSpotLight[2]; + LLVector4 mSunClipPlanes; + LLVector4 mSunOrthoClipPlanes; LLVector2 mScreenScale; @@ -444,6 +491,8 @@ public: //noise map U32 mNoiseMap; + U32 mTrueNoiseMap; + U32 mLightFunc; LLColor4 mSunDiffuse; LLVector3 mSunDir; @@ -504,12 +553,45 @@ protected: // LLDrawable::drawable_list_t mBuildQ1; // priority LLDrawable::drawable_list_t mBuildQ2; // non-priority + LLSpatialGroup::sg_list_t mGroupQ1; //priority + LLSpatialGroup::sg_vector_t mGroupQ2; // non-priority + LLViewerObject::vobj_list_t mCreateQ; LLDrawable::drawable_set_t mActiveQ; LLDrawable::drawable_set_t mRetexturedList; + class HighlightItem + { + public: + const LLPointer mItem; + mutable F32 mFade; + + HighlightItem(LLDrawable* item) + : mItem(item), mFade(0) + { + } + + bool operator<(const HighlightItem& rhs) const + { + return mItem < rhs.mItem; + } + + bool operator==(const HighlightItem& rhs) const + { + return mItem == rhs.mItem; + } + + void incrFade(F32 val) const + { + mFade = llclamp(mFade+val, 0.f, 1.f); + } + }; + + std::set mHighlightSet; + LLPointer mHighlightObject; + ////////////////////////////////////////////////// // // Draw pools are responsible for storing all rendered data, diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml index 24a895b..e85eaa8 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_hardware_settings.xml @@ -64,7 +64,35 @@ tool_tip="Enabling this on modern hardware gives a performance gain. However, older hardware often has poor implementations of VBOs and you may get crashes when this is enabled." width="315" /> - + Enable FBO: + + + + + Deferred Rendering: + + + + + mouse_opaque="true" name="label color" v_pad="0" width="57"> Color: + + Texture + + + increment="0.1" initial_val="0.5" label="Intensity:" label_width="55" + left="10" max_val="1" min_val="0" mouse_opaque="true" + name="Light Intensity" width="120" /> + + increment="0.1" initial_val="5" label="Radius" label_width="55" + left="10" max_val="20" min_val="0" mouse_opaque="true" + name="Light Radius" width="120" /> + + increment="0.25" initial_val="1" label="Falloff" label_width="55" + left="10" max_val="2" min_val="0" mouse_opaque="true" + name="Light Falloff" width="120" /> + -- cgit v1.1