local mat_Morph = Material( "pp/morph/refract" ) local mat_Brush = Material( "pp/morph/brush1" ) local mat_BrushOut = Material( "pp/morph/brush_outline" ) local tex_MorphBuffer = render.GetMorphTex0() mat_Morph:SetMaterialTexture( "$fbtexture", render.GetScreenEffectTexture() ) Morph = {} Morph.Clear = true Morph.Drawing = false Morph.BrushSize = 64 // This morph was so awesome. It was just like in photoshop or something // But it turned out that it only worked on my Geforce 7800GTX // So I had to make it dumb :( // Maybe one day it'll be awesome again! /*--------------------------------------------------------- Register the convars that will control this effect ---------------------------------------------------------*/ local pp_morph = CreateClientConVar( "pp_morph", "0", false, false ) local pp_morph_scale = CreateClientConVar( "pp_morph_scale", "0.2", false, false ) local function MorphFrameVisible() if ( !Morph.Frame ) then return false end return Morph.Frame:IsVisible() end /*--------------------------------------------------------- Draws the morph - you can call this from a function if you need to. ---------------------------------------------------------*/ function DrawMorph( size ) if ( !render.SupportsPixelShaders_2_0() ) then return end if ( !render.SupportsHDR() ) then return end // Copy the backbuffer to the screen effect texture render.UpdateScreenEffectTexture() // Clear the morph buffer if (Morph.Clear) then render.ClearRenderTarget( tex_MorphBuffer, Color( 128, 128, 128, 255 ) ) Morph.Clear = false end local x, y = gui.MousePos() // Here's the situation with this. // I had it set up awesome, when it drew it just used the additive blend mode and it added/subtracted just fine. // Then I found out it didn't work on ATI cards so I had to complicate everything. if (Morph.Drawing && MorphFrameVisible()) then local OldRT = render.GetRenderTarget(); render.SetRenderTarget( tex_MorphBuffer ) render.SetMaterial( mat_Brush ) // Interpolate the two positions local vStart = Vector ( Morph.oldX, Morph.oldY, 0 ) local vEnd = Vector ( x, y, 0 ) local vDiff = vEnd-vStart local fLen = vDiff:Length() local vNorm = vDiff:GetNormalized() color = Color( 128, 128, 128, 16 ) local r = (Morph.oldX - x)*10 local g = (Morph.oldY - y)*10 color.r = color.r + math.Clamp( r, -127, 127 ) color.g = color.g + math.Clamp( g, -127, 127 ) if ( math.abs(r) > 5 || math.abs(g) > 5 ) then for i=0, fLen, 16 do render.DrawQuadEasy( vStart + vNorm*i, Vector( 0, 0, -1 ), Morph.BrushSize, Morph.BrushSize, color ) end end render.SetRenderTarget( OldRT ) end Morph.oldX = x Morph.oldY = y mat_Morph:SetMaterialFloat( "$refractamount", size ) mat_Morph:SetMaterialTexture( "$normalmap", tex_MorphBuffer ) mat_Morph:SetMaterialTexture( "$basetexture", tex_MorphBuffer ) render.SetMaterial( mat_Morph ) render.DrawScreenQuad() // Draw the handle if ( vgui.IsHoveringWorld() && MorphFrameVisible()) then render.SetMaterial( mat_BrushOut ) render.DrawQuadEasy( Vector( Morph.oldX, Morph.oldY, 0 ), Vector( 0, 0, -1 ), Morph.BrushSize, Morph.BrushSize, color_white ) end end /*--------------------------------------------------------- Hooked function to draw the morph ---------------------------------------------------------*/ local function DrawInternal() if ( !pp_morph:GetBool() ) then return end if ( !GAMEMODE:PostProcessPermitted( "morph" ) ) then return end DrawMorph( pp_morph_scale:GetFloat() ); end hook.Add( "RenderScreenspaceEffects", "DrawMorph", DrawInternal ) /*--------------------------------------------------------- Mouse button down ---------------------------------------------------------*/ local function MouseDown( mouse ) if (!MorphFrameVisible()) then return end // This makes it so that even if you're hovering over another panel when you // release the mouse - it will still send the release event to this panel vgui.GetWorldPanel():MouseCapture( true ) Morph.Drawing = true end /*--------------------------------------------------------- Mouse button released ---------------------------------------------------------*/ local function MouseUp( mouse ) if (!MorphFrameVisible()) then return end vgui.GetWorldPanel():MouseCapture( false ) Morph.Drawing = false end hook.Add( "GUIMousePressed", "MorphMouseDown", MouseDown ) hook.Add( "GUIMouseReleased", "MorphMouseUp", MouseUp ) /*--------------------------------------------------------- This is a console command that opens the morph window ---------------------------------------------------------*/ local function MorphFrame( player, command, arguments ) if (Morph.Frame) then Morph.Frame:SetVisible( true ) return end local frame = vgui.Create( "Frame" ) frame:SetName( "Morph" ) // Brush Size Slider local brushsize = function( panel, message, param1, param2 ) if (message != "SliderMoved") then return end Morph.BrushSize = param1 end local slider = vgui.Create( "Slider", frame, "MorphSlider" ) slider:PostMessage( "SetLower", "f", "8" ) slider:PostMessage( "SetHigher", "f", "256" ) slider:PostMessage( "SetValue", "f", Morph.BrushSize ) slider:SetActionFunction( brushsize ) // Refract Size Slider local refractsize = function( panel, message, param1, param2 ) if (message != "SliderMoved") then return end RunConsoleCommand( "pp_morph_scale", param1 ) end local slider = vgui.Create( "Slider", frame, "RefractSlider" ) slider:PostMessage( "SetInteger", "b", "0" ) slider:PostMessage( "SetLower", "f", "-1.0" ) slider:PostMessage( "SetHigher", "f", "1.0" ) slider:PostMessage( "SetValue", "f", pp_morph_scale:GetFloat() ) slider:SetActionFunction( refractsize ) // Clear Button local clear = function( panel, message, param1, param2 ) if (message != "Command") then return end Morph.Clear = true end local button = vgui.Create( "Button", frame, "ClearButton" ) button:SetActionFunction( clear ) // Screenshot Button local screenshot = function( panel, message, param1, param2 ) if (message != "Command") then return end frame:SetVisible( false ) timer.Simple( 0.1, LocalPlayer().ConCommand, LocalPlayer(), "jpeg\n" ) timer.Simple( 0.2, frame.SetVisible, frame, true ) end local button = vgui.Create( "Button", frame, "ScreenshotButton" ) button:SetActionFunction( screenshot ) frame:LoadControlsFromFile( "resource/ui/Morph.res" ) frame:SetKeyBoardInputEnabled( false ) frame:SetMouseInputEnabled( true ) frame:SetVisible( true ) Morph.Frame = frame // Turn morphing on RunConsoleCommand( "pp_morph", "1" ) end concommand.Add( "pp_morph_open", MorphFrame ) /* // Control Panel */ local function BuildControlPanel( CPanel ) CPanel:AddControl( "Header", { Text = "#Morph", Description = "#Morph_Information" } ) CPanel:AddControl( "CheckBox", { Label = "#Morph_Toggle", Command = "pp_morph" } ) CPanel:Button( "#Morph_Open", "pp_morph_open" ) end /* // Tool Menu */ local function AddPostProcessMenu() spawnmenu.AddToolMenuOption( "PostProcessing", "PPShader", "Morph", "#Morph", "", "", BuildControlPanel, { SwitchConVar = "pp_morph" } ) end hook.Add( "PopulateToolMenu", "AddPostProcessMenu_Morph", AddPostProcessMenu )