Search code examples
canvasluacrashlove2d

Love2d crash when quitting, if window was resized after canvas creation


My problem is, when you resize the window, the quit by pressing a key in the console, love.exe will crash. This happens only when a canvas is used. Here's how to reprodure the crash:

  • Run the .love file
  • Wait for the circle thing to end and window to close
  • Press any key, love.exe should then crash

This will not work if you only run the code, because console needs to be enabled in conf.lua, so please run the love file. If window isn't resized, no crash will occur.

Crash

function draw()
   love.graphics.circle("fill", 100, 100, 50)  -- Draw circle
   love.graphics.setColor(255, 255, 255, 255)
   love.graphics.setCanvas()
   love.graphics.draw(canvas, 0, 0, 0, 2)  -- 200% zoom
   love.graphics.setCanvas(canvas)
   love.graphics.present()  -- Refresh screen
end

love.window.setMode(500, 500)
canvas = love.graphics.newCanvas(1000, 1000)  -- Create canvas
love.graphics.setCanvas(canvas)
draw()  -- Draw circle
love.timer.sleep(1)

love.window.setMode(800, 800)  -- Resize window
love.graphics.setCanvas(canvas)
draw()  -- Redraw circle

love.timer.sleep(2)
love.window.close()
print("Should crash when you quit this by pressing key")
os.execute("pause")
love.event.push("quit")

No crash

function draw()
   love.graphics.circle("fill", 100, 100, 50)  -- Draw circle
   love.graphics.setColor(255, 255, 255, 255)
   love.graphics.setCanvas()
   love.graphics.draw(canvas, 0, 0, 0, 2)  -- 200% zoom
   love.graphics.setCanvas(canvas)
   love.graphics.present()  -- Refresh screen
end

love.window.setMode(500, 500)

canvas = love.graphics.newCanvas(1000, 1000)  -- Create canvas
love.graphics.setCanvas(canvas)
draw()  -- Draw circle
love.timer.sleep(1)

-- Window was resized once, before canvas creation --> no crash

love.window.close()
os.execute("pause")
love.event.push("quit")

Download .love file

Note that I also posted this issue on the LOVE forums here but no good answers yet. I thought maybe I could get an answer here.


Solution

  • As per the setMode documentation:

    Changing the display mode may have side effects: for example, canvases will be cleared and values sent to shaders with Shader:send will be erased. Make sure to save the contents of canvases beforehand or re-draw to them afterward if you need to.

    You can maintain the canvas data and prevent the crash by resetting the render target to being the main screen during the setMode operation:

    love.graphics.setCanvas() -- Reset render target to screen
    love.window.setMode(800, 800)  -- Resize window
    love.graphics.setCanvas(canvas) -- Render to canvas again
    

    HTH,

    Xeozim