OpenGL ES 中的大滚动背景

发布于 2024-07-07 17:42:51 字数 461 浏览 7 评论 0原文

我正在为 iPhone 开发一款 2D 卷轴游戏。 我有一个大图像背景,比如 480×6000 像素,只有一部分可见(正好一个屏幕的大小,480×320 像素)。 在屏幕上获得这样的背景的最佳方法是什么?

目前,我将背景分成几个纹理(以绕过最大纹理大小限制),并将每个帧中的整个背景绘制为纹理三角形条。 滚动是通过平移模型视图矩阵来完成的。 剪刀框设置为窗口大小,480×320像素。 这并不意味着要快,我只是想要在优化之前有一个工作代码。

我认为 OpenGL 实现可能足够聪明,可以丢弃背景的不可见部分,但根据我编写的一些测量代码,背景绘制平均需要 7 毫秒,最多需要 84 毫秒。 (这是在模拟器中测量的。)这大约是整个渲染循环的一半,即。 对我来说相当慢。

绘制背景应该像将一些 480×320 像素从 VRAM 的一个部分复制到另一部分一样简单,或者换句话说,速度非常快。 接近这样的性能的最佳方法是什么?

I am working on a 2D scrolling game for iPhone. I have a large image background, say 480×6000 pixels, of only a part is visible (exactly one screen’s worth, 480×320 pixels). What is the best way to get such a background on the screen?

Currently I have the background split into several textures (to get around the maximum texture size limit) and draw the whole background in each frame as a textured triangle strip. The scrolling is done by translating the modelview matrix. The scissor box is set to the window size, 480×320 pixels. This is not meant to be fast, I just wanted a working code before I get to optimizing.

I thought that maybe the OpenGL implementation would be smart enough to discard the invisible portion of the background, but according to some measuring code I wrote it looks like background takes 7 ms to draw on average and 84 ms at maximum. (This is measured in the simulator.) This is about a half of the whole render loop, ie. quite slow for me.

Drawing the background should be as easy as copying some 480×320 pixels from one part of the VRAM to another, or, in other words, blazing fast. What is the best way to get closer to such performance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

じее 2024-07-14 17:42:51

这是最快的方法。 您可以采取以下措施来提高性能:

  • 尝试不同的纹理格式。 SDK 文档大概有关于首选格式的详细信息,并且大概越小越好。
  • 自己剔除完全屏幕外的图块
  • 将图像分割成更小的纹理

我假设您正在以 1:1 的缩放级别进行绘制; 是这样吗?

编辑:哎呀。 更仔细地阅读了您的问题后,我必须提供另一条建议:在模拟器上进行的计时毫无价值。

That's the fast way of doing it. Things you can do to improve performance:

  • Try different texture-formats. Presumably the SDK docs have details on the preferred format, and presumably smaller is better.
  • Cull out entirely offscreen tiles yourself
  • Split the image into smaller textures

I'm assuming you're drawing at a 1:1 zoom-level; is that the case?

Edit: Oops. Having read your question more carefully, I have to offer another piece of advice: Timings made on the simulator are worthless.

做个ˇ局外人 2024-07-14 17:42:51

快速解决方案:

  • 创建图块的几何矩阵(最好是四边形),以便在可视区域的所有侧面至少有一行/列的离屏图块。

  • 将纹理映射到所有这些图块。

  • 一旦一个图块超出了可视区域,您就可以释放该纹理并绑定一个新纹理。

    一旦一个图块超出了可视区域,

  • 使用图块宽度和图块高度的模数作为位置来移动图块(这样,当图块移动了恰好一个图块长度时,它会将自身重新定位在其起始位置)。 还要记住在该操作期间重新映射纹理。 这允许您在任何给定时间加载非常小的网格/非常小的纹理内存。 我认为这在 GL ES 中尤其重要。

如果您有空闲内存并且仍然受到加载速度慢的困扰(尽管您不应该使用那么多纹理)。 您可以构建一个纹理流引擎,当您到达新区域时,该引擎将纹理预加载到更快的内存中(无论目标设备上有什么内存)。 在这种情况下,纹理映射将在需要时从更快的内存中进行。 只需确保您能够在不耗尽所有内存的情况下预加载它,并记住在不需要时动态释放它。

这是 GL(非 ES)图块引擎的链接。 我自己没有使用过它,所以我不能保证它的功能,但它可能可以帮助你: http://www.mesa3d.org/brianp/TR.html

The quick solution:

  • Create a geometry matrix of tiles (quads preferably) so that there is at least one row/column of off-screen tiles on all sides of the viewable area.

  • Map textures to all those tiles.

  • As soon as one tile is outside the viewable area you can release this texture and bind a new one.

  • Move the tiles using a modulo of the tile width and tile height as position (so that the tile will reposition itself at its starting pos when it have moved exactly one tile in length). Also remember to remap the textures during that operation. This allows you to have a very small grid/very little texture memory loaded at any given time. Which I guess is especially important in GL ES.

If you have memory to spare and are still plagued with slow load speed (although you shouldn't for that amount of textures). You could build a texture streaming engine that preloads textures into faster memory (whatever that may be on your target device) when you reach a new area. Mapping as textures will in that case go from that faster memory when needed. Just be sure that you are able to preload it without using up all memory and remember to release it dynamically when not needed.

Here is a link to a GL (not ES) tile engine. I haven't used it myself so I cannot vouch for its functionality but it might be able to help you: http://www.mesa3d.org/brianp/TR.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文