【问题标题】:A method to rotate a texture in SDL2, C++在 SDL2、C++ 中旋转纹理的方法
【发布时间】:2014-06-15 17:49:30
【问题描述】:

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

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。

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

【问题讨论】:

  • 碰撞检测依赖于SDL_Texture?您是否对代码进行了基准测试以验证渲染时旋转实际上更慢?
  • 好吧,我可以使用纹理进行碰撞还是需要保留表面?如果我不能使用纹理,那么问题必须改为表面旋转。关于速度,是因为每个实体旋转一次,然后多次blit到屏幕上。

标签: c++ methods rotation textures sdl-2


【解决方案1】:

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

至于2),考虑源矩形的中心点为原点,四个向量指向四个顶点。这四个点总是离中心较远的点,所以如果你在旋转后确保它们在纹理内部,你很好。您可以使用以下公式将向量围绕 z 轴旋转角度 a(以弧度为单位):

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

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

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

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

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

来源:lipk

【讨论】:

    猜你喜欢
    • 2021-01-08
    • 1970-01-01
    • 1970-01-01
    • 2013-05-19
    • 2012-09-12
    • 2014-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多