I made some quick mockups for a simpler explanation.
Here is a list rendered in 2D, which is so big it can't fit on screen. There are 8 entries, but you can only partially see the 5th.
Now, imagine that list rendered in a 3D2D context. You'd expect to now see everything on the list, since it's being rendered in the world with no pesky viewport to stop it.
However, in reality, it won't render anything that you couldn't see in 2D. Things that were only partially off-screen will render, but anything fully off screen is gone. This is of course dependent on the height of your monitor. Not only does this mean vertical monitor gaming finally has a competitive advantage, it means people on lower resolutions will suffer this bug more intensely.
Tested on Linux through Proton, on:
Stable version 2023.07.07
x86-64 version 2023.07.14
dev version 2023.07.17
Steps to reproduce
I have included a short script to replicate this. You can save it to garrysmod/lua/testlist.lua, run lua_openscript_cl testlist.lua, then run test3dlist. This will spawn a list in the world, which says its size and number of children. You might have to look around you. You can pass an argument to change the number of children, like test3dlist 25
Test code
```lua
concommand.Add( "test3dlist", function( player, _, args )
local ChildrenToAdd = args[1] or 10
local list = vgui.Create("DListLayout")
list:SetPaintedManually(true)
list:SetWidth(500)
list:DockMargin(5, 5, 5, 5)
list:SetPaintBackground(true)
list:SetBackgroundColor(Color(0, 100, 100))
local titleLabel = vgui.Create("DLabel", list)
titleLabel:DockMargin(0, 0, 0, 15)
titleLabel:SetContentAlignment(8)
titleLabel:SetFont("DermaLarge")
local function AddEntry()
local panel = vgui.Create("DPanel")
panel:SetHeight(100)
panel:DockMargin(5, 5, 5, 5)
panel:SetPaintBackground(true)
panel:SetBackgroundColor(Color(255, 64, 64, 255))
local countLabel = vgui.Create("DLabel", panel)
countLabel:Dock(FILL)
countLabel:SetContentAlignment(5)
countLabel:SetFont("DermaLarge")
countLabel:SetText("I'm entry " .. list:ChildCount() .. " in the list!")
return panel
end
for i=1, ChildrenToAdd, 1 do
list:Add(AddEntry())
end
list:InvalidateLayout(true)
list:SizeToChildren(true, true)
titleLabel:SetText("I'm " .. list:GetTall() .. "px tall with " .. list:ChildCount()-1 .. " children!")
local eyePos = player:EyePos()
local forward = player:GetForward()
local forwardAngle = forward:Angle()
local pos = eyePos + (forward * 50)
local ang = Angle(0, forwardAngle.y - 90, forwardAngle.r + 90)
hook.Add( "PostDrawTranslucentRenderables", "3DListTest", function()
if not IsValid(list) then return end
cam.Start3D2D(pos, ang, 0.05)
list:PaintManual()
cam.End3D2D()
end )
end )
```
I had to move the fix to an optional argument as it was causing issues with existing addons, so now you'll want to use PaintManual(true) to get the desired effect.
Details
I made some quick mockups for a simpler explanation.
Here is a list rendered in 2D, which is so big it can't fit on screen. There are 8 entries, but you can only partially see the 5th.
Now, imagine that list rendered in a 3D2D context. You'd expect to now see everything on the list, since it's being rendered in the world with no pesky viewport to stop it.
However, in reality, it won't render anything that you couldn't see in 2D. Things that were only partially off-screen will render, but anything fully off screen is gone. This is of course dependent on the height of your monitor. Not only does this mean vertical monitor gaming finally has a competitive advantage, it means people on lower resolutions will suffer this bug more intensely.
Tested on Linux through Proton, on:
Steps to reproduce
I have included a short script to replicate this. You can save it to
garrysmod/lua/testlist.lua
, runlua_openscript_cl testlist.lua
, then runtest3dlist
. This will spawn a list in the world, which says its size and number of children. You might have to look around you. You can pass an argument to change the number of children, liketest3dlist 25
Test code
```lua concommand.Add( "test3dlist", function( player, _, args ) local ChildrenToAdd = args[1] or 10 local list = vgui.Create("DListLayout") list:SetPaintedManually(true) list:SetWidth(500) list:DockMargin(5, 5, 5, 5) list:SetPaintBackground(true) list:SetBackgroundColor(Color(0, 100, 100)) local titleLabel = vgui.Create("DLabel", list) titleLabel:DockMargin(0, 0, 0, 15) titleLabel:SetContentAlignment(8) titleLabel:SetFont("DermaLarge") local function AddEntry() local panel = vgui.Create("DPanel") panel:SetHeight(100) panel:DockMargin(5, 5, 5, 5) panel:SetPaintBackground(true) panel:SetBackgroundColor(Color(255, 64, 64, 255)) local countLabel = vgui.Create("DLabel", panel) countLabel:Dock(FILL) countLabel:SetContentAlignment(5) countLabel:SetFont("DermaLarge") countLabel:SetText("I'm entry " .. list:ChildCount() .. " in the list!") return panel end for i=1, ChildrenToAdd, 1 do list:Add(AddEntry()) end list:InvalidateLayout(true) list:SizeToChildren(true, true) titleLabel:SetText("I'm " .. list:GetTall() .. "px tall with " .. list:ChildCount()-1 .. " children!") local eyePos = player:EyePos() local forward = player:GetForward() local forwardAngle = forward:Angle() local pos = eyePos + (forward * 50) local ang = Angle(0, forwardAngle.y - 90, forwardAngle.r + 90) hook.Add( "PostDrawTranslucentRenderables", "3DListTest", function() if not IsValid(list) then return end cam.Start3D2D(pos, ang, 0.05) list:PaintManual() cam.End3D2D() end ) end ) ```