[SOLVED] Canvas remains empty despite drawing operations

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
entuland
Prole
Posts: 6
Joined: Sun Feb 26, 2017 4:41 pm

[SOLVED] Canvas remains empty despite drawing operations

Post by entuland »

Hello,
I've stomped on a strange behavior where a canvas retained the last drawing operation only (as if it got cleared at every love.draw() run).

Trying to reproduce the issue on a reduced program, I've stomped on a different (but perhaps connected) weird behavior where the same operations get performed on two canvases, the first canvas retains all data and works fine while the second remains completely blank.

Here is the code:

Code: Select all

local handler = {}

function handler.load()
  handler.canvas1 = love.graphics.newCanvas(100, 100)
  handler.canvas2 = love.graphics.newCanvas(100, 100)
  
  love.graphics.setCanvas(handler.canvas1)
  love.graphics.clear(255, 0, 0)
  love.graphics.print("this is canvas 1")
  
  love.graphics.setCanvas(handler.canvas2)
  love.graphics.clear(0, 255, 0)
  love.graphics.print("this is canvas 2")
end

function handler.update()
  handler.randomLine(handler.canvas1)
  handler.randomLine(handler.canvas2)
end

function handler.randomLine(canvas)
  love.graphics.setBlendMode("alpha")
  love.graphics.setCanvas(canvas)
  local l = {
    x1 = math.random(20, 80),
    y1 = math.random(20, 80),
    x2 = math.random(20, 80),
    y2 = math.random(20, 80),
    r = math.random(192, 255),
    g = math.random(192, 255),
    b = math.random(192, 255),
  }
  love.graphics.setColor(l.r, l.g, l.b)
  love.graphics.line(l.x1, l.y1, l.x2, l.y2)
end

function handler.flipCanvas(canvas, x, y)
  love.graphics.setBlendMode("alpha", "premultiplied")
  love.graphics.setColor(255, 255, 255)
  love.graphics.draw(canvas, x, y)
end

function handler.draw()
  love.graphics.setCanvas()
  love.graphics.setBlendMode("alpha")
  love.graphics.clear(0, 0, 255)
  handler.flipCanvas(handler.canvas1, 10, 10)
  handler.flipCanvas(handler.canvas2, 120, 120)
end

local game = {}

function love.load()
  game.handler = handler
  game.handler.load()
end

function love.update(dt)
  game.handler.update(dt)
end

function love.draw()
  game.handler.draw()
end
And here is what I get to see running the above code:
lua-canvas-test.png
lua-canvas-test.png (13.29 KiB) Viewed 3749 times
That is, canvas1 gets drawn, canvas2 appears as just a black square.

Any advice about how to troubleshoot the issue?

Thanks for your attention, cheers!

[Solution: since love.graphics.clear() gets called between love.update() and love.draw(), the currently active drawing target (in my case handler.canvas2) gets blanked out; the solution is to reset the drawing target with love.graphics.setCanvas() before getting into love.draw() or to refactor the code to use a different approach, see messages below for the details]
Last edited by entuland on Mon Mar 06, 2017 2:28 pm, edited 1 time in total.
User avatar
0x72
Citizen
Posts: 55
Joined: Thu Jun 18, 2015 9:02 am

Re: Canvas remains empty despite drawing operations

Post by 0x72 »

This is because after love.update and before love.draw the love.graphics.clear is called.

https://love2d.org/wiki/love.run

Code: Select all

-- ...
  if love.update then love.update(dt) end
 
  if love.window and love.graphics and love.window.isCreated() then
    love.graphics.clear() -- <- HERE
    love.graphics.origin()
    if love.draw then love.draw() end
    love.graphics.present()
  end
-- ...
In order to fix that you can do one of those:
- move your drawing to from love.update (and love.load) to love.draw (best option)
- alter your love.run so it resets target back to screen before the love.graphics.clear (love.graphics.setCanvas())
- alter your love.update so it resets target back to screen just before it finish (love.graphics.setCanvas())
entuland
Prole
Posts: 6
Joined: Sun Feb 26, 2017 4:41 pm

Re: Canvas remains empty despite drawing operations

Post by entuland »

0x72, thanks a lot for the insight, now the issue is fully clear and this will surely help me sort out the original issue as well.

I think I'll go with :renderTo() - as advised on the #love irc channel - so that I don't have to mess with setCanvas() at all, seems the safest option so far.

Thanks again 0x72!
User avatar
zorg
Party member
Posts: 3465
Joined: Thu Dec 13, 2012 2:55 pm
Location: Absurdistan, Hungary
Contact:

Re: [SOLVED] Canvas remains empty despite drawing operations

Post by zorg »

For the sake of completion, as mentioned on IRC as well, the real issue was that the render target was never set back to the window, it was on the second canvas when love.update ended, meaning the love.graphics.clear call in love.run cleared that canvas, instead of the window; putting a love.graphics.setCanvas() at the end of love.update would have solved it as well, but renderTo is safer in that regard.
Me and my stuff :3True Neutral Aspirant. Why, yes, i do indeed enjoy sarcastically correcting others when they make the most blatant of spelling mistakes. No bullying or trolling the innocent tho.
entuland
Prole
Posts: 6
Joined: Sun Feb 26, 2017 4:41 pm

Re: [SOLVED] Canvas remains empty despite drawing operations

Post by entuland »

zorg, yep, I mentioned that as part of the solution editing the original post, thanks for the feedback on IRC too :)
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest