Навигация
Поддержать материально
Steam Greenlight

Логотипы
Медальки
Гость
Имя

Пароль



Вы не зарегистрированны?
Нажмите здесь для регистрации.

Забыли пароль?
Запросите новый здесь.
Темы форума
185 - RPG
9.02.2024
 Vaskrol
В каком банке открыт…
24.01.2024
 Darthman
185 - ?
30.12.2023
 Mefistofel
TESTAMENT - Тактичес…
15.11.2023
 KregHek
WoL
13.10.2023
 Darthman
RES - Движок для пик…
27.09.2023
 rimush
177 - One Button Str…
20.09.2023
 VoroneTZ
JS 13k contest
13.09.2023
 Mefistofel
184 - Arcade II
14.08.2023
 tiger1025
184 - ?
14.07.2023
 Kaps
Сейчас на сайте
Гостей: 2
На сайте нет зарегистрированных пользователей

Пользователей: 1,787
новичок: vovasmirnov198
Обсуждение «Рендеринг тайловой карты»
IvanN
Avatar пользователя

Опубликовано 04.03.2014 06:27 (10 лет назад)    #
Здравствуйте. В игрострое я новичок, вот пытаюсь разобраться как в играх рендерится 2D тайловая карта игрового уровня. Применительно к OpenGL.
С ходу в голову пришло два варианта:
1. Создается плоскость в размер экрана и массив текстурных координат. Берем координаты из массива и натягиваем тайлы на плоскость.
2. Сдвигаем 0 системы координат в левый нижний/верхний угол (ортографическая проекция) и рисуем сетку QUADов, на которые натягиваем текстуры.

Вопрос, собственно, какой подход лучше, может вообще какой-то третий или четвертый до которого я еще не додумался? И где будет меньше проблем с прокруткой карты на экране?
MysticCoder
Avatar пользователя

Опубликовано 04.03.2014 09:13 (10 лет назад)    #
я обычно делаю так.... массив[0..MapWidth,0..MapHeight], значения массива - тип тайла(или одно из значений записи, если нужна еще карта проходимости и прочая инфа), ну а дальше просто отображаешь квады, используя положение в массиве как координаты, а текстурные координаты берешь исходя из значения массива либо для каждого тайла отдельную текстуру.
Если нужно прокрутить карту, то просто сдвигаешь камеру.
IvanN
Avatar пользователя

Опубликовано 04.03.2014 09:28 (10 лет назад)    #
То есть получается выводим целиком локацию, полагаясь на плоскости отсечения а потом елозим по ней камерой?

редакция от IvanN, 04.03.2014 11:22

Mefistofel
Инженер‑космогоник
Avatar пользователя

Опубликовано 04.03.2014 18:34 (10 лет назад)    #
IvanN
Первый вариант не понял совершенно, как простыми средствами можно натянуть на одну плоскость(полигон?) несколько тайлов с разными текстурными координатами? Только если шейдерами.
Предложенный CoderInTank вариант очень простой, и для 2д вполне годный.
База всегда примерно одна:
У тебя есть массив тайлов(каждый элемент - либо номер тайла в сете либо 2 текстурные координаты сдвига). При каждой отрисовке просто рисуется куча квадов стык в стык с динамически вычисляемыми из массива тайлов текстурными координатами.

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

Сдвигать камеру в ортопроекцию с основанием от угла можно, но совершенно не обязательно, для многих случаев центральное расположение куда удобнее.

Насчет оптимизаций можно предложить 2 основных.

Первая - сделать сразу массивы вершин, текстур, цветов и т.д. и рисовать все поле тайлов за раз. Будет быстрее и через glBegin / glEnd и если рисовать сразу буфферами. Подходит больше для неизменяемых тайлов, для персонажей и прочего надо координаты менять.

Вторая - самому считать видимое количество тайлов и отрисовывать поле не от начала до конца, а только то, что видно.
примерно так:


MapXB:= trunc(Camera.X / TILE_SIZE); // сдвиги камеры от начала
MapYB:= trunc(Camera.Y / TILE_SIZE);
MapXE:= MapXB + trunc(Window.Width / TILE_SIZE) + 1; // сдвиг к концу
MapYE:= MapYB + trunc(Window.Height/ TILE_SIZE) + 1;
// проверки на выход за границы массива
if MapXB < 0 then MapXB:= 0;
if MapYB < 0 then MapYB:= 0;
if MapXE > MAP_X then MapXE:= MAP_X;
if MapYE > MAP_Y then MapYE:= MAP_Y;
ViewLeft:= -Camera.X;
ViewTop := -Camera.Y;
// отрисовка только видимой области, от начала до конца будет от 0 до MAP_X / MAP_Y
for i:= MapXB to MapXE do
for j:= MapYB to MapYE do
begin
Resources.TileTexture.Draw(ViewLeft + i * 64, ViewTop + j * 64, Color, Map[i,j].Tile);
end;

Здесь сдвиги находятся для обычных оконных координат, если камера рисует от центра, то MapXB, MapYB, MapXE, MapYE находятся чуть по другому:

MapXB:= trunc(Camera.X / TILE_SIZE) - X_TILE_ON_SCREEN / 2;
MapYB:= trunc(Camera.Y / TILE_SIZE) - Y_TILE_ON_SCREEN / 2;
MapXE:= trunc(Camera.X / TILE_SIZE) + X_TILE_ON_SCREEN / 2;
MapYE:= trunc(Camera.Y / TILE_SIZE) + Y_TILE_ON_SCREEN / 2;
IvanN
Avatar пользователя

Опубликовано 04.03.2014 20:13 (10 лет назад)    #
Mefistofel
Спасибо за развернутый ответ.
Я обычно двигал камеру не трансформом, а делал чуть сложнее - заводил 2 координаты сдвига и при отрисовке каждого квада вычислял его координату, а потом отнимал сдвиг.

Пошевелив полдня своей извилиной я примерно к этому и пришел. Вы подтвердили мои подозрения. Спасибо за пример кода. Мне так проще разбираться.
Первая - сделать сразу массивы вершин, текстур, цветов и т.д. и рисовать все поле тайлов за раз. Будет быстрее и через glBegin / glEnd и если рисовать сразу буфферами. Подходит больше для неизменяемых тайлов, для персонажей и прочего надо координаты менять.

Вторая - самому считать видимое количество тайлов и отрисовывать поле не от начала до конца, а только то, что видно.

Вот ради второй, собственно, я и задавал вопрос. На glBegin/Еnd я даже не смотрел, в стандарте они deprecated.

Подскажите мне еще одну вещь, пожалуйста:
я правильно понял, при вызове glBind* выполняется копирование данных и память занятую массивами можно освободить?
Mefistofel
Инженер‑космогоник
Avatar пользователя

Опубликовано 04.03.2014 21:48 (10 лет назад)    #
Никогда так не делал(оперативки всегда больше, чем видеопамяти, и проще при необходимости обновлять локальные массивы, поэтому храню. Да и вообще, на спичках экономить), но должно быть именно так.
Я так понимаю, уже с 3-го ОГЛ выпилены все иные способы передачи вершинных данных, кроме как бинд массивов в видеопамять.

Кстати - если дело касается только тайлов поверхности, то даже для сравнительно больших уровней(100*100) будет дешевле по производительности вывести все поле одним мешем, чем использовать оптимизацию процессора.
Для еще больших уровней оптимизацию применяют опять же не для отдельных квадов, а для кусков, к примеру 20*20
IvanN
Avatar пользователя

Опубликовано 05.03.2014 07:21 (10 лет назад)    #
Ну текстура с тайлами/спрайтами скушает не так уж мало оперативы, особенно если поддерживать несколько разрешений экрана. Я в основном про это. И теоритически файл можно вообще на загружать в буфер оперативы, можно "сказать" процессору что "вот этот файл" есть страница памяти, передать на нужный его участок указатель а потом его закрыть. Для мобильных устройств это может дать нехилый прирост и сэкономить память. Вроде как есть расширения которые позволяют передавать сжатые текстуры? Но все это при условии что Bind действительно выполняет копирование.
Daemon
Avatar пользователя

Опубликовано 05.03.2014 07:36 (10 лет назад)    #
Не на чем проверить, но загруженную в память текстуру/буфер можно удалять, по крайней мере я так делаю. Только не после bind, а после непосредственной загрузки. glTexImage2D, glBufferData и прочего.

С opengl es не знаю, но вряд ли что-то иначе.
Mefistofel
Инженер‑космогоник
Avatar пользователя

Опубликовано 05.03.2014 13:44 (10 лет назад)    #
Mefistofel
Ах, речь про текстуры.
Да, можно сносить.
Перейти на форум:
Конкурсы
Открытые конкурсы:
Активных нет
Недавние конкурсы:
 185 - RPG XII
 184 - Arcade II
 183 - Novel
 182 - RPG XI
 181 - Pixel Craft 128
 Все конкурсы
Случайная игра
Мини-чат
Вам необходимо залогиниться.

Архив чата

25,320,115 уникальных посетителей

Создано на базе русской версии PHP-Fusion copyright © 2003-2006 by Nick Jones.
Released as free software under the terms of the GNU/GPL license.