Главная » Free Pascal » Начальные установки системы GLUT OpenGL Free Pascal

0

Большинство руководств, методических пособий и опубликованных книг, так или иначе связанных с OpenGL, рекомендуют начинать пролог с обращения к про- цедуре glutInit, передавая ей адреса двух аргументов — счетчика параметров ко-

мандной строки (@argc) и указателя на строку, содержащую все параметры, вклю- чая и имя запускаемого приложения (@argv). В одном из таких руководств, разме- щенных на сайте Wikipedia, даже приводится пример процедуры на Паскале, из- влекающей нужные данные из командной строки и передающей их процедуре инициализации системы GLUT (листинг 16.1).

   Листинг 16.1. Пр име р  инициал иза ции                                                                                           

procedure glutInitPascal(ParseCmdLine: Boolean);

var

Cmd: array of PChar; CmdCount, I: Integer;

begin

if ParseCmdLine then

CmdCount := ParamCount + 1

else

CmdCount := 1; SetLength(Cmd, CmdCount); for I := 0 to CmdCount – 1 do

Cmd[I] := PChar(ParamStr(I)); glutInit(@CmdCount, @Cmd);

end;

В этой процедуре все правильно, кроме одного — пользоваться этой процеду- рой не стоит. Вместо того чтобы включать указанную процедуру в текст своего приложения и обращаться к ней с помощью следующего вызова: glutInitPascal(true);

в программе на языке Free Pascal достаточно выполнить другой, менее затратный вызов:

glutInit(@argc,argv);

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

int main(int argc, char *argv[]);

Однако компилятор FP не считает приведенное обращение к glutInit ошибоч- ным, т. к. в модуле System, который автоматически подключается ко всем прило- жениям FP, содержится описание указанных переменных. Заполнение их нужными значениями происходит также автоматически в момент запуска приложения, и дублировать уже выполненную работу смысла не имеет.

Нам стало интересно, о каких параметрах командной строки, предназначенных для утилит GLUT, идет речь. Дело в том, что в некоторых литературных источни- ках туманно намекали, что командная строка может быть использована для переда- чи в GLUT имен файлов, необходимых для выполнения операций текстурирования. Для устранения недомолвок и эффекта испорченного телефона пришлось заглянуть в исходный текст процедуры glutInit, благо он открыт для всех на сайте http://www.opengl.org. Оказалось, что при проектировании этой процедуры ее ав- тор М. Килгард предусмотрел возможность задания нескольких ключей, разме- щаемых в командной строке. Мы упомянем только те из них,  которые  имеют смысл при работе в среде Win32:

± -display k — количество мониторов, подключенных к ПК (k=1 или k=2);

± -geometry W x H + X + Y — ширина и высота графического окна, его позиция на экране;

± -iconic — старт с графическим окном, свернутым в значок.

Хочется верить, что автор завел эти ключи для себя, чтобы экспериментировать с рядом параметров без перетрансляции программы. На самом деле, нагружать пользователя заданием нелепого набора данных не стоило. Количество дисплеев по умолчанию GLUT извлекает из списка оборудования, графическое окно на экране можно перетаскивать и изменять его размеры, сворачивать и разворачивать. Кроме того, влияние ряда ключей автоматически будет изменено при вызове таких процедур как glutInitWindowSize, glutInitWindowPosition. Одним словом, возня с исполь- зованием параметров командной строки сродни пустым хлопотам.

Но, так или иначе, какие-то другие операции, связанные с настройкой утилит GLUT, должны быть выполнены, и начинать их надо с упомянутого ранее обраще- ния к процедуре glutInit.

Для задания ширины (w) и высоты (h) графического окна может быть использо-

вана процедура glutInitWindowSize:

glutInitWindowSize(w, h);      // размеры задаются в пикселах

По умолчанию создается окно размером 300  300.

Если вы хотите расположить графическое окно в заданном месте экрана, то можно воспользоваться процедурой glutInitWindowPosition: glutInitWindowPosition(X, Y);  // значения X и Y в пикселах

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

В группе команд инициализации утилиты GLUT довольно часто используется обращение к процедуре установки режимов отображения. Один из возможных ва- риантов выбора режима демонстрирует следующий вызов: glutInitDisplayMode(GLUT_DOUBLE or GLUT_RGB or GLUT_DEPTH);

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

± GLUT_DOUBLE — режим отображения с двойной буферизацией;

± GLUT_RGB — управление цветом пикселов в формате truecolor;

± GLUT_DEPTH — окно с буфером глубины (Z-буфер).

Таблица 16.2

Признак режима

Пояснение

GLUT_RGBA

Управление цветом в формате TrueColor с признаком прозрачности

GLUT_RGB

То же самое (этот режим установлен по умолчанию)

GLUT_INDEX

Управление цветом по индексу в палитре

GLUT_SINGLE

Формирование изображения в единственном буфере (действует по умолчанию)

GLUT_DOUBLE

Формирование изображения с двойной буферизацией

GLUT_ACCUM

Окно с буфером накопления

GLUT_ALPHA

Режим использования свойства прозрачности в цветовых буферах

GLUT_DEPTH

Режим использования Z-буфера

GLUT_STENCIL

Режим использования буфера шаблонов. С помощью шаблонов (трафаретов) отдельные части фигуры могут быть вырезаны

GLUT_MULTISAMPLE

Режим, поддерживающий отображение нескольких графических окон

GLUT_STEREO

Режим создания стереоизображений. Для их просмотра используется специальная аппаратура (стереоочки, 3D-дисплеи)

GLUT_LUMINANCE

Режим специальной обработки красной составляющей цвета в модели RGBA, не содержащей зеленой и синей составляющих

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

кадр. Для отображения статических сцен можно использовать схему с одним буфе- ром (признак GLUT_SINGLE), в котором осуществляются текущие построения. В этом случае вывод изображения на экран осуществляет процедура glFlush. Режим уда- ления невидимых частей с помощью алгоритма Z-буфера имеет смысл при обра- ботке трехмерных объектов.

Для работы с графическим окном, в котором отображаются статические или динамические сцены, очень важно иметь набор подпрограмм, которые должны реа- гировать на различные события, возникающие во время сеанса. К событиям такого рода относятся перемещения графического окна и изменение его размеров (в том числе сворачивание в значок и распахивание до предшествующего размера), сигна- лы, поступающие от различных органов управления (мышь, клавиатура, игровые джойстики), истечение промежутка времени, установленного на таймере, и многое другое. Всего таких событий порядка 20. Перечень некоторых из них приведен в табл. 16.3. Там же описаны форматы данных, передаваемые обработчику соответ- ствующего события. Разработчик приложения должен решить, какие из этих собы- тий следует обрабатывать в его программе, и написать текст соответствующих процедур. Вызываться эти процедуры будут из главного цикла утилиты GLUT. Для такого рода подпрограмм обработки событий, инициированных за пределами на- шего приложения, существует англоязычный термин — callback-процедуры. Пере- водят его как подпрограммы обратного вызова, но это название зачастую ставит пользователя в тупик. В системах визуального программирования (например, в Delphi) используют более понятные термины: OnDoubleClickButton1(…) — об- работчик события "двойной щелчок кнопкой мыши" по объекту с именем Button1.

По существу, речь идет о процедурах, к которым наша программа непосредст- венно не обращается. Их вызывает "кто-то другой", и по завершению обработки события управление передается "кому-то другому". Этим кем-то другим является главный цикл утилиты GLUT, который осуществляет сверху управление процеду- рами нашей программы.

Таблица 16.3

Регистратор в GLUT

Событие

Параметры для обработчика

glutDisplayFunc

Перерисовка содержимого окна

Нет

glutReshapeFunc

Восстановление формы

(w, h) — новые ширина и высота

glutKeyboardFunc

Нажатие клавиши

(key, x, y) — код нажатой клавиши и позиция курсора мыши в этот момент

glutMouseFunc

Нажатие кнопки мыши

(button, state, x, y) — кнопка, состояние (нажатие, отпускание) и координаты курсора

glutMotionFunc

Перемещение мыши по графическому окну с нажатой кнопкой

(x, y) — координаты мыши

Таблица 16.3 (окончание)

Регистратор в GLUT

Событие

Параметры для обработчика

glutTimerFunc

Завершение очередного временного интервала после предыдущего вызова таймера

(dt, @func(v), v) — интервал времени в миллисекундах, адрес функции, к которой надо обратиться по "звонку" будильника, аргумент, который передается функции обработки события

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

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

glutDisplayFunc(@OnRedraw);  // процедура перерисовки окна glutReshapeFunc(@OnResize);  // процедура учета изменения формы glutKeyboardFunc(@OnKey);    // обработка событий клавиатуры

После выполнения необходимых операций по настройке утилит GLUT выпол- няется операция по созданию графического окна и запускается главный цикл: glutCreateWindow(‘Prog 1′);         // создание окна с именем Prog 1

glClearColor(0.75, 0.75, 0.75, 1);  // очистка области клиента glutMainLoop;                      // старт главного цикла Glut

Источник: Кетков, Ю. Л., Свободное программное обеспечение. FREE PASCAL для студентов и школьников, Ю. Л. Кетков, А. Ю. Кетков. — СПб.: БХВ-Петербург, 2011. — 384 с.: ил. + CD-ROM — (ИиИКТ)

По теме:

  • Комментарии