Drawing UI Bits: composition or direct paint?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
RaycatRakittra
Prole
Posts: 22
Joined: Fri Sep 30, 2016 12:40 am
Location: Chicago, IL
Contact:

Drawing UI Bits: composition or direct paint?

Post by RaycatRakittra »

(Still at work so, I can't really jump into the code.)

I was kicking some ideas around in my head and the topic of UI came up. What do you guys do to draw it on the screen? Some people paint it directly inside of love.draw() but does anyone draw to a Canvas like a compositor?

So, instead of:

Code: Select all

function love.draw()
	love.graphics.rectangle(0, 0, 100, 100)
end
you have:

Code: Select all

local composedFrame = new love.graphics.newCanvas()

function love.draw()
	love.graphics.setCanvas(composedFrame)
	love.graphics.clear()
	love.graphics.rectangle(0, 0, 100, 100)
	love.graphics.setCanvas()
	
	love.graphics.draw(composedFrame)
end
I'd imagine this would prevent the possibility of main thread blocking (if it was ever a problem). On the other hand, I'm not so sure. Does this actually save you any headaches?
Sometimes, I can code things.
User avatar
Bunnybacon
Prole
Posts: 20
Joined: Fri Mar 25, 2016 8:42 am

Re: Drawing UI Bits: composition or direct paint?

Post by Bunnybacon »

I am working on a ui system that utilizes the first method.

Something like:

Code: Select all

myUiElement = uiElement.new(0, 0, 100, 100,255)

UiElement:draw = function()
	love.graphics.setColor(255, 255, 255, self.o)
	love.graphics.rectangle("fill", self.x, self.y, self.w, self.h)
end

function drawUI()
	for i = 1, #uiElements, 1 do
		uiElements[i]:draw()
	end
end

function love.graphics.draw()
	drawUI()
end
This is just an example because I am too lazy to dig for my actual code. But I think this is useful, specially if you want to run efficiently on mobile. (edit: I have experienced problems with going canvas-crazy on mobile)
User avatar
ken.athomos
Citizen
Posts: 77
Joined: Fri Aug 05, 2016 10:13 am
Location: Philippines

Re: Drawing UI Bits: composition or direct paint?

Post by ken.athomos »

Admittedly, I don't know how to use Canvases yet or the implications of using them (though I've seen some of the stuff you can do with it via tutorials) so as of the moment, I'm just drawing stuff directly via a draw function.

If you don't mind though, I would like to ask a question. Why use Canvas, does the use of Canvases have any hit to performance (increase or decrease), and would this give you more control in drawing stuff?
User avatar
RaycatRakittra
Prole
Posts: 22
Joined: Fri Sep 30, 2016 12:40 am
Location: Chicago, IL
Contact:

Re: Drawing UI Bits: composition or direct paint?

Post by RaycatRakittra »

ken.athomos wrote: Thu Jun 08, 2017 2:18 pm [...]
If you don't mind though, I would like to ask a question. Why use Canvas, does the use of Canvases have any hit to performance (increase or decrease), and would this give you more control in drawing stuff?
It's just an off-screen render target but yeah, it has more control in regards to overall graphics transformations.
The rest of that question is what this thread was supposed to be about.
Sometimes, I can code things.
User avatar
erasio
Party member
Posts: 118
Joined: Wed Mar 15, 2017 8:52 am
Location: Germany

Re: Drawing UI Bits: composition or direct paint?

Post by erasio »

If you have a lot of static elements that don't change or don't change often. A canvas can increase performance.

Personally I'm not using it for my UI for two reasons.

1. I want the UI to be dynamic (hover animations, etc). Which means I'd have to add and remove stuff from the canvas, redraw it, etc all the time. The performance gain is really minimal and I'm manually controlling the transformation and all that stuff from within my UI handler. Which brings me to

2. My UI is setup in a callback type of way. I have a UI handler that is called in love.draw. Widgets can register to the UI but don't actually provide anything finished. I keep another draw function within each widget to have functionality and graphics encapsulated in that container. So either I end up with tons of canvases (one for each widget) or have one UI canvas (which makes grouping up sub groups of elements not all that great)

However. The widgets are really lightweight. Usually little more than a rectangle + one text. So the performance gain from making them into canvases is negligible.

This allows for amazing control in terms of when to display what (I simply have a visibility bool or can remove a widget or create one at any time), modify location, color, and what not. While I can handle all of the translation stuff for scaling and other modifications inside of the UI handler and have a similar degree of control as I'd have with a canvas. So in the end I have more control over UI elements than one would have with a canvas. Or at least more freedom without redrawing it all the time in which case I might as well draw it directly ;)

TLDR: My answer is. If you have lots of things that do not move. Use a canvas. If you have things that do move or change. Draw directly.
User avatar
ken.athomos
Citizen
Posts: 77
Joined: Fri Aug 05, 2016 10:13 am
Location: Philippines

Re: Drawing UI Bits: composition or direct paint?

Post by ken.athomos »

Thanks for the info erasio!

Now I'll ask it here instead of starting a new thread (because it'll still be about Canvases).

I was wondering why the tutorial on Canvases in the wiki would set the canvas in the love.load? And is this performance related? Thanks.
User avatar
RaycatRakittra
Prole
Posts: 22
Joined: Fri Sep 30, 2016 12:40 am
Location: Chicago, IL
Contact:

Re: Drawing UI Bits: composition or direct paint?

Post by RaycatRakittra »

ken.athomos wrote: Tue Jun 13, 2017 4:05 pm [...]
I was wondering why the tutorial on Canvases in the wiki would set the canvas in the love.load? And is this performance related? Thanks.
I'd imagine they were setting up the Canvas's initial state.
You don't want to constantly reset your Canvas in something like love.update() or love.draw().
The LOVE wiki on love.graphics.newCanvas wrote: This function can be slow if it is called repeatedly, such as from love.update or love.draw. If you need to use a specific resource often, create it once and store it somewhere it can be reused!
Sometimes, I can code things.
User avatar
erasio
Party member
Posts: 118
Joined: Wed Mar 15, 2017 8:52 am
Location: Germany

Re: Drawing UI Bits: composition or direct paint?

Post by erasio »

As RaycatRakitta said.

It's for simplicitys sake.

A prime example for a canvas would be a topdown map.

Let's say you have some houses, a path, a grass texture, etc.

You don't want to draw everything in one picture. Because then modifying anything would mean opening up photoshop or pait.net or gimp or whatever you use and hustle with the layers n stuff.

So instead. You can have all those things be an object that's labeled as static. You draw all of it according to your map file once. Onto a canvas. And now instead of drawing all the sprites individually you draw the canvas once which is already prepared and basically a single picture. Only you still have control over layers and such or can modify it if needed (by drawing it again without one object or simply drawing another element onto it).

And all dynamic elements (like the player, leafs, enemies and what not) can simply be drawn after the canvas (aka ontop of it).

The whole point of the canvas is to not modify it often. So to have an easy tutorial they set it up in load instead of creating a separate function or starting with much more elaborate things :)
Post Reply

Who is online

Users browsing this forum: No registered users and 24 guests