等距倾斜地图滚动
我这里有问题。我正在寻找这个问题的答案有一段时间了,试图自己解决这个问题,但没有结果。这个问题可能被问过很多次,但无论我发现什么,总有一些东西是我不清楚的。 所以: 我正在使用 SDL+OpenGL 编写 2D 游戏。游戏以等轴测视图显示。玩家看到的地图由图块组成,比方说,15x15 的图块(2D 数组)。它看起来像这样: https://i.sstatic.net/sOxcP.png
X 和 Y 是每个图块的索引,但除此之外,这些图块有自己的 X 和 Y 坐标(北顶点,用绿点标记 [0][0] 图块),它们正在其中绘制。
我的问题是,我想为此添加滚动。如果这张地图是 100x100 的图块,那么它的绘制速度会非常慢,因为所有图块都是在屏幕之外绘制的。我不想让它完成。
例如,让我们看一下: https://i.sstatic.net/cPb7V.jpg
蓝色矩形是我的屏幕(800x600,不可调整大小)。整体地图尺寸为 8000x6000,图块按照屏幕上的方式绘制。我知道,我只需要绘制那些标记为绿色的图块,但我的问题是:
如何确定必须绘制哪些图块(我的意思是,使用哪些索引)?
我感谢所有帮助我的尝试。
I have a problem here. I'm searching answer for this for some time now, trying to get into solution by myself, but with no results. This question was probably asked many times, but everywhere I find anything about it, there is always something, that is not clear to me.
So:
I'm writing a 2D game using a SDL+OpenGL. The game is showed in isometric view. Player sees the map that consists from a tiles, let's say, a 15x15 tiles (2D array). It looks like this:
https://i.sstatic.net/sOxcP.png
X and Y are indexes of each tile, but beside this, those tiles have their own X and Y coordinates(north vertex, marked with green dot for [0][0] tile), in which they are beeing drawed.
My problem is, that I want to add scrolling for this. If this map would be 100x100 tiles, it would by drawn very slow, becouse all tiles drawed outside the screen. I don't want it to be done.
Let's look, for example, on this:
https://i.sstatic.net/cPb7V.jpg
Blue rectangle is my screen (800x600, not resizable). The overall map dimensions are 8000x6000, and tiles are drawed as on screen. I know, I need only draw those tiles that are marked on green, but my problem is:
How do I determine which tiles (I mean, with which indexes) have to be drawed?
I appreciate all attempts of helping me.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
为什么不呢?屏幕外的整个三角形都会被剔除,因此您损失的只是顶点传输和变换时间。是的,您应该采取合理的步骤来确保您不会发送可以轻松剔除的内容,但由于您只是绘制简单的 2D 图块地图,因此这不会成为性能问题。即使对于低端硬件也是如此。
这就是为什么过早的优化是错误的。因为你花时间担心一些根本不是问题的事情。当某些事情实际上很慢时而不是可能很慢时进行优化。
一般来说,您应该选择要绘制的图块组。如果其中一个可见,则将其全部绘制出来。这样,您就不必花费大量时间来选择专门绘制的图块。然后,您可以优化传输数据(即:将每个组放入一个缓冲区对象中)并一次性绘制整个组。
Why not? Entire triangles that are off-screen are culled, so all you lose is the vertex transfer and transformation time. Yes, you should take reasonable steps to ensure that you aren't sending stuff you could easily cull out, but since you're just drawing a simple 2D tilemap, it's not going to be a performance problem. Even for low-end hardware.
This is why premature optimizations are wrong. Because you're spending time worrying about something that quite simply is not a problem. Optimize when something is actually slow, not when it might be slow.
In general, you should pick groups of tiles to draw. If one is visible, you draw all of them. That way, you're not spending lots of time selecting which tiles specifically to draw. You can then optimize the data for transfer (ie: putting each group into a buffer object) and just draw the whole group in one go.
我正在回答我自己的问题,因为我不能发布超过 2 个链接(因为我是新人),而且我不能发布任何图像。
我做了一些测试:
对于 100x100,它运行得很好,对于 150x150,它也运行得很好,对于 200x200,它直接掉到地上,对于 500x500,它完全是灾难:
http://imgur.com/msAx4l&EJ9Qw&iKXFZ&ybFt0
(画廊中的 4 个屏幕)
好吧,我正在考虑不需要任何检查,而只需要一些数学方程的解决方案。
例如,在我的另一个游戏(很久以前写的)中,使用方形瓷砖而不是菱形瓷砖,确定绘制瓷砖的索引非常简单。它看起来像这样:
https://i.sstatic.net/bD12V.png
绘制过程:
Here, in等轴测视图,没那么简单,但我不知道如何确定这个起始索引和图块范围。
这是我当前的绘图代码:
I'm answering my own, becouse I can't post more than 2 links (as I am new), and I cant post ANY images.
I made some tests:
for 100x100 it runs nice, for 150x150 too, for 200x200 it drops right down to ground, and for 500x500 its totally disaster:
http://imgur.com/msAx4l&EJ9Qw&iKXFZ&ybFt0
(4 screens in gallery)
well, I was thinking on solution that doesnt require any checking, but just some mathematical equations.
For example, in my other game (written long time ago) with squre tiles, not diamond, it is very simple to determine indexes of drawed tiles. It look's like this:
https://i.sstatic.net/bD12V.png
Drawing procedure for it:
Here, in isometric view, it's not that simple, but I don't know how to determine this starting indexes and ranges of tiles.
Here is my current drawing code:
我会在渲染全部和检查每个图块之间选择一个折衷的解决方案。
在屏幕坐标中查找角块。这将为您提供可见图块的最小和最大 X:Y 位置。现在仅渲染这些边界内的那些图块。 GPU 将裁剪看不见的图块,但您不需要发送所有 8000x6000 图块进行渲染,而只需发送其中的一部分。
如上所述,过早的优化是错误的,因此除非您的地图至少为 800x600 图块,否则我会首先尝试在其他地方搜索瓶颈。例如,按纹理将图块批处理到显示列表或 VBO 中似乎是一个更好的主意。
I would choose a compromise solution between rendering all and checking every tile.
Find corner tiles in screen coords. That will give you minimum and maximum X:Y positions of visible tiles. Now render only those tiles within these bounds. GPU will clip unseen tiles, but you would not need to send all 8000x6000 tiles to render, but only a portion of it.
As noted above, premature optimizations are wrong, so unless your map is at least 800x600 tiles I would try to search a bottleneck elsewhere elsewhere first. E.g. batching tiles by texture into display-lists or VBO seems like a better idea.