Graphic Transformations Explained

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.
User avatar
MattyAB
Citizen
Posts: 57
Joined: Wed Mar 25, 2015 8:37 pm

Graphic Transformations Explained

Post by MattyAB »

Hey Everyone,

I know I may sound a bit nooby when I say this, but can somebody explain the principle of a 'Graphic Transformation' and what one is used for? I have looked everywhere, and none of the tutorials or wiki pages actually explain what one is...
Please explain!

Thanks!
Check out my blog - The place to find out about the latest tech news! http://thegeekcircle.blogspot.co.uk/
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Graphic Transformations Explained

Post by Jasoco »

I assume you mean stuff like scaling, sheering and rotating images?
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Graphic Transformations Explained

Post by Karai17 »

As Jasoco said, transforming generally refers to translating, rotating, and scaling something.

Translating is when you move the position of the object from one point to another. An example would be making a character walk across the screen. You would say that you are translating the character.

Rotating is when you spin an object along some axis. An example would be the hands on an analog clock. The hands of a clock rotate around the pivot point (which happens to be the centre).

Scaling is when you shrink or grow an object in any proportion. An example of this would be if you make a boss monster that is simply a bigger version of a regular monster,you might scale the sprite up proportionally by 2x or 3x. You can also scale each axis individually, making the sprite stretched or skewed.

You always want to transform in the order listed above: Translate, Rotate, Scale. You can skip any of those steps as needed, but you should not perform that step afterwards. At least not in the same transform group. This means that maybe in frame one you only want to scale, and in frame 2 you want to translate and rotate. This is fine as they are done on different frames and the results will be expected.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
MattyAB
Citizen
Posts: 57
Joined: Wed Mar 25, 2015 8:37 pm

Re: Graphic Transformations Explained

Post by MattyAB »

Okay. So transforming is the movement and scaling of images. So what do the 'Push' and 'Pop' Functions do?

Thanks!
Check out my blog - The place to find out about the latest tech news! http://thegeekcircle.blogspot.co.uk/
User avatar
Jasoco
Inner party member
Posts: 3726
Joined: Mon Jun 22, 2009 9:35 am
Location: Pennsylvania, USA
Contact:

Re: Graphic Transformations Explained

Post by Jasoco »

There's two ways to transform the image on screen. Either you pass the proper values to the image draw call or you use the graphics transformation calls which apply to everything drawn in between.

For example, say I have an image and I want to draw it at 100, 100. I can do this the normal way:

Code: Select all

love.graphics.draw(image, 100, 100)
Or the transformation way:

Code: Select all

love.graphics.push()
love.graphics.transform(100, 100)
love.graphics.draw(image, 0, 0)
love.graphics.pop()
Why bother with the second version? It does the same thing. Note the image being drawn at 0, 0 because the coordinates system itself has been moved to 100, 100 so the image draws relatively to 100, 100. So if you were to put 100, 100 in the image too it would move to 200, 200. Hope that makes sense for you.

Now, the benefit to the second version is that you can put anything you want in between the push and pop and it'll apply to all those drawables. Text, images, quads, meshes, EVERYTHING that can be drawn.

You can ALSO nest push and pop inside others. For example, say you want to rotate an image around its center? For the example, imagine the image is 100, 100 pixels in size. In the first example you would pass half the width and height as the offset X and Y values for the image as well as the rotation in its rotation argument. But for the second example you'd do it a bit differently...

Code: Select all

love.graphics.push()
love.graphics.transform(50, 50)
love.graphics.rotate(1)
love.graphics.transform(-50, -50)
love.graphics.draw(image, 0, 0)
love.graphics.pop()
What's happening here is first the coordinates system is moved to 50, 50, or half the images size. Then it the imagebefore moving it back to the newly rotated 0, 0 position.

Using this method you can do some neat effects. Like utilize scaling to have it scale or zoom the contents from their center.

Play around. Create a sample project with just an image or two and do some tests and see what you can do. Read up on the Wiki for more.

Couple this with an animation library like Flux and you can do some really awesome stuff..


You can do all this cool stuff (Referring to the inventory and shop UI) with a tweening library and the transformation stack.

(Apologies for once again possibly blowing someone's mind with my work. I'm so sorry.)
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Graphic Transformations Explained

Post by Karai17 »

It is worth mentioning that push and pop allow you to stack and remove graphics transforms and other graphics state changes such as color, scissor, etc. When you push onto the graphics stack, you are creating a separate level of graphics state. This is nothing fancy. The important thing here is that you can pop the state off the stack and return to the previous state.

Code: Select all

love.graphics.push()
love.graphics.translate(100, 100)
love.graphics.draw(image1, 0, 0) -- draws at 100,100
love.graphics.pop()

love.graphics.draw(image2, 0, 0) -- draws at 0,0
A common use case for this would be to translate your world so that your player character is always in the centre of the screen without affecting where the UI is drawn

Code: Select all

love.graphics.push()
love.graphics.translate(500, 500)
world:draw()
love.graphics.pop()

gui:draw()
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
User avatar
MattyAB
Citizen
Posts: 57
Joined: Wed Mar 25, 2015 8:37 pm

Re: Graphic Transformations Explained

Post by MattyAB »

Umm.. So I think I get it... The push and pop functions are used to get a certain part of the draw and apply the transformations to it, and then put the transformed graphics with all the other drawables.
I was getting confused but thinking it's some sort of z ordering system or something.

Thanks for the help!
Check out my blog - The place to find out about the latest tech news! http://thegeekcircle.blogspot.co.uk/
User avatar
Karai17
Party member
Posts: 930
Joined: Sun Sep 02, 2012 10:46 pm

Re: Graphic Transformations Explained

Post by Karai17 »

push and pop are used to control the graphics state. If you use love.graphics.setColor within a push, and then pop it away, the color is reset to the previous graphic state's color. That sort of thing.
STI - An awesome Tiled library
LÖVE3D - A 3D library for LÖVE 0.10+

Dev Blog | GitHub | excessive ❤ moé
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Graphic Transformations Explained

Post by davisdude »

Just as a personal preference, I like to indent the code between push and pop to make it more clear.

Code: Select all

function love.draw()
    love.graphics.push()
        love.graphics.scale( 2, 2 )
        love.graphics.circle( 'line', 10, 10, 2 )
    love.graphics.pop()
    love.graphics.circle( 'fill', 10, 10, 2 )
end
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: Graphic Transformations Explained

Post by bobbyjones »

Also I didn't see this mentioned but graphic transformations are done on the coordinate system and everything else follows along with it. So translate moves the origin of the coordinate system by an offset everything being drawn will stay in position relative to the origin. So if you translate the origin to the left by 1 then everything on screen will move left by 1. Scale changes the spacing in between 1 and 2 and so forth. And rotate, rotates the whole coordinate plane. Understanding that the transformations are done on the coordinate plane will help you better utilize them.
Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests