简体   繁体   中英

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). 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. 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.

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.

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

    The best is to have 3x3 matrix with accumulated all the transform converting from world coordinates into GL screen space:

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

    To get the AABB we need the opposite transforming screen corners into world:

     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...

  2. grid size gx

    compute grid size from AABB. Simply if your grid is of some world unit size base (like 10) then just simply how big the grid squares will be. For simplicity I will do just single axis (either use min of the 2 axises or do both axises separately):

     // 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

    simply align x0,y0 to gx,gy... again just one axis:

     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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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