3D2D in DModelPanel

I am trying to draw some 2D elements in a DModelPanel, but I can’t figure out the correct way to do it.

You would have to override the paint function and call the cam.Start3D2D stuff etc.

I made a DPanel3D that calls a Paint3D function that you can override and draw your own stuff with.

[lua]local PANEL = {}

AccessorFunc( PANEL, “m_iFOV”, “FOV”, FORCE_NUMBER )
AccessorFunc( PANEL, “m_cAmbientLight”, “AmbientLight” )
AccessorFunc( PANEL, “m_bCameraControl”, “CameraControl”, FORCE_BOOL )
AccessorFunc( PANEL, “m_vCamPos”, “CamPos” )
AccessorFunc( PANEL, “m_aCamAngle”, “CamAngle” )
AccessorFunc( PANEL, “m_bDebugText”, “DebugText”, FORCE_BOOL )

function PANEL:Init()
self.m_tDirectionalLight = {}
self.m_fLastPaint = 0
self.m_vCamPos = Vector( 64, 64, 64 )
self.m_aCamAngle = Angle( 0, 0, 0 )
self.m_bCameraControl = true
self.m_iFOV = 75

self:SetAmbientLight( Color( 50, 50, 50 ) )

self:SetKeyboardInputEnabled( true )
self:SetMouseInputEnabled( true )

end

function PANEL:SetDirectionalLight( iDirection, color )
self.m_tDirectionalLight[ iDirection ] = color
end

function PANEL:OnMousePressed( mousecode )
self.m_tMouseMovement = { gui.MousePos() }
self:MouseCapture( true )
self.m_iClickMode = mousecode
end

function PANEL:OnMouseReleased()
self.m_tMouseMovement = nil
self:MouseCapture( false )
end

function PANEL:Think()

if !self.m_bCameraControl then
	return
end

local speed = input.IsKeyDown( KEY_LSHIFT ) and 100 or 25

if self.m_iClickMode == MOUSE_LEFT and self.m_tMouseMovement then
	self.m_fMouseMoveSpeedX = ( self.m_tMouseMovement[1] - gui.MouseX() ) * RealFrameTime() * 15
	self.m_fMouseMoveSpeedY = ( self.m_tMouseMovement[2] - gui.MouseY() ) * RealFrameTime() * 15

	if input.IsKeyDown( KEY_LCONTROL ) then
		-- Move camera left/right
		self.m_vCamPos.y = self.m_vCamPos.y - self.m_fMouseMoveSpeedX
		-- Move camera up/down
		self.m_vCamPos.x = self.m_vCamPos.x - self.m_fMouseMoveSpeedY
	else
		-- Rotate camera left/right
		self.m_aCamAngle.y = self.m_aCamAngle.y + self.m_fMouseMoveSpeedX
		-- Rotate camera up/down
		self.m_aCamAngle.p = self.m_aCamAngle.p - self.m_fMouseMoveSpeedY
	end
	
	self.m_tMouseMovement = { gui.MousePos() }
end

if input.IsKeyDown( KEY_W ) then -- Forward
	self.m_vCamPos = self.m_vCamPos + self.m_aCamAngle:Forward() * RealFrameTime() * speed
end
if input.IsKeyDown( KEY_A ) then -- Left
	self.m_vCamPos = self.m_vCamPos - self.m_aCamAngle:Right() * RealFrameTime() * speed
end
if input.IsKeyDown( KEY_S ) then -- Back
	self.m_vCamPos = self.m_vCamPos - self.m_aCamAngle:Forward() * RealFrameTime() * speed
end
if input.IsKeyDown( KEY_D ) then -- Right
	self.m_vCamPos = self.m_vCamPos + self.m_aCamAngle:Right() * RealFrameTime() * speed
end

end

local parent
local sl, st, sr, sb = 0, 0, 0, 0
local pl, pt, pr, pb = 0, 0, 0, 0

function PANEL:Paint( w, h )

local x, y = self:LocalToScreen( 0, 0 )

--[[sl, st, sr, sb = x, y, x + w, y + h

parent = self

while parent:GetParent() do
	parent = parent:GetParent()
	pl, pt = parent:LocalToScreen( 0, 0 )
	pr, pb = pl + parent:GetWide(), pt + parent:GetTall()
	sl = sl < pl and pl or sl
	st = st < pt and pt or st
	sr = sr > pr and pr or sr
	sb = sb > pb and pb or sb
end]]

--render.SetScissorRect( sl, st, sr, sb, true )
	cam.Start3D( self.m_vCamPos, self.m_aCamAngle, self.m_iFOV, x, y, w, h )
		render.SuppressEngineLighting( true )
			render.ResetModelLighting( self.m_cAmbientLight.r/255, self.m_cAmbientLight.g/255, self.m_cAmbientLight.b/255 )
			
			for i=0, 6 do
				local col = self.m_tDirectionalLight[ i ]
				if col then
					render.SetModelLighting( i, col.r/255, col.g/255, col.b/255 )
				end
			end
		
			self:Paint3D()
		render.SuppressEngineLighting( false )
	cam.End3D()
--render.SetScissorRect( 0, 0, 0, 0, false )

if self.m_bDebugText then
	draw.SimpleText( "pos: " .. tostring( self.m_vCamPos ), "DefaultSmall", 0, 0, Color(255,0,0) )
	draw.SimpleText( "ang: " .. tostring( self.m_aCamAngle ), "DefaultSmall", 0, 16, Color(255,0,0) )
	draw.SimpleText( "fov: " .. tostring( self.m_iFOV ), "DefaultSmall", 0, 32, Color(255,0,0) )
end

self.m_fLastPaint = RealTime()

end

function PANEL:Paint3D()
– Override this
end

derma.DefineControl( “DPanel3D”, “”, PANEL, “DPanel” )[/lua]

Feel free to use it if you want.

That worked, but I am severely confused about something.

I drew a simple rectangle at 0, 0 with the 3D2D cam at vector_origin, but the actual rectangle is at ~140 x.

[editline]a[/editline]

I found it was because I was calling self:SetPos().
That shouldn’t affect the drawing position, that’s for setting the panel’s position.

[editline]a[/editline]

Okay, this doesn’t make sense.

The panel’s size is 128x512 and the position is 1664, 0.
The rectangle is drawn at 0, 0 and is set with a size of 256, 512.

The actual panel’s position is at 166.4, 0 (3D2D scale is 0.1) and the size is 128, 512.

Can anyone explain this?

This is the code used in that (using Blackawps’ code):

[lua]pDirPanel = pDirPanel or vgui.Create(“DPanel3D”); local mp = pDirPanel;
mp:SetSize(128, 256);
mp:SetPos(ScrW() - 256, 0);
mp:SetDebugText(true);
mp:SetCameraControl(false);
mp:SetCamPos(Vector(166.4, 0, 10));
mp:SetFOV(90);
mp.PaintOver = function(self, w, h)

    surface.SetDrawColor(color_white);
    surface.DrawOutlinedRect(0, 0, w, h);
    
end
mp.Paint3D = function(self, w, h)
    mp:SetCamAngle(EyeAngles());

        cam.Start3D2D(vector_origin, Angle(0, 0, 0), 0.1);
            render.PushFilterMag(TEXFILTER.ANISOTROPIC);
            render.PushFilterMin(TEXFILTER.ANISOTROPIC);
            
            render.SuppressEngineLighting(true);
            
            render.ResetModelLighting(255, 255, 255);
            
            cam.IgnoreZ(true);
                render.SetScissorRect(0, 0, 0, 0, false);
                
                surface.SetDrawColor(color_white);
                surface.DrawRect(0, 0, 256, 512);
                
                surface.SetDrawColor(Color(255, 50, 50))
                surface.DrawRect(0, 0, 16, 16)
                
                surface.SetDrawColor(Color(50, 255, 50))
                surface.DrawRect(240, 240, 16, 16)
                
            cam.IgnoreZ(false);
            
            render.SuppressEngineLighting(false);
            
            render.PopFilterMin();
            render.PopFilterMag();
        cam.End3D2D();
    
end[/lua]

I’m having the same issue, anyone ever find a solution to this?