Сейчас уже ни кого не удивляет разнообразие игр с 3-х мерной графикой. За относительно небольшие сроки программисты умудряются создать небольшой виртуальный мир. Если посмотреть в его корень, то станут видны сложные математические формулы. Лет 10-15 назад, используя их, программисты с нуля разрабатывали 3-х мерные миры таких игр, как Wolf 3d, Rise Of the Triad, Doom. Тоже самое происходило и с CAD-ситемами для создания моделей будущих механизмов и машин. Сегодня же для этих целей используются готовые программные средства, берущие на себя заботы о прорисовке графики. Наверное, нет человека, который бы не слышал таких названий, как Direct3D, OpenGL. Они являются результатом сотрудничества крупных компьютерных компаний.

 

OpenGL появилась и сформировалась как стандарт 3-х мерной графики в 1992 г. Однако, разработка ее велась еще с 1982. Формированием этого стандарта занимались также такие фирмы, как: Microsoft, IBM сorporation, Sun Microsystems, Inc., Digital Equipment Corporation (DEC), Hewlett-Packard Corporation, Intel Corporation и др. Результат - это OpenGL - стандартная библиотека для многих 32-разрядных операционных систем (Windows, Linux в том числе), в отличие от Direct3D, которая характерна только для Windows. OpenGl содержит в себе более 100 процедур и функций для построения 3-х мерной графики. Они находятся в opengl32.dll (Windows\system\) и в расширении glu32.dll.

 

Чтобы вы могли хотябы немного (:-) представить их возможности, вспомните такие игры как: Quake 3, Return To the Castle Of Wolf, а также хранитель экрана в Windows под названием "Объемный текст" :-).

 

OpenGl можно использовать с разными языками программирования, поддерживающими работу с DLL. Но во многих уже есть поддержка OpenGl, "ограждающая" программиста от непосредственой работы с функциями и процедурами из DLL. Одним из таких языков программирования является Object Pascal, использующийся в среде Delphi. Да, да! Именно Delphi. Этот факт еще раз доказывает то, что в Delphi можно создавать не только скучные базы данных, но и полноценные мультимедийные приложения (игры, демо-програмки). Да и вообще в Delphi столько разных возможностей! Но сегодня поговорим об использовании OpenGl.

 

Delphi и OpenGl

 

Начиная с 3-й версии в комплекте Delphi поставляется заголовочный файл, содержащий описания процедур и функций, содержащихся в opengl32.dll. А также файл помощи с описанием типов, процедур и функций (далее команд). В 3-й версии хэлп очень уж облегченный и почти полностью "стянутый" с СИ, в 5-й версии уже наблюдаются улучшения. Для того, чтобы использовать OpenGL в Delphi-проекте нужно дописать к списку подключаемых модулей opengl. После этого по любой ее команде можно получить подсказку или помощь обычным в Delphi способом. Для использования OpenGL вовсе не обязательно иметь 3d аксселератор (но не помешало бы). При работе с простенькими сценами и для изучения основ вполне достаточно даже S3 Trio с 1 мб. Сервер OpenGL перед началом работы определяет, на каком оборудовании его пользуют и, в соответствие с этим, подбирает оптимальные настройки. Для этого программист в своей программе должен сделать установку формата пикселя, которому соответствует тип TPixelFormatDescriptor. При установке формата пикселя можно задавать различные флаги, влияющие на вывод изображения. Например, если вы используете анимацию, то без установки флага PFD_DOUBLEBUFFER никак не обойтись. Он устанавливает режим двойной буферизации - изображение сначала рисуется в памяти (в буфере), а потом выводится на экран для устранения мерцания. Следует также отметить, что OpenGl является промежуточным звеном между программой и устройством вывода. Т.е. ему надо сообщать, куда будет производиться вывод. Для этого используется контекст устройства и контекст воспроизведения. Первому соответствует свойство canvas.handle формы или др. Для второго - в OpenGl существует специальный тип HGLRC (Handle openGL Rendering Context) - ссылка на контекст воспроизведения.

 

Команды и типы OpenGl

 

Мультиплатформенность OpenGl обусловлена наличием ее собственных типов данных. Начинаются они с префикса GL и приведены в заголовочном файле Delphi - opengl.pas. Многим соответствуют стандартные типы Delphi (например, GLfloat соответствует типу Single - числу с плавающей точкой). Команды OpenGl начинаются тоже с префикса GL, после которого идет обозначение действия команды. В окончании определяется количество требуемых аргументов и их тип. Например, glColor3f - команда OpenGl для установки цвета, использующая 3 аргумента - числа с плавающей точкой (f - от слова float). Если в окончании присутсвует симовол v (пример, 3fv), это значит, что в качестве аргумента будет использоваться массив (окончание 3fv указывает, что аргумент - массив 3-х чисел с плавающей точкой). Практически все команды для рисования размещаются в специальных программных скобках glBegin и glEnd. Они не имеют ничего общего с паскалевским begin, end. У glBegin есть аргумент, которым является константа, определяющая рисуемый далее (до glEnd) графический примитив. Например, между glbegin и glEnd есть команды, задающие координаты вершин примитива. Если аргументом glBegin является, к примеру, константа gl_quads, то построится прямоугольник на задаваемых далее вершинах, если gl_points - просто точки с координатами вершин и т.п. Рекомендуется использовать тип аргументов - GlFloat, но можно работать и с другими. Если вы используете GlFloat, то обратите внимание на то, что вывод будет осуществляться в область от -1 до +1 по x и по y. Так (-1,-1) - координата верхнего левого угла области вывода, а (-0.99,-1) - точка где-то рядом с ним. При задании цвета, 0 - минимальное значение его составляющей (rgb), а 1 - максимальное (вроде, как 255), 0.5 - среднее.


Чтобы разобраться со всем этим на практике давайте рассмотрим простой пример. Он рисует некое кубическое подобие коробка, которое вращается и освещается источником света. Первым делом пропишем процедуру, устанавливающую формат пиксела. Она имеет такой вид:


procedure SetDCPixelFormat (hdc : HDC);

var

pfd : TPixelFormatDescriptor;

nPixelFormat : Integer;

begin

FillChar (pfd, SizeOf (pfd), 0);

pfd.dwFlags :=PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;

nPixelFormat :=ChoosePixelFormat (hdc, @pfd);

SetPixelFormat(hdc, nPixelFormat, @pfd);

end;


Здесь во флагах pfd устанавливаются PFD_SUPPORT_OPENGL или PFD_DOUBLEBUFFER - это “говорит” серверу OpenGL, что система, на которой он будет работать поддерживает работу с ним, а также, что будет использоваться двойная буферизация. Далее ChoosePixelFormat подбирает формат пикселя, а SetPixelFormat - устанавливает этот формат. В качестве аргумента в процедуру передается ссылка на контекст устройства. Далее в обработчиках событий OnCreate и OnDestroy формы напишите следующее:


procedure Tform1.FormCreate(Sender: TObject);

begin

DC := GetDC (Handle);

SetDCPixelFormat(DC);

hrc := wglCreateContext(DC);

wglMakeCurrent(DC, hrc);

glClearColor (0.0, 0.0, 0.75, 1.0);

glMatrixMode (GL_PROJECTION);

glLoadIdentity;

glFrustum (-1, 1, -1, 1, 2, 20);

glMatrixMode (GL_MODELVIEW);

glLoadIdentity;

glTranslatef(0.0, 0.0, -6.0);

end;

procedure Tform1.FormDestroy(Sender: TObject);

begin

wglMakeCurrent(0, 0);

wglDeleteContext(hrc);

ReleaseDC (Handle, DC);

DeleteDC (DC);

end;


В первом случае при создании формы получаем GetDC контекст устройства (в данном случае формы), устанавливаем формат пикстела, с помощью wglCreateContext создаем контекст воспроизведения и делаем его основным (можно использовать несколько контекстов). Переменная hrc имеет тип HGLRC, а DC - HDC. Рекомендуется определять их в разделе private. Затем определяем цвет фона и устанавливаем матрицу преобразования координат для построения объемного изображения. glTranslatef "сдвигает в глубину" рисуемый далее объект.

Теперь создайте на форме кнопку - для запуска анимации. А в ее обработчике события OnCLick наберите такой текст:


procedure Tform1.Button1Click(Sender: TObject);

begin

glEnable (GL_LIGHTING);

glEnable (GL_LIGHT0);

glEnable (GL_DEPTH_TEST);

timer1.enabled:=true;

end;


glEnable позволяет включать разные опции. В данном случае - использование источников света.

 

Далее этой же командой включаем источник света GL_LIGHT0. Их может быть несколько, но в данном случае ограничимся одним. glEnable (GL_DEPTH_TEST) - включает режим проверки глубины изображения. Позднее попробуйте ее убрать - сразу поймете, что к чему.

 

Поместите на форму таймер, установите его интервал 100 и enable=false, а обработчик его события приведите к таком виду:


procedure Tform1.Timer1Timer(Sender: TObject);

begin

glRotatef(1.0, 1.0, 1.0, 1.0);

glRotatef(1.0, 1.0, 1.0, 0.0);

glRotatef(1.0, 1.0, 1.0, 1.0);

SwapBuffers(DC);

InvalidateRect(Handle, nil, False);

end;


На каждый тик таймера будет происходить поворот командой glRotatef на угол 1 (первый аргумент).

 

Затем SwapBuffers(DC) картинку из памяти отобразит на форме. Для перерисовки формы лучше использовать функцию API InvalidateRect - это быстрее, чем repaint. Теперь осталось последнее - задать, что же будет вырисовываться. В обработчике события формы Onpaint каждый раз рисуется одна и та же картинка, но так как по таймеру происходит поворот координатных осей, создается эффект анимации и вращения именно объекта. В OpenGl есть также возможность изменять точку наблюдателя - glLookAt.


procedure Tform1.FormPaint(Sender: TObject);

begin

glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glBegin(GL_QUADS);

glNormal3f(0.0, 0.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, 1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(-1.0, 0.0, 0.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(0.0, 1.0, 0.0);

glVertex3f(-1.0, 1.0, -1.0);

glVertex3f(-1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(1.0, 0.0, -1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(1.0, 1.0, 1.0);

glVertex3f(1.0, 1.0, -1.0);

glEnd;

glBegin(GL_QUADS);

glNormal3f(0.0, 0.0, -1.0);

glVertex3f(1.0, -1.0, 1.0);

glVertex3f(1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, -1.0);

glVertex3f(-1.0, -1.0, 1.0);

glEnd;

end;


GlClear - очищает буфер. А далее заданием коодинат вершин (glVertex) строим стороны куба. glNormal - задает так называемый вектор нормали, требующийся для корректного изменения цвета объекта при освещении. Теперь все готово - можете запускать и любоваться сиим творением.

 

 

Данная статья только знакомит с некоторыми основами OpenGL, но не рассматривает многочисленных нюансов и возможностей этой замечательной библиотеки, т.к. для это потребовалось бы несколько десятков журналов, посвященных только ей. Да и вообще, зачем превращать замечательный журнал в узкоспециализированное учебное поссобие - ведь информации по OpenGL достаточно и в Интернет и на книжных рынках. Могу посоветовать книгу "OpenGL: графика в проектах Delphi", М.Краснов, 2000 г. издательство bhv. Также есть очень интересный материал на сайте delphigfx.narod.ru. Вообще, со слов специалистов, OpenGL более легкий в изучении, чем Direct3D, а по мощности и возможностям не уступает. Причина, по которой многие используют Direct3d в основном заключается в том, что в придачу к нему есть еще библиотеки для работы со звуком, музыкой, сеткой, вводом/выводом. Но вы же видели, что создают парни из Id Software? На мой взгляд, (без лишних слов) OpenGL - rulez! Так, что изучайте. Пригодится не только для создания игр, но и для серьёзных вещей, вроде моделирования работы различных механизмов и т.п.

2004.04.15
19.03.2009
В IV квартале 2008 г. украинский рынок серверов по сравнению с аналогичным периодом прошлого года сократился в денежном выражении на 34% – до $30 млн (в ценах для конечных пользователей), а за весь календарный год – более чем на 5%, до 132 млн долл.


12.03.2009
4 марта в Киеве компания Telco провела конференцию "Инновационные телекоммуникации", посвященную новым эффективным телекоммуникационным технологиям для решения задач современного бизнеса.


05.03.2009
25 февраля в Киеве компания IBM, при информационной поддержке "1С" и Canonical, провела конференцию "Как сохранить деньги в условиях кризиса?"


26.02.2009
18-19 февраля в Киеве прошел юбилейный съезд ИТ-директоров Украины. Участниками данного мероприятия стали ИТ-директора, ИТ-менеджеры, поставщики ИТ-решений из Киева, Николаева, Днепропетровска, Чернигова и других городов Украины...


19.02.2009
10 февраля в Киеве состоялась пресс-конференция, посвященная итогам деятельности компании "DiaWest – Комп’ютерний світ" в 2008 году.


12.02.2009
С 5 февраля 2009 г. в Киеве начали работу учебные курсы по использованию услуг "электронного предприятия/ учреждения" на базе сети информационно-маркетинговых центров (ИМЦ).


04.02.2009
29 января 2009 года в редакции еженедельника "Computer World/Украина" состоялось награждение победителей акции "Оформи подписку – получи приз!".


29.01.2009
22 января в Киеве компания "МУК" и представительство компании Cisco в Украине провели семинар для партнеров "Обзор продуктов и решений Cisco Small Business"

 

 
 
Copyright © 1997-2008 ИД "Комиздат".