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