diff options
Diffstat (limited to 'indra')
| -rw-r--r-- | indra/llrender/llrendertarget.cpp | 95 | ||||
| -rw-r--r-- | indra/llrender/llrendertarget.h | 24 | ||||
| -rw-r--r-- | indra/newview/llface.cpp | 12 | ||||
| -rw-r--r-- | indra/newview/llflexibleobject.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 435 | 
5 files changed, 325 insertions, 249 deletions
| diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index 867c174f4b..ccbd027f30 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -50,7 +50,7 @@ void check_framebuffer_status()  	}  } -BOOL LLRenderTarget::sUseFBO = FALSE; +bool LLRenderTarget::sUseFBO = false;  LLRenderTarget::LLRenderTarget() :  	mResX(0), @@ -59,8 +59,8 @@ LLRenderTarget::LLRenderTarget() :  	mFBO(0),  	mDepth(0),  	mStencil(0), -	mUseDepth(FALSE), -	mRenderDepth(FALSE), +	mUseDepth(false), +	mRenderDepth(false),  	mUsage(LLTexUnit::TT_TEXTURE),  	mSamples(0),  	mSampleBuffer(NULL) @@ -78,7 +78,7 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)  	mSampleBuffer = buffer;  } -void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo) +void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)  {  	stop_glerror();  	mResX = resx; @@ -209,6 +209,16 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)  		llerrs << "Cannot share depth buffer between non FBO render targets." << llendl;  	} +	if (target.mDepth) +	{ +		llerrs << "Attempting to override existing depth buffer.  Detach existing buffer first." << llendl; +	} + +	if (target.mUseDepth) +	{ +		llerrs << "Attempting to override existing shared depth buffer. Detach existing buffer first." << llendl; +	} +  	if (mDepth)  	{  		stop_glerror(); @@ -221,37 +231,21 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)  			stop_glerror();  			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);			  			stop_glerror(); +			target.mStencil = true;  		}  		else  		{  			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);  			stop_glerror(); -			if (mStencil) -			{ -				glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0); -				stop_glerror(); -			}  		}  		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); -		target.mUseDepth = TRUE; +		target.mUseDepth = true;  	}  }  void LLRenderTarget::release()  { -	if (mFBO) -	{ -		glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); -		mFBO = 0; -	} - -	if (mTex.size() > 0) -	{ -		LLImageGL::deleteTextures(mTex.size(), &mTex[0]); -		mTex.clear(); -	} -  	if (mDepth)  	{  		if (mStencil) @@ -266,6 +260,33 @@ void LLRenderTarget::release()  		}  		mDepth = 0;  	} +	else if (mUseDepth && mFBO) +	{ //detach shared depth buffer +		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO); +		if (mStencil) +		{ //attached as a renderbuffer +			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); +			glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); +			mStencil = false; +		} +		else +		{ //attached as a texture +			glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), 0, 0); +		} +		mUseDepth = false; +	} + +	if (mFBO) +	{ +		glDeleteFramebuffersEXT(1, (GLuint *) &mFBO); +		mFBO = 0; +	} + +	if (mTex.size() > 0) +	{ +		LLImageGL::deleteTextures(mTex.size(), &mTex[0]); +		mTex.clear(); +	}  	mSampleBuffer = NULL;  	sBoundTarget = NULL; @@ -349,19 +370,19 @@ U32 LLRenderTarget::getTexture(U32 attachment) const  	{  		llerrs << "Invalid attachment index." << llendl;  	} +	if (mTex.empty()) +	{ +		return 0; +	}  	return mTex[attachment];  }  void LLRenderTarget::bindTexture(U32 index, S32 channel)  { -	if (index > mTex.size()-1) -	{ -		llerrs << "Invalid attachment index." << llendl; -	} -	gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]); +	gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));  } -void LLRenderTarget::flush(BOOL fetch_depth) +void LLRenderTarget::flush(bool fetch_depth)  {  	gGL.flush();  	if (!mFBO) @@ -497,9 +518,9 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0  	}  } -BOOL LLRenderTarget::isComplete() const +bool LLRenderTarget::isComplete() const  { -	return (!mTex.empty() || mDepth) ? TRUE : FALSE; +	return (!mTex.empty() || mDepth) ? true : false;  }  void LLRenderTarget::getViewport(S32* viewport) @@ -520,10 +541,10 @@ LLMultisampleBuffer::LLMultisampleBuffer()  LLMultisampleBuffer::~LLMultisampleBuffer()  { -	releaseSampleBuffer(); +	release();  } -void LLMultisampleBuffer::releaseSampleBuffer() +void LLMultisampleBuffer::release()  {  	if (mFBO)  	{ @@ -573,12 +594,12 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)  	sBoundTarget = this;  } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil,  LLTexUnit::eTextureType usage, BOOL use_fbo ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil,  LLTexUnit::eTextureType usage, bool use_fbo )  {  	allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);  } -void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil,  LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples ) +void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil,  LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )  {  	stop_glerror();  	mResX = resx; @@ -588,7 +609,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth  	mUseDepth = depth;  	mStencil = stencil; -	releaseSampleBuffer(); +	release();  	if (!gGLManager.mHasFramebufferMultisample)  	{ @@ -625,11 +646,9 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth  			{  				glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);			  			} -			glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);  		} -		 +	  		stop_glerror(); -  		glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);  		stop_glerror();  	} diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h index ae8613d9be..12dd1c8b90 100644 --- a/indra/llrender/llrendertarget.h +++ b/indra/llrender/llrendertarget.h @@ -63,7 +63,7 @@ class LLRenderTarget  {  public:  	//whether or not to use FBO implementation -	static BOOL sUseFBO;  +	static bool sUseFBO;   	LLRenderTarget();  	virtual ~LLRenderTarget(); @@ -71,7 +71,7 @@ public:  	//allocate resources for rendering  	//must be called before use  	//multiple calls will release previously allocated resources -	void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE); +	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);  	//provide this render target with a multisample resource.  	void setSampleBuffer(LLMultisampleBuffer* buffer); @@ -88,7 +88,7 @@ public:  	//free any allocated resources  	//safe to call redundantly -	void release(); +	virtual void release();  	//bind target for rendering  	//applies appropriate viewport @@ -115,7 +115,7 @@ public:  	U32 getTexture(U32 attachment = 0) const;  	U32 getDepth(void) const { return mDepth; } -	BOOL hasStencil() const { return mStencil; } +	bool hasStencil() const { return mStencil; }  	void bindTexture(U32 index, S32 channel); @@ -125,7 +125,7 @@ public:  	// call bindTarget once, do all your rendering, call flush once  	// if fetch_depth is TRUE, every effort will be made to copy the depth buffer into   	// the current depth texture.  A depth texture will be allocated if needed. -	void flush(BOOL fetch_depth = FALSE); +	void flush(bool fetch_depth = FALSE);  	void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,  						S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter); @@ -136,7 +136,7 @@ public:  	//Returns TRUE if target is ready to be rendered into.  	//That is, if the target has been allocated with at least  	//one renderable attachment (i.e. color buffer, depth buffer). -	BOOL isComplete() const; +	bool isComplete() const;  	static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; } @@ -147,9 +147,9 @@ protected:  	std::vector<U32> mTex;  	U32 mFBO;  	U32 mDepth; -	BOOL mStencil; -	BOOL mUseDepth; -	BOOL mRenderDepth; +	bool mStencil; +	bool mUseDepth; +	bool mRenderDepth;  	LLTexUnit::eTextureType mUsage;  	U32 mSamples;  	LLMultisampleBuffer* mSampleBuffer; @@ -164,12 +164,12 @@ public:  	LLMultisampleBuffer();  	virtual ~LLMultisampleBuffer(); -	void releaseSampleBuffer(); +	virtual void release();  	virtual void bindTarget();  	void bindTarget(LLRenderTarget* ref); -	virtual void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo); -	void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples); +	virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo); +	void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);  	virtual void addColorAttachment(U32 color_fmt);  	virtual void allocateDepth();  }; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index e862d91aca..4de61964c7 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1658,12 +1658,16 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,  	{  		LLVector4a src; -		src.splat(reinterpret_cast<F32&>(color.mAll)); +		U32 vec[4]; +		vec[0] = vec[1] = vec[2] = vec[3] = color.mAll; +		 +		src.loadua((F32*) vec); -		F32* dst = (F32*) colors.get(); -		for (S32 i = 0; i < num_vertices; i+=4) +		LLVector4a* dst = (LLVector4a*) colors.get(); +		S32 num_vecs = num_vertices/4; +		for (S32 i = 0; i < num_vecs; i++)  		{	 -			LLVector4a::copy4a(dst+i, (F32*) &src); +			dst[i] = src;  		}  	} diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index b7f255e052..689fa72958 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -316,11 +316,13 @@ BOOL LLVolumeImplFlexible::doIdleUpdate(LLAgent &agent, LLWorld &world, const F6  		return FALSE; // (we are not initialized or updated)  	} -	if (force_update) +	bool visible = mVO->mDrawable->isVisible(); + +	if (force_update && visible)  	{  		gPipeline.markRebuild(mVO->mDrawable, LLDrawable::REBUILD_POSITION, FALSE);  	} -	else if	(mVO->mDrawable->isVisible() && +	else if	(visible &&  		!mVO->mDrawable->isState(LLDrawable::IN_REBUILD_Q1) &&  		mVO->getPixelArea() > 256.f)  	{ @@ -364,7 +366,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()  	LLFastTimer ftm(FTM_DO_FLEXIBLE_UPDATE);  	LLVolume* volume = mVO->getVolume();  	LLPath *path = &volume->getPath(); -	if (mSimulateRes == 0) +	if (mSimulateRes == 0 && mVO->mDrawable->isVisible())  	{  		mVO->markForUpdate(TRUE);  		if (!doIdleUpdate(gAgent, *LLWorld::getInstance(), 0.0)) diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b6ff1f8e57..c154fe7b75 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -577,6 +577,10 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	if (LLPipeline::sRenderDeferred)  	{ +		S32 shadow_detail = gSavedSettings.getS32("RenderShadowDetail"); +		BOOL ssao = gSavedSettings.getBOOL("RenderDeferredSSAO"); +		bool gi = LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_DEFERRED); +  		samples = llmin(samples, (U32) 8); //cap multisample buffers to 8 samples when rendering deferred  		//allocate deferred rendering color buffers  		mDeferredScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE); @@ -588,14 +592,40 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		mScreen.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		  		mEdgeMap.allocate(resX, resY, GL_ALPHA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE); -		for (U32 i = 0; i < 3; i++) +		if (shadow_detail > 0 || ssao) +		{ //only need mDeferredLight[0] for shadows OR ssao +			mDeferredLight[0].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +		} +		else  		{ -			mDeferredLight[i].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[0].release();  		} -		for (U32 i = 0; i < 2; i++) +		if (ssao) +		{ //only need mDeferredLight[1] for ssao +			mDeferredLight[1].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +		} +		else  		{ -			mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			mDeferredLight[1].release(); +		} + +		if (gi) +		{ //only need mDeferredLight[2] and mGIMapPost for gi +			mDeferredLight[2].allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			for (U32 i = 0; i < 2; i++) +			{ +				mGIMapPost[i].allocate(resX,resY, GL_RGB, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			} +		} +		else +		{ +			mDeferredLight[2].release(); +		 +			for (U32 i = 0; i < 2; i++) +			{ +				mGIMapPost[i].release(); +			}  		}  		F32 scale = gSavedSettings.getF32("RenderShadowResolutionScale"); @@ -603,18 +633,37 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		//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++) +		if (shadow_detail > 0) +		{ //allocate 4 sun shadow maps +			for (U32 i = 0; i < 4; i++) +			{ +				mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			} +		} +		else  		{ -			mShadow[i].allocate(U32(resX*scale),U32(resY*scale), shadow_fmt, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE); +			for (U32 i = 0; i < 4; i++) +			{ +				mShadow[i].release(); +			}  		} -  		U32 width = nhpo2(U32(resX*scale))/2;  		U32 height = width; -		for (U32 i = 4; i < 6; i++) +		if (shadow_detail > 1) +		{ //allocate two spot shadow maps +			for (U32 i = 4; i < 6; i++) +			{ +				mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); +			} +		} +		else  		{ -			mShadow[i].allocate(width, height, shadow_fmt, TRUE, FALSE); +			for (U32 i = 4; i < 6; i++) +			{ +				mShadow[i].release(); +			}  		}  		width = nhpo2(resX)/2; @@ -623,6 +672,24 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  	}  	else  	{ +		for (U32 i = 0; i < 3; i++) +		{  +			mDeferredLight[i].release(); +		} +		for (U32 i = 0; i < 2; i++) +		{ +			mGIMapPost[i].release(); +		} +		for (U32 i = 0; i < 6; i++) +		{ +			mShadow[i].release(); +		} +		mScreen.release(); +		mDeferredScreen.release(); //make sure to release any render targets that share a depth buffer with mDeferredScreen first +		mDeferredDepth.release(); +		mEdgeMap.release(); +		mLuminanceMap.release(); +		  		mScreen.allocate(resX, resY, GL_RGBA, TRUE, TRUE, LLTexUnit::TT_RECT_TEXTURE, FALSE);		  	} @@ -641,13 +708,20 @@ void LLPipeline::allocateScreenBuffer(U32 resX, U32 resY)  		stop_glerror();  	} +	else +	{ +		mSampleBuffer.release(); +	}  	if (LLPipeline::sRenderDeferred)  	{ //share depth buffer between deferred targets  		mDeferredScreen.shareDepthBuffer(mScreen);  		for (U32 i = 0; i < 3; i++)  		{ //share stencil buffer with screen space lightmap to stencil out sky -			mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); +			if (mDeferredLight[i].getTexture(0)) +			{ +				mDeferredScreen.shareDepthBuffer(mDeferredLight[i]); +			}  		}  	} @@ -698,7 +772,7 @@ void LLPipeline::releaseGLBuffers()  	mScreen.release();  	mPhysicsDisplay.release();  	mUIScreen.release(); -	mSampleBuffer.releaseSampleBuffer(); +	mSampleBuffer.release();  	mDeferredScreen.release();  	mDeferredDepth.release();  	for (U32 i = 0; i < 3; i++) @@ -6749,16 +6823,15 @@ void LLPipeline::renderDeferredLighting()  			glTexCoord4f(tc.v[0], tc.v[1], tc.v[2], 0);  		} -			glPushMatrix(); -			glLoadIdentity(); -			glMatrixMode(GL_PROJECTION); -			glPushMatrix(); -			glLoadIdentity(); - -			mDeferredLight[0].bindTarget(); +		glPushMatrix(); +		glLoadIdentity(); +		glMatrixMode(GL_PROJECTION); +		glPushMatrix(); +		glLoadIdentity();  		if (gSavedSettings.getBOOL("RenderDeferredSSAO") || gSavedSettings.getS32("RenderShadowDetail") > 0)  		{ +			mDeferredLight[0].bindTarget();  			{ //paint shadow/SSAO light map (direct lighting lightmap)  				LLFastTimer ftm(FTM_SUN_SHADOW);  				bindDeferredShader(gDeferredSunProgram, 0); @@ -6799,16 +6872,9 @@ void LLPipeline::renderDeferredLighting()  				unbindDeferredShader(gDeferredSunProgram);  			} -		} -			else -			{ -			glClearColor(1,1,1,1); -				mDeferredLight[0].clear(GL_COLOR_BUFFER_BIT); -			glClearColor(0,0,0,0); -			} -  			mDeferredLight[0].flush(); - +		} +		  		{ //global illumination specific block (still experimental)  			if (gSavedSettings.getBOOL("RenderDeferredBlurLight") &&  			    gSavedSettings.getBOOL("RenderDeferredGI")) @@ -6914,74 +6980,74 @@ void LLPipeline::renderDeferredLighting()  		}  		if (gSavedSettings.getBOOL("RenderDeferredSSAO")) -			{ //soften direct lighting lightmap -				LLFastTimer ftm(FTM_SOFTEN_SHADOW); -				//blur lightmap -				mDeferredLight[1].bindTarget(); +		{ //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", 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", 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();  			} +			mDeferredLight[0].flush(); +			unbindDeferredShader(gDeferredBlurLightProgram); +		} -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); -			glMatrixMode(GL_MODELVIEW); -			stop_glerror(); -			glPopMatrix(); -			stop_glerror(); +		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(), @@ -9014,152 +9080,137 @@ void LLPipeline::generateSunShadow(LLCamera& camera)  	//hack to disable projector shadows  -	static bool clear = true;  	bool gen_shadow = gSavedSettings.getS32("RenderShadowDetail") > 1;  	if (gen_shadow)  	{ -		clear = true; -	F32 fade_amt = gFrameIntervalSeconds * llmax(LLViewerCamera::getInstance()->getVelocityStat()->getCurrentPerSec(), 1.f); +		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; +		//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]; +			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); -		mShadow[i+4].bindTarget(); -		mShadow[i+4].getViewport(gGLViewport); +			stop_glerror(); -		static LLCullResult result[2]; +			mShadow[i+4].bindTarget(); +			mShadow[i+4].getViewport(gGLViewport); -		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; +			static LLCullResult result[2]; -		renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); +			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_SHADOW0+i+4; -		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(); -			} -		} +			renderShadow(view[i+4], proj[i+4], shadow_cam, result[i], FALSE, FALSE); + +			mShadow[i+4].flush(); + 		}  	}  	if (!gSavedSettings.getBOOL("CameraOffset")) | 
