SDL2的硬件加速纹理渲染还能给我们提供图像快速翻转和旋转的能力。在本教程中,我们将利用这一点使一个箭头纹理旋转和翻转。
//Texture wrapper class
class LTexture
{
public:
//Initializes variables
LTexture();
//Deallocates memory
~LTexture();
//Loads image at specified path
bool loadFromFile( std::string path );
//Deallocates texture
void free();
//Set color modulation
void setColor( Uint8 red, Uint8 green, Uint8 blue );
//Set blending
void setBlendMode( SDL_BlendMode blending );
//Set alpha modulation
void setAlpha( Uint8 alpha );
//Renders texture at given point
void render( int x, int y, SDL_Rect* clip = NULL, double angle = 0.0, SDL_Point* center = NULL, SDL_RendererFlip flip = SDL_FLIP_NONE );
//Gets image dimensions
int getWidth();
int getHeight();
private:
//The actual hardware texture
SDL_Texture* mTexture;
//Image dimensions
int mWidth;
int mHeight;
};
在这里,我们为 texture class 添加了更多的功能。渲染函数现在需要一个旋转角度、一个用于旋转纹理的点和SDL翻转枚举[1]。
就像剪裁矩形一样,我们给出了参数的默认值,以防你想在没有旋转或翻转的情况下渲染纹理。
void LTexture::render( int x, int y, SDL_Rect* clip, double angle, SDL_Point* center, SDL_RendererFlip flip ){
//设置渲染空间并渲染至屏幕
SDL_Rect renderQuad = { x, y, mWidth, mHeight };
//设置剪裁渲染尺寸
if( clip != NULL )
{
renderQuad.w = clip->w;
renderQuad.h = clip->h;
}
//渲染到屏幕
SDL_RenderCopyEx( gRenderer, mTexture, clip, &renderQuad, angle, center, flip );
正如你所看到的,我们所做的只是将我们函数中的参数传递给 SDL_RenderCopyEx[2]。这个函数的工作原理与原来的 SDL_RenderCopy 相同,但增加了旋转和翻转的参数。
//Main loop flag
bool quit = false;
//Event handler
SDL_Event e;
//旋转角度
double degrees = 0;
//翻转类型
SDL_RendererFlip flipType = SDL_FLIP_NONE;
在进入主循环之前,我们声明变量来跟踪旋转角度和翻转类型。
//Handle events on queue
while( SDL_PollEvent( &e ) != 0 ){
//User requests quit
if( e.type == SDL_QUIT ){
quit = true;
}else if( e.type == SDL_KEYDOWN ){
switch( e.key.keysym.sym )
{
case SDLK_a:
degrees -= 60;
break;
case SDLK_d:
degrees += 60;
break;
case SDLK_q:
flipType = SDL_FLIP_HORIZONTAL;
break;
case SDLK_w:
flipType = SDL_FLIP_NONE;
break;
case SDLK_e:
flipType = SDL_FLIP_VERTICAL;
break;
}
}
}
在事件循环中,我们想用a/d键增加/减少旋转次数,并用q、w和e键改变翻转类型。
//Clear screen
SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
SDL_RenderClear( gRenderer );
//渲染箭头
gArrowTexture.render( ( SCREEN_WIDTH - gArrowTexture.getWidth() ) / 2, ( SCREEN_HEIGHT - gArrowTexture.getHeight() ) / 2, NULL, degrees, NULL, flipType );
//Update screen
SDL_RenderPresent( gRenderer );
这里我们进行实际的渲染。首先我们传入x和y坐标。这看起来像是一个复杂的公式,但它所做的只是将图像居中。如果图像在640像素宽的屏幕上是440像素宽,我们希望它的每一面都能垫高100像素。换句话说,x坐标将是屏幕宽度(640)减去图像宽度(440),全部除以2 ((640 - 440 ) / 2 = 100)。
下一个参数是剪裁矩形,由于我们要渲染整个纹理,所以设置为空。下一个参数是旋转角度,单位是度。下一个参数是我们要旋转的点。当这个参数为空时,它将围绕图像的中心旋转。最后一个参数是图像的翻转方式。
要想了解如何使用旋转,最好的方法就是玩转它。实验一下,看看通过组合不同的旋转/翻转,你会得到什么样的效果。
[1]
SDL翻转枚举: http://wiki.libsdl.org/SDL_RendererFlip
[2]
SDL_RenderCopyEx: http://wiki.libsdl.org/SDL_RenderCopyEx
[3]
这里: http://www.lazyfoo.net/tutorials/SDL/15_rotation_and_flipping/15_rotation_and_flipping.zip
[4]
原文链接: http://www.lazyfoo.net/tutorials/SDL/15_rotation_and_flipping/index.php