Наиболее оптимальная архитектура рендерера
Здравствуйте.
Пытаюсь написать DLL библиотеку-рендерер (С++, OepnGL), но никак не могу определиться с наиболее оптимальной "архитектурой". Изначально задумка была примерно следующей:
- Есть классы ресурсов (геометрия, текстуры, прочее). Объекты этих классов можно создать (в этот момент ресурс загружается в видео-память) и ресурсы нельзя копировать (поскольку объект содержит OpenGL хендлы ресурсов, и уничтожение одного объекта повлечет деаллокацию памяти ресурса и для всех остальных, да и копировать ресурсы в целом смысла нет)
- Есть класс "меш". Объекты класса "меш" ссылаются на ресурс геометрии и текстур, а так же обладают пространственными параметрами (положение, вращение, масштаб). Могут быть скопированы.
- Есть класс "источник света". Объекты этого класса обладают пространственными параметрами и параметрами связанными с самим светом (цвет, затухание и прочее). Могут быть скопированы.
- Есть сам класс "рендерер". У класса есть поля "меши","источники света". Это обычные vecor'ы, которые содержат хендлы/указатели объектов мешей и источников света. У класса рендерера так же есть метод типа "addMesh" и "addLight", которые добавляют в эти векторы хендлы/указатели на объекты мешей и источников света. Есть методы "removeMesh" и "removeLight", которые удаляют из векторов эти указатели. И также есть метод "draw", в котором происходит проход по всем мешам и источникам света из вышеупомянутых векторов и осуществляется сам рендеринг сцены.
Каким предполагалось использование рендерера:
- Происходит загрузка всех ресурсов, получаем хендлы ресурсов текстур и геометрии
- Происходит загрузка игровых объектов, и для тех объектов, которые должны быть отрисованы, создаются объекты рендерера (меши/спрайты/частицы и прочее). Хендлы созданных объектов рендерера записываются в поля игровых объектов. Для источников освещения аналогично (для каждого игрового источника освещения создается источник освещения рендерера, и его хендл вписывается в соответствующее поле игрового источника света)
- Когда игровые отображаемые объекты как-то меняются (меняется положение, поворот, прочее), то при помощи функций рендерера и хранимых у игровых объектов хендлов объектов рендерера происходит так же и изменение пространственных (и других) параметров объектов рендерера.
- В определенный момент, после того как все данные кадра были обновлены, происходит метод draw объекта рендерера и все рисуемые объекты (которые на данный момент есть в массиве рендерера) рисуются.
И что не так в этом подходе?
У игровых объектов, которые отображаются, должно быть поле "объект рендерера" и при использовании рендерера нужно постоянно держать в голове эту схему (что есть некие объекты рендерера, и их нужно вовремя обновить/удалить/добавить и т.д). При этом как бы возникает дубликат отображаемого объекта в "мире" рендерера и в "мире" игры.
А как иначе?
Мне бы хотелось, чтобы у игровых объектов, которые должны быть отрисованы, было что-то вроде метода "render", который бы вызывался в каждом кадре, и там бы уже происходил вызов функции рендерера, что-то типа "нарисуй такой-то меш с такими-то параметрами и такими-то текстурами", куда бы просто передавались хендлы ресурсов. То есть не нужно было бы отдельно следить за тем, изменилось ли положение игрового объекта и всякий раз менять параметры соответствующего объекта рендерера.
Но в чем проблема, почему бы просто взять и не сделать так?
- Чтобы реализовать именно такой подход, насколько я понимаю (могу ошибаться) нужно будет, чтобы это самый метод "нарисуй такой-то меш с такими-то параметрами и такими-то текстурами" делал именно создание и добавление в списоки рендерера (мешей/источников света). То есть всякий раз, в каждом кадре будет происходит создание объекта и добавление его в массив/мап
- Чтобы объекты бесконечно не накапливались - нужно будет в каждом кадре, после отрисовки их всех - очищать массив/мап.
Вопрос:
Не будет ли это плохо сказываться на скорости? Такой подход вообще адекватен? Как можно было бы достичь вышеописанного иначе? Какую структуру данных лучше использовать для хранения объектов рендерера? Может не один из вышеописанных подходов не является оптимальным? Заранее спасибо.