Closed Jaffies closed 5 months ago
I am really confused as to why you'd need this, or how you'd even expect this to work.
You want a global function that converts relative VGUI coordinates, which would be relative to a panel, to screen-space coordinates without using a panel object? Do you see the problem here, or did I misunderstand your intention?
Also, what do you mean "In cases where you have a custom draw function, you can't hold a panel object, because it can be used everywhere."?
You do realize you can pass arguments to a function, yes? The default Panel paint function provides 3: the panel itself (becomes self
when using with PANEL:Paint
calling convention), width and height. No matter what, you have the panel object.
I am really confused as to why you'd need this, or how you'd even expect this to work.
You want a global function that converts relative VGUI coordinates, which would be relative to a panel, to screen-space coordinates without using a panel object? Do you see the problem here, or did I misunderstand your intention?
Also, what do you mean "In cases where you have a custom draw function, you can't hold a panel object, because it can be used everywhere."?
You do realize you can pass arguments to a function, yes? The default Panel paint function provides 3: the panel itself (becomes
self
when using withPANEL:Paint
calling convention), width and height. No matter what, you have the panel object.
The problem is that i DO NOT have access to panel:Paint function or whatever. I have only draw functions which are default replacement to draw. functions. They cant have a panel object inside argument because no any coder will provide this panel object to draw.RoundedBox() for an example.
I have to manually make my own panels and forget about replacing default draw. functions in VGUI.
I have my own function:
function draw.roundedBoxEx(radius, x, y, w, h, color, leftTop, rightTop, rightBottom, leftBottom, materialOverride, outlineColor, outlineLeft, outlineTop, outlineRight, outlineBottom)
in idea it should just replace the default one, but i can't do it because it draws figures in screen space coordinates, not VGUI relative ones. And there's no thing as "pass the self object". Tell that to 100% coders of gmod which use that function, and change 1 million lines of gmod code to pass the goddamn self
argument.
So there's why there should be a global function which converts VGUI relative coordinates.
Still doesnt explain how this is at all an issue unless you are using meshes (even then you should be fine if you render to a rt then (0, 0)).
If your functions replace draw and only you are using them (aka, libname.draw.RoundedBox
) then just pass the argument or create another function libname.draw.RoundedBoxPanel
if your functions replace draw and are overriding _G.draw
, you are doing something wrong if you cannot do exactly what you want. Its not exactly complicated to replace roundedbox with something better, i just think youre going about it in a horrific way.
Please, send your fn decl, id love to see what weird stuff you have going on to need this.
I'm not entirely opposed to having something like this, but this seems like its for the wrong reasons, something like vgui.CurrentRenderingPanel
or GM:PreRenderPanel
GM:PostRenderPanel
would be more useful.
Please correct me if I'm wrong, but I believe the idea here is that in order to create mesh
- or IMesh
-based drop-in replacements for surface
and draw
library functions, you need to be able to determine what the currently active screen origin is.
Inside of PANEL:Paint()
, something is being done to shift the (0,0)
origin point of the screen to the top-left corner of the PANEL
being painted. That shifting only seems to affect the surface
library and its derivatives (Namely draw
.) Because of that, if you're creating a 2D drawing function that uses something like mesh
or IMesh
and the model matrix for positioning, scaling, etc. you have no "good" way to find out where on the screen the (0,0)
origin point currently is to mimic it with whatever drawing method you're using.
You can pass the PANEL
as an argument to the function and then use PANEL:LocalToScreen( 0, 0 )
to figure it out, but that's inconvenient and requires passing around the PANEL
object which is not required for the surface
library. The goal here is to achieve usage parity between how you call a custom draw function and a function from the surface
library.
That's my understanding of the issue but, again, I could be wrong. Please correct me if I am.
In the engine it looks like these surface calls are done through surface()->surfaceFunctionHere
and surface()
just returns g_pVGuiSurface
which looks like a global reference to the current vgui surface being drawn to?
There also seems to be some sort of stack kept in surface to keep track of the currently drawn panel which this could maybe use?
// draw the front of the panel with the inset
if ( _flags.IsFlagSet( PAINT_ENABLED ) )
{
surface()->PushMakeCurrent( vpanel, true );
Paint();
surface()->PopMakeCurrent( vpanel );
}
local function drawQuad(x, y, w, h, color)
--[[
if rubat will add it, then.......
local absoluteX, absoluteY = GetVGUIAbsoluteCoordinates()
x = x + absoluteX
y = y + absoluteY
]]
render.SetColorMaterial()
mesh.Begin(MATERIAL_QUADS, 1)
mesh.Color(color.r, color.g, color.b, color.a)
mesh.Position(Vector(x, y + h))
mesh.AdvanceVertex()
mesh.Color(color.r, color.g, color.b, color.a)
mesh.Position(Vector(x, y))
mesh.AdvanceVertex()
mesh.Color(color.r, color.g, color.b, color.a)
mesh.Position(Vector(x + w, y))
mesh.AdvanceVertex()
mesh.Color(color.r, color.g, color.b, color.a)
mesh.Position(Vector(x + w, y + h))
mesh.AdvanceVertex()
mesh.End()
end
function PANEL:Paint(w, h)
local startX, startY = self:LocalToScreen(0, 0) -- if you do not set startX, startY coordinates, then drawQuad will be rendered in left-top corner of screen. BAAD
drawQuad(startX, startY, w, h, color_white)
end
Basically this is the code that reproduces the issue. Therefore, my recent convo in wayvo encountered my to make a separate issue.
I am really confused as to why you'd need this, or how you'd even expect this to work.
You want a global function that converts relative VGUI coordinates, which would be relative to a panel, to screen-space coordinates without using a panel object? Do you see the problem here, or did I misunderstand your intention?
Also, what do you mean "In cases where you have a custom draw function, you can't hold a panel object, because it can be used everywhere."?
You do realize you can pass arguments to a function, yes? The default Panel paint function provides 3: the panel itself (becomes
self
when using withPANEL:Paint
calling convention), width and height. No matter what, you have the panel object.
Basically this function should return convert realtive VGUI coordinates to absolute screen coordinates. Further notice:
panel:LocalToScreen(0,0)
is bad because it needs panel object In cases where you have a custom draw function, you can't hold a panel object, because it can be used everywhere.