Open GL - статьи

Архитектура

Более глубоко погружаясь в технологию OpenGL, мы обнаружим стройную и гармоничную архитектуру, общий вид которой показан .
Точно так же, как процессор имеет два типа конвейеров - для целочисленных вычислений и чисел с плавающей точкой, OpenGL имеет два конвейера для пиксельных данных и вертексных операций, то есть для операций с векторными данными. Каждый из потоков обрабатывается отдельно, до тех пор пока это возможно - то есть до стадии мэппинга, когда пиксельные растры как фактуры "натягиваются" на плоскости и более сложные поверхности.
Первый этап - аппроксимация кривых и поверхностей вычислением полиномов от входных значений. Второй проход оперирует с примитивами типа точек, отрезков и полигонов - они преобразуются по правилам аффинных преобразований, совмещаются и сцена отсекается в подготовке к растрированию.
Растрирование в качестве результата создает список объектов (точек, отрезков и треугольников) в двумерной плоскости. Над отдельными объектами может быть выполнена операция раскрашивания, градиентной заливки или применения мэппинга, то есть наложения фактуры.
Готовые фрагменты окончательно обрабатываются перед тем, как они реально будут внесены в frame buffer. В частности, фрагменты сортируются зависимо от значений "глубины" - и эти значения сравниваются с известными на предмет рекомпозиции. Применение блендинга приводит к тому, что прозрачные фрагменты принимают цвет, состоящий из их собственного и цветов "ниже лежащих" фрагментов. Дополнительно может быть реализовано маскирование и другие эффекты.
Пиксельный процессор в ходе растрирования встраивает двумерные битовые фрагменты прямо в кадр. Часть готового кадра также может быть прочитана для повторного использования как массив пикселей - так что данные, отображаемые в буфере, могут стать частью других сцен.

Что будем рисовать

Конечно, можно было нарисовать простую пирамиду или же куб. Но мы сделаем большее - нарисуем "признание в любви"** (рис.1). Специально для этого методом "научного перебора" была разработана модель, описывающая соответствующую кривую:
Что будем рисовать
Остается только перевести ее с языка математики на нормальный человеческий.

Функции

Ниже перечислены основные функции OpenGL, о некоторых из них уже упоминалось. По ним вы можете судить об уровне языка и используемых примитивах.
  • Альфа-канал. Позволяет делать предметы прозрачными, уровень прозрачности от 0 до 100%.
  • Антиалиасинг. Сглаживание цветовых переходов, более реалистическое изображение.
  • Буфер аккумулятора. Дополнительный буфер для 2,5-мерных эффектов, спецэффектов и глобального сглаживания по всей сцене.
  • Градиентная заливка (gouraud shading). Линейно-градиентная заливка полигонов и отрезков.
  • Графические примитивы. В пространстве: точка, отрезок, полигон, битовое изображение или изображение в другом формате.
  • Двойная буферизация. Применяется для сглаживания эффектов анимации, когда новое изображение строится на заднем плане и потом отображается целиком. При этом пользователь не видит самого процесса создания изображения в несогласованном состоянии, например различных "изнанок объектов", "дыр в пространстве", "граней мира" и подобных нежелательных деталей.
  • Заливка и освещенность фактур. К фактурам применяются эффекты освещенности и затенения в зависимости от характеристик "материала". В версии 1.2 реализованы блики поверх текстур.
  • Маскирование. Можно маскировать некоторые цвета по трафарету.
  • Массивы вершин. Новая возможность версии 1.5 - для повышения производительности задавать вершины массивами, а не отдельно.
  • Обратная связь. Данные после растрирования могут быть возвращены в приложение вместо передачи из/в frame buffer или параллельно с ней.
  • Пересечения. Автоматическое определение того, пересекает ли тот или иной объект заданный пространственный регион.
  • Пиксельные операции. Масштабирование и другие аффинные преобразования битовых образов.
  • Поддиапазоны. Возможность работать с частью матрицы вершин; применяется как метод оптимизации.
  • Полиноминальные операции. Поддержка неравномерных рациональных би-сплайнов для описания кривых поверхностей.
  • Полноцветное отображение. Представление в режиме RGBA, то есть тремя цветами и значением альфа-канала. Начиная с версии 1.2, поддерживаются также схемы BGRA и схемы с упакованными цветами для быстрой обработки популярных типов графических файлов.
  • Пространственные преобразования. Масштабирование, вращение и перемещение объектов в пространстве.
  • Режим индексированных цветов. Представление цветов не RGB-триплетами, а индексами в таблице цветов. Применяется для сжатия размена изображений "по глубине цвета" и эффектов быстрой замены одного цвета другим.
  • Режим прямой отрисовки. Рисование по мере поступления команд, без использования списков отображения.
  • Смешивание цветов. Позволяет устанавливать несколько режимов наложения одного изображения на другое. С помощью этой операции, в частности, реализуется альфа-канал и другие эффекты.
  • Список отображения (display list). Пакет описания объектов сцены для предварительного разбора и оптимизации кэширования.
  • Текстуры. Наложение двухмерных изображений на объемные поверхности для придания сцене реализма. Начиная с версии 1.2, поддерживаются трехмерные текстуры. Кроме того, начиная с этой же версии, поддерживается уровень текстур, позволяющий загружать их только до определенной степени детализации - в целях экономии памяти текстур.
  • Z-буффер. Понятие об удалении объектов и их частей от наблюдателя, часть алгоритма удаления скрытых поверхностей.


  • С точки зрения сложности освоения

    С точки зрения сложности освоения OpenGL сопоставим с другими подобными библиотеками. Так что с одной стороны нет разницы, в чем разбираться и что изучать. Но с точки зрения разумного подхода любой проект трехмерной графики должен как минимум поддерживать OpenGL в качестве одной из опций. Ведь серьезные вещи считаются и визуализируются, как правило, под Unix/IRIX/Linux/FreeBSD, и в то же время было бы неправильно игнорировать пользователей Windows. Так что OpenGL как раз и является тем универсальным языком и общим знаменателем, позволяющим вашим приложениям свободно мигрировать с одной платформы на другую.
    программы.

    OpenGL и Delphi на практике

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

  • Формат пикселей удобно вынести в отдельную процедуру, которую мы оформим следующим образом: procedure SetDCPixelFormat (dc: HDC); var pfd: TPixelFormatDescriptor; nPixelFormat: Integer; begin FillChar (pfd, SizeOf (pfd),0); with pfd do begin nSize:= sizeof (pfd); nVersion:= 1; dwFlags:= PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER; iPixelType:= PFD_TYPE_RGBA; cColorBits:= 16; cDepthBits:= 64; iLayerType:= PFD_MAIN_PLANE; end; nPixelFormat:=ChoosePixelFormat (DC,@pfd); SetPixelFormat (DC, nPixelFormat,@pfd); end;
    Здесь при заполнении структуры TPixelFormatDescriptor мы задаем параметры будущего графического отображения, в том числе количество цветовых бит, а также тип пикселей (iPixelType). Мы также задаем флаги, которые, как видно из названия, указывают, что наша программа будет поддерживать OpenGL, а также что мы будем рисовать в окне и использовать двойную буферизацию (параметр, необходимый для воспроизведения движущихся объектов).
    Далее посредством вызова ChoosePixelFormat система выбирает подходящий формат пикселя - и мы присваиваем его (через SetPixelFormat) нашему окну.
    Теперь нужно инициализировать контекст самого OpenGL посредством функций, содержащихся в модуле Windows, и произвести дополнительную настройку движка: procedure TForm1.FormCreate (Sender: TObject); begin H:=Handle; DC:=GetDC (H); SetDCPixelFormat (DC); RC:=wglCreateContext (DC); wglMakeCurrent (DC, RC); glClearColor (0.6,0.6,0.6,1.0); glMatrixMode (GL_PROJECTION); glLoadIdentity; glFrustum (-1,1,-1,1,2,20); glMatrixMode (GL_MODELVIEW); glLoadIdentity; glTranslatef (0.0,-1.0,-6.0); BeginPaint; end;
    Как видим, сначала мы задали для нашей графики необходимый формат пикселей. Теперь при помощи функции wglCreateContext создаем OpenGL-контекст, а впоследствии делаем его текущим контекстом. Далее, используя уже универсальные функции**, произведем настройку "мира", который будем создавать. Для этого через glClearColor очистим контекст и заполним ее 60-процентным черным цветом. Далее выберем матрицу проекций, которая определяет, как будут проецироваться трехмерные объекты на плоскость экрана (в оконные координаты) и через glLoadIdentity установим единичную матрицу и зададим границы плана в "мировых координатах" при помощи вызова glFrustum. После чего загрузим модельно видовую матрицу и произведем ее смещение (glTranslatef).

    OpenGL: раскрой глаза на трехмерную графику

    Арсений Чеботарёв,
    Современный мир уже немыслим без трехмерной графики - в том числе интерактивной. В свое время было предпринято множество попыток создать универсальный язык описания трехмерных сцен. Самой удачной оказалась попытка компании Silicon Graphics - ее язык OpenGL получил всемирное признание
    Многие из вас знают, что все самые красивые спецэффекты, а также почти вся промышленная 3D графика рендерится в формате OpenGL. Этот формат был разработан Silicon Graphics и в настоящее время стал стандартом де-факто для трехмерного моделирования. Я попытаюсь дать краткий обзор этой технологии, и во второй части статьи наш "заслуженный дельфиец" Миша Продан покажет пару примеров ее использования, разумеется, средствами Delphi.

    Принципы

    Основная идея OpenGL: графическая библиотека должна быть аппаратно независимой, но в то же время использовать аппаратные ускорители, если они доступны. Кроме того, этот язык с самого начала предусматривал механизм расширения и гибкости - по мере того как расширения становились "общепринятыми", они становились частью следующего релиза.
    Для любого протокола, будь то сетевой протокол или язык описания сцен, важным является вопрос уровня абстракции - то есть того, на каком уровне работает данная система или протокол, что является входными данными и что выходными, какие компоненты будут взаимодействовать в качестве поставщиков и приемников данных. Говоря попросту, нужно определиться по вопросу "что мы делаем и чего не делаем".
    Создатели OpenGL планировали свой язык с явным намерением создать "виртуальный графический акселератор", так чтобы примитивы OpenGL максимально соответствовали примитивам современных графических карт и требовали минимум кода для трансляции из одной системы команд в другую. Фактически большинство современных графических процессоров (обычно называемых видеокартами, хотя к видео они имеют лишь касательное отношение) напрямую воспринимают OpenGL как язык входного уровня без какой-либо (или с минимумом) трансляции.
    OpenGL оперирует графическими примитивами "начального уровня", такими как точки трехмерного пространства (вертексы, вершины), отрезки прямых, выпуклые полигоны и растровые изображения. Поддерживаются аффинные и проективные преобразования, вычисление освещения. К "продвинутым" функциям можно отнести мэппинг текстур (натягивание битовых карт на трехмерные поверхности) и антиалиасинг (сглаживание цветовых переходов - как локальное, в рамках отдельного объекта, так и глобальное, по всей сцене). Предполагается, что приложение более высокого уровня будет выполнять операции, которых недостает в OpenGL,- например, декомпозицию невыпуклых полигонов.
    С точки зрения программиста, OpenGL - это система вызовов процедур с передачей им параметров, то есть этот язык представляет собой Call Level API. Ключевым моментом с точки зрения производительности, особенно в сетевом окружении, является наличие двух режимов: пошагового и пакетного. Пакетный группирует команды описания объектов и режимы в пакет, называемый списком отображения (display list). Подобная техника применяется, например, при описании страниц в PostScript или, в несколько другом контексте, при создании хранимых процедур в SQL. Смысл ясен - инкапсуляция функциональности (в данном случае - объектов для последующего многократного использования). При этом можно провести несколько оптимизаций: предварительно один раз проверить синтаксис, а также кэшировать готовый объект при передаче по сети на целевой машине.
    Недостаток списка отображения проявляется при частом внесении в него изменений - при этом, понятно, ни один метод оптимизации не будет работать. Для работы с такими "изменчивыми" объектами и сценами в OpenGL предусмотрен режим прямого отображения, когда каждое предложение интерпретируется в порядке поступления, не дожидаясь закрывающего список тега или какой-то подобной команды на отрисовку. В практике оба метода нашли широкое применение.

    Приоритеты

    При реализации авторы ставили себе пять ориентиров, важных с точки зрения получаемых результатов.
  • Производительность. С самого начала в OpenGL была заложена "крайне желательная" возможность отрисовки динамических сцен. Для получения нужных результатов в систему введено множество параметров, или, как говорят, режимов рисования. Если некоторый режим или комбинация режимов на данном оборудовании не в состоянии обеспечить интерактивного взаимодействия и необходимой частоты обновления сцены, то пользователь или сама программа должны быть в состоянии отключать так много дополнительных функций, сколько нужно для получения "живой" картинки.
  • Ортогональность. По возможности все функции OpenGL являются ортогональными, то есть независимыми. Вы можете использовать их в произвольной комбинации, например использование мэппинга не ограничивает возможностей применения светотени.
  • Полнота. Насколько это представляется возможным, OpenGL соответствует набору функций, предоставляемому современными аппаратными средствами графической акселерации. OpenGL старается избегать всего, что должно быть реализовано программно. С другой стороны, по крайней мере, гарантируется получение рабочей картинки, даже если производительность и не позволяет получить ее со всеми подробностями. То есть, если что-то работает на одной платформе, то этот же код будет работать и на другой - хотя, возможно, и с другим результатом.
  • Интероперабельность. В сетевом окружении важно передавать данные между разными платформами. Поэтому OpenGL заранее ориентирован на работу в режиме клиент-сервер, даже если и клиент и сервер расположены на одном компьютере.
  • Расширяемость. Поскольку OpenGL рассчитан на максимальное соответствие возможностям аппаратуры (а аппаратура, как известно, имеет тенденцию развиваться), то в OpenGL также встроены механизмы включения новых функций. С другой стороны, нестабильный интерфейс затрудняет жизнь разработчиков, поэтому новые возможности накапливаются достаточное время и применяются согласованно с выходом новой версии.


  • Прорисовка сцены

    Прорисовка сцены
    Подготовку сцены начнем с подключения разных дополнительных функций, без которых дальнейшая работа невозможна. Эти функции прописаны в методе BeginPaint, а также в методе FormResize (чтобы при изменении размера формы соответственно менялся размер объекта). Для этого используем функцию glEnable с соответствующими параметрами.
    Далее в FormPaint используем подготовленные заранее методы DrawFace и DrawElement (см. листинг ниже) для отрисовки упомянутого объекта. А для придания ему еще большей "жары" используем возможности OpenGL по освещению сцены.

    Ресурсы

    Для быстрого и всестороннего "проникновения" идеями OpenGL вы должны (как минимум) детально изучить две книги, являющиеся "классикой жанра". Первая из них носит название (на ее обложке действительно преобладает синий цвет) и представляет собой справочник по функциям и переменным.
    Вторая книга (а возможно, по порядку прочтения и первая) - это OpenGL Programming Guide, так называемая .
    Красная книга снабжена примерами, на которые я бы советовал обратить самое пристальное внимание. К слову: указанные ссылки ведут к устаревшим версиям документации, не описывающим новые возможности. Новые версии доступны только в печатном виде. Можете попробовать найти их через сети P2P - однако результаты такого поиска предсказывать не берусь.

    

        Биржевая торговля: Механические торговые системы - Создание - Программирование