如何在 SDL 中缩放到分辨率
How to scale to resolution in SDL?
我正在使用 SDL 和 C++ 编写一款 2D 平台游戏。但是,我遇到了一个涉及缩放到分辨率的巨大问题。我希望游戏在全高清下看起来不错,因此已经创建了游戏的所有图像,以便游戏的自然分辨率为 1920x1080。但是,如果有人使用较小的分辨率,我希望游戏缩小到正确的分辨率,或者如果有人使用较大的分辨率,则放大到正确的分辨率。
问题是我无法找到一种有效的方法来做到这一点。我首先使用 SDL_gfx 库预先缩放所有图像,但这不起作用,因为它会产生许多逐个错误,其中一个像素丢失。而且由于我的动画包含在一个图像中,当动画播放时,动画会在每一帧中略微向上或向下移动。
然后,经过一番环顾,我尝试使用 opengl 来处理缩放。目前,我的程序将所有图像绘制为 1920x1080 的SDL_Surface。然后,它将此表面转换为 opengl 纹理,将此纹理缩放到屏幕分辨率,然后绘制纹理。这在视觉上工作正常,但问题是它根本没有效率。目前我的最大 fps 为 18 :(
所以我的问题是,有谁知道将 SDL 显示器扩展到屏幕分辨率的有效方法?
它效率低下,因为OpenGL不是为这种工作而设计的。 当前设计的主要性能问题:
- 第一个问题:您正在使用 SDL 进行软件栅格化。 抱歉,但无论您使用此配置做什么,这都将是一个瓶颈。 在 1920x1080 的分辨率下,您需要为 2,073,600 像素着色。 假设每个 4 通道像素着色需要 10 个时钟周期,那么在 2GHz 处理器上,您最多运行 96.4 fps。 这听起来还不错,除了你可能无法那么快地着色像素,而且你还没有做过人工智能、用户输入、游戏机制、声音、物理和其他一切,而且你可能至少画过一次像素。 SDL_gfx可能很快,但对于大分辨率,CPU 从根本上来说是超负荷的。
- 第二个问题:每一帧,你都在通过图形总线将数据复制到 GPU。 这是您在图形方面可以做的最慢的事情。 图像数据可能是其中最糟糕的,因为通常有太多。 基本上,每一帧你告诉GPU将200万个像素从RAM复制到VRAM。 根据维基百科,您可以期望,对于 2,073,600 像素,每个像素 4 字节,不超过 258.9 fps,在您记住您需要做的所有其他事情之前,这听起来还不错。
我的建议:将你的应用程序完全切换到OpenGL。 这样就无需渲染到纹理并复制到屏幕 - 只需直接渲染到屏幕即可! 此外,缩放由视图矩阵(glOrtho/gluOrtho2D for 2D)自动处理,因此您根本不需要关心缩放问题 - 您的视口只会以相同的比例显示所有内容。 这是您问题的理想解决方案。
现在,它有一个主要缺点,即您必须使用 OpenGL 绘制命令重新编码所有内容(这是工作,但不是太难,尤其是从长远来看)。 除此之外,您可以尝试以下想法来提高速度:
- 人民银行。 像素缓冲区对象可用于通过异步加载/复制纹理来解决问题二。
- 多线程渲染。 大多数 CPU 至少有两个内核,在较新的芯片上,可以为单个内核保存两个寄存器状态(超线程)。 你实际上是在复制GPU解决渲染问题的方式(有很多线程)。 我不确定SDL_gfx线程的安全性如何,但我敢打赌可以解决一些问题,特别是如果您只同时处理图像的不同部分。
- 请务必注意绘图表面在 SDL 中的位置。 它可能应该是SDL_SWSURFACE的(因为你是在CPU上绘制的)。
- 删除 VSync。 这可以提高性能,即使您没有以 60Hz 运行
- 确保你正在绘制原始纹理 - 不要将其放大或缩小到新的纹理。 以不同的大小绘制它,然后让光栅器完成工作!
- 偶尔更新:一次只更新一半的图像。 这可能会接近您的"帧速率"的两倍,并且(通常)不明显。
- 同样,仅更新图像的更改部分。
希望这有帮助。
- UE4-如何在给定4个屏幕坐标的情况下缩放纹理或材质
- 计算缩放多边形的比例,得到给定的多边形面积
- QwtPlot具有相等的轴和自动缩放
- 如何在directx/c++中进行平移/缩放操作
- 在Qt中实现无限可缩放的画布
- 是否可以为 QPixmap 派生类嵌入缩放方法?
- 形状对象的旋转和缩放不正确C++
- 如何在 OpenSceneGraph 中缩放/旋转/移动资产
- 如何在OpenGL(GLFW,很高兴)中进行2D缩放?
- 改变或缩放两个正态分布以具有特定的相关系数
- SDL2 调整窗口大小后如何缩放鼠标坐标?
- 如何在OpenGL中正确旋转和缩放对象?
- 仅当类型为 std::complex 时,才进行缩放
- 将 VS Code 用于跨平台可缩放C++项目
- 根据帧速率缩放/缩小数字
- 在 c++ 中缩放浮点值
- 如何防止 DirectX C++程序的拉伸/缩放
- C++ WinRT - 如何动态缩放可写位图以匹配当前屏幕分辨率
- 如何在 Windows 10 上检测辅助监视器的本机屏幕分辨率或缩放因子
- 不支持缩放/固定输出分辨率