将顶点缓冲区对象用于基于图块的游戏和纹理图集

发布于 2024-10-06 04:26:28 字数 562 浏览 0 评论 0原文

我正在使用 OpenGL 用 C# 创建一个基于图块的游戏,并且我正在尝试尽可能地优化我的代码。

我读过几篇文章和书籍中的章节,并且都得出相同的结论(您可能知道):使用 VBO 可以极大地提高性能。

然而,我不太确定它们到底是如何工作的。

我的游戏屏幕上会有图块,有些会改变,有些会保持不变。 要为此使用 VBO,我需要将每个图块的坐标添加到数组中,对吗?

此外,为了对这些图块进行纹理处理,我必须为此创建一个单独的 VBO ?

如果我在屏幕上有动画的图块和静态的图块,我不太确定平铺这些坐标的代码会是什么样子。 有人能给我一个快速的概述吗?

我计划使用我所有瓷砖的纹理图集。我不知道从哪里开始使用这个图集来制作纹理瓷砖。 我需要计算要应用的图集中图块的坐标吗?有什么方法可以简单地使用图集的坐标来应用纹理吗?

如果有人可以解决这些问题,我们将不胜感激。我什至可以报销某人的时间和精力。如果需要的话可以帮忙。

谢谢,

格雷格

I'm creating a tile-based game in C# with OpenGL and I'm trying to optimize my code as best as possible.

I've read several articles and sections in books and all come to the same conclusion (as you may know) that use of VBOs greatly increases performance.

I'm not quite sure, however, how they work exactly.

My game will have tiles on the screen, some will change and some will stay the same. To use a VBO for this, I would need to add the coordinates of each tile to an array, correct?

Also, to texture these tiles, I would have to create a separate VBO for this?

I'm not quite sure what the code would look like for tiling these coordinates if I've got tiles that are animated and tiles that will be static on the screen.
Could anyone give me a quick rundown of this?

I plan on using a texture atlas of all of my tiles. I'm not sure where to begin to use this atlas for the textured tiles.
Would I need to compute the coordinates of the tile in the atlas to be applied? Is there any way I could simply use the coordinates of the atlas to apply a texture?

If anyone could clear up these questions it would be greatly appreciated. I could even possibly reimburse someone for their time & help if wanted.

Thanks,

Greg

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

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

发布评论

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

评论(1

听风吹 2024-10-13 04:26:28

好的,让我们把它分成几个部分。 您没有指定要使用哪个版本的 OpenGL - 我假设 GL 3.3。

VBO


顶点缓冲区对象在被视为客户端顶点数组的替代方案时,主要节省 GPU 带宽。瓦片地图并不是真正的几何图形。然而,在最近的 GL 版本中,顶点缓冲区对象是指定顶点的唯一方式(这很有意义),因此我们不能在这里真正谈论“提高性能”。如果您的意思是“与立即模式或客户端数组等已弃用的顶点规范方法相比”,那么是的,您将获得性能提升,但您可能只能在每个顶点超过 10k 的情况下感受到它框架,我想。

纹理图集


纹理图集确实是一个节省纹理切换的好功能。然而,在支持 GL3(和 DX10)的 GPU 上,您可以避免这种技术特有的很多麻烦,因为可以使用更现代、更方便的方法。检查 GL 参考文档 中的 TEXTURE_2D_ARRAY - 您会喜欢它的。如果 GL3 卡是您的目标,请忘记纹理图集。如果没有,请谷歌一下哪些旧卡支持纹理数组作为扩展,我不熟悉细节。

渲染


那么如何高效地绘制瓦片地图呢?让我们关注数据。有很多图块,每个图块都有以下信息:

  • 网格位置(x,y)
  • 材质(我们称其为“材质”而不是“纹理”,因为正如您所说,图像可能会动画并随时间变化;“材质”然后将被解释为“一个纹理或一组随时间变化的纹理”或任何你想要的)。

这应该是您需要发送到 GPU 的所有“每个图块”数据。您希望将每个图块渲染为四边形或三角形条带,因此您有两种选择:

  • 发送 4 个顶点 (x,y),(x+w,y),(x+w,y+h),(x,y +h) 而不是每个图块的 (x,y),
  • 使用几何着色器计算 4 个点以及每发送 1 个点的纹理坐标。

选择你最喜欢的。另请注意,它直接对应于您的 VBO 将包含的内容 - 后一种解决方案会将其缩小 4 倍。

对于材质,您可以将其作为符号整数传递,并且在片段着色器中 - 根据当前时间(作为统一变量传递)和给定图块的材质 ID - 您可以从纹理数组中决定纹理 ID使用。这样就可以制作一个简单的纹理动画了。

OK, so let's split this into parts. You didn't specify which version of OpenGL you want to use - I'll assume GL 3.3.

VBO


Vertex buffer objects, when considered as an alternative to client vertex arrays, mostly save the GPU bandwidth. A tile map is not really a lot of geometry. However, in recent GL versions the vertex buffer objects are the only way of specifying the vertices (which makes a lot of sense), so we cannot really talked about "increasing performance" here. If you mean "compared to deprecated vertex specification methods like immediate mode or client-side arrays", then yes, you'll get a performance boost, but you'd probably only feel it with 10k+ vertices per frame, I suppose.

Texture atlases


The texture atlases are indeed a nice feature to save on texture switching. However, on GL3 (and DX10)-enabled GPUs you can save yourself a LOT of trouble characteristic to this technique, because a more modern and convenient approach is available. Check the GL reference docs for TEXTURE_2D_ARRAY - you'll like it. If GL3 cards are your target, forget texture atlases. If not, have a google which older cards support texture arrays as an extension, I'm not familiar with the details.

Rendering


So how to draw a tile map efficiently? Let's focus on the data. There are lots of tiles and each tile has the following infromation:

  • grid position (x,y)
  • material (let's call it "material" not "texture" because as you said the image might be animated and change in time; the "material" would then be interpreted as "one texture or set of textures which change in time" or anything you want).

That should be all the "per-tile" data you'd need to send to the GPU. You want to render each tile as a quad or triangle strip, so you have two alternatives:

  • send 4 vertices (x,y),(x+w,y),(x+w,y+h),(x,y+h) instead of (x,y) per tile,
  • use a geometry shader to calculate the 4 points along with texture coords for every 1 point sent.

Pick your favourite. Also note that directly corresponds to what your VBO is going to contain - the latter solution would make it 4x smaller.

For the material, you can pass it as a symbolic integer, and in your fragment shader - basing on current time (passed as an uniform variable) and the material ID for a given tile - you can decide on the texture ID from the texture array to use. In this way you can make a simple texture animation.

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