Render Targets

I can’t wrap my head around how to simply make a render target in the world somewhere.

Is there no basic tutorial for placing a rectangle in the world at specified coordinates, with a specific width & height, and having it render the view of a rendertarget?
Or do I need to script an entity specifically for it?

What do you already know?

1: have an imaterial that exists to contain the rendertarget as the material’s texture
2: make and draw to the render target
3: render the imaterial arbitrarily in world space

Well I did try experimenting with it using those steps, and all I can really manage to do is get it to draw a black rectangle.
No image appears, and sometimes my viewmodel will disappear or move elsewhere.

That means you aren’t rendering anything to the render target.



--make the render target with GetRenderTarget (not intuitively named)
local MyRenderTarget = GetRenderTarget("UniqueNameHere",512,512) --512 is a size of render space; you can plan for all drawing to take place within a 512x512 coordinate range for example
hook.Add("HUDPaint","UniqueNameHere",function()
	local oldw,oldh,oldrt = ScrW(), ScrH(), render.GetRenderTarget()
	--going to change the target of render oprations from your game's screen to a virtual screen (the render target), which means also changing the viewport, then we do the rendering, and after we put everything back how it was so that the rest of the game's drawing code can work with the screen's render target instead of breaking everything
	render.SetRenderTarget(MyRenderTarget)
	render.SetViewPort(0,0,512,512)
		surface.SetDrawColor(255,0,0,255)
		surface.SetFont("TargetID")
		surface.SetTextPos(100,100)
		surface.DrawText("Test")
	render.SetRenderTarget(oldrt)
	render.SetViewPort(0,0,oldw,oldh)
end)

local  MyIMaterial = CreateMaterial("UniqueNameHere","UnlitGeneric",{
	["$basetexture"] = "models/shadertest/shader5", --placeholder to be changed on demand
	["$vertexcolor"] = 1, --allows custom coloring
	["$vertexalpha"] = 1, --allows custom coloring
	["$model"] = 1, --???; i see other code using it so i always do whatever
})
--now whenever you want to set a new RT to render from, you change it on this material with:
MyIMaterial:SetTexture("$basetexture",MyRenderTarget)


--now you have a render target being drawn to with custom code, and applied as the texture for an imaterial; you just need to draw it in space! try a 3D drawing hook like a PostDrawOpaqueRenderables and put a cam.Start3D2D() for drawing in 3D space; the MyIMaterial is valid for any material setting function be it a model or an abritrary draw such as surface.SetMaterial/surface.DrawTexturedRect, but i've had issues using the surface library inside 3D2D


AFAIK you don’t need to create a 2D context because HUDPaint is already in a 2D context. If you want to render stuff that needs a 3D context, my preferred hook for this is GM:RenderScene( Origin, Angles ).

whoops
edited my post, thanks

i’ll have to try out renderscene sometime

To render to a rendertarget you don’t even need a hook, you can do it wherever you want.

Yeah but for some things that you often do with rendertargets, you need specific hooks (for example, using stencils with rendertargets sometimes requires you to use certain hooks).

it is true that a render target will hold onto the last image it was given without need for repeat, but i got the implication that OP wants to render a camera view of some part of the world live but elsewhere

Then if I recall correctly the suggested RenderScene hook is a bad idea, it will cause infinite recursion if you call render.RenderView from that hook.

But if it is only called once, won’t the rendertarget simply capture what was going on at the instantiation of the code, rather than streaming the view?

Yes, it will. You can actually use this to your own advantage if you want, like freezing last frame to look at it in more detail. If you want updating you can use Think hook (better don’t use draw hooks, it may get wonky).

if you want laggy (as in slow to update; low frame) drawing use the think hook

??? bad idea

rendering a whole new scene WILL take a framerate toll, but you can control the capture resolution to mitigate the issue

Okay, I’ll try that.

And bitches, would render.RenderView be used anywhere? I was looking through the snippet you gave, but I don’t see anything that defines what the rendertarget will actually be looking at.

A render target is just a target for rendering operations. You need to draw to the render target replacing the example surface text drawing, using renderview.

[editline]30th July 2015[/editline]

don’t use the think hook for this jesus fucking christ

Wat? On clients Think is called each frame, just like HUDPaint/RenderScene/other rendering hooks. If you use render.RenderView onto a rendertarget this IS a good place to call it, 3D rendering hooks AREN’T.

Ohhhh, ok, that makes sense, thanks.

HUDPaint is not a 3D rendering hook

Why would you use HUDPaint for rendering not onto HUD?