如何在SDL中扩展到分辨率?

时间:2012-06-15 02:39:55

标签: c++ opengl sdl

我正在使用带有C ++的SDL编写2D平台游戏。但是我遇到了涉及扩展到分辨率的巨大问题。我希望游戏在全高清中看起来不错,因此游戏的所有图像都已创建,因此游戏的自然分辨率为1920x1080。但是,如果有人使用较小的分辨率,我希望游戏缩小到正确的分辨率,如果有人使用更大的分辨率,我希望缩小比例。

问题是我无法找到一种有效的方法来实现这一点。我首先使用SDL_gfx库预先缩放所有图像,但这不起作用,因为它创建了大量的off-by-一个错误,其中一个像素丢失。由于动画播放时我的动画包含在一个图像中,动画会在每帧上下移动。

然后经过一些回顾,我尝试使用opengl来处理缩放。目前我的程序将所有图像绘制到一个1920x1080的SDL_Surface。然后,它将此曲面转换为opengl纹理,将此纹理缩放到屏幕分辨率,然后绘制纹理。这在视觉上很好用,但问题是它根本没有效率。目前我得到的最大fps为18 :(

所以我的问题是,是否有人知道将SDL显示缩放到屏幕分辨率的有效方法?

1 个答案:

答案 0 :(得分:10)

这是低效的,因为OpenGL不是以这种方式工作的。当前设计的主要性能问题:

  • 第一个问题:您使用SDL进行软件光栅化。抱歉,无论您使用此配置执行什么操作,都将成为瓶颈。在1920x1080的分辨率下,你有2073,600像素的颜色。假设需要10个时钟周期来遮蔽每个4通道像素,在2GHz处理器上运行最大为96.4 fps。这听起来不是很糟糕,除非你不能快速遮挡像素,你还没有完成AI,用户输入,游戏机制,声音,物理以及其他所有东西,而且你可能至少要在一些像素上画一些像素。 SDL_gfx可能很快,但对于大分辨率,CPU只是从根本上超过了。
  • 第二个问题:每个帧,您将数据通过图形总线复制到GPU。这是你可能在图形方面做的最慢的事情。图像数据可能是 中最差的,因为它通常有很多。基本上,每个帧都告诉GPU将200万像素从RAM复制到VRAM。根据{{​​3}},您可以预期,每个4字节的2,073,600像素,不超过258.9 fps,在您还记得需要做的其他事情之前,这听起来也不错。

我的建议:将您的应用程序完全切换到OpenGL。这消除了渲染到纹理并复制到屏幕的需要 - 只需直接渲染到屏幕!此外,缩放由您的视图矩阵自动处理(glOrtho / gluOrtho2D用于2D),因此您根本不必关心缩放问题< - 您的视口将只显示所有内容规模。 这是解决您问题的理想方法。

现在,它带来了一个主要的缺点,你必须用OpenGL绘图命令重新编码所有东西(这是工作,但不是太难,特别是从长远来看)。除此之外,您可以尝试以下想法来提高速度:

  • 公益组织。像素缓冲区对象可用于通过使纹理加载/复制异步来解决问题二。
  • 多线程渲染。大多数CPU至少有两个内核,在较新的芯片上,可以为单个内核保存两个寄存器状态(Wikipedia)。你基本上复制了GPU如何解决渲染问题(有很多线程)。我不确定SDL_gfx是如何线程安全的,但我敢打赌,可以解决一些问题,特别是如果你只是同时处理图像的不同部分。
  • 确保注意您的绘图表面在SDL中的位置。应该是SDL_SWSURFACE(因为你正在绘制CPU)。
  • 删除VSync。这可以提高性能,即使您没有以60Hz运行
  • 确保您正在绘制原始纹理 - 请勿将其向上或向下缩放到新纹理。以不同的尺寸绘制它,让光栅化器完成工作!
  • 偶尔更新:一次只更新一半图像。这可能接近你的“帧率”的两倍,并且(通常)不明显。
  • 同样,只更新图像的变化部分。

希望这会有所帮助。