Самый эффективный метод рисования нескольких квадов в OpenGL - PullRequest
0 голосов
/ 14 мая 2010

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

У меня есть класс с именем "ScreenObject", который в основном состоит из

Dictionary<Point, Tile>

Клавиша «Точка» показывает, где можно отобразить плитку на экране, и плитка содержит одну или несколько текстур, которые нужно нарисовать в этой точке. Это ScreenObject, где плитки будут изменены, удалены, добавлены и т. Д.

Мой оригинальный метод рисования тайлов в тестировании, которое я провел, заключался в том, чтобы перебирать ScreenObject и рисовать каждый квад в каждом месте отдельно. Из того, что я прочитал, это огромная трата ресурсов. Это не было ужасно медленно в тестировании, но после того, как я закончил классы анимации и классы эффектов, я уверен, что это будет очень медленно.

И последнее, если не возражаете ... Как я уже говорил, класс Tile может содержать несколько текстур, которые можно нарисовать в точке Point на экране.

Я узнаю, возможно, два варианта для меня здесь. Либо добавьте квад в этом месте для каждой нарисованной текстуры, либо, каким-то образом ... используйте несколько текстур для одного квада (если это возможно). Даже если каждая плитка содержит только одну текстуру, это будет 64 квадратов, которые будут нарисованы на экране. Большинство плиток будет содержать от 2 до 5 текстур, поэтому с помощью этого метода число общих четырехугольников значительно увеличится. Возможно ли добавить квад для каждой новой текстуры, или я игнорирую лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 15 апреля 2013

Я бы рекомендовал использовать один объект VAO, состоящий из треугольников + индексов. Рассчитайте позицию на стороне клиента и просто обновите ее в каждом кадре (потоковая передача).

Используйте текстурный атлас, чтобы хранить все в одной текстуре (чтобы избежать переключения состояний). Вы можете использовать инструмент упаковщика текстур.

Рендеринг за один снимок (если у вас включен буфер глубины). В противном случае рендерит сначала непрозрачные объекты, а затем рендерит все, что нужно смешать

0 голосов
/ 14 мая 2010

Я подозреваю, что использование словаря будет медленнее, чем использование простого массива. Если ваш мир состоит из 512x512 плиток, то вы выделяете массив длиной 512x512 (262144). YВы можете получить любую плитку в этом массиве, используя «array [x + (y * 512)]».

Вы знаете, сколько плиток существует, поэтому храните массив, в котором каждая либо указывает на плитку в этой позиции, либо имеет индекс на плитку в списке (вы, вероятно, сэкономите память таким образом, так как вы, вероятно, сможете сохранить все свои плитки). в массиве размером менее 65536 или, может быть, даже 256, и, таким образом, индекс сохраняется как 16-битный.

Затем вы находите область вашего массива, которую хотите визуализировать. Чтобы сделать это оптимально, вы должны избегать максимально возможного переключения текстур. Итак, во-первых, я бы проверил, насколько велики ваши плитки, а затем попытался бы объединить как можно больше текстур в одну большую текстуру. Затем настройте ваши UV для выборки части этой большой текстуры. Таким образом, вы сможете ограничить количество используемых текстур несколькими большими текстурами. Конечно, вы, вероятно, обнаружите, что в данном наборе плиток (например, на скалистом грунте) будут использоваться те же группы текстур. Также может быть какое-то смешение с травой где-то, так что вполне может стоить удерживать текстуры травы в ОБОИХ больших текстурах, чтобы избежать такого большого количества свопов текстур. т.е. жертвовать видеопамяти на скорость.

Затем вы перебираете видимую часть массива и рисуете все плитки, используя текстуру 1, а затем все плитки, используя текстуру 2 и т. Д.

...