如何绘制根据相机变焦调整的动态二维网格:OpenGL
How to draw dynamic 2D grid that adjusts according to camera zoom: OpenGL
所以我的问题和标题一样。我不是在寻找具体的代码示例,只是在寻找一些 thoughts/guidelines 的任何首选方法。
在我的 2D 游戏引擎中,我喜欢有一个代表一定数量像素(例如 32x32 像素)的网格。我特别希望能够定义世界中每个网格的宽度和高度space,在所有线条上具有一致的笔触宽度,并能够根据相机变焦调整图块大小。
我过去尝试过几种不同的方法来绘制这个网格:
我尝试的第一件事是使用自定义着色器绘制网格。我在网上找到了一些代码,其中使用了一些我不理解的概念,只是在 2D 平面上绘制网格。这种方法的问题是我不知道如何在我的游戏世界中控制确切的大小,也不了解它的一般工作原理。
我的第二种方法是使用我的调试绘图工具。我编写了一套函数,允许我在世界 space 中添加不同笔划宽度的线条,并且我通过在每一帧为每条线条动态生成四边形来实现它。然后我可以画一堆线,给我一个网格。
我的第三种方法是绘制一堆四边形,然后使用自定义着色器为它们绘制轮廓。然后我就画了一堆黑色轮廓的白色四边形,给出了网格的外观。
有人有更好的解决方案吗?在我所有的方法中,我也从未尝试根据相机的缩放级别动态调整网格。因此,如果有任何关于这些方法是否是典型解决方案,或者是否有更好的解决方案的想法,我们将不胜感激。此外,如果您对如何将这些方法扩展到 3D space 有任何想法,那也很好,我似乎找不到在世界 [=45] 中绘制的线条上获得统一笔画宽度的好方法=].
我的引擎目前也在使用 Opengl 和 C++ 进行编码,所以我主要关心的是如何使用现代 opengl 来实现它,而不是即时模式。
这是我要实现的目标的图片:
编辑:
我主要关心渲染技术。你使用几个四边形吗?一架飞机和一个复杂的着色器?还是每行都使用四边形?还是完全不同?
这是我的一次尝试,作为我试图实现的外观和感觉的另一个参考。我只是忍不住认为必须有比我尝试过的方法更好的方法。
不管渲染方法如何首先你必须计算网格。我是这样做的:
获取屏幕在世界坐标中的 AABB (x0,y0,x1,y1)
最好是拥有 3x3 矩阵,累积所有从世界坐标转换为 GL 屏幕的变换 space:
vec2 world,screen;
mat3 w2s;
screen = w2s*world;
要获得 AABB,我们需要将屏幕角落转换为世界:
mat3 s2w;
s2w = inverse(w2s);
world = s2w*screen;
所以只需将 (+/-1,+/-1)
的所有 4 种组合转换为世界并记住最小值和最大值 x,y
(AABB) 让我们称它们为 (x0,y0,x1,y1)
这个矩阵对于鼠标交互也非常有用因为它会将鼠标(如果转换为屏幕坐标)转换为可用于编辑、选择的世界坐标...
网格大小gx
根据 AABB 计算网格大小。简单地说,如果您的网格是某个世界单位大小的基数(例如 10),那么网格正方形的大小就是这么简单。为简单起见,我将只做单轴(使用两个轴中的最小值或分别做两个轴):
// let consider x0=-50, x1=+180
gx = log10(x1-x0); // bigest power of 10 to fit inside gx = 2.3617278360175928788677771122512
gx = floor(gx-1); // round down and use 10 times smaller grid
gx = pow(10,gx); // your grid size in world coordinates gx=10
网格起始位置
再次将 x0,y0
对齐到 gx,gy...
仅一个轴:
x0 = floor(x0/gx)-1
x0*= gx
渲染
简单地从 x0
循环到 x1
逐步 gx
并渲染线...我通常也会在 gx/10
步进时再做一次并渲染在 gx
步骤行之前一个点或更少的 bright/thick 行。
所以我的问题和标题一样。我不是在寻找具体的代码示例,只是在寻找一些 thoughts/guidelines 的任何首选方法。
在我的 2D 游戏引擎中,我喜欢有一个代表一定数量像素(例如 32x32 像素)的网格。我特别希望能够定义世界中每个网格的宽度和高度space,在所有线条上具有一致的笔触宽度,并能够根据相机变焦调整图块大小。
我过去尝试过几种不同的方法来绘制这个网格:
我尝试的第一件事是使用自定义着色器绘制网格。我在网上找到了一些代码,其中使用了一些我不理解的概念,只是在 2D 平面上绘制网格。这种方法的问题是我不知道如何在我的游戏世界中控制确切的大小,也不了解它的一般工作原理。
我的第二种方法是使用我的调试绘图工具。我编写了一套函数,允许我在世界 space 中添加不同笔划宽度的线条,并且我通过在每一帧为每条线条动态生成四边形来实现它。然后我可以画一堆线,给我一个网格。
我的第三种方法是绘制一堆四边形,然后使用自定义着色器为它们绘制轮廓。然后我就画了一堆黑色轮廓的白色四边形,给出了网格的外观。
有人有更好的解决方案吗?在我所有的方法中,我也从未尝试根据相机的缩放级别动态调整网格。因此,如果有任何关于这些方法是否是典型解决方案,或者是否有更好的解决方案的想法,我们将不胜感激。此外,如果您对如何将这些方法扩展到 3D space 有任何想法,那也很好,我似乎找不到在世界 [=45] 中绘制的线条上获得统一笔画宽度的好方法=].
我的引擎目前也在使用 Opengl 和 C++ 进行编码,所以我主要关心的是如何使用现代 opengl 来实现它,而不是即时模式。
这是我要实现的目标的图片:
编辑: 我主要关心渲染技术。你使用几个四边形吗?一架飞机和一个复杂的着色器?还是每行都使用四边形?还是完全不同?
这是我的一次尝试,作为我试图实现的外观和感觉的另一个参考。我只是忍不住认为必须有比我尝试过的方法更好的方法。
不管渲染方法如何首先你必须计算网格。我是这样做的:
获取屏幕在世界坐标中的 AABB
(x0,y0,x1,y1)
最好是拥有 3x3 矩阵,累积所有从世界坐标转换为 GL 屏幕的变换 space:
vec2 world,screen; mat3 w2s; screen = w2s*world;
要获得 AABB,我们需要将屏幕角落转换为世界:
mat3 s2w; s2w = inverse(w2s); world = s2w*screen;
所以只需将
(+/-1,+/-1)
的所有 4 种组合转换为世界并记住最小值和最大值x,y
(AABB) 让我们称它们为(x0,y0,x1,y1)
这个矩阵对于鼠标交互也非常有用因为它会将鼠标(如果转换为屏幕坐标)转换为可用于编辑、选择的世界坐标...网格大小
gx
根据 AABB 计算网格大小。简单地说,如果您的网格是某个世界单位大小的基数(例如 10),那么网格正方形的大小就是这么简单。为简单起见,我将只做单轴(使用两个轴中的最小值或分别做两个轴):
// let consider x0=-50, x1=+180 gx = log10(x1-x0); // bigest power of 10 to fit inside gx = 2.3617278360175928788677771122512 gx = floor(gx-1); // round down and use 10 times smaller grid gx = pow(10,gx); // your grid size in world coordinates gx=10
网格起始位置
再次将
x0,y0
对齐到gx,gy...
仅一个轴:x0 = floor(x0/gx)-1 x0*= gx
渲染
简单地从
x0
循环到x1
逐步gx
并渲染线...我通常也会在gx/10
步进时再做一次并渲染在gx
步骤行之前一个点或更少的 bright/thick 行。