简体   繁体   English

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

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

So my question is exactly like the title states.所以我的问题和标题一样。 I'm not looking for a concrete code example, just some thoughts/guidelines on any preferred methods of doing this.我不是在寻找具体的代码示例,只是关于任何首选方法的一些想法/指南。

In my 2D game engine, I like to have a grid that represents a certain amount of pixels (eg 32x32 pixels).在我的 2D 游戏引擎中,我喜欢有一个网格来表示一定数量的像素(例如 32x32 像素)。 I specifically want to be able to define, the width and height of each grid in world space, have a consistent stroke width on all the lines, and be able to adjust the tile size according to camera zoom.我特别希望能够定义世界空间中每个网格的宽度和高度,在所有线条上具有一致的笔划宽度,并且能够根据相机缩放调整图块大小。

I've tried several different methods in the past to draw this grid:我过去尝试过几种不同的方法来绘制这个网格:

  1. The first thing I tried was using a custom shader to draw a grid.我尝试的第一件事是使用自定义着色器来绘制网格。 I found some code online that used some concepts I didn't understand to just draw the grid on a 2D plane.我在网上找到了一些代码,这些代码使用了一些我不理解的概念,只是在 2D 平面上绘制网格。 The problems with this approach are that I didn't know how to control the exact size in my game world, and didn't understand how it worked in general.这种方法的问题是我不知道如何在我的游戏世界中控制确切的大小,也不了解它是如何工作的。

  2. My second approach was to use my debug drawing facilities.我的第二种方法是使用我的调试绘图工具。 I coded a suite of functions that allows me to add lines of different stroke widths in world space, and I implemented that by just dynamically generating quads for each line every frame.我编写了一套函数,允许我在世界空间中添加不同笔划宽度的线条,我通过为每一帧的每一行动态生成四边形来实现这一点。 I can then draw a bunch of lines which gives me a grid.然后我可以画一堆线,给我一个网格。

  3. My third approach was to draw a bunch of quads, and use a custom shader to give them an outline.我的第三种方法是绘制一堆四边形,并使用自定义着色器给它们一个轮廓。 Then I just draw a bunch of white quads with black outlines, giving the appearance of a grid.然后我只画了一堆带有黑色轮廓的白色四边形,呈现出网格的外观。

Does anybody have a better solution?有人有更好的解决方案吗? In all my approaches I have never tried to adjust the grid dynamically according to the camera's zoom level either.在我所有的方法中,我也从未尝试过根据相机的缩放级别动态调整网格。 So any thoughts on whether these approaches are the typical solutions, or if there is a better one would be much appreciated.因此,对于这些方法是否是典型解决方案或是否有更好的解决方案的任何想法将不胜感激。 Also, if you have any thoughts on how to extend these methods to 3D space that would also be nice, I can't seem to find a good way to get a uniform stroke width on lines drawn in world space.此外,如果您对如何将这些方法扩展到 3D 空间有任何想法,那也很好,我似乎找不到在世界空间中绘制的线条上获得统一笔划宽度的好方法。

My engine is currently being coded using Opengl and C++ too, so I'm primarily concerned on how to implement this using modern opengl, not immediate mode.我的引擎目前也在使用 Opengl 和 C++ 进行编码,所以我主要关心如何使用现代 opengl 来实现这一点,而不是立即模式。

Here's an image of what I'm trying to achieve:这是我要实现的目标的图像: 网格示例

Edit: I am primarily concerned with rendering techniques.编辑:我主要关心渲染技术。 Do you use several quads?你使用几个四边形吗? One plane and a complex shader?一个平面和一个复杂的着色器? Or do you use a quad for each line?或者您是否为每条线使用四边形? Or something else entirely?还是完全不同的东西?

This is one of my attempts, for another reference of the look and feel I'm trying to achieve.这是我的尝试之一,作为我试图实现的外观和感觉的另一个参考。 I just can't help but think there has to be a better method then the ones I've tried.我只是忍不住认为必须有比我尝试过的方法更好的方法。 在此处输入图像描述

regardless of the rendering method First you have to compute the grid.不管渲染方法如何 首先你必须计算网格。 I do it like this:我这样做:

  1. get AABB (x0,y0,x1,y1) of screen in world coordinates在世界坐标中获取屏幕的 AABB (x0,y0,x1,y1)

    The best is to have 3x3 matrix with accumulated all the transform converting from world coordinates into GL screen space:最好的方法是累积所有从世界坐标转换到 GL 屏幕空间的 3x3 矩阵:

     vec2 world,screen; mat3 w2s; screen = w2s*world;

    To get the AABB we need the opposite transforming screen corners into world:要获得 AABB,我们需要将屏幕角落转换为世界:

     mat3 s2w; s2w = inverse(w2s); world = s2w*screen;

    So simply transform all 4 combinations of (+/-1,+/-1) into world and remember the min and max x,y (AABB) lets call them (x0,y0,x1,y1) This matrix is also extra usefull for mouse interaction as it will transform mouse (if converted to screen coordinates) into world coordinates which you can use for editing,selecting...因此,只需将(+/-1,+/-1)的所有 4 种组合转换为世界并记住最小和最大x,y (AABB) 让我们称它们为(x0,y0,x1,y1)这个矩阵也非常有用用于鼠标交互,因为它将鼠标(如果转换为屏幕坐标)转换为可用于编辑、选择的世界坐标...

  2. grid size gx网格大小gx

    compute grid size from AABB.从 AABB 计算网格大小。 Simply if your grid is of some world unit size base (like 10) then just simply how big the grid squares will be.简单地说,如果您的网格是某个世界单位大小的基数(例如 10),那么只需简单的网格正方形有多大。 For simplicity I will do just single axis (either use min of the 2 axises or do both axises separately):为简单起见,我将只做单轴(使用 2 个轴中的最小值或分别做两个轴):

     // 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. grid start position电网启动 position

    simply align x0,y0 to gx,gy... again just one axis:只需将x0,y0gx,gy...再次对齐一个轴:

     x0 = floor(x0/gx)-1 x0*= gx
  4. render使成为

    simply loop from x0 to x1 by step gx and render lines... I usually do also another pass when I step by gx/10 and render just a dot or less bright/thick line prior to the gx step lines.只需按步gxx0循环到x1并渲染线条...当我按gx/10步进并在gx步进线之前仅渲染一个点或不太亮/粗的线时,我通常还会做另一遍。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM