[QUESTION] How does Canvases work?

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
User avatar
nice
Party member
Posts: 191
Joined: Sun Sep 15, 2013 12:17 am
Location: Sweden

[QUESTION] How does Canvases work?

Post by nice »

Hello boys and girls!

I'm currently working on a project that I call "Helium" (see link to project below), it's pretty much done but when I asked a fellow Löve user they said this:
A paint program would really benefit from using canvases. Actually they'd pretty much be required. The way you have it now works fine at first, but eventually is going to grind to a halt because you're looping through each square every frame. Plus a canvas could be saved just as easy as a screenshot.

You might benefit better from creating a thread if you haven't yet. But a canvas would be my first suggestion.
So I have decided to do a small side project that focuses on saving and canvas functions, so I have made a square in the middle of my screen and to colour it I'm using math.random(0, 255) so every colour is different every time.
I also have a light blue "Ui" at the bottom of the screen and I also have a save icon at the bottom right of the screen inside the Ui.

What I'm wondering is:
1. How does the canvas function actually work?
2. How can I make it so that I draw inside the canvas?
3. How can I save the canvas as a "screenshot"?
4. Is there anything else that I should know about canvases?
5. Does anyone have a good example on how to save images in Löve according to the questions I have just asked?

The idea of this small project is that when I save the image/canvas of the flashing square it will save the colour it currently have, as math.random switches colours every frame (From what I understand how it works) it will save the image in a still frame.
Here's a link to a previous thread that I asked on how to save images:
http://www.love2d.org/forums/viewtopic.php?f=3&t=78913

I hope that I have made myself clear with my questions and I thank you for helping me out.

My small side project:

Code: Select all

function love.load()

canvas = love.graphics.newCanvas(800, 480)
-- Images --
-- Floppy Disc Save Icon
saveIcon = love.graphics.newImage("saveIcon.png")

-- Blue User Interface Bar
ui = love.graphics.newImage("blueUI.png")
end

function love.update()
end

function love.draw()
love.graphics.setBackgroundColor(255, 255, 255)

-- Square With Random Color
love.graphics.setColor( math.random(0, 255), math.random(0, 255), math.random(0, 255) )
love.graphics.rectangle("fill", 350, 250, 120, 120)

-- Part Of The User Interface --
-- User Interface
love.graphics.setColor(255, 255, 255)
love.graphics.draw(ui, 0, 480)

-- Save Icon
love.graphics.draw(saveIcon, 675, 500)
end
Helium project:
https://www.dropbox.com/s/syex5uxkptox0 ... m.zip?dl=0
:awesome: Have a good day! :ultraglee:
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: [QUESTION] How does Canvases work?

Post by davisdude »

nice wrote:1. How does the canvas function actually work?
About like this:

Code: Select all

MyCanvas = love.graphics.newCanvas( Width, Height )
And then draw things to it. So, for example, a red square would be:

Code: Select all

local Canvas = love.graphics.newCanvas( 32, 32 )
love.graphics.setCanvas( Canvas )
    -- I like to indent this code to make it clearer, but you don't have to
    Canvas:clear()
    love.graphics.setColor( 255, 0, 0, 255 )
    love.graphics.rectangle( 'fill', 0, 0, 32, 32 )
love.graphics.setCanvas()
nice wrote:2. How can I make it so that I draw inside the canvas?
See above answer (I'm assuming this is what you mean).
nice wrote:3. How can I save the canvas as a "screenshot"?
Assuming you're drawing just the canvas, that would be something like this:

Code: Select all

love.graphics.draw( Canvas, x, y )
ScreenShot = love.graphics.newScreenshot()
ScreenSchot:encode( OutputFile, Format )
nice wrote:4. Is there anything else that I should know about canvases?
Make sure the graphics card supports canvases and PO2.

Code: Select all

function MakePO2( Width, Height )
	local a, b = 1, 1
	while a < Width do
		a = a * 2
	end
	while b < Height do
		b = b * 2
	end
end

local HasCanvas, P02 = love.graphics.isSupported( 'canvas', 'npot' )
local Width, Height = 12, 24
if not PO2 then
   Width, Height = MakePO2()
end

if HasCanvas then
    -- Draw canvas
end
nice wrote:5. Does anyone have a good example on how to save images in Löve according to the questions I have just asked?
See #3.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
slime
Solid Snayke
Posts: 3172
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: [QUESTION] How does Canvases work?

Post by slime »

davisdude wrote:

Code: Select all

local HasCanvas, P02 = love.graphics.isSupported( 'canvas', 'npot' )
[wiki]love.graphics.isSupported[/wiki] only returns a single value, which will be true if all the graphics feature arguments are supported and false otherwise.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: [QUESTION] How does Canvases work?

Post by davisdude »

Oh. My bad.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Jasoco
Inner party member
Posts: 3727
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: [QUESTION] How does Canvases work?

Post by Jasoco »

davisdude wrote:

Code: Select all

local Canvas = love.graphics.newCanvas( 32, 32 )
love.graphics.setCanvas( Canvas )
    -- I like to indent this code to make it clearer, but you don't have to
    Canvas:clear()
    love.graphics.setColor( 255, 0, 0, 255 )
    love.graphics.rectangle( 'fill', 0, 0, 32, 32 )
love.graphics.setCanvas()
A simpler alternative to this is as follows:

Code: Select all

Canvas:renderTo(function()
    Canvas:clear()
    love.graphics.setColor( 255, 0, 0, 255 )
    love.graphics.rectangle( 'fill', 0, 0, 32, 32 )
end)
Using the renderTo function lets you draw to a canvas without having to switch back. And you can pass a function with the draw stuff in it.

The :clear() part is optional too and should only be called when you want to actually empty your canvas. If you're asking about it for your painting program project then don't use :clear() every frame since that would defeat the purpose of the idea you were trying to achieve. Just clear it once at the beginning to the color of your choice using the normal r,g,b,a format with a being optional.

Also, make sure you're not creating the canvas every frame. Call it once at load and reuse it. Only call it again if you need to resize it or something.
User avatar
nice
Party member
Posts: 191
Joined: Sun Sep 15, 2013 12:17 am
Location: Sweden

Re: [QUESTION] How does Canvases work?

Post by nice »

Jasoco wrote:
davisdude wrote:

Code: Select all

local Canvas = love.graphics.newCanvas( 32, 32 )
love.graphics.setCanvas( Canvas )
    -- I like to indent this code to make it clearer, but you don't have to
    Canvas:clear()
    love.graphics.setColor( 255, 0, 0, 255 )
    love.graphics.rectangle( 'fill', 0, 0, 32, 32 )
love.graphics.setCanvas()
A simpler alternative to this is as follows:

Code: Select all

Canvas:renderTo(function()
    Canvas:clear()
    love.graphics.setColor( 255, 0, 0, 255 )
    love.graphics.rectangle( 'fill', 0, 0, 32, 32 )
end)
Using the renderTo function lets you draw to a canvas without having to switch back. And you can pass a function with the draw stuff in it.

The :clear() part is optional too and should only be called when you want to actually empty your canvas. If you're asking about it for your painting program project then don't use :clear() every frame since that would defeat the purpose of the idea you were trying to achieve. Just clear it once at the beginning to the color of your choice using the normal r,g,b,a format with a being optional.

Also, make sure you're not creating the canvas every frame. Call it once at load and reuse it. Only call it again if you need to resize it or something.
I had a thought about the clear function that you mentioned, the idea is that I tie "clear canvas from stuff" to a key for example the "C" key.
I have it there as a function that I can use whenever I want and it's only activated when I press it.
Also if I take my "Helium" projects drawing functions and put it inside that part of the code, will that work?
slime wrote:
davisdude wrote:

Code: Select all

local HasCanvas, P02 = love.graphics.isSupported( 'canvas', 'npot' )
[wiki]love.graphics.isSupported[/wiki] only returns a single value, which will be true if all the graphics feature arguments are supported and false otherwise.
From what I understand, why is the canvas function so unstable? Is it tied to the graphics card on the computer?
:awesome: Have a good day! :ultraglee:
User avatar
slime
Solid Snayke
Posts: 3172
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: [QUESTION] How does Canvases work?

Post by slime »

nice wrote:From what I understand, why is the canvas function so unstable? Is it tied to the graphics card on the computer?
It's mostly tied to the video driver – almost all drivers support Canvases, but a few really old ones that haven't had any new OpenGL features implemented since ~2005 don't.

There are some stats showing support for various video cards/drivers here: http://feedback.wildfiregames.com/repor ... fer_object
User avatar
nice
Party member
Posts: 191
Joined: Sun Sep 15, 2013 12:17 am
Location: Sweden

Re: [QUESTION] How does Canvases work?

Post by nice »

slime wrote:
nice wrote:From what I understand, why is the canvas function so unstable? Is it tied to the graphics card on the computer?
It's mostly tied to the video driver – almost all drivers support Canvases, but a few really old ones that haven't had any new OpenGL features implemented since ~2005 don't.

There are some stats showing support for various video cards/drivers here: http://feedback.wildfiregames.com/repor ... fer_object
Ah okay, thanks!
:awesome: Have a good day! :ultraglee:
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 5 guests