c++ - 一种在SDL2、C++中旋转纹理的方法

标签 c++ methods rotation textures sdl-2

我有一个纹理类,它允许我加载图像并渲染它们。 它具有以下属性:

private:
   SDL_Texture *m_texture; ///The actual texture
   int m_width; ///Its width
   int m_height; ///Its height

我想创建一种将纹理旋转一个角度的方法。这是我所做的:

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 );
   //Save texture
   SDL_DestroyTexture( m_texture );
   m_texture = target;
}

然而,它并不完全有效:

  1. 透明度丢失(变成黑色)。
  2. 只保留了一部分纹理,因为转换纹理的尺寸不应该是初始的 m_width 和 m_height。

由于碰撞检测和效率等诸多原因,我不能在渲染时简单地旋转纹理。那么,我应该怎么做呢?

最佳答案

至于 1),您需要在源纹理上设置 alpha 混合,在目标纹理上设置 (IIRC)。

至于 2),将源矩形的中心点视为原点,将四个 vector 指向四个顶点。这四个点将始终是离中心较远的点,因此如果您确保它们在旋转后位于纹理内部,就可以了。您可以使用以下公式将 vector 绕 z 轴旋转角度 a(以弧度为单位):

x' = cos(a) * x - sin(a) * y
y' = sin(a) * x + cos(a) * y

其中 (x;y) 是原始 vector ,(x';y') 是旋转后的 vector 。将此变换应用于所有四个 vector ,然后选择最小和最大 x 和 y 值,您就得到了目标纹理的边界。

嗯,其实,因为有两对平行的 vector ,你可以进一步简化计算:只需要两个不平行的 vector ,用下面的公式得到宽和高:

w = 2*max(abs(x1', x2'))
h = 2*max(abs(y1', y2'))

此方法的唯一问题是,如果您现在进一步旋转此纹理,您将获得不断增长的帧。为避免这种情况,您可以记住原始纹理的尺寸并在任何后续转换中使用它。

来源:lipk

关于c++ - 一种在SDL2、C++中旋转纹理的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24232419/

相关文章:

java - 为什么 A->B 不构成 List<A>->List<B>?这不会消除对通配符的需要吗?

python - 在Python中实现rfind

c++ - 仅在 1 个轴上旋转对象

Android - 仅在父 View 上播放动画

java - 如何旋转缓冲图像而不裁剪它?有没有办法旋转 JLayeredPane 或 JLabel?

c++ - Opencv 函数和宽字符串

c++ - Qt 视频流应用程序 : no service found for qt. mediaplayer

c++ - 简单仿射密码加密解密

java - 在 Java 中执行某些操作并返回指示操作成功的 boolean 值的好习惯是什么?

ruby - 如何在 ruby​​ 中打印 Fixnum 类的所有方法