2017-01-26 5 views
1

Я пытаюсь создать 2d карту (для игры, думаю, карту из плиточного мира) в OpenGL ES 2.0 для Android-игры. В принципе, существует несколько типов плитки, которые имеют разные текстуры, а карта генерируется случайным образом из этих типов, поэтому из игры в игру меняется карта, но на протяжении одной игры она остается неизменной.Как текстурировать прямоугольник с несколькими текстурами в OpenGL

Моя первая мысль состояла в том, чтобы сгенерировать одну большую текстуру/изображение/растровое изображение (независимо от OpenGL) заранее, в основном сшивая повторяющиеся текстуры плитки вместе, чтобы сделать большую карту, а затем используя эту единственную текстуру для одного большого прямоугольника карты. В теории я думаю, что это просто и будет работать нормально, но я обеспокоен тем, что он не будет хорошо масштабироваться для больших карт, и особенно на мобильных устройствах. У меня закончится память с такой большой картинной картой. Кроме того, есть небольшой набор плиток, которые дублируются снова и снова, поэтому кажется, что огромные отходы дублируют данные пикселей в большой текстуре снова и снова.

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

Наконец-то я подумал, что использование текстурного атласа может работать, иметь одну текстуру/изображение со всеми данными плитки в нем, это было бы относительно мало. Но я изо всех сил пытаюсь представить, как заставить математику работать так, чтобы «плитки» или подразделы прямоугольника карты использовали совершенно разные координаты текстуры.

Я подхожу к этому неправильно? Должен ли я использовать прямоугольник для каждой плитки? По крайней мере, таким образом я могу передавать шейдеры как вершины, так и текстурные координаты для каждой плитки независимо. Это кажется более простым, но также кажется неправильным, так как карта действительно представляет собой только один прямоугольник, который не будет меняться.

ответ

0

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

  • Actualy, что-то вроде этого уже использовалась в ид Tech ID Software, начиная с версии 4. Это называется MegaTexture. В основном, это большая текстура, которая также может содержать дополнительные данные.

Моя вторая мысль была иметь много текстур ...

  • Вам не нужно держать все текстуры в шейдере. Сделайте это так:

    1. Реализовать цикл с n итерациями, где n - это количество различных типов текстур.

    2. Внутри цикла привяжите текущий тип текстуры.

    3. Передайте любые данные, например, положение/цвет/текстура коордов с шейдерами.

    4. Нарисуйте все плитки, которые используют ограниченную текстуру. Вы можете использовать GLES30.glDrawElementsInstanced или GLES30.glDrawArraysInstanced, если вы используете таргетинг на устройства с GLES 3.x или соответствующую поддержку расширения. В противном случае нарисуйте плитки с помощью GLES20.glDrawArrays или GLES20.glDrawElements.

    Шейдеры не будут сложными при таком подходе.

Наконец, я думал, что с помощью текстурного атласа может работать ...

  • Вы можете использовать цикл здесь и вычислить координаты текстуры для каждого типа плитки на CPU, то просто передайте их в шейдеры.

Учитывая, что ваша карта не меняется в игровой сессии, подход MegaTexture выглядит хорошо. Однако это зависит от того, насколько велика ваша карта и сколько памяти доступно. Также обратите внимание, что максимальный размер текстуры ограничен. Максимальный размер отличается от устройства к устройству, но должен быть (AFAIK) равным или большим размера экрана и не менее 64 текселей (16 для текстур с отображением кубов). Максимальный размер текстуры можно получить на любом устройстве, используя glGet(GL_MAX_TEXTURE_SIZE).

Смежные вопросы