164 lines
3.7 KiB
Lua
164 lines
3.7 KiB
Lua
OUTLINE_MODE_BOTH = 0
|
|
OUTLINE_MODE_NOTVISIBLE = 1
|
|
OUTLINE_MODE_VISIBLE = 2
|
|
|
|
local istable = istable
|
|
local render = render
|
|
local LocalPlayer = LocalPlayer
|
|
local Material = Material
|
|
local CreateMaterial = CreateMaterial
|
|
local hook = hook
|
|
local cam = cam
|
|
local ScrW = ScrW
|
|
local ScrH = ScrH
|
|
local IsValid = IsValid
|
|
local surface = surface
|
|
|
|
module( "outline", package.seeall )
|
|
|
|
local List, ListSize = {}, 0
|
|
local RenderEnt = NULL
|
|
|
|
local OutlineMatSettings = {
|
|
[ "$ignorez" ] = 1,
|
|
[ "$alphatest" ] = 1
|
|
}
|
|
|
|
local CopyMat = Material( "pp/copy" )
|
|
local OutlineMat = CreateMaterial( "OutlineMat", "UnlitGeneric", OutlineMatSettings )
|
|
local StoreTexture = render.GetScreenEffectTexture( 0 )
|
|
local DrawTexture = render.GetScreenEffectTexture( 1 )
|
|
|
|
local ENTS = 1
|
|
local COLOR = 2
|
|
local MODE = 3
|
|
|
|
function Add( ents, color, mode )
|
|
|
|
if ( ListSize >= 255 ) then return end --Maximum 255 reference values
|
|
if ( !istable( ents ) ) then ents = { ents } end --Support for passing Entity as first argument
|
|
if ( ents[ 1 ] == nil ) then return end --Do not pass empty tables
|
|
|
|
local t = {
|
|
[ ENTS ] = ents,
|
|
[ COLOR ] = color,
|
|
[ MODE ] = mode or OUTLINE_MODE_BOTH
|
|
}
|
|
|
|
ListSize = ListSize + 1
|
|
List[ ListSize ] = t
|
|
end
|
|
|
|
function RenderedEntity()
|
|
|
|
return RenderEnt
|
|
|
|
end
|
|
|
|
local function Render()
|
|
local ply = LocalPlayer()
|
|
local IsLineOfSightClear = ply.IsLineOfSightClear
|
|
|
|
local scene = render.GetRenderTarget()
|
|
render.CopyRenderTargetToTexture( StoreTexture )
|
|
|
|
local w = ScrW()
|
|
local h = ScrH()
|
|
|
|
render.Clear( 0, 0, 0, 0, true, true )
|
|
|
|
render.SetStencilEnable( true )
|
|
cam.IgnoreZ( true )
|
|
render.SuppressEngineLighting( true )
|
|
|
|
render.SetStencilWriteMask( 0xFF )
|
|
render.SetStencilTestMask( 0xFF )
|
|
|
|
render.SetStencilCompareFunction( STENCIL_ALWAYS )
|
|
render.SetStencilFailOperation( STENCIL_KEEP )
|
|
render.SetStencilZFailOperation( STENCIL_REPLACE )
|
|
render.SetStencilPassOperation( STENCIL_REPLACE )
|
|
|
|
cam.Start3D()
|
|
|
|
for i = 1, ListSize do
|
|
local v = List[ i ]
|
|
local mode = v[ MODE ]
|
|
local ents = v[ ENTS ]
|
|
|
|
render.SetStencilReferenceValue( i )
|
|
|
|
for j = 1, #ents do
|
|
local ent = ents[ j ]
|
|
|
|
if ( !IsValid( ent ) ) then continue end
|
|
|
|
if ( ( mode == OUTLINE_MODE_NOTVISIBLE && IsLineOfSightClear( ply, ent ) ) || ( mode == OUTLINE_MODE_VISIBLE && !IsLineOfSightClear( ply, ent ) ) ) then
|
|
continue
|
|
end
|
|
|
|
RenderEnt = ent
|
|
|
|
ent:DrawModel()
|
|
end
|
|
end
|
|
|
|
RenderEnt = NULL
|
|
|
|
cam.End3D()
|
|
|
|
render.SetStencilCompareFunction( STENCIL_EQUAL )
|
|
|
|
cam.Start2D()
|
|
|
|
for i = 1, ListSize do
|
|
render.SetStencilReferenceValue( i )
|
|
|
|
surface.SetDrawColor( List[ i ][ COLOR ] )
|
|
surface.DrawRect( 0, 0, w, h )
|
|
end
|
|
|
|
cam.End2D()
|
|
|
|
render.SuppressEngineLighting( false )
|
|
cam.IgnoreZ( false )
|
|
render.SetStencilEnable( false )
|
|
|
|
render.CopyRenderTargetToTexture( DrawTexture )
|
|
|
|
render.SetRenderTarget( scene )
|
|
CopyMat:SetTexture( "$basetexture", StoreTexture )
|
|
render.SetMaterial( CopyMat )
|
|
render.DrawScreenQuad()
|
|
|
|
render.SetStencilEnable( true )
|
|
render.SetStencilReferenceValue( 0 )
|
|
render.SetStencilCompareFunction( STENCIL_EQUAL )
|
|
|
|
OutlineMat:SetTexture( "$basetexture", DrawTexture )
|
|
render.SetMaterial( OutlineMat )
|
|
|
|
render.DrawScreenQuadEx( -1, -1, w ,h )
|
|
render.DrawScreenQuadEx( -1, 0, w, h )
|
|
render.DrawScreenQuadEx( -1, 1, w, h )
|
|
render.DrawScreenQuadEx( 0, -1, w, h )
|
|
render.DrawScreenQuadEx( 0, 1, w, h )
|
|
render.DrawScreenQuadEx( 1, 1, w, h )
|
|
render.DrawScreenQuadEx( 1, 0, w, h )
|
|
render.DrawScreenQuadEx( 1, 1, w, h )
|
|
|
|
render.SetStencilEnable( false )
|
|
|
|
end
|
|
|
|
hook.Add( "PostDrawEffects", "RenderOutlines", function()
|
|
|
|
hook.Run( "PreDrawOutlines" )
|
|
|
|
if ( ListSize == 0 ) then return end
|
|
|
|
Render()
|
|
|
|
List, ListSize = {}, 0
|
|
|
|
end ) |