In the last tutorial we learned how to load and render png files with alpha layers. This time we’re gonna dive into rotating textures. Or more precisely ; rendering them rotated.
Today we’ll be making a simple, but working, analog clock. This will show how to rotate textures in
SDL2. We’ll also improve how we represent textures
Until now, we have been rendering using
SDL_RencerCopy. But in order to rotate, we need a different function ; int SDL_RenderCopyEx it takes a couple more arguments. I’ll try to explain all of them.
12345678910 SDL_RenderCopyEx(SDL_Renderer* renderer,SDL_Texture* texture,const SDL_Rect* srcrect,const SDL_Rect* dstrectconst double angle,const SDL_Point* center,const SDL_RendererFlip flip)
renderer– the SDL_Renderer we always use for rendering
texture– the SDL_Texture we want to render
srcrect– which part of the SDL_Texture to render. null for everything.
dstrect– where to render it. Used exactly like in SDL_RenderFillRect)
angle– angle of rotation
center– the center of rotation
flip– flipping of texture ( vertical, horizontal, no flip )
As you can see, the first four parameters are identical to
SDL_RenderCopy you can read more about them in part 6.
Texture flip is represented as an SDL_TextureFlip
It is simply an enum with the following three values :
SDL_FLIP_NONE– don’t flip at all
SDL_FLIP_HORIZONTAL– flip horizontaly
SDL_FLIP_VERTICAL– flip vertically
For now, we will just be using
Center of rotation
The center of rotation is given as a position seen from the top-left of the texture ( remember; in
0,0 is the top-left of a texture. ) If the center of rotation is
0,0 you rotate it from the top-left corner.
Finding the center of rotation is usually quite simple, it’ll usually just be the center of the texture you are using. For a circle, like a spinning wheel, the center of rotation will simply be the center of the wheel. Or for a Tetris piece it will be the center of the Tetros piece. The center of a texture is easy to find. Since a center of any rectangle will be halfway along its x axis and halfway along its y axis, the position can be calculate as follows ;
Find Center of TextureC++
123456 // The rect of the texure withSDL_Rect textureRect;SDL_Point center;// Calculate center pos by settingcenter.x = textureRect.w / 2;
The type of
center is one we haven’t used before,
SDL_Point. But an
SDL_Point is simply just a struct with an x and y value.
In our case we are going to make a working analog wall clock. So we can’t rotate it around the middle ( that would be a weird clock! ) What we need to do, is find the base of the hands ( where they connect to the center of the clock )
Here is a picture of on our clock hands. The white hole in the middle is where we want the center of rotation to be. All three hands look very similar to this, all hands have a hole in the base, and all of them rotate around that point.
If you look closely at the green dots, you’ll see that the distance to the hole from either of the sides and the bottom is all the same ( three green dots. ) The green dots span the entire width of the base. So to find the center x value, we simply take half of the width. Looking at the picture, you’ll see that the distance from the bottom to the hole is the same as the distance from the sides subtract half of the width to find the y position of the hole.
So the code for finding the center of rotation will be as follows:
Find Base of handsC++
123467910 SDL_Rect textureRect;SDL_Point textureCenter;// Get half of the width// Center.x is middle of the hand, half the width// Center.y is half of the width above texture bottom.
Putting things together
Previously we have worked with simply storing the
SDL_Rect as separate objects in our main.cpp. But now we also need to store the center of rotation and the angle. So that’s four variables for each texture. With so many variables, it’s a good idea to split it into a separate struct :
We also need to change
main.cpp to make the clock work :
As you can see, there is very little code needed in main since a lot of it is moved into
SDL_RenderCopyEx function can be very useful and is a very simple way of rotating textures. An by wrapping the
SDL_Texture in a separate
struct we can make the remaining code smaller and simpler while still keeping all the functionality we need.
The full code can be downloaded here.
Feel free to comment if you have anything to say or ask questions if anything is unclear. I always appreciate getting comments.You can also email me : firstname.lastname@example.org