Наиболее практичным подходом, по-видимому, является игнорирование большей части функциональности OpenGL, которая не применима напрямую (либо медленная, либо не аппаратно ускоренная, либо больше не подходит для аппаратного обеспечения).
ООП или нет, для рендеринга какой-либо сцены, это различные типы и сущности, которые у вас обычно есть:
Геометрия (сетки). Чаще всего это массив вершин и массив индексов (то есть три индекса на треугольник, или «список треугольников»). Вершина может быть в произвольном формате (например, только позиция float3; позиция float3 + нормаль float3; позиция float3 + нормаль float3 + текстовая координата float2 и т. Д. И т. Д.). Итак, чтобы определить кусок геометрии вам нужно:
- определить формат вершины (это может быть битовая маска, перечисление из списка форматов; ...),
- имеет массив вершин с чередованием их компонентов ("чередующиеся массивы")
- имеет массив треугольников.
Если вы находитесь на земле ООП, вы можете назвать этот класс Mesh .
Материалы - вещи, которые определяют, как какой-то фрагмент геометрии отображается . В простейшем случае это может быть, например, цвет объекта. Или следует ли применять освещение. Или должен ли объект быть альфа-смешанным. Или текстуру (или список текстур) для использования. Или вершинный / фрагментный шейдер для использования. И так далее, возможности безграничны. Начните с размещения вещей, которые вам нужны в материалы. В ООП земле этот класс можно назвать (сюрприз!) Материал .
Сцена - у вас есть кусочки геометрии, коллекция материалов, время, чтобы определить, что находится на сцене. В простом случае каждый объект в сцене может быть определен с помощью:
- Какую геометрию он использует (указатель на сетку),
- как это должно быть отображено (указатель на материал),
- Где это находится. Это может быть матрица преобразования 4x4 или матрица преобразования 4x3, или вектор (положение), кватернион (ориентация) и другой вектор (масштаб). Давайте назовем это Узлом в ООП земле.
Камера . Что ж, камера - это не что иное, как «где она находится» (опять же, матрица 4x4 или 4x3 или положение и ориентация), а также некоторые параметры проекции (поле зрения, соотношение сторон, ...).
Так что в принципе это все! У вас есть сцена, которая представляет собой набор узлов, ссылающихся на сетки и материалы, и у вас есть камера, которая определяет, где находится зритель.
Теперь, куда поместить фактические вызовы OpenGL - это вопрос дизайна. Я бы сказал, не помещайте вызовы OpenGL в классы Node, Mesh или Material. Вместо этого создайте что-то вроде OpenGLRenderer , которое может пересечь сцену и выполнить все вызовы. Или, что еще лучше, создайте что-то, что проходит через сцену независимо от OpenGL, и поместите вызовы более низкого уровня в зависимый класс OpenGL.
Так что да, все вышеперечисленное в значительной степени зависит от платформы. Пройдя по этому пути, вы обнаружите, что glRotate, glTranslate, gluLookAt и друзья совершенно бесполезны. У вас уже есть все матрицы, просто передайте их OpenGL. Вот как работает большинство реальных кодов в реальных играх / приложениях.
Конечно, вышесказанное может быть осложнено более сложными требованиями. В частности, материалы могут быть довольно сложными. Сетки обычно должны поддерживать множество различных форматов вершин (например, упакованные нормали для эффективности). Узлы сцены, возможно, должны быть организованы в иерархию (это может быть легко - просто добавьте указатели родителя / потомка к узлу). Скин-меши и анимация в целом добавляют сложности. И так далее.
Но основная идея проста: есть геометрия, есть материалы, есть объекты на сцене. Затем какой-то небольшой фрагмент кода может их отрендерить.
В случае OpenGL установка сеток, скорее всего, создаст / активирует / изменит объекты VBO. Перед тем, как какой-либо узел будет визуализирован, необходимо установить матрицы. А настройка Material коснется большей части оставшегося состояния OpenGL (смешивание, текстурирование, освещение, объединители, шейдеры, ...).