How to change screenspace origin?

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.
tabbul
Prole
Posts: 4
Joined: Sun Dec 08, 2024 6:27 pm

How to change screenspace origin?

Post 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
MrFariator
Party member
Posts: 559
Joined: Wed Oct 05, 2016 11:53 am

Re: How to change screenspace origin?

Post 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).
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: How to change screenspace origin?

Post 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.
tabbul
Prole
Posts: 4
Joined: Sun Dec 08, 2024 6:27 pm

Re: How to change screenspace origin?

Post 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 1404 times
I guess what I'm really asking is how do I move the origin without also moving the content on screen
MrFariator
Party member
Posts: 559
Joined: Wed Oct 05, 2016 11:53 am

Re: How to change screenspace origin?

Post 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 1380 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.
RNavega
Party member
Posts: 385
Joined: Sun Aug 16, 2020 1:28 pm

Re: How to change screenspace origin?

Post 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 1313 times

The same but with other words:
https://stackoverflow.com/a/39296957
User avatar
dusoft
Party member
Posts: 654
Joined: Fri Nov 08, 2013 12:07 am
Location: Europe usually
Contact:

Re: How to change screenspace origin?

Post by dusoft »

Also maybe https://love2d.org/wiki/love.graphics.setScissor might be of help to contain drawing operations.
tabbul
Prole
Posts: 4
Joined: Sun Dec 08, 2024 6:27 pm

Re: How to change screenspace origin?

Post 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.
tabbul
Prole
Posts: 4
Joined: Sun Dec 08, 2024 6:27 pm

Re: How to change screenspace origin?

Post 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 1081 times
User avatar
pgimeno
Party member
Posts: 3672
Joined: Sun Oct 18, 2015 2:58 pm

Re: How to change screenspace origin?

Post 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)
Post Reply

Who is online

Users browsing this forum: Amazon [Bot] and 12 guests