I have a Texture class which allows me to load images and render them.
It has the following attributes:
SDL_Texture *m_texture; ///The actual texture
int m_width; ///Its width
int m_height; ///Its height
I wanted to create a method to rotate the texture by an angle. And here’s what I’ve done :
void Texture::rotation( SDL_Renderer *renderer, float angle )
//Target texture to render to
SDL_Texture *target = SDL_CreateTexture( renderer, SDL_PIXELFORMAT_RGBA4444, SDL_TEXTUREACCESS_TARGET, m_width, m_height );
//Set the target texture for rendering
SDL_SetRenderTarget( renderer, target );
//Render m_texture to the target texture with an angle
SDL_RenderCopyEx( renderer, m_texture, NULL, NULL, angle, NULL, SDL_FLIP_NONE );
//Detach the target texture
SDL_SetRenderTarget( renderer, NULL );
SDL_DestroyTexture( m_texture );
m_texture = target;
However, it doesn’t quite work :
- Transparency is lost ( it becomes black ).
- Only a part of the texture is kept because the dimensions for the transformed texture should not be the initial m_width and m_height.
I can’t simply rotate the texture when rendering because of many reasons such as the collision detection and the efficiency. So, how should I do it ?
As for 1), you need to set alpha blending (https://wiki.libsdl.org/SDL_SetTextureBlendMode) on the source and (IIRC) on the target texture.
As for 2), consider the source rectangle’s centerpoint the origin and four vectors pointing to the four vertexes. These four points will always be the further away points from the center, so if you make sure that they’re inside the texture after rotating it, you’re good. You can rotate a vector around the z-axis by the angle a (in radians) with the following formula:
x’ = cos(a) * x - sin(a) * y
y’ = sin(a) * x + cos(a) * y
where (x;y) is the original vector and (x’;y’) is the rotated vector. Apply this transformation to all four vectors, then choose the minimal and maximal x and y values, and you have the boundaries of the target texture.
Well, actually, since there are two parallel pairs of vectors, you can simplify the calculation further: you only need two non-parallel vectors and get the width and height with the following formula:
w = 2max(abs(x1’, x2’))
h = 2max(abs(y1’, y2’))
The only problem with this method is that if you now rotate this texture further, you’ll get an ever growing frame. To avoid this, you could remember the dimensions of the original texture and use that in any subsequent transformation.