Как нарисовать динамическую c 2D сетку, которая настраивается в соответствии с масштабированием камеры: OpenGL - PullRequest
1 голос
/ 18 июня 2020

Итак, мой вопрос точно такой же, как в заголовке. Я не ищу конкретный пример кода, а просто некоторые мысли / рекомендации по любым предпочтительным методам этого.

В моем движке 2D-игр мне нравится иметь сетку, которая представляет определенное количество пикселей (например, 32x32 пикселя). Я специально хочу иметь возможность определять ширину и высоту каждой сетки в мировом пространстве, иметь одинаковую ширину обводки на всех линиях и иметь возможность регулировать размер плитки в соответствии с масштабированием камеры.

I В прошлом я пробовал несколько разных методов рисования этой сетки:

  1. Первое, что я попробовал, - это использовать собственный шейдер для рисования сетки. Я нашел в Интернете код, в котором использовались некоторые концепции, которые я не понимал, чтобы просто нарисовать сетку на 2D-плоскости. Проблемы с этим подходом заключаются в том, что я не знал, как контролировать точный размер в моем игровом мире, и не понимал, как он работает в целом.

  2. Мой второй подход был использовать мои средства отладки чертежа. Я закодировал набор функций, которые позволяют мне добавлять строки с разной шириной штриха в мировом пространстве, и я реализовал это, просто динамически генерируя квадраты для каждой строки в каждом кадре. Затем я могу нарисовать группу линий, которая дает мне сетку.

  3. Мой третий подход заключался в том, чтобы нарисовать группу четырехугольников и использовать собственный шейдер для придания им контура. Затем я просто рисую кучу белых квадратов с черными контурами, создавая вид сетки.

Есть ли у кого-нибудь лучшее решение? Во всех своих подходах я никогда не пытался динамически настраивать сетку в соответствии с уровнем масштабирования камеры. Поэтому мы будем очень признательны за любые мысли о том, являются ли эти подходы типичными решениями или есть лучшее. Кроме того, если у вас есть какие-либо мысли о том, как распространить эти методы на трехмерное пространство, что тоже было бы неплохо, я не могу найти хороший способ получить одинаковую ширину обводки на линиях, нарисованных в мировом пространстве. * Мой движок в настоящее время кодируется с использованием Opengl и C ++, поэтому меня в первую очередь беспокоит то, как реализовать это, используя современный opengl, а не немедленный режим.

Вот изображение того, чего я пытаюсь достичь: grid example

Изменить: Меня в первую очередь интересуют методы рендеринга. Вы используете несколько квадроциклов? Одна плоскость и сложный шейдер? Или вы используете четверной на каждую линию? Или что-то совсем другое?

Это одна из моих попыток, еще одна ссылка на внешний вид, которого я пытаюсь достичь. Я просто не могу не думать, что должен быть способ лучше, чем те, которые я пробовал. enter image description here

1 Ответ

1 голос
/ 18 июня 2020

независимо от метода рендеринга Сначала вам нужно вычислить сетку. Я делаю это так:

  1. получить AABB (x0,y0,x1,y1) экрана в мировых координатах

    Лучше всего иметь матрицу 3x3 с накопленным всем преобразование преобразования мировых координат в пространство экрана GL:

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

    Чтобы получить AABB, нам нужны противоположные углы преобразования экрана в мир:

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

    Так что просто преобразуйте все 4 комбинации (+/-1,+/-1) в мир и запомнить минимальное и максимальное 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. рендеринг

    просто l oop от x0 до x1 пошагово gx и рендеринг линий ... Обычно я делаю еще один проход, когда шагаю по gx/10 и рендерю только точку или менее яркую / толстую линию перед шагом gx линий.

...