如何绘制根据相机变焦调整的动态二维网格:OpenGL

How to draw dynamic 2D grid that adjusts according to camera zoom: OpenGL

所以我的问题和标题一样。我不是在寻找具体的代码示例,只是在寻找一些 thoughts/guidelines 的任何首选方法。

在我的 2D 游戏引擎中,我喜欢有一个代表一定数量像素(例如 32x32 像素)的网格。我特别希望能够定义世界中每个网格的宽度和高度space,在所有线条上具有一致的笔触宽度,并能够根据相机变焦调整图块大小。

我过去尝试过几种不同的方法来绘制这个网格:

  1. 我尝试的第一件事是使用自定义着色器绘制网格。我在网上找到了一些代码,其中使用了一些我不理解的概念,只是在 2D 平面上绘制网格。这种方法的问题是我不知道如何在我的游戏世界中控制确切的大小,也不了解它的一般工作原理。

  2. 我的第二种方法是使用我的调试绘图工具。我编写了一套函数,允许我在世界 space 中添加不同笔划宽度的线条,并且我通过在每一帧为每条线条动态生成四边形来实现它。然后我可以画一堆线,给我一个网格。

  3. 我的第三种方法是绘制一堆四边形,然后使用自定义着色器为它们绘制轮廓。然后我就画了一堆黑色轮廓的白色四边形,给出了网格的外观。

有人有更好的解决方案吗?在我所有的方法中,我也从未尝试根据相机的缩放级别动态调整网格。因此,如果有任何关于这些方法是否是典型解决方案,或者是否有更好的解决方案的想法,我们将不胜感激。此外,如果您对如何将这些方法扩展到 3D space 有任何想法,那也很好,我似乎找不到在世界 [=45] 中绘制的线条上获得统一笔画宽度的好方法=].

我的引擎目前也在使用 Opengl 和 C++ 进行编码,所以我主要关心的是如何使用现代 opengl 来实现它,而不是即时模式。

这是我要实现的目标的图片:

编辑: 我主要关心渲染技术。你使用几个四边形吗?一架飞机和一个复杂的着色器?还是每行都使用四边形?还是完全不同?

这是我的一次尝试,作为我试图实现的外观和感觉的另一个参考。我只是忍不住认为必须有比我尝试过的方法更好的方法。

不管渲染方法如何首先你必须计算网格。我是这样做的:

  1. 获取屏幕在世界坐标中的 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) 这个矩阵对于鼠标交互也非常有用因为它会将鼠标(如果转换为屏幕坐标)转换为可用于编辑、选择的世界坐标...

  2. 网格大小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
    
  3. 网格起始位置

    再次将 x0,y0 对齐到 gx,gy... 仅一个轴:

    x0 = floor(x0/gx)-1
    x0*= gx
    
  4. 渲染

    简单地从 x0 循环到 x1 逐步 gx 并渲染线...我通常也会在 gx/10 步进时再做一次并渲染在 gx 步骤行之前一个点或更少的 bright/thick 行。