Виктор Коваленко
ИПМ им. М.В.Келдыша РАН, Москва
kvn@keldysh.ru

Ключ - явное представление моделей
Граф сцены
Основные характеристики OpenGL Optimizer
Упрощение и уровни детальности
Операции отсечения
Пространственная организация графа сцены
Оптимизация передачи геометрических данных
Поддержка сложных поверхностей
Топология модели
Разбиение поверхностей
Инфраструктура мультипроцессирования
Использование OpenGL Optimizer
Заключение
Литература

Трудно переоценить роль стандарта OpenGL в становлении и распространении трехмерной машинной графики. С этим стандартом связан прикладной интерфейс для визуализации пространственных объектов, равно как с ним ассоциируется и целая идеология проектирования специальной аппаратуры - графических ускорителей, благодаря которым трехмерные сцены стали реальностью, хотя и виртуальной. Однако, сегодня впору задаться вопросом, есть ли перспективы у OpenGL или она обречена?

На сегодня OpenGL представляет собой общепризнанный стандарт, реализованный для всех классов компьютеров от ПК до суперкомпьютеров. Для разработчика, OpenGL - это, прежде всего, базовая библиотека из нескольких сотен графических функций, с помощью которых можно создать геометрию сцены и произвести ее рендеринг, плюс расширения: GLU - вспомогательные функции, упрощающие разработку и опирающиеся на базовый набор возможностей, и GLX - интерфейс для взаимодействия с оконной системой X Window. Однако успех OpenGL, по-видимому, все же обусловлен не удачным API, а следующими двумя обстоятельствами. Первое: еще в 1982 г. в Стенфордском университете была разработана концепция графической машины, на основе которой в рабочей станции Silicon IRIS был реализован конвейер рендеринга. Второе: OpenGL - открытый и мобильный стандарт. Это означает, в частности, что программы можно переносить на любую платформу, а графический вывод OpenGL получать как локально, так и по сети на любом рабочем месте, поддерживающем X Window и имеющем расширение GLX.

Машинная графика еще относительно молода, и подходящим здесь является именно развивающийся стандарт. Давление главным образом ощущается со стороны производителей CAD систем - средства пространственного моделирования уже стали повседневным инструментом для многих инженеров и проектировщиков. Однако в течение последних 15-20 лет сложность моделей постоянно росла, и на сегодня сложилась ситуация, при которой прогрессивные формы организации проектирования (работа с большими сборками) лимитируются возможностями современного графического оборудования и ПО интерактивной визуализации.

Специалисты пришли к выводу, что тип взаимодействия с моделью, известный как проектирование в контексте, позволяет обнаруживать такие ошибки как некорректное расположение компонентов, еще на ранних этапах цикла разработки, а это определеннейшим образом приводит к уменьшению трудозатрат и стоимости проекта.

В идеале требуются такие CAD - системы, в которых можно было бы визуализировать и взаимодействовать с базой данных любых масштабов, от отдельных деталей до законченных проектов. Как показала практика, получить такие средства, не затрагивая уровень базового графического аппарата, невозможно. А для базового уровня задача состоит в том, чтобы добиться визуализации больших инженерных моделей с интерактивной скоростью, не жертвуя при этом точностью воспроизведения в той мере, в какой это может привести к ошибочной интерпретации результирующих изображений.

Ключ - явное представление моделей

OpenGL открывает перед пользователем возможности очень тонкого управления процессом рендеринга: можно определить такие параметры как матрицы преобразований координат, коэффициенты уравнений расчета освещенности, метод антиалиасинга и т.д. Но! Все это чистая визуализация. OpenGL не имеет средств для представления собственно моделей сложных геометрических объектов, если понимать модель как структурное описание элементов, отличных от примитивов. Программа на OpenGL в большей степени специфицирует, порядок получения определенного результата, а не его внешнее представление. Результат работы программы - только изображение. Иначе говоря, OpenGL является фундаментально процедурным, а не дескриптивным языком.

Здесь полезно напомнить, что абстрактный конвейер рендеринга [1], являющийся полной схемой графической обработки, кроме этапов, реализуемых в аппаратных ускорителях, включает в себя еще два: генерацию прикладной модели и ее обход, во время которого вызываются функции OpenGL. До сих пор эти два этапа отдавались на усмотрение программиста и хост-процессора, а между тем именно в них заложены резервы повышения графической производительности.

Не удивительно, что в этом направлении и пошло развитие, главной движущей силой которого снова стала компания Silicon Graphics. Появились IRIS Performer, Open Inventor, Cosmo 3D, а теперь и OpenGL Optimizer. Хотя акценты в этих программно-инструментальных системах расставлены по-разному, общим для этой линии является развитие средств управления прикладной моделью (графом сцены) и реализация заложенных в ней возможностей.

Граф сцены

Граф сцены - это определенная формализация прикладной графической модели [2], с которой работает OpenGL Optimizer. Граф сцены представляет собой набор узлов, часть которых соединена направленными связями. Существует прямая аналогия между командами OpenGL и типами узлов графа. Первый тип узлов соответствует геометрическим элементам сцены. Это либо примитивы, либо стандартные формы, порождаемые расширением GLU OpenGL. Направленные связи графа соединяют два узла и реализуют отношение группирования. Правила здесь следующие: к узлу-группе (это второй тип узлов) можно привесить несколько потомков, каждый потомок может быть подвешен к нескольким родителям-группам, но циклы в графе не допускаются.

Для чего нужно группирование? Напомним, что в OpenGL визуальные свойства и расположение геометрических элементов порождаются из текущего состояния рендеринга, которое определяется матрицей преобразования координат, условиями освещения и закрашивания, материалом и текстурой. Эти атрибуты задаются в программе на OpenGL путем вызова соответствующей функции и действуют на все последующие примитивы, пока не будет произведено изменение состояния. Примерно такая же система и в графе сцены: имеются узлы, соответствующие преобразованиям и свойствам, которые также можно помещать в группы. Состояние рендеринга для некоторого объекта сцены определяется либо последним свойством на пути из корня в этот узел, либо произведением матриц. В типовом случае, когда подмножество объектов (например, жестко скрепленные детали) обладает одинаковыми свойствами, это позволяет задавать их все однократно в единственном узле. Другое применение группирования - в ситуации, когда имеется несколько различающихся по свойствам или расположению вариантов одного элемента (он может быть и составным). Тогда геометрия элемента представляется в одном узле графа, но этот узел прикрепляется к разным группам.

Наиболее адекватный стиль для работы с графом сцены - объектно-ориентированный (API OpenGL Optimizer построен на C++). Узлы графа рассматриваются как объекты языка и обладают совокупностью применимых к ним методов, соответствующих типу узла. Пример метода - рендеринг, он обычно применяется к корневому узлу. Порождение графа происходит при обращении к методам создания объектов и заполнении их полей параметрами. С виду это напоминает действия приложения OpenGL, отличие в том, что после создания графа появляется возможность динамически модифицировать его через объектное API: изменить, например, радиус сферы, занеся в параметры узла новое значение параметра, удалить некоторую группу полигонов, видоизменить матрицу преобразования, тем самым вызвав перемещение группы элементов по сцене. (В OpenGL, как известно, нужно заново повторять всю последовательность команд, генерирующих кадр.)

Что же дает граф сцены? В перспективе системы, основанные на этом принципе, способны свести реализацию графических приложений к порождению прикладной модели. Эта модель, кроме собственно визуализации, может обрабатываться универсальными программами, которые не знают ничего о конкретном ее содержании, но могут, тем не менее, делать с ее помощью полезные вещи. Пример такой программы - универсальный редактор, получающий на входе любую модель сцены, и позволяющий методом указания менять расположение объектов, их свойства, расставлять источники освещения, определять способы проецирования и т.д. Создание 3D моделей - весьма трудоемкая задача, однако накапливая из них библиотеки, можно затем получать сцены путем простой компоновки.

Второй момент - явное представление прикладной модели позволяет существенно повысить производительность рендеринга при сохранении высокого качества. В настоящее время накоплено большое количество алгоритмов машиной графики, использующих явное представление объектов, но до сих пор такие методы не были востребованы в стандартных системах, потому что объектных моделей в них не было. Этот пробел закрывает OpenGL Optimizer - предоставляя API для создания эффективных представлений и их рендеринга.

Основные характеристики OpenGL Optimizer

Компания SGI развивала аппарат для работы с графом сцены в несколько этапов: IRIS Performer, Open Inventor, Cosmo 3D, в каждом из которых предполагалось использование в основном базовых средств. Последний шаг - OpenGL Optimizer [3,4] не отменяет этого подхода, но дополняет его рядом более сложных, но столь же необходимых для высокопроизводительного рендеринга функций:

  • различные виды отсечения объектов непосредственно на графе сцены;
  • построение параметрических поверхностей высокой степени;
  • триангуляция поверхностей;
  • упрощение полигонального разбиения;
  • оптимизация сеток;
  • вывод топологии сцены;
  • интегрированное мультипроцессирование.

Эти функции реализованы в виде коллекции независимых и взаимодополняющих модулей в форме методов API C++. Таким образом, сейчас прикладное графическое программирование имеет три уровня графических средств: API OpenGL, API уровня графа сцены и API OpenGL Optimizer, причем все они могут применяться совместно. Приложение может быть смесью вызовов функций OpenGL, обращений к методам формирования графа сцены и оптимизирующих преобразований третьего уровня.

OpenGL Optimizer - составная часть набора API с общей маркой OpenGL. Как и последний, он определяется независимым от оконной и операционной системы способом, что обеспечивает интероперабельность и переносимость приложений на OpenGL Optimizer. Это открытый стандарт, поддержанный ведущими отраслевыми экспертами: OpenGL Optimizer включен в реестр открытых промышленных стандартов MCAD, известный как LMVAC (Large Model Visualization API Consortium). Благодаря четко оговоренному механизму расширения API, участники LMVAC имеют возможность вводить новшества и развивать стандарт. В результате, развитие API происходит в интересах всей индустрии, а не только в интересах отдельных компаний, как бывает в случае частных, навязанных одним из производителей "стандартов". Такой подход хорошо зарекомендовал себя в прошлом, сделав OpenGL основным межплатформным графическим стандартом.

В уровневой модульной архитектуре OpenGL Optimizer (рис. 1) специально подчеркивается, что каждая составляющая подсистема может использоваться либо отдельно, либо в сочетании с другими. Например, в одной разработке можно применить только упрощение полигональной сетки, а в другой - высокоточную триангуляцию поверхностей.

Picture 1.

Рисунок 1.
Архитектура OpenGL Optimizer

В любом варианте необходимо учитывать следующее общее положение. Архитектурно графические системы в значительной степени представляют собой последовательный конвейер, часть которого реализована аппаратно, а часть программно. Основная забота проектировщика конвейера, состоит в том, чтобы все его этапы были сбалансированы и не было слабых звеньев, лимитирующих общую производительность. Модули OpenGL Optimizer являются составными, хотя и отключаемыми, частями конвейера рендеринга - они разделяют ресурсы системы в распределенной мультипроцессорной среде. Выполнение любого оптимизирующего преобразования графа сцены требует определенных затрат ресурсов, но с другой стороны оптимизация ускоряет следующие этапы конвейера. Примером может служить операция построения вспомогательной пространственной структуры сцены, которая существенно убыстряет отсечение объектов и их идентификацию при указывании. Более тонкое пространственное разбиение дает лучшую производительность этих операций. Однако, разбиение сцены на слишком большое число маленьких кусков может уменьшить общую производительность приложения. Таким образом, в этом примере требуется достичь баланса между пространственным поиском и эффективностью конвейера в целом. Эта ситуация общая, и в OpenGL Optimizer предусмотрены компоненты, позволяющие приложению динамически находить баланс между оптимизацией графа сцены и оптимизацией аппаратной части конвейера.

Упрощение и уровни детальности

Один из фундаментальных приемов работы с большими сценами - введение в граф сцены нескольких вариантов геометрической информации, отвечающих разной степени визуального разрешения. Обычно объекты рендеринга в графических приложениях аппроксимируются сетью смежных треугольников. В OpenGL Optimizer такая сеть для поверхностей высокого порядка строится с помощью генераторов покрытия, а кроме того она может быть импортирована извне - триангулированное представление практически необходимая вещь в CAD системах: на него опирается технологический анализ.

Хоть и не всегда, но нужно проводить рендеринг всех треугольников модели. Ясно, что для качественной визуализации объекта, находящегося вблизи точки наблюдения, требуется учесть во много раз больше треугольников, чем в ситуации, когда тот же объект расположен на удалении: его изображение вообще может состоять из нескольких пикселей. Рендеринг одного и того же множества вершин модели во втором случае нагрузит графический конвейер совершенно лишней работой, что особенно скажется на этапе преобразований. Разумно также использовать меньше деталей для движущихся объектов - и в этом случае подробная геометрия не столь важна.

Техника создания множественного представления объекта состоит в том, что в графе сцены формируется узел типа LOD - Level-Of-Detail и к нему подвешиваются различные варианты геометрии объекта с разной густотой разбиения. Обычно с увеличением индекса потомка LOD-узла разрешение падает и, соответственно, возрастает скорость его рендеринга. В предельном случае рендеринг объекта возможно вообще не нужно производить, но это уже другая операция - отсечение. Еще один тип узла - csLOD позволяет специфицировать правила выбора варианта геометрии. Эти правила задаются в форме набора диапазонов расстояния до объекта. В ходе выполнения действия обхода графа csLOD действует как переключатель, выбирающий потомка узла LOD по текущей дистанции наблюдения.

Добавление в граф сцены уровней детальности не составляет труда, единственная серьезная проблема - как построить по оригинальной геометрии объектов их упрощенные представления. В OpenGL Optimizer для этого есть объекты-действия - симплификаторы, которые применяются к некоторому множеству узлов графа сцены и на выходе выдают новую геометрию с меньшим числом треугольников. Количество треугольников, которые требуется получить в результате, задается либо явно, либо как процент по отношению к исходному их числу.

OpenGL Optimizer содержит два типа симплификаторов: первый учитывает топологию объекта и пытается ее сохранить, а второй реализует более прямолинейный алгоритм. Действующий на основе топологии, симплификатор реализует алгоритм SRA - Successive Relaxation Algorithm. Принцип работы состоит в последовательном устранении вершин до целевого счетчика (либо до состояния, когда удалить уже ничего нельзя без нарушения ограничений). Вначале алгоритм пытается удалить вершины, отсутствие которых существенно не деформирует объект, и только потом удаляет значимые для формы вершины до достижения требуемого значения счетчика узлов.. Заметим, что данный тип упрощения полезен не только для специалистов моделирующих в CAD, но и для пользователей и разработчиков Web: по сети можно вначале передавать модель с низким разрешением, а по требованию повышать ее точность.

Более простой и быстрый, но потенциально сильнее искажающий модель симплификатор, базируется на методе, впервые предложенном Яреком Россиньяком (Jarek Rossignac). На вход алгоритма подается трехмерная решетка точек и каждая из вершин объекта переносится в ближайшую точку решетки. Те полигоны, у которых после выполнения операции стягивания оказывается менее трех различных вершин, отбрасываются. Этот метод быстр в силу своей линейности и легко реализуем. Как правило точность, с которой он воспроизводит модель, не отличима от оригинала, если размеры изображений одинаковы. Тем не менее симплификатор на основе пространственной решетки применять выгодно при условии правильного выбора дистанции наблюдения - результат будет вполне удовлетворительным.

Операции отсечения

Различные способы отсечения также составляют фундамент 3D графики, поэтому естественно, что различные виды отсечения поддерживаются в API и геометрической машине OpenGL. Принципиальное отличие подхода OpenGL Optimizer в том, что здесь отсечение производится над объектами, а не над совокупностью составляющих их примитивов. Отсечение становится очень мощным средством разгрузки графического конвейера - объекты, которые заведомо не нужно рисовать, вообще в него не передаются. OpenGL Optimizer поддерживает три вида отсечения: по видимому объему, по вкладу в изображение и отсечение загороженных частей.

Отсечение по видимому объему основывается на том, что при данной точке наблюдения может быть видна не вся сцена, а только ее часть, лежащая в определенном телесном угле. Чем меньше расстояние до сцены, тем большая ее часть оказывается вне видимого объема, и такая ситуация типична для прогулок по виртуальным архитектурным сооружениям. С другой стороны, если здание рассматривается снаружи, тест по видимому объему не даст никакого эффекта. Алгоритм для такого отсечения устроен иерархически: когда устанавливается, что некоторая область сцены полностью видима/невидима, проверка объектов, лежащих внутри ее, уже не производится. Действие отсечения по видимому объему иллюстрирует рис. 4б.

Отсечение по видимому объему уменьшает количество работы, выполняемой аппаратной частью графического конвейера, но эта операция может приводить как к уменьшению, так и к увеличению нагрузки на хост-компьютер. Все зависит от соотношения времени, затраченного на тесты отсечения, и времени, сэкономленного за счет условия, при котором отброшенные части графа сцены не обходятся при генерации кадра. Сбалансировать нагрузку на хост и на графическую аппаратуру можно с помощью средств пространственной организации графа сцены.

Хотя упрощение сцены с помощью уровней детальности весьма полезно для выбора оптимального количества вершин полигонального представления объектов, логическую завершенность этот прием находит в идее явного отбрасывания объектов, размер которых не превосходит некоторого порога 'малости'. Это второй вид отсечения - отсечение деталей. 'Малость' определяется здесь как отношение размера геометрии узла к общему размеру графа сцены и вычисляется, исходя из радиусов соответствующих ограничивающих сфер.

Следующий вид отсечения - отбрасывание частично видимых объектов, во многих отношениях это наиболее мощный алгоритм. Он находит на графе сцены полигоны, которые заслонены объектами, находящимися на переднем плане, и прекращает их дальнейшую обработку на графическом конвейере. Критической степенью загороженности можно управлять с помощью параметра "доля заслоненности" - ограничивающего объект прямоугольного параллелепипеда. По умолчанию этот параметр равен 100%, и в этом случае сохраняются все сколь-нибудь видимые полигоны, но его можно изменять динамически, основываясь на измерении скорости работы графического конвейера.

Если отсечение загораживания не задействовано, закрытые треугольники будут передаваться в конвейер OpenGL. Это не приведет к изъянам в изображении - генерируемые по закрытым полигонам пикселы будут стерты в тесте буфера глубины. Но тест этот выполняется последним, после того как произведены преобразования вершин и растеризация, и если рассчитывать только на него, большая часть работы графической машины будет проделана вхолостую. Как и в случае с отсечением по видимому объему, отсечение закрытых объектов является средством экономного использования нижележащих процессорных ресурсов графического конвейера.

Данный вид отсечения имеет максимальный эффект для сцен с большим разбросом объектов по глубине. Например, на изображении общего вида автомобиля или другой сложной сборки 95% треугольников будут заслонены. Напротив, в приложениях визуального моделирования объекты не имеют внутренних деталей, и здесь обычно видима большая часть полигонов. В этом случае применение отсечения невидимых частей не скажется существенно на скорости кадров.

Пространственная организация графа сцены

С помощью пространственного упорядочения граф сцены можно структурировать таким образом, что он начнет отражать взаиморасположение объектов (степень близости, справа-слева, сверху-снизу). Такая организация нелинейно ускоряет поиск узлов по координатам соответствующих объектов в пространстве, что непосредственно сказывается на производительности разных видов отсечения. Другое применение - ускорение идентификации в графе объектов, которые указываются пользователем на изображении. Пространственная организация настолько эффективна, что возможен режим подсвечивания выбора в реальном времени: когда мышь проходит по сцене, лежащие под ней объекты меняют цвет - важный прием для обеспечения правильности указания в сложных сценах.

Реализованный в OpenGL Optimizer метод пространственного упорядочения основан на классическом понятии октарного дерева, в котором потомки узла соответствуют последовательному разделению родительской области пространства (куба) на 8 равных подобъемов. Однако в OpenGL Optimizer деление пространства производится не совсем так, как в октарном дереве. Плоскости, разбивающие куб, проводятся таким образом, чтобы нагрузка рендеринга всех получающихся объемов была примерно равной: после каждого разрезания число треугольников по обе стороны секущей плоскости одинаково.

Для управления гранулярностью представления задаются два параметра: наименьшее и наибольшее количество треугольников в каждом геометрическом наборе графа сцены. Более тонкое пространственное разбиение уменьшает нагрузку на графическую аппаратуру, но увеличивает время обхода графа - в нем увеличивается число узлов. Известны примеры, в которых правильный выбор гранулярности приводил к уменьшению времени рендеринга более чем на порядок.

Пространственную организацию рекомендуется применять для сцен с крупными объектами и для приложений, в которых производится интерактивная манипуляция объектами. Ее полезность невелика для приложений типа прогулок и для приложений с движущимися объектами.

Оптимизация передачи геометрических данных

Одним из узких мест конвейера рендеринга может стать этап передачи данных из хоста в графическую машину. В API OpenGL есть несколько приемов для обеспечения компактного потока: создание дисплейного списка, массива вершин, минимизация переключений состояний. OpenGL Optimizer предлагает средства еще для одного способа - генерации связанных примитивов OpenGL.

Для минимизации избыточности информации о вершинах в OpenGL определяются два геометрических примитива: веер треугольников (triangle fan) и полоска треугольников (triangle strip). В этих примитивах вершины, принадлежащие общим ребрам соседних треугольников, представляются однократно. Поэтому геометрия N треугольников задается всего N+2 вершинами, что существенно меньше 3*N, если треугольники описаны независимо.

Компактное представление треугольников особенно полезно для триангулированных NURBS-поверхностей - веерные структуры наиболее подходят в местах обрыва поверхностей (например, возле отверстия в пластине), а внутренние области хорошо покрываются полосками. Вееры и полоски треугольников взаимодополняют друг друга: алгоритмы для построения первых хорошо работают там, где плохо строятся вторые, и наоборот. Генерация вееров - более простая задача: в качестве хорошего кандидата на роль начальной вершины, как правило, годится любая вершина, в которую входит большое число ребер. В состав OpenGL Optimizer входят три класса, соответствующие трем способам упаковки треугольников: генератор вееров, генератор полосок и их комбинация.

Работа с веерами и полосками требует известной аккуратности ведь вершина OpenGL - это не только координаты, но и атрибуты: нормаль, цвет и т.д. Вершины смежных треугольников могут иметь одинаковые координаты, но различные наборы атрибутов. В OpenGL двусмысленность вершин в компактном представлении устраняется следующим образом каждая вершина получает атрибуты, соответствующие первому треугольнику, в который она входит, а все последующие атрибуты теряются.

Алгоритмы генерации вееров и полосок в OpenGL Optimizer действуют более точно. Для генераторов компактных примитивов можно определить максимально допустимую разницу между атрибутами вершины в добавляемом треугольнике и наследуемыми атрибутами, и тем самым проконтролировать приемлемую степень нарушений в изображении. Чтобы понять, насколько это важно, рассмотрим случай двух прилегающих треугольников, которые лежат на двух смежных гранях куба. Правильные нормали разделяемых вершин на общей грани куба ортогональны друг другу. Если рассматриваемые треугольники сгруппировать в полоску, то один из них будет изображаться как криволинейная поверхность по той причине, что оригинальные нормали его разделяемых вершин не будут учитываться при расчете освещенности.

Поддержка сложных поверхностей

Простота и эффективность процесса создания геометрических моделей в большей мере зависит от набора примитивных элементов, которыми располагает конструктор. Если базовый набор ограничен, как в OpenGL, сферой, конусом, цилиндром, то придется приложить усилия, вырезая из них подходящие куски и склеивая их друг с другом. Для того, чтобы быстро строить поверхности с большим числом выпуклостей и вогнутостей, требуются примитивы, которые описываются математически как полиномы высокого порядка. Тогда сложную поверхность можно построить одним махом - подобрав коэффициенты полинома.

OpenGL Optimizer поддерживает большое количество типов кривых и поверхностей высокого порядка, использующихся на практике в распространенных CAD системах:

  • плазовые поверхности;
  • билинейные поверхности Куна;
  • поверхности общего вида, получаемые натягиванием на образующие;
  • Эрмитовы сплайновые поверхности;
  • неоднородные рациональные B-сплайновые поверхности (NURBS).

Все кривые и поверхности высокого порядка непосредственно представимы в графе сцены - им соответствуют специальные типы узлов-форм. Таким образом в OpenGL Optimizer граф рядовой модели будет состоять из относительно небольшого числа кусков поверхностей высокого порядка, а не из большего числа плоских и квадратичных кусков. То, что часто используемые конструктивные элементы представляются в явном виде, способствует ускорению рендеринга: учитывая их глобальные свойства, методы OpenGL Optimizer строят для них оптимальную триангуляцию и более эффективно обрабатывают их на графической аппаратуре.

Топология модели

В моделях CAD абстрактные математические поверхности не более, чем строительный материал. Путем усечения из них выбираются подходящие по форме куски, которые сопрягаются друг с другом. Для многих алгоритмов обработки модели важно, чтобы условия стыковки поверхностей (тождественность линий-швов, общих вершин) были заданы точно, а чисто геометрической информации - координат точек - для этого мало. Явные стыковочные ограничения называются топологией поверхности модели. Наличие топологических данных критически важно, например, для триангуляции и особенно, когда строится разбиение с небольшим числом полигонов. Топологическая информация может быть либо получена от вызвавшей OpenGL Optimizer прикладной системы, либо выведена им самостоятельно по технологии Topology Synthesis.

После создания топологических метаданных, OpenGL Optimizer обретает способность определить, формируют ли поверхности, составляющие модель, твердое тело - многообразие, или это несколько упакованных друг в друга объектов. Такое "распознавание" очень помогает позднее, при отсечении закрытых элементов и определении видимости. По известной топологии производится также, "починка" ориентации модели, так чтобы нормали смежных ячеек смотрели в одну и ту же сторону. Поскольку ориентация ошутимо воздействует на процесс закраски, в некоторых системах починка может удвоить графическую производительность. Таким образом, конструирование и поддержание топологии является ключевым моментом для высокой точности и быстродействия при визуализации CAD-моделей.

Разбиение поверхностей

Современные интегрированные CAD-системы - это не только средства конструирования и визуализации. На построенных 3D моделях производят анализ технологических решений, автоматически выпускают прототипы. Такого рода задачи решаются численными методами, для которых требуется дискретизация модели в виде натянутой на ее поверхность сетки. Триангуляция (или в более общей форме разбиение) - процесс преобразования кусков параметрических поверхностей в набор треугольников.

Реализованные в OpenGL Optimizer методы разбиения представляют интерес прежде всего потому, что они рассчитаны на поверхности высокого порядка. OpenGL Optimizer - объектно-ориентированная система, поэтому кроме конкретных методов, реализованных в генераторах разбиения, в нем определен обобщенный механизм, с помощью которого пользователь может добавить свой собственный тип генератора. Генераторы разбиения - это объекты-действия C++, применяемые к графу сцены и при его обходе триангулирующие все входящие в него объекты. Каждый генератор опознает тот тип объектов-форм, на который он рассчитан, и добавляет производимые треугольники к графу сцены. В число генераторов разбиения входят следующие.

  • Обобщенный генератор: обработка всех типов параметрических поверхностей, включая определенные пользователем через механизм расширения.
  • Генератор разбиений Nurbs-поверхностей. Nurbs-поверхности могут быть обработаны обобщенным генератором, однако, поскольку это важная и часто используемая форма представления, OpenGL Optimizer имеет специально настроенный на них тип генератора. И тот, и другой генератор дают пользователю контроль за максимальным отклонением хорд триангулированной поверхности от аналитической. Это эффективная мера, гарантирующая качество результирующей сетки, в том числе и с точки зрения аппроксимации кривизны.
  • Генератор для инженерной и научной визуализации. Этот тип генератора применяется в задачах визуализации данных, представленных на пространственной решетке. Довольно часто они привязаны еще и к модели объекта, которую тоже нужно показывать. Например, при проектировании поддерживающего кронштейна неплохо отслеживать, как на нем распределены напряжения. Реализация этого типа генератора основана в OpenGL Optimizer на технике переопределения функций (overload). Генератор совершает преобразование абстрактных данных в геометрическую форму, которую уже можно визуализировать. Для приведенного примера, в каждой точке сетки числовые данные могут быть превращены в цвет, изображающий модуль напряжения, и в эллиптическую икону, представляющую собственные векторы и значения тензора напряжений.

Набор средств разбиения OpenGL Optimizer достаточно эффективен. В некоторых случаях пользователи обращались к OpenGL Optimizer только затем, чтобы получить доступ к высококачественным средствам обработки поверхностей, используя их для неинтерактивых приложений рендеринга.

Инфраструктура мультипроцессирования

Одной из целей проекта OpenGL Optimizer было продвижение мультипроцессорной технологии, опробованной SGI в графических комплексах высшего класса, на настольные системы. Причем сделать это требовалось таким образом, чтобы средства распараллеливания основывались на стандартах и были мобильны. Это очень важный шаг - сосредоточение всех ресурсов обработки на одной задаче - визуализации. В сегодняшних ОС это не предусмотрено, в них есть только базовые примитивы распараллеливания и аппарат разделения ресурсов между несколькими задачами. Важно также понять, что любая графическая система многопроцессорна по умолчанию - имеет хост и графическую машину. Поэтому даже на однопроцессорном компьютере можно получить выигрыш от использования множественных процессов. К примеру, хост может производить отсечение в тот период времени, когда процесс OpenGL заблокирован и ожидает рассасывания графической очереди.

Аппарат OpenGL Optimizer создает инфраструктуру, упрощающую разработку задач с взаимодействующими процессами. На верхнем уровне можно выделить две группы средств:

  • диспетчеризации и управления процессами;
  • безопасной модификации графа сцены.

Создание мультипроцессорных программ заключается в следующем. Приложение формирует списки объектов-действий, реализующих требуемую функциональность. К примеру, сцена может быть разбита на несколько фрагментов, и рендеринг каждой из них поручен отдельному действию. Список действий передается диспетчеру, который помещает их в очередь. Продвижение действия по очереди управляется его приоритетом, и когда оно оказывается в голове очереди, начинается его выполнение.

Запуск действий вообще говоря происходит параллельно, и чтобы получить эффективную программу, необходимы средства для контроля и управления порядком их выполнения. Весьма вероятно, что придется реализовать зависимости между процессами типа: 'выполнять A после B' или 'подождать окончания C'. В OpenGL Optimizer это осуществляется методами посылки и приема сообщений waitForRequests(), markRequests().

Для координации изменений графа сцены несколькими процессами, в OpenGL Optimizer применяется метод "одного хозяина". Один процесс (обычно это процесс рендеринга) контролирует все модификации. Другие процессы могут только читать из графа, но не могут его менять напрямую. Вместо этого они обращаются к Монитору Транзакций с запросами, включающими полный цикл считывания-обновления, которые помещаются в очередь и обрабатываются в порядке поступления.

Использование OpenGL Optimizer

Исходя из вышеизложенного, можно сделать вывод, что OpenGL Optimizer - многофункциональная система с большим количеством интероперабельных компонентов. Каким способом их лучше всего использовать? Все зависит от разрабатываемого приложения. Если, например, оно самостоятельно выполняет триангуляцию модели, то можно обойтись симплификатором для генерации ее упрощенных вариантов. Но система проявляется во всем своем блеске лишь в том случае, когда задействуются все средства.

Типичное приложение OpenGL Optimizer состоит из двух частей: подготовительной и интерактивной. Первая после загрузки модели может обратиться к OpenGL Optimizer: для извлечения топологических метаданных и для построения нескольких разбиений модели при различных разрешениях. Если в результате разбиения получено слишком большое количество полигонов, можно вызвать симплификатор с целью уменьшения объема геометрической информации. Завершает подготовку генерация пространственной организации сцены - операция, в значительной степени увеличивающая производительность интерактивной фазы.

Расширенный граф сцены передается интерактивной части приложения, которая выполняется циклически при рендеринге каждого кадра. Обходя граф, эта часть производит в реальном времени все виды отсечений. В ходе этого процесса можно выбирать разрешение элементов модели, наиболее подходящее для генерации картинки, исходя из текущего положения точки наблюдения и программно измеряемой скорости воспроизведения. На каждом шаге цикла через OpenGL Optimizer можно производить сортировку и оптимизацию графического потока в несколько нитей рендеринга.

Примененные вместе, все эти виды оптимизации, способны поднять графическое быстродействие на порядок и более. Для пользователей систем CAD и мультимедиа это означает, что современная метафора "прогулки по сцене" в скором времени уступит место полномасштабному взаимодействию со сценами любой сложности на интерактивной скорости при высокореалистичном воспроизведении. Под сложностью сцены здесь понимается практически неограниченное число объектов, их многоуровневая вложенность, абсолютная точность представления в модели проектной информации.

Заключение

Не так давно подводились итоги прошедшего года. OpenGL Optimizer получил приз от Computer Graphics World Magazine как самая заметная инновация 1997 г. и вошел в десятку лучших программных продуктов по рейтингу журнала IEEE Computer Graphics and Applications. Представители отечественной компьютерной прессы не скрывают своего скепсиса по поводу множества расплодившихся премий однако в данном случае речь идет о наградах, выданных ведущими журналами по машинной графике.

Литература

  1. Е.Хухлаев "Аппаратное ускорение для OpenGL",- Открытые Системы, N 2, 1997.
  2. Е.Валентинов "OpenInventor как средство разработки интерактивных графических приложений",- Открытые Системы, N 6, 1997.
  3. Silicon Graphics, OpenGL Optimizer 1.0, - http://www.sgi.com/Technology/OpenGL/optimizer_wp.html
  4. OpenGL Optimizer Programmer's Guide: An Open API for Large Model Visualization