Page 1 of 1

[SOLVED] Nested context scale doesn't work

Posted: Wed Oct 01, 2014 12:29 am
by drunken_thor
Hey all, I have been struggling to get this to work and I finally am turned to you. I cannot seem to get scaling working if it is in a nested context let me show you what I mean

Code: Select all

local scale, camera
local canvas1, canvas2, canvas3

function love.load()
  scale = 1
	canvas1 = love.graphics.newCanvas()
	canvas2 = love.graphics.newCanvas()
	canvas3 = love.graphics.newCanvas()

  local w, h = love.graphics.getWidth(), love.graphics.getHeight() 
  canvas1:clear()
  love.graphics.setCanvas(canvas1)
    love.graphics.setColor(255,0,0)  
    love.graphics.rectangle("fill", 50, 50, w - 100, h - 100)
  love.graphics.setCanvas()

  canvas2:clear()
  love.graphics.setCanvas(canvas2)
    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas1, 0, 0)
    love.graphics.setColor(0,255,0)
    love.graphics.rectangle("fill", 75, 75, w - 150, h - 150)
  love.graphics.setCanvas()

  canvas3:clear()
  love.graphics.setCanvas(canvas3)
    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas2, 0, 0)
    love.graphics.setColor(0,0,255)
    love.graphics.rectangle("fill", 100, 100, w - 200, h - 200)
  love.graphics.setCanvas()
end

function love.keypressed(k)
  if k == "escape" then
    love.event.quit()
  end
end

function love.update(dt)
  if love.keyboard.isDown("=") then
    scale = scale + 0.01
  elseif love.keyboard.isDown("-") then
    scale = scale - 0.01
  end
end

function love.draw()
  love.graphics.push()
    love.graphics.scale(scale)
    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas3, 0, 0)
  love.graphics.pop()
end
is how I expect the scaling to work but I need it within other context like thus:

Code: Select all

local scale, camera
local canvas1, canvas2, canvas3

function love.load()
  scale = 1
	canvas1 = love.graphics.newCanvas()
	canvas2 = love.graphics.newCanvas()
	canvas3 = love.graphics.newCanvas()
end

function love.keypressed(k)
  if k == "escape" then
    love.event.quit()
  end
end

function love.update(dt)
  if love.keyboard.isDown("=") then
    scale = scale + 0.01
  elseif love.keyboard.isDown("-") then
    scale = scale - 0.01
  end
end

function love.draw()
  love.graphics.push()
    love.graphics.scale(scale)

    love.graphics.push()
      love.graphics.scale(1) -- This does not work at all

      local w, h = love.graphics.getWidth(), love.graphics.getHeight() 
      canvas1:clear()
      love.graphics.setCanvas(canvas1)
        love.graphics.setColor(255,0,0)  
        love.graphics.rectangle("fill", 50, 50, w - 100, h - 100)
      love.graphics.setCanvas()

      canvas2:clear()
      love.graphics.setCanvas(canvas2)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas1, 0, 0)
        love.graphics.setColor(0,255,0)
        love.graphics.rectangle("fill", 75, 75, w - 150, h - 150)
      love.graphics.setCanvas()

      canvas3:clear()
      love.graphics.setCanvas(canvas3)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas2, 0, 0)
        love.graphics.setColor(0,0,255)
        love.graphics.rectangle("fill", 100, 100, w - 200, h - 200)
      love.graphics.setCanvas()
    love.graphics.pop()

    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas3, 0, 0)

  love.graphics.pop()
end
I would draw them outside of the context if I could but I can't. Can anyone give me any clue how to make the scale act as I expect it to? I have attached both versions of love files for you to see what I mean.

Re: Nested context scale doesn't work

Posted: Wed Oct 01, 2014 8:07 am
by zorg
Untested, but you probably want something like this:

Code: Select all

function love.draw()
  love.graphics.push()
    love.graphics.scale(scale)

    love.graphics.push()
      love.graphics.origin() -- the addition; reset all transformations.
      love.graphics.scale(1) -- This does not work at all

      local w, h = love.graphics.getWidth(), love.graphics.getHeight() 
      canvas1:clear()
      love.graphics.setCanvas(canvas1)
        love.graphics.setColor(255,0,0)  
        love.graphics.rectangle("fill", 50, 50, w - 100, h - 100)
      love.graphics.setCanvas()

      canvas2:clear()
      love.graphics.setCanvas(canvas2)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas1, 0, 0)
        love.graphics.setColor(0,255,0)
        love.graphics.rectangle("fill", 75, 75, w - 150, h - 150)
      love.graphics.setCanvas()

      canvas3:clear()
      love.graphics.setCanvas(canvas3)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas2, 0, 0)
        love.graphics.setColor(0,0,255)
        love.graphics.rectangle("fill", 100, 100, w - 200, h - 200)
      love.graphics.setCanvas()
    love.graphics.pop()

    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas3, 0, 0)

  love.graphics.pop()
end
The wiki has a nice example too: [wiki]love.graphics.origin[/wiki]

Re: Nested context scale doesn't work

Posted: Wed Oct 01, 2014 12:27 pm
by drunken_thor
Sorry I should have been more clear, the scaling is an issue because I need to retain the translation and rotation but reset the scale. this is because I am drawing many canvases, then having them all added to a last one that I want to scale up.

Re: Nested context scale doesn't work

Posted: Wed Oct 01, 2014 5:37 pm
by drunken_thor
okay so someone on reddit was able to give me a good answer/solution you can find it here:https://www.reddit.com/r/love2d/comment ... ue/ckxieez
Scale is relative. scaling to 1 just sets it to what it currently is.
If your first scale is, say, 2 (2/1) then to fix the scale you need to reverse the numbers (1/2). scale 4 -> scale 1/4, etc.
that was the tidbit of info that I did not realize, I did not expect scale to effect even the scale call.

the new code looks like this and works as I expected:

Code: Select all

local scale, camera
local canvas1, canvas2, canvas3

function love.load()
  scale = 1
	canvas1 = love.graphics.newCanvas()
	canvas2 = love.graphics.newCanvas()
	canvas3 = love.graphics.newCanvas()
end

function love.keypressed(k)
  if k == "escape" then
    love.event.quit()
  end
end

function love.update(dt)
  if love.keyboard.isDown("=") then
    scale = scale + 0.01
  elseif love.keyboard.isDown("-") then
    scale = scale - 0.01
  end
end

function love.draw()
  love.graphics.push()
    love.graphics.scale(scale)

    love.graphics.push()
      love.graphics.scale(1/scale)
      local w, h = love.graphics.getWidth(), love.graphics.getHeight() 
      canvas1:clear()
      love.graphics.setCanvas(canvas1)
        love.graphics.setColor(255,0,0)  
        love.graphics.rectangle("fill", 50, 50, w - 100, h - 100)
      love.graphics.setCanvas()

      canvas2:clear()
      love.graphics.setCanvas(canvas2)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas1, 0, 0)
        love.graphics.setColor(0,255,0)
        love.graphics.rectangle("fill", 75, 75, w - 150, h - 150)
      love.graphics.setCanvas()

      canvas3:clear()
      love.graphics.setCanvas(canvas3)
        love.graphics.setColor(255,255,255)
        love.graphics.draw(canvas2, 0, 0)
        love.graphics.setColor(0,0,255)
        love.graphics.rectangle("fill", 100, 100, w - 200, h - 200)
      love.graphics.setCanvas()
    love.graphics.pop()

    love.graphics.setColor(255,255,255)
    love.graphics.draw(canvas3, 0, 0)

  love.graphics.pop()
end

Re: Nested context scale doesn't work

Posted: Thu Oct 02, 2014 6:13 am
by zorg
drunken_thor wrote:Sorry I should have been more clear, the scaling is an issue because I need to retain the translation and rotation but reset the scale. this is because I am drawing many canvases, then having them all added to a last one that I want to scale up.
in that case, the code:

Code: Select all


love.graphics.translate(tx,ty)
love.graphics.rotate(phi)
love.graphics.push()
love.graphics.scale(sx,sy)

-- first canvas stuff, affected by translation, rotation and scale

love.graphics.pop()

-- second canvas stuff -- affected by translation, rotation, but not scaling 

but of course, your method works too; i'm just giving an alternative one :3