


local mat_Downsample	= Material( "pp/downsample" )
local mat_Bloom			= Material( "pp/bloom" )
local mat_BlurX			= Material( "pp/blurx" )
local mat_BlurY			= Material( "pp/blury" )

local tex_Bloom0		= render.GetBloomTex0()
local tex_Bloom1		= render.GetBloomTex1()

/*---------------------------------------------------------
   Register the convars that will control this effect
---------------------------------------------------------*/   
CreateClientConVar( "pp_bloom", "1", true, false )				// On/Off
CreateClientConVar( "pp_bloom_darken", "0.65", false, false )		// Decides the strength of the bloom
CreateClientConVar( "pp_bloom_multiply", "2.0", false, false )	// Decides the strength of the bloom
CreateClientConVar( "pp_bloom_sizex", "9.0", false, false )		// Horizontal blur size
CreateClientConVar( "pp_bloom_sizey", "9.0", false, false )		// Vertical blur size
CreateClientConVar( "pp_bloom_color", "1.0", false, false )
CreateClientConVar( "pp_bloom_color_r", "1.0", false, false )
CreateClientConVar( "pp_bloom_color_g", "1.0", false, false )
CreateClientConVar( "pp_bloom_color_b", "1.0", false, false )
CreateClientConVar( "pp_bloom_passes", "1", false, false )

/*---------------------------------------------------------
   Can be called from engine or hooks using bloom.Draw
---------------------------------------------------------*/
function DrawBloom( darken, multiply, sizex, sizey, passes, color, colr, colg, colb )

	// No bloom for crappy gpus
	if ( !render.SupportsPixelShaders_2_0() ) then return end
	
	local w = ScrW()
	local h = ScrH();
	
	// Copy the backbuffer to the screen effect texture
	render.UpdateScreenEffectTexture()
	
	// Store the render target so we can swap back at the end
	local OldRT = render.GetRenderTarget();
	
	// The downsample material adjusts the contrast
	mat_Downsample:SetMaterialFloat( "$darken", darken )
	mat_Downsample:SetMaterialFloat( "$multiply", multiply  )
	
	// Downsample to BloomTexture0
	render.SetRenderTarget( tex_Bloom0 )
	//render.SetViewPort( 0, 0, tex_Bloom0:GetActualWidth(), tex_Bloom0:GetActualHeight() )
	
	render.SetMaterial( mat_Downsample )
	render.DrawScreenQuad()			 
					 
	mat_BlurX:SetMaterialTexture( "$basetexture", tex_Bloom0 )
	mat_BlurY:SetMaterialTexture( "$basetexture", tex_Bloom1  )
	mat_BlurX:SetMaterialFloat( "$size", sizex )
	mat_BlurY:SetMaterialFloat( "$size", sizey )
	
	for i=1, passes do

		render.SetRenderTarget( tex_Bloom1 )
		render.SetMaterial( mat_BlurX )
		render.DrawScreenQuad()

		render.SetRenderTarget( tex_Bloom0 )
		render.SetMaterial( mat_BlurY )
		render.DrawScreenQuad()

	end
			 
	render.SetRenderTarget( OldRT );
	
	mat_Bloom:SetMaterialFloat( "$levelr", colr )
	mat_Bloom:SetMaterialFloat( "$levelg", colg )
	mat_Bloom:SetMaterialFloat( "$levelb", colb )
	mat_Bloom:SetMaterialFloat( "$colormul", color )
	mat_Bloom:SetMaterialTexture( "$basetexture", tex_Bloom0 )
	
	render.SetMaterial( mat_Bloom )
	render.DrawScreenQuad()
	
end


/*---------------------------------------------------------
   The function to draw the bloom (called from the hook)
---------------------------------------------------------*/
local function DrawInternal()

	// No bloom for crappy gpus
	if ( !render.SupportsPixelShaders_2_0() ) then return end	
	if ( GetConVarNumber( "pp_bloom" ) == 0 ) then return end
	if ( !GAMEMODE:PostProcessPermitted( "bloom" ) ) then return end
	
	DrawBloom( GetConVarNumber( "pp_bloom_darken" ), 
				GetConVarNumber( "pp_bloom_multiply" ),
				GetConVarNumber( "pp_bloom_sizex" ),
				GetConVarNumber( "pp_bloom_sizey" ),
				GetConVarNumber( "pp_bloom_passes"),
				GetConVarNumber( "pp_bloom_color"),
				GetConVarNumber( "pp_bloom_color_r"),
				GetConVarNumber( "pp_bloom_color_g"),
				GetConVarNumber( "pp_bloom_color_b") )

end



hook.Add( "RenderScreenspaceEffects", "RenderBloom", DrawInternal )