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

我正在用C编写一个使用SDL的2D平台游戏.但是,我遇到了一个涉及扩展到解决方案的巨大问题.我想让游戏在全高清看起来很漂亮,所以游戏的所有图像都是创建的,这样游戏的自然分辨率就是1920×1080.然而,如果有人使用较小的分辨率,或者如果有人使用较大的分辨率,则我希望游戏能够缩小到正确的分辨率.

问题是我无法找到一个有效的方式来做到这一点.我开始使用SDL_gfx库预缩放所有图像,但这不起作用,因为它创建了大量的一个一个错误,一个像素丢失了.而且,动画播放时,由于我的动画包含在一个图像中,所以每帧都会稍微向上或向下移动.

然后经过一些回顾,我试过使用opengl来处理缩放.目前,我的程序将所有图像绘制到1920×1080的SDL_Surface.然后将该表面转换为opengl纹理,将该纹理缩放到屏幕分辨率,然后绘制纹理.这在视觉上工作很好,但问题是它的效率不高.目前我得到的最大fps为18:

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

解决方法

这是无效的,因为OpenGL不是设计为这样工作.当前设计的主要性能问题:

>第一个问题:您正在使用SDL软件光栅化.对不起,不管你用这个配置做什么,这将是一个瓶颈.在1920×1080的分辨率下,您有2073,600像素的颜色.假设需要10个时钟周期来遮蔽每个4通道像素,在2GHz处理器上运行的最大值为96.4 fps.这听起来不错,除了你可能不能遮住那些快速的像素,你还没有完成AI,用户输入,游戏机制,声音,物理和其他一切,你可能会画出一些像素至少一次. SDL_gfx可能很快,但对于大分辨率,cpu基本上是超额的.
>第二个问题:每个框架,你将图形总线上的数据复制到GPU.这是你可以用图形方式做的最慢的事情.图像数据可能是最糟糕的数据,因为它通常有这么多.基本上,每个框架你都会告诉GPU将256个像素从RAM复制到VRAM.根据Wikipedia,您可以期望,每个4个字节的2,073,600个像素,不超过258.9 fps,这再一次听起来不错,直到你还记得你需要做的一切.

我的建议:将您的应用程序完全切换到OpenGL.这不需要渲染到纹理并复制到屏幕上 – 只需直接渲染到屏幕上!此外,缩放由您的视图矩阵(glOrtho / gluOrtho2D for 2D)自动处理,因此您完全不必关心缩放问题 – 您的视口将只显示相同尺度的所有内容.这是您的问题的理想解决方案.

现在,它带来了一个主要的缺点,你必须使用OpenGL绘制命令重新编码所有内容(这是非常有用的,但是不要太难,特别是从长远来看).不过,您可以尝试以下想法来提高速度:

>公益组织像素缓冲区对象可以通过使异步的纹理加载/复制来解决问题二.
>多线程你的渲染.大多数cpu至少有两个内核,在较新的芯片上,两个寄存器状态可以节省单个内核(Hyperthreading).您基本上重复了GPU如何解决渲染问题(有很多线程).我不知道如何线程安全SDL_gfx是,但我敢打赌,可以解决一些问题,特别是如果你只是在同一时间处理图像的不同部分.
>确保你注意SDL中你的绘图表面是什么.它应该是SDL_SWSURFACE(因为你正在画在cpu上).
>删除VSync.即使您没有以60Hz运行,也可以提高性能
>确保您绘制原始纹理 – 不要将其缩放到一个新的纹理.绘制不同的大小,让光栅化器做工作!
>偶尔更新:一次更新一半的图像.这可能会使您的“帧速率”翻倍,而且(通常)并不明显.
>类似地,只更新图像的变化部分.

希望这可以帮助.

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...