diff options
| -rw-r--r-- | indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl | 4 | ||||
| -rw-r--r-- | indra/newview/llviewerdisplay.cpp | 7 | ||||
| -rw-r--r-- | indra/newview/pipeline.cpp | 955 | ||||
| -rw-r--r-- | indra/newview/pipeline.h | 2 | 
4 files changed, 524 insertions, 444 deletions
diff --git a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl index e08284f762..71fa095505 100644 --- a/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/glowcombineV.glsl @@ -35,7 +35,7 @@ VARYING vec2 vary_texcoord1;  void main()  {  	gl_Position = vec4(position.xyz, 1.0); -	vary_texcoord0 = texcoord0; -	vary_texcoord1 = texcoord1; +	vary_texcoord0 = position.xy * 0.5 + 0.5; +	vary_texcoord1 = vary_texcoord0;  } diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1b2f07515a..58b1716caa 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1348,9 +1348,12 @@ void render_ui(F32 zoom_factor, int subfield)  	}  	{ +		// Render our post process prior to the HUD, UI, etc. +		gPipeline.renderPostProcess(); +          // draw hud and 3D ui elements into screen render target so they'll be able to use           // the depth buffer (avoids extra copy of depth buffer per frame) -        gPipeline.mRT->screen.bindTarget(); +        gPipeline.screenTarget()->bindTarget();  		// SL-15709  		// NOTE: Tracy only allows one ZoneScoped per function.  		// Solutions are: @@ -1384,7 +1387,7 @@ void render_ui(F32 zoom_factor, int subfield)              }          } -        gPipeline.mRT->screen.flush(); +        gPipeline.screenTarget()->flush();          // apply gamma correction and post effects before rendering 2D UI          gPipeline.renderFinalize(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 744d21b2c9..4edc092271 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -880,7 +880,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples)  		if (shadow_detail > 0 || ssao || RenderDepthOfField || samples > 0)  		{ //only need mRT->deferredLight for shadows OR ssao OR dof OR fxaa -			if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false; +			if (!mRT->deferredLight.allocate(resX, resY, GL_RGBA16, FALSE, FALSE, LLTexUnit::TT_TEXTURE, FALSE)) return false;  		}  		else  		{ @@ -7530,500 +7530,541 @@ void LLPipeline::bindScreenToTexture()  static LLTrace::BlockTimerStatHandle FTM_RENDER_BLOOM("Bloom"); -void LLPipeline::renderFinalize() +void LLPipeline::renderPostProcess()  { -    LLVertexBuffer::unbind(); -    LLGLState::checkStates(); -    LLGLState::checkTextureChannels(); +	LLVertexBuffer::unbind(); +	LLGLState::checkStates(); +	LLGLState::checkTextureChannels(); -    assertInitialized(); +	assertInitialized(); -    LLVector2 tc1(0, 0); -    LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2); +	LLVector2 tc1(0, 0); +	LLVector2 tc2((F32)mRT->screen.getWidth() * 2, (F32)mRT->screen.getHeight() * 2); -    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); -    LL_PROFILE_GPU_ZONE("renderFinalize"); +	LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +	LL_PROFILE_GPU_ZONE("renderPostProcess"); -    gGL.color4f(1, 1, 1, 1); -    LLGLDepthTest depth(GL_FALSE); -    LLGLDisable blend(GL_BLEND); -    LLGLDisable cull(GL_CULL_FACE); +	gGL.color4f(1, 1, 1, 1); +	LLGLDepthTest depth(GL_FALSE); +	LLGLDisable blend(GL_BLEND); +	LLGLDisable cull(GL_CULL_FACE); -    enableLightsFullbright(); +	enableLightsFullbright(); -    LLGLDisable test(GL_ALPHA_TEST); +	LLGLDisable test(GL_ALPHA_TEST); -    gGL.setColorMask(true, true); -    glClearColor(0, 0, 0, 0); +	gGL.setColorMask(true, true); +	glClearColor(0, 0, 0, 0); -    if (!gCubeSnapshot) -    { -        LLRenderTarget* screen_target = &mRT->screen; -        screen_target->bindTarget(); +	if (sRenderGlow) +	{ +		LL_PROFILE_GPU_ZONE("glow"); +		mGlow[2].bindTarget(); +		mGlow[2].clear(); -        if (RenderScreenSpaceReflections) -        { -            LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections"); -            LL_PROFILE_GPU_ZONE("screen space reflections"); +		gGlowExtractProgram.bind(); +		F32 minLum = llmax((F32)RenderGlowMinLuminance, 0.0f); +		F32 maxAlpha = RenderGlowMaxExtractAlpha; +		F32 warmthAmount = RenderGlowWarmthAmount; +		LLVector3 lumWeights = RenderGlowLumWeights; +		LLVector3 warmthWeights = RenderGlowWarmthWeights; -            bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL); -            mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +		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); -            set_camera_projection_matrix(gPostScreenSpaceReflectionProgram); +		{ +			LLGLEnable blend_on(GL_BLEND); +			LLGLEnable test(GL_ALPHA_TEST); -            // We need linear depth. -            static LLStaticHashedString zfar("zFar"); -            static LLStaticHashedString znear("zNear"); -            float                       nearClip = LLViewerCamera::getInstance()->getNear(); -            float                       farClip  = LLViewerCamera::getInstance()->getFar(); -            gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip); -            gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip); +			gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); -            S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screen_target->getUsage()); -            if (channel > -1) -            { -                screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); -            } +			mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT); -            { -                LLGLDisable blend(GL_BLEND); -                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); +			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); -                stop_glerror(); -                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); -                stop_glerror(); -            } +			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +			gGL.vertex2f(-1, 3); -            unbindDeferredShader(gPostScreenSpaceReflectionProgram); -        } +			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +			gGL.vertex2f(3, -1); -        // gamma correct lighting -        { -            LL_PROFILE_GPU_ZONE("gamma correct"); +			gGL.end(); -            LLGLDepthTest depth(GL_FALSE, GL_FALSE); +			gGL.getTexUnit(0)->unbind(mRT->screen.getUsage()); -            LLVector2 tc1(0, 0); -            LLVector2 tc2((F32)screen_target->getWidth() * 2, (F32)screen_target->getHeight() * 2); +			mGlow[2].flush(); -            // Apply gamma correction to the frame here. -            gDeferredPostGammaCorrectProgram.bind(); -            // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); -            S32 channel = 0; -            channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screen_target->getUsage()); -            if (channel > -1) -            { -                screen_target->bindTexture(0, channel, LLTexUnit::TFO_POINT); -            } +			tc1.setVec(0, 0); +			tc2.setVec(2, 2); +		} -            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screen_target->getWidth(), screen_target->getHeight()); +		// power of two between 1 and 1024 +		U32 glowResPow = RenderGlowResolutionPow; +		const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); -            F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); +		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; -            gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); +		gGlowProgram.bind(); +		gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); -            gGL.begin(LLRender::TRIANGLE_STRIP); -            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -            gGL.vertex2f(-1, -1); +		for (S32 i = 0; i < kernel; i++) +		{ +			mGlow[i % 2].bindTarget(); +			mGlow[i % 2].clear(); -            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -            gGL.vertex2f(-1, 3); +			if (i == 0) +			{ +				gGL.getTexUnit(0)->bind(&mGlow[2]); +			} +			else +			{ +				gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); +			} -            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -            gGL.vertex2f(3, -1); +			if (i % 2 == 0) +			{ +				gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); +			} +			else +			{ +				gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); +			} -            gGL.end(); +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +			gGL.vertex2f(-1, -1); -            gGL.getTexUnit(channel)->unbind(screen_target->getUsage()); -            gDeferredPostGammaCorrectProgram.unbind(); -        } +			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +			gGL.vertex2f(-1, 3); -        screen_target->flush(); +			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +			gGL.vertex2f(3, -1); -        LLVertexBuffer::unbind(); -    } +			gGL.end(); -    if (sRenderGlow) -    { -        LL_PROFILE_GPU_ZONE("glow"); -        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); +			mGlow[i % 2].flush(); +		} -            gGL.setSceneBlendType(LLRender::BT_ADD_WITH_ALPHA); +		gGlowProgram.unbind(); +	} +	else // !sRenderGlow, skip the glow ping-pong and just clear the result target +	{ +		mGlow[1].bindTarget(); +		mGlow[1].clear(); +		mGlow[1].flush(); +	} -            mRT->screen.bindTexture(0, 0, LLTexUnit::TFO_POINT); +	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]); -            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); +	tc2.setVec((F32)mRT->screen.getWidth(), (F32)mRT->screen.getHeight()); -            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -            gGL.vertex2f(-1, 3); +	gGL.flush(); -            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -            gGL.vertex2f(3, -1); +	LLVertexBuffer::unbind(); -            gGL.end(); +	if (LLPipeline::sRenderDeferred) +	{ +		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && +			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && +			RenderDepthOfField && +			!gCubeSnapshot; -            gGL.getTexUnit(0)->unbind(mRT->screen.getUsage()); +		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; -            mGlow[2].flush(); +		gViewerWindow->setup3DViewport(); -            tc1.setVec(0, 0); -            tc2.setVec(2, 2);  -        } +		if (dof_enabled) +		{ +			LL_PROFILE_GPU_ZONE("dof"); +			LLGLSLShader* shader = &gDeferredPostProgram; +			LLGLDisable blend(GL_BLEND); -        // power of two between 1 and 1024 -        U32 glowResPow = RenderGlowResolutionPow; -        const U32 glow_res = llmax(1, llmin(1024, 1 << glowResPow)); +			// depth of field focal plane calculations +			static F32 current_distance = 16.f; +			static F32 start_distance = 16.f; +			static F32 transition_time = 1.f; -        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; +			LLVector3 focus_point; -        gGlowProgram.bind(); -        gGlowProgram.uniform1f(LLShaderMgr::GLOW_STRENGTH, strength); +			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(); +					} +				} +			} -        for (S32 i = 0; i < kernel; i++) -        { -            mGlow[i % 2].bindTarget(); -            mGlow[i % 2].clear(); +			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(); -            if (i == 0) -            { -                gGL.getTexUnit(0)->bind(&mGlow[2]); -            } -            else -            { -                gGL.getTexUnit(0)->bind(&mGlow[(i - 1) % 2]); -            } +					gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); -            if (i % 2 == 0) -            { -                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, delta, 0); -            } -            else -            { -                gGlowProgram.uniform2f(LLShaderMgr::GLOW_DELTA, 0, delta); -            } +					focus_point.set(result.getF32ptr()); +				} +				else +				{ +					// focus on alt-zoom target +					LLViewerRegion* region = gAgent.getRegion(); +					if (region) +					{ +						focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); +					} +				} +			} -            gGL.begin(LLRender::TRIANGLE_STRIP); -            gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -            gGL.vertex2f(-1, -1); +			LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); +			F32 target_distance = 16.f; +			if (!focus_point.isExactlyZero()) +			{ +				target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); +			} -            gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -            gGL.vertex2f(-1, 3); +			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); -            gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -            gGL.vertex2f(3, -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.end(); +			// convert to mm +			F32 subject_distance = current_distance * 1000.f; +			F32 fnumber = CameraFNumber; +			F32 default_focal_length = CameraFocalLength; -            mGlow[i % 2].flush(); -        } +			F32 fov = LLViewerCamera::getInstance()->getView(); -        gGlowProgram.unbind(); -    } -    else // !sRenderGlow, skip the glow ping-pong and just clear the result target -    { -        mGlow[1].bindTarget(); -        mGlow[1].clear(); -        mGlow[1].flush(); -    } +			const F32 default_fov = CameraFieldOfView * F_PI / 180.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 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); -    tc2.setVec((F32) mRT->screen.getWidth(), (F32) mRT->screen.getHeight()); +			F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); -    gGL.flush(); +			F32 focal_length = dv / (2 * tanf(fov / 2.f)); -    LLVertexBuffer::unbind(); +			// F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); -    if (LLPipeline::sRenderDeferred) -    { -        bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && -                           (RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && -                           RenderDepthOfField && -                            !gCubeSnapshot; +			// from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) +			// where	 N = fnumber +			//			 s2 = dot distance +			//			 s1 = subject distance +			//			 f = focal length +			// -        bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; +			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); -        gViewerWindow->setup3DViewport(); +			{ // build diffuse+bloom+CoF +                mRT->deferredLight.bindTarget(); +				shader = &gDeferredCoFProgram; -        if (dof_enabled) -        { -            LL_PROFILE_GPU_ZONE("dof"); -            LLGLSLShader *shader = &gDeferredPostProgram; -            LLGLDisable blend(GL_BLEND); +				bindDeferredShader(*shader); -            // depth of field focal plane calculations -            static F32 current_distance = 16.f; -            static F32 start_distance = 16.f; -            static F32 transition_time = 1.f; +				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); +				if (channel > -1) +				{ +					mRT->screen.bindTexture(0, channel); +				} -            LLVector3 focus_point; +				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); -            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(); -                    } -                } -            } +				gGL.begin(LLRender::TRIANGLE_STRIP); +				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +				gGL.vertex2f(-1, -1); -            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(tc1.mV[0], tc2.mV[1]); +				gGL.vertex2f(-1, 3); -                    gViewerWindow->cursorIntersect(-1, -1, 512.f, NULL, -1, FALSE, FALSE, TRUE, NULL, &result); +				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +				gGL.vertex2f(3, -1); -                    focus_point.set(result.getF32ptr()); -                } -                else -                { -                    // focus on alt-zoom target -                    LLViewerRegion *region = gAgent.getRegion(); -                    if (region) -                    { -                        focus_point = LLVector3(gAgentCamera.getFocusGlobal() - region->getOriginGlobal()); -                    } -                } -            } +				gGL.end(); -            LLVector3 eye = LLViewerCamera::getInstance()->getOrigin(); -            F32 target_distance = 16.f; -            if (!focus_point.isExactlyZero()) -            { -                target_distance = LLViewerCamera::getInstance()->getAtAxis() * (focus_point - eye); -            } +				unbindDeferredShader(*shader); +                mRT->deferredLight.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); +			U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); +			U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); -                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; -            } +			{ // perform DoF sampling at half-res (preserve alpha channel) +				mRT->screen.bindTarget(); +				glViewport(0, 0, dof_width, dof_height); +				gGL.setColorMask(true, false); -            // convert to mm -            F32 subject_distance = current_distance * 1000.f; -            F32 fnumber = CameraFNumber; -            F32 default_focal_length = CameraFocalLength; +				shader = &gDeferredPostProgram; +				bindDeferredShader(*shader); +                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); +				if (channel > -1) +				{ +                    mRT->deferredLight.bindTexture(0, channel); +				} -            F32 fov = LLViewerCamera::getInstance()->getView(); +				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -            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); -            // F32 aspect_ratio = (F32) mRT->screen.getWidth()/(F32)mRT->screen.getHeight(); +				gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +				gGL.vertex2f(-1, 3); -            F32 dv = 2.f * default_focal_length * tanf(default_fov / 2.f); +				gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +				gGL.vertex2f(3, -1); -            F32 focal_length = dv / (2 * tanf(fov / 2.f)); +				gGL.end(); -            // F32 tan_pixel_angle = tanf(LLDrawable::sCurPixelAngle); +				unbindDeferredShader(*shader); +				mRT->screen.flush(); +				gGL.setColorMask(true, true); +			} -            // from wikipedia -- c = |s2-s1|/s2 * f^2/(N(S1-f)) -            // where	 N = fnumber -            //			 s2 = dot distance -            //			 s1 = subject distance -            //			 f = focal length -            // +			{ // combine result based on alpha +				if (multisample) +				{ +					mRT->deferredLight.bindTarget(); +					glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.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]); +				} -            F32 blur_constant = focal_length * focal_length / (fnumber * (subject_distance - focal_length)); -            blur_constant /= 1000.f; // convert to meters for shader -            F32 magnification = focal_length / (subject_distance - focal_length); +				shader = &gDeferredDoFCombineProgram; +				bindDeferredShader(*shader); -            { // build diffuse+bloom+CoF -                mRT->deferredLight.bindTarget(); -                shader = &gDeferredCoFProgram; +				S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); +				if (channel > -1) +				{ +					mRT->screen.bindTexture(0, channel); +				} -                bindDeferredShader(*shader); +				shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); +				shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +				shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth()); +				shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight()); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); -                if (channel > -1) -                { -                    mRT->screen.bindTexture(0, channel); -                } +				gGL.begin(LLRender::TRIANGLE_STRIP); +				gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +				gGL.vertex2f(-1, -1); -                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); +				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(tc2.mV[0], tc1.mV[1]); +				gGL.vertex2f(3, -1); -                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -                gGL.vertex2f(-1, 3); +				gGL.end(); -                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -                gGL.vertex2f(3, -1); +				unbindDeferredShader(*shader); -                gGL.end(); +				if (multisample) +				{ +					mRT->deferredLight.flush(); +				} +			} +		} +		else +		{ +			LL_PROFILE_GPU_ZONE("no dof"); +			if (multisample) +			{ +				mRT->deferredLight.bindTarget(); +			} +			LLGLSLShader* shader = &gDeferredPostNoDoFProgram; -                unbindDeferredShader(*shader); -                mRT->deferredLight.flush(); -            } +			bindDeferredShader(*shader); -            U32 dof_width = (U32)(mRT->screen.getWidth() * CameraDoFResScale); -            U32 dof_height = (U32)(mRT->screen.getHeight() * CameraDoFResScale); +			S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); +			if (channel > -1) +			{ +				mRT->screen.bindTexture(0, channel); +			} -            { // perform DoF sampling at half-res (preserve alpha channel) -                mRT->screen.bindTarget(); -                glViewport(0, 0, dof_width, dof_height); -                gGL.setColorMask(true, false); +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); +			gGL.vertex2f(-1, -1); -                shader = &gDeferredPostProgram; -                bindDeferredShader(*shader); -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); -                if (channel > -1) -                { -                    mRT->deferredLight.bindTexture(0, channel); -                } +			gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); +			gGL.vertex2f(-1, 3); -                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); +			gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); +			gGL.vertex2f(3, -1); -                gGL.begin(LLRender::TRIANGLE_STRIP); -                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -                gGL.vertex2f(-1, -1); +			gGL.end(); -                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -                gGL.vertex2f(-1, 3); +			unbindDeferredShader(*shader); -                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -                gGL.vertex2f(3, -1); +			if (multisample) +			{ +				mRT->deferredLight.flush(); +			} +		} +	} +} -                gGL.end(); +LLRenderTarget* LLPipeline::screenTarget() { -                unbindDeferredShader(*shader); -                mRT->screen.flush(); -                gGL.setColorMask(true, true); -            } +	bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() && +		(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) && +		RenderDepthOfField && +		!gCubeSnapshot; -            { // combine result based on alpha -                if (multisample) -                { -                    mRT->deferredLight.bindTarget(); -                    glViewport(0, 0, mRT->deferredScreen.getWidth(), mRT->deferredScreen.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]); -                } +	bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; -                shader = &gDeferredDoFCombineProgram; -                bindDeferredShader(*shader); +	if (multisample || dof_enabled) +		return &mRT->deferredLight; +	 +	return &mRT->screen; +} -                S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); -                if (channel > -1) -                { -                    mRT->screen.bindTexture(0, channel); -                } +void LLPipeline::renderFinalize() +{ +    LLVertexBuffer::unbind(); +    LLGLState::checkStates(); +    LLGLState::checkTextureChannels(); + +    assertInitialized(); + +    LLVector2 tc1(0, 0); +    LLVector2 tc2((F32) mRT->screen.getWidth() * 2, (F32) mRT->screen.getHeight() * 2); -                shader->uniform1f(LLShaderMgr::DOF_MAX_COF, CameraMaxCoF); -                shader->uniform1f(LLShaderMgr::DOF_RES_SCALE, CameraDoFResScale); -                shader->uniform1f(LLShaderMgr::DOF_WIDTH, (dof_width - 1) / (F32)mRT->screen.getWidth()); -                shader->uniform1f(LLShaderMgr::DOF_HEIGHT, (dof_height - 1) / (F32)mRT->screen.getHeight()); +    LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); +    LL_PROFILE_GPU_ZONE("renderFinalize"); -                gGL.begin(LLRender::TRIANGLE_STRIP); -                gGL.texCoord2f(tc1.mV[0], tc1.mV[1]); -                gGL.vertex2f(-1, -1); +    gGL.color4f(1, 1, 1, 1); +    LLGLDepthTest depth(GL_FALSE); +    LLGLDisable blend(GL_BLEND); +    LLGLDisable cull(GL_CULL_FACE); -                gGL.texCoord2f(tc1.mV[0], tc2.mV[1]); -                gGL.vertex2f(-1, 3); +    enableLightsFullbright(); -                gGL.texCoord2f(tc2.mV[0], tc1.mV[1]); -                gGL.vertex2f(3, -1); +    LLGLDisable test(GL_ALPHA_TEST); -                gGL.end(); +    gGL.setColorMask(true, true); +    glClearColor(0, 0, 0, 0); -                unbindDeferredShader(*shader); +    if (!gCubeSnapshot) +    { +		screenTarget()->bindTarget(); -                if (multisample) -                { -                    mRT->deferredLight.flush(); -                } -            } -        } -        else +        if (RenderScreenSpaceReflections)          { -            LL_PROFILE_GPU_ZONE("no dof"); -            if (multisample) +            LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - screen space reflections"); +            LL_PROFILE_GPU_ZONE("screen space reflections"); + +            bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL); +            mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + +            set_camera_projection_matrix(gPostScreenSpaceReflectionProgram); + +            // We need linear depth. +            static LLStaticHashedString zfar("zFar"); +            static LLStaticHashedString znear("zNear"); +            float                       nearClip = LLViewerCamera::getInstance()->getNear(); +            float                       farClip  = LLViewerCamera::getInstance()->getFar(); +            gPostScreenSpaceReflectionProgram.uniform1f(zfar, farClip); +            gPostScreenSpaceReflectionProgram.uniform1f(znear, nearClip); + +            S32 channel = gPostScreenSpaceReflectionProgram.enableTexture(LLShaderMgr::DIFFUSE_MAP, screenTarget()->getUsage()); +            if (channel > -1)              { -                mRT->deferredLight.bindTarget(); +				screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);              } -            LLGLSLShader *shader = &gDeferredPostNoDoFProgram; -            bindDeferredShader(*shader); +            { +                LLGLDisable blend(GL_BLEND); +                LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); + +                stop_glerror(); +                mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); +                stop_glerror(); +            } -            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->screen.getUsage()); +            unbindDeferredShader(gPostScreenSpaceReflectionProgram); +        } + +        // gamma correct lighting +        { +            LL_PROFILE_GPU_ZONE("gamma correct"); + +            LLGLDepthTest depth(GL_FALSE, GL_FALSE); + +            LLVector2 tc1(0, 0); +            LLVector2 tc2((F32)screenTarget()->getWidth() * 2, (F32)screenTarget()->getHeight() * 2); + +            // Apply gamma correction to the frame here. +            gDeferredPostGammaCorrectProgram.bind(); +            // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); +            S32 channel = 0; +            channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage());              if (channel > -1)              { -                mRT->screen.bindTexture(0, channel); +				screenTarget()->bindTexture(0, channel, LLTexUnit::TFO_POINT);              } +            gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight()); + +            F32 gamma = gSavedSettings.getF32("RenderDeferredDisplayGamma"); + +            gDeferredPostGammaCorrectProgram.uniform1f(LLShaderMgr::DISPLAY_GAMMA, (gamma > 0.1f) ? 1.0f / gamma : (1.0f / 2.2f)); +              gGL.begin(LLRender::TRIANGLE_STRIP);              gGL.texCoord2f(tc1.mV[0], tc1.mV[1]);              gGL.vertex2f(-1, -1); @@ -8036,82 +8077,116 @@ void LLPipeline::renderFinalize()              gGL.end(); -            unbindDeferredShader(*shader); - -            if (multisample) -            { -                mRT->deferredLight.flush(); -            } +            gGL.getTexUnit(channel)->unbind(screenTarget()->getUsage()); +            gDeferredPostGammaCorrectProgram.unbind();          } -        if (multisample) -        { -            LL_PROFILE_GPU_ZONE("aa"); -            // bake out texture2D with RGBL for FXAA shader -            mRT->fxaaBuffer.bindTarget(); +		screenTarget()->flush(); -            S32 width = mRT->screen.getWidth(); -            S32 height = mRT->screen.getHeight(); -            glViewport(0, 0, width, height); +        LLVertexBuffer::unbind(); +    } -            LLGLSLShader *shader = &gGlowCombineFXAAProgram; +	if (RenderDeferred) +	{ +		bool multisample = RenderFSAASamples > 1 && mRT->fxaaBuffer.isComplete() && !gCubeSnapshot; +		LLGLSLShader* shader = &gGlowCombineProgram; -            shader->bind(); -            shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); +		S32 width = mRT->screen.getWidth(); +		S32 height = mRT->screen.getHeight(); -            S32 channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); -            if (channel > -1) -            { -                mRT->deferredLight.bindTexture(0, channel); -            } +		S32 channel = -1; -            gGL.begin(LLRender::TRIANGLE_STRIP); -            gGL.vertex2f(-1, -1); -            gGL.vertex2f(-1, 3); -            gGL.vertex2f(3, -1); -            gGL.end(); +		// Present everything. +		if (multisample) +		{ +			LL_PROFILE_GPU_ZONE("aa"); +			// bake out texture2D with RGBL for FXAA shader +			mRT->fxaaBuffer.bindTarget(); -            gGL.flush(); +			glViewport(0, 0, width, height); -            shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); -            shader->unbind(); +			shader = &gGlowCombineFXAAProgram; -            mRT->fxaaBuffer.flush(); +			shader->bind(); +			shader->uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, width, height); -            shader = &gFXAAProgram; -            shader->bind(); +			channel = shader->enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); +			if (channel > -1) +			{ +				mRT->deferredLight.bindTexture(0, channel); +			} -            channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); -            if (channel > -1) -            { -                mRT->fxaaBuffer.bindTexture(0, channel, LLTexUnit::TFO_BILINEAR); -            } +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.vertex2f(-1, -1); +			gGL.vertex2f(-1, 3); +			gGL.vertex2f(3, -1); +			gGL.end(); -            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 / mRT->fxaaBuffer.getWidth(); -            F32 scale_y = (F32) height / mRT->fxaaBuffer.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.flush(); -            gGL.begin(LLRender::TRIANGLE_STRIP); -            gGL.vertex2f(-1, -1); -            gGL.vertex2f(-1, 3); -            gGL.vertex2f(3, -1); -            gGL.end(); +			shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, mRT->deferredLight.getUsage()); +			shader->unbind(); -            gGL.flush(); -            shader->unbind(); -        } -    } +			mRT->fxaaBuffer.flush(); + +			shader = &gFXAAProgram; +			shader->bind(); + +			channel = shader->enableTexture(LLShaderMgr::DIFFUSE_MAP, mRT->fxaaBuffer.getUsage()); +			if (channel > -1) +			{ +				mRT->fxaaBuffer.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 / mRT->fxaaBuffer.getWidth(); +			F32 scale_y = (F32)height / mRT->fxaaBuffer.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 +		{ +			shader->bind(); + + +			gGL.getTexUnit(0)->bind(&mGlow[1]); +			gGL.getTexUnit(1)->bind(screenTarget()); + +			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]); + +			gGL.begin(LLRender::TRIANGLE_STRIP); +			gGL.vertex2f(-1, -1); +			gGL.vertex2f(-1, 3); +			gGL.vertex2f(3, -1); +			gGL.end(); + +			gGL.flush(); +			shader->unbind(); +		} +	} +      #if 0 // DEPRECATED      else // not deferred      { diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 0097b863ab..bac68cfff0 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -137,6 +137,8 @@ public:  	void generateImpostor(LLVOAvatar* avatar, bool preview_avatar = false);  	void bindScreenToTexture();  	void renderFinalize(); +	void renderPostProcess(); +	LLRenderTarget* screenTarget();  	void init();  	void cleanup();  | 
