diff options
Diffstat (limited to 'indra')
99 files changed, 3257 insertions, 1964 deletions
| diff --git a/indra/llcommon/lldarray.h b/indra/llcommon/lldarray.h index 0e56a11d53..af647c7e7a 100644 --- a/indra/llcommon/lldarray.h +++ b/indra/llcommon/lldarray.h @@ -202,7 +202,7 @@ public:  		{  			U32 n = mVector.size();  			mIndexMap[k] = n; -			mVector.resize(n+1); +			mVector.push_back(Type());  			llassert(mVector.size() == mIndexMap.size());  			return mVector[n];  		} diff --git a/indra/llcommon/llstrider.h b/indra/llcommon/llstrider.h index 369b06b48a..44ea80a36b 100644 --- a/indra/llcommon/llstrider.h +++ b/indra/llcommon/llstrider.h @@ -51,7 +51,7 @@ public:  	void setStride (S32 skipBytes)	{ mSkip = (skipBytes ? skipBytes : sizeof(Object));}  	void skip(const U32 index)     { mBytep += mSkip*index;} - +	U32 getSkip() const			   { return mSkip; }  	Object* get()                  { return mObjectp; }  	Object* operator->()           { return mObjectp; }  	Object& operator *()           { return *mObjectp; } diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp index c1022c1195..4bda00ed86 100755 --- a/indra/llcrashlogger/llcrashlogger.cpp +++ b/indra/llcrashlogger/llcrashlogger.cpp @@ -370,6 +370,8 @@ void LLCrashLogger::updateApplication(const std::string& message)  bool LLCrashLogger::init()  { +	LLCurl::initClass(); +  	// We assume that all the logs we're looking for reside on the current drive  	gDirUtilp->initAppDirs("SecondLife"); diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 34348230b6..3c3356f41d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -86,6 +86,8 @@ const F32 SKEW_MAX	=  0.95f;  const F32 SCULPT_MIN_AREA = 0.002f;  const S32 SCULPT_MIN_AREA_DETAIL = 1; +#define GEN_TRI_STRIP 0 +  BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLVector3& pt3, const LLVector3& norm)  {      	LLVector3 test = (pt2-pt1)%(pt3-pt2); @@ -1688,7 +1690,7 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge  	mGenerateSingleFace = generate_single_face;  	generate(); -	if (mParams.getSculptID().isNull()) +	if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE)  	{  		createVolumeFaces();  	} @@ -1864,6 +1866,11 @@ void LLVolume::createVolumeFaces()  			LLProfile::Face& face = mProfilep->mFaces[i];  			vf.mBeginS = face.mIndex;  			vf.mNumS = face.mCount; +			if (vf.mNumS < 0) +			{ +				llerrs << "Volume face corruption detected." << llendl; +			} +  			vf.mBeginT = 0;  			vf.mNumT= getPath().mPath.size();  			vf.mID = i; @@ -1907,6 +1914,10 @@ void LLVolume::createVolumeFaces()  					if (face.mFlat && vf.mNumS > 2)  					{ //flat inner faces have to copy vert normals  						vf.mNumS = vf.mNumS*2; +						if (vf.mNumS < 0) +						{ +							llerrs << "Volume face corruption detected." << llendl; +						}  					}  				}  				else @@ -4521,7 +4532,9 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  	if (!partial_build)  	{ +#if GEN_TRI_STRIP  		mTriStrip.clear(); +#endif  		S32 idxs[] = {0,1,(grid_size+1)+1,(grid_size+1)+1,(grid_size+1),0};  		for(S32 gx = 0;gx<grid_size;gx++)  		{ @@ -4535,6 +4548,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  						mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);  					} +#if GEN_TRI_STRIP  					if (gy == 0)  					{  						mTriStrip.push_back((gx+1)*(grid_size+1)); @@ -4550,6 +4564,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  					{  						mTriStrip.push_back(gy+1+gx*(grid_size+1));  					} +#endif  				}  				else  				{ @@ -4558,6 +4573,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  						mIndices.push_back(vtop+(gy*(grid_size+1))+gx+idxs[i]);  					} +#if GEN_TRI_STRIP  					if (gy == 0)  					{  						mTriStrip.push_back(gx*(grid_size+1)); @@ -4572,15 +4588,18 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)  					{  						mTriStrip.push_back(gy+1+(gx+1)*(grid_size+1));  					} +#endif  				}  			}  		} +#if GEN_TRI_STRIP  		if (mTriStrip.size()%2 == 1)  		{  			mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);  		} +#endif  	}  	return TRUE; @@ -4950,6 +4969,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  			mIndices[3*i+v2] = i + 1;  		} +#if GEN_TRI_STRIP  		//make tri strip  		if (mTypeMask & OPEN_MASK)  		{ @@ -4992,6 +5012,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  				mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);  			}  		} +#endif  	}  	return TRUE; @@ -4999,6 +5020,7 @@ BOOL LLVolumeFace::createCap(LLVolume* volume, BOOL partial_build)  void LLVolumeFace::makeTriStrip()  { +#if GEN_TRI_STRIP  	for (U32 i = 0; i < mIndices.size(); i+=3)  	{  		U16 i0 = mIndices[i]; @@ -5027,6 +5049,7 @@ void LLVolumeFace::makeTriStrip()  	{  		mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);  	} +#endif  }  void LLVolumeFace::createBinormals() @@ -5112,12 +5135,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  		mHasBinormals = FALSE;  	} - -	LLVector3& face_min = mExtents[0]; -	LLVector3& face_max = mExtents[1]; - -	mCenter.clearVec(); -  	S32 begin_stex = llfloor( profile[mBeginS].mV[2] );  	S32 num_s = ((mTypeMask & INNER_MASK) && (mTypeMask & FLAT_MASK) && mNumS > 2) ? mNumS/2 : mNumS; @@ -5173,15 +5190,6 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			mVertices[cur_vertex].mNormal = LLVector3(0,0,0);  			mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); -			 -			if (cur_vertex == 0) -			{ -				face_min = face_max = mesh[i].mPos; -			} -			else -			{ -				update_min_max(face_min, face_max, mesh[i].mPos); -			}  			cur_vertex++; @@ -5215,12 +5223,22 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  			mVertices[cur_vertex].mNormal = LLVector3(0,0,0);  			mVertices[cur_vertex].mBinormal = LLVector3(0,0,0); -			update_min_max(face_min,face_max,mesh[i].mPos); -  			cur_vertex++;  		}  	} + +	//get bounding box for this side +	LLVector3& face_min = mExtents[0]; +	LLVector3& face_max = mExtents[1]; +	mCenter.clearVec(); + +	face_min = face_max = mVertices[0].mPosition; +	for (U32 i = 1; i < mVertices.size(); ++i) +	{ +		update_min_max(face_min, face_max, mVertices[i].mPosition); +	} +  	mCenter = (face_min + face_max) * 0.5f;  	S32 cur_index = 0; @@ -5229,13 +5247,17 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  	if (!partial_build)  	{ +#if GEN_TRI_STRIP  		mTriStrip.clear(); +#endif  		// Now we generate the indices.  		for (t = 0; t < (mNumT-1); t++)  		{ +#if GEN_TRI_STRIP  			//prepend terminating index to strip  			mTriStrip.push_back(mNumS*t); +#endif  			for (s = 0; s < (mNumS-1); s++)  			{	 @@ -5246,6 +5268,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  				mIndices[cur_index++] = s+1 + mNumS*t;			//bottom right  				mIndices[cur_index++] = s+1 + mNumS*(t+1);		//top right +#if GEN_TRI_STRIP  				if (s == 0)  				{  					mTriStrip.push_back(s+mNumS*t); @@ -5253,6 +5276,7 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  				}  				mTriStrip.push_back(s+1+mNumS*t);  				mTriStrip.push_back(s+1+mNumS*(t+1)); +#endif  				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2+1;						//bottom left/top right neighbor face   				if (t < mNumT-2) {												//top right/top left neighbor face  @@ -5294,44 +5318,37 @@ BOOL LLVolumeFace::createSide(LLVolume* volume, BOOL partial_build)  				}  				mEdge[cur_edge++] = (mNumS-1)*2*t+s*2;							//top right/bottom left neighbor face	  			} +#if GEN_TRI_STRIP  			//append terminating vertex to strip  			mTriStrip.push_back(mNumS-1+mNumS*(t+1)); +#endif  		} +#if GEN_TRI_STRIP  		if (mTriStrip.size()%2 == 1)  		{  			mTriStrip.push_back(mTriStrip[mTriStrip.size()-1]);  		} +#endif  	}  	//generate normals   	for (U32 i = 0; i < mIndices.size()/3; i++) //for each triangle  	{ -		const S32 i0 = mIndices[i*3+0]; -		const S32 i1 = mIndices[i*3+1]; -		const S32 i2 = mIndices[i*3+2]; -		const VertexData& v0 = mVertices[i0]; -		const VertexData& v1 = mVertices[i1]; -		const VertexData& v2 = mVertices[i2]; +		const U16* idx = &(mIndices[i*3]); +			 +		VertexData* v[] =  +		{	&mVertices[idx[0]], &mVertices[idx[1]], &mVertices[idx[2]] };  		//calculate triangle normal -		LLVector3 norm = (v0.mPosition-v1.mPosition) % (v0.mPosition-v2.mPosition); +		LLVector3 norm = (v[0]->mPosition-v[1]->mPosition) % (v[0]->mPosition-v[2]->mPosition); -		for (U32 j = 0; j < 3; j++)  -		{ //add triangle normal to vertices -			const S32 idx = mIndices[i*3+j]; -			mVertices[idx].mNormal += norm; // * (weight_sum - d[j])/weight_sum; -		} +		v[0]->mNormal += norm; +		v[1]->mNormal += norm; +		v[2]->mNormal += norm;  		//even out quad contributions -		if ((i & 1) == 0)  -		{ -			mVertices[i2].mNormal += norm; -		} -		else  -		{ -			mVertices[i1].mNormal += norm; -		} +		v[i%2+1]->mNormal += norm;  	}  	// adjust normals based on wrapping and stitching diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp index 5e9dfd81fa..e3ce2c5ad3 100644 --- a/indra/llmessage/llpumpio.cpp +++ b/indra/llmessage/llpumpio.cpp @@ -444,13 +444,13 @@ void LLPumpIO::pump()  	pump(DEFAULT_POLL_TIMEOUT);  } -static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); +static LLFastTimer::DeclareTimer FTM_PUMP_IO("Pump IO");  //timeout is in microseconds  void LLPumpIO::pump(const S32& poll_timeout)  {  	LLMemType m1(LLMemType::MTYPE_IO_PUMP); -	LLFastTimer t1(FTM_PUMP); +	LLFastTimer t1(FTM_PUMP_IO);  	//llinfos << "LLPumpIO::pump()" << llendl;  	// Run any pending runners. @@ -778,6 +778,8 @@ bool LLPumpIO::respond(  	return true;  } +static LLFastTimer::DeclareTimer FTM_PUMP_CALLBACK_CHAIN("Chain"); +  void LLPumpIO::callback()  {  	LLMemType m1(LLMemType::MTYPE_IO_PUMP); @@ -799,6 +801,7 @@ void LLPumpIO::callback()  		callbacks_t::iterator end = mCallbacks.end();  		for(; it != end; ++it)  		{ +			LLFastTimer t(FTM_PUMP_CALLBACK_CHAIN);  			// it's always the first and last time for respone chains  			(*it).mHead = (*it).mChainLinks.begin();  			(*it).mInit = true; diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 4f828186cb..e67d436887 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -286,6 +286,7 @@ public:  	void setLightTexture(const LLUUID& id) { mLightTexture = id; }  	LLUUID getLightTexture() const         { return mLightTexture; } +	bool isLightSpotlight() const         { return mLightTexture.notNull(); }  	void setParams(const LLVector3& params) { mParams = params; }  	LLVector3 getParams() const			   { return mParams; } diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index a3f7a946ec..7ff68fe34b 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -185,6 +185,9 @@ PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT =  // GL_EXT_framebuffer_blit  PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL; +// GL_EXT_blend_func_separate +PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL; +  // GL_ARB_draw_buffers  PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB = NULL; @@ -324,6 +327,7 @@ LLGLManager::LLGLManager() :  	mHasCompressedTextures(FALSE),  	mHasFramebufferObject(FALSE),  	mHasFramebufferMultisample(FALSE), +	mHasBlendFuncSeparate(FALSE),  	mHasVertexBufferObject(FALSE),  	mHasPBuffer(FALSE), @@ -633,6 +637,11 @@ void LLGLManager::initExtensions()  #else  	mHasDrawBuffers = FALSE;  # endif +# if GL_EXT_blend_func_separate +	mHasBlendFuncSeparate = TRUE; +#else +	mHasBlendFuncSeparate = FALSE; +# endif  	mHasMipMapGeneration = FALSE;  	mHasSeparateSpecularColor = FALSE;  	mHasAnisotropic = FALSE; @@ -659,6 +668,7 @@ void LLGLManager::initExtensions()  		&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);  	mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);  	mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); +	mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);  	mHasTextureRectangle = ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts);  #if !LL_DARWIN  	mHasPointParameters = !mIsATI && ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); @@ -682,6 +692,7 @@ void LLGLManager::initExtensions()  		mHasFramebufferObject = FALSE;  		mHasFramebufferMultisample = FALSE;  		mHasDrawBuffers = FALSE; +		mHasBlendFuncSeparate = FALSE;  		mHasMipMapGeneration = FALSE;  		mHasSeparateSpecularColor = FALSE;  		mHasAnisotropic = FALSE; @@ -706,6 +717,7 @@ void LLGLManager::initExtensions()  		mHasShaderObjects = FALSE;  		mHasVertexShader = FALSE;  		mHasFragmentShader = FALSE; +		mHasBlendFuncSeparate = FALSE;  		LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL;  	}  	if (getenv("LL_GL_BLACKLIST"))	/* Flawfinder: ignore */ @@ -734,7 +746,8 @@ void LLGLManager::initExtensions()  		if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S  		if (strchr(blacklist,'s')) mHasFramebufferMultisample = FALSE;  		if (strchr(blacklist,'t')) mHasTextureRectangle = FALSE; - +		if (strchr(blacklist,'u')) mHasBlendFuncSeparate = FALSE;//S +		  	}  #endif // LL_LINUX || LL_SOLARIS @@ -782,6 +795,14 @@ void LLGLManager::initExtensions()  	{  		LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_fragment_shader" << LL_ENDL;  	} +	if (!mHasBlendFuncSeparate) +	{ +		LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; +	} +	if (!mHasDrawBuffers) +	{ +		LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL; +	}  	// Disable certain things due to known bugs  	if (mIsIntel && mHasMipMapGeneration) @@ -852,6 +873,10 @@ void LLGLManager::initExtensions()  	{  		glDrawBuffersARB = (PFNGLDRAWBUFFERSARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDrawBuffersARB");  	} +	if (mHasBlendFuncSeparate) +	{ +		glBlendFuncSeparateEXT = (PFNGLBLENDFUNCSEPARATEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlendFuncSeparateEXT"); +	}  #if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS  	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah  	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements"); @@ -1014,24 +1039,9 @@ void flush_glerror()  	glGetError();  } -void assert_glerror() +void do_assert_glerror()  { -	if (!gGLActive) -	{ -		//llwarns << "GL used while not active!" << llendl; - -		if (gDebugSession) -		{ -			//ll_fail("GL used while not active"); -		} -	} - -	if (gNoRender || !gDebugGL)  -	{ -		return; -	} -	 -	if (!gGLManager.mInited) +	if (LL_UNLIKELY(!gGLManager.mInited))  	{  		LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;  	} @@ -1039,10 +1049,9 @@ void assert_glerror()  	GLenum error;  	error = glGetError();  	BOOL quit = FALSE; -	while (error) +	while (LL_UNLIKELY(error))  	{  		quit = TRUE; -#ifndef LL_LINUX // *FIX: !  This should be an error for linux as well.  		GLubyte const * gl_error_msg = gluErrorString(error);  		if (NULL != gl_error_msg)  		{ @@ -1066,7 +1075,6 @@ void assert_glerror()  			}  		}  		error = glGetError(); -#endif  	}  	if (quit) @@ -1082,6 +1090,25 @@ void assert_glerror()  	}  } +void assert_glerror() +{ +	if (!gGLActive) +	{ +		//llwarns << "GL used while not active!" << llendl; + +		if (gDebugSession) +		{ +			//ll_fail("GL used while not active"); +		} +	} + +	if (!gNoRender && gDebugGL)  +	{ +		do_assert_glerror(); +	} +} +	 +  void clear_glerror()  {  	//  Create or update texture to be used with this data  diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 91421f3c95..0c2da7dd08 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -87,6 +87,7 @@ public:  	BOOL mHasCompressedTextures;  	BOOL mHasFramebufferObject;  	BOOL mHasFramebufferMultisample; +	BOOL mHasBlendFuncSeparate;  	// ARB Extensions  	BOOL mHasVertexBufferObject; diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f33ae7d8f0..f6d35bc766 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -216,6 +216,9 @@ extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;  extern PFNGLCOLORTABLEEXTPROC glColorTableEXT; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; +  //GL_EXT_framebuffer_object  extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;  extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -249,7 +252,10 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;  # include "GL/glh_extensions.h"  # undef __APPLE__ -#elif LL_LINUX  +#elif LL_LINUX +//---------------------------------------------------------------------------- +// LL_LINUX +  //----------------------------------------------------------------------------  // Linux, MESA headers, but not necessarily assuming MESA runtime.  // quotes so we get libraries/.../GL/ version @@ -285,6 +291,7 @@ extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;  # define LL_LINUX_NV_GL_HEADERS 0  #endif // LL_LINUX && defined(WINGDIAPI) +  #if LL_LINUX_NV_GL_HEADERS  // Missing functions when using nvidia headers:  extern PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB; @@ -445,6 +452,9 @@ extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;  extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;  extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; +  //GL_EXT_framebuffer_object  extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;  extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -473,7 +483,10 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;  //GL_ARB_draw_buffers  extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +  #elif LL_WINDOWS +//---------------------------------------------------------------------------- +// LL_WINDOWS  // windows gl headers depend on things like APIENTRY, so include windows.  #define WIN32_LEAN_AND_MEAN @@ -641,6 +654,9 @@ extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;  extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;  extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB; +//GL_EXT_blend_func_separate +extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; +  //GL_EXT_framebuffer_object  extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;  extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT; @@ -669,6 +685,7 @@ extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;  //GL_ARB_draw_buffers  extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB; +  #elif LL_DARWIN  //----------------------------------------------------------------------------  // LL_DARWIN @@ -685,6 +702,9 @@ extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;  // Note that they also must not be called on 10.3.9.  This should be taken care of by a runtime check for the existence of the GL extension.  #include <AvailabilityMacros.h> +//GL_EXT_blend_func_separate +extern void glBlendFuncSeparateEXT(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; +  // GL_EXT_framebuffer_object  extern GLboolean glIsRenderbufferEXT(GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;  extern void glBindRenderbufferEXT(GLenum target, GLuint renderbuffer) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index ff47c57c70..2f02ccf30b 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -1645,7 +1645,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()  	}  } -void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h) +void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)  {  	if(!mNeedsAlphaAndPickMask)  	{ @@ -1653,26 +1653,91 @@ void LLImageGL::analyzeAlpha(const void* data_in, S32 w, S32 h)  	}  	U32 length = w * h; -	const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset ; +	U32 alphatotal = 0; -	S32 sample[16]; -	memset(sample, 0, sizeof(S32)*16); - -	for (U32 i = 0; i < length; i++) +	U32 sample[16]; +	memset(sample, 0, sizeof(U32)*16); + +	// generate histogram of quantized alpha. +	// also add-in the histogram of a 2x2 box-sampled version.  The idea is +	// this will mid-skew the data (and thus increase the chances of not +	// being used as a mask) from high-frequency alpha maps which +	// suffer the worst from aliasing when used as alpha masks. +	if (w >= 2 && h >= 2) +	{ +		llassert(w%2 == 0); +		llassert(h%2 == 0); +		const GLubyte* rowstart = ((const GLubyte*) data_in) + mAlphaOffset; +		for (U32 y = 0; y < h; y+=2) +		{ +			const GLubyte* current = rowstart; +			for (U32 x = 0; x < w; x+=2) +			{ +				const U32 s1 = current[0]; +				alphatotal += s1; +				const U32 s2 = current[w * mAlphaStride]; +				alphatotal += s2; +				current += mAlphaStride; +				const U32 s3 = current[0]; +				alphatotal += s3; +				const U32 s4 = current[w * mAlphaStride]; +				alphatotal += s4; +				current += mAlphaStride; + +				++sample[s1/16]; +				++sample[s2/16]; +				++sample[s3/16]; +				++sample[s4/16]; + +				const U32 asum = (s1+s2+s3+s4); +				alphatotal += asum; +				sample[asum/(16*4)] += 4; +			} +			 +			rowstart += 2 * w * mAlphaStride; +		} +		length *= 2; // we sampled everything twice, essentially +	} +	else  	{ -		++sample[*current/16]; -		current += mAlphaStride ; +		const GLubyte* current = ((const GLubyte*) data_in) + mAlphaOffset; +		for (U32 i = 0; i < length; i++) +		{ +			const U32 s1 = *current; +			alphatotal += s1; +			++sample[s1/16]; +			current += mAlphaStride; +		}  	} +	 +	// if more than 1/16th of alpha samples are mid-range, this +	// shouldn't be treated as a 1-bit mask -	U32 total = 0; +	// also, if all of the alpha samples are clumped on one half +	// of the range (but not at an absolute extreme), then consider +	// this to be an intentional effect and don't treat as a mask. + +	U32 midrangetotal = 0;  	for (U32 i = 4; i < 11; i++)  	{ -		total += sample[i]; +		midrangetotal += sample[i]; +	} +	U32 lowerhalftotal = 0; +	for (U32 i = 0; i < 8; i++) +	{ +		lowerhalftotal += sample[i]; +	} +	U32 upperhalftotal = 0; +	for (U32 i = 8; i < 16; i++) +	{ +		upperhalftotal += sample[i];  	} -	if (total > length/16) +	if (midrangetotal > length/16 || // lots of midrange, or +	    (lowerhalftotal == length && alphatotal != 0) || // all close to transparent but not all totally transparent, or +	    (upperhalftotal == length && alphatotal != 255*length)) // all close to opaque but not all totally opaque  	{ -		mIsMask = FALSE; +		mIsMask = FALSE; // not suitable for masking  	}  	else  	{ diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index 41239d24c8..03939888a5 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -91,7 +91,7 @@ public:  protected:  	virtual ~LLImageGL(); -	void analyzeAlpha(const void* data_in, S32 w, S32 h); +	void analyzeAlpha(const void* data_in, U32 w, U32 h);  	void calcAlphaChannelOffsetAndStride();  public: diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index c3540a717c..5597b23c69 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -778,8 +778,10 @@ LLRender::LLRender()  	mCurrAlphaFunc = CF_DEFAULT;  	mCurrAlphaFuncVal = 0.01f; -	mCurrBlendSFactor = BF_UNDEF; -	mCurrBlendDFactor = BF_UNDEF; +	mCurrBlendColorSFactor = BF_UNDEF; +	mCurrBlendAlphaSFactor = BF_UNDEF; +	mCurrBlendColorDFactor = BF_UNDEF; +	mCurrBlendAlphaDFactor = BF_UNDEF;  }  LLRender::~LLRender() @@ -995,15 +997,44 @@ void LLRender::blendFunc(eBlendFactor sfactor, eBlendFactor dfactor)  {  	llassert(sfactor < BF_UNDEF);  	llassert(dfactor < BF_UNDEF); -	if (mCurrBlendSFactor != sfactor || mCurrBlendDFactor != dfactor) +	if (mCurrBlendColorSFactor != sfactor || mCurrBlendColorDFactor != dfactor || +	    mCurrBlendAlphaSFactor != sfactor || mCurrBlendAlphaDFactor != dfactor)  	{ -		mCurrBlendSFactor = sfactor; -		mCurrBlendDFactor = dfactor; +		mCurrBlendColorSFactor = sfactor; +		mCurrBlendAlphaSFactor = sfactor; +		mCurrBlendColorDFactor = dfactor; +		mCurrBlendAlphaDFactor = dfactor;  		flush();  		glBlendFunc(sGLBlendFactor[sfactor], sGLBlendFactor[dfactor]);  	}  } +void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, +			 eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor) +{ +	llassert(color_sfactor < BF_UNDEF); +	llassert(color_dfactor < BF_UNDEF); +	llassert(alpha_sfactor < BF_UNDEF); +	llassert(alpha_dfactor < BF_UNDEF); +	if (!gGLManager.mHasBlendFuncSeparate) +	{ +		LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << llendl; +		blendFunc(color_sfactor, color_dfactor); +		return; +	} +	if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || +	    mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) +	{ +		mCurrBlendColorSFactor = color_sfactor; +		mCurrBlendAlphaSFactor = alpha_sfactor; +		mCurrBlendColorDFactor = color_dfactor; +		mCurrBlendAlphaDFactor = alpha_dfactor; +		flush(); +		glBlendFuncSeparateEXT(sGLBlendFactor[color_sfactor], sGLBlendFactor[color_dfactor], +				       sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]); +	} +} +  LLTexUnit* LLRender::getTexUnit(U32 index)  {  	if (index < mTexUnits.size()) diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index a90fbd4a5c..f6c87aa1db 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -323,7 +323,11 @@ public:  	void setAlphaRejectSettings(eCompareFunc func, F32 value = 0.01f); +	// applies blend func to both color and alpha  	void blendFunc(eBlendFactor sfactor, eBlendFactor dfactor); +	// applies separate blend functions to color and alpha +	void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, +		       eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);  	LLTexUnit* getTexUnit(U32 index); @@ -362,8 +366,10 @@ private:  	std::vector<LLTexUnit*>		mTexUnits;  	LLTexUnit*			mDummyTexUnit; -	eBlendFactor mCurrBlendSFactor; -	eBlendFactor mCurrBlendDFactor; +	eBlendFactor mCurrBlendColorSFactor; +	eBlendFactor mCurrBlendColorDFactor; +	eBlendFactor mCurrBlendAlphaSFactor; +	eBlendFactor mCurrBlendAlphaDFactor;  	F32				mMaxAnisotropy; diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bf5eda21eb..ae43915a9d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -61,6 +61,7 @@ BOOL LLVertexBuffer::sVBOActive = FALSE;  BOOL LLVertexBuffer::sIBOActive = FALSE;  U32 LLVertexBuffer::sAllocatedBytes = 0;  BOOL LLVertexBuffer::sMapped = FALSE; +BOOL LLVertexBuffer::sUseStreamDraw = TRUE;  std::vector<U32> LLVertexBuffer::sDeleteList; @@ -381,6 +382,11 @@ LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) :  	{  		mUsage = 0 ;   	} + +	if (mUsage == GL_STREAM_DRAW_ARB && !sUseStreamDraw) +	{ +		mUsage = 0; +	}  	S32 stride = calcStride(typemask, mOffsets); diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index b785a22976..e2fecdffef 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -83,6 +83,8 @@ public:  	static LLVBOPool sDynamicVBOPool;  	static LLVBOPool sStreamIBOPool;  	static LLVBOPool sDynamicIBOPool; +	 +	static BOOL	sUseStreamDraw;  	static void initClass(bool use_vbo);  	static void cleanupClass(); diff --git a/indra/newview/app_settings/high_graphics.xml b/indra/newview/app_settings/high_graphics.xml index 6368f7099e..587b2f2a89 100644 --- a/indra/newview/app_settings/high_graphics.xml +++ b/indra/newview/app_settings/high_graphics.xml @@ -12,8 +12,6 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="9"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="4096"/>  	<!--bump okay--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="TRUE"/> +  <!--Deferred Shading--> +  <RenderDeferred value="FALSE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--Sun Shadows--> +  <RenderShadowDetail value="0"/> +  </settings> diff --git a/indra/newview/app_settings/low_graphics.xml b/indra/newview/app_settings/low_graphics.xml index d02a13a671..a5bbdfc1d0 100644 --- a/indra/newview/app_settings/low_graphics.xml +++ b/indra/newview/app_settings/low_graphics.xml @@ -14,8 +14,6 @@  	<RenderFlexTimeFactor value="0.5"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="8"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="0"/>  	<!--Low number-->  	<RenderMaxPartCount value="1024"/>  	<!--bump okay--> @@ -33,9 +31,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="FALSE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="FALSE"/> +  <!--No Deferred Shading--> +  <RenderDeferred value="FALSE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--No Shadows--> +  <RenderShadowDetail value="0"/> +  </settings> diff --git a/indra/newview/app_settings/mid_graphics.xml b/indra/newview/app_settings/mid_graphics.xml index 12da77da40..a1430a58f9 100644 --- a/indra/newview/app_settings/mid_graphics.xml +++ b/indra/newview/app_settings/mid_graphics.xml @@ -12,8 +12,6 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="8"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="2048"/>  	<!--bump okay--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="1.125"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="FALSE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="FALSE"/> +  <!--No Deferred Shading--> +  <RenderDeferred value="FALSE"/> +  <!--SSAO Disabled--> +  <RenderDeferredSSAO value="FALSE"/> +  <!--No Shadows--> +  <RenderShadowDetail value="0"/> +  </settings> diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index c0be54a105..c2f110e8fc 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -6318,7 +6318,7 @@      <key>Type</key>      <string>U32</string>      <key>Value</key> -    <integer>60</integer> +    <integer>200</integer>    </map>    <key>RenderSSAOFactor</key>    <map> @@ -6693,6 +6693,64 @@      <real>0.01</real>    </map> +  <key>RenderShadowBiasError</key> +  <map> +    <key>Comment</key> +    <string>Error scale for shadow bias (based on altitude).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0</real> +  </map> +  <key>RenderShadowOffsetError</key> +  <map> +    <key>Comment</key> +    <string>Error scale for shadow offset (based on altitude).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0</real> +  </map> +   +  <key>RenderSpotLightsInNondeferred</key> +  <map> +    <key>Comment</key> +    <string>Whether to support projectors as spotlights when Lighting and Shadows is disabled</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>0</integer> +  </map> + +  <key>RenderSpotShadowBias</key> +  <map> +    <key>Comment</key> +    <string>Bias value for shadows (prevent shadow acne).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0.0</real> +  </map> +  <key>RenderSpotShadowOffset</key> +  <map> +    <key>Comment</key> +    <string>Offset value for shadows (prevent shadow acne).</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>F32</string> +    <key>Value</key> +    <real>0.04</real> +  </map> +    <key>RenderShadowResolutionScale</key>    <map>      <key>Comment</key> @@ -6705,8 +6763,6 @@      <real>1.0</real>    </map> - -    <key>RenderDeferredTreeShadowBias</key>    <map>      <key>Comment</key> @@ -6828,7 +6884,7 @@      <key>Type</key>      <string>F32</string>      <key>Value</key> -    <real>1</real> +    <real>8</real>    </map>    <key>RenderDeferred</key> @@ -6842,19 +6898,7 @@      <key>Value</key>      <integer>0</integer>    </map> - -  <key>RenderDeferredShadow</key> -  <map> -    <key>Comment</key> -    <string>Enable shadows in deferred renderer.</string> -    <key>Persist</key> -    <integer>1</integer> -    <key>Type</key> -    <string>Boolean</string> -    <key>Value</key> -    <integer>1</integer> -  </map> - +      <key>RenderDeferredGI</key>    <map>      <key>Comment</key> @@ -6867,10 +6911,10 @@      <integer>0</integer>    </map> -  <key>RenderDeferredSunShadow</key> +  <key>RenderDeferredSun</key>    <map>      <key>Comment</key> -    <string>Generate shadows from the sun.</string> +    <string>Execute sunlight shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -6879,10 +6923,10 @@      <integer>1</integer>    </map> -  <key>RenderDeferredSun</key> +  <key>RenderDeferredAtmospheric</key>    <map>      <key>Comment</key> -    <string>Execute sunlight shader in deferred renderer.</string> +    <string>Execute atmospheric shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -6891,10 +6935,10 @@      <integer>1</integer>    </map> -  <key>RenderDeferredAtmospheric</key> +  <key>RenderDeferredSSAO</key>    <map>      <key>Comment</key> -    <string>Execute atmospheric shader in deferred renderer.</string> +    <string>Execute screen space ambient occlusion shader in deferred renderer.</string>      <key>Persist</key>      <integer>1</integer>      <key>Type</key> @@ -7153,10 +7197,10 @@        <key>Value</key>        <real>256.0</real>      </map> -    <key>RenderFastAlpha</key> +    <key>RenderAutoMaskAlphaNonDeferred</key>      <map>        <key>Comment</key> -      <string>Use lossy alpha rendering optimization (opaque/nonexistent small alpha faces).</string> +      <string>Use alpha masks where appropriate, in the non-deferred (non-'Lighting and Shadows') graphics mode</string>        <key>Persist</key>        <integer>1</integer>        <key>Type</key> @@ -7164,6 +7208,17 @@        <key>Value</key>        <integer>0</integer>      </map> +    <key>RenderAutoMaskAlphaDeferred</key> +    <map> +      <key>Comment</key> +      <string>Use alpha masks where appropriate, in the deferred ('Lighting and Shadows') graphics mode</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>Boolean</string> +      <key>Value</key> +      <integer>1</integer> +    </map>      <key>RenderFastUI</key>      <map>        <key>Comment</key> @@ -7425,17 +7480,6 @@        <key>Value</key>        <integer>0</integer>      </map> -    <key>RenderLightingDetail</key> -    <map> -      <key>Comment</key> -      <string>Amount of detail for lighting objects/avatars/terrain (0=sun/moon only, 1=enable local lights)</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>S32</string> -      <key>Value</key> -      <integer>1</integer> -    </map>      <key>RenderMaxPartCount</key>      <map>        <key>Comment</key> @@ -7535,7 +7579,19 @@        <key>Value</key>        <integer>2</integer>      </map> -    <key>RenderReflectionRes</key> +    <key>RenderShadowDetail</key> +    <map> +      <key>Comment</key> +      <string>Detail of shadows.</string> +      <key>Persist</key> +      <integer>1</integer> +      <key>Type</key> +      <string>S32</string> +      <key>Value</key> +      <integer>2</integer> +    </map> + +  <key>RenderReflectionRes</key>      <map>        <key>Comment</key>        <string>Reflection map resolution.</string> @@ -7665,7 +7721,7 @@        <key>Type</key>        <string>Boolean</string>        <key>Value</key> -      <integer>0</integer> +      <integer>1</integer>      </map>      <key>RenderUIBuffer</key>      <map> @@ -7766,6 +7822,17 @@        <key>Value</key>        <integer>1</integer>      </map> +  <key>RenderUseStreamVBO</key> +  <map> +    <key>Comment</key> +    <string>Use VBO's for stream buffers</string> +    <key>Persist</key> +    <integer>1</integer> +    <key>Type</key> +    <string>Boolean</string> +    <key>Value</key> +    <integer>1</integer> +  </map>      <key>RenderVolumeLODFactor</key>      <map>        <key>Comment</key> @@ -7810,17 +7877,6 @@        <key>Value</key>        <integer>512</integer>      </map> -    <key>RenderWaterReflections</key> -    <map> -      <key>Comment</key> -      <string>Reflect the environment in the water.</string> -      <key>Persist</key> -      <integer>1</integer> -      <key>Type</key> -      <string>Boolean</string> -      <key>Value</key> -      <integer>0</integer> -    </map>      <key>RotateRight</key>      <map>        <key>Comment</key> diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl index 4fb109d687..fea2e16090 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaF.glsl @@ -24,8 +24,6 @@ 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) @@ -57,15 +55,6 @@ void main()  	color.rgb = scaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && gl_Color.a < 1.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); diff --git a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl index 1a7d58b07b..04e556c11a 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/alphaV.glsl @@ -9,7 +9,7 @@ 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); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -41,23 +41,22 @@ void main()  	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); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// 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[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_light = gl_LightSource[0].position.xyz;  	vary_ambient = col.rgb*gl_Color.rgb; diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl index c1988d3c78..650fbcc3f5 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarAlphaV.glsl @@ -10,7 +10,7 @@ mat4 getSkinnedTransform();  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -47,23 +47,22 @@ void main()  	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); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// 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[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	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))); diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl index 75df388941..afbe08a579 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarF.glsl @@ -20,6 +20,7 @@ void main()  	gl_FragData[0] = vec4(diff.rgb, 0.0);  	gl_FragData[1] = vec4(0,0,0,0); -	gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +	vec3 nvn = normalize(vary_normal); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl index 00083eb6b3..085ffddeec 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/avatarShadowF.glsl @@ -10,7 +10,7 @@ uniform sampler2D diffuseMap;  void main()   { -	gl_FragColor = vec4(1,1,1,gl_Color.a * texture2D(diffuseMap, gl_TexCoord[0].xy).a); -	//gl_FragColor = vec4(1,1,1,1); +	//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/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl index bd5e9dd758..d1c5d7cb19 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/blurLightF.glsl @@ -10,13 +10,11 @@  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap;  uniform sampler2DRect lightMap; -uniform sampler2DRect giLightMap;  uniform float dist_factor;  uniform float blur_size;  uniform vec2 delta; -uniform vec3 kern[32]; -uniform int kern_length; +uniform vec3 kern[4];  uniform float kern_scale;  varying vec2 vary_fragcoord; @@ -39,7 +37,8 @@ vec4 getPosition(vec2 pos_screen)  void main()   { -	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	vec3 pos = getPosition(vary_fragcoord.xy).xyz;  	vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; @@ -50,7 +49,7 @@ void main()  	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++) +	for (int i = 1; i < 4; i++)  	{  		vec2 tc = vary_fragcoord.xy + kern[i].z*dlt;  	        vec3 samppos = getPosition(tc).xyz;  @@ -61,12 +60,22 @@ void main()  			defined_weight += kern[i].xy;  		}  	} +	for (int i = 1; i < 4; 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/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl index 1c29dae5f7..2197744a37 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/bumpF.glsl @@ -14,14 +14,16 @@ varying vec3 vary_mat2;  void main()   { -	vec3 col = texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; +	vec3 col = gl_Color.rgb * 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)); +			  dot(norm,vary_mat1), +			  dot(norm,vary_mat2)); -	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); +	gl_FragData[0] = vec4(col, 0.0); +	gl_FragData[1] = gl_Color.aaaa; // spec +	//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested +	vec3 nvn = normalize(tnorm); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl index 5895ebda84..3803119cda 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/diffuseF.glsl @@ -11,8 +11,10 @@ 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(col*(gl_Color.a*1.5), gl_Color.a); -	gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +	vec3 col = gl_Color.rgb * texture2D(diffuseMap, gl_TexCoord[0].xy).rgb; +	gl_FragData[0] = vec4(col, 0.0); +	gl_FragData[1] = gl_Color.aaaa; // spec +	//gl_FragData[1] = vec4(vec3(gl_Color.a), gl_Color.a+(1.0-gl_Color.a)*gl_Color.a); // spec - from former class3 - maybe better, but not so well tested +	vec3 nvn = normalize(vary_normal); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index e518bddb98..0db9586a88 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -23,8 +23,6 @@ varying vec4 vary_position;  varying vec3 vary_normal;  varying vec3 vary_fragcoord; -uniform float alpha_soften; -  uniform mat4 inv_proj;  vec4 getPosition(vec2 pos_screen) @@ -56,15 +54,6 @@ void main()  	color.rgb = fullbrightScaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && color.a < 1.0) -	{ -		float dist_factor = alpha_soften; -		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); -	} -  	//gl_FragColor = gl_Color;  	gl_FragColor = color;  	//gl_FragColor = vec4(1,0,1,1); diff --git a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl index b351eec6e5..d4b153c4af 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/giF.glsl @@ -159,7 +159,8 @@ void main()  {  	vec2 pos_screen = vary_fragcoord.xy;  	vec4 pos = getPosition(pos_screen); -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	gl_FragData[0].xyz = giAmbient(pos, norm);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl index 8c140a7b4f..508bbf415e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl @@ -11,7 +11,8 @@ uniform sampler2D specularMap;  void main()   { -	gl_FragData[0] = texture2D(diffuseMap, gl_TexCoord[0].xy); +	vec4 col = texture2D(diffuseMap, gl_TexCoord[0].xy); +	gl_FragData[0] = vec4(col.rgb, col.a <= 0.5 ? 0.0 : 0.005);  	gl_FragData[1] = texture2D(specularMap, gl_TexCoord[0].xy);  	gl_FragData[2] = vec4(texture2D(normalMap, gl_TexCoord[0].xy).xyz, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl index 797b9e9f3b..b494b521ca 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl @@ -53,7 +53,9 @@ void main()  		discard;  	} -	vec3 norm = normalize(texture2DRect(normalMap, frag.xy).xyz*2.0-1.0); +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +	norm = normalize(norm);  	vec4 spec = texture2DRect(specularRect, frag.xy);  	vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;  	float noise = texture2D(noiseMap, frag.xy/128.0).b; diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl index 28bcd720c0..82e9450e68 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl @@ -5,9 +5,10 @@   * $License$   */ -  #version 120 +//class 1 -- no shadows +  #extension GL_ARB_texture_rectangle : enable  uniform sampler2DRect diffuseRect; @@ -26,12 +27,15 @@ 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; @@ -40,6 +44,52 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -68,7 +118,7 @@ void main()  	{  		discard;  	} -	 +		  	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0;  	norm = normalize(norm); @@ -83,7 +133,11 @@ void main()  	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); +	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); @@ -101,32 +155,32 @@ void main()  		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); +			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);  			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a;  			lit = da * dist_atten * noise;  			col = lcol*lit*diff_tex; +			amb_da += (da*0.5)*proj_ambiance;  		} -		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; -		 +		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); +		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_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;  	} @@ -144,35 +198,28 @@ void main()  		{  			vec3 pfinal = pos + ref * dot(pdelta, proj_n)/ds; -			vec3 stc = (proj_mat * vec4(pfinal.xyz, 1.0)).xyz; +			vec4 stc = (proj_mat * vec4(pfinal.xyz, 1.0));  			if (stc.z > 0.0)  			{ -				stc.xy /= stc.z+proj_near; -					 +				stc.xy /= stc.w; + +				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								  				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); +					vec4 scol = texture2DLodSpecular(projectionMap, stc.xy, proj_lod-spec.a*proj_lod);  					col += dist_atten*scol.rgb*gl_Color.rgb*scol.a*spec.rgb;  				}  			}  		}  	} -	/*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; -	}*/ -	  	gl_FragColor.rgb = col;	  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl index 78256e20cc..3aecbc5f23 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl @@ -55,7 +55,8 @@ void main()  		discard;  	} -	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	float da = dot(norm, lv);  	if (da < 0.0)  	{ diff --git a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl index 9612aee405..bd554c2d84 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postgiF.glsl @@ -38,10 +38,10 @@ vec4 getPosition(vec2 pos_screen)  void main()   { -	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	vec3 pos = getPosition(vary_fragcoord.xy).xyz; -	  	vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb;  	vec2 dlt = kern_scale * delta/(1.0+norm.xy*norm.xy);  	dlt /= max(-pos.z*dist_factor, 1.0); @@ -51,9 +51,10 @@ void main()  	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; +		vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz; +		sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm -	    float d = dot(norm.xyz, sampNorm); +		float d = dot(norm.xyz, sampNorm);  		if (d > 0.8)  		{ diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl index b4b0d0ce9d..bef91e735d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl @@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect positionMap;  uniform sampler2DRect normalMap; +uniform sampler2DRect lightMap;  uniform sampler2DRect depthMap;  uniform sampler2D	  noiseMap;  uniform samplerCube environmentMap; @@ -40,7 +41,7 @@ uniform float scene_light_strength;  uniform vec3 env_mat[3];  //uniform mat4 shadow_matrix[3];  //uniform vec4 shadow_clip; -//uniform mat3 ssao_effect_mat; +uniform mat3 ssao_effect_mat;  varying vec4 vary_light;  varying vec2 vary_fragcoord; @@ -55,9 +56,8 @@ vec3 vary_AtmosAttenuation;  uniform mat4 inv_proj;  uniform vec2 screen_res; -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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -68,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -178,7 +184,17 @@ void calcAtmospherics(vec3 inPositionEye, float ambFactor) {  	temp2.x += .25;  	//increase ambient when there are more clouds -	vec4 tmpAmbient = ambient + (vec4(1.) - ambient) * cloud_shadow.x * 0.5;	 +	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( @@ -241,8 +257,10 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz; +	vec3 norm = texture2DRect(normalMap, tc).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;  	float da = max(dot(norm.xyz, vary_light.xyz), 0.0); @@ -250,23 +268,76 @@ void main()  	vec4 diffuse = texture2DRect(diffuseRect, tc);  	vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy); -	calcAtmospherics(pos.xyz, 0.0); +	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(clamp(da, diffuse.a, 1.0)); +	col += atmosAffectDirectionalLight(max(min(da, scol), diffuse.a));  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		vec3 ref = normalize(reflect(pos.xyz, norm.xyz)); -		float sa = dot(ref, vary_light.xyz); -		col.rgb += vary_SunlitColor*spec.rgb*texture2D(lightFunc, vec2(sa, spec.a)).a; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		float sa = dot(refnormpersp, vary_light.xyz); +		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + +		/* +		// screen-space cheap fakey reflection map +		// +		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); +		depth -= 0.5; // unbias depth +		// first figure out where we'll make our 2D guess from +		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; +		// Offset the guess source a little according to a trivial +		// checkerboard dither function and spec.a. +		// This is meant to be similar to sampling a blurred version +		// of the diffuse map.  LOD would be better in that regard. +		// The goal of the blur is to soften reflections in surfaces +		// with low shinyness, and also to disguise our lameness. +		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 +		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); +		ref2d += vec2(checkoffset, checkoffset); +		ref2d += tc.xy; // use as offset from destination +		// Get attributes from the 2D guess point. +		// We average two samples of diffuse (not of anything else) per +		// pixel to try to reduce aliasing some more. +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + +				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		vec3 refn = texture2DRect(normalMap, ref2d).rgb; +		refn = normalize(vec3((refn.xy-0.5)*2.0,refn.z)); // unpack norm +		// figure out how appropriate our guess actually was +		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); +		// darken reflections from points which face away from the reflected ray - our guess was a back-face +		//refapprop *= step(dot(refnorm, refn), 0.0); +		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant +		// get appropriate light strength for guess-point. +		// reflect light direction to increase the illusion that +		// these are reflections. +		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); +		float reflit = max(dot(refn, reflight.xyz), 0.0); +		// apply sun color to guess-point, dampen according to inappropriateness of guess +		float refmod = min(refapprop, reflit); +		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; +		vec3 ssshiny = (refprod * spec.a); +		ssshiny *= 0.3; // dampen it even more +		*/ +		vec3 ssshiny = vec3(0,0,0); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	col = atmosLighting(col);  	col = scaleSoftClip(col); -	 +		  	gl_FragColor.rgb = col;  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl index 2a7234fd83..1b95b253c3 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/spotLightF.glsl @@ -68,7 +68,8 @@ void main()  		discard;  	} -	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -161,17 +162,6 @@ void main()  		}  	} -	/*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; -	}*/ -	  	gl_FragColor.rgb = col;	  	gl_FragColor.a = 0.0;  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl index 22bdd2c7f3..56e4055c02 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightF.glsl @@ -5,196 +5,11 @@   * $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; -} +//class 1, no shadow, no SSAO, should never be called -//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)); -} +#extension GL_ARB_texture_rectangle : enable  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 (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 (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; -		} - -		// 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 - just use directional shading as shadow -		shadow = dp_directional_light; -	} -	 -	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; +	gl_FragColor = vec4(0,0,0,0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl new file mode 100644 index 0000000000..cdbed4b791 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/sunLightSSAOF.glsl @@ -0,0 +1,124 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +//class 1 -- no shadow, SSAO only + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +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) +{ +	float ret = 1.0; +	 +	float dist = dot(pos.xyz,pos.xyz); +	 +	if (dist < 64.0*64.0) +	{ +		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); +		 +		ret = (1.0 - (float(points != 0) * angle_hidden)); +		ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); +	} +	 +	return min(ret, 1.0); +} + +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; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm +		 +	gl_FragColor[0] = 1.0; +	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	gl_FragColor[2] = 1.0;  +	gl_FragColor[3] = 1.0; +} diff --git a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl index 3cccfb7202..fa0a60c98d 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/terrainF.glsl @@ -29,6 +29,7 @@ void main()  	gl_FragData[0] = vec4(outColor.rgb, 0.0);  	gl_FragData[1] = vec4(outColor.rgb*0.2, 0.2); -	gl_FragData[2] = vec4(normalize(vary_normal)*0.5+0.5, 0.0); +	vec3 nvn = normalize(vary_normal); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl index 258acee08c..5b33ea5bfe 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/treeF.glsl @@ -14,5 +14,6 @@ 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); +	vec3 nvn = normalize(vary_normal); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl index d21575119d..361ae8dc84 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/waterF.glsl @@ -115,7 +115,7 @@ void main()  	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 +	// Note we actually want to use just df1, but multiplying by 0.999999 gets around an nvidia compiler bug  	color.rgb = mix(fb.rgb, refcol.rgb, df1 * 0.99999);  	float shadow = 1.0; @@ -131,11 +131,11 @@ void main()  	//color.rgb = scaleSoftClip(color.rgb);  	//color.a = spec * sunAngle2; -	//wavef.z = -0.25f; -	wavef = normalize(wavef); -	wavef = (norm_mat*vec4(wavef, 1.0)).xyz; +	//wavef.z *= 0.1f; +	//wavef = normalize(wavef); +	vec3 screenspacewavef = (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.0); +	gl_FragData[0] = vec4(color.rgb, 0.5); // diffuse +	gl_FragData[1] = vec4(0.5,0.5,0.5, 0.95); // speccolor*spec, spec +	gl_FragData[2] = vec4(screenspacewavef.xy*0.5+0.5, screenspacewavef.z, screenspacewavef.z*0.5); // normalxyz, displace  } diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl index 3e8fdfb3e4..da49e59b89 100644 --- a/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl +++ b/indra/newview/app_settings/shaders/class1/lighting/lightFuncV.glsl @@ -12,7 +12,8 @@ float calcDirectionalLight(vec3 n, vec3 l)  	return a;  } -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la) + +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight)  {  	//get light vector  	vec3 lv = lp.xyz-v; @@ -26,9 +27,13 @@ float calcPointLight(vec3 v, vec3 n, vec4 lp, float la)  	//distance attenuation  	float da = clamp(1.0/(la * d), 0.0, 1.0); +	// spotlight coefficient. +	float spot = max(dot(-ln, lv), is_pointlight); +	da *= spot*spot; // GL_SPOT_EXPONENT=2 +  	//angular attenuation  	da *= calcDirectionalLight(n, lv); -	 +  	return da;	  } diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index ad16de6d81..665fe16b43 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -29,8 +29,6 @@ varying vec3 vary_fragcoord;  varying vec3 vary_position;  varying vec3 vary_light; -uniform float alpha_soften; -  uniform float shadow_bias;  uniform mat4 inv_proj; @@ -115,15 +113,6 @@ void main()  	color.rgb = scaleSoftClip(color.rgb); -	if (samp_pos.z != 0.0 && gl_Color.a < 1.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/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl index 5991e1f3b5..1fae8c4da3 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaV.glsl @@ -9,7 +9,7 @@ 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); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -42,23 +42,21 @@ void main()  	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); +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// 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[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	vary_light = gl_LightSource[0].position.xyz;  	vary_ambient = col.rgb*gl_Color.rgb; diff --git a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl index a939499b17..f8dd1b7431 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/avatarAlphaV.glsl @@ -10,7 +10,7 @@ mat4 getSkinnedTransform();  void calcAtmospherics(vec3 inPositionEye);  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -53,23 +53,22 @@ void main()  	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); + +	vec4 col = vec4(0.0, 0.0, 0.0, gl_Color.a);  	// 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[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); +	// Add windlight lights +	col.rgb += atmosAmbient(vec3(0.)); +	  	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))); diff --git a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl index 0fad5b4b50..d1c5d7cb19 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/blurLightF.glsl @@ -37,7 +37,8 @@ vec4 getPosition(vec2 pos_screen)  void main()   { -	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	vec3 pos = getPosition(vary_fragcoord.xy).xyz;  	vec4 ccol = texture2DRect(lightMap, vary_fragcoord.xy).rgba; diff --git a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl index 02beddd43b..e32e9f4b32 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/edgeF.glsl @@ -31,7 +31,8 @@ float getDepth(vec2 pos_screen)  void main()   { -	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	float depth = getDepth(vary_fragcoord.xy);  	vec2 tc = vary_fragcoord.xy; @@ -46,8 +47,12 @@ void main()  	de = step(depth_cutoff, de);  	vec2 ne; -	ne.x = dot(texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb*2.0-1.0, norm); -	ne.y = dot(texture2DRect(normalMap, tc+vec2(sc,sc)).rgb*2.0-1.0, norm); +	vec3 nexnorm = texture2DRect(normalMap, tc+vec2(-sc,-sc)).rgb; +	nexnorm = vec3((nexnorm.xy-0.5)*2.0,nexnorm.z); // unpack norm +	ne.x = dot(nexnorm, norm); +	vec3 neynorm = texture2DRect(normalMap, tc+vec2(sc,sc)).rgb; +	neynorm = vec3((neynorm.xy-0.5)*2.0,neynorm.z); // unpack norm +	ne.y = dot(neynorm, norm);  	ne = 1.0-ne; diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl index 651959413c..22ffb58c63 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl @@ -43,6 +43,52 @@ uniform vec2 screen_res;  uniform mat4 inv_proj; +vec4 texture2DLodSpecular(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float det = max(1.0-lod/(proj_lod*0.5), 0.0); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0)+det, 1.0); +	 +	return ret; +} + +vec4 texture2DLodDiffuse(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = vec2(0.5) - abs(tc-vec2(0.5)); +	 +	float det = min(lod/(proj_lod*0.5), 1.0); +	 +	float d = min(dist.x, dist.y); +	 +	float edge = 0.25*det; +		 +	ret *= clamp(d/edge, 0.0, 1.0); +	 +	return ret; +} + +vec4 texture2DLodAmbient(sampler2D projectionMap, vec2 tc, float lod) +{ +	vec4 ret = texture2DLod(projectionMap, tc, lod); +	 +	vec2 dist = tc-vec2(0.5); +	 +	float d = dot(dist,dist); +		 +	ret *= min(clamp((0.25-d)/0.25, 0.0, 1.0), 1.0); +	 +	return ret; +} + +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -83,7 +129,8 @@ void main()  		shadow = min(sh[proj_shadow_idx]+shadow_fade, 1.0);  	} -	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -126,7 +173,7 @@ void main()  			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); +			vec4 plcol = texture2DLodDiffuse(projectionMap, proj_tc.xy, lod);  			vec3 lcol = gl_Color.rgb * plcol.rgb * plcol.a; @@ -137,7 +184,7 @@ void main()  		}  		//float diff = clamp((proj_range-proj_focus)/proj_range, 0.0, 1.0); -		vec4 amb_plcol = texture2DLod(projectionMap, proj_tc.xy, proj_ambient_lod); +		vec4 amb_plcol = texture2DLodAmbient(projectionMap, proj_tc.xy, proj_lod);  		amb_da += (da*da*0.5+0.5)*proj_ambiance; @@ -167,22 +214,23 @@ void main()  			if (stc.z > 0.0)  			{  				stc.xy /= stc.w; -					 + +				float fatten = clamp(spec.a*spec.a+spec.a*0.5, 0.25, 1.0); +				 +				stc.xy = (stc.xy - vec2(0.5)) * fatten + vec2(0.5); +								  				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); +					vec4 scol = texture2DLodSpecular(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/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl index 531f7376a3..fd6ae2b960 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl @@ -11,6 +11,7 @@ uniform sampler2DRect diffuseRect;  uniform sampler2DRect specularRect;  uniform sampler2DRect normalMap;  uniform sampler2DRect lightMap; +uniform sampler2DRect depthMap;  uniform sampler2D	  noiseMap;  uniform samplerCube environmentMap;  uniform sampler2D	  lightFunc; @@ -41,7 +42,6 @@ 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; @@ -55,9 +55,8 @@ 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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -68,6 +67,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -251,8 +256,10 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz; +	vec3 norm = texture2DRect(normalMap, tc).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;  	float da = max(dot(norm.xyz, vary_light.xyz), 0.0); @@ -271,24 +278,67 @@ void main()  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		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; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		float sa = dot(refnormpersp, vary_light.xyz); +		vec3 dumbshiny = vary_SunlitColor*scol_ambocc.r*texture2D(lightFunc, vec2(sa, spec.a)).a; + +		/* +		// screen-space cheap fakey reflection map +		// +		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); +		depth -= 0.5; // unbias depth +		// first figure out where we'll make our 2D guess from +		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; +		// Offset the guess source a little according to a trivial +		// checkerboard dither function and spec.a. +		// This is meant to be similar to sampling a blurred version +		// of the diffuse map.  LOD would be better in that regard. +		// The goal of the blur is to soften reflections in surfaces +		// with low shinyness, and also to disguise our lameness. +		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 +		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); +		ref2d += vec2(checkoffset, checkoffset); +		ref2d += tc.xy; // use as offset from destination +		// Get attributes from the 2D guess point. +		// We average two samples of diffuse (not of anything else) per +		// pixel to try to reduce aliasing some more. +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + +				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		float refshad = texture2DRect(lightMap, ref2d).r; +		vec3 refn = texture2DRect(normalMap, ref2d).rgb; +		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm +		refn = normalize(refn); +		// figure out how appropriate our guess actually was +		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); +		// darken reflections from points which face away from the reflected ray - our guess was a back-face +		//refapprop *= step(dot(refnorm, refn), 0.0); +		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant +		// get appropriate light strength for guess-point +		// reflect light direction to increase the illusion that +		// these are reflections. +		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); +		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); +		// apply sun color to guess-point, dampen according to inappropriateness of guess +		float refmod = min(refapprop, reflit); +		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; +		vec3 ssshiny = (refprod * spec.a); +		ssshiny *= 0.3; // dampen it even more +		*/ +		vec3 ssshiny = vec3(0,0,0); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	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/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl index d6534083cf..8a90199b7c 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl @@ -82,7 +82,8 @@ void main()  		discard;  	} -	vec3 norm = texture2DRect(normalMap, frag.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, frag.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	norm = normalize(norm);  	float l_dist = -dot(lv, proj_n); @@ -179,21 +180,6 @@ void main()  		}  	} -	/*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/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl index a0026edcd2..7423347346 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightF.glsl @@ -7,6 +7,8 @@  #extension GL_ARB_texture_rectangle : enable +//class 2, shadows, no SSAO +  uniform sampler2DRect depthMap;  uniform sampler2DRect normalMap;  uniform sampler2DRectShadow shadowMap0; @@ -39,6 +41,9 @@ uniform vec2 proj_shadow_res;  uniform float shadow_bias;  uniform float shadow_offset; +uniform float spot_shadow_bias; +uniform float spot_shadow_offset; +  vec4 getPosition(vec2 pos_screen)  {  	float depth = texture2DRect(depthMap, pos_screen.xy).a; @@ -52,56 +57,6 @@ vec4 getPosition(vec2 pos_screen)  	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)); -} -  float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)  {  	stc.xyz /= stc.w; @@ -123,7 +78,7 @@ float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl)  float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)  {  	stc.xyz /= stc.w; -	stc.z += shadow_bias*scl; +	stc.z += spot_shadow_bias*scl;  	float cs = shadow2D(shadowMap, stc.xyz).x;  	float shadow = cs; @@ -134,8 +89,7 @@ float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl)  	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs);  	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs);  	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); -	 -			 +				  	return shadow/5.0;  	//return shadow; @@ -149,7 +103,10 @@ void main()  	vec4 pos = getPosition(pos_screen); -    vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; +	vec4 nmap4 = texture2DRect(normalMap, pos_screen); +	nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +	float displace = nmap4.w; +	vec3 norm = nmap4.xyz;  	/*if (pos.z == 0.0) // do nothing for sky *FIX: REMOVE THIS IF/WHEN THE POSITION MAP IS BEING USED AS A STENCIL  	{ @@ -158,9 +115,12 @@ 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 + vary_light.xyz * (1.0-dp_directional_light)*shadow_offset, 1.0); +	vec3 shadow_pos = pos.xyz + displace*norm; +	vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.0);  	if (spos.z > -shadow_clip.w)  	{	 @@ -220,15 +180,17 @@ void main()  	}  	gl_FragColor[0] = shadow; -	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	gl_FragColor[1] = 1.0; +	 +	spos = vec4(shadow_pos+norm*spot_shadow_offset, 1.0);  	//spotlight shadow 1  	vec4 lpos = shadow_matrix[4]*spos; -	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.1).x;  +	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8);   	//spotlight shadow 2  	lpos = shadow_matrix[5]*spos; -	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.1).x;  +	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8);   	//gl_FragColor.rgb = pos.xyz;  	//gl_FragColor.b = shadow; diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl new file mode 100644 index 0000000000..4e33a1af45 --- /dev/null +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -0,0 +1,257 @@ +/**  + * @file sunLightSSAOF.glsl + * + * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#extension GL_ARB_texture_rectangle : enable + +//class 2 -- shadows and SSAO + +uniform sampler2DRect depthMap; +uniform sampler2DRect normalMap; +uniform sampler2DRectShadow shadowMap0; +uniform sampler2DRectShadow shadowMap1; +uniform sampler2DRectShadow shadowMap2; +uniform sampler2DRectShadow shadowMap3; +uniform sampler2DShadow shadowMap4; +uniform sampler2DShadow 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 vec2 shadow_res; +uniform vec2 proj_shadow_res; + +uniform float shadow_bias; +uniform float shadow_offset; + +uniform float spot_shadow_bias; +uniform float spot_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) +{ +	float ret = 1.0; +	 +	float dist = dot(pos.xyz,pos.xyz); +	 +	if (dist < 64.0*64.0) +	{ +		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); +		 +		ret = (1.0 - (float(points != 0) * angle_hidden)); +		ret += max((dist-32.0*32.0)/(32.0*32.0), 0.0); +	} +	 +	return min(ret, 1.0); +} + +float pcfShadow(sampler2DRectShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += shadow_bias*scl; +	 +	float cs = shadow2DRect(shadowMap, stc.xyz).x; +	float shadow = cs; + +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(1.5, -1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, 1.5, 0.0)).x, cs); +	shadow += max(shadow2DRect(shadowMap, stc.xyz+vec3(-1.5, -1.5, 0.0)).x, cs); +			 +	return shadow/5.0; +	 +	//return shadow; +} + +float pcfShadow(sampler2DShadow shadowMap, vec4 stc, float scl) +{ +	stc.xyz /= stc.w; +	stc.z += spot_shadow_bias*scl; +	 +	float cs = shadow2D(shadowMap, stc.xyz).x; +	float shadow = cs; + +	vec2 off = 1.5/proj_shadow_res; +	 +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(off.x, -off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, off.y, 0.0)).x, cs); +	shadow += max(shadow2D(shadowMap, stc.xyz+vec3(-off.x, -off.y, 0.0)).x, cs); +	 +			 +	return shadow/5.0; +	 +	//return shadow; +} + +void main()  +{ +	vec2 pos_screen = vary_fragcoord.xy; +	 +	//try doing an unproject here +	 +	vec4 pos = getPosition(pos_screen); +	 +	vec4 nmap4 = texture2DRect(normalMap, pos_screen); +	nmap4 = vec4((nmap4.xy-0.5)*2.0,nmap4.z,nmap4.w); // unpack norm +	float displace = nmap4.w; +	vec3 norm = nmap4.xyz; +	 +	/*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)); + +	vec3 shadow_pos = pos.xyz + displace*norm; +	vec3 offset = vary_light.xyz * (1.0-dp_directional_light); +	 +	vec4 spos = vec4(shadow_pos+offset*shadow_offset, 1.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 *= shadow_res; +				shadow = pcfShadow(shadowMap3, lpos, 0.25); +				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 *= shadow_res; +				shadow = pcfShadow(shadowMap2, lpos, 0.5); +			} +			else if (spos.z < -shadow_clip.x) +			{ +				lpos = shadow_matrix[1]*spos; +				lpos.xy *= shadow_res; +				shadow = pcfShadow(shadowMap1, lpos, 0.75); +			} +			else +			{ +				lpos = shadow_matrix[0]*spos; +				lpos.xy *= shadow_res; +				shadow = pcfShadow(shadowMap0, lpos, 1.0); +			} +		 +			// 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); +			 +			//lpos.xy /= lpos.w*32.0; +			//if (fract(lpos.x) < 0.1 || fract(lpos.y) < 0.1) +			//{ +			//	shadow = 0.0; +			//} +			 +		} +	} +	else +	{ +		// more distant than the shadow map covers +		shadow = 1.0; +	} +	 +	gl_FragColor[0] = shadow; +	gl_FragColor[1] = calcAmbientOcclusion(pos, norm); +	 +	spos.xyz = shadow_pos+offset*spot_shadow_offset; +	 +	//spotlight shadow 1 +	vec4 lpos = shadow_matrix[4]*spos; +	gl_FragColor[2] = pcfShadow(shadowMap4, lpos, 0.8);  +	 +	//spotlight shadow 2 +	lpos = shadow_matrix[5]*spos; +	gl_FragColor[3] = pcfShadow(shadowMap5, lpos, 0.8);  + +	//gl_FragColor.rgb = pos.xyz; +	//gl_FragColor.b = shadow; +} diff --git a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl index f4c59734a4..19800d96dc 100644 --- a/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class2/lighting/sumLightsV.glsl @@ -6,7 +6,7 @@   */  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -18,9 +18,10 @@ vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)  	// Collect normal lights (need to be divided by two, as we later multiply by 2)  	col.rgb += gl_LightSource[1].diffuse.rgb * calcDirectionalLight(norm, gl_LightSource[1].position.xyz); -	col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	//col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); + +	col.rgb += gl_LightSource[2].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	//col.rgb += gl_LightSource[4].diffuse.rgb * calcPointLightOrSpotLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a);  	col.rgb = scaleDownLight(col.rgb);  	// Add windlight lights diff --git a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl index 7325825d6d..66606233cd 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giDownsampleF.glsl @@ -44,7 +44,8 @@ float getDepth(vec2 pos_screen)  void main()   { -	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, vary_fragcoord.xy).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	float depth = getDepth(vary_fragcoord.xy);  	vec3 ccol = texture2DRect(giLightMap, vary_fragcoord.xy).rgb; @@ -56,9 +57,10 @@ void main()  	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); +		vec3 sampNorm = texture2DRect(normalMap, tc.xy).xyz; +		sampNorm = vec3((sampNorm.xy-0.5)*2.0,sampNorm.z); // unpack norm +		 +		float d = dot(norm.xyz, sampNorm);  		if (d > 0.5)  		{ diff --git a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl index 939710cb56..1b8354dbd1 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/giF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/giF.glsl @@ -178,7 +178,8 @@ void main()  	float rad = gi_range*0.5; -	vec3 norm = texture2DRect(normalMap, pos_screen).xyz*2.0-1.0; +	vec3 norm = texture2DRect(normalMap, pos_screen).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	float dist = max(length(pos.xyz)-rad, 0.0);  	float da = clamp(1.0-dist/rad, 0.0, 1.0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 96a083b522..c88edd0a60 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -56,9 +56,8 @@ vec3 vary_AdditiveColor;  vec3 vary_AtmosAttenuation;  uniform float gi_ambiance; -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; +vec4 getPosition_d(vec2 pos_screen, float depth) +{  	vec2 sc = pos_screen.xy*2.0;  	sc /= screen_res;  	sc -= vec2(1.0,1.0); @@ -69,6 +68,12 @@ vec4 getPosition(vec2 pos_screen)  	return pos;  } +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; +	return getPosition_d(pos_screen, depth); +} +  vec3 getPositionEye()  {  	return vary_PositionEye; @@ -252,8 +257,10 @@ vec3 scaleSoftClip(vec3 light)  void main()   {  	vec2 tc = vary_fragcoord.xy; -	vec3 pos = getPosition(tc).xyz; -	vec3 norm = texture2DRect(normalMap, tc).xyz*2.0-1.0; +	float depth = texture2DRect(depthMap, tc.xy).a; +	vec3 pos = getPosition_d(tc, depth).xyz; +	vec3 norm = texture2DRect(normalMap, tc).xyz; +	norm = vec3((norm.xy-0.5)*2.0,norm.z); // unpack norm  	//vec3 nz = texture2D(noiseMap, vary_fragcoord.xy/128.0).xyz;  	float da = max(dot(norm.xyz, vary_light.xyz), 0.0); @@ -274,11 +281,63 @@ void main()  	col *= diffuse.rgb; -	if (spec.a > 0.0) +	if (spec.a > 0.0) // specular reflection  	{ -		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; +		// the old infinite-sky shiny reflection +		// +		vec3 refnormpersp = normalize(reflect(pos.xyz, norm.xyz)); +		float sa = dot(refnormpersp, vary_light.xyz); +		vec3 dumbshiny = vary_SunlitColor*scol*texture2D(lightFunc, vec2(sa, spec.a)).a; + +		/* +		// screen-space cheap fakey reflection map +		// +		vec3 refnorm = normalize(reflect(vec3(0,0,-1), norm.xyz)); +		depth -= 0.5; // unbias depth +		// first figure out where we'll make our 2D guess from +		vec2 ref2d = (0.25 * screen_res.y) * (refnorm.xy) * abs(refnorm.z) / depth; +		// Offset the guess source a little according to a trivial +		// checkerboard dither function and spec.a. +		// This is meant to be similar to sampling a blurred version +		// of the diffuse map.  LOD would be better in that regard. +		// The goal of the blur is to soften reflections in surfaces +		// with low shinyness, and also to disguise our lameness. +		float checkerboard = floor(mod(tc.x+tc.y, 2.0)); // 0.0, 1.0 +		float checkoffset = (3.0 + (7.0*(1.0-spec.a)))*(checkerboard-0.5); + +		ref2d += vec2(checkoffset, checkoffset); +		ref2d += tc.xy; // use as offset from destination +		// Get attributes from the 2D guess point. +		// We average two samples of diffuse (not of anything else) per +		// pixel to try to reduce aliasing some more. +		vec3 refcol = 0.5 * (texture2DRect(diffuseRect, ref2d + vec2(0.0, -checkoffset)).rgb + +				     texture2DRect(diffuseRect, ref2d + vec2(-checkoffset, 0.0)).rgb); +		float refdepth = texture2DRect(depthMap, ref2d).a; +		vec3 refpos = getPosition_d(ref2d, refdepth).xyz; +		float refshad = texture2DRect(lightMap, ref2d).r; +		vec3 refn = texture2DRect(normalMap, ref2d).rgb; +		refn = vec3((refn.xy-0.5)*2.0,refn.z); // unpack norm +		refn = normalize(refn); +		// figure out how appropriate our guess actually was +		float refapprop = max(0.0, dot(-refnorm, normalize(pos - refpos))); +		// darken reflections from points which face away from the reflected ray - our guess was a back-face +		//refapprop *= step(dot(refnorm, refn), 0.0); +		refapprop = min(refapprop, max(0.0, -dot(refnorm, refn))); // more conservative variant +		// get appropriate light strength for guess-point. +		// reflect light direction to increase the illusion that +		// these are reflections. +		vec3 reflight = reflect(lightnorm.xyz, norm.xyz); +		float reflit = min(max(dot(refn, reflight.xyz), 0.0), refshad); +		// apply sun color to guess-point, dampen according to inappropriateness of guess +		float refmod = min(refapprop, reflit); +		vec3 refprod = vary_SunlitColor * refcol.rgb * refmod; +		vec3 ssshiny = (refprod * spec.a); +		ssshiny *= 0.3; // dampen it even more +		*/ +		vec3 ssshiny = vec3(0,0,0); + +		// add the two types of shiny together +		col += (ssshiny + dumbshiny) * spec.rgb;  	}  	col = atmosLighting(col); diff --git a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl index 258acee08c..5b33ea5bfe 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/treeF.glsl @@ -14,5 +14,6 @@ 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); +	vec3 nvn = normalize(vary_normal); +	gl_FragData[2] = vec4(nvn.xy * 0.5 + 0.5, nvn.z, 0.0);  } diff --git a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl index 1c5234c450..f129a1517b 100644 --- a/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl +++ b/indra/newview/app_settings/shaders/class3/lighting/sumLightsV.glsl @@ -6,7 +6,7 @@   */  float calcDirectionalLight(vec3 n, vec3 l); -float calcPointLight(vec3 v, vec3 n, vec4 lp, float la); +float calcPointLightOrSpotLight(vec3 v, vec3 n, vec4 lp, vec3 ln, float la, float is_pointlight);  vec3 atmosAmbient(vec3 light);  vec3 atmosAffectDirectionalLight(float lightIntensity); @@ -15,24 +15,21 @@ vec3 scaleUpLight(vec3 light);  vec4 sumLights(vec3 pos, vec3 norm, vec4 color, vec4 baseLight)  { -	vec4 col; -	col.a = color.a; +	vec4 col = vec4(0.0, 0.0, 0.0, color.a); -	// Add windlight lights -	col.rgb = atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); -	col.rgb += atmosAmbient(baseLight.rgb); -	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, norm, gl_LightSource[2].position, gl_LightSource[2].linearAttenuation); -	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[3].position, gl_LightSource[3].linearAttenuation); -	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[4].position, gl_LightSource[4].linearAttenuation); -	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[5].position, gl_LightSource[5].linearAttenuation); - 	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[6].position, gl_LightSource[6].linearAttenuation); - 	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLight(pos, norm, gl_LightSource[7].position, gl_LightSource[7].linearAttenuation); +	col.rgb += gl_LightSource[2].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[2].position, gl_LightSource[2].spotDirection.xyz, gl_LightSource[2].linearAttenuation, gl_LightSource[2].specular.a); +	col.rgb += gl_LightSource[3].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[3].position, gl_LightSource[3].spotDirection.xyz, gl_LightSource[3].linearAttenuation, gl_LightSource[3].specular.a); +	col.rgb += gl_LightSource[4].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[4].position, gl_LightSource[4].spotDirection.xyz, gl_LightSource[4].linearAttenuation, gl_LightSource[4].specular.a); +	col.rgb += gl_LightSource[5].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[5].position, gl_LightSource[5].spotDirection.xyz, gl_LightSource[5].linearAttenuation, gl_LightSource[5].specular.a); +	col.rgb += gl_LightSource[6].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[6].position, gl_LightSource[6].spotDirection.xyz, gl_LightSource[6].linearAttenuation, gl_LightSource[6].specular.a); +	col.rgb += gl_LightSource[7].diffuse.rgb*calcPointLightOrSpotLight(pos.xyz, norm, gl_LightSource[7].position, gl_LightSource[7].spotDirection.xyz, gl_LightSource[7].linearAttenuation, gl_LightSource[7].specular.a);  	col.rgb += gl_LightSource[1].diffuse.rgb*calcDirectionalLight(norm, gl_LightSource[1].position.xyz);  	col.rgb = scaleDownLight(col.rgb); -				 + +	// Add windlight lights +	col.rgb += atmosAffectDirectionalLight(calcDirectionalLight(norm, gl_LightSource[0].position.xyz)); +	col.rgb += atmosAmbient(baseLight.rgb);  	col.rgb = min(col.rgb*color.rgb, 1.0); diff --git a/indra/newview/app_settings/ultra_graphics.xml b/indra/newview/app_settings/ultra_graphics.xml index f16ec6c30f..f741089ca2 100644 --- a/indra/newview/app_settings/ultra_graphics.xml +++ b/indra/newview/app_settings/ultra_graphics.xml @@ -12,14 +12,12 @@  	<RenderFlexTimeFactor value="1"/>  	<!--256... but they don't use this-->  	<RenderGlowResolutionPow value="9"/> -	<!--Sun/Moon only--> -	<RenderLightingDetail value="1"/>  	<!--Low number-->  	<RenderMaxPartCount value="4096"/>  	<!--bump okay-->  	<RenderObjectBump value="TRUE"/>  	<!--NO SHADERS--> -	<RenderReflectionDetail value="3"/> +	<RenderReflectionDetail value="4"/>  	<!--Simple-->  	<RenderTerrainDetail value="1"/>  	<!--Default for now--> @@ -31,9 +29,14 @@  	<!--Default for now-->  	<RenderVolumeLODFactor value="2.0"/>  	<!--NO SHADERS--> -	<RenderWaterReflections value="TRUE"/> -	<!--NO SHADERS-->  	<VertexShaderEnable value="TRUE"/>  	<!--NO SHADERS-->  	<WindLightUseAtmosShaders value="TRUE"/> +  <!--Deferred Shading--> +  <RenderDeferred value="TRUE"/> +  <!--SSAO Enabled--> +  <RenderDeferredSSAO value="TRUE"/> +  <!--Full Shadows--> +  <RenderShadowDetail value="2"/> +  </settings> diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index b4add267fe..80269c68c8 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -23,7 +23,7 @@ version 21  // NOTE: All settings are set to the MIN of applied values, including 'all'!  //  list all -RenderAnisotropic			1	0 +RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0  RenderAvatarVP				1	1 @@ -35,18 +35,16 @@ RenderFogRatio				1	4.0  RenderGamma					1	0  RenderGlowResolutionPow		1	9  RenderGround				1	1 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderNightBrightness		1	1.0  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  UseStartScreen				1	1  UseOcclusion				1	1  VertexShaderEnable			1	1 @@ -57,6 +55,9 @@ Disregard96DefaultDrawDistance	1	1  RenderTextureMemoryMultiple		1	1.0  RenderShaderLightingMaxLevel	1	3  SkyUseClassicClouds			1	1 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2  //  // Low Graphics Settings @@ -70,7 +71,6 @@ RenderAvatarVP				1	0  RenderFarClip				1	64  RenderFlexTimeFactor		1	0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	0  RenderMaxPartCount			1	0  RenderObjectBump			1	0  RenderReflectionDetail		1	0 @@ -79,11 +79,14 @@ RenderTerrainLODFactor		1	1  RenderTreeLODFactor			1	0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	0 -RenderWaterReflections		1	0  VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48  SkyUseClassicClouds			1	0 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // Mid Graphics Settings @@ -96,7 +99,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	1  RenderMaxPartCount			1	2048  RenderObjectBump			1	1  RenderReflectionDetail		1	0 @@ -105,10 +107,13 @@ RenderTerrainLODFactor		1	1.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // High Graphics Settings (purty) @@ -121,7 +126,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	4096  RenderObjectBump			1	1  RenderReflectionDetail		1	2 @@ -130,10 +134,13 @@ RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // Ultra graphics (REALLY PURTY!) @@ -146,19 +153,21 @@ RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2 +  //  // Class Unknown Hardware (unknown) @@ -196,9 +205,12 @@ RenderVBOEnable				1	1  list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0  //  // No Vertex Shaders available @@ -206,9 +218,13 @@ WindLightUseAtmosShaders	0	0  list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  // "Default" setups for safe, low, medium, high  // @@ -216,14 +232,17 @@ list safe  RenderAnisotropic			1	0  RenderAvatarCloth			0	0  RenderAvatarVP				0	0 -RenderLightingDetail		1	0  RenderObjectBump			0	0  RenderMaxPartCount			1	1024  RenderTerrainDetail 		1	0  RenderUseImpostors			0	0  RenderVBOEnable				1	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  //  // CPU based feature masks @@ -247,11 +266,9 @@ RenderVBOEnable				1	0  list Intel  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  list GeForce2  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  RenderMaxPartCount			1	2048  RenderTerrainDetail			1	0  RenderVBOEnable				1	1 diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 4fb529ab39..bf5a3a646a 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -23,7 +23,7 @@ version 21  // NOTE: All settings are set to the MIN of applied values, including 'all'!  //  list all -RenderAnisotropic			1	0 +RenderAnisotropic			1	1  RenderAvatarCloth			1	1  RenderAvatarLODFactor		1	1.0  RenderAvatarVP				1	1 @@ -35,18 +35,16 @@ RenderFogRatio				1	4.0  RenderGamma					1	0  RenderGlowResolutionPow		1	9  RenderGround				1	1 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderNightBrightness		1	1.0  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVBOEnable				1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  UseStartScreen				1	1  UseOcclusion				1	1  VertexShaderEnable			1	1 @@ -56,6 +54,10 @@ Disregard128DefaultDrawDistance	1	1  Disregard96DefaultDrawDistance	1	1  RenderTextureMemoryMultiple		1	1.0  SkyUseClassicClouds			1	1 +RenderShaderLightingMaxLevel		1	3 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2  //  // Low Graphics Settings @@ -69,7 +71,6 @@ RenderAvatarVP				1	0  RenderFarClip				1	64  RenderFlexTimeFactor		1	0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	0  RenderMaxPartCount			1	0  RenderObjectBump			1	0  RenderReflectionDetail		1	0 @@ -78,11 +79,14 @@ RenderTerrainLODFactor		1	1  RenderTreeLODFactor			1	0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	0 -RenderWaterReflections		1	0  VertexShaderEnable			1	0  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48  SkyUseClassicClouds			1	0 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // Mid Graphics Settings @@ -95,7 +99,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	96  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	8 -RenderLightingDetail		1	1  RenderMaxPartCount			1	2048  RenderObjectBump			1	1  RenderReflectionDetail		1	0 @@ -104,10 +107,13 @@ RenderTerrainLODFactor		1	1.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	0  WLSkyDetail					1	48 +RenderDeferred				1	0 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	0 +  //  // High Graphics Settings (purty) @@ -120,7 +126,6 @@ RenderAvatarVP				1	1  RenderFarClip				1	128  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	4096  RenderObjectBump			1	1  RenderReflectionDetail		1	2 @@ -129,10 +134,13 @@ RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	0.5  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	1.125 -RenderWaterReflections		1	0  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	48 +RenderDeferred				1	1 +RenderDeferredSSAO			1	0 +RenderShadowDetail			1	1 +  //  // Ultra graphics (REALLY PURTY!) @@ -145,19 +153,21 @@ RenderAvatarVP				1	1  RenderFarClip				1	256  RenderFlexTimeFactor		1	1.0  RenderGlowResolutionPow		1	9 -RenderLightingDetail		1	1  RenderMaxPartCount			1	8192  RenderObjectBump			1	1 -RenderReflectionDetail		1	3 +RenderReflectionDetail		1	4  RenderTerrainDetail			1	1  RenderTerrainLODFactor		1	2.0  RenderTreeLODFactor			1	1.0  RenderUseImpostors			1	1  RenderVolumeLODFactor		1	2.0 -RenderWaterReflections		1	1  VertexShaderEnable			1	1  WindLightUseAtmosShaders	1	1  WLSkyDetail					1	128 +RenderDeferred				1	1 +RenderDeferredSSAO			1	1 +RenderShadowDetail			1	2 +  //  // Class Unknown Hardware (unknown) @@ -195,9 +205,12 @@ RenderVBOEnable				1	1  list NoPixelShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0  //  // No Vertex Shaders available @@ -205,9 +218,13 @@ WindLightUseAtmosShaders	0	0  list NoVertexShaders  RenderAvatarVP				0	0  RenderAvatarCloth			0	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  VertexShaderEnable			0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  // "Default" setups for safe, low, medium, high  // @@ -215,14 +232,17 @@ list safe  RenderAnisotropic			1	0  RenderAvatarCloth			0	0  RenderAvatarVP				0	0 -RenderLightingDetail		1	0  RenderObjectBump			0	0  RenderMaxPartCount			1	1024  RenderTerrainDetail 		1	0  RenderUseImpostors			0	0  RenderVBOEnable				1	0 -RenderWaterReflections		0	0 +RenderReflectionDetail		0	0  WindLightUseAtmosShaders	0	0 +RenderDeferred				0	0 +RenderDeferredSSAO			0	0 +RenderShadowDetail			0	0 +  //  // CPU based feature masks @@ -246,13 +266,11 @@ RenderVBOEnable				1	0  list Intel  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  // Avoid some Intel crashes on Linux  RenderCubeMap				0	0  list GeForce2  RenderAnisotropic			1	0 -RenderLightingDetail		1	0  RenderMaxPartCount			1	2048  RenderTerrainDetail			1	0  RenderVBOEnable				1	1 @@ -464,17 +482,47 @@ list NVIDIA_GeForce_Go_6  RenderVBOEnable				1	0  Disregard128DefaultDrawDistance	1	0 +list NVIDIA_GeForce_7000 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7100 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7200  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7300  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_7400  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7500 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7600 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7700 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7800 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_7900 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7200  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7300  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7300_LE +RenderShaderLightingMaxLevel	1	2  list NVIDIA_GeForce_Go_7400  Disregard128DefaultDrawDistance	1	0 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7600 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7700 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7800 +RenderShaderLightingMaxLevel	1	2 +list NVIDIA_GeForce_Go_7900 +RenderShaderLightingMaxLevel	1	2 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index fbc589d3e7..52fae2f160 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -369,6 +369,7 @@ list ATI_Radeon_X1500  Disregard128DefaultDrawDistance	1	0  list ATI_Radeon_X1600   Disregard128DefaultDrawDistance	1	0 +RenderUseFBO 					0	0  list ATI_Radeon_X1700   Disregard128DefaultDrawDistance	1	0  list ATI_Mobility_Radeon_X1xxx diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index deafb20af7..b1619b3c07 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -914,6 +914,11 @@ static LLFastTimer::DeclareTimer FTM_LFS("LFS Thread");  static LLFastTimer::DeclareTimer FTM_PAUSE_THREADS("Pause Threads");  static LLFastTimer::DeclareTimer FTM_IDLE("Idle");  static LLFastTimer::DeclareTimer FTM_PUMP("Pump"); +static LLFastTimer::DeclareTimer FTM_PUMP_ARES("Ares"); +static LLFastTimer::DeclareTimer FTM_PUMP_SERVICE("Service"); +static LLFastTimer::DeclareTimer FTM_SERVICE_CALLBACK("Callback"); +static LLFastTimer::DeclareTimer FTM_AGENT_AUTOPILOT("Autopilot"); +static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE("Update");  bool LLAppViewer::mainLoop()  { @@ -1023,10 +1028,20 @@ bool LLAppViewer::mainLoop()  						LLMemType mt_ip(LLMemType::MTYPE_IDLE_PUMP);  						pingMainloopTimeout("Main:ServicePump");				  						LLFastTimer t4(FTM_PUMP); -						gAres->process(); -						// this pump is necessary to make the login screen show up -						gServicePump->pump(); -						gServicePump->callback(); +						{ +							LLFastTimer t(FTM_PUMP_ARES); +							gAres->process(); +						} +						{ +							LLFastTimer t(FTM_PUMP_SERVICE); +							// this pump is necessary to make the login screen show up +							gServicePump->pump(); + +							{ +								LLFastTimer t(FTM_SERVICE_CALLBACK); +								gServicePump->callback(); +							} +						}  					}  					resumeMainloopTimeout(); @@ -3524,9 +3539,12 @@ void LLAppViewer::idle()  			gAgent.moveYaw(-1.f);  		} -	    // Handle automatic walking towards points -	    gAgentPilot.updateTarget(); -	    gAgent.autoPilot(&yaw); +		{ +			LLFastTimer t(FTM_AGENT_AUTOPILOT); +			// Handle automatic walking towards points +			gAgentPilot.updateTarget(); +			gAgent.autoPilot(&yaw); +		}  	    static LLFrameTimer agent_update_timer;  	    static U32 				last_control_flags; @@ -3537,6 +3555,7 @@ void LLAppViewer::idle()  	    if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))  	    { +		    LLFastTimer t(FTM_AGENT_UPDATE);  		    // Send avatar and camera info  		    last_control_flags = gAgent.getControlFlags();  		    send_agent_update(TRUE); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 38eda5bd2e..ed6a791e7f 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -523,7 +523,7 @@ F32 LLDrawable::updateXform(BOOL undamped)  		{  			// snap to final position  			dist_squared = 0.0f; -			if (!isRoot()) +			if (getVOVolume() && !isRoot())  			{ //child prim snapping to some position, needs a rebuild  				gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);  			} diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index e3e66fa00d..ae30af3647 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -474,6 +474,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)  	{  		if (params.mTexture.notNull())  		{ +			params.mTexture->addTextureStats(params.mVSize);  			gGL.getTexUnit(0)->bind(params.mTexture, TRUE) ;  			if (params.mTextureMatrix)  			{ diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 67870c10e9..f85b46cfba 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -133,6 +133,7 @@ public:  		PASS_FULLBRIGHT_SHINY,  		PASS_SHINY,  		PASS_BUMP, +		PASS_POST_BUMP,  		PASS_GLOW,  		PASS_ALPHA,  		PASS_ALPHA_MASK, diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 875c9ac6a9..def463cb41 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -60,7 +60,9 @@ static BOOL deferred_render = FALSE;  LLDrawPoolAlpha::LLDrawPoolAlpha(U32 type) :  		LLRenderPass(type), current_shader(NULL), target_shader(NULL), -		simple_shader(NULL), fullbright_shader(NULL) +		simple_shader(NULL), fullbright_shader(NULL), +		mColorSFactor(LLRender::BF_UNDEF), mColorDFactor(LLRender::BF_UNDEF), +		mAlphaSFactor(LLRender::BF_UNDEF), mAlphaDFactor(LLRender::BF_UNDEF)  {  } @@ -178,9 +180,16 @@ void LLDrawPoolAlpha::render(S32 pass)  	LLGLSPipelineAlpha gls_pipeline_alpha; -	if (LLPipeline::sFastAlpha && !deferred_render) +	gGL.setColorMask(true, true); + +	if (LLPipeline::sAutoMaskAlphaNonDeferred && !deferred_render)  	{ -		LLGLDisable blend_disable(GL_BLEND); +		mColorSFactor = LLRender::BF_ONE;  // } +		mColorDFactor = LLRender::BF_ZERO; // } these are like disabling blend on the color channels, but we're still blending on the alpha channel so that we can suppress glow +		mAlphaSFactor = LLRender::BF_ZERO; +		mAlphaDFactor = LLRender::BF_ZERO; // block (zero-out) glow where the alpha test succeeds +		gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +  		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.33f);  		if (mVertexShaderLevel > 0)  		{ @@ -204,8 +213,17 @@ void LLDrawPoolAlpha::render(S32 pass)  	}  	LLGLDepthTest depth(GL_TRUE, LLDrawPoolWater::sSkipScreenCopy ? GL_TRUE : GL_FALSE); + +	mColorSFactor = LLRender::BF_SOURCE_ALPHA;           // } regular alpha blend +	mColorDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; // } +	mAlphaSFactor = LLRender::BF_ZERO;                         // } glow suppression +	mAlphaDFactor = LLRender::BF_ONE_MINUS_SOURCE_ALPHA;       // } +	gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +  	renderAlpha(getVertexDataMask()); +	gGL.setColorMask(true, false); +  	if (deferred_render && current_shader != NULL)  	{  		gPipeline.unbindDeferredShader(*current_shader); @@ -283,9 +301,18 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  	for (LLCullResult::sg_list_t::iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)  	{  		LLSpatialGroup* group = *i; +		llassert(group); +		llassert(group->mSpatialPartition); +  		if (group->mSpatialPartition->mRenderByGroup && -			!group->isDead()) +		    !group->isDead())  		{ +			bool draw_glow_for_this_partition = mVertexShaderLevel > 0 && // no shaders = no glow. +				// All particle systems seem to come off the wire with texture entries which claim that they glow.  This is probably a bug in the data.  Suppress. +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_PARTICLE && +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_CLOUD && +				group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD_PARTICLE; +  			LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];  			for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)	 @@ -294,96 +321,118 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask)  				LLRenderPass::applyModelMatrix(params); -				if (params.mFullbright)  				{ -					// Turn off lighting if it hasn't already been so. -					if (light_enabled || !initialized_lighting) +					if (params.mFullbright) +					{ +						// Turn off lighting if it hasn't already been so. +						if (light_enabled || !initialized_lighting) +						{ +							initialized_lighting = TRUE; +							if (use_shaders)  +							{ +								target_shader = fullbright_shader; +							} +							else +							{ +								gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +							} +							light_enabled = FALSE; +						} +					} +					// Turn on lighting if it isn't already. +					else if (!light_enabled || !initialized_lighting)  					{  						initialized_lighting = TRUE;  						if (use_shaders)   						{ -							target_shader = fullbright_shader; +							target_shader = simple_shader;  						}  						else  						{ -							gPipeline.enableLightsFullbright(LLColor4(1,1,1,1)); +							gPipeline.enableLightsDynamic();  						} -						light_enabled = FALSE; +						light_enabled = TRUE;  					} -				} -				// Turn on lighting if it isn't already. -				else if (!light_enabled || !initialized_lighting) -				{ -					initialized_lighting = TRUE; -					if (use_shaders)  -					{ -						target_shader = simple_shader; -					} -					else -					{ -						gPipeline.enableLightsDynamic(); -					} -					light_enabled = TRUE; -				} -				// If we need shaders, and we're not ALREADY using the proper shader, then bind it -				// (this way we won't rebind shaders unnecessarily). -				if(use_shaders && (current_shader != target_shader)) -				{ -					llassert(target_shader != NULL); -					if (deferred_render && current_shader != NULL) +					// If we need shaders, and we're not ALREADY using the proper shader, then bind it +					// (this way we won't rebind shaders unnecessarily). +					if(use_shaders && (current_shader != target_shader))  					{ -						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 -					{ -						current_shader->bind(); +						llassert(target_shader != NULL); +						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 +						{ +							current_shader->bind(); +						}  					} -				} -				else if (!use_shaders && current_shader != NULL) -				{ -					if (deferred_render) +					else if (!use_shaders && current_shader != NULL)  					{ -						gPipeline.unbindDeferredShader(*current_shader); -						diffuse_channel = 0; +						if (deferred_render) +						{ +							gPipeline.unbindDeferredShader(*current_shader); +							diffuse_channel = 0; +						} +						LLGLSLShader::bindNoShader(); +						current_shader = NULL;  					} -					LLGLSLShader::bindNoShader(); -					current_shader = NULL; -				} - -				if (params.mGroup) -				{ -					params.mGroup->rebuildMesh(); -				} -				 -				if (params.mTexture.notNull()) -				{ -					gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); -					if(params.mTexture.notNull()) +					if (params.mGroup)  					{ -						params.mTexture->addTextureStats(params.mVSize); +						params.mGroup->rebuildMesh();  					} -					if (params.mTextureMatrix) + +					 +					if (params.mTexture.notNull())  					{ -						gGL.getTexUnit(0)->activate(); -						glMatrixMode(GL_TEXTURE); -						glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix); -						gPipeline.mTextureMatrixOps++; +						gGL.getTexUnit(diffuse_channel)->bind(params.mTexture.get()); +						if(params.mTexture.notNull()) +						{ +							params.mTexture->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(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);  				gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); +				 +				// If this alpha mesh has glow, then draw it a second time to add the destination-alpha (=glow).  Interleaving these state-changing calls could be expensive, but glow must be drawn Z-sorted with alpha. +				if (draw_glow_for_this_partition && +				    params.mGlowColor.mV[3] > 0) +				{ +					// install glow-accumulating blend mode +					gGL.blendFunc(LLRender::BF_ZERO, LLRender::BF_ONE, // don't touch color +						      LLRender::BF_ONE, LLRender::BF_ONE); // add to alpha (glow) +					// glow doesn't use vertex colors from the mesh data +					params.mVertexBuffer->setBuffer(mask & ~LLVertexBuffer::MAP_COLOR); +					glColor4ubv(params.mGlowColor.mV); + +					// do the actual drawing, again +					params.mVertexBuffer->drawRange(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset); +					gPipeline.addTrianglesDrawn(params.mCount, params.mDrawMode); + +					// restore our alpha blend mode +					gGL.blendFunc(mColorSFactor, mColorDFactor, mAlphaSFactor, mAlphaDFactor); +				} +			  				if (params.mTextureMatrix && params.mTexture.notNull())  				{  					gGL.getTexUnit(0)->activate(); diff --git a/indra/newview/lldrawpoolalpha.h b/indra/newview/lldrawpoolalpha.h index 3aa752f72c..61f73d0b31 100644 --- a/indra/newview/lldrawpoolalpha.h +++ b/indra/newview/lldrawpoolalpha.h @@ -34,6 +34,7 @@  #define LL_LLDRAWPOOLALPHA_H  #include "lldrawpool.h" +#include "llrender.h"  #include "llframetimer.h"  class LLFace; @@ -83,6 +84,12 @@ private:  	LLGLSLShader* target_shader;  	LLGLSLShader* simple_shader;  	LLGLSLShader* fullbright_shader;	 + +	// our 'normal' alpha blend function for this pass +	LLRender::eBlendFactor mColorSFactor; +	LLRender::eBlendFactor mColorDFactor;	 +	LLRender::eBlendFactor mAlphaSFactor; +	LLRender::eBlendFactor mAlphaDFactor;  };  class LLDrawPoolAlphaPostWater : public LLDrawPoolAlpha diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 546b60f286..c58fbbdcd0 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -123,7 +123,7 @@ void LLDrawPoolAvatar::prerender()  	if (sShaderLevel > 0)  	{ -		sBufferUsage = GL_STATIC_DRAW_ARB; +		sBufferUsage = GL_DYNAMIC_DRAW_ARB;  	}  	else  	{ @@ -157,6 +157,8 @@ void LLDrawPoolAvatar::beginDeferredPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_CHARACTERS); +	sSkipTransparent = TRUE; +  	if (LLPipeline::sImpostorRender)  	{  		beginDeferredSkinned(); @@ -181,6 +183,8 @@ void LLDrawPoolAvatar::endDeferredPass(S32 pass)  {  	LLFastTimer t(FTM_RENDER_CHARACTERS); +	sSkipTransparent = FALSE; +  	if (LLPipeline::sImpostorRender)  	{  		endDeferredSkinned(); @@ -250,7 +254,6 @@ S32 LLDrawPoolAvatar::getNumShadowPasses()  void LLDrawPoolAvatar::beginShadowPass(S32 pass)  {  	LLFastTimer t(FTM_SHADOW_AVATAR); -	  	sVertexProgram = &gDeferredAvatarShadowProgram;  	if (sShaderLevel > 0)  	{ @@ -272,7 +275,6 @@ void LLDrawPoolAvatar::beginShadowPass(S32 pass)  void LLDrawPoolAvatar::endShadowPass(S32 pass)  {  	LLFastTimer t(FTM_SHADOW_AVATAR); -  	if (sShaderLevel > 0)  	{  		sRenderingSkinned = FALSE; @@ -310,6 +312,11 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)  		return;  	} +	if (sShaderLevel > 0) +	{ +		gAvatarMatrixParam = sVertexProgram->mUniform[LLViewerShaderMgr::AVATAR_MATRIX]; +	} +  	avatarp->renderSkinned(AVATAR_RENDER_PASS_SINGLE);  } @@ -346,7 +353,7 @@ void LLDrawPoolAvatar::beginRenderPass(S32 pass)  	switch (pass)  	{  	case 0: -		beginFootShadow(); +		beginImpostor();  		break;  	case 1:  		beginRigid(); @@ -370,7 +377,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)  	switch (pass)  	{  	case 0: -		endFootShadow(); +		endImpostor();  		break;  	case 1:  		endRigid(); @@ -380,7 +387,7 @@ void LLDrawPoolAvatar::endRenderPass(S32 pass)  	}  } -void LLDrawPoolAvatar::beginFootShadow() +void LLDrawPoolAvatar::beginImpostor()  {  	if (!LLPipeline::sReflectionRender)  	{ @@ -392,7 +399,7 @@ void LLDrawPoolAvatar::beginFootShadow()  	diffuse_channel = 0;  } -void LLDrawPoolAvatar::endFootShadow() +void LLDrawPoolAvatar::endImpostor()  {  	gPipeline.enableLightsDynamic();  } @@ -564,7 +571,6 @@ void LLDrawPoolAvatar::endSkinned()  void LLDrawPoolAvatar::beginDeferredSkinned()  { -	sSkipTransparent = TRUE;  	sShaderLevel = mVertexShaderLevel;  	sVertexProgram = &gDeferredAvatarProgram; @@ -579,7 +585,6 @@ void LLDrawPoolAvatar::beginDeferredSkinned()  void LLDrawPoolAvatar::endDeferredSkinned()  { -	sSkipTransparent = FALSE;  	// if we're in software-blending, remember to set the fence _after_ we draw so we wait till this rendering is done  	sRenderingSkinned = FALSE;  	disable_vertex_weighting(sVertexProgram->mAttribute[LLViewerShaderMgr::AVATAR_WEIGHT]); @@ -691,10 +696,6 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)  			}  			avatarp->renderImpostor(LLColor4U(255,255,255,255), diffuse_channel);  		} -		else if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS) && !LLPipeline::sRenderDeferred) -		{ -			avatarp->renderFootShadows();	 -		}  		return;  	} @@ -848,9 +849,7 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const  LLVertexBufferAvatar::LLVertexBufferAvatar()  : LLVertexBuffer(sDataMask,  -	LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0 ?	 -	GL_DYNAMIC_DRAW_ARB :  -	GL_STREAM_DRAW_ARB) +	GL_STREAM_DRAW_ARB) //avatars are always stream draw due to morph targets  {  } diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index b947943619..d247260527 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -88,11 +88,11 @@ public:  	/*virtual*/ void renderShadow(S32 pass);  	void beginRigid(); -	void beginFootShadow(); +	void beginImpostor();  	void beginSkinned();  	void endRigid(); -	void endFootShadow(); +	void endImpostor();  	void endSkinned();  	void beginDeferredImpostor(); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 19cdccb630..84fbb861ba 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -94,7 +94,16 @@ void LLStandardBumpmap::shutdown()  // static   void LLStandardBumpmap::restoreGL()  { -	llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); +	addstandard(); +} + +// static +void LLStandardBumpmap::addstandard() +{ +	// can't assert; we destroyGL and restoreGL a lot during *first* startup, which populates this list already, THEN we explicitly init the list as part of *normal* startup.  Sigh.  So clear the list every time before we (re-)add the standard bumpmaps. +	//llassert( LLStandardBumpmap::sStandardBumpmapCount == 0 ); +	clear(); +	llinfos << "Adding standard bumpmaps." << llendl;  	gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("None");		// BE_NO_BUMP  	gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Brightness");	// BE_BRIGHTNESS  	gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount++] = LLStandardBumpmap("Darkness");	// BE_DARKNESS @@ -156,8 +165,9 @@ void LLStandardBumpmap::restoreGL()  }  // static -void LLStandardBumpmap::destroyGL() +void LLStandardBumpmap::clear()  { +	llinfos << "Clearing standard bumpmaps." << llendl;  	for( U32 i = 0; i < LLStandardBumpmap::sStandardBumpmapCount; i++ )  	{  		gStandardBumpmapList[i].mLabel.assign(""); @@ -166,6 +176,12 @@ void LLStandardBumpmap::destroyGL()  	sStandardBumpmapCount = 0;  } +// static +void LLStandardBumpmap::destroyGL() +{ +	clear(); +} +  //////////////////////////////////////////////////////////////// @@ -618,9 +634,9 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel)  }  //static -void LLDrawPoolBump::beginBump() +void LLDrawPoolBump::beginBump(U32 pass)  {	 -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +	if (!gPipeline.hasRenderBatches(pass))  	{  		return;  	} @@ -663,9 +679,9 @@ void LLDrawPoolBump::beginBump()  }  //static -void LLDrawPoolBump::renderBump() +void LLDrawPoolBump::renderBump(U32 pass)  { -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +	if (!gPipeline.hasRenderBatches(pass))  	{  		return;  	} @@ -678,13 +694,13 @@ void LLDrawPoolBump::renderBump()  	/// Get rid of z-fighting with non-bump pass.  	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL);  	glPolygonOffset(-1.0f, -1.0f); -	renderBump(LLRenderPass::PASS_BUMP, sVertexMask); +	renderBump(pass, sVertexMask);  }  //static -void LLDrawPoolBump::endBump() +void LLDrawPoolBump::endBump(U32 pass)  { -	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) +	if (!gPipeline.hasRenderBatches(pass))  	{  		return;  	} @@ -701,6 +717,18 @@ void LLDrawPoolBump::endBump()  	gGL.setSceneBlendType(LLRender::BT_ALPHA);  } +S32 LLDrawPoolBump::getNumDeferredPasses() +{  +	if (gSavedSettings.getBOOL("RenderObjectBump")) +	{ +		return 1; +	} +	else +	{ +		return 0; +	} +} +  void LLDrawPoolBump::beginDeferredPass(S32 pass)  {  	if (!gPipeline.hasRenderBatches(LLRenderPass::PASS_BUMP)) @@ -755,21 +783,45 @@ void LLDrawPoolBump::renderDeferred(S32 pass)  void LLDrawPoolBump::beginPostDeferredPass(S32 pass)  { -	beginFullbrightShiny(); +	switch (pass) +	{ +	case 0: +		beginFullbrightShiny(); +		break; +	case 1: +		beginBump(LLRenderPass::PASS_POST_BUMP); +		break; +	}  }  void LLDrawPoolBump::endPostDeferredPass(S32 pass)  { -	endFullbrightShiny(); +	switch (pass) +	{ +	case 0: +		endFullbrightShiny(); +		break; +	case 1: +		endBump(LLRenderPass::PASS_POST_BUMP); +		break; +	}  }  void LLDrawPoolBump::renderPostDeferred(S32 pass)  { -	renderFullbrightShiny(); +	switch (pass) +	{ +	case 0: +		renderFullbrightShiny(); +		break; +	case 1: +		renderBump(LLRenderPass::PASS_POST_BUMP); +		break; +	}  }  //////////////////////////////////////////////////////////////// -// List of one-component bump-maps created from other texures. +// List of bump-maps created from other textures.  //const LLUUID TEST_BUMP_ID("3d33eaf2-459c-6f97-fd76-5fce3fc29447"); @@ -782,24 +834,32 @@ void LLBumpImageList::init()  	LLStandardBumpmap::init();  } -void LLBumpImageList::shutdown() +void LLBumpImageList::clear()  { +	llinfos << "Clearing dynamic bumpmaps." << llendl; +	// these will be re-populated on-demand  	mBrightnessEntries.clear();  	mDarknessEntries.clear(); + +	LLStandardBumpmap::clear(); +} + +void LLBumpImageList::shutdown() +{ +	clear();  	LLStandardBumpmap::shutdown();  }  void LLBumpImageList::destroyGL()  { -	mBrightnessEntries.clear(); -	mDarknessEntries.clear(); +	clear();  	LLStandardBumpmap::destroyGL();  }  void LLBumpImageList::restoreGL()  { -	// Images will be recreated as they are needed.  	LLStandardBumpmap::restoreGL(); +	// Images will be recreated as they are needed.  } @@ -851,6 +911,7 @@ void LLBumpImageList::updateImages()  			}  		}  	} +	  	for (bump_image_map_t::iterator iter = mDarknessEntries.begin(); iter != mDarknessEntries.end(); )  	{  		bump_image_map_t::iterator curiter = iter++; @@ -1002,8 +1063,8 @@ void LLBumpImageList::generateNormalMapFromAlpha(LLImageRaw* src, LLImageRaw* nr  			LLVector3 right = LLVector3(norm_scale, 0, (F32) src_data[(j*resX+rX)*src_cmp+src_cmp-1]-cH);  			LLVector3 left = LLVector3(-norm_scale, 0, (F32) src_data[(j*resX+lX)*src_cmp+src_cmp-1]-cH); -			LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH); -			LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); +			LLVector3 up = LLVector3(0, -norm_scale, (F32) src_data[(lY*resX+i)*src_cmp+src_cmp-1]-cH); +			LLVector3 down = LLVector3(0, norm_scale, (F32) src_data[(rY*resX+i)*src_cmp+src_cmp-1]-cH);  			LLVector3 norm = right%down + down%left + left%up + up%right; @@ -1028,7 +1089,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  	{  		bump_image_map_t& entries_list(bump_code == BE_BRIGHTNESS ? gBumpImageList.mBrightnessEntries : gBumpImageList.mDarknessEntries );  		bump_image_map_t::iterator iter = entries_list.find(source_asset_id); -		if (iter != entries_list.end()) +		if (iter != entries_list.end()) // bump not cached yet  		{  			LLPointer<LLImageRaw> dst_image = new LLImageRaw(src->getWidth(), src->getHeight(), 1);  			U8* dst_data = dst_image->getData(); @@ -1113,8 +1174,8 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  				F32 twice_one_over_range = 2.f / (maximum - minimum);  				S32 i; -				const F32 ARTIFICIAL_SCALE = 2.f;  // Advantage: exagerates the effect in midrange.  Disadvantage: clamps at the extremes. -				if( BE_DARKNESS == bump_code ) +				const F32 ARTIFICIAL_SCALE = 2.f;  // Advantage: exaggerates the effect in midrange.  Disadvantage: clamps at the extremes. +				if (BE_DARKNESS == bump_code)  				{  					for( i = minimum; i <= maximum; i++ )  					{ @@ -1124,7 +1185,6 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  				}  				else  				{ -					// BE_LIGHTNESS  					for( i = minimum; i <= maximum; i++ )  					{  						F32 minus_one_to_one = F32(i - minimum) * twice_one_over_range - 1.f; @@ -1139,9 +1199,9 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  			}  			//--------------------------------------------------- -			//immediately assign bump to a global smart pointer in case some local smart pointer -			//accidently releases it. -			LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE); +			// immediately assign bump to a global smart pointer in case some local smart pointer +			// accidentally releases it. +			LLPointer<LLViewerTexture> bump = LLViewerTextureManager::getLocalTexture( TRUE );  			if (!LLPipeline::sRenderDeferred)  			{ @@ -1150,8 +1210,8 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI  			}  			else  			{ -				LLPointer<LLImageRaw> nrm_image = new LLImageRaw(src->getWidth(), src->getHeight(), 4); -				generateNormalMapFromAlpha(src, nrm_image); +				LLPointer<LLImageRaw> nrm_image = new LLImageRaw(dst_image->getWidth(), dst_image->getHeight(), 4); +				generateNormalMapFromAlpha(dst_image, nrm_image);  				bump->setExplicitFormat(GL_RGBA, GL_RGBA);  				bump->createGLTexture(0, nrm_image);  			} diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index bf940cf1e4..07846c2812 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -75,16 +75,16 @@ public:  	void renderFullbrightShiny();  	void endFullbrightShiny(); -	void beginBump(); -	void renderBump(); -	void endBump(); +	void beginBump(U32 pass = LLRenderPass::PASS_BUMP); +	void renderBump(U32 pass = LLRenderPass::PASS_BUMP); +	void endBump(U32 pass = LLRenderPass::PASS_BUMP); -	virtual S32 getNumDeferredPasses() { return 1; } +	virtual S32 getNumDeferredPasses();  	/*virtual*/ void beginDeferredPass(S32 pass);  	/*virtual*/ void endDeferredPass(S32 pass);  	/*virtual*/ void renderDeferred(S32 pass); -	virtual S32 getNumPostDeferredPasses() { return 1; } +	virtual S32 getNumPostDeferredPasses() { return 2; }  	/*virtual*/ void beginPostDeferredPass(S32 pass);  	/*virtual*/ void endPostDeferredPass(S32 pass);  	/*virtual*/ void renderPostDeferred(S32 pass); @@ -115,9 +115,12 @@ public:  	static	U32 sStandardBumpmapCount;  // Number of valid values in gStandardBumpmapList[] +	static void clear(); +	static void addstandard(); +  	static void init();  	static void shutdown(); -	static void	restoreGL(); +	static void restoreGL();  	static void destroyGL();  }; @@ -136,6 +139,7 @@ public:  	void		init();  	void		shutdown(); +	void            clear();  	void		destroyGL();  	void		restoreGL();  	void		updateImages(); diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index ca7a1b47c2..91191287cd 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -55,6 +55,10 @@ void LLDrawPoolGlow::render(S32 pass)  	LLFastTimer t(FTM_RENDER_GLOW);  	LLGLEnable blend(GL_BLEND);  	LLGLDisable test(GL_ALPHA_TEST); +	gGL.flush(); +	/// Get rid of z-fighting with non-glow pass. +	LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); +	glPolygonOffset(-1.0f, -1.0f);  	gGL.setSceneBlendType(LLRender::BT_ADD);  	U32 shader_level = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_OBJECT); @@ -147,7 +151,8 @@ void LLDrawPoolSimple::render(S32 pass)  		renderTexture(LLRenderPass::PASS_SIMPLE, getVertexDataMask());  		if (LLPipeline::sRenderDeferred) -		{ +		{ //if deferred rendering is enabled, bump faces aren't reigstered as simple +			//render bump faces here as simple so bump faces will appear under water  			renderTexture(LLRenderPass::PASS_BUMP, getVertexDataMask());  		}  	} diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index e0e5b32299..6a1a9dd4e1 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -862,11 +862,34 @@ void LLFace::updateRebuildFlags()  	}  } + +bool LLFace::canRenderAsMask() +{ +	const LLTextureEntry* te = getTextureEntry(); +	return ( +		( +		 (LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaDeferred) || +		  +		 (!LLPipeline::sRenderDeferred && LLPipeline::sAutoMaskAlphaNonDeferred)		  +		 ) // do we want masks at all? +		&& +		(te->getColor().mV[3] == 1.0f) && // can't treat as mask if we have face alpha +		!(LLPipeline::sRenderDeferred && te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible in deferred rendering mode, need to figure out why - for now, avoid +		(te->getGlow() == 0.f) && // glowing masks are hard to implement - don't mask + +		getTexture()->getIsAlphaMask() // texture actually qualifies for masking (lazily recalculated but expensive) +		); +} + + +static LLFastTimer::DeclareTimer FTM_FACE_GET_GEOM("Face Geom"); +  BOOL LLFace::getGeometryVolume(const LLVolume& volume,  							   const S32 &f,  								const LLMatrix4& mat_vert, const LLMatrix3& mat_normal,  								const U16 &index_offset)  { +	LLFastTimer t(FTM_FACE_GET_GEOM);  	const LLVolumeFace &vf = volume.getVolumeFace(f);  	S32 num_vertices = (S32)vf.mVertices.size();  	S32 num_indices = LLPipeline::sUseTriStrips ? (S32)vf.mTriStrip.size() : (S32) vf.mIndices.size(); diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 67dd97e6f7..02cc2af433 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -138,10 +138,10 @@ public:  	void			unsetFaceColor(); // switch back to material color  	const LLColor4&	getFaceColor() const { return mFaceColor; }   	const LLColor4& getRenderColor() const; -	  	//for volumes  	void updateRebuildFlags(); +	bool canRenderAsMask(); // logic helper  	BOOL getGeometryVolume(const LLVolume& volume,  						const S32 &f,  						const LLMatrix4& mat_vert, const LLMatrix3& mat_normal, diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 0eeef0039c..f29f7160e8 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -799,7 +799,7 @@ void LLFloaterPreference::buildPopupLists()  void LLFloaterPreference::refreshEnabledState()  {	 -	LLCheckBoxCtrl* ctrl_reflections = getChild<LLCheckBoxCtrl>("Reflections"); +	LLComboBox* ctrl_reflections = getChild<LLComboBox>("Reflections");  	LLRadioGroup* radio_reflection_detail = getChild<LLRadioGroup>("ReflectionDetailRadio");  	// Reflections @@ -812,7 +812,7 @@ void LLFloaterPreference::refreshEnabledState()  	bool bumpshiny = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps && LLFeatureManager::getInstance()->isFeatureAvailable("RenderObjectBump");  	getChild<LLCheckBoxCtrl>("BumpShiny")->setEnabled(bumpshiny ? TRUE : FALSE); -	radio_reflection_detail->setEnabled(ctrl_reflections->get() && reflections); +	radio_reflection_detail->setEnabled(reflections);  	// Avatar Mode  	// Enable Avatar Shaders @@ -858,6 +858,30 @@ void LLFloaterPreference::refreshEnabledState()  	// *HACK just checks to see if we can use shaders...   	// maybe some cards that use shaders, but don't support windlight  	ctrl_wind_light->setEnabled(ctrl_shader_enable->getEnabled() && shaders); + +	//Deferred/SSAO/Shadows +	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +	if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseFBO") && +	    LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +		shaders) +	{ +		BOOL enabled = (ctrl_wind_light->get()) ? TRUE : FALSE; + +		ctrl_deferred->setEnabled(enabled); +	 +		LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO"); +		LLComboBox* ctrl_shadow = getChild<LLComboBox>("ShadowDetail"); + +		enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO") && (ctrl_deferred->get() ? TRUE : FALSE); +		 +		ctrl_ssao->setEnabled(enabled); + +		enabled = enabled && LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail"); + +		ctrl_shadow->setEnabled(enabled); +	} + +  	// now turn off any features that are unavailable  	disableUnavailableSettings(); @@ -866,12 +890,15 @@ void LLFloaterPreference::refreshEnabledState()  void LLFloaterPreference::disableUnavailableSettings()  {	 -	LLCheckBoxCtrl* ctrl_reflections   = getChild<LLCheckBoxCtrl>("Reflections"); +	LLComboBox* ctrl_reflections   = getChild<LLComboBox>("Reflections");  	LLCheckBoxCtrl* ctrl_avatar_vp     = getChild<LLCheckBoxCtrl>("AvatarVertexProgram");  	LLCheckBoxCtrl* ctrl_avatar_cloth  = getChild<LLCheckBoxCtrl>("AvatarCloth");  	LLCheckBoxCtrl* ctrl_shader_enable = getChild<LLCheckBoxCtrl>("BasicShaders");  	LLCheckBoxCtrl* ctrl_wind_light    = getChild<LLCheckBoxCtrl>("WindLightUseAtmosShaders");  	LLCheckBoxCtrl* ctrl_avatar_impostors = getChild<LLCheckBoxCtrl>("AvatarImpostors"); +	LLCheckBoxCtrl* ctrl_deferred = getChild<LLCheckBoxCtrl>("UseLightShaders"); +	LLComboBox* ctrl_shadows = getChild<LLComboBox>("ShadowDetail"); +	LLCheckBoxCtrl* ctrl_ssao = getChild<LLCheckBoxCtrl>("UseSSAO");  	// if vertex shaders off, disable all shader related products  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("VertexShaderEnable")) @@ -883,13 +910,22 @@ void LLFloaterPreference::disableUnavailableSettings()  		ctrl_wind_light->setValue(FALSE);  		ctrl_reflections->setEnabled(FALSE); -		ctrl_reflections->setValue(FALSE); +		ctrl_reflections->setValue(0);  		ctrl_avatar_vp->setEnabled(FALSE);  		ctrl_avatar_vp->setValue(FALSE);  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE); + +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE);  	}  	// disabled windlight @@ -897,10 +933,47 @@ void LLFloaterPreference::disableUnavailableSettings()  	{  		ctrl_wind_light->setEnabled(FALSE);  		ctrl_wind_light->setValue(FALSE); + +		//deferred needs windlight, disable deferred +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE); +	} + +	// disabled deferred +	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred")) +	{ +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE); +	} +	 +	// disabled deferred SSAO +	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferredSSAO")) +	{ +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE);  	} +	// disabled deferred shadows +	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderShadowDetail")) +	{ +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +	} +  	// disabled reflections -	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderWaterReflections")) +	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderReflectionDetail"))  	{  		ctrl_reflections->setEnabled(FALSE);  		ctrl_reflections->setValue(FALSE); @@ -914,13 +987,25 @@ void LLFloaterPreference::disableUnavailableSettings()  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE); + +		//deferred needs AvatarVP, disable deferred +		ctrl_shadows->setEnabled(FALSE); +		ctrl_shadows->setValue(0); +		 +		ctrl_ssao->setEnabled(FALSE); +		ctrl_ssao->setValue(FALSE); + +		ctrl_deferred->setEnabled(FALSE); +		ctrl_deferred->setValue(FALSE);  	} +  	// disabled cloth  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderAvatarCloth"))  	{  		ctrl_avatar_cloth->setEnabled(FALSE);  		ctrl_avatar_cloth->setValue(FALSE);  	} +  	// disabled impostors  	if(!LLFeatureManager::getInstance()->isFeatureAvailable("RenderUseImpostors"))  	{ diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index fbe68b4d92..8b01637239 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -574,7 +574,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )  		LLUUID id = LightTextureCtrl->getImageAssetID();  		if (id.notNull())  		{ -			if (volobjp->getLightTextureID().isNull()) +			if (!volobjp->isLightSpotlight())  			{ //this commit is making this a spot light, set UI to default params  				volobjp->setLightTextureID(id);  				LLVector3 spot_params = volobjp->getSpotLightParams(); @@ -591,7 +591,7 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata )  				volobjp->setSpotLightParams(spot_params);  			}  		} -		else if (volobjp->getLightTextureID().notNull()) +		else if (volobjp->isLightSpotlight())  		{ //no longer a spot light  			volobjp->setLightTextureID(id);  			//self->childDisable("Light FOV"); diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index d6e9256fee..c229657ded 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1513,6 +1513,7 @@ void LLSpatialGroup::checkOcclusion()  {  	if (LLPipeline::sUseOcclusion > 1)  	{ +		LLFastTimer t(FTM_OCCLUSION_READBACK);  		LLSpatialGroup* parent = getParent();  		if (parent && parent->isOcclusionState(LLSpatialGroup::OCCLUDED))  		{	//if the parent has been marked as occluded, the child is implicitly occluded @@ -1520,7 +1521,6 @@ void LLSpatialGroup::checkOcclusion()  		}  		else if (isOcclusionState(QUERY_PENDING))  		{	//otherwise, if a query is pending, read it back -			LLFastTimer t(FTM_OCCLUSION_READBACK);  			GLuint res = 1;  			if (!isOcclusionState(DISCARD_QUERY) && mOcclusionQuery[LLViewerCamera::sCurCameraID])  			{ @@ -1924,11 +1924,8 @@ public:  			return;  		} -		if (mRes == 2) -		{ -			//fully in, don't traverse further (won't effect extents -		} -		else if (mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) +		if ((mRes && group->isState(LLSpatialGroup::SKIP_FRUSTUM_CHECK)) || +			mRes == 2)  		{	//don't need to do frustum check  			LLSpatialGroup::OctreeTraveler::traverse(n);  		} @@ -3423,11 +3420,23 @@ LLCullResult::LLCullResult()  void LLCullResult::clear()  {  	mVisibleGroupsSize = 0; +	mVisibleGroupsEnd = mVisibleGroups.begin(); +  	mAlphaGroupsSize = 0; +	mAlphaGroupsEnd = mAlphaGroups.begin(); +  	mOcclusionGroupsSize = 0; +	mOcclusionGroupsEnd = mOcclusionGroups.begin(); +  	mDrawableGroupsSize = 0; +	mDrawableGroupsEnd = mDrawableGroups.begin(); +  	mVisibleListSize = 0; +	mVisibleListEnd = mVisibleList.begin(); +  	mVisibleBridgeSize = 0; +	mVisibleBridgeEnd = mVisibleBridge.begin(); +  	for (U32 i = 0; i < LLRenderPass::NUM_RENDER_TYPES; i++)  	{ @@ -3436,6 +3445,7 @@ void LLCullResult::clear()  			mRenderMap[i][j] = 0;  		}  		mRenderMapSize[i] = 0; +		mRenderMapEnd[i] = mRenderMap[i].begin();  	}  } @@ -3446,7 +3456,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginVisibleGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endVisibleGroups()  { -	return mVisibleGroups.begin() + mVisibleGroupsSize; +	return mVisibleGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups() @@ -3456,7 +3466,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginAlphaGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endAlphaGroups()  { -	return mAlphaGroups.begin() + mAlphaGroupsSize; +	return mAlphaGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups() @@ -3466,7 +3476,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginOcclusionGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endOcclusionGroups()  { -	return mOcclusionGroups.begin() + mOcclusionGroupsSize; +	return mOcclusionGroupsEnd;  }  LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups() @@ -3476,7 +3486,7 @@ LLCullResult::sg_list_t::iterator LLCullResult::beginDrawableGroups()  LLCullResult::sg_list_t::iterator LLCullResult::endDrawableGroups()  { -	return mDrawableGroups.begin() + mDrawableGroupsSize; +	return mDrawableGroupsEnd;  }  LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList() @@ -3486,7 +3496,7 @@ LLCullResult::drawable_list_t::iterator LLCullResult::beginVisibleList()  LLCullResult::drawable_list_t::iterator LLCullResult::endVisibleList()  { -	return mVisibleList.begin() + mVisibleListSize; +	return mVisibleListEnd;  }  LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge() @@ -3496,7 +3506,7 @@ LLCullResult::bridge_list_t::iterator LLCullResult::beginVisibleBridge()  LLCullResult::bridge_list_t::iterator LLCullResult::endVisibleBridge()  { -	return mVisibleBridge.begin() + mVisibleBridgeSize; +	return mVisibleBridgeEnd;  }  LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type) @@ -3506,7 +3516,7 @@ LLCullResult::drawinfo_list_t::iterator LLCullResult::beginRenderMap(U32 type)  LLCullResult::drawinfo_list_t::iterator LLCullResult::endRenderMap(U32 type)  { -	return mRenderMap[type].begin() + mRenderMapSize[type]; +	return mRenderMapEnd[type];  }  void LLCullResult::pushVisibleGroup(LLSpatialGroup* group) @@ -3520,6 +3530,7 @@ void LLCullResult::pushVisibleGroup(LLSpatialGroup* group)  		mVisibleGroups.push_back(group);  	}  	++mVisibleGroupsSize; +	mVisibleGroupsEnd = mVisibleGroups.begin()+mVisibleGroupsSize;  }  void LLCullResult::pushAlphaGroup(LLSpatialGroup* group) @@ -3533,6 +3544,7 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)  		mAlphaGroups.push_back(group);  	}  	++mAlphaGroupsSize; +	mAlphaGroupsEnd = mAlphaGroups.begin()+mAlphaGroupsSize;  }  void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group) @@ -3546,6 +3558,7 @@ void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)  		mOcclusionGroups.push_back(group);  	}  	++mOcclusionGroupsSize; +	mOcclusionGroupsEnd = mOcclusionGroups.begin()+mOcclusionGroupsSize;  }  void LLCullResult::pushDrawableGroup(LLSpatialGroup* group) @@ -3559,6 +3572,7 @@ void LLCullResult::pushDrawableGroup(LLSpatialGroup* group)  		mDrawableGroups.push_back(group);  	}  	++mDrawableGroupsSize; +	mDrawableGroupsEnd = mDrawableGroups.begin()+mDrawableGroupsSize;  }  void LLCullResult::pushDrawable(LLDrawable* drawable) @@ -3572,6 +3586,7 @@ void LLCullResult::pushDrawable(LLDrawable* drawable)  		mVisibleList.push_back(drawable);  	}  	++mVisibleListSize; +	mVisibleListEnd = mVisibleList.begin()+mVisibleListSize;  }  void LLCullResult::pushBridge(LLSpatialBridge* bridge) @@ -3585,6 +3600,7 @@ void LLCullResult::pushBridge(LLSpatialBridge* bridge)  		mVisibleBridge.push_back(bridge);  	}  	++mVisibleBridgeSize; +	mVisibleBridgeEnd = mVisibleBridge.begin()+mVisibleBridgeSize;  }  void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info) @@ -3598,6 +3614,7 @@ void LLCullResult::pushDrawInfo(U32 type, LLDrawInfo* draw_info)  		mRenderMap[type].push_back(draw_info);  	}  	++mRenderMapSize[type]; +	mRenderMapEnd[type] = mRenderMap[type].begin() + mRenderMapSize[type];  } diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 7896488379..19af6a0c38 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -346,11 +346,11 @@ public:  	F32 mBuilt;  	OctreeNode* mOctreeNode;  	LLSpatialPartition* mSpatialPartition; -	LLVector3 mBounds[2]; -	LLVector3 mExtents[2]; +	LLVector3 mBounds[2]; // bounding box (center, size) of this node and all its children (tight fit to objects) +	LLVector3 mExtents[2]; // extents (min, max) of this node and all its children -	LLVector3 mObjectExtents[2]; -	LLVector3 mObjectBounds[2]; +	LLVector3 mObjectExtents[2]; // extents (min, max) of objects in this node +	LLVector3 mObjectBounds[2]; // bounding box (center, size) of objects in this node  	LLPointer<LLVertexBuffer> mVertexBuffer;  	F32*					mOcclusionVerts; @@ -534,12 +534,19 @@ private:  	U32					mRenderMapSize[LLRenderPass::NUM_RENDER_TYPES];  	sg_list_t			mVisibleGroups; +	sg_list_t::iterator mVisibleGroupsEnd;  	sg_list_t			mAlphaGroups; +	sg_list_t::iterator mAlphaGroupsEnd;  	sg_list_t			mOcclusionGroups; +	sg_list_t::iterator	mOcclusionGroupsEnd;  	sg_list_t			mDrawableGroups; +	sg_list_t::iterator mDrawableGroupsEnd;  	drawable_list_t		mVisibleList; +	drawable_list_t::iterator mVisibleListEnd;  	bridge_list_t		mVisibleBridge; +	bridge_list_t::iterator mVisibleBridgeEnd;  	drawinfo_list_t		mRenderMap[LLRenderPass::NUM_RENDER_TYPES]; +	drawinfo_list_t::iterator mRenderMapEnd[LLRenderPass::NUM_RENDER_TYPES];  }; @@ -606,14 +613,13 @@ public:  //class for wrangling geometry out of volumes (implemented in LLVOVolume.cpp)  class LLVolumeGeometryManager: public LLGeometryManager  { -public: + public:  	virtual ~LLVolumeGeometryManager() { }  	virtual void rebuildGeom(LLSpatialGroup* group);  	virtual void rebuildMesh(LLSpatialGroup* group);  	virtual void getGeometry(LLSpatialGroup* group);  	void genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort = FALSE);  	void registerFace(LLSpatialGroup* group, LLFace* facep, U32 type); -  };  //spatial partition that uses volume geometry manager (implemented in LLVOVolume.cpp) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index f02e15706d..2144ab1489 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -43,6 +43,7 @@  #include "llagent.h"  #include "llagentcamera.h"  #include "llconsole.h" +#include "lldrawpoolbump.h"  #include "lldrawpoolterrain.h"  #include "llflexibleobject.h"  #include "llfeaturemanager.h" @@ -117,6 +118,10 @@ static bool handleTerrainDetailChanged(const LLSD& newvalue)  static bool handleSetShaderChanged(const LLSD& newvalue)  { +	// changing shader level may invalidate existing cached bump maps, as the shader type determines the format of the bump map it expects - clear and repopulate the bump cache +	gBumpImageList.destroyGL(); +	gBumpImageList.restoreGL(); +  	LLViewerShaderMgr::instance()->setShaders();  	return true;  } @@ -298,15 +303,6 @@ static bool handleWLSkyDetailChanged(const LLSD&)  	return true;  } -static bool handleRenderLightingDetailChanged(const LLSD& newvalue) -{ -	if (gPipeline.isInit()) -	{ -		gPipeline.setLightingDetail(newvalue.asInteger()); -	} -	return true; -} -  static bool handleResetVertexBuffersChanged(const LLSD&)  {  	if (gPipeline.isInit()) @@ -489,6 +485,10 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderAvatarVP")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("VertexShaderEnable")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderUIBuffer")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderSpecularResX")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderSpecularResY")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderSpecularExponent")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2)); +	gSavedSettings.getControl("RenderFSAASamples")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderShadowResolutionScale")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleReleaseGLBufferChanged, _2));  	gSavedSettings.getControl("RenderGlow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); @@ -509,7 +509,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _2));  	gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _2));  	gSavedSettings.getControl("RenderDebugTextureBind")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); -	gSavedSettings.getControl("RenderFastAlpha")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); +	gSavedSettings.getControl("RenderAutoMaskAlphaDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2)); +	gSavedSettings.getControl("RenderAutoMaskAlphaNonDeferred")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderObjectBump")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderMaxVBOSize")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("RenderUseFBO")->getSignal()->connect(boost::bind(&handleRenderUseFBOChanged, _2)); @@ -519,7 +520,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("RenderDebugPipeline")->getSignal()->connect(boost::bind(&handleRenderDebugPipelineChanged, _2));  	gSavedSettings.getControl("RenderResolutionDivisor")->getSignal()->connect(boost::bind(&handleRenderResolutionDivisorChanged, _2));  	gSavedSettings.getControl("RenderDeferred")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); -	gSavedSettings.getControl("RenderDeferredShadow")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); +	gSavedSettings.getControl("RenderShadowDetail")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2)); +	gSavedSettings.getControl("RenderDeferredSSAO")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("RenderDeferredGI")->getSignal()->connect(boost::bind(&handleSetShaderChanged, _2));  	gSavedSettings.getControl("TextureMemory")->getSignal()->connect(boost::bind(&handleVideoMemoryChanged, _2));  	gSavedSettings.getControl("AuditTexture")->getSignal()->connect(boost::bind(&handleAuditTextureChanged, _2)); @@ -544,8 +546,8 @@ void settings_setup_listeners()  	gSavedSettings.getControl("MuteAmbient")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));  	gSavedSettings.getControl("MuteUI")->getSignal()->connect(boost::bind(&handleAudioVolumeChanged, _2));  	gSavedSettings.getControl("RenderVBOEnable")->getSignal()->connect(boost::bind(&handleRenderUseVBOChanged, _2)); +	gSavedSettings.getControl("RenderUseStreamVBO")->getSignal()->connect(boost::bind(&handleResetVertexBuffersChanged, _2));  	gSavedSettings.getControl("WLSkyDetail")->getSignal()->connect(boost::bind(&handleWLSkyDetailChanged, _2)); -	gSavedSettings.getControl("RenderLightingDetail")->getSignal()->connect(boost::bind(&handleRenderLightingDetailChanged, _2));  	gSavedSettings.getControl("NumpadControl")->getSignal()->connect(boost::bind(&handleNumpadControlChanged, _2));  	gSavedSettings.getControl("JoystickAxis0")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2));  	gSavedSettings.getControl("JoystickAxis1")->getSignal()->connect(boost::bind(&handleJoystickChanged, _2)); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 3482ac508e..48df946a5d 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -595,7 +595,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			LLPipeline::sUseOcclusion = 3;  		} -		LLPipeline::sFastAlpha = gSavedSettings.getBOOL("RenderFastAlpha"); +		LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); +		LLPipeline::sAutoMaskAlphaNonDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaNonDeferred");  		LLPipeline::sUseFarClip = gSavedSettings.getBOOL("RenderUseFarClip");  		LLVOAvatar::sMaxVisible = gSavedSettings.getS32("RenderAvatarMaxVisible");  		LLPipeline::sDelayVBUpdate = gSavedSettings.getBOOL("RenderDelayVBUpdate"); @@ -869,12 +870,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} -		/// We copy the frame buffer straight into a texture here, -		/// 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->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw()); -		  		if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)  		{  			gPipeline.renderDeferredLighting(); @@ -936,9 +931,10 @@ void render_hud_attachments()  		bool render_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES) && gSavedSettings.getBOOL("RenderHUDParticles");  		//only render hud objects -		U32 mask = gPipeline.getRenderTypeMask(); +		gPipeline.pushRenderTypeMask(); +		  		// turn off everything -		gPipeline.setRenderTypeMask(0); +		gPipeline.andRenderTypeMask(LLPipeline::END_RENDER_TYPES);  		// turn on HUD  		gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_HUD);  		// turn on HUD particles @@ -992,7 +988,8 @@ void render_hud_attachments()  		render_hud_elements();  		//restore type mask -		gPipeline.setRenderTypeMask(mask); +		gPipeline.popRenderTypeMask(); +  		if (has_ui)  		{  			gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); @@ -1117,7 +1114,7 @@ void render_ui(F32 zoom_factor, int subfield)  		{  			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);  		} - +		  		render_hud_elements();  		render_hud_attachments();  	} diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp index 95f05b5f5f..8f2006b431 100644 --- a/indra/newview/llviewerjoint.cpp +++ b/indra/newview/llviewerjoint.cpp @@ -440,13 +440,13 @@ void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pix  	}  } -void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) +void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)  {  	for (child_list_t::iterator iter = mChildren.begin();  		 iter != mChildren.end(); ++iter)  	{  		LLViewerJoint* joint = (LLViewerJoint*)(*iter); -		joint->updateFaceData(face, pixel_area, damp_wind); +		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);  	}  } diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h index 0d3092a044..67bd7786c3 100644 --- a/indra/newview/llviewerjoint.h +++ b/indra/newview/llviewerjoint.h @@ -126,7 +126,7 @@ public:  	PickName getPickName() { return mPickName; }  	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); -	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); +	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);  	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);  	virtual void updateJointGeometry();  	virtual void dump(); diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index 7225aa1523..6be7c442ef 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -667,7 +667,9 @@ void LLViewerJointMesh::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32  //-----------------------------------------------------------------------------  // updateFaceData()  //----------------------------------------------------------------------------- -void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind) +static LLFastTimer::DeclareTimer FTM_AVATAR_FACE("Avatar Face"); + +void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)  {  	mFace = face; @@ -676,6 +678,8 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w  		return;  	} +	LLFastTimer t(FTM_AVATAR_FACE); +  	LLStrider<LLVector3> verticesp;  	LLStrider<LLVector3> normalsp;  	LLStrider<LLVector2> tex_coordsp; @@ -694,29 +698,98 @@ void LLViewerJointMesh::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_w  			face->mVertexBuffer->getIndexStrider(indicesp);  			stop_glerror(); -			for (U16 i = 0; i < mMesh->getNumVertices(); i++) +			verticesp += mMesh->mFaceVertexOffset; +			tex_coordsp += mMesh->mFaceVertexOffset; +			normalsp += mMesh->mFaceVertexOffset; +			vertex_weightsp += mMesh->mFaceVertexOffset; +			clothing_weightsp += mMesh->mFaceVertexOffset; + +			const U32* __restrict coords = (U32*) mMesh->getCoords(); +			const U32* __restrict tex_coords = (U32*) mMesh->getTexCoords(); +			const U32* __restrict normals = (U32*) mMesh->getNormals(); +			const U32* __restrict weights = (U32*) mMesh->getWeights(); +			const U32* __restrict cloth_weights = (U32*) mMesh->getClothingWeights(); + +			const U32 num_verts = mMesh->getNumVertices(); + +			U32 i = 0; + +			const U32 skip = verticesp.getSkip()/sizeof(U32); + +			U32* __restrict v = (U32*) verticesp.get(); +			U32* __restrict n = (U32*) normalsp.get(); +			 +			if (terse_update)  			{ -				verticesp[mMesh->mFaceVertexOffset + i] = *(mMesh->getCoords() + i); -				tex_coordsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getTexCoords() + i); -				normalsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getNormals() + i); -				vertex_weightsp[mMesh->mFaceVertexOffset + i] = *(mMesh->getWeights() + i); -				if (damp_wind) +				for (S32 i = num_verts; i > 0; --i)  				{ -					clothing_weightsp[mMesh->mFaceVertexOffset + i] = LLVector4(0,0,0,0); +					//morph target application only, only update positions and normals +					v[0] = coords[0];  +					v[1] = coords[1];  +					v[2] = coords[2];		 +					coords += 3; +					v += skip;  				} -				else + +				for (S32 i = num_verts; i > 0; --i)  				{ -					clothing_weightsp[mMesh->mFaceVertexOffset + i] = (*(mMesh->getClothingWeights() + i)); +					n[0] = normals[0];  +					n[1] = normals[1]; +					n[2] = normals[2]; +					normals += 3; +					n += skip;  				}  			} +			else +				{ -			for (S32 i = 0; i < mMesh->getNumFaces(); i++) -			{ -				for (U32 j = 0; j < 3; j++) +				U32* __restrict tc = (U32*) tex_coordsp.get(); +				U32* __restrict vw = (U32*) vertex_weightsp.get(); +				U32* __restrict cw = (U32*) clothing_weightsp.get(); +				 +				do +				{ +					v[0] = *(coords++);  +					v[1] = *(coords++);  +					v[2] = *(coords++); +					v += skip; + +					tc[0] = *(tex_coords++);  +					tc[1] = *(tex_coords++); +					tc += skip; + +					n[0] = *(normals++);  +					n[1] = *(normals++); +					n[2] = *(normals++); +					n += skip; + +					vw[0] = *(weights++); +					vw += skip; + +					cw[0] = *(cloth_weights++); +					cw[1] = *(cloth_weights++); +					cw[2] = *(cloth_weights++); +					cw[3] = *(cloth_weights++); +					cw += skip; +				} +				while (++i < num_verts); + +				const U32 idx_count = mMesh->getNumFaces()*3; + +				indicesp += mMesh->mFaceIndexOffset; + +				U16* __restrict idx = indicesp.get(); +				S32* __restrict src_idx = (S32*) mMesh->getFaces(); + +				i = 0; + +				const S32 offset = (S32) mMesh->mFaceVertexOffset; + +				do  				{ -					U32 k = i*3+j+mMesh->mFaceIndexOffset; -					indicesp[k] = mMesh->getFaces()[i][j] + mMesh->mFaceVertexOffset; +					*(idx++) = *(src_idx++)+offset;  				} +				while (++i < idx_count);  			}  		}  	} diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h index d62b0ada85..3b8d9c82b8 100644 --- a/indra/newview/llviewerjointmesh.h +++ b/indra/newview/llviewerjointmesh.h @@ -140,7 +140,7 @@ public:  	/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );  	/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area); -	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE); +	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);  	/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);  	/*virtual*/ void updateJointGeometry();  	/*virtual*/ void dump(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 69352e6685..3a155dfb03 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2051,9 +2051,9 @@ class LLAdvancedEnableRenderDeferred: public view_listener_t  };  ///////////////////////////////////// -// Enable Global Illumination 	  /// +// Enable Deferred Rendering sub-options  ///////////////////////////////////// -class LLAdvancedEnableRenderDeferredGI: public view_listener_t +class LLAdvancedEnableRenderDeferredOptions: public view_listener_t  {  	bool handleEvent(const LLSD& userdata)  	{ @@ -6541,7 +6541,7 @@ void handle_dump_attachments(void*)  } -// these are used in the gl menus to set control values. +// these are used in the gl menus to set control values, generically.  class LLToggleControl : public view_listener_t  {  	bool handleEvent(const LLSD& userdata) @@ -6560,8 +6560,44 @@ class LLCheckControl : public view_listener_t  		std::string callback_data = userdata.asString();  		bool new_value = gSavedSettings.getBOOL(callback_data);  		return new_value; -} +	} +}; + +// not so generic +class LLAdvancedCheckRenderShadowOption: public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		std::string control_name = userdata.asString(); +		S32 current_shadow_level = gSavedSettings.getS32(control_name); +		if (current_shadow_level == 0) // is off +		{ +			return false; +		} +		else // is on +		{ +			return true; +		} +	} +}; + +class LLAdvancedClickRenderShadowOption: public view_listener_t +{ +	bool handleEvent(const LLSD& userdata) +	{ +		std::string control_name = userdata.asString(); +		S32 current_shadow_level = gSavedSettings.getS32(control_name); +		if (current_shadow_level == 0) // upgrade to level 2 +		{ +			gSavedSettings.setS32(control_name, 2); +		} +		else // downgrade to level 0 +		{ +			gSavedSettings.setS32(control_name, 0); +		} +		return true; +	}  };  void menu_toggle_attached_lights(void* user_data) @@ -7857,7 +7893,7 @@ void initialize_menus()  	// Help menu  	// most items use the ShowFloater method -	// Advance menu +	// Advanced menu  	view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");  	view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");  	view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole"); @@ -7884,12 +7920,13 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");  	view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");  	view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); +	// Develop > Render  	view_listener_t::addMenu(new LLAdvancedToggleTextureAtlas(), "Advanced.ToggleTextureAtlas");  	view_listener_t::addMenu(new LLAdvancedCheckTextureAtlas(), "Advanced.CheckTextureAtlas");  	view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion");  	view_listener_t::addMenu(new LLAdvancedEnableRenderFBO(), "Advanced.EnableRenderFBO");  	view_listener_t::addMenu(new LLAdvancedEnableRenderDeferred(), "Advanced.EnableRenderDeferred"); -	view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredGI(), "Advanced.EnableRenderDeferredGI"); +	view_listener_t::addMenu(new LLAdvancedEnableRenderDeferredOptions(), "Advanced.EnableRenderDeferredOptions");  	view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");  	view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");  	view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); @@ -7898,6 +7935,8 @@ void initialize_menus()  	view_listener_t::addMenu(new LLAdvancedToggleFrameTest(), "Advanced.ToggleFrameTest");  	view_listener_t::addMenu(new LLAdvancedCheckFrameTest(), "Advanced.CheckFrameTest");  	view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles"); +	view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption"); +	view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");  	#ifdef TOGGLE_HACKED_GODLIKE_VIEWER diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index 5836aff4e7..abac3d26bf 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -3606,6 +3606,7 @@ const F32 THRESHOLD_HEAD_ROT_QDOT = 0.9997f;	// ~= 2.5 degrees -- if its less th  const F32 MAX_HEAD_ROT_QDOT = 0.99999f;			// ~= 0.5 degrees -- if its greater than this then no need to update head_rot  												// between these values we delay the updates (but no more than one second) +static LLFastTimer::DeclareTimer FTM_AGENT_UPDATE_SEND("Send Message");  void send_agent_update(BOOL force_send, BOOL send_reliable)  { @@ -3764,6 +3765,7 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)  	if (duplicate_count < DUP_MSGS && !gDisconnected)  	{ +		LLFastTimer t(FTM_AGENT_UPDATE_SEND);  		// Build the message  		msg->newMessageFast(_PREHASH_AgentUpdate);  		msg->nextBlockFast(_PREHASH_AgentData); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 86b1a8c910..0e29851778 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -317,10 +317,16 @@ S32 LLViewerShaderMgr::getVertexShaderLevel(S32 type)  void LLViewerShaderMgr::setShaders()  { -	if (!gPipeline.mInitialized || !sInitialized) +	//setShaders might be called redundantly by gSavedSettings, so return on reentrance +	static bool reentrance = false; +	 +	if (!gPipeline.mInitialized || !sInitialized || reentrance)  	{  		return;  	} + +	reentrance = true; +  	// Make sure the compiled shader map is cleared before we recompile shaders.  	mShaderObjects.clear(); @@ -368,17 +374,11 @@ void LLViewerShaderMgr::setShaders()  		S32 wl_class = 2;  		S32 water_class = 2;  		S32 deferred_class = 0; -		if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") -			  && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) -		{ -			// user has disabled WindLight in their settings, downgrade -			// windlight shaders to stub versions. -			wl_class = 1; -		} - -		if (LLPipeline::sRenderDeferred) +		 +		if (LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +		    gSavedSettings.getBOOL("RenderDeferred"))  		{ -			if (gSavedSettings.getBOOL("RenderDeferredShadow")) +			if (gSavedSettings.getS32("RenderShadowDetail") > 0)  			{  				if (gSavedSettings.getBOOL("RenderDeferredGI"))  				{ //shadows + gi @@ -393,6 +393,24 @@ void LLViewerShaderMgr::setShaders()  			{ //no shadows  				deferred_class = 1;  			} + +			//make sure framebuffer objects are enabled +			gSavedSettings.setBOOL("RenderUseFBO", TRUE); + +			//make sure hardware skinning is enabled +			gSavedSettings.setBOOL("RenderAvatarVP", TRUE); +			 +			//make sure atmospheric shaders are enabled +			gSavedSettings.setBOOL("WindLightUseAtmosShaders", TRUE); +		} + + +		if (!(LLFeatureManager::getInstance()->isFeatureAvailable("WindLightUseAtmosShaders") +			  && gSavedSettings.getBOOL("WindLightUseAtmosShaders"))) +		{ +			// user has disabled WindLight in their settings, downgrade +			// windlight shaders to stub versions. +			wl_class = 1;  		}  		if(!gSavedSettings.getBOOL("EnableRippleWater")) @@ -517,6 +535,8 @@ void LLViewerShaderMgr::setShaders()  		gViewerWindow->setCursor(UI_CURSOR_ARROW);  	}  	gPipeline.createGLBuffers(); + +	reentrance = false;  }  void LLViewerShaderMgr::unloadShaders() @@ -973,10 +993,21 @@ BOOL LLViewerShaderMgr::loadShadersDeferred()  	if (success)  	{ +		std::string fragment; + +		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +		{ +			fragment = "deferred/sunLightSSAOF.glsl"; +		} +		else +		{ +			fragment = "deferred/sunLightF.glsl"; +		} +  		gDeferredSunProgram.mName = "Deferred Sun Shader";  		gDeferredSunProgram.mShaderFiles.clear();  		gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightV.glsl", GL_VERTEX_SHADER_ARB)); -		gDeferredSunProgram.mShaderFiles.push_back(make_pair("deferred/sunLightF.glsl", GL_FRAGMENT_SHADER_ARB)); +		gDeferredSunProgram.mShaderFiles.push_back(make_pair(fragment, GL_FRAGMENT_SHADER_ARB));  		gDeferredSunProgram.mShaderLevel = mVertexShaderLevel[SHADER_DEFERRED];  		success = gDeferredSunProgram.createShader(NULL, NULL);  	} diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp index bdc34d0f18..6ada122662 100644 --- a/indra/newview/llviewerstats.cpp +++ b/indra/newview/llviewerstats.cpp @@ -592,7 +592,7 @@ void update_statistics(U32 frame_count)  		}  	}  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable")); -	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gSavedSettings.getS32("RenderLightingDetail")); +	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));  	LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));  #if 0 // 1.9.2 diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index d91f232f0e..38d9c31663 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -1376,7 +1376,7 @@ LLViewerWindow::LLViewerWindow(  		gSavedSettings.getBOOL("DisableVerticalSync"),  		!gNoRender,  		ignore_pixel_depth, -		gSavedSettings.getU32("RenderFSAASamples")); +		0); //gSavedSettings.getU32("RenderFSAASamples"));  	if (!LLAppViewer::instance()->restoreErrorTrap())  	{ @@ -3845,140 +3845,6 @@ void LLViewerWindow::playSnapshotAnimAndSound()  BOOL LLViewerWindow::thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type)  {  	return rawSnapshot(raw, preview_width, preview_height, FALSE, FALSE, show_ui, do_rebuild, type); -	 -	// *TODO below code was broken in deferred pipeline -	/* -	if ((!raw) || preview_width < 10 || preview_height < 10) -	{ -		return FALSE; -	} - -	if(gResizeScreenTexture) //the window is resizing -	{ -		return FALSE ; -	} - -	setCursor(UI_CURSOR_WAIT); - -	// Hide all the UI widgets first and draw a frame -	BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); - -	if ( prev_draw_ui != show_ui) -	{ -		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); -	} - -	BOOL hide_hud = !gSavedSettings.getBOOL("RenderHUDInSnapshot") && LLPipeline::sShowHUDAttachments; -	if (hide_hud) -	{ -		LLPipeline::sShowHUDAttachments = FALSE; -	} - -	S32 render_name = gSavedSettings.getS32("RenderName"); -	gSavedSettings.setS32("RenderName", 0); -	LLVOAvatar::updateFreezeCounter(1) ; //pause avatar updating for one frame -	 -	S32 w = preview_width ; -	S32 h = preview_height ; -	LLVector2 display_scale = mDisplayScale ; -	mDisplayScale.setVec((F32)w / mWindowRectRaw.getWidth(), (F32)h / mWindowRectRaw.getHeight()) ; -	LLRect window_rect = mWindowRectRaw; -	mWindowRectRaw.set(0, h, w, 0); -	 -	gDisplaySwapBuffers = FALSE; -	gDepthDirty = TRUE; -	glClearColor(0.f, 0.f, 0.f, 0.f); -	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); -	setup3DRender(); - -	LLFontGL::setFontDisplay(FALSE) ; -	LLHUDText::setDisplayText(FALSE) ; -	if (type == SNAPSHOT_TYPE_OBJECT_ID) -	{ -		gObjectList.renderPickList(gViewerWindow->getWindowRectScaled(), FALSE, FALSE); -	} -	else -	{ -		display(do_rebuild, 1.0f, 0, TRUE); -		render_ui(); -	} - -	S32 glformat, gltype, glpixel_length ; -	if(SNAPSHOT_TYPE_DEPTH == type) -	{ -		glpixel_length = 4 ; -		glformat = GL_DEPTH_COMPONENT ;  -		gltype = GL_FLOAT ; -	} -	else -	{ -		glpixel_length = 3 ; -		glformat = GL_RGB ; -		gltype = GL_UNSIGNED_BYTE ; -	} - -	raw->resize(w, h, glpixel_length); -	glReadPixels(0, 0, w, h, glformat, gltype, raw->getData()); - -	if(SNAPSHOT_TYPE_DEPTH == type) -	{ -		LLViewerCamera* camerap = LLViewerCamera::getInstance(); -		F32 depth_conversion_factor_1 = (camerap->getFar() + camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); -		F32 depth_conversion_factor_2 = (camerap->getFar() - camerap->getNear()) / (2.f * camerap->getFar() * camerap->getNear()); - -		//calculate the depth  -		for (S32 y = 0 ; y < h ; y++) -		{ -			for(S32 x = 0 ; x < w ; x++) -			{ -				S32 i = (w * y + x) << 2 ; -				 -				F32 depth_float_i = *(F32*)(raw->getData() + i); -				 -				F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float_i * depth_conversion_factor_2)); -				U8 depth_byte = F32_to_U8(linear_depth_float, camerap->getNear(), camerap->getFar()); -				*(raw->getData() + i + 0) = depth_byte; -				*(raw->getData() + i + 1) = depth_byte; -				*(raw->getData() + i + 2) = depth_byte; -				*(raw->getData() + i + 3) = 255; -			} -		}		 -	} - -	LLFontGL::setFontDisplay(TRUE) ; -	LLHUDText::setDisplayText(TRUE) ; -	mDisplayScale.setVec(display_scale) ; -	mWindowRectRaw = window_rect;	 -	setup3DRender(); -	gDisplaySwapBuffers = FALSE; -	gDepthDirty = TRUE; - -	// POST SNAPSHOT -	if (!gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) -	{ -		LLPipeline::toggleRenderDebugFeature((void*)LLPipeline::RENDER_DEBUG_FEATURE_UI); -	} - -	if (hide_hud) -	{ -		LLPipeline::sShowHUDAttachments = TRUE; -	} - -	setCursor(UI_CURSOR_ARROW); - -	if (do_rebuild) -	{ -		// If we had to do a rebuild, that means that the lists of drawables to be rendered -		// was empty before we started. -		// Need to reset these, otherwise we call state sort on it again when render gets called the next time -		// and we stand a good chance of crashing on rebuild because the render drawable arrays have multiple copies of -		// objects on them. -		gPipeline.resetDrawOrders(); -	} -	 -	gSavedSettings.setS32("RenderName", render_name);	 -	 -	return TRUE;*/  }  // Saves the image from the screen to the specified filename and path. @@ -4738,8 +4604,9 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  		return TRUE;  	} -	U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); -	U32 old_fsaa = mWindow->getFSAASamples(); +	//U32 fsaa = gSavedSettings.getU32("RenderFSAASamples"); +	//U32 old_fsaa = mWindow->getFSAASamples(); +  	// going from windowed to windowed  	if (!old_fullscreen && !fullscreen)  	{ @@ -4749,7 +4616,7 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  			mWindow->setSize(size);  		} -		if (fsaa == old_fsaa) +		//if (fsaa == old_fsaa)  		{  			return TRUE;  		} @@ -4778,13 +4645,13 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,  		gSavedSettings.setS32("WindowY", old_pos.mY);  	} -	mWindow->setFSAASamples(fsaa); +	//mWindow->setFSAASamples(fsaa);  	result_first_try = mWindow->switchContext(fullscreen, size, disable_vsync);  	if (!result_first_try)  	{  		// try to switch back -		mWindow->setFSAASamples(old_fsaa); +		//mWindow->setFSAASamples(old_fsaa);  		result_second_try = mWindow->switchContext(old_fullscreen, old_size, disable_vsync);  		if (!result_second_try) diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 7a232afba6..14267d10ff 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -700,10 +700,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  		mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);  	} -	mDirtyMesh = TRUE;	// Dirty geometry, need to regenerate. +	mDirtyMesh = 2;	// Dirty geometry, need to regenerate.  	mMeshTexturesDirty = FALSE; -	mShadow0Facep = NULL; -	mShadow1Facep = NULL;  	mHeadp = NULL;  	mIsBuilt = FALSE; @@ -739,12 +737,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,  	mRippleTimeLast = 0.f; -	mShadowImagep = LLViewerTextureManager::getFetchedTextureFromFile("foot_shadow.j2c"); -	 -	// GL NOT ACTIVE HERE -	//gGL.getTexUnit(0)->bind(mShadowImagep.get()); -	//mShadowImagep->setAddressMode(LLTexUnit::TAM_CLAMP); -	  	mInAir = FALSE;  	mStepOnLand = TRUE; @@ -1971,7 +1963,7 @@ void LLVOAvatar::updateMeshData()  			}  			if(num_vertices < 1)//skip empty meshes  			{ -				break ; +				continue ;  			}  			if(last_v_num > 0)//put the last inserted part into next vertex buffer.  			{ @@ -1993,6 +1985,8 @@ void LLVOAvatar::updateMeshData()  			// resize immediately  			facep->setSize(num_vertices, num_indices); +			bool terse_update = false; +  			if(facep->mVertexBuffer.isNull())  			{  				facep->mVertexBuffer = new LLVertexBufferAvatar(); @@ -2000,7 +1994,15 @@ void LLVOAvatar::updateMeshData()  			}  			else  			{ -				facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; +				if (facep->mVertexBuffer->getRequestedIndices() == num_indices && +					facep->mVertexBuffer->getRequestedVerts() == num_vertices) +				{ +					terse_update = true; +				} +				else +				{ +					facep->mVertexBuffer->resizeBuffer(num_vertices, num_indices) ; +				}  			}  			facep->setGeomIndex(0); @@ -2015,7 +2017,7 @@ void LLVOAvatar::updateMeshData()  			for(S32 k = j ; k < part_index ; k++)  			{ -				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR); +				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update);  			}  			stop_glerror(); @@ -2411,12 +2413,6 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)  	LLJoint::sNumUpdates = 0;  	LLJoint::sNumTouches = 0; -	// *NOTE: this is necessary for the floating name text above your head. -	if (mDrawable.notNull()) -	{ -		gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_SHADOW, TRUE); -	} -  	BOOL visible = isVisible() || mNeedsAnimUpdate;  	// update attachments positions @@ -3767,12 +3763,19 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)  		return num_indices;  	} -	if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) +	LLFace* face = mDrawable->getFace(0); + +	bool needs_rebuild = !face || face->mVertexBuffer.isNull() || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY); + +	if (needs_rebuild || mDirtyMesh)  	{	//LOD changed or new mesh created, allocate new vertex buffer if needed -		updateMeshData(); -		mDirtyMesh = FALSE; -		mNeedsSkin = TRUE; -		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); +		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4) +		{ +			updateMeshData(); +			mDirtyMesh = 0; +			mNeedsSkin = TRUE; +			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY); +		}  	}  	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0) @@ -4020,54 +4023,6 @@ U32 LLVOAvatar::renderRigid()  	return num_indices;  } -U32 LLVOAvatar::renderFootShadows() -{ -	U32 num_indices = 0; - -	if (!mIsBuilt) -	{ -		return 0; -	} - -	if (isSelf() && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead())) -	{ -		return 0; -	} -	 -	if (!mIsBuilt) -	{ -		return 0; -	} -	 -	// Don't render foot shadows if your lower body is completely invisible. -	// (non-humanoid avatars rule!) -	if (!isTextureVisible(TEX_LOWER_BAKED)) -	{ -		return 0; -	} - -	// Update the shadow, tractor, and text label geometry. -	if (mDrawable->isState(LLDrawable::REBUILD_SHADOW) && !isImpostor()) -	{ -		updateShadowFaces(); -		mDrawable->clearState(LLDrawable::REBUILD_SHADOW); -	} - -	U32 foot_mask = LLVertexBuffer::MAP_VERTEX | -					LLVertexBuffer::MAP_TEXCOORD0; - -	LLGLDepthTest test(GL_TRUE, GL_FALSE); -	//render foot shadows -	LLGLEnable blend(GL_BLEND); -	gGL.getTexUnit(0)->bind(mShadowImagep, TRUE); -	glColor4fv(mShadow0Facep->getRenderColor().mV); -	mShadow0Facep->renderIndexed(foot_mask); -	glColor4fv(mShadow1Facep->getRenderColor().mV); -	mShadow1Facep->renderIndexed(foot_mask); -	 -	return num_indices; -} -  U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)  {  	if (!mImpostor.isComplete()) @@ -4188,11 +4143,6 @@ void LLVOAvatar::updateTextures()  	{  		setDebugText(llformat("%4.0f:%4.0f", fsqrtf(mMinPixelArea),fsqrtf(mMaxPixelArea)));  	}	 -	 -	if( render_avatar ) -	{ -		mShadowImagep->addTextureStats(mPixelArea); -	}  } @@ -5383,7 +5333,7 @@ BOOL LLVOAvatar::updateJointLODs()   		if (res)  		{  			sNumLODChangesThisFrame++; -			dirtyMesh(); +			dirtyMesh(2);  			return TRUE;  		}  	} @@ -5407,18 +5357,9 @@ LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline)  	mDrawable->addFace(poolp, NULL);  	mDrawable->setRenderType(LLPipeline::RENDER_TYPE_AVATAR); -	LLFace *facep; - -	// Add faces for the foot shadows -	facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); -	mShadow0Facep = facep; - -	facep = mDrawable->addFace((LLFacePool*) NULL, mShadowImagep); -	mShadow1Facep = facep; -  	mNumInitFaces = mDrawable->getNumFaces() ; -	dirtyMesh(); +	dirtyMesh(2);  	return mDrawable;  } @@ -5458,107 +5399,6 @@ BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable)  }  //----------------------------------------------------------------------------- -// updateShadowFaces() -//----------------------------------------------------------------------------- -void LLVOAvatar::updateShadowFaces() -{ -	LLFace *face0p = mShadow0Facep; -	LLFace *face1p = mShadow1Facep; - -	// -	// render avatar shadows -	// -	if (mInAir || mUpdatePeriod >= IMPOSTOR_PERIOD) -	{ -		face0p->setSize(0, 0); -		face1p->setSize(0, 0); -		return; -	} - -	LLSprite sprite(mShadowImagep.notNull() ? mShadowImagep->getID() : LLUUID::null); -	sprite.setFollow(FALSE); -	const F32 cos_angle = gSky.getSunDirection().mV[2]; -	F32 cos_elev = sqrt(1 - cos_angle * cos_angle); -	if (cos_angle < 0) cos_elev = -cos_elev; -	sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); -	LLVector3 sun_vec = gSky.mVOSkyp ? gSky.mVOSkyp->getToSun() : LLVector3(0.f, 0.f, 0.f); - -	if (mShadowImagep->hasGLTexture()) -	{ -		LLVector3 normal; -		LLVector3d shadow_pos; -		LLVector3 shadow_pos_agent; -		F32 foot_height; - -		if (mFootLeftp) -		{ -			LLVector3 joint_world_pos = mFootLeftp->getWorldPosition(); -			// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now -			// but we make an explicit ray trace call in expectation of future improvements -			resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),  -									 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); -			shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); -			foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; - -			// Pull sprite in direction of surface normal -			shadow_pos_agent += normal * SHADOW_OFFSET_AMT; - -			// Render sprite -			sprite.setNormal(normal); -			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) -			{ -				sprite.setColor(0.f, 0.f, 0.f, 0.f); -			} -			else -			{ -				sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); -			} -			sprite.setPosition(shadow_pos_agent); - -			LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos; -			//foot_to_knee.normalize(); -			foot_to_knee -= projected_vec(foot_to_knee, sun_vec); -			sprite.setYaw(azimuth(sun_vec - foot_to_knee)); -		 -			sprite.updateFace(*face0p); -		} - -		if (mFootRightp) -		{ -			LLVector3 joint_world_pos = mFootRightp->getWorldPosition(); -			// this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now -			// but we make an explicit ray trace call in expectation of future improvements -			resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos),  -									 gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); -			shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); -			foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; - -			// Pull sprite in direction of surface normal -			shadow_pos_agent += normal * SHADOW_OFFSET_AMT; - -			// Render sprite -			sprite.setNormal(normal); -			if (isSelf() && gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK) -			{ -				sprite.setColor(0.f, 0.f, 0.f, 0.f); -			} -			else -			{ -				sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); -			} -			sprite.setPosition(shadow_pos_agent); - -			LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos; -			//foot_to_knee.normalize(); -			foot_to_knee -= projected_vec(foot_to_knee, sun_vec); -			sprite.setYaw(azimuth(sun_vec - foot_to_knee)); -	 -			sprite.updateFace(*face1p); -		} -	} -} - -//-----------------------------------------------------------------------------  // updateSexDependentLayerSets()  //-----------------------------------------------------------------------------  void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake ) @@ -5573,9 +5413,12 @@ void LLVOAvatar::updateSexDependentLayerSets( BOOL upload_bake )  //-----------------------------------------------------------------------------  void LLVOAvatar::dirtyMesh()  { -	mDirtyMesh = TRUE; +	dirtyMesh(1); +} +void LLVOAvatar::dirtyMesh(S32 priority) +{ +	mDirtyMesh = llmax(mDirtyMesh, priority);  } -  //-----------------------------------------------------------------------------  // hideSkirt()  //----------------------------------------------------------------------------- @@ -7770,18 +7613,15 @@ BOOL LLVOAvatar::updateLOD()  	BOOL res = updateJointLODs();  	LLFace* facep = mDrawable->getFace(0); -	if (facep->mVertexBuffer.isNull() || -		(LLVertexBuffer::sEnableVBOs && -		((facep->mVertexBuffer->getUsage() == GL_STATIC_DRAW ? TRUE : FALSE) != -		 (facep->getPool()->getVertexShaderLevel() > 0 ? TRUE : FALSE)))) +	if (facep->mVertexBuffer.isNull())  	{ -		mDirtyMesh = TRUE; +		dirtyMesh(2);  	} -	if (mDirtyMesh || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY)) +	if (mDirtyMesh >= 2 || mDrawable->isState(LLDrawable::REBUILD_GEOMETRY))  	{	//LOD changed or new mesh created, allocate new vertex buffer if needed  		updateMeshData(); -		mDirtyMesh = FALSE; +		mDirtyMesh = 0;  		mNeedsSkin = TRUE;  		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);  	} diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 3c940e03c0..fdda3bdd37 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -339,7 +339,6 @@ private:   **/  public: -	U32 		renderFootShadows();  	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);  	U32 		renderRigid();  	U32 		renderSkinned(EAvatarRenderPass pass); @@ -575,7 +574,8 @@ protected:  	void 			releaseMeshData();  	virtual void restoreMeshData();  private: -	BOOL 			mDirtyMesh; +	void 			dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority +	S32 			mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD  	BOOL			mMeshTexturesDirty;  	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d6453111d7..d9f5017a31 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2456,6 +2456,17 @@ void LLVOVolume::updateSpotLightPriority()  } +bool LLVOVolume::isLightSpotlight() const +{ +	LLLightImageParams* params = (LLLightImageParams*) getParameterEntry(LLNetworkData::PARAMS_LIGHT_IMAGE); +	if (params) +	{ +		return params->isLightSpotlight(); +	} +	return false; +} + +  LLViewerTexture* LLVOVolume::getLightTexture()  {  	LLUUID id = getLightTextureID(); @@ -2915,9 +2926,7 @@ F32 LLVOVolume::getBinRadius()  		{  			LLFace* face = mDrawable->getFace(i);  			if (face->getPoolType() == LLDrawPool::POOL_ALPHA && -				(!LLPipeline::sFastAlpha ||  -				face->getFaceColor().mV[3] != 1.f || -				!face->getTexture()->getIsAlphaMask())) +			    !face->canRenderAsMask())  			{  				alpha_wrap = TRUE;  				break; @@ -3193,11 +3202,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  	S32 idx = draw_vec.size()-1; -  	BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || -					  (type == LLRenderPass::PASS_INVISIBLE) || -					  (type == LLRenderPass::PASS_ALPHA ? facep->isState(LLFace::FULLBRIGHT) : FALSE); - +		(type == LLRenderPass::PASS_INVISIBLE) || +		(type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)); +	  	if (!fullbright && type != LLRenderPass::PASS_GLOW && !facep->mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_NORMAL))  	{  		llwarns << "Non fullbright face has no normals!" << llendl; @@ -3222,16 +3230,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,  		model_mat = &(drawable->getRegion()->mRenderMatrix);  	} -	U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); + +	U8 bump = (type == LLRenderPass::PASS_BUMP || type == LLRenderPass::PASS_POST_BUMP) ? facep->getTextureEntry()->getBumpmap() : 0;  	LLViewerTexture* tex = facep->getTexture(); -	U8 glow = 0; -		 -	if (type == LLRenderPass::PASS_GLOW) -	{ -		glow = (U8) (facep->getTextureEntry()->getGlow() * 255); -	} +	U8 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);  	if (facep->mVertexBuffer.isNull())  	{ @@ -3296,6 +3300,7 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)  static LLFastTimer::DeclareTimer FTM_REBUILD_VOLUME_VB("Volume");  static LLFastTimer::DeclareTimer FTM_REBUILD_VBO("VBO Rebuilt"); +  void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  {  	if (group->changeLOD()) @@ -3421,10 +3426,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  				if (type == LLDrawPool::POOL_ALPHA)  				{ -					if (LLPipeline::sFastAlpha && -					    (te->getColor().mV[VW] == 1.0f) && -					    (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid -					    facep->getTexture()->getIsAlphaMask()) +					if (facep->canRenderAsMask())  					{ //can be treated as alpha mask  						simple_faces.push_back(facep);  					} @@ -3526,6 +3528,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)  }  static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM("Volume Geometry"); +static LLFastTimer::DeclareTimer FTM_VOLUME_GEOM_PARTIAL("Terse Rebuild"); +  void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  {  	llassert(group); @@ -3538,6 +3542,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)  		for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)  		{ +			LLFastTimer t(FTM_VOLUME_GEOM_PARTIAL);  			LLDrawable* drawablep = *drawable_iter;  			if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) ) @@ -3765,15 +3770,12 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  			const LLTextureEntry* te = facep->getTextureEntry(); -			BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; +			BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE;  			if (is_alpha)  			{  				// can we safely treat this as an alpha mask? -				if (LLPipeline::sFastAlpha && -				    (te->getColor().mV[VW] == 1.0f) && -				    (!te->getFullbright()) && // hack: alpha masking renders fullbright faces invisible, need to figure out why - for now, avoid -				    facep->getTexture()->getIsAlphaMask()) +				if (facep->canRenderAsMask())  				{  					if (te->getFullbright())  					{ @@ -3798,66 +3800,76 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				&& group->mSpatialPartition->mPartitionType != LLViewerRegion::PARTITION_HUD   				&& LLPipeline::sRenderBump   				&& te->getShiny()) -			{ +			{ //shiny  				if (tex->getPrimaryFormat() == GL_ALPHA) -				{ +				{ //invisiprim+shiny  					registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);  					registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);  				}  				else if (LLPipeline::sRenderDeferred) -				{ -					if (te->getBumpmap()) -					{ -						registerFace(group, facep, LLRenderPass::PASS_BUMP); -					} -					else if (te->getFullbright()) -					{ +				{ //deferred rendering +					if (te->getFullbright()) +					{ //register in post deferred fullbright shiny pass  						registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY); +						if (te->getBumpmap()) +						{ //register in post deferred bump pass +							registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); +						} +					} +					else if (te->getBumpmap()) +					{ //register in deferred bump pass +						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else -					{ +					{ //register in deferred simple pass (deferred simple includes shiny)  						llassert(mask & LLVertexBuffer::MAP_NORMAL);  						registerFace(group, facep, LLRenderPass::PASS_SIMPLE);  					}  				}  				else if (fullbright) -				{						 +				{	//not deferred, register in standard fullbright shiny pass					  					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);  				}  				else -				{ +				{ //not deferred or fullbright, register in standard shiny pass  					registerFace(group, facep, LLRenderPass::PASS_SHINY);  				}  			}  			else -			{ +			{ //not alpha and not shiny  				if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) -				{ +				{ //invisiprim  					registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);  				}  				else if (fullbright) -				{ +				{ //fullbright  					registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); +					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) +					{ //if this is the deferred render and a bump map is present, register in post deferred bump +						registerFace(group, facep, LLRenderPass::PASS_POST_BUMP); +					}  				}  				else  				{ -					if (LLPipeline::sRenderDeferred && te->getBumpmap()) -					{ +					if (LLPipeline::sRenderDeferred && LLPipeline::sRenderBump && te->getBumpmap()) +					{ //non-shiny or fullbright deferred bump  						registerFace(group, facep, LLRenderPass::PASS_BUMP);  					}  					else -					{ +					{ //all around simple  						llassert(mask & LLVertexBuffer::MAP_NORMAL);  						registerFace(group, facep, LLRenderPass::PASS_SIMPLE);  					}  				} +				//not sure why this is here -- shiny HUD attachments maybe?  -- davep 5/11/2010  				if (!is_alpha && te->getShiny() && LLPipeline::sRenderBump)  				{  					registerFace(group, facep, LLRenderPass::PASS_SHINY);  				}  			} +			//not sure why this is here, and looks like it might cause bump mapped objects to get rendered redundantly -- davep 5/11/2010  			if (!is_alpha && !LLPipeline::sRenderDeferred)  			{  				llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright); @@ -3869,7 +3881,7 @@ void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::  				}  			} -			if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) +			if (!is_alpha && LLPipeline::sRenderGlow && te->getGlow() > 0.f)  			{  				registerFace(group, facep, LLRenderPass::PASS_GLOW);  			} diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index a8bb597f93..fbae011ffc 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -215,6 +215,7 @@ public:  	LLColor3 getLightBaseColor() const; // not scaled by intensity  	LLColor3 getLightColor() const; // scaled by intensity  	LLUUID	getLightTextureID() const; +	bool isLightSpotlight() const;  	LLVector3 getSpotLightParams() const;  	void	updateSpotLightPriority();  	F32		getSpotLightPriority() const; diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp index f30567f481..a1e4df8a66 100644 --- a/indra/newview/llworld.cpp +++ b/indra/newview/llworld.cpp @@ -1055,9 +1055,11 @@ void LLWorld::disconnectRegions()  	}  } +static LLFastTimer::DeclareTimer FTM_ENABLE_SIMULATOR("Enable Sim");  void process_enable_simulator(LLMessageSystem *msg, void **user_data)  { +	LLFastTimer t(FTM_ENABLE_SIMULATOR);  	// enable the appropriate circuit for this simulator and   	// add its values into the gSimulator structure  	U64		handle; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cc65b34a61..e4b565b26b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -191,6 +191,7 @@ std::string gPoolNames[] =  };  void drawBox(const LLVector3& c, const LLVector3& r); +void drawBoxOutline(const LLVector3& pos, const LLVector3& size);  U32 nhpo2(U32 v)   { @@ -268,7 +269,8 @@ BOOL	LLPipeline::sRenderHighlight = TRUE;  BOOL	LLPipeline::sForceOldBakedUpload = FALSE;  S32		LLPipeline::sUseOcclusion = 0;  BOOL	LLPipeline::sDelayVBUpdate = TRUE; -BOOL	LLPipeline::sFastAlpha = TRUE; +BOOL	LLPipeline::sAutoMaskAlphaDeferred = TRUE; +BOOL	LLPipeline::sAutoMaskAlphaNonDeferred = FALSE;  BOOL	LLPipeline::sDisableShaders = FALSE;  BOOL	LLPipeline::sRenderBump = TRUE;  BOOL	LLPipeline::sUseTriStrips = TRUE; @@ -328,7 +330,6 @@ LLPipeline::LLPipeline() :  	mInitialized(FALSE),  	mVertexShadersEnabled(FALSE),  	mVertexShadersLoaded(0), -	mRenderTypeMask(0),  	mRenderDebugFeatureMask(0),  	mRenderDebugMask(0),  	mOldRenderDebugMask(0), @@ -362,6 +363,7 @@ void LLPipeline::init()  	sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD");  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); +	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");  	sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -381,7 +383,11 @@ void LLPipeline::init()  	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();  	resetFrameStats(); -	mRenderTypeMask = 0xffffffff;	// All render types start on +	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) +	{ +		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled +	} +  	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on  	mRenderDebugMask = 0;	// All debug starts off @@ -408,6 +414,8 @@ void LLPipeline::init()  	{  		mSpotLightFade[i] = 1.f;  	} + +	setLightingDetail(-1);  }  LLPipeline::~LLPipeline() @@ -510,6 +518,7 @@ void LLPipeline::destroyGL()  }  static LLFastTimer::DeclareTimer FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture"); +  void LLPipeline::resizeScreenTexture()  {  	LLFastTimer ft(FTM_RESIZE_SCREEN_TEXTURE); @@ -566,9 +575,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); +		//HACK: make alpha masking work on ATI depth shadows (work around for ATI driver bug) +		U32 shadow_fmt = gGLManager.mIsATI ? GL_ALPHA : 0; +  		for (U32 i = 0; i < 4; i++)  		{ -			mShadow[i].allocate(U32(resX*scale),U32(resY*scale), 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE);  		} @@ -577,11 +589,9 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		for (U32 i = 4; i < 6; i++)  		{ -			mShadow[i].allocate(width, height, 0, TRUE, FALSE); +			mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE);  		} - -  		width = nhpo2(resX)/2;  		height = nhpo2(resY)/2;  		mLuminanceMap.allocate(width,height, GL_RGBA, FALSE, FALSE); @@ -625,10 +635,12 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  void LLPipeline::updateRenderDeferred()  {  	BOOL deferred = (gSavedSettings.getBOOL("RenderDeferred") &&  -		LLRenderTarget::sUseFBO && -		gSavedSettings.getBOOL("VertexShaderEnable") &&  -		gSavedSettings.getBOOL("RenderAvatarVP") && -		gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE; +			 LLRenderTarget::sUseFBO && +			 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") && +			 gSavedSettings.getBOOL("VertexShaderEnable") &&  +			 gSavedSettings.getBOOL("RenderAvatarVP") && +			 (gSavedSettings.getBOOL("WindLightUseAtmosShaders")) ? TRUE : FALSE) && +		!gUseWireframe;  	sRenderDeferred = deferred;			  } @@ -903,13 +915,18 @@ S32 LLPipeline::setLightingDetail(S32 level)  	if (level < 0)  	{ -		level = gSavedSettings.getS32("RenderLightingDetail"); +		if (gSavedSettings.getBOOL("VertexShaderEnable")) +		{ +			level = 1; +		} +		else +		{ +			level = 0; +		}  	}  	level = llclamp(level, 0, getMaxLightingDetail());  	if (level != mLightingDetail)  	{ -		gSavedSettings.setS32("RenderLightingDetail", level); -		  		mLightingDetail = level;  		if (mVertexShadersLoaded == 1) @@ -1513,8 +1530,10 @@ BOOL LLPipeline::visibleObjectsInFrustum(LLCamera& camera)  BOOL LLPipeline::getVisibleExtents(LLCamera& camera, LLVector3& min, LLVector3& max)  { -	min = LLVector3(F32_MAX, F32_MAX, F32_MAX); -	max = LLVector3(-F32_MAX, -F32_MAX, -F32_MAX); +	const F32 X = 65536.f; + +	min = LLVector3(X,X,X); +	max = LLVector3(-X,-X,-X);  	U32 saved_camera_id = LLViewerCamera::sCurCameraID;  	LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; @@ -1953,31 +1972,40 @@ void LLPipeline::updateGeom(F32 max_dtime)  void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)  {  	LLMemType mt(LLMemType::MTYPE_PIPELINE_MARK_VISIBLE); -	if(!drawablep || drawablep->isDead()) -	{ -		return; -	} -	 -	if (drawablep->isSpatialBridge()) -	{ -		LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; -		if (root && root->getParent() && root->getVObj() && root->getVObj()->isAttachment()) +	if(drawablep && !drawablep->isDead()) +	{ +		if (drawablep->isSpatialBridge())  		{ -			LLVOAvatar* av = root->getParent()->getVObj()->asAvatar(); -			if (av && av->isImpostor()) +			const LLDrawable* root = ((LLSpatialBridge*) drawablep)->mDrawable; +			llassert(root); // trying to catch a bad assumption +			if (root && //  // this test may not be needed, see above +			    root->getVObj()->isAttachment())  			{ -				return; +				LLDrawable* rootparent = root->getParent(); +				if (rootparent) // this IS sometimes NULL +				{ +					LLViewerObject *vobj = rootparent->getVObj(); +					llassert(vobj); // trying to catch a bad assumption +					if (vobj) // this test may not be needed, see above +					{ +						const LLVOAvatar* av = vobj->asAvatar(); +						if (av && av->isImpostor()) +						{ +							return; +						} +					} +				}  			} +			sCull->pushBridge((LLSpatialBridge*) drawablep); +		} +		else +		{ +			sCull->pushDrawable(drawablep);  		} -		sCull->pushBridge((LLSpatialBridge*) drawablep); -	} -	else -	{ -		sCull->pushDrawable(drawablep); -	} -	drawablep->setVisible(camera); +		drawablep->setVisible(camera); +	}  }  void LLPipeline::markMoved(LLDrawable *drawablep, BOOL damped_motion) @@ -2187,14 +2215,13 @@ static LLFastTimer::DeclareTimer FTM_RESET_DRAWORDER("Reset Draw Order");  void LLPipeline::stateSort(LLCamera& camera, LLCullResult &result)  { -	const U32 face_mask = (1 << LLPipeline::RENDER_TYPE_AVATAR) | -						  (1 << LLPipeline::RENDER_TYPE_GROUND) | -						  (1 << LLPipeline::RENDER_TYPE_TERRAIN) | -						  (1 << LLPipeline::RENDER_TYPE_TREE) | -						  (1 << LLPipeline::RENDER_TYPE_SKY) | -						  (1 << LLPipeline::RENDER_TYPE_WATER); - -	if (mRenderTypeMask & face_mask) +	if (hasAnyRenderType(LLPipeline::RENDER_TYPE_AVATAR, +					  LLPipeline::RENDER_TYPE_GROUND, +					  LLPipeline::RENDER_TYPE_TERRAIN, +					  LLPipeline::RENDER_TYPE_TREE, +					  LLPipeline::RENDER_TYPE_SKY, +					  LLPipeline::RENDER_TYPE_WATER, +					  LLPipeline::END_RENDER_TYPES))  	{  		//clear faces from face pools  		LLFastTimer t(FTM_RESET_DRAWORDER); @@ -3417,26 +3444,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera)  	gGLLastMatrix = NULL;  	glLoadMatrixd(gGLModelView); -	renderHighlights(); -	mHighlightFaces.clear(); - -	renderDebug(); - -	LLVertexBuffer::unbind(); - -	if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) -	{ -		// Render debugging beacons. -		gObjectList.renderObjectBeacons(); -		gObjectList.resetObjectBeacons(); -	} -  	if (occlude)  	{  		occlude = FALSE;  		gGLLastMatrix = NULL;  		glLoadMatrixd(gGLModelView);  		doOcclusion(camera); +		gGLLastMatrix = NULL; +		glLoadMatrixd(gGLModelView);  	}  } @@ -3599,12 +3614,17 @@ void LLPipeline::renderDebug()  		for (U32 i = 0; i < 8; i++)  		{ +			LLVector3* frust = mShadowCamera[i].mAgentFrustum; +  			if (i > 3) -			{ +			{ //render shadow frusta as volumes +				if (mShadowFrustPoints[i-4].empty()) +				{ +					continue; +				} +  				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); @@ -3632,31 +3652,49 @@ void LLPipeline::renderDebug()  			if (i < 4)  			{ -				gGL.begin(LLRender::LINES); -				 -				F32* c = col+i*4; -				for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) + +				if (i == 0 || !mShadowFrustPoints[i].empty())  				{ -					 -					gGL.color3fv(c); +					//render visible point cloud +					gGL.flush(); +					glPointSize(8.f); +					gGL.begin(LLRender::POINTS); -					for (U32 k = 0; k < mShadowFrustPoints[i].size(); ++k) -					{ -						if (j != k) -						{ -							gGL.vertex3fv(mShadowFrustPoints[i][j].mV); -							gGL.vertex3fv(mShadowFrustPoints[i][k].mV); -						} -					} +					F32* c = col+i*4; +					gGL.color3fv(c); -					if (!mShadowFrustOrigin[i].isExactlyZero()) -					{ +					for (U32 j = 0; j < mShadowFrustPoints[i].size(); ++j) +					{	  						gGL.vertex3fv(mShadowFrustPoints[i][j].mV); -						gGL.color4f(1,1,1,1); -						gGL.vertex3fv(mShadowFrustOrigin[i].mV); +						  					} +					gGL.end(); + +					gGL.flush(); +					glPointSize(1.f); + +					LLVector3* ext = mShadowExtents[i];  +					LLVector3 pos = (ext[0]+ext[1])*0.5f; +					LLVector3 size = (ext[1]-ext[0])*0.5f; +					drawBoxOutline(pos, size); + +					//render camera frustum splits as outlines +					gGL.begin(LLRender::LINES); +					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); +					gGL.end();  				} -				gGL.end(); +  			}  			/*for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();  @@ -4280,7 +4318,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit)  		glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 	 0.0f);  		glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f);  		glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 		 0.0f); -		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 			 180.0f); +		glLightf (GL_LIGHT1, GL_SPOT_CUTOFF,		 180.0f);  	}  	else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini)  	{ @@ -4568,32 +4606,42 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  			LLVector4 light_pos_gl(light_pos, 1.0f);  			F32 light_radius = llmax(light->getLightRadius(), 0.001f); -			F32 atten, quad; -#if 0 //1.9.1 -			if (pool->getVertexShaderLevel() > 0) -			{ -				atten = light_radius; -				quad = llmax(light->getLightFalloff(), 0.0001f); -			} -			else -#endif -			{ -				F32 x = (3.f * (1.f + light->getLightFalloff())); -				atten = x / (light_radius); // % of brightness at radius -				quad = 0.0f; -			} +			F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic?  probably trying to match a historic behavior. +			float linatten = x / (light_radius); // % of brightness at radius +  			mHWLightColors[cur_light] = light_color;  			S32 gllight = GL_LIGHT0+cur_light;  			glLightfv(gllight, GL_POSITION, light_pos_gl.mV);  			glLightfv(gllight, GL_DIFFUSE,  light_color.mV);  			glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV); -			glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);  			glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f); -			glLightf (gllight, GL_LINEAR_ATTENUATION,     atten); -			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad); -			glLightf (gllight, GL_SPOT_EXPONENT,          0.0f); -			glLightf (gllight, GL_SPOT_CUTOFF,            180.0f); +			glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten); +			glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f); +			if (light->isLightSpotlight() // directional (spot-)light +			    && (LLPipeline::sRenderDeferred || gSavedSettings.getBOOL("RenderSpotLightsInNondeferred"))) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on +			{ +				LLVector3 spotparams = light->getSpotLightParams(); +				LLQuaternion quat = light->getRenderRotation(); +				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction +				at_axis *= quat; +				//llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; +				glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); +				glLightf (gllight, GL_SPOT_EXPONENT,  2.0f); // 2.0 = good old dot product ^ 2 +				glLightf (gllight, GL_SPOT_CUTOFF,    90.0f); // hemisphere +				const float specular[] = {0.f, 0.f, 0.f, 0.f}; +				glLightfv(gllight, GL_SPECULAR, specular); +			} +			else // omnidirectional (point) light +			{ +				glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); +				glLightf (gllight, GL_SPOT_CUTOFF,   180.0f); + +				// we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight +				const float specular[] = {0.f, 0.f, 0.f, 1.f}; +				glLightfv(gllight, GL_SPECULAR, specular); +				//llinfos << "boring light" << llendl; +			}  			cur_light++;  			if (cur_light >= 8)  			{ @@ -4620,13 +4668,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		LLVector4 light_pos_gl(light_pos, 1.0f);  		F32 light_radius = 16.f; -		F32 atten, quad; -		{ -			F32 x = 3.f; -			atten = x / (light_radius); // % of brightness at radius -			quad = 0.0f; -		} +		F32 x = 3.f; +		float linatten = x / (light_radius); // % of brightness at radius +  		mHWLightColors[2] = light_color;  		S32 gllight = GL_LIGHT2;  		glLightfv(gllight, GL_POSITION, light_pos_gl.mV); @@ -4634,8 +4679,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)  		glLightfv(gllight, GL_AMBIENT,  LLColor4::black.mV);  		glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV);  		glLightf (gllight, GL_CONSTANT_ATTENUATION,   0.0f); -		glLightf (gllight, GL_LINEAR_ATTENUATION,     atten); -		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  quad); +		glLightf (gllight, GL_LINEAR_ATTENUATION,     linatten); +		glLightf (gllight, GL_QUADRATIC_ATTENUATION,  0.0f);  		glLightf (gllight, GL_SPOT_EXPONENT,          0.0f);  		glLightf (gllight, GL_SPOT_CUTOFF,            180.0f);  	} @@ -4756,16 +4801,16 @@ void LLPipeline::enableLightsFullbright(const LLColor4& color)  	enableLights(mask);  	glLightModelfv(GL_LIGHT_MODEL_AMBIENT,color.mV); -	if (mLightingDetail >= 2) +	/*if (mLightingDetail >= 2)  	{  		glColor4f(0.f, 0.f, 0.f, 1.f); // no local lighting by default -	} +	}*/  }  void LLPipeline::disableLights()  {  	enableLights(0); // no lighting (full bright) -	glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default +	//glColor4f(1.f, 1.f, 1.f, 1.f); // lighting color = white by default  }  //============================================================================ @@ -4955,8 +5000,7 @@ void LLPipeline::setLight(LLDrawable *drawablep, BOOL is_light)  //static  void LLPipeline::toggleRenderType(U32 type)  { -	U32 bit = (1<<type); -	gPipeline.mRenderTypeMask ^= bit; +	gPipeline.mRenderTypeEnabled[type] = !gPipeline.mRenderTypeEnabled[type];  }  //static @@ -5368,6 +5412,7 @@ void LLPipeline::resetVertexBuffers()  {  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  	sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); +	LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO");  	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();   			iter != LLWorld::getInstance()->getRegionList().end(); ++iter) @@ -5503,6 +5548,7 @@ void LLPipeline::bindScreenToTexture()  }  static LLFastTimer::DeclareTimer FTM_RENDER_BLOOM("Bloom"); +  void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  {  	LLMemType mt_ru(LLMemType::MTYPE_PIPELINE_RENDER_BLOOM); @@ -5825,6 +5871,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  		gGL.getTexUnit(0)->activate();  		gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + +		if (LLRenderTarget::sUseFBO) +		{ //copy depth buffer from mScreen to framebuffer +			LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),  +				0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); +		}  	} @@ -5841,8 +5893,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)  } +static LLFastTimer::DeclareTimer FTM_BIND_DEFERRED("Bind Deferred"); +  void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRenderTarget* gi_source, LLRenderTarget* last_gi_post, U32 noise_map)  { +	LLFastTimer t(FTM_BIND_DEFERRED); +  	if (noise_map == 0xFFFFFFFF)  	{  		noise_map = mNoiseMap; @@ -6180,11 +6236,16 @@ void LLPipeline::bindDeferredShader(LLGLSLShader& shader, U32 light_index, LLRen  								matrix_nondiag, matrix_nondiag, matrix_diag};  	shader.uniformMatrix3fv("ssao_effect_mat", 1, GL_FALSE, ssao_effect_mat); +	F32 shadow_offset_error = 1.f + gSavedSettings.getF32("RenderShadowOffsetError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); +	F32 shadow_bias_error = 1.f + gSavedSettings.getF32("RenderShadowBiasError") * fabsf(LLViewerCamera::getInstance()->getOrigin().mV[2]); +  	shader.uniform2f("screen_res", mDeferredScreen.getWidth(), mDeferredScreen.getHeight());  	shader.uniform1f("near_clip", LLViewerCamera::getInstance()->getNear()*2.f); -	shader.uniform1f("alpha_soften", gSavedSettings.getF32("RenderDeferredAlphaSoften")); -	shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")); -	shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")); +	shader.uniform1f ("shadow_offset", gSavedSettings.getF32("RenderShadowOffset")*shadow_offset_error); +	shader.uniform1f("shadow_bias", gSavedSettings.getF32("RenderShadowBias")*shadow_bias_error); +	shader.uniform1f ("spot_shadow_offset", gSavedSettings.getF32("RenderSpotShadowOffset")); +	shader.uniform1f("spot_shadow_bias", gSavedSettings.getF32("RenderSpotShadowBias"));	 +  	shader.uniform1f("lum_scale", gSavedSettings.getF32("RenderLuminanceScale"));  	shader.uniform1f("sun_lum_scale", gSavedSettings.getF32("RenderSunLuminanceScale"));  	shader.uniform1f("sun_lum_offset", gSavedSettings.getF32("RenderSunLuminanceOffset")); @@ -6278,16 +6339,16 @@ void LLPipeline::renderDeferredLighting()  			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);  		} -		if (gSavedSettings.getBOOL("RenderDeferredShadow")) -		{ -			glPushMatrix(); -			glLoadIdentity(); -			glMatrixMode(GL_PROJECTION); -			glPushMatrix(); -			glLoadIdentity(); +		glPushMatrix(); +		glLoadIdentity(); +		glMatrixMode(GL_PROJECTION); +		glPushMatrix(); +		glLoadIdentity(); -			mDeferredLight[0].bindTarget(); -			if (gSavedSettings.getBOOL("RenderDeferredSun")) +		mDeferredLight[0].bindTarget(); + +		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0) +		{  			{ //paint shadow/SSAO light map (direct lighting lightmap)  				LLFastTimer ftm(FTM_SUN_SHADOW);  				bindDeferredShader(gDeferredSunProgram, 0); @@ -6328,18 +6389,22 @@ void LLPipeline::renderDeferredLighting()  				unbindDeferredShader(gDeferredSunProgram);  			} -			else -			{ -				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); -			} +		} +		else +		{ +			glClearColor(1,1,1,1); +			mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); +			glClearColor(0,0,0,0); +		} -			mDeferredLight[0].flush(); +		mDeferredLight[0].flush(); +		{ //global illumination specific block (still experimental)  			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") && -			    gSavedSettings.getBOOL("RenderDeferredGI")) -			{ +				gSavedSettings.getBOOL("RenderDeferredGI")) +			{   				LLFastTimer ftm(FTM_EDGE_DETECTION); -				//get edge map +				//generate edge map  				LLGLDisable blend(GL_BLEND);  				LLGLDisable test(GL_ALPHA_TEST);  				LLGLDepthTest depth(GL_FALSE); @@ -6436,79 +6501,79 @@ void LLPipeline::renderDeferredLighting()  					unbindDeferredShader(gDeferredPostGIProgram);  				}  			} +		} -			if (gSavedSettings.getBOOL("RenderDeferredBlurLight")) -			{ //soften direct lighting lightmap -				LLFastTimer ftm(FTM_SOFTEN_SHADOW); -				//blur lightmap -				mDeferredLight[1].bindTarget(); +		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) +		{ //soften direct lighting lightmap +			LLFastTimer ftm(FTM_SOFTEN_SHADOW); +			//blur lightmap +			mDeferredLight[1].bindTarget(); -				glClearColor(1,1,1,1); -				mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); -				glClearColor(0,0,0,0); -				 -				bindDeferredShader(gDeferredBlurLightProgram); +			glClearColor(1,1,1,1); +			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); +			glClearColor(0,0,0,0); +			 +			bindDeferredShader(gDeferredBlurLightProgram); -				LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); -				const U32 kern_length = 4; -				F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); -				F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); +			LLVector3 go = gSavedSettings.getVector3("RenderShadowGaussian"); +			const U32 kern_length = 4; +			F32 blur_size = gSavedSettings.getF32("RenderShadowBlurSize"); +			F32 dist_factor = gSavedSettings.getF32("RenderShadowBlurDistFactor"); -				// sample symmetrically with the middle sample falling exactly on 0.0 -				F32 x = 0.f; +			// sample symmetrically with the middle sample falling exactly on 0.0 +			F32 x = 0.f; -				LLVector3 gauss[32]; // xweight, yweight, offset +			LLVector3 gauss[32]; // xweight, yweight, offset -				for (U32 i = 0; i < kern_length; i++) -				{ -					gauss[i].mV[0] = llgaussian(x, go.mV[0]); -					gauss[i].mV[1] = llgaussian(x, go.mV[1]); -					gauss[i].mV[2] = x; -					x += 1.f; -				} +			for (U32 i = 0; i < kern_length; i++) +			{ +				gauss[i].mV[0] = llgaussian(x, go.mV[0]); +				gauss[i].mV[1] = llgaussian(x, go.mV[1]); +				gauss[i].mV[2] = x; +				x += 1.f; +			} -				gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); -				gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); -				gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); -				gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); -				gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); +			gDeferredBlurLightProgram.uniform2f("delta", 1.f, 0.f); +			gDeferredBlurLightProgram.uniform1f("dist_factor", dist_factor); +			gDeferredBlurLightProgram.uniform3fv("kern[0]", kern_length, gauss[0].mV); +			gDeferredBlurLightProgram.uniform3fv("kern", kern_length, gauss[0].mV); +			gDeferredBlurLightProgram.uniform1f("kern_scale", blur_size * (kern_length/2.f - 0.5f)); +		 +			{ +				LLGLDisable blend(GL_BLEND); +				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +				stop_glerror(); +				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +				stop_glerror(); +			} -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -					stop_glerror(); -				} -				 -				mDeferredLight[1].flush(); -				unbindDeferredShader(gDeferredBlurLightProgram); +			mDeferredLight[1].flush(); +			unbindDeferredShader(gDeferredBlurLightProgram); -				bindDeferredShader(gDeferredBlurLightProgram, 1); -				mDeferredLight[0].bindTarget(); +			bindDeferredShader(gDeferredBlurLightProgram, 1); +			mDeferredLight[0].bindTarget(); -				gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); +			gDeferredBlurLightProgram.uniform2f("delta", 0.f, 1.f); -				{ -					LLGLDisable blend(GL_BLEND); -					LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); -					stop_glerror(); -					glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); -					stop_glerror(); -				} -				mDeferredLight[0].flush(); -				unbindDeferredShader(gDeferredBlurLightProgram); +			{ +				LLGLDisable blend(GL_BLEND); +				LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +				stop_glerror(); +				glDrawArrays(GL_TRIANGLE_STRIP, 0, 3); +				stop_glerror();  			} - -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); -			glMatrixMode(GL_MODELVIEW); -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); +			mDeferredLight[0].flush(); +			unbindDeferredShader(gDeferredBlurLightProgram);  		} +		stop_glerror(); +		glPopMatrix(); +		stop_glerror(); +		glMatrixMode(GL_MODELVIEW); +		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); @@ -6516,11 +6581,15 @@ void LLPipeline::renderDeferredLighting()  		if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED) > 2)  		{  			mDeferredLight[1].bindTarget(); -			mDeferredLight[1].clear(GL_COLOR_BUFFER_BIT); +			// clear color buffer here (GI) - zeroing alpha (glow) is important or it will accumulate against sky +			glClearColor(0,0,0,0); +			mScreen.clear(GL_COLOR_BUFFER_BIT);  		}  		else  		{  			mScreen.bindTarget(); +			// clear color buffer here - zeroing alpha (glow) is important or it will accumulate against sky +			glClearColor(0,0,0,0);  			mScreen.clear(GL_COLOR_BUFFER_BIT);  		} @@ -6557,15 +6626,16 @@ void LLPipeline::renderDeferredLighting()  			LLGLDisable stencil(GL_STENCIL_TEST);  			gGL.setSceneBlendType(LLRender::BT_ALPHA); -			U32 render_mask = mRenderTypeMask; -			mRenderTypeMask =	mRenderTypeMask &  -								((1 << LLPipeline::RENDER_TYPE_SKY) | -								(1 << LLPipeline::RENDER_TYPE_CLOUDS) | -								(1 << LLPipeline::RENDER_TYPE_WL_SKY)); +			gPipeline.pushRenderTypeMask(); +			 +			gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +										LLPipeline::RENDER_TYPE_CLOUDS, +										LLPipeline::RENDER_TYPE_WL_SKY, +										LLPipeline::END_RENDER_TYPES);  			renderGeomPostDeferred(*LLViewerCamera::getInstance()); -			mRenderTypeMask = render_mask; +			gPipeline.popRenderTypeMask();  		}  		BOOL render_local = gSavedSettings.getBOOL("RenderDeferredLocalLights"); @@ -6610,6 +6680,15 @@ void LLPipeline::renderDeferredLighting()  						continue;  					} +					if (volume->isAttachment()) +					{ +						if (!sRenderAttachedLights) +						{ +							continue; +						} +					} + +  					LLVector3 center = drawablep->getPositionAgent();  					F32* c = center.mV;  					F32 s = volume->getLightRadius()*1.5f; @@ -6660,7 +6739,7 @@ void LLPipeline::renderDeferredLighting()  					{ //draw box if camera is outside box  						if (render_local)  						{ -							if (volume->getLightTexture()) +							if (volume->isLightSpotlight())  							{  								drawablep->getVOVolume()->updateSpotLightPriority();  								spot_lights.push_back(drawablep); @@ -6677,7 +6756,7 @@ void LLPipeline::renderDeferredLighting()  					}  					else if (render_fullscreen)  					{	 -						if (volume->getLightTexture()) +						if (volume->isLightSpotlight())  						{  							drawablep->getVOVolume()->updateSpotLightPriority();  							fullscreen_spot_lights.push_back(drawablep); @@ -6878,29 +6957,48 @@ void LLPipeline::renderDeferredLighting()  		LLGLDisable blend(GL_BLEND);  		LLGLDisable stencil(GL_STENCIL_TEST); -		U32 render_mask = mRenderTypeMask; -		mRenderTypeMask =	mRenderTypeMask &  -							((1 << LLPipeline::RENDER_TYPE_ALPHA) | -							(1 << LLPipeline::RENDER_TYPE_FULLBRIGHT) | -							(1 << LLPipeline::RENDER_TYPE_VOLUME) | -							(1 << LLPipeline::RENDER_TYPE_GLOW) | -							(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) | -							(1 << LLPipeline::RENDER_TYPE_AVATAR)); +		pushRenderTypeMask(); +		andRenderTypeMask(LLPipeline::RENDER_TYPE_ALPHA, +						 LLPipeline::RENDER_TYPE_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_VOLUME, +						 LLPipeline::RENDER_TYPE_GLOW, +						 LLPipeline::RENDER_TYPE_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_SIMPLE, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA, +						 LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_POST_BUMP, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, +						 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_GLOW, +						 LLPipeline::RENDER_TYPE_PASS_GRASS, +						 LLPipeline::RENDER_TYPE_PASS_SHINY, +						 LLPipeline::RENDER_TYPE_PASS_INVISIBLE, +						 LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +						 LLPipeline::RENDER_TYPE_AVATAR, +						 END_RENDER_TYPES);  		renderGeomPostDeferred(*LLViewerCamera::getInstance()); -		mRenderTypeMask = render_mask; +		popRenderTypeMask(); +	} + +	{ +		//render highlights, etc. +		renderHighlights(); +		mHighlightFaces.clear(); + +		renderDebug(); + +		LLVertexBuffer::unbind(); + +		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) +		{ +			// Render debugging beacons. +			gObjectList.renderObjectBeacons(); +			LLHUDObject::renderAll(); +			gObjectList.resetObjectBeacons(); +		}  	}  	mScreen.flush(); @@ -7137,8 +7235,8 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		LLPipeline::sUseOcclusion = llmin(occlusion, 1); -		U32 type_mask = gPipeline.mRenderTypeMask; - +		gPipeline.pushRenderTypeMask(); +		  		glh::matrix4f projection = glh_get_current_projection();  		glh::matrix4f mat; @@ -7206,44 +7304,48 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  			glCullFace(GL_FRONT);  			static LLCullResult ref_result; -			U32 ref_mask = 0; +		  			if (LLDrawPoolWater::sNeedsDistortionUpdate)  			{  				//initial sky pass (no user clip plane)  				{ //mask out everything but the sky -					U32 tmp = mRenderTypeMask; -					mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | -										(1 << LLPipeline::RENDER_TYPE_WL_SKY)); +					gPipeline.pushRenderTypeMask(); +					gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +												LLPipeline::RENDER_TYPE_WL_SKY, +												LLPipeline::END_RENDER_TYPES);  					static LLCullResult result;  					updateCull(camera, result);  					llpushcallstacks ;  					stateSort(camera, result); -					mRenderTypeMask = tmp & ((1 << LLPipeline::RENDER_TYPE_SKY) | -										(1 << LLPipeline::RENDER_TYPE_CLOUDS) | -										(1 << LLPipeline::RENDER_TYPE_WL_SKY)); +					andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY, +										LLPipeline::RENDER_TYPE_CLOUDS, +										LLPipeline::RENDER_TYPE_WL_SKY, +										LLPipeline::END_RENDER_TYPES); +  					renderGeom(camera, TRUE); -					mRenderTypeMask = tmp; +					gPipeline.popRenderTypeMask();  				} -				U32 mask = mRenderTypeMask; -				mRenderTypeMask &=	~((1<<LLPipeline::RENDER_TYPE_WATER) | -									  (1<<LLPipeline::RENDER_TYPE_GROUND) | -									  (1<<LLPipeline::RENDER_TYPE_SKY) | -									  (1<<LLPipeline::RENDER_TYPE_CLOUDS));	 - -				if (gSavedSettings.getBOOL("RenderWaterReflections")) +				gPipeline.pushRenderTypeMask(); +				 +				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, +									LLPipeline::RENDER_TYPE_GROUND, +									LLPipeline::RENDER_TYPE_SKY, +									LLPipeline::RENDER_TYPE_CLOUDS, +									LLPipeline::END_RENDER_TYPES);	 + +				S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); +				if (detail > 0)  				{ //mask out selected geometry based on reflection detail - -					S32 detail = gSavedSettings.getS32("RenderReflectionDetail"); -					if (detail < 3) +					if (detail < 4)  					{ -						mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_PARTICLES); -						if (detail < 2) +						clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES); +						if (detail < 3)  						{ -							mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_AVATAR); -							if (detail < 1) +							clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES); +							if (detail < 2)  							{ -								mRenderTypeMask &= ~(1 << LLPipeline::RENDER_TYPE_VOLUME); +								clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);  							}  						}  					} @@ -7255,18 +7357,17 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  					stateSort(camera, ref_result);  				} -				ref_mask = mRenderTypeMask; -				mRenderTypeMask = mask; -			} -			if (LLDrawPoolWater::sNeedsDistortionUpdate) -			{ -				mRenderTypeMask = ref_mask; -				if (gSavedSettings.getBOOL("RenderWaterReflections")) +				if (LLDrawPoolWater::sNeedsDistortionUpdate)  				{ -					gPipeline.grabReferences(ref_result); -					LLGLUserClipPlane clip_plane(plane, mat, projection); -					renderGeom(camera); +					if (gSavedSettings.getS32("RenderReflectionDetail") > 0) +					{ +						gPipeline.grabReferences(ref_result); +						LLGLUserClipPlane clip_plane(plane, mat, projection); +						renderGeom(camera); +					}  				} + +				gPipeline.popRenderTypeMask();  			}	  			glCullFace(GL_BACK);  			glPopMatrix(); @@ -7280,18 +7381,20 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		if (last_update)  		{  			camera.setFar(camera_in.getFar()); -			mRenderTypeMask = type_mask & (~(1<<LLPipeline::RENDER_TYPE_WATER) | -											(1<<LLPipeline::RENDER_TYPE_GROUND));	 +			clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER, +								LLPipeline::RENDER_TYPE_GROUND, +								END_RENDER_TYPES);	  			stop_glerror();  			LLPipeline::sUnderWaterRender = LLViewerCamera::getInstance()->cameraUnderWater() ? FALSE : TRUE;  			if (LLPipeline::sUnderWaterRender)  			{ -				mRenderTypeMask &=	~((1<<LLPipeline::RENDER_TYPE_GROUND) | -									  (1<<LLPipeline::RENDER_TYPE_SKY) | -									  (1<<LLPipeline::RENDER_TYPE_CLOUDS) | -									  (1<<LLPipeline::RENDER_TYPE_WL_SKY));		 +				clearRenderTypeMask(LLPipeline::RENDER_TYPE_GROUND, +									LLPipeline::RENDER_TYPE_SKY, +									LLPipeline::RENDER_TYPE_CLOUDS, +									LLPipeline::RENDER_TYPE_WL_SKY, +									END_RENDER_TYPES);		  			}  			LLViewerCamera::updateFrustumPlanes(camera); @@ -7333,7 +7436,7 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)  		}  		glClearColor(0.f, 0.f, 0.f, 0.f);  		gViewerWindow->setup3DViewport(); -		mRenderTypeMask = type_mask; +		gPipeline.popRenderTypeMask();  		LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;  		LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;  		LLViewerCamera::getInstance()->setUserClipPlane(LLPlane(-pnorm, -pd)); @@ -7525,115 +7628,172 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera  	LLPipeline::sShadowRender = FALSE;  } - +static LLFastTimer::DeclareTimer FTM_VISIBLE_CLOUD("Visible Cloud");  BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector3& max, std::vector<LLVector3>& fp, LLVector3 light_dir)  { +	LLFastTimer t(FTM_VISIBLE_CLOUD);  	//get point cloud of intersection of frust and min, max -	//get set of planes -	std::vector<LLPlane> 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))); +	//get set of planes on bounding box +	std::vector<LLPlane> bp; +		 +	bp.push_back(LLPlane(min, LLVector3(-1,0,0))); +	bp.push_back(LLPlane(min, LLVector3(0,-1,0))); +	bp.push_back(LLPlane(min, LLVector3(0,0,-1))); +	bp.push_back(LLPlane(max, LLVector3(1,0,0))); +	bp.push_back(LLPlane(max, LLVector3(0,1,0))); +	bp.push_back(LLPlane(max, LLVector3(0,0,1))); +	 +	//potential points +	std::vector<LLVector3> pp; + +	//add corners of AABB +	pp.push_back(LLVector3(min.mV[0], min.mV[1], min.mV[2])); +	pp.push_back(LLVector3(max.mV[0], min.mV[1], min.mV[2])); +	pp.push_back(LLVector3(min.mV[0], max.mV[1], min.mV[2])); +	pp.push_back(LLVector3(max.mV[0], max.mV[1], min.mV[2])); +	pp.push_back(LLVector3(min.mV[0], min.mV[1], max.mV[2])); +	pp.push_back(LLVector3(max.mV[0], min.mV[1], max.mV[2])); +	pp.push_back(LLVector3(min.mV[0], max.mV[1], max.mV[2])); +	pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2])); -	/*if (!light_dir.isExactlyZero()) +	//add corners of camera frustum +	for (U32 i = 0; i < 8; i++)  	{ -		LLPlane ucp; -		LLPlane mcp; +		pp.push_back(camera.mAgentFrustum[i]); +	} -		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]; -			} +	//bounding box line segments +	U32 bs[] =  +	{ +		0,1, +		1,3, +		3,2, +		2,0, + +		4,5, +		5,7, +		7,6, +		6,4, + +		0,4, +		1,5, +		3,7, +		2,6 +	}; + +	for (U32 i = 0; i < 12; i++) +	{ //for each line segment in bounding box +		for (U32 j = 0; j < 6; j++)  +		{ //for each plane in camera frustum +			const LLPlane& cp = camera.getAgentPlane(j); +			const LLVector3& v1 = pp[bs[i*2+0]]; +			const LLVector3& v2 = pp[bs[i*2+1]]; +			const LLVector3 n(cp.mV); + +			LLVector3 line = v1-v2; + +			F32 d1 = line*n; +			F32 d2 = -cp.dist(v2); + +			F32 t = d2/d1; -			if (da < mind) +			if (t > 0.f && t < 1.f)  			{ -				mind = da; -				mcp = ps[i]; +				LLVector3 intersect = v2+line*t; +				pp.push_back(intersect);  			}  		} -			 -		camera.setUserClipPlane(ucp); +	} -		ps.clear(); -		ps.push_back(ucp); -		ps.push_back(mcp); -	}*/ -	 -	for (U32 i = 0; i < 6; i++) +	//camera frustum line segments +	const U32 fs[] =  	{ -		ps.push_back(camera.getAgentPlane(i)); -	} +		0,1, +		1,2, +		2,3, +		3,1, -	//get set of points where planes intersect and points are not above any plane -	fp.clear(); -	 -	for (U32 i = 0; i < ps.size(); ++i) +		4,5, +		5,6, +		6,7, +		7,4, + +		0,4, +		1,5, +		2,6, +		3,7	 +	}; + +	LLVector3 center = (max+min)*0.5f; +	LLVector3 size = (max-min)*0.5f; + +	for (U32 i = 0; i < 12; i++)  	{ -		for (U32 j = 0; j < ps.size(); ++j) +		for (U32 j = 0; j < 6; ++j)  		{ -			for (U32 k = 0; k < ps.size(); ++k) -			{ -				if (i == j || -					i == k || -					k == j) -				{ -					continue; -				} +			const LLVector3& v1 = pp[fs[i*2+0]+8]; +			const LLVector3& v2 = pp[fs[i*2+1]+8]; +			const LLPlane& cp = bp[j]; +			const LLVector3 n(cp.mV); -				LLVector3 n1,n2,n3; -				F32 d1,d2,d3; +			LLVector3 line = v1-v2; -				n1.setVec(ps[i].mV); -				n2.setVec(ps[j].mV); -				n3.setVec(ps[k].mV); +			F32 d1 = line*n; +			F32 d2 = -cp.dist(v2); -				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;	 -						} -					} +			F32 t = d2/d1; -					if (found) -					{ -						fp.push_back(p); -					} -				} -			} +			if (t > 0.f && t < 1.f) +			{ +				LLVector3 intersect = v2+line*t; +				pp.push_back(intersect); +			}	  		}  	} +	LLVector3 ext[] = { min-LLVector3(0.05f,0.05f,0.05f), +		max+LLVector3(0.05f,0.05f,0.05f) }; + +	for (U32 i = 0; i < pp.size(); ++i) +	{ +		bool found = true; +		 +		const F32* p = pp[i].mV; + +		for (U32 j = 0; j < 3; ++j) +		{ +			if (p[j] < ext[0].mV[j] || +				p[j] > ext[1].mV[j]) +			{ +				found = false; +				break; +			} +		} +			 +		for (U32 j = 0; j < 6; ++j) +		{ +			const LLPlane& cp = camera.getAgentPlane(j); +			F32 dist = cp.dist(pp[i]); +			if (dist > 0.05f) //point is above some plane, not contained +			{ +				found = false; +				break; +			} +		} + +		if (found) +		{ +			fp.push_back(pp[i]); +		} +	} +  	if (fp.empty())  	{  		return FALSE; @@ -7731,21 +7891,22 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L  	sun_cam.ignoreAgentFrustumPlane(LLCamera::AGENT_PLANE_NEAR);  	static LLCullResult result; -	U32 type_mask = mRenderTypeMask; +	pushRenderTypeMask(); -	mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | -								   (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | -								   (1<<LLPipeline::RENDER_TYPE_BUMP) | -								   (1<<LLPipeline::RENDER_TYPE_VOLUME) | -								   (1<<LLPipeline::RENDER_TYPE_TREE) |  -								   (1<<LLPipeline::RENDER_TYPE_TERRAIN) | -								   (1<<LLPipeline::RENDER_TYPE_WATER) | -								   (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | -								   (1<<LLPipeline::RENDER_TYPE_AVATAR) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | -									(1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | -									(1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | -									(1 << LLPipeline::RENDER_TYPE_PASS_SHINY)); +	andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, +								 LLPipeline::RENDER_TYPE_FULLBRIGHT, +								 LLPipeline::RENDER_TYPE_BUMP, +								 LLPipeline::RENDER_TYPE_VOLUME, +								 LLPipeline::RENDER_TYPE_TREE,  +								 LLPipeline::RENDER_TYPE_TERRAIN, +								 LLPipeline::RENDER_TYPE_WATER, +								 LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, +								 LLPipeline::RENDER_TYPE_AVATAR, +								 LLPipeline::RENDER_TYPE_PASS_SIMPLE, +								 LLPipeline::RENDER_TYPE_PASS_BUMP, +								 LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +								 LLPipeline::RENDER_TYPE_PASS_SHINY, +								 END_RENDER_TYPES); @@ -7814,7 +7975,7 @@ void LLPipeline::generateGI(LLCamera& camera, LLVector3& lightDir, std::vector<L  	LLPipeline::sShadowRender = FALSE;  	sMinRenderSize = 0.f; -	mRenderTypeMask = type_mask; +	popRenderTypeMask();  } @@ -7898,30 +8059,11 @@ void LLPipeline::generateHighlight(LLCamera& camera)  void LLPipeline::generateSunShadow(LLCamera& camera)  { -	if (!sRenderDeferred || !gSavedSettings.getBOOL("RenderDeferredShadow")) +	if (!sRenderDeferred || gSavedSettings.getS32("RenderShadowDetail") <= 0)  	{  		return;  	} -	//temporary hack to disable shadows but keep local lights -	static BOOL clear = TRUE; -	BOOL gen_shadow = gSavedSettings.getBOOL("RenderDeferredSunShadow"); -	if (!gen_shadow) -	{ -		if (clear) -		{ -			clear = FALSE; -			for (U32 i = 0; i < 6; i++) -			{ -				mShadow[i].bindTarget(); -				mShadow[i].clear(); -				mShadow[i].flush(); -			} -		} -		return; -	} -	clear = TRUE; -  	F64 last_modelview[16];  	F64 last_projection[16];  	for (U32 i = 0; i < 16; i++) @@ -7930,23 +8072,24 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		last_projection[i] = gGLLastProjection[i];  	} -	U32 type_mask = mRenderTypeMask; -	mRenderTypeMask = type_mask & ((1<<LLPipeline::RENDER_TYPE_SIMPLE) | -								   (1<<LLPipeline::RENDER_TYPE_ALPHA) | -								   (1<<LLPipeline::RENDER_TYPE_GRASS) | -								   (1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | -								   (1<<LLPipeline::RENDER_TYPE_BUMP) | -								   (1<<LLPipeline::RENDER_TYPE_VOLUME) | -								   (1<<LLPipeline::RENDER_TYPE_AVATAR) | -								   (1<<LLPipeline::RENDER_TYPE_TREE) |  -								   (1<<LLPipeline::RENDER_TYPE_TERRAIN) | -								   (1<<LLPipeline::RENDER_TYPE_WATER) | -								   (1<<LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_BUMP) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_SHINY) | -								   (1 << LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY)); +	pushRenderTypeMask(); +	andRenderTypeMask(LLPipeline::RENDER_TYPE_SIMPLE, +					LLPipeline::RENDER_TYPE_ALPHA, +					LLPipeline::RENDER_TYPE_GRASS, +					LLPipeline::RENDER_TYPE_FULLBRIGHT, +					LLPipeline::RENDER_TYPE_BUMP, +					LLPipeline::RENDER_TYPE_VOLUME, +					LLPipeline::RENDER_TYPE_AVATAR, +					LLPipeline::RENDER_TYPE_TREE,  +					LLPipeline::RENDER_TYPE_TERRAIN, +					LLPipeline::RENDER_TYPE_WATER, +					LLPipeline::RENDER_TYPE_PASS_ALPHA_SHADOW, +					LLPipeline::RENDER_TYPE_PASS_SIMPLE, +					LLPipeline::RENDER_TYPE_PASS_BUMP, +					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +					LLPipeline::RENDER_TYPE_PASS_SHINY, +					LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +					END_RENDER_TYPES);  	gGL.setColorMask(false, false); @@ -7998,17 +8141,32 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	at.normVec(); +	LLCamera main_camera = camera; +	  	F32 near_clip = 0.f;  	{  		//get visible point cloud  		std::vector<LLVector3> fp; +		main_camera.calcAgentFrustumPlanes(main_camera.mAgentFrustum); +		  		LLVector3 min,max; -		getVisiblePointCloud(camera,min,max,fp); +		getVisiblePointCloud(main_camera,min,max,fp);  		if (fp.empty())  		{ -			mRenderTypeMask = type_mask; +			if (!hasRenderDebugMask(RENDER_DEBUG_SHADOW_FRUSTA)) +			{ +				mShadowCamera[0] = main_camera; +				mShadowExtents[0][0] = min; +				mShadowExtents[0][1] = max; + +				mShadowFrustPoints[0].clear(); +				mShadowFrustPoints[1].clear(); +				mShadowFrustPoints[2].clear(); +				mShadowFrustPoints[3].clear(); +			} +			popRenderTypeMask();  			return;  		} @@ -8082,7 +8240,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		shadow_cam = camera;  		shadow_cam.setFar(16.f); -		LLViewerCamera::updateFrustumPlanes(shadow_cam); +		LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE);  		LLVector3* frust = shadow_cam.mAgentFrustum; @@ -8094,10 +8252,11 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		for (U32 i = 0; i < 4; i++)  		{  			LLVector3 delta = frust[i+4]-eye; +			delta += (frust[i+4]-frust[(i+2)%4+4])*0.05f;  			delta.normVec();  			F32 dp = delta*pn; -			frust[i] = eye + (delta*dist[j])/dp; -			frust[i+4] = eye + (delta*dist[j+1])/dp; +			frust[i] = eye + (delta*dist[j]*0.95f)/dp; +			frust[i+4] = eye + (delta*dist[j+1]*1.05f)/dp;  		}  		shadow_cam.calcAgentFrustumPlanes(frust); @@ -8437,135 +8596,155 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		}  	} -	 - -	F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); -	//update shadow targets -	for (U32 i = 0; i < 2; i++) -	{ //for each current shadow -		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; +	//hack to disable projector shadows  +	static bool clear = true; +	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1; +	 +	if (gen_shadow) +	{ +		clear = true; +		F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); -		if (mShadowSpotLight[i].notNull() &&  -			(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || -			mShadowSpotLight[i] == mTargetShadowSpotLight[1])) -		{ //keep this spotlight -			mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); -		} -		else -		{ //fade out this light -			mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); -			 -			if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) -			{ //faded out, grab one of the pending spots (whichever one isn't already taken) -				if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) -				{ -					mShadowSpotLight[i] = mTargetShadowSpotLight[0]; -				} -				else -				{ -					mShadowSpotLight[i] = mTargetShadowSpotLight[1]; +		//update shadow targets +		for (U32 i = 0; i < 2; i++) +		{ //for each current shadow +			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW4+i; + +			if (mShadowSpotLight[i].notNull() &&  +				(mShadowSpotLight[i] == mTargetShadowSpotLight[0] || +				mShadowSpotLight[i] == mTargetShadowSpotLight[1])) +			{ //keep this spotlight +				mSpotLightFade[i] = llmin(mSpotLightFade[i]+fade_amt, 1.f); +			} +			else +			{ //fade out this light +				mSpotLightFade[i] = llmax(mSpotLightFade[i]-fade_amt, 0.f); +				 +				if (mSpotLightFade[i] == 0.f || mShadowSpotLight[i].isNull()) +				{ //faded out, grab one of the pending spots (whichever one isn't already taken) +					if (mTargetShadowSpotLight[0] != mShadowSpotLight[(i+1)%2]) +					{ +						mShadowSpotLight[i] = mTargetShadowSpotLight[0]; +					} +					else +					{ +						mShadowSpotLight[i] = mTargetShadowSpotLight[1]; +					}  				}  			}  		} -	} - -	for (S32 i = 0; i < 2; i++) -	{ -		glh_set_current_modelview(saved_view); -		glh_set_current_projection(saved_proj); - -		if (mShadowSpotLight[i].isNull()) +		 +		for (S32 i = 0; i < 2; i++)  		{ -			continue; -		} +			glh_set_current_modelview(saved_view); +			glh_set_current_projection(saved_proj); -		LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); +			if (mShadowSpotLight[i].isNull()) +			{ +				continue; +			} -		if (!volume) -		{ -			mShadowSpotLight[i] = NULL; -			continue; -		} +			LLVOVolume* volume = mShadowSpotLight[i]->getVOVolume(); -		LLDrawable* drawable = mShadowSpotLight[i]; +			if (!volume) +			{ +				mShadowSpotLight[i] = NULL; +				continue; +			} -		LLVector3 params = volume->getSpotLightParams(); -		F32 fov = params.mV[0]; +			LLDrawable* drawable = mShadowSpotLight[i]; -		//get agent->light space matrix (modelview) -		LLVector3 center = drawable->getPositionAgent(); -		LLQuaternion quat = volume->getRenderRotation(); +			LLVector3 params = volume->getSpotLightParams(); +			F32 fov = params.mV[0]; -		//get near clip plane -		LLVector3 scale = volume->getScale(); -		LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); -		at_axis *= quat; +			//get agent->light space matrix (modelview) +			LLVector3 center = drawable->getPositionAgent(); +			LLQuaternion quat = volume->getRenderRotation(); -		LLVector3 np = center+at_axis; -		at_axis.normVec(); +			//get near clip plane +			LLVector3 scale = volume->getScale(); +			LLVector3 at_axis(0,0,-scale.mV[2]*0.5f); +			at_axis *= quat; -		//get origin that has given fov for plane np, at_axis, and given scale -		F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); +			LLVector3 np = center+at_axis; +			at_axis.normVec(); -		LLVector3 origin = np - at_axis*dist; +			//get origin that has given fov for plane np, at_axis, and given scale +			F32 dist = (scale.mV[1]*0.5f)/tanf(fov*0.5f); -		LLMatrix4 mat(quat, LLVector4(origin, 1.f)); +			LLVector3 origin = np - at_axis*dist; -		view[i+4] = glh::matrix4f((F32*) mat.mMatrix); +			LLMatrix4 mat(quat, LLVector4(origin, 1.f)); -		view[i+4] = view[i+4].inverse(); +			view[i+4] = glh::matrix4f((F32*) mat.mMatrix); -		//get perspective matrix -		F32 near_clip = dist+0.01f; -		F32 width = scale.mV[VX]; -		F32 height = scale.mV[VY]; -		F32 far_clip = dist+volume->getLightRadius()*1.5f; +			view[i+4] = view[i+4].inverse(); -		F32 fovy = fov * RAD_TO_DEG; -		F32 aspect = width/height; -		 -		proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); +			//get perspective matrix +			F32 near_clip = dist+0.01f; +			F32 width = scale.mV[VX]; +			F32 height = scale.mV[VY]; +			F32 far_clip = dist+volume->getLightRadius()*1.5f; -		//translate and scale to from [-1, 1] to [0, 1] -		glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, -						0.f, 0.5f, 0.f, 0.5f, -						0.f, 0.f, 0.5f, 0.5f, -						0.f, 0.f, 0.f, 1.f); +			F32 fovy = fov * RAD_TO_DEG; +			F32 aspect = width/height; +			 +			proj[i+4] = gl_perspective(fovy, aspect, near_clip, far_clip); -		glh_set_current_modelview(view[i+4]); -		glh_set_current_projection(proj[i+4]); +			//translate and scale to from [-1, 1] to [0, 1] +			glh::matrix4f trans(0.5f, 0.f, 0.f, 0.5f, +							0.f, 0.5f, 0.f, 0.5f, +							0.f, 0.f, 0.5f, 0.5f, +							0.f, 0.f, 0.f, 1.f); -		mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; -		 -		for (U32 j = 0; j < 16; j++) -		{ -			gGLLastModelView[j] = mShadowModelview[i+4].m[j]; -			gGLLastProjection[j] = mShadowProjection[i+4].m[j]; -		} +			glh_set_current_modelview(view[i+4]); +			glh_set_current_projection(proj[i+4]); -		mShadowModelview[i+4] = view[i+4]; -		mShadowProjection[i+4] = proj[i+4]; +			mSunShadowMatrix[i+4] = trans*proj[i+4]*view[i+4]*inv_view; +			 +			for (U32 j = 0; j < 16; j++) +			{ +				gGLLastModelView[j] = mShadowModelview[i+4].m[j]; +				gGLLastProjection[j] = mShadowProjection[i+4].m[j]; +			} -		LLCamera shadow_cam = camera; -		shadow_cam.setFar(far_clip); -		shadow_cam.setOrigin(origin); +			mShadowModelview[i+4] = view[i+4]; +			mShadowProjection[i+4] = proj[i+4]; -		LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); +			LLCamera shadow_cam = camera; +			shadow_cam.setFar(far_clip); +			shadow_cam.setOrigin(origin); -		stop_glerror(); +			LLViewerCamera::updateFrustumPlanes(shadow_cam, FALSE, FALSE, TRUE); + +			stop_glerror(); -		mShadow[i+4].bindTarget(); -		mShadow[i+4].getViewport(gGLViewport); +			mShadow[i+4].bindTarget(); +			mShadow[i+4].getViewport(gGLViewport); -		static LLCullResult result[2]; +			static LLCullResult result[2]; -		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; +			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; -		renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); +			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); -		mShadow[i+4].flush(); - 	} +			mShadow[i+4].flush(); + 		} +	} +	else +	{ +		if (clear) +		{ +			clear = false; +			for (U32 i = 4; i < 6; i++) +			{ +				mShadow[i].bindTarget(); +				mShadow[i].clear(); +				mShadow[i].flush(); +			} +		} +	}  	if (!gSavedSettings.getBOOL("CameraOffset"))  	{ @@ -8589,7 +8768,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  		gGLLastProjection[i] = last_projection[i];  	} -	mRenderTypeMask = type_mask; +	popRenderTypeMask();  }  void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, BOOL texture) @@ -8625,38 +8804,36 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	assertInitialized(); -	U32 mask;  	BOOL muted = LLMuteList::getInstance()->isMuted(avatar->getID()); +	pushRenderTypeMask(); +	  	if (muted)  	{ -		mask  = 1 << LLPipeline::RENDER_TYPE_AVATAR; +		andRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, END_RENDER_TYPES);  	}  	else  	{ -		mask  = (1<<LLPipeline::RENDER_TYPE_VOLUME) | -				(1<<LLPipeline::RENDER_TYPE_AVATAR) | -				(1<<LLPipeline::RENDER_TYPE_BUMP) | -				(1<<LLPipeline::RENDER_TYPE_GRASS) | -				(1<<LLPipeline::RENDER_TYPE_SIMPLE) | -				(1<<LLPipeline::RENDER_TYPE_FULLBRIGHT) | -				(1<<LLPipeline::RENDER_TYPE_ALPHA) |  -				(1<<LLPipeline::RENDER_TYPE_INVISIBLE) | -				(1 << LLPipeline::RENDER_TYPE_PASS_SIMPLE) | -				(1 << LLPipeline::RENDER_TYPE_PASS_ALPHA) | -				(1 << LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK) | -				(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_SHINY) | -				(1 << LLPipeline::RENDER_TYPE_PASS_INVISIBLE) | -				(1 << LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY); +		andRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, +						LLPipeline::RENDER_TYPE_AVATAR, +						LLPipeline::RENDER_TYPE_BUMP, +						LLPipeline::RENDER_TYPE_GRASS, +						LLPipeline::RENDER_TYPE_SIMPLE, +						LLPipeline::RENDER_TYPE_FULLBRIGHT, +						LLPipeline::RENDER_TYPE_ALPHA,  +						LLPipeline::RENDER_TYPE_INVISIBLE, +						LLPipeline::RENDER_TYPE_PASS_SIMPLE, +						LLPipeline::RENDER_TYPE_PASS_ALPHA, +						LLPipeline::RENDER_TYPE_PASS_ALPHA_MASK, +						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT, +						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_ALPHA_MASK, +						LLPipeline::RENDER_TYPE_PASS_FULLBRIGHT_SHINY, +						LLPipeline::RENDER_TYPE_PASS_SHINY, +						LLPipeline::RENDER_TYPE_PASS_INVISIBLE, +						LLPipeline::RENDER_TYPE_PASS_INVISI_SHINY, +						END_RENDER_TYPES);  	} -	mask = mask & gPipeline.getRenderTypeMask(); -	U32 saved_mask = gPipeline.mRenderTypeMask; -	gPipeline.mRenderTypeMask = mask; -  	S32 occlusion = sUseOcclusion;  	sUseOcclusion = 0;  	sReflectionRender = sRenderDeferred ? FALSE : TRUE; @@ -8830,7 +9007,7 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)  	sReflectionRender = FALSE;  	sImpostorRender = FALSE;  	sShadowRender = FALSE; -	gPipeline.mRenderTypeMask = saved_mask; +	popRenderTypeMask();  	glMatrixMode(GL_PROJECTION);  	glPopMatrix(); @@ -8871,4 +9048,121 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups()  	return sCull->endAlphaGroups();  } +BOOL LLPipeline::hasRenderType(const U32 type) const +{ +	return mRenderTypeEnabled[type]; +} + +void LLPipeline::setRenderTypeMask(U32 type, ...) +{ +	va_list args; + +	va_start(args, type); +	while (type < END_RENDER_TYPES) +	{ +		mRenderTypeEnabled[type] = TRUE; +		type = va_arg(args, U32); +	} +	va_end(args); + +	if (type > END_RENDER_TYPES) +	{ +		llerrs << "Invalid render type." << llendl; +	} +} + +BOOL LLPipeline::hasAnyRenderType(U32 type, ...) const +{ +	va_list args; + +	va_start(args, type); +	while (type < END_RENDER_TYPES) +	{ +		if (mRenderTypeEnabled[type]) +		{ +			return TRUE; +		} +		type = va_arg(args, U32); +	} +	va_end(args); + +	if (type > END_RENDER_TYPES) +	{ +		llerrs << "Invalid render type." << llendl; +	} + +	return FALSE; +} + +void LLPipeline::pushRenderTypeMask() +{ +	std::string cur_mask; +	cur_mask.assign((const char*) mRenderTypeEnabled, sizeof(mRenderTypeEnabled)); +	mRenderTypeEnableStack.push(cur_mask); +} + +void LLPipeline::popRenderTypeMask() +{ +	if (mRenderTypeEnableStack.empty()) +	{ +		llerrs << "Depleted render type stack." << llendl; +	} + +	memcpy(mRenderTypeEnabled, mRenderTypeEnableStack.top().data(), sizeof(mRenderTypeEnabled)); +	mRenderTypeEnableStack.pop(); +} + +void LLPipeline::andRenderTypeMask(U32 type, ...) +{ +	va_list args; + +	BOOL tmp[NUM_RENDER_TYPES]; +	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i) +	{ +		tmp[i] = FALSE; +	} + +	va_start(args, type); +	while (type < END_RENDER_TYPES) +	{ +		if (mRenderTypeEnabled[type])  +		{ +			tmp[type] = TRUE; +		} + +		type = va_arg(args, U32); +	} +	va_end(args); + +	if (type > END_RENDER_TYPES) +	{ +		llerrs << "Invalid render type." << llendl; +	} + +	for (U32 i = 0; i < LLPipeline::NUM_RENDER_TYPES; ++i) +	{ +		mRenderTypeEnabled[i] = tmp[i]; +	} + +} + +void LLPipeline::clearRenderTypeMask(U32 type, ...) +{ +	va_list args; + +	va_start(args, type); +	while (type < END_RENDER_TYPES) +	{ +		mRenderTypeEnabled[type] = FALSE; +		 +		type = va_arg(args, U32); +	} +	va_end(args); + +	if (type > END_RENDER_TYPES) +	{ +		llerrs << "Invalid render type." << llendl; +	} +} + diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 89649a0682..faa8cec5d6 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -46,6 +46,8 @@  #include "lldrawable.h"  #include "llrendertarget.h" +#include <stack> +  class LLViewerTexture;  class LLEdge;  class LLFace; @@ -277,12 +279,25 @@ public:  	LLCullResult::sg_list_t::iterator beginAlphaGroups();  	LLCullResult::sg_list_t::iterator endAlphaGroups(); +  	void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES); -	BOOL hasRenderType(const U32 type) const				{ return (type && (mRenderTypeMask & (1<<type))) ? TRUE : FALSE; } +  	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }  	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; } -	void setRenderTypeMask(const U32 mask)					{ mRenderTypeMask = mask; } -	U32  getRenderTypeMask() const							{ return mRenderTypeMask; } +	 + + +	BOOL hasRenderType(const U32 type) const; +	BOOL hasAnyRenderType(const U32 type, ...) const; + +	void setRenderTypeMask(U32 type, ...); +	void orRenderTypeMask(U32 type, ...); +	void andRenderTypeMask(U32 type, ...); +	void clearRenderTypeMask(U32 type, ...); +	 +	void pushRenderTypeMask(); +	void popRenderTypeMask(); +  	static void toggleRenderType(U32 type);  	// For UI control of render features @@ -360,6 +375,7 @@ public:  		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_POST_BUMP				= LLRenderPass::PASS_POST_BUMP,  		RENDER_TYPE_PASS_GLOW					= LLRenderPass::PASS_GLOW,  		RENDER_TYPE_PASS_ALPHA					= LLRenderPass::PASS_ALPHA,  		RENDER_TYPE_PASS_ALPHA_MASK				= LLRenderPass::PASS_ALPHA_MASK, @@ -370,7 +386,9 @@ public:  		RENDER_TYPE_VOLUME,  		RENDER_TYPE_PARTICLES,  		RENDER_TYPE_CLOUDS, -		RENDER_TYPE_HUD_PARTICLES +		RENDER_TYPE_HUD_PARTICLES, +		NUM_RENDER_TYPES, +		END_RENDER_TYPES = NUM_RENDER_TYPES  	};  	enum LLRenderDebugFeatureMask @@ -444,7 +462,8 @@ public:  	static BOOL				sForceOldBakedUpload; // If true will not use capabilities to upload baked textures.  	static S32				sUseOcclusion;  // 0 = no occlusion, 1 = read only, 2 = read/write  	static BOOL				sDelayVBUpdate; -	static BOOL				sFastAlpha; +	static BOOL				sAutoMaskAlphaDeferred; +	static BOOL				sAutoMaskAlphaNonDeferred;  	static BOOL				sDisableShaders; // if TRUE, rendering will be done without shaders  	static BOOL				sRenderBump;  	static BOOL				sUseTriStrips; @@ -533,7 +552,9 @@ public:  	S32						mVertexShadersLoaded; // 0 = no, 1 = yes, -1 = failed  protected: -	U32						mRenderTypeMask; +	BOOL					mRenderTypeEnabled[NUM_RENDER_TYPES]; +	std::stack<std::string> mRenderTypeEnableStack; +  	U32						mRenderDebugFeatureMask;  	U32						mRenderDebugMask; diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index aff8f7ddf4..7b1633d76e 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -29,7 +29,9 @@              <menu_item_call.on_click               function="BuyCurrency" />          </menu_item_call> +          <menu_item_separator/> +          <menu_item_call           label="My Profile"           name="Profile"> @@ -113,7 +115,9 @@              <menu_item_call.on_click               function="Advanced.LeaveAdminStatus" />          </menu_item_call> +          <menu_item_separator/> +          <menu_item_call           label="Exit [APP_NAME]"           name="Quit" @@ -142,7 +146,9 @@               function="SideTray.PanelPeopleTab"               parameter="groups_panel" />          </menu_item_call> +          <menu_item_separator/> +          <!--menu_item_call           label="Chat"           name="Chat"> @@ -240,7 +246,9 @@               parameter="region_info" />          </menu_item_call>          </menu> +          <menu_item_separator/> +          <menu_item_call               label="Buy This Land"               name="Buy Land"> @@ -337,7 +345,9 @@                 control="NavBarShowParcelProperties" />            </menu_item_check>          </menu> +          <menu_item_separator/> +  	    <menu_item_call  	     label="Teleport Home"  	     name="Teleport Home" @@ -376,7 +386,9 @@               parameter="ShowNavbarFavoritesPanel" />          </menu_item_check>          <menu_item_separator/>--> +          <menu_item_separator/> +      <menu           create_jump_keys="true"           label="Sun" @@ -419,7 +431,9 @@                   function="World.EnvSettings"                   parameter="default" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_call               label="Environment Editor"               name="Environment Editor"> @@ -568,6 +582,7 @@              </menu_item_call>          </menu>          <menu_item_separator/> +          <menu_item_call             label="Focus on Selection"             name="Focus on Selection" @@ -588,7 +603,9 @@            <menu_item_call.on_enable               function="Tools.SomethingSelectedNoHUD" />          </menu_item_call> +          <menu_item_separator/> +          <menu           create_jump_keys="true"           label="Object" @@ -690,7 +707,9 @@                 function="EditableSelected" />            </menu_item_call>          </menu> +          <menu_item_separator/> +          <menu           create_jump_keys="true"           label="Options" @@ -713,7 +732,9 @@  				 function="ToggleControl"  				 parameter="DebugPermissions" />  			</menu_item_check> +              <menu_item_separator/> +              <menu_item_check                   label="Select Only My Objects"                   name="Select Only My Objects"> @@ -740,7 +761,9 @@                      <menu_item_check.on_click                       function="Tools.SelectBySurrounding" />              </menu_item_check> +            <menu_item_separator/> +                  <menu_item_check                   label="Show Hidden Selection"                   name="Show Hidden Selection"> @@ -766,7 +789,9 @@                       function="ToggleControl"                       parameter="ShowSelectionBeam" />                  </menu_item_check> +          <menu_item_separator/> +                  <menu_item_check                   label="Snap to Grid"                   name="Snap to Grid" @@ -885,7 +910,9 @@               function="Floater.Show"               parameter="hud" />          </menu_item_call>--> +          <menu_item_separator/> +          <menu_item_call               label="Report Abuse"               name="Report Abuse"> @@ -899,7 +926,9 @@                   function="ShowHelp"                   parameter="report_bug" />              </menu_item_call> +          <menu_item_separator/> +          <menu_item_call           label="About [APP_NAME]"           name="About Second Life"> @@ -950,7 +979,9 @@             function="Floater.Show"             parameter="window_size" />          </menu_item_call> +          <menu_item_separator/> +          <menu_item_check           label="Limit Select Distance"           name="Limit Select Distance"> @@ -971,7 +1002,9 @@               function="ToggleControl"               parameter="DisableCameraConstraints" />          </menu_item_check> +          <menu_item_separator/> +          <menu_item_check           label="High-res Snapshot"           name="HighResSnapshot"> @@ -1002,7 +1035,9 @@               function="ToggleControl"               parameter="CompressSnapshotsToDisk" />          </menu_item_check> +          <menu_item_separator/> +          <menu           create_jump_keys="true"           label="Performance Tools" @@ -1115,7 +1150,9 @@                  <menu_item_check.on_click                   function="View.ShowHoverTips" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_check               label="Show Land Tooltips"               name="Land Tips"> @@ -1422,7 +1459,9 @@               function="ToggleControl"               parameter="MouseSmooth" />          </menu_item_check> +          <menu_item_separator/> +          <menu           label="Shortcuts"           name="Shortcuts" @@ -1466,7 +1505,9 @@                  <menu_item_call.on_click                   function="View.DefaultUISize" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_check               label="Always Run"               name="Always Run" @@ -1487,7 +1528,9 @@                  <menu_item_check.on_enable                   function="Agent.enableFlying" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_call               label="Close Window"               name="Close Window" @@ -1506,7 +1549,9 @@                  <menu_item_call.on_enable                   function="File.EnableCloseAllWindows" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_call               label="Snapshot to Disk"               name="Snapshot to Disk" @@ -1515,7 +1560,9 @@                  <menu_item_call.on_click                   function="File.TakeSnapshotToDisk" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_call               label="Mouselook"               name="Mouselook" @@ -1552,7 +1599,9 @@                  <menu_item_call.on_enable                   function="View.EnableLastChatter" />              </menu_item_call> +              <menu_item_separator/> +              <menu               create_jump_keys="true"               label="Select Build Tool" @@ -1599,7 +1648,9 @@                       parameter="land" />                  </menu_item_call>              </menu> +              <menu_item_separator/> +              <menu_item_call               label="Zoom In"               name="Zoom In" @@ -1622,7 +1673,9 @@                   function="View.ZoomOut" />              </menu_item_call>          </menu> +          <menu_item_separator/> +          <menu_item_call           label="Show Debug Settings"           name="Debug Settings"> @@ -1732,7 +1785,9 @@                   function="Advanced.ToggleConsole"                   parameter="memory view" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_call               label="Region Info to Debug Console"               name="Region Info to Debug Console"> @@ -1754,7 +1809,9 @@                   function="Advanced.DumpInfoToConsole"                   parameter="capabilities" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_check               label="Camera"               name="Camera"> @@ -1842,7 +1899,9 @@                   function="ToggleControl"                   parameter="DebugShowColor" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_check               label="Show Updates to Objects"               name="Show Updates" @@ -1854,7 +1913,9 @@                   function="Advanced.ToggleShowObjectUpdates" />              </menu_item_check>          </menu> +          <menu_item_separator/> +          <menu           create_jump_keys="true"           label="Force an Error" @@ -2148,9 +2209,12 @@              <menu_item_check.on_enable                   function="Advanced.EnableRenderFBO" />             </menu_item_check> + +          <menu_item_separator /> +            <menu_item_check -                       label="Deferred Rendering" -                       name="Deferred Rendering"> +                       label="Lighting and Shadows" +                       name="Lighting and Shadows">              <menu_item_check.on_check               function="CheckControl"               parameter="RenderDeferred" /> @@ -2161,7 +2225,31 @@                   function="Advanced.EnableRenderDeferred" />            </menu_item_check>            <menu_item_check -                   label="Global Illumination" +                       label="   Shadows from Sun/Moon/Projectors" +                       name="Shadows from Sun/Moon/Projectors"> +            <menu_item_check.on_check +             function="Advanced.CheckRenderShadowOption" +             parameter="RenderShadowDetail" /> +            <menu_item_check.on_click +             function="Advanced.ClickRenderShadowOption" +             parameter="RenderShadowDetail" /> +            <menu_item_check.on_enable +                 function="Advanced.EnableRenderDeferredOptions" /> +          </menu_item_check> +          <menu_item_check +                   label="   SSAO and Shadow Smoothing" +                   name="SSAO and Shadow Smoothing"> +            <menu_item_check.on_check +             function="CheckControl" +             parameter="RenderDeferredSSAO" /> +            <menu_item_check.on_click +             function="ToggleControl" +             parameter="RenderDeferredSSAO" /> +            <menu_item_check.on_enable +                 function="Advanced.EnableRenderDeferredOptions" /> +          </menu_item_check> +          <menu_item_check +                   label="   Global Illumination (experimental)"                     name="Global Illumination">              <menu_item_check.on_check               function="CheckControl" @@ -2170,9 +2258,11 @@               function="ToggleControl"               parameter="RenderDeferredGI" />              <menu_item_check.on_enable -                 function="Advanced.EnableRenderDeferredGI" /> +                 function="Advanced.EnableRenderDeferredOptions" />            </menu_item_check> +            <menu_item_separator /> +            <menu_item_check               label="Debug GL"               name="Debug GL"> @@ -2194,14 +2284,24 @@                   parameter="RenderDebugPipeline" />              </menu_item_check>              <menu_item_check -             label="Fast Alpha" -             name="Fast Alpha"> +             label="Automatic Alpha Masks (deferred)" +             name="Automatic Alpha Masks (deferred)"> +                <menu_item_check.on_check +                 function="CheckControl" +                 parameter="RenderAutoMaskAlphaDeferred" /> +                <menu_item_check.on_click +                 function="ToggleControl" +                 parameter="RenderAutoMaskAlphaDeferred" /> +            </menu_item_check> +            <menu_item_check +             label="Automatic Alpha Masks (non-deferred)" +             name="Automatic Alpha Masks (non-deferred)">                  <menu_item_check.on_check                   function="CheckControl" -                 parameter="RenderFastAlpha" /> +                 parameter="RenderAutoMaskAlphaNonDeferred" />                  <menu_item_check.on_click                   function="ToggleControl" -                 parameter="RenderFastAlpha" /> +                 parameter="RenderAutoMaskAlphaNonDeferred" />              </menu_item_check>              <menu_item_check               label="Animation Textures" @@ -2244,7 +2344,7 @@                 parameter="AuditTexture" />              </menu_item_check>              <menu_item_check -             label="Texture Atlas" +             label="Texture Atlas (experimental)"               name="Texture Atlas">                <menu_item_check.on_check                 function="CheckControl" @@ -2300,7 +2400,9 @@                   function="ToggleControl"                   parameter="AgentPause" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_call               label="Enable Message Log"               name="Enable Message Log"> @@ -2313,7 +2415,9 @@                  <menu_item_call.on_click                   function="Advanced.DisableMessageLog" />              </menu_item_call> +              <menu_item_separator/> +              <menu_item_check               label="Velocity Interpolate Objects"               name="Velocity Interpolate Objects"> @@ -2334,7 +2438,9 @@                   function="ToggleControl"                   parameter="PingInterpolate" />              </menu_item_check> +              <menu_item_separator/> +              <menu_item_call               label="Drop a Packet"               name="Drop a Packet" @@ -2522,6 +2628,7 @@              </menu_item_check>              <menu_item_separator /> +              <menu_item_check               label="Debug SelectMgr"               name="Debug SelectMgr"> @@ -2867,7 +2974,9 @@                   function="Advanced.DumpAvatarLocalTextures" />              </menu_item_call>          </menu> +          <menu_item_separator/> +          <menu_item_check           label="HTTP Textures"           name="HTTP Textures"> @@ -2904,7 +3013,9 @@               function="ToggleControl"               parameter="ShowConsoleWindow" />          </menu_item_check> +          <menu_item_separator/> +          <menu_item_check           label="Show Admin Menu"           name="View Admin Options"> @@ -3239,7 +3350,9 @@                       name="PublicIssueTrackerHelp_url"                       parameter="WebLaunchPublicIssueHelp,http://wiki.secondlife.com/wiki/Issue_tracker" />                  </menu_item_call> +                  <menu_item_separator/> +                  <menu_item_call                   label="Bug Reporting 101"                   name="Bug Reporing 101"> diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml index 266fd6cb5e..d046fed2e9 100644 --- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml +++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml @@ -155,7 +155,7 @@  	 visiblity_control="ShowAdvancedGraphicsSettings"       border="false"  	 follows="top|left" -     height="260" +     height="283"       label="CustomGraphics"       layout="topleft"       left="5" @@ -211,119 +211,112 @@  			<check_box.commit_callback  			function="Pref.VertexShaderEnable" />  		</check_box> -		<check_box -		control_name="RenderWaterReflections" +<!-- DISABLED UNTIL WE REALLY WANT TO SUPPORT THIS +    <check_box +		control_name="RenderDeferred"  		height="16"  		initial_value="true" -		label="Water reflections" +		label="Lighting and Shadows"  		layout="topleft"  		left_delta="0" -		name="Reflections" +		name="UseLightShaders"  		top_pad="1"  		width="256"> -			<check_box.commit_callback +      <check_box.commit_callback  			function="Pref.VertexShaderEnable" /> -		</check_box> -		<text -		type="string" -		length="1" -		follows="left|top" -		height="12" -		layout="topleft" -		left_delta="0" -		name="ReflectionDetailText" -		top_pad="7" -		width="128"> -			Reflection detail: -		</text> -		<radio_group -		control_name="RenderReflectionDetail" -		draw_border="false" -		height="70" -		layout="topleft" -		left_delta="-2" -		name="ReflectionDetailRadio" -		top_pad="3" -		width="321"> -			<radio_item -			height="16" -			label="Terrain and trees" -			layout="topleft" -			left="3" -			name="0" -			top="3" -			width="315" /> -			<radio_item -			height="16" -			label="All static objects" -			layout="topleft" -			left_delta="0" -			name="1" -			top_delta="16" -			width="315" /> -			<radio_item -			height="16" -			label="All avatars and objects" -			layout="topleft" -			left_delta="0" -			name="2" -			top_delta="16" -			width="315" /> -			<radio_item -			height="16" -			label="Everything" -			layout="topleft" -			left_delta="0" -			name="3" -			top_delta="16" -			width="315" /> -		</radio_group> -		<text -		type="string" -		length="1" -		follows="left|top" -		height="12" -		layout="topleft" -		left_delta="2" -		name="AvatarRenderingText" -		top_pad="5" -		width="158"> -			Avatar rendering: -		</text> -		<check_box -		control_name="RenderUseImpostors" +    </check_box> +    <check_box +		control_name="RenderDeferredSSAO"  		height="16"  		initial_value="true" -		label="Avatar impostors" +		label="Ambient Occlusion"  		layout="topleft"  		left_delta="0" -		name="AvatarImpostors" -		top_pad="7" -		width="256" /> -		<check_box -		control_name="RenderAvatarVP" -		height="16" -		initial_value="true" -		label="Hardware skinning" -		layout="topleft" -		left_delta="0" -		name="AvatarVertexProgram" +		name="UseSSAO"  		top_pad="1"  		width="256"> -			<check_box.commit_callback +      <check_box.commit_callback  			function="Pref.VertexShaderEnable" /> -		</check_box> -		<check_box -		control_name="RenderAvatarCloth" -		height="16" -		initial_value="true" -		label="Avatar cloth" -		layout="topleft" -		left_delta="0" -		name="AvatarCloth" -		top_pad="1" -		width="256" /> +    </check_box> +     <text +    type="string" +    length="1" +    top_pad="8" +    follows="top|left" +    height="23" +    width="110" +    word_wrap="true" +    layout="topleft" +    left="10" +    name="shadows_label"> +        Shadows: +      </text> +      <combo_box +      control_name="RenderShadowDetail" +      height="23" +      layout="topleft" +      left="10" +      top_pad="0"  +      name="ShadowDetail" +      width="150"> +        <combo_box.item +        label="None" +        name="0" +        value="0"/> +        <combo_box.item +        label="Sun/Moon" +        name="1" +        value="1"/> +        <combo_box.item +        label="Sun/Moon + Projectors" +        name="2" +        value="2"/> +      </combo_box> +--> +      <text +  type="string" +  length="1" +  top_pad="8" +  follows="top|left" +  height="23" +  width="110" +  word_wrap="true" +  layout="topleft" +  left="10" +  name="reflection_label"> +        Water Reflections: +      </text> +      <combo_box +      control_name="RenderReflectionDetail" +      height="23" +      layout="topleft" +      left_="10" +      top_pad ="0" +      name="Reflections" +      width="150"> +        <combo_box.item +        label="Minimal" +        name="0" +        value="0"/> +        <combo_box.item +        label="Terrain and trees" +        name="1" +        value="1"/> +        <combo_box.item +        label="All static objects" +        name="2" +        value="2"/> +        <combo_box.item +        label="All avatars and objects" +        name="3" +        value="3"/> +        <combo_box.item +        label="Everything" +        name="4" +        value="4"/> +      </combo_box> +      		<slider  		control_name="RenderFarClip"  		decimal_digits="0" @@ -627,49 +620,58 @@          width="128">             Low          </text> -        <text -        type="string" -        length="1" -        follows="left|top" -        height="12" -        layout="topleft" -        left="200" -        name="LightingDetailText" +      <text +      type="string" +      length="1" +      follows="left|top" +      height="12" +      layout="topleft" +      left_delta="-260" +      name="AvatarRenderingText"          top_pad="18" -        width="140"> -           Lighting detail: -        </text> -        <radio_group -        control_name="RenderLightingDetail" -        draw_border="false" -        height="38" -        layout="topleft" -        name="LightingDetailRadio" -        top_pad="5" -        width="200"> -           <radio_item -            height="16" -            label="Sun and moon only" -            layout="topleft" -            name="SunMoon" -            value="0" -            top="3" -            width="156" /> -           <radio_item -            height="16" -            label="Nearby local lights" -            layout="topleft" -            name="LocalLights" -            value="1" -            top_delta="16" -            width="156" /> -        </radio_group> +      width="128"> +        Avatar rendering: +      </text> +      <check_box +      control_name="RenderUseImpostors" +      height="16" +      initial_value="true" +      label="Avatar impostors" +      layout="topleft" +      left_delta="0" +      name="AvatarImpostors" +      top_pad="7" +      width="256" /> +      <check_box +      control_name="RenderAvatarVP" +      height="16" +      initial_value="true" +      label="Hardware skinning" +      layout="topleft" +      left_delta="0" +      name="AvatarVertexProgram" +      top_pad="1" +      width="256"> +        <check_box.commit_callback +        function="Pref.VertexShaderEnable" /> +      </check_box> +      <check_box +      control_name="RenderAvatarCloth" +      height="16" +      initial_value="true" +      label="Avatar cloth" +      layout="topleft" +      left_delta="0" +      name="AvatarCloth" +      top_pad="1" +      width="256" />          <text          type="string"          length="1"          follows="left|top"          height="12"          layout="topleft" +        left="358"          left_pad="-30"          name="TerrainDetailText"          top="226" @@ -699,7 +701,7 @@              name="2"              top_delta="16"              width="50" /> -        </radio_group> +        </radio_group> -->  	</panel>          <button | 
