diff options
| author | Dave Houlton <euclid@lindenlab.com> | 2020-07-24 21:51:34 +0000 | 
|---|---|---|
| committer | Dave Houlton <euclid@lindenlab.com> | 2020-07-24 21:51:34 +0000 | 
| commit | cd0372b68957f97deb0c6ad7a40bc9990e8251a8 (patch) | |
| tree | 2e640bc6c61e5824be99feaad3c0ca0229d5f432 | |
| parent | 6fbf39f9b319106e39f80b8641acaba122d02e0a (diff) | |
| parent | fb45ca014c812f7166c750da112984fd8dd88bc8 (diff) | |
Merged in euclid-13406-lmr (pull request #215)
SL-13406, glow disable no longer breaks rendering
Approved-by: Michael Pohoreski
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 111 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 1143 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 2 | 
3 files changed, 602 insertions, 654 deletions
| diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 2b1f4b138f..95f8785c90 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -705,9 +705,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		LLGLState::checkTextureChannels();  		LLGLState::checkClientArrays(); -		BOOL to_texture = gPipeline.canUseVertexShaders() && -						LLPipeline::sRenderGlow; -  		LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");  		{  @@ -914,31 +911,28 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  		stop_glerror(); -		if (to_texture) -		{ -			gGL.setColorMask(true, true); -					 -			if (LLPipeline::sRenderDeferred) -			{ -				gPipeline.mDeferredScreen.bindTarget(); -				glClearColor(1,0,1,1); -				gPipeline.mDeferredScreen.clear(); -			} -			else -			{ -				gPipeline.mScreen.bindTarget(); -				if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) -				{ -					const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); -					glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); -				} -				gPipeline.mScreen.clear(); -			} -			 -			gGL.setColorMask(true, false); -		} -		 -		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom"); +        gGL.setColorMask(true, true); + +        if (LLPipeline::sRenderDeferred) +        { +            gPipeline.mDeferredScreen.bindTarget(); +            glClearColor(1, 0, 1, 1); +            gPipeline.mDeferredScreen.clear(); +        } +        else +        { +            gPipeline.mScreen.bindTarget(); +            if (LLPipeline::sUnderWaterRender && !gPipeline.canUseWindLightShaders()) +            { +                const LLColor4 &col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor(); +                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f); +            } +            gPipeline.mScreen.clear(); +        } + +        gGL.setColorMask(true, false); + +        LLAppViewer::instance()->pingMainloopTimeout("Display:RenderGeom");  		if (!(LLAppViewer::instance()->logoutRequestSent() && LLAppViewer::instance()->hasSavedFinalSnapshot())  				&& !gRestoreGL) @@ -1000,38 +994,20 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)  			}  		} -		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush");		 -		 -		if (to_texture) -		{ -			if (LLPipeline::sRenderDeferred) -			{ -				gPipeline.mDeferredScreen.flush(); -				if(LLRenderTarget::sUseFBO) -				{ -					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(),  -															  gPipeline.mDeferredScreen.getHeight(), 0, 0,  -															  gPipeline.mDeferredScreen.getWidth(),  -															  gPipeline.mDeferredScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -				} -			} -			else -			{ -				gPipeline.mScreen.flush(); -				if(LLRenderTarget::sUseFBO) -				{				 -					LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(),  -															  gPipeline.mScreen.getHeight(), 0, 0,  -															  gPipeline.mScreen.getWidth(),  -															  gPipeline.mScreen.getHeight(),  -															  GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, GL_NEAREST); -				} -			} -		} +		LLAppViewer::instance()->pingMainloopTimeout("Display:RenderFlush"); -		if (LLPipeline::sRenderDeferred) -		{ +        LLRenderTarget &rt = (gPipeline.sRenderDeferred ? gPipeline.mDeferredScreen : gPipeline.mScreen); +        rt.flush(); + +        if (rt.sUseFBO) +        { +            LLRenderTarget::copyContentsToFramebuffer(rt, 0, 0, rt.getWidth(), rt.getHeight(), 0, 0, rt.getWidth(), +                                                      rt.getHeight(), GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT, +                                                      GL_NEAREST); +        } + +        if (LLPipeline::sRenderDeferred) +        {  			gPipeline.renderDeferredLighting(&gPipeline.mScreen);  		} @@ -1295,19 +1271,12 @@ void render_ui(F32 zoom_factor, int subfield)  		gGL.popMatrix();  	} -	{ -		BOOL to_texture = gPipeline.canUseVertexShaders() && -							LLPipeline::sRenderGlow; +    // Finalize scene +    gPipeline.renderFinalize(); -		if (to_texture) -		{ -			gPipeline.renderBloom(gSnapshot, zoom_factor, subfield); -		} -		 -		LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); -		render_hud_elements(); -		render_hud_attachments(); -	} +    LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); +    render_hud_elements(); +	render_hud_attachments();  	LLGLSDefault gls_default;  	LLGLSUIDefault gls_ui; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index f3b8ad9008..3f8f7b278f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1049,25 +1049,19 @@ void LLPipeline::updateRenderBump()  	sRenderBump = gSavedSettings.getBOOL("RenderObjectBump");  } -//static +// static  void LLPipeline::updateRenderDeferred()  { -	bool deferred = (bool(RenderDeferred &&  -					 LLRenderTarget::sUseFBO && -					 LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred") &&	  -					 LLPipeline::sRenderBump && -					 RenderAvatarVP && -					 WindLightUseAtmosShaders)) && -					!gUseWireframe; - -	sRenderDeferred = deferred;	 -	if (deferred) -	{ //must render glow when rendering deferred since post effect pass is needed to present any lighting at all -		sRenderGlow = true; -	} +    sRenderDeferred = !gUseWireframe && +                      RenderDeferred && +                      LLRenderTarget::sUseFBO && +                      LLPipeline::sRenderBump && +                      RenderAvatarVP && +                      WindLightUseAtmosShaders && +                      (bool) LLFeatureManager::getInstance()->isFeatureAvailable("RenderDeferred");  } -//static +// static  void LLPipeline::refreshCachedSettings()  {  	LLPipeline::sAutoMaskAlphaDeferred = gSavedSettings.getBOOL("RenderAutoMaskAlphaDeferred"); @@ -1259,24 +1253,20 @@ void LLPipeline::createGLBuffers()  	GLuint resX = gViewerWindow->getWorldViewWidthRaw();  	GLuint resY = gViewerWindow->getWorldViewHeightRaw(); -	 -	if (LLPipeline::sRenderGlow) -	{ //screen space glow buffers -		const U32 glow_res = llmax(1,  -			llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); -		for (U32 i = 0; i < 3; i++) -		{ -			mGlow[i].allocate(512,glow_res,GL_RGBA,FALSE,FALSE); -		} +    // allocate screen space glow buffers +    const U32 glow_res = llmax(1, llmin(512, 1 << gSavedSettings.getS32("RenderGlowResolutionPow"))); +    for (U32 i = 0; i < 3; i++) +    { +        mGlow[i].allocate(512, glow_res, GL_RGBA, FALSE, FALSE); +    } -		allocateScreenBuffer(resX,resY); -		mScreenWidth = 0; -		mScreenHeight = 0; -	} -	 -	if (sRenderDeferred) -	{ +    allocateScreenBuffer(resX, resY); +    mScreenWidth = 0; +    mScreenHeight = 0; + +    if (sRenderDeferred) +    {  		if (!mNoiseMap)  		{  			const U32 noiseRes = 128; @@ -7544,641 +7534,630 @@ void LLPipeline::bindScreenToTexture()  static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); -void LLPipeline::renderBloom(bool for_snapshot, F32 zoom_factor, int subfield) +void LLPipeline::renderFinalize()  { -	if (!(gPipeline.canUseVertexShaders() && -		sRenderGlow)) -	{ -		return; -	} +    LLVertexBuffer::unbind(); +    LLGLState::checkStates(); +    LLGLState::checkTextureChannels(); -	LLVertexBuffer::unbind(); -	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); +    assertInitialized(); -	assertInitialized(); +    if (gUseWireframe) +    { +        glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +    } -	if (gUseWireframe) -	{ -		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -	} +    LLVector2 tc1(0, 0); +    LLVector2 tc2((F32) mScreen.getWidth() * 2, (F32) mScreen.getHeight() * 2); -	LLVector2 tc1(0,0); -	LLVector2 tc2((F32) mScreen.getWidth()*2, -				  (F32) mScreen.getHeight()*2); +    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +    gGL.color4f(1, 1, 1, 1); +    LLGLDepthTest depth(GL_FALSE); +    LLGLDisable blend(GL_BLEND); +    LLGLDisable cull(GL_CULL_FACE); -	LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); -	gGL.color4f(1,1,1,1); -	LLGLDepthTest depth(GL_FALSE); -	LLGLDisable blend(GL_BLEND); -	LLGLDisable cull(GL_CULL_FACE); -	 -	enableLightsFullbright(); +    enableLightsFullbright(); -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.pushMatrix(); -	gGL.loadIdentity(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.pushMatrix(); -	gGL.loadIdentity(); +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.pushMatrix(); +    gGL.loadIdentity(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.pushMatrix(); +    gGL.loadIdentity(); -	LLGLDisable test(GL_ALPHA_TEST); +    LLGLDisable test(GL_ALPHA_TEST); -	gGL.setColorMask(true, true); -	glClearColor(0,0,0,0); -		 -	{ -		{ -			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -			mGlow[2].bindTarget(); -			mGlow[2].clear(); -		} -		 -		gGlowExtractProgram.bind(); -		F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); -		F32 maxAlpha = RenderGlowMaxExtractAlpha;		 -		F32 warmthAmount = RenderGlowWarmthAmount;	 -		LLVector3 lumWeights = RenderGlowLumWeights; -		LLVector3 warmthWeights = RenderGlowWarmthWeights; - - -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); -		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], lumWeights.mV[2]); -		gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], warmthWeights.mV[2]); -		gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); -		LLGLEnable blend_on(GL_BLEND); -		LLGLEnable test(GL_ALPHA_TEST); -		 -		gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -		 -		mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); -		 -		gGL.color4f(1,1,1,1); -		gPipeline.enableLightsFullbright(); -		gGL.begin(LLRender::TRIANGLE_STRIP); -		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -		gGL.vertex2f(-1,-1); -		 -		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -		gGL.vertex2f(-1,3); -		 -		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -		gGL.vertex2f(3,-1); -		 -		gGL.end(); -		 -		gGL.getTexUnit(0)->unbind(mScreen.getUsage()); +    gGL.setColorMask(true, true); +    glClearColor(0, 0, 0, 0); -		mGlow[2].flush(); -	} +    if (sRenderGlow) +    { +        { +            LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); +            mGlow[2].bindTarget(); +            mGlow[2].clear(); +        } -	tc1.setVec(0,0); -	tc2.setVec(2,2); +        gGlowExtractProgram.bind(); +        F32 minLum = llmax((F32) RenderGlowMinLuminance, 0.0f); +        F32 maxAlpha = RenderGlowMaxExtractAlpha; +        F32 warmthAmount = RenderGlowWarmthAmount; +        LLVector3 lumWeights = RenderGlowLumWeights; +        LLVector3 warmthWeights = RenderGlowWarmthWeights; -	// power of two between 1 and 1024 -	U32 glowResPow = RenderGlowResolutionPow; -	const U32 glow_res = llmax(1,  -		llmin(1024, 1 << glowResPow)); +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MIN_LUMINANCE, minLum); +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_MAX_EXTRACT_ALPHA, maxAlpha); +        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_LUM_WEIGHTS, lumWeights.mV[0], lumWeights.mV[1], +                                      lumWeights.mV[2]); +        gGlowExtractProgram.uniform3f(LLShaderMgr::GLOW_WARMTH_WEIGHTS, warmthWeights.mV[0], warmthWeights.mV[1], +                                      warmthWeights.mV[2]); +        gGlowExtractProgram.uniform1f(LLShaderMgr::GLOW_WARMTH_AMOUNT, warmthAmount); +        LLGLEnable blend_on(GL_BLEND); +        LLGLEnable test(GL_ALPHA_TEST); -	S32 kernel = RenderGlowIterations*2; -	F32 delta = RenderGlowWidth / glow_res; -	// Use half the glow width if we have the res set to less than 9 so that it looks -	// almost the same in either case. -	if (glowResPow < 9) -	{ -		delta *= 0.5f; -	} -	F32 strength = RenderGlowStrength; +        gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -	gGlowProgram.bind(); -	gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); +        mScreen.bindTexture(0, 0, LLTexUnit::TFO_POINT); -	for (S32 i = 0; i < kernel; i++) -	{ -		{ -			LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -			mGlow[i%2].bindTarget(); -			mGlow[i%2].clear(); -		} -			 -		if (i == 0) -		{ -			gGL.getTexUnit(0)->bind(&mGlow[2]); -		} -		else -		{ -			gGL.getTexUnit(0)->bind(&mGlow[(i-1)%2]); -		} +        gGL.color4f(1, 1, 1, 1); +        gPipeline.enableLightsFullbright(); +        gGL.begin(LLRender::TRIANGLE_STRIP); +        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +        gGL.vertex2f(-1, -1); -		if (i%2 == 0) -		{ -			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); -		} -		else -		{ -			gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); -		} +        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +        gGL.vertex2f(-1, 3); -		gGL.begin(LLRender::TRIANGLE_STRIP); -		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -		gGL.vertex2f(-1,-1); -		 -		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -		gGL.vertex2f(-1,3); -		 -		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -		gGL.vertex2f(3,-1); -		 -		gGL.end(); -		 -		mGlow[i%2].flush(); -	} +        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +        gGL.vertex2f(3, -1); -	gGlowProgram.unbind(); +        gGL.end(); -	/*if (LLRenderTarget::sUseFBO) -	{ -		LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); -		glBindFramebuffer(GL_FRAMEBUFFER, 0); -	}*/ +        gGL.getTexUnit(0)->unbind(mScreen.getUsage()); -	gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -	gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -	gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -	gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +        mGlow[2].flush(); -	tc2.setVec((F32) mScreen.getWidth(), -			(F32) mScreen.getHeight()); +        tc1.setVec(0, 0); +        tc2.setVec(2, 2); -	gGL.flush(); -	 -	LLVertexBuffer::unbind(); +        // power of two between 1 and 1024 +        U32 glowResPow = RenderGlowResolutionPow; +        const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); -	if (LLPipeline::sRenderDeferred) -	{ +        S32 kernel = RenderGlowIterations * 2; +        F32 delta = RenderGlowWidth / glow_res; +        // Use half the glow width if we have the res set to less than 9 so that it looks +        // almost the same in either case. +        if (glowResPow < 9) +        { +            delta *= 0.5f; +        } +        F32 strength = RenderGlowStrength; -		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && -			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && -							RenderDepthOfField; +        gGlowProgram.bind(); +        gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); +        for (S32 i = 0; i < kernel; i++) +        { +            { +                LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM_FBO); +                mGlow[i % 2].bindTarget(); +                mGlow[i % 2].clear(); +            } -		bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); +            if (i == 0) +            { +                gGL.getTexUnit(0)->bind(&mGlow[2]); +            } +            else +            { +                gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); +            } -		gViewerWindow->setup3DViewport(); -				 -		if (dof_enabled) -		{ -			LLGLSLShader* shader = &gDeferredPostProgram; -			LLGLDisable blend(GL_BLEND); +            if (i % 2 == 0) +            { +                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); +            } +            else +            { +                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); +            } -			//depth of field focal plane calculations -			static F32 current_distance = 16.f; -			static F32 start_distance = 16.f; -			static F32 transition_time = 1.f; +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +            gGL.vertex2f(-1, -1); -			LLVector3 focus_point; +            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +            gGL.vertex2f(-1, 3); -			LLViewerObject* obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); -			if (obj && obj->mDrawable && obj->isSelected()) -			{ //focus on selected media object -				S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); -				if (obj && obj->mDrawable) -				{ -					LLFace* face = obj->mDrawable->getFace(face_idx); -					if (face) -					{ -						focus_point = face->getPositionAgent(); -					} -				} -			} -		 -			if (focus_point.isExactlyZero()) -			{ -				if (LLViewerJoystick::getInstance()->getOverrideCamera()) -				{ //focus on point under cursor -					focus_point.set(gDebugRaycastIntersection.getF32ptr()); -				} -				else if (gAgentCamera.cameraMouselook()) -				{ //focus on point under mouselook crosshairs -					LLVector4a result; -					result.clear(); +            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +            gGL.vertex2f(3, -1); -					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, -													NULL, -													&result); +            gGL.end(); -					focus_point.set(result.getF32ptr()); -				} -				else -				{ -					//focus on alt-zoom target -					LLViewerRegion* region = gAgent.getRegion(); -					if (region) -					{ -						focus_point = LLVector3(gAgentCamera.getFocusGlobal()-region->getOriginGlobal()); -					} -				} -			} +            mGlow[i % 2].flush(); +        } -			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); -			F32 target_distance = 16.f; -			if (!focus_point.isExactlyZero()) -			{ -				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point-eye); -			} +        gGlowProgram.unbind(); +    } +    else // !sRenderGlow, skip the glow ping-pong and just clear the result target +    { +        mGlow[1].bindTarget(); +        mGlow[1].clear(); +        mGlow[1].flush(); +    } -			if (transition_time >= 1.f && -				fabsf(current_distance-target_distance)/current_distance > 0.01f) -			{ //large shift happened, interpolate smoothly to new target distance -				transition_time = 0.f; -				start_distance = current_distance; -			} -			else if (transition_time < 1.f) -			{ //currently in a transition, continue interpolating -				transition_time += 1.f/CameraFocusTransitionTime*gFrameIntervalSeconds.value(); -				transition_time = llmin(transition_time, 1.f); +    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -				F32 t = cosf(transition_time*F_PI+F_PI)*0.5f+0.5f; -				current_distance = start_distance + (target_distance-start_distance)*t; -			} -			else -			{ //small or no change, just snap to target distance -				current_distance = target_distance; -			} +    tc2.setVec((F32) mScreen.getWidth(), (F32) mScreen.getHeight()); -			//convert to mm -			F32 subject_distance = current_distance*1000.f; -			F32 fnumber = CameraFNumber; -			F32 default_focal_length = CameraFocalLength; +    gGL.flush(); -			F32 fov = LLViewerCamera::getInstance()->getView(); -		 -			const F32 default_fov = CameraFieldOfView * F_PI/180.f; -		 -			//F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); -		 -			F32 dv = 2.f*default_focal_length * tanf(default_fov/2.f); +    LLVertexBuffer::unbind(); -			F32 focal_length = dv/(2*tanf(fov/2.f)); -		  -			//F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -	 -			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) -			// where	 N = fnumber -			//			 s2 = dot distance -			//			 s1 = subject distance -			//			 f = focal length -			//	 +    if (LLPipeline::sRenderDeferred) +    { -			F32 blur_constant = focal_length*focal_length/(fnumber*(subject_distance-focal_length)); -			blur_constant /= 1000.f; //convert to meters for shader -			F32 magnification = focal_length/(subject_distance-focal_length); +        bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && +                           (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && +                           RenderDepthOfField; -			{ //build diffuse+bloom+CoF -				mDeferredLight.bindTarget(); -				shader = &gDeferredCoFProgram; +        bool multisample = RenderFSAASamples > 1 && mFXAABuffer.isComplete(); -				bindDeferredShader(*shader); +        gViewerWindow->setup3DViewport(); -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -				if (channel > -1) -				{ -					mScreen.bindTexture(0, channel); -				} +        if (dof_enabled) +        { +            LLGLSLShader *shader = &gDeferredPostProgram; +            LLGLDisable blend(GL_BLEND); -				shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance/1000.f); -				shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); -				shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f/LLDrawable::sCurPixelAngle)); -				shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +            // depth of field focal plane calculations +            static F32 current_distance = 16.f; +            static F32 start_distance = 16.f; +            static F32 transition_time = 1.f; -				gGL.begin(LLRender::TRIANGLE_STRIP); -				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -				gGL.vertex2f(-1,-1); -		 -				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -				gGL.vertex2f(-1,3); -		 -				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -				gGL.vertex2f(3,-1); -		 -				gGL.end(); +            LLVector3 focus_point; -				unbindDeferredShader(*shader); -				mDeferredLight.flush(); -			} +            LLViewerObject *obj = LLViewerMediaFocus::getInstance()->getFocusedObject(); +            if (obj && obj->mDrawable && obj->isSelected()) +            { // focus on selected media object +                S32 face_idx = LLViewerMediaFocus::getInstance()->getFocusedFace(); +                if (obj && obj->mDrawable) +                { +                    LLFace *face = obj->mDrawable->getFace(face_idx); +                    if (face) +                    { +                        focus_point = face->getPositionAgent(); +                    } +                } +            } -			U32 dof_width = (U32) (mScreen.getWidth()*CameraDoFResScale); -			U32 dof_height = (U32) (mScreen.getHeight()*CameraDoFResScale); -			 -			{ //perform DoF sampling at half-res (preserve alpha channel) -				mScreen.bindTarget(); -				glViewport(0,0, dof_width, dof_height); -				gGL.setColorMask(true, false); +            if (focus_point.isExactlyZero()) +            { +                if (LLViewerJoystick::getInstance()->getOverrideCamera()) +                { // focus on point under cursor +                    focus_point.set(gDebugRaycastIntersection.getF32ptr()); +                } +                else if (gAgentCamera.cameraMouselook()) +                { // focus on point under mouselook crosshairs +                    LLVector4a result; +                    result.clear(); -				shader = &gDeferredPostProgram; -				bindDeferredShader(*shader); -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -				if (channel > -1) -				{ -					mDeferredLight.bindTexture(0, channel); -				} +                    gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, NULL, &result); -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -				 -				gGL.begin(LLRender::TRIANGLE_STRIP); -				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -				gGL.vertex2f(-1,-1); -		 -				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -				gGL.vertex2f(-1,3); -		 -				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -				gGL.vertex2f(3,-1); -		 -				gGL.end(); +                    focus_point.set(result.getF32ptr()); +                } +                else +                { +                    // focus on alt-zoom target +                    LLViewerRegion *region = gAgent.getRegion(); +                    if (region) +                    { +                        focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); +                    } +                } +            } -				unbindDeferredShader(*shader); -				mScreen.flush(); -				gGL.setColorMask(true, true); -			} -	 -			{ //combine result based on alpha -				if (multisample) -				{ -					mDeferredLight.bindTarget(); -					glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); -				} -				else -				{ -					gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -					gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -					gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -					gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -					glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); -				} +            LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +            F32 target_distance = 16.f; +            if (!focus_point.isExactlyZero()) +            { +                target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); +            } -				shader = &gDeferredDoFCombineProgram; -				bindDeferredShader(*shader); -				 -				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -				if (channel > -1) -				{ -					mScreen.bindTexture(0, channel); -				} +            if (transition_time >= 1.f && fabsf(current_distance - target_distance) / current_distance > 0.01f) +            { // large shift happened, interpolate smoothly to new target distance +                transition_time = 0.f; +                start_distance = current_distance; +            } +            else if (transition_time < 1.f) +            { // currently in a transition, continue interpolating +                transition_time += 1.f / CameraFocusTransitionTime * gFrameIntervalSeconds.value(); +                transition_time = llmin(transition_time, 1.f); -				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -				shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width-1); -				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height-1); +                F32 t = cosf(transition_time * F_PI + F_PI) * 0.5f + 0.5f; +                current_distance = start_distance + (target_distance - start_distance) * t; +            } +            else +            { // small or no change, just snap to target distance +                current_distance = target_distance; +            } -				gGL.begin(LLRender::TRIANGLE_STRIP); -				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -				gGL.vertex2f(-1,-1); -		 -				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -				gGL.vertex2f(-1,3); -		 -				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -				gGL.vertex2f(3,-1); -		 -				gGL.end(); +            // convert to mm +            F32 subject_distance = current_distance * 1000.f; +            F32 fnumber = CameraFNumber; +            F32 default_focal_length = CameraFocalLength; -				unbindDeferredShader(*shader); +            F32 fov = LLViewerCamera::getInstance()->getView(); -				if (multisample) -				{ -					mDeferredLight.flush(); -				} -			} -		} -		else -		{ -			if (multisample) -			{ -				mDeferredLight.bindTarget(); -			} -			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; -			 -			bindDeferredShader(*shader); -							 -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); -			if (channel > -1) -			{ -				mScreen.bindTexture(0, channel); -			} +            const F32 default_fov = CameraFieldOfView * F_PI / 180.f; -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -			gGL.vertex2f(-1,-1); -		 -			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -			gGL.vertex2f(-1,3); -		 -			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -			gGL.vertex2f(3,-1); -		 -			gGL.end(); +            // F32 aspect_ratio = (F32) mScreen.getWidth()/(F32)mScreen.getHeight(); -			unbindDeferredShader(*shader); +            F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); -			if (multisample) -			{ -				mDeferredLight.flush(); -			} -		} +            F32 focal_length = dv / (2 * tanf(fov / 2.f)); -		if (multisample) -		{ -			//bake out texture2D with RGBL for FXAA shader -			mFXAABuffer.bindTarget(); -			 -			S32 width = mScreen.getWidth(); -			S32 height = mScreen.getHeight(); -			glViewport(0, 0, width, height); +            // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -			LLGLSLShader* shader = &gGlowCombineFXAAProgram; +            // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) +            // where	 N = fnumber +            //			 s2 = dot distance +            //			 s1 = subject distance +            //			 f = focal length +            // -			shader->bind(); -			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); +            F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); +            blur_constant /= 1000.f; // convert to meters for shader +            F32 magnification = focal_length / (subject_distance - focal_length); -			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -			if (channel > -1) -			{ -				mDeferredLight.bindTexture(0, channel); -			} -						 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); +            { // build diffuse+bloom+CoF +                mDeferredLight.bindTarget(); +                shader = &gDeferredCoFProgram; -			gGL.flush(); +                bindDeferredShader(*shader); -			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); -			shader->unbind(); -			 -			mFXAABuffer.flush(); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                if (channel > -1) +                { +                    mScreen.bindTexture(0, channel); +                } -			shader = &gFXAAProgram; -			shader->bind(); +                shader->uniform1f(LLShaderMgr::DOF_FOCAL_DISTANCE, -subject_distance / 1000.f); +                shader->uniform1f(LLShaderMgr::DOF_BLUR_CONSTANT, blur_constant); +                shader->uniform1f(LLShaderMgr::DOF_TAN_PIXEL_ANGLE, tanf(1.f / LLDrawable::sCurPixelAngle)); +                shader->uniform1f(LLShaderMgr::DOF_MAGNIFICATION, magnification); +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); -			if (channel > -1) -			{ -				mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); -			} -			 -			gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; -			gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; -			gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); -			gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); -			glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); - -			F32 scale_x = (F32) width/mFXAABuffer.getWidth(); -			F32 scale_y = (F32) height/mFXAABuffer.getHeight(); -			shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); -			shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f/width*scale_x, 1.f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f/width*scale_x, -0.5f/height*scale_y, 0.5f/width*scale_x, 0.5f/height*scale_y); -			shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f/width*scale_x, -2.f/height*scale_y, 2.f/width*scale_x, 2.f/height*scale_y); -			 -			gGL.begin(LLRender::TRIANGLE_STRIP); -			gGL.vertex2f(-1,-1); -			gGL.vertex2f(-1,3); -			gGL.vertex2f(3,-1); -			gGL.end(); +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); -			gGL.flush(); -			shader->unbind(); -		} -	} -	else -	{ -		U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; -		LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); -		buff->allocateBuffer(3,0,TRUE); +                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +                gGL.vertex2f(-1, 3); -		LLStrider<LLVector3> v; -		LLStrider<LLVector2> uv1; -		LLStrider<LLVector2> uv2; +                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +                gGL.vertex2f(3, -1); -		buff->getVertexStrider(v); -		buff->getTexCoord0Strider(uv1); -		buff->getTexCoord1Strider(uv2); -		 -		uv1[0] = LLVector2(0, 0); -		uv1[1] = LLVector2(0, 2); -		uv1[2] = LLVector2(2, 0); -		 -		uv2[0] = LLVector2(0, 0); -		uv2[1] = LLVector2(0, tc2.mV[1]*2.f); -		uv2[2] = LLVector2(tc2.mV[0]*2.f, 0); -		 -		v[0] = LLVector3(-1,-1,0); -		v[1] = LLVector3(-1,3,0); -		v[2] = LLVector3(3,-1,0); -				 -		buff->flush(); +                gGL.end(); -		LLGLDisable blend(GL_BLEND); +                unbindDeferredShader(*shader); +                mDeferredLight.flush(); +            } -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gGlowCombineProgram.bind(); -		} -		else -		{ -			//tex unit 0 -			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); -			//tex unit 1 -			gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR); -		} -		 -		gGL.getTexUnit(0)->bind(&mGlow[1]); -		gGL.getTexUnit(1)->bind(&mScreen); -		 -		LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); -		 -		buff->setBuffer(mask); -		buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); -		 -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gGlowCombineProgram.unbind(); -		} -		else -		{ -			gGL.getTexUnit(1)->disable(); -			gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); +            U32 dof_width = (U32)(mScreen.getWidth() * CameraDoFResScale); +            U32 dof_height = (U32)(mScreen.getHeight() * CameraDoFResScale); -			gGL.getTexUnit(0)->activate(); -			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); -		} -		 -	} +            { // perform DoF sampling at half-res (preserve alpha channel) +                mScreen.bindTarget(); +                glViewport(0, 0, dof_width, dof_height); +                gGL.setColorMask(true, false); -	gGL.setSceneBlendType(LLRender::BT_ALPHA); +                shader = &gDeferredPostProgram; +                bindDeferredShader(*shader); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +                if (channel > -1) +                { +                    mDeferredLight.bindTexture(0, channel); +                } -	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) -	{ -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gSplatTextureRectProgram.bind(); -		} +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -		gGL.setColorMask(true, false); +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); -		LLVector2 tc1(0,0); -		LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw()*2, -				  (F32) gViewerWindow->getWorldViewHeightRaw()*2); +                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +                gGL.vertex2f(-1, 3); -		LLGLEnable blend(GL_BLEND); -		gGL.color4f(1,1,1,0.75f); +                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +                gGL.vertex2f(3, -1); -		gGL.getTexUnit(0)->bind(&mPhysicsDisplay); +                gGL.end(); -		gGL.begin(LLRender::TRIANGLES); -		gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -		gGL.vertex2f(-1,-1); -		 -		gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -		gGL.vertex2f(-1,3); -		 -		gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -		gGL.vertex2f(3,-1); -		 -		gGL.end(); -		gGL.flush(); +                unbindDeferredShader(*shader); +                mScreen.flush(); +                gGL.setColorMask(true, true); +            } -		if (LLGLSLShader::sNoFixedFunction) -		{ -			gSplatTextureRectProgram.unbind(); -		} -	} +            { // combine result based on alpha +                if (multisample) +                { +                    mDeferredLight.bindTarget(); +                    glViewport(0, 0, mDeferredScreen.getWidth(), mDeferredScreen.getHeight()); +                } +                else +                { +                    gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +                    gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +                    gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +                    gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +                    glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); +                } -	 -	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_STENCIL_BUFFER_BIT, GL_NEAREST); -	} -	 +                shader = &gDeferredDoFCombineProgram; +                bindDeferredShader(*shader); -	gGL.matrixMode(LLRender::MM_PROJECTION); -	gGL.popMatrix(); -	gGL.matrixMode(LLRender::MM_MODELVIEW); -	gGL.popMatrix(); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +                if (channel > -1) +                { +                    mScreen.bindTexture(0, channel); +                } -	LLVertexBuffer::unbind(); +                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +                shader->uniform1f(LLShaderMgr::DOF_WIDTH, dof_width - 1); +                shader->uniform1f(LLShaderMgr::DOF_HEIGHT, dof_height - 1); -	LLGLState::checkStates(); -	LLGLState::checkTextureChannels(); +                gGL.begin(LLRender::TRIANGLE_STRIP); +                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +                gGL.vertex2f(-1, -1); + +                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +                gGL.vertex2f(-1, 3); + +                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +                gGL.vertex2f(3, -1); + +                gGL.end(); + +                unbindDeferredShader(*shader); + +                if (multisample) +                { +                    mDeferredLight.flush(); +                } +            } +        } +        else +        { +            if (multisample) +            { +                mDeferredLight.bindTarget(); +            } +            LLGLSLShader *shader = &gDeferredPostNoDoFProgram; + +            bindDeferredShader(*shader); + +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mScreen.getUsage()); +            if (channel > -1) +            { +                mScreen.bindTexture(0, channel); +            } + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +            gGL.vertex2f(-1, -1); + +            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +            gGL.vertex2f(-1, 3); + +            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +            gGL.vertex2f(3, -1); + +            gGL.end(); + +            unbindDeferredShader(*shader); + +            if (multisample) +            { +                mDeferredLight.flush(); +            } +        } + +        if (multisample) +        { +            // bake out texture2D with RGBL for FXAA shader +            mFXAABuffer.bindTarget(); + +            S32 width = mScreen.getWidth(); +            S32 height = mScreen.getHeight(); +            glViewport(0, 0, width, height); + +            LLGLSLShader *shader = &gGlowCombineFXAAProgram; + +            shader->bind(); +            shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); + +            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            if (channel > -1) +            { +                mDeferredLight.bindTexture(0, channel); +            } + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.vertex2f(-1, -1); +            gGL.vertex2f(-1, 3); +            gGL.vertex2f(3, -1); +            gGL.end(); + +            gGL.flush(); + +            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mDeferredLight.getUsage()); +            shader->unbind(); + +            mFXAABuffer.flush(); + +            shader = &gFXAAProgram; +            shader->bind(); + +            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mFXAABuffer.getUsage()); +            if (channel > -1) +            { +                mFXAABuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); +            } + +            gGLViewport[0] = gViewerWindow->getWorldViewRectRaw().mLeft; +            gGLViewport[1] = gViewerWindow->getWorldViewRectRaw().mBottom; +            gGLViewport[2] = gViewerWindow->getWorldViewRectRaw().getWidth(); +            gGLViewport[3] = gViewerWindow->getWorldViewRectRaw().getHeight(); +            glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]); + +            F32 scale_x = (F32) width / mFXAABuffer.getWidth(); +            F32 scale_y = (F32) height / mFXAABuffer.getHeight(); +            shader->uniform2f(LLShaderMgr::FXAA_TC_SCALE, scale_x, scale_y); +            shader->uniform2f(LLShaderMgr::FXAA_RCP_SCREEN_RES, 1.f / width * scale_x, 1.f / height * scale_y); +            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT, -0.5f / width * scale_x, -0.5f / height * scale_y, +                              0.5f / width * scale_x, 0.5f / height * scale_y); +            shader->uniform4f(LLShaderMgr::FXAA_RCP_FRAME_OPT2, -2.f / width * scale_x, -2.f / height * scale_y, +                              2.f / width * scale_x, 2.f / height * scale_y); + +            gGL.begin(LLRender::TRIANGLE_STRIP); +            gGL.vertex2f(-1, -1); +            gGL.vertex2f(-1, 3); +            gGL.vertex2f(3, -1); +            gGL.end(); + +            gGL.flush(); +            shader->unbind(); +        } +    } +    else // not deferred +    { +        U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; +        LLPointer<LLVertexBuffer> buff = new LLVertexBuffer(mask, 0); +        buff->allocateBuffer(3, 0, TRUE); + +        LLStrider<LLVector3> v; +        LLStrider<LLVector2> uv1; +        LLStrider<LLVector2> uv2; + +        buff->getVertexStrider(v); +        buff->getTexCoord0Strider(uv1); +        buff->getTexCoord1Strider(uv2); + +        uv1[0] = LLVector2(0, 0); +        uv1[1] = LLVector2(0, 2); +        uv1[2] = LLVector2(2, 0); + +        uv2[0] = LLVector2(0, 0); +        uv2[1] = LLVector2(0, tc2.mV[1] * 2.f); +        uv2[2] = LLVector2(tc2.mV[0] * 2.f, 0); + +        v[0] = LLVector3(-1, -1, 0); +        v[1] = LLVector3(-1, 3, 0); +        v[2] = LLVector3(3, -1, 0); + +        buff->flush(); + +        LLGLDisable blend(GL_BLEND); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gGlowCombineProgram.bind(); +        } +        else +        { +            // tex unit 0 +            gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_TEX_COLOR); +            // tex unit 1 +            gGL.getTexUnit(1)->setTextureColorBlend(LLTexUnit::TBO_ADD, LLTexUnit::TBS_TEX_COLOR, +                                                    LLTexUnit::TBS_PREV_COLOR); +        } + +        gGL.getTexUnit(0)->bind(&mGlow[1]); +        gGL.getTexUnit(1)->bind(&mScreen); + +        LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE_ARB : 0); + +        buff->setBuffer(mask); +        buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gGlowCombineProgram.unbind(); +        } +        else +        { +            gGL.getTexUnit(1)->disable(); +            gGL.getTexUnit(1)->setTextureBlendType(LLTexUnit::TB_MULT); + +            gGL.getTexUnit(0)->activate(); +            gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); +        } +    } + +    gGL.setSceneBlendType(LLRender::BT_ALPHA); + +    if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) +    { +        if (LLGLSLShader::sNoFixedFunction) +        { +            gSplatTextureRectProgram.bind(); +        } + +        gGL.setColorMask(true, false); + +        LLVector2 tc1(0, 0); +        LLVector2 tc2((F32) gViewerWindow->getWorldViewWidthRaw() * 2, +                      (F32) gViewerWindow->getWorldViewHeightRaw() * 2); + +        LLGLEnable blend(GL_BLEND); +        gGL.color4f(1, 1, 1, 0.75f); + +        gGL.getTexUnit(0)->bind(&mPhysicsDisplay); + +        gGL.begin(LLRender::TRIANGLES); +        gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +        gGL.vertex2f(-1, -1); + +        gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +        gGL.vertex2f(-1, 3); + +        gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +        gGL.vertex2f(3, -1); + +        gGL.end(); +        gGL.flush(); + +        if (LLGLSLShader::sNoFixedFunction) +        { +            gSplatTextureRectProgram.unbind(); +        } +    } + +    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_STENCIL_BUFFER_BIT, GL_NEAREST); +    } + +    gGL.matrixMode(LLRender::MM_PROJECTION); +    gGL.popMatrix(); +    gGL.matrixMode(LLRender::MM_MODELVIEW); +    gGL.popMatrix(); + +    LLVertexBuffer::unbind(); +    LLGLState::checkStates(); +    LLGLState::checkTextureChannels();  }  static LLTrace::BlockTimerStatHandle FTM_BIND_DEFERRED("Bind Deferred"); diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 5a07bdebe3..600bdd9d06 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -139,7 +139,7 @@ public:  	void resetVertexBuffers(LLDrawable* drawable);  	void generateImpostor(LLVOAvatar* avatar);  	void bindScreenToTexture(); -	void renderBloom(bool for_snapshot, F32 zoom_factor = 1.f, int subfield = 0); +	void renderFinalize();  	void init();  	void cleanup(); | 
