Add a RenderingServer method to quickly clone a CanvasItem #7488
gokiburikin
started this conversation in
2D
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Context
I'm making a game where all the graphics are rendered using
RenderingServer.canvas_item_add_multiline
,RenderingServer.canvas_item_add_rect
, and similar calls.It looks like this.
What I'm doing
I make a CanvasItem for each entity so that I can don't have to call of the
draw_*
commands every frame for each of them. This also allows me to change their colours and transforms, but the "initial draw" where I add commands to the CanvasItem is being "wastefully" done each and every time I make a new entity resulting in the exact same CanvasItem "state" before modulate and transforms are applied.These CanvasItems are prepared with an array of lines to draw (with
draw_multiline
) and every time I make a new bullet, enemy, or particle I call the same series of draw commands on it to get it to its "base" state.What I want to do
If I could just "clone" the state of an existing CanvasItem or alternatively tell Godot to render a CanvasItem with two different transforms and modulates (like MultiMesh seems to do) I assume there would be a performance gain.
Why I thought about this solution
I originally was using Polyline but it does not handle sharp turns well so I moved to Multilines. Problem with Multilines is that you don't get corner shaping. My original solution was to call
draw_circle
at each point and that looks great, butdraw_circle
is the slowest thing in the known universe so it brought my game to a crawl.Line Points Visual Comparison
In response I made a little benchmark for testing alternatives to draw_circle that still gave me good results at the scale I was using (very small) and at that size
draw_rect
is mostly good enough. It turned out that a significant amount of time is spent simply calling thedraw_circle
function to prepare the CanvasItem; not actually doing the drawing.Thoughts
Granted, if you're not clearing and re-drawing the CanvasItem each update then you only incur this cost the first time (the intended way to use CanvasItems I imagine), but what this does mean is that moments in the game where there is a lot of instantiation (spawning in a bunch of enemies or projectiles on one frame for example) I perform these functions that result in the exact same commands on each separate CanvasItem apart from whatever unique ids have to be allocated.
Technically I could have a pool of CanvasItems with each shape so I can just pluck one from the pool and if this doesn't pan out that's probably what I will do.
Functionally what I hoped I could do is set up "reference" CanvasItems to call something like
RenderingServer.canvas_item_copy( target_canvas_item:RID, reference_canvas_item:RID )
on and have the same commands be quickly copied over to the new CanvasItem without doing all the calculations. After thesedraw_*
commands all I ever want to do is set their modulate and transforms anyway which doesn't require calling the commands again.It's possible of course that I just don't know how to use MultiMesh through the RenderingServer (I don't know how you'd pass it a CanvasItem as the source mesh) and it is exactly what I'm looking for.
There may even already be code to do this since Nodes can be copy pasted, but I don't know how to search the source code for that.
Beta Was this translation helpful? Give feedback.
All reactions