• RenderTarget shenanigans
    2 replies, posted
As some of you may know, I am trying to add some easy-to-use rendertarget functions in [url=https://github.com/ARitz-Cracker/ARCLib]ARCLib[/url] Most of my issues have been solved, however, it doesn't draw LocalPlayer when I want it to! This is the behaviour I am getting [vid]http://www.aritzcracker.ca/uploads/aritz/Garry's Mod 2016-11-08 1_14_19 PM.mp4[/vid] SO SOMEHOW DRAWING A HALO FIXES EVERYTHING! Here's the file that goes in lua/arclib/client [code] -- Big shoutout to bobbleheadbob and JamesXx for helping me with this local RTs = {} local DRAWING_RT = false ARCLib.TrackRT = false hook.Add( "RenderScene", "ARCLib RenderRTs", function( wat, skybox ) if ( not LocalPlayer() ) then return end if ( not skybox ) then return end if ( not DRAWING_RT ) then DRAWING_RT = true for k, v in pairs( RTs ) do if v.Update then local oldW, oldH = ScrW(), ScrH() local oldRT = render.GetRenderTarget() render.SetRenderTarget( v.RenderTarget ) render.Clear( 0, 0, 0, 255, true, true ) render.SetViewPort( 0, 0, v.renderInformation.w, v.renderInformation.h ) if ARCLib.TrackRT then MsgN("BeforeRender "..k.." "..SysTime()) end render.RenderView(v.renderInformation) if ARCLib.TrackRT then MsgN("AfterRender "..k.." "..SysTime()) end render.UpdateScreenEffectTexture() if v.Screenie then v.Screenie(render.Capture({ format = v.ScreenieFormat, quality = v.ScreenieQuality, h = v.renderInformation.h, w = v.renderInformation.w, x = v.renderInformation.x, y = v.renderInformation.y, })) v.Screenie = nil v.ScreenieFormat = nil v.ScreenieQuality = nil end render.SetRenderTarget( oldRT ) render.SetViewPort( 0, 0, oldW, oldH ) end end DRAWING_RT = false end end) hook.Add( "ShouldDrawLocalPlayer", "ARCLib PlayerRTs", function( ply ) if ARCLib.TrackRT then MsgN("ShouldDrawLocalPlayer "..tostring(DRAWING_RT).." "..SysTime()) end if ( DRAWING_RT ) then return true end --return false end) hook.Add( "GetMotionBlurValues", "ARCLib PlayerRTs GetMotionBlurValues", function( x, y, fwd, spin ) if ( DRAWING_RT ) then return 0, 0, 0, 0 end end ) hook.Add( "PostProcessPermitted", "ARCLib PlayerRTs PostProcessPermitted", function( element ) if ( DRAWING_RT and element == "bloom" ) then return false end end ) function ARCLib.CreateRenderTarget(name,w,h,pos,angles,fov) local rt = {} assert(isstring(name) and name != "","ARCLib.CreateRenderTarget: Render targets need a name!") assert(isnumber(w) and w > 16,"ARCLib.CreateRenderTarget: Width must be greater than 16") assert(isnumber(h) and h > 16,"ARCLib.CreateRenderTarget: Height must be greater than 16") pos = pos or vector_origin angles = angles or angle_zero fov = fov or 75 rt.RenderTarget = GetRenderTarget( name, w, h, false ) rt.renderInformation = { origin = pos, angles = angles, x = 0, y = 0, w = w, h = h, dopostprocess = false, drawhud = false, drawmonitors = false, drawviewmodel = true, ortho = false } RTs[name] = rt end function ARCLib.DisableRenderTarget(name) RTs[name].Update = false end function ARCLib.EnableRenderTarget(name) RTs[name].Update = true end function ARCLib.SetRenderTargetPos(name,pos) RTs[name].renderInformation.origin = pos or vector_origin end function ARCLib.SetRenderTargetAngles(name,ang) RTs[name].renderInformation.angles = ang or angle_zero end function ARCLib.CaptureRenderTarget(name,format,quality,cal lback) RTs[name].Screenie = callback RTs[name].ScreenieFormat = format RTs[name].ScreenieQuality = quality end function ARCLib.DestroyRenderTarget(name) RTs[name] = nil --TODO: There's a GetRenderTarget, but there is no KillRenderTarget?? end function ARCLib.GetRenderTargetTexture(name) return RTs[name].RenderTarget end function ARCLib.GetRenderTargetMaterial(name) if !RTs[name].material then local params = {} params[ "$basetexture" ] = RTs[name].RenderTarget:GetName() params[ "$vertexcolor" ] = 1 params[ "$vertexalpha" ] = 0 -- params[ "$model" ] = 1 -- TODO: Is this required? RTs[name].material = CreateMaterial( "arclib_rt_"..name, "UnlitGeneric", params ) end return RTs[name].material end [/code] shared.lua for sent_arc_camera [code] ENT.Base = "base_anim" ENT.Type = "anim" ENT.PrintName = "Camera" ENT.Author = "ARitz Cracker" ENT.Category = "Test" ENT.Contact = "" ENT.Purpose = "" ENT.Instructions = "" ENT.Spawnable = true; ENT.AdminOnly = false [/code] cl_init.lua for sent_arc_camera [code] -- cl_init.lua include('shared.lua') function ENT:Initialize() ARCLib.CreateRenderTarget("arc_camera"..self:EntIndex(),256,256,self:GetPos(),self:GetAn gles(),75) ARCLib.EnableRenderTarget("arc_camera"..self:EntIndex()) end function ENT:Think() ARCLib.SetRenderTargetPos("arc_camera"..self:EntIndex(),self:GetPos() + self:GetAngles():Forward()*7) ARCLib.SetRenderTargetAngles("arc_camera"..self:EntIndex(),self:GetAngles()) end function ENT:OnRemove() ARCLib.DestroyRenderTarget("arc_camera"..self:EntIndex()) end hook.Add( "HUDPaint", "ARCTestCamera", function() for k,v in ipairs(ents.FindByClass("sent_arc_camera")) do surface.SetDrawColor(255,255,255,255) surface.SetMaterial( ARCLib.GetRenderTargetMaterial("arc_camera"..v:EntIndex()) ) surface.DrawTexturedRect( -256 + (256+16)*k,16,256,256 ) end end) [/code] init.lua for sent_arc_camera [code] AddCSLuaFile("cl_init.lua") AddCSLuaFile("shared.lua") include('shared.lua') function ENT:Initialize() self:SetModel( "models/dav0r/camera.mdl" ) self:PhysicsInit( SOLID_VPHYSICS ) self:SetMoveType( MOVETYPE_VPHYSICS ) self:SetSolid( SOLID_VPHYSICS ) self:SetUseType( SIMPLE_USE ) self.phys = self:GetPhysicsObject() if self.phys:IsValid() then self.phys:Wake() end end function ENT:SpawnFunction( ply, tr ) if ( !tr.Hit ) then return end local blarg = ents.Create ("sent_arc_camera") blarg:SetPos(tr.HitPos + tr.HitNormal * 40) blarg:Spawn() blarg:Activate() return blarg end [/code] I bound a couple of keys to ARCLib.TrackRT = false and ARCLib.TrackRT = true, it just raised more questions that answers. This has been troubling me for days :cry:
I just took the time to test around with this. First of all, a general tip - when you come across a problem and you have no idea what its source is, that's when you drop whatever you're doing and test that one thing, separately, outside of your complex system. In this case, the code I used to test looks like this: [lua]local sdlp = nil hook.Add("PreRender","any identifier",function() if RENDER_VIEW_WITH_PLAYER and not sdlp then sdlp = true render.RenderView() sdlp = nil end end) hook.Add("ShouldDrawLocalPlayer","any identifier",function() return sdlp end)[/lua] "PreRender" was originally "RenderView", and your problem was apparent. When I changed it to PreRender, though, the problem went away. I think what's happening is that, for some reason, the new result of ShouldDrawLocalPlayer called by render.RenderView overrides the previous (or future?) result of ShouldDrawLocalPlayer that should affect the bigger frame. The engine, having already called ShouldDrawLocalPlayer, thinks that that result is applicable to all rendering operations currently in progress. When it's done in PreRender, the 'real' rendering operation hasn't started yet, so it will call ShouldDrawLocalPlayer again a second time, as we want it to do. You should use PreRender instead of RenderScene. For the record, if I'm not mistaken you can also use Think - you don't have to use a rendering hook. Two more things - you seem to have some really weird parameters for that hook (wat, skybox), is that intentional? The other thing is that for code cleanliness, should be using [url=https://wiki.garrysmod.com/page/render/PushRenderTarget]render.PushRenderTarget[/url] and [url=https://wiki.garrysmod.com/page/render/PopRenderTarget]render.PopRenderTarget[/url]. The "oldRT" trick is ugly in comparison. [editline]9th November 2016[/editline] And for the record, I totally think render.RenderView should accept the drawviewer element to decide whether to draw the local player. You should request it on the requests github if it hasn't been already
Hello! Thanks for responding. Unfortunately, PreRender was my first (failed) attempt at a solution. The resulting rendertarget is 100% black. Using Think also has the same result. (wat, skybox) is intentional, that is because the first argument is listed as "unknown" on the wiki :smile: I'll use pop and push. I didn't know that Push supported changing the viewport as well, so I'll go ahead and do that!
Sorry, you need to Log In to post a reply to this thread.