Стратегии управления конечным автоматом OpenGL
В настоящее время я получаю доступ к OpenGL. Я начал с GLUT, но решил "окончить" библиотеки SFML. SFML фактически обеспечивает еще меньше утилит GL, чем GLUT, но переносится и предоставляет некоторые другие функции. Так что это действительно только я, GL и GLU. Да, я в отчаянии за наказание.
Я хотел спросить о стратегиях, которые люди имеют для управления такими вещами, как изменения матрицы, изменения цвета, изменения материалов и т.д.
В настоящее время я получаю от одного потока, следуя философии дизайна "Голые объекты". то есть. Каждый графический объект имеет функцию Render()
, которая выполняет работу по рисованию. Эти объекты сами могут быть агрегатами других объектов или совокупности графических примитивов. Когда конкретный Render()
называется, он не имеет информации о том, какие преобразования/изменения материала были вызваны перед ним (что хорошо, конечно).
По мере того, как все сложилось, я решил определенные стратегии, такие как заставить каждую функцию обещать нажать, а затем поп матрицы, если они выполняют какие-либо преобразования. С другими настройками я явно устанавливаю все, что требует настройки, перед вызовом glBegin()
и не принимаю ничего как должное. Проблемы ползутся, когда одна функция рендеринга производит некоторые изменения в менее распространенных переменных состояния, и я начинаю рассматривать использование некоторого RAII для принудительного изменения всех изменений состояния, сделанных в области. Использование OpenGL иногда напоминает мне много программирования сборки.
Чтобы сделать все это управляемым и помочь с отладкой, я обнаружил, что я практически разрабатываю свою собственную оболочку openGL, поэтому я решил, что было бы хорошо услышать о тех стратегиях, которые использовали другие, или о мыслях и соображениях по этому вопросу, Или, может быть, просто пора переключиться на нечто вроде библиотеки графа сцены?
Обновление: 13/5/11
Теперь посмотрев на рендеринг с массивами вершин/нормальных/цветных цветов и VBO, я решил объединить всю фактическую связь openGL в отдельный модуль. Процесс рендеринга будет состоять в том, чтобы получить нагрузку от независимых пространственных/материальных данных GL из моих объектов, а затем передать всю эту информацию в openGL в интерпретируемом формате. Это означает, что вся обработка необработанных массивов и манипуляция состояния будут объединены в одну область. Он добавляет дополнительную косвенность и небольшую вычислительную нагрузку на процесс рендеринга, но это означает, что я могу использовать один VBO/массив для всех своих данных, а затем передавать все сразу, один раз для каждого кадра в openGL.
Ответы
Ответ 1
Так что это действительно только я, GL и GLU
В этом я ничего плохого не вижу. Я бы даже избавился от GLU, если это возможно.
С другими настройками я явно устанавливаю все, что требует настройки до вызов glBegin() и ничего не беру для само собой разумеющееся.
Кроме того, это хорошая стратегия, но, конечно же, вы должны держать дорогие переключатели состояния до минимума. Вместо немедленного режима (glBegin/glEnd) вы должны перенестись на использование массивов вершин и доступных доступных объектов буфера вершин.
Проблемы ползутся, когда один рендер функция делает некоторые изменения меньше общие переменные состояния, и я начиная рассматривать некоторые RAII для обеспечения отмены всех государственных изменения, внесенные в область.
Старые версии OpenGL предоставляют вам стек атрибутов с функциями доступа glPushAttrib/glPopAttrib и glPushClientAttrib/glPopClientAttrib для состояний клиента.
Но да, огромное пространство состояний старых версий OpenGL было одной из основных причин похудения OpenGL-3; то, что было охвачено множеством состояний консистенции фиксированной функции, теперь настраивается и доступно через шейдеры, где каждый шейдер инкапсулирует то, что было бы десятками значений переменных состояния OpenGL.
Использование OpenGL иногда напоминает мне много программирования сборки.
Это вовсе не сюрприз, поскольку первое воплощение OpenGL было разработано с учетом некоторой абстрактной машины (реализации), на которой вызовы OpenGL являются видными кодами операций этой машины.
Ответ 2
Сначала попробуйте не использовать вызовы glBegin/glEnd для новой разработки. Они устарели в OpenGL 3 и просто не работают в OpenGL ES (iOS, WebOS, Android). Вместо этого используйте вершинные массивы и VBOs для консолидации вашего чертежа.
Во-вторых, вместо того, чтобы писать свою собственную оболочку, взгляните на некоторые недавние версии с открытым исходным кодом, чтобы увидеть, как они это делают. Например, проверьте библиотеку визуализации (http://www.visualizationlibrary.com/jetcms/). Это довольно тонкая оболочка вокруг OpenGL, поэтому стоит посмотреть.