Problem: the previous load screen was glitchy, i.e. slow.
I spent some time paying attention to timings. At 60fps, we have 16.667ms/frame. At 30fps, 33.333ms/frame.
The calls to love.graphics.origin() and love.graphics.clear() in love.run() themselves get us to 15ms/frame.
So there's no way a LÖVE game can run at 60fps on my (fairly recent 1.4GHz) laptop. And even to run at 30fps – there isn't much time per frame.
I considered bumping down to 10fps. But the degradation is visible, particularly during the loading animation.
I considered smearing work across frames, but for the animation we do have situations where we need to render the entire surface. There's nowhere to hide work.
So, canvas. These changes were arrived at after a lengthy process of learning about LÖVE's notion of quads and how they're used for rendering textures. (A canvas is just a texture once you finish rendering to it.)
In case it helps someone else, some documentation on love.graphics.newQuad(x,y, w,h, sw,sh):
Once you have this quad, the call to love.graphics.draw(canvas, quad, x,y) specifies where to start drawing from in the window coordinates.
All this is what I can understand from experiments. I'm not changing any global settings. No changes to love.graphics.setBlendMode [another gotcha is to setColor(1,1,1) before drawing the canvas], or to Texture:setWrap() [the default wrap mode is clamp, which means areas of the texture outside (0,0) and (sw,sh) take on the values at the boundaries] or anything else I'm ignorant of.
This was hard to debug because I didn't realize I was drawing to a tiny corner of the huge canvas I'd established. I missed that I need to set zoom at 1 when rendering the canvas until very late. Since I was simultaneously trying to figure out the drawing API, I didn't trust I was asking correctly for "show me the whole canvas". Debugging 2 things is hard.
BUFUT2NOLF3GOOFLUEMNFVPOVQNYFYLWWRQWJZ3SKULTSCBXGB5QC
local zoom = math.min(App.screen.width/(maxx-minx), App.screen.height/(maxy-miny))
local zoomx = App.screen.width/(maxx-minx)
local zoomy = App.screen.height/(maxy-miny)
local zoom, cw, ch
if zoomx < zoomy then
zoom = zoomx
cw = maxx-minx
ch = cw*App.screen.height/App.screen.width
else
zoom = zoomy
ch = maxy-miny
cw = ch*App.screen.width/App.screen.height
end
local desired_viewport = Viewport
Global_viewport = {x=minx, y=miny, w=cw, h=ch, zoom=zoom}
-- Render the canvas at pixel perfect resolution.
local winw,winh = App.screen.width, App.screen.height
App.screen.width,App.screen.height = Global_viewport.w, Global_viewport.h
Viewport = {x=minx, y=miny, w=cw, h=ch, zoom=1.0}
A()
Canvas = love.graphics.newCanvas(cw,ch)
love.graphics.setCanvas(Canvas)
App.run_tests = true -- Hack; disable drawing the menu
on.draw()
App.run_tests = nil
love.graphics.setCanvas()
App.screen.width,App.screen.height = winw,winh
-- initialize animation
love.graphics.setColor(1,0,0)
if Animating then
local q = love.graphics.newQuad((Viewport.x-Global_viewport.x)*Viewport.zoom,(Viewport.y-Global_viewport.y)*Viewport.zoom, App.screen.width, App.screen.height, Global_viewport.w*Viewport.zoom, Global_viewport.h*Viewport.zoom)
App.color{r=1,g=1,b=1}
love.graphics.draw(Canvas, q, 0,0)
return
end