Page 1 of 2

How to change screenspace origin?

Posted: Sun Dec 08, 2024 6:31 pm
by tabbul
I am trying to implement a zoom into a game I am making, but I want it to zoom towards the center; it always zooms towards the top left corner. I looked through the documentation for love.graphics a ton but didn't find anything suiting my needs.
Are there any methods, formal or informal, that I could use?

Thanks
tabbul

Re: How to change screenspace origin?

Posted: Sun Dec 08, 2024 10:22 pm
by MrFariator
The origin point (0,0) in löve's API is the top-left corner, with the coordinates incrementing when going towards down-right. This applies to the screen space coordinates, as well as drawing operations involving things like quads or images (at least, can't think of an example where this isn't the case).

In order to implement zoom in/out effects, you'll have to use functions like love.graphics.translate and love.graphics.scale. Translate for moving the origin point around (so that you can set the "center" where to zoom), and scale for well, scaling things without needing to manually do that with every love.graphics.draw call. Just do keep in mind that you need to "revert" the change afterwards, otherwise your visuals might get messy (love.graphics.push/pop can be useful for this).

Re: How to change screenspace origin?

Posted: Mon Dec 09, 2024 12:12 pm
by RNavega
Besides what MrFariator said, there's also the use of Transform objects.
When you create a Transform with love.math.newTransform(), or when you call its setTransformation() method, you can set the ox, oy offsets that'll be used for the scaling and rotation values sent in that same call.
So when you call setTransformation() and set some sx,sy scale values and also some ox,oy values (like the center of the screen etc), the Transform object will represent a scaling from that position.

You can then use that to draw graphics like this:

Code: Select all

local zoomTF = love.math.newTransform()
(...)

zoomTF:setTransformation(0, 0, 0, zoom, zoom, centerX, centerY)
love.graphics.replaceTransform(zoomTF)

love.graphics.draw(...)
love.graphics.draw(...)
love.graphics.draw(...)

-- In love.run it already resets the current graphics transform, so this is only needed
-- if you're drawing unzoomed things after this.
love.graphics.origin()
Remembering that you can also use a transform object in the one of the overloads for graphics.draw(), like for an additional transform onto each image.

Re: How to change screenspace origin?

Posted: Mon Dec 09, 2024 10:25 pm
by tabbul
I have tried translating the screen, but it also translates everything on screen to the center, which defeats the purpose of translating it.
Here is a video demostrating my problem
ezgif-7-96e3bd77a8.gif
ezgif-7-96e3bd77a8.gif (212.69 KiB) Viewed 1411 times
I guess what I'm really asking is how do I move the origin without also moving the content on screen

Re: How to change screenspace origin?

Posted: Tue Dec 10, 2024 12:56 am
by MrFariator
If you know you are going to be drawing an area of specific size, with an arbitrary zoom, with a moving camera, you can do something like (very crude example):

Code: Select all

local zoom = 1
local posX = 0
local posY = 0

function love.update ( dt )
  if love.keyboard.isDown("z") then
    zoom = math.min ( zoom + 0.016, 4 )
  elseif love.keyboard.isDown("x") then
    zoom = math.max ( zoom - 0.016, 1 )
  end

  if love.keyboard.isDown("up") then
    posY = posY - 4
  elseif love.keyboard.isDown("down") then
    posY = posY + 4
  elseif love.keyboard.isDown("left") then
    posX = posX - 4
  elseif love.keyboard.isDown("right") then
    posX = posX + 4
  end
end

function love.draw ( )
  love.graphics.push ( ) -- not strictly necessary in this example program
  love.graphics.translate ( posX, posY )
  love.graphics.scale ( zoom )

  -- draw a grid of squares for easier visualization
  -- the grid is 32*8 by 32*8, so we know the total size is 256x256 pixels
  -- as such, we offset the drawing by half
  love.graphics.translate ( -128, -128 )
  for x = 1, 8 do
    for y = 1, 8 do
	  love.graphics.setColor  ( (x*32)/256, (y*32)/256, 1, 1)
      love.graphics.rectangle ( "fill", (x-1)*32, (y-1)*32, 32, 32 )
    end
  end
  
  love.graphics.setColor ( 1, 1, 1 )
  love.graphics.pop ( )
end
sample-record.gif
sample-record.gif (3.04 MiB) Viewed 1387 times

There are other approaches (like using transforms like RNavega mentioned), but chaining translate and scale in different orders or compounding them can yield results like this. That said, there are some camera libraries listed on awesome-love2d repo, though I have no experience with them. gamera seems to support some form of zooming at least.

Re: How to change screenspace origin?

Posted: Tue Dec 10, 2024 6:53 am
by RNavega
tabbul wrote: Mon Dec 09, 2024 10:25 pm I guess what I'm really asking is how do I move the origin without also moving the content on screen
Everything scales and rotates around point (0, 0). If you want to scale/rotate about some other point and keep it fixed in space while everything else changes, then you need to do a (negative) translate -> scale -> (positive) translate operations, as explained below.

From some slide presentation on 2D affine transformations:
2D_transformatiomcomputer-graphics-2d-translation-rotation-and-scaling-transformation-and-matrix-representation-39-638.jpg
2D_transformatiomcomputer-graphics-2d-translation-rotation-and-scaling-transformation-and-matrix-representation-39-638.jpg (22.66 KiB) Viewed 1320 times

The same but with other words:
https://stackoverflow.com/a/39296957

Re: How to change screenspace origin?

Posted: Tue Dec 10, 2024 4:57 pm
by dusoft
Also maybe https://love2d.org/wiki/love.graphics.setScissor might be of help to contain drawing operations.

Re: How to change screenspace origin?

Posted: Wed Dec 11, 2024 11:42 pm
by tabbul
I think I am getting closer to solving my problem, thanks for all of the replies. I will go try this out tonight.

Re: How to change screenspace origin?

Posted: Thu Dec 12, 2024 1:03 am
by tabbul
Thanks y'all; I have gotten it to work, slightly modified so it always zooms to the center of the screen.
ezgif-6-3d24e2016f.gif
ezgif-6-3d24e2016f.gif (41.07 KiB) Viewed 1088 times

Re: How to change screenspace origin?

Posted: Fri Dec 13, 2024 10:41 am
by pgimeno
I think RNavega's suggestion of using a transform object was good, it just missed a little detail. This zooms around the centre of the screen, assuming centreX, centreY are set to love.graphics.getWidth()/2 and love.graphics.getHeight()/2 respectively:

Code: Select all

zoomTF:setTransformation(centreX, centreY, 0, zoom, zoom, centreX, centreY)