Выбор основного языка программирования и графической библиотеки для реализации программ компьютерной графики – Часть 3

Различия между библиотеками DirectX и OpenGL

По своей сути данные библиотеки различаются обработкой графической информации, и если OpenGL – это процедурная система, то DirectX основан на COM-модели. Однако, даже несмотря на различную природу работы с информацией, обе библиотеки оптимальным образом сконфигурированы под взаимодействие с аппаратными устройствами. OpenGL не поддерживает напрямую Pixel Shaders, однако это не повод отказываться от работы с этой библиотекой (пример тому Unreal Tournament, движок которого построен на основе OpenGL). Библиотека DirectX в состоянии эмулировать некоторые функции, не поддерживаемые аппаратно, однако на пиксельном уровне это неосуществимо и программа должна сама проверять возможности такой эмуляции. Чтобы внедрять новые технологии, у OpenGL существует механизм расширений, когда различные функции (недоступные изначально, но реализованные аппаратно) разрабатываются производителем железа и поддерживаются спецификацией для конкретной модели видеоадаптера. В DirectX система немного другая – версия библиотеки может содержать или не содержать определенных функций (даже если они присутствуют в железе) и для их поддержки требуется ждать нового релиза DirectX, однако Microsoft активно общается с производителями видеокарт, и такая ситуация возникает достаточно редко.

То есть, хотя поддержка на уровне железа и реализована по-разному (различается как реализация базовых функций, так и фирменные технологии, направленные на улучшение качества графики), выявить лучший механизм сложно, поскольку новые функции OpenGL доступны лишь через extensions, тогда как для DirectX приходится ждать новой версии библиотеки.

Программная поддержка и реализация

OpenGL

Поскольку данная библиотека разрабатывалась группой компаний, она является мультиплатформенной и поддерживается большим количеством языков программирования (включая Java, Perl, Python), операционных систем (Windows, Macintosh, *nix). Причем любой производитель видеоадаптеров может купить лицензию и выпустить свою версию OpenGL не только для компьютера, но и для других устройств (существуют реализации под игровые консоли, КПК и даже телефоны). Консорциум, занимающийся продвижением OpenGL, рассматривает большинство расширений, созданных производителями видеоадаптеров, и всегда есть вероятность их включения в спецификацию следующей версии библиотеки.

DirectX

DirectX разрабатывается одной лишь компанией Microsoft, и, соответственно, официальная поддержка доступна только для операционных систем семейства Windows и платформы XBox. Причем необходимо отметить тот факт, что поддержка новейших версий библиотеки на старых версиях операционной системы может быть затруднена либо полностью отсутствовать. Учитывая, что данная работа не требует новейших достижений программирования трехмерной графики, таких как шейдеры, можно считать, что достаточно использовать девятую версию библиотеки DirectX, которая без проблем поддерживается такой широко распространенной системой как Windows XP.

Сравнение программных реализаций

Если обратить внимание на программную реализацию обоих библиотек, то можно сделать единственный вывод: программировать приложения с использованием OpenGL гораздо легче, чем писать их под DirectX (для примера: чтобы нарисовать обыкновенный треугольник на экране с использованием DirectX, нужно написать почти в 5 раз больше текста, чем с использованием OpenGL). Правда, разработчики D3D постоянно пытаются облегчить работу программистов, объединяя наиболее часто используемые вызовы и операции в Common Files. Факт большей простоты OpenGL будет принят во внимание при принятии окончательного решения об использовании библиотеки.

Рисунок 5. Сравнительная схема программных реализаций DirectX (слева) и OpenGL (справа).

Microsoft включает в Windows библиотеки OpenGL, причем версии «слегка» устаревшей, которая ко всему прочему не использует аппаратные возможности ускорения, это серьезное «упущение» исправляют драйверы графических ускорителей.

Также необходимо отметить, что компанией Microsoft было выпущено несколько версий Managed DirectX, то есть версии данной библиотеки на платформу .NET. Как было разъяснено выше, для реализации алгоритмов настоящей работы будет использовать один из языков платформы .NET, а именно C#, так что будет естественным использовать также managed-версию графической библиотеки. Графическая библиотека OpenGL также портирована на C#, но, будучи процедурной, весьма посредственно вписывается в концепцию объектно-ориентированного языка. Таким образом, поддержка managed-языков без необходимости организации прослойки между managed- и unmanaged-модулями системы дает большое преимущество использованию комбинации Managed DirectX и C#.

Простейшая программа на OpenGL и на Direct3D

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

Для начала очистим фон. В OpenGL для этого потребуется написать следующую строку:

glClear(GL_COLOR_BUFFER_BIT);

где glClear() — функция, предназначенная для очистки буферов, а константа GL_COLOR_BUFFER_BIT указывает, что именно нужно очистить.

Для аналогичной операции в D3D нужно написать

d3d_Device->Clear (0, 0, D3DCLEAR_TARGET, D3DCOLOR_XRGB (0, 0, 0), 0, 0);

Clear обладает большей функциональностью и, как следствие, более сложным синтаксисом. Поскольку нам эта функциональность не нужна — среди параметров так много нулей. Первые два отвечают за возможность очищения не всего кадра, а некоторого количества прямоугольников. Последняя пара отвечает за очистку только тех точек, удаление которых от камеры (координата Z) находится в определенных пределах. Константа D3DCLEAR_TARGET указывает на то, что мы будем очищать буфер неким цветом, указанным в четвертом параметре (черный цвет).

Вот рабочее пространство и готово, можно приступать к рисованию. В OGL все примитивы для обрисовки должны находиться между вызовами glBegin() и glEnd(), некоторым их аналогом в D3D являются d3d_Device->BeginScene () и d3d_Device->EndScene (). В случае с OGL уже можно привести фрагмент кода, выполняющий нашу задачу:

glBegin(GL_TRIANGLES);
glColor3d(1,0,0);
glVertex3d(1,2,3);
glColor3d(0,1,0);
glVertex3d(4,5,6);
glColor3d(0,0,1);
glVertex3d(7,8,9);
glEnd();

glVertex3d — это вершины нашего треугольника, Название функции интуитивно понятно, но 3d, как ни странно, не означает «трехмерный»; точнее, 3 — как раз означает, а вот d — это тип аргументов (double). GL_TRIANGLES указывает, что все последующие вершины будут последовательно образовывать треугольники (если бы у нас было не три, а шесть вершин — получилось бы два треугольника). glColor3d принимает на вход цветовые компоненты RGB, и все вершины, идущие после него и до следующего вызова glColor, будут иметь соответствующий цвет.

В D3D перед рисованием необходимо подготовить специальную структуру данных:

struct CUSTOMVERTEX { FLOAT x, y, z, rhw; DWORD color;};
CUSTOMVERTEX g_Vertices[] =
{
{1, 2, 3, 1, 0xffff0000},
{4, 5, 6, 1, 0xff00ff00},
{7, 8, 9, 1, 0xff0000ff},
};
LPDIRECT3DVERTEXBUFFER8 p_VertexBuffer = NULL;

Эта структура содержит и координаты вершин, и их цвета. p_VertexBuffer — указатель на нашу структуру, для хранения вершин.

Теперь напишем следующее:

d3d_Device->CreateVertexBuffer (3*sizeof(CUSTOMVERTEX),
0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &p_VertexBuffer);
VOID* pVertices;
p_VertexBuffer->Lock (0, sizeof(g_Vertices), (BYTE**)&pVertices, 0);
memcpy (pVertices, g_Vertices, sizeof(g_Vertices));
p_VertexBuffer->Unlock();

CreateVertexBuffer — выделяет место на устройстве под три вершины (3*sizeof(CUSTOMVERTEX),) и присваивает его нашему указателю (p_VertexBuffer). Далее «запираем» (Lock()) буфер вершин, чтобы случайно его не повредить. Копируем весь наш буфер (memcpy()) в буфер видеокарты. И снова разрешаем доступ (Unlock();).

И наконец, мы готовы к рисованию:

d3d_Device->BeginScene ();
d3d_Device->SetVertexShader (D3DFVF_CUSTOMVERTEX);
d3d_Device->SetStreamSource (0, p_VertexBuffer, sizeof(CUSTOMVERTEX));
d3d_Device->DrawPrimitive (D3DFVF_XYZRHW | D3DFVF_DIFFUSE, 0, 1);
d3d_Device->EndScene ();

SetVertexShader() определяет тип вершин. SetStreamSource() задает поток для дальнейшей работы. Здесь 0 — номер потока, второй параметр — данные, которые присваиваются к этому потоку, и третий параметр — размер, занимаемый в памяти одной вершиной. DrawPrimitive — рисует примитивы на экране, принимает на вход (в порядке следования) тип примитивов для отрисовки, индекс первой вершины, с которой нужно начать рисование, и количество примитивов в последовательности.

Новое слово в разработке трехмерных приложений – XNA

XNA – это надстройка над unmanaged (классическим) DirectX. Во всяком случае, такую картину можно наблюдать для операционной системы Windows. Дело в том, что XNA является кроссплатформенной библиотекой.

Библиотека разрабатывалась корпорацией Microsoft с целью создания единого инструмента для разработки игр на двух не совместимых платформах, принадлежащих той же компании, а именно: Microsoft Windows и Microsoft XBOX360. В связи с этим XNA framework не является банальной оберткой DirectX.

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

Во-вторых, математические классы XNA не являются обертками над неуправляемым DirectX, а полностью реализованы с нуля. Что, в большинстве случаев, позволяет добиться производительности на уровне классического DirectX.

В-третьих, используя специализированные классы библиотеки, программист может лишить себя «удовольствия» писать обработчики на такие задачи, как обработка потери устройства, загрузка/выгрузка контента (модели, текстуры и др.), организация игрового цикла и многие другие «прелести», которые очень сильно омрачали жизнь каждому программисту компьютерной графики.

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

Выводы

Итак, рассмотрев две наиболее популярных графических библиотеки – OpenGL и DirectX, а также одну из наиболее прогрессивных технологий для разработки трехмерных приложений – библиотеку XNA, можно сделать следующие выводы о выборе технологии для реализации системы согласно задаче настоящей работы.

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

Итак, обе библиотеки достаточно мощные и производительные, но их преимущества проявляются в разных областях. DirectX оптимально подходит для создания игр и других графических приложений под операционной системой Windows (что чаще всего и происходит), OpenGL же лучше всего проявляет себя на мощных рабочих станциях и там, где требуется совместимость приложений с различными платформами (как программная, так и аппаратная). Хотя и в сфере игр эта библиотека так же достаточно востребована (Doom III, Unreal Tournament 2004). Если разрабатываемая система имеет своей целью только платформу Windows, причем в качестве основного языка программирования выбран C# на платформе .NET, то очевидным выбором в качестве графической библиотеки становится Managed DirectX.

Реклама
Запись опубликована в рубрике Разные старые статьи. Добавьте в закладки постоянную ссылку.

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s