Я работал над различными демонстрационными проектами с OpenGL и С++, но все они включали просто визуализацию одного куба (или аналогично простой сетки) с некоторыми интересными эффектами. Для простой сцены, подобной этой, данные вершин для куба могут храниться в неэлегантном глобальном массиве. Теперь я просматриваю рендеринг более сложных сцен с несколькими объектами разных типов.
Я думаю, что имеет смысл иметь разные классы для разных типов объектов (Rock
, Tree
, Character
и т.д.), но мне интересно, как чисто разбить данные и функции рендеринга для объектов в сцене. Каждый класс будет хранить свой собственный массив вершинных позиций, координаты текстуры, нормали и т.д. Однако я не уверен, куда поместить вызовы OpenGL. Я думаю, что у меня будет цикл (в классе World
или Scene
), который выполняет итерацию по всем объектам сцены и отображает их.
Должны ли они включать вызов метода визуализации в каждый объект (Rock::render(), Tree::render(),...)
или один метод визуализации, который принимает объект как параметр (render(Rock), render(Tree),...)
? Последнее кажется более чистым, так как у меня не будет повторяющегося кода в каждом классе (хотя это можно было бы смягчить, наследуя от одного класса RenderableObject
), и он позволяет легко заменить метод render(), если я хочу позже порт в DirectX. С другой стороны, я не уверен, могу ли я держать их в отдельности, поскольку в любом случае мне могут понадобиться специальные типы OpenGL, хранящиеся в объектах (например, буферы вершин). Кроме того, представляется немного громоздким, чтобы функция визуализации была отделена от объекта, так как для получения данных от объектов придется вызывать множество методов Get()
. Наконец, я не уверен, как эта система будет обрабатывать объекты, которые нужно рисовать по-разному (разные шейдеры, разные переменные, которые передаются шейдерам и т.д.).
Является ли один из этих проектов лучше, чем другой? Каким образом я могу улучшить их, чтобы мой код был хорошо организованным и эффективным?