Подключение библиотеки OpenGL в Delphi

Автор: Пользователь скрыл имя, 02 Ноября 2012 в 14:22, курсовая работа

Краткое описание

Эта работа посвящена компьютерной графике, а именно тому, как использовать OpenGL в Delphi. OpenGL - это стандартная библиотека для всех 32-разрядных операционных систем, в том числе и для операционной системы Windows. OpenGL - не отдельная программа, а часть операционной системы

Оглавление

ВВЕДЕНИЕ__________________________________________________2стр.
1. Раздел 1 “Windows-приложения“_____________________5стр.
1.1. Событие, сообщение, ссылка ___________________________5стр.
1.2. Перехват сообщений_________________________________10стр.
2. Раздел 2 “Подключение OpenGL”_____________________17стр.
2.1. Минимальная программа OpenGL_____________________17стр.
2.2. Вывод на компоненты Delphi средствами OpenGL _______27стр.
Вывод_____________________________________________________41стр.
Список литературы ____________________________________42стр.

Файлы: 1 файл

Копия Курсовая 1.doc

— 318.50 Кб (Скачать)

procedure MesDblClick (var MyMessage TWMMouse); message wm LButtonDblClk;

Замечание 
          Как правило, перехватчики сообщений для повышения надежности работы приложения описываются в блоке protected

Имя процедуры я задал таким, чтобы не появлялось предупреждение компилятора о том, что я перекрываю соответствующее событие формы. Служебное слово message указывает на то, что процедура будет перехватывать сообщение, мнемонику которого указывают за этим словом. Тип аргумента процедуры-перехватчика индивидуален для каждого сообщения. Имя аргумента произвольно, но, конечно, нельзя брать в качестве имени служебное СЛОВО message. Пожалуй, самым сложным в процессе описания перехвата сообщений является определение типа аргумента процедуры, здесь оперативная помощь оказывается малополезной. В четвертой и пятой версиях Delphi инспектор кода облегчает задачу, но незначительно. Чтобы решить эту задачу для сообщения wm_LButtonDblclk, я просмотрел все вхождения фразы "LButtonDblClk" в файле messages. pas и обнаружил строку, подсказавшую решение:

TWMLButtonDblClk = TWMMouse;

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

Замечание 
          Перехватчики сообщений приходится писать в тех случаях, когда в списке событий нет аналога нужного нам сообщения, а также тогда, когда важна скорость работы приложения. Обработка сообщений происходит быстрее обработки событий, поэтому именно этим способом мы будем пользоваться в приложениях, особенно требовательных к скорости работы в следующем проекте создан обработчик сообщения wmPaint - перерисовка окна:

protected 
          procedure WMPaint(var Msg: TWMPaint); message WM_PAINT; ...

procedure TForml. WMPaint(var Msg: TWMPaint);

var ps: TPaintStruct;

begin BeginPaint(Handle, ps);

Rectangle (Canvas. Handle, 10, 10, 100, 100);

EndPaint(Handle, ps);

end;

Строки Beginpaint и EndPaint присутствуют для  более корректной работы приложения, при их удалении появляется неприятное мерцание при изменении размеров окна Обратите внимание на функцию  построения прямоугольника: я воспользовался тем, что свойство canvas. Handle и есть ссылка на контекст устройства, соответствующая окну формы. Точно так же, как перехватчики сообщений предпочтительнее обработчиков событий, использование непосредственно ссылок на окно и ссылок на контекст устройства предпочтительнее использования их аналогов из мира ООП.

Работа с таймером

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

const 
          AppName = 'WinPaint';

id_Timer = 100; // идентификатор таймера

Идентифицировать таймер необходимо потому, что у приложения их может  быть несколько. Для включения таймера (то, что в привычном антураже соответствует Timerl. Enabled: = True) вызывается функция API SetTimer, где задается требуемый интервал таймера:

SetTimer (Window, id_Timer, 200, nil); // установка таймера

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

wm_Timer: InvalidateRect (Window, nil, False);

Как видим, работать с таймером, используя  только функции API, совсем не сложно. Компонент Delphi TTimer основывается на функциях и  сообщениях, которые мы только что  рассмотрели.

Работа с мышью и  клавиатурой

При нажатой левой кнопки мыши за указателем остается след. Оконная  функция дополнилась обработчиками  сообщений wm_LButtonDown, wm_LButtonUp И wm_MouseMove. Для определения координат курсора пользуемся тем, что поле iParam подобных сообщений содержит эти самые координаты.

Down: = not Down;

wm_Create: Down: = False;

wm_LButtonDown, wm_LButtonUp

wm_MouseMove:

begin If Down then begin xpos: = LoWord ( LParam);

ypos: = HiWord ( LParam); InvalidateRect(Window, nil, False); end; end;

wm_Paint: begin If Down then begin dc: = BeginPaint (Window, MyPaint);

Ellipse (dc, xPos, yPos, xPos + 2, yPos + 2);

EndPaint (Window, MyPaint); ReleaseDC (Window, dc);

end;

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

wm_Char: // анализ нажатой  клавиши

case wParam of $58, $78: If HiWord {GetKeyState (vk_Shift)) = 0 { Shift }  

then

MessageBox(Window, 'X', 'Нажата клавиша', MB_OK) else

MessageBox(Window, 'X вместе с Shift', 'Нажата клавиша', MB_OK);

end; // wm char

При нажатии клавиши 'X' выводится сообщение, в котором  указано, нажата ли одновременно клавиша <Shift>. Я использовал шестнадцатеричное  представление кода клавиши, но, конечно, можно использовать и десятичное. Надеюсь, здесь не требуются особые пояснения, и мы сможем использовать этот код в качестве шаблона в будущих проектах.

 

 

 

DLL

Файлы DLL (Dynamic Link Library, библиотека динамической компоновки) являются основой  программной архитектуры Windows и отличаются от исполняемых файлов фактически только заголовком

Для загрузки операционной системы необходимо запустить файл win com, имеющий размер всего 25 Кбайт. Как легко догадаться, в файл такого размера невозможно поместить код, реализующий всю ту гигантскую работу, которая производится по ходу выполнения любого приложения. Этот файл является загрузчиком ядра операционной системы, физически размещенным в нескольких DLL-файлах. Помимо кода, DLL-файлы могут хранить данные и ресурсы. Например, при изменении значка (ярлыка) пользователю предлагается на выбор набор значков из файла SHELL32. DLL. Библиотека OpenGL физически также размещена в виде двух DLL-файлов: opengl23. dll и glu32. dll. Первый из этих файлов и есть собственно библиотека OpenGL. Назначение его - осуществление взаимодействия с акселератором или программная эмуляция ускорителя за счет центрального процессора. Поддержка ЗD-акселерации осуществляется с помощью полного (устанавливаемого) клиентского драйвера (Installable Client Driver, ICD) и мини-драйвера (Mini-Client Driver, MCD). Библиотека OpenGL реализована по клиент-серверной схеме, т.e. ее одновременно может использовать несколько приложений при единственной копии сервера в памяти или вообще при удаленном расположении сервера (сервер в принципе может располагаться и не на компьютере клиента). Чаще всего DLL представляет собой набор функций и процедур. Как говорится в справке Delphi по DLL, "динамические библиотеки являются идеалом для многоязыковых проектов". Это действительно так: при использовании OpenGL совершенно безразлично, в какой среде созданы сама библиотека и вызывающие ее модули.

 

Раздел 2 “Подключение OpenGL”

2.1. Минимальная программа OpenGL

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

hrc: HGLRC; // ссылка на  контекст воспроизведения

Смысл этой величины мы рассмотрели  в предыдущем разделе. Обработчик события OnCreate формы содержит следующие строки:

SetDCPixelFormat(Canvas. Handle); //задаем формат пиксела

hrc: = wglCreateContext(Canvas. Handle); // создаем контекст воспроизведения

Первая строка - обращение  к описанной в этом же модуле пользовательской процедуре, задающей формат пиксела

procedure SetDCPixelFormat (hdc: HDC);

var

pfd: TPixelFormatDescriptor;

nPixelFormat: Integer;

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

nPixelFormat: = ChoosePixelFormat (hdc, @pfd);

SetPixelFormat (hdc, nPixelFormat, @pfd);

end;

По поводу формата пиксела мы подробнее поговорим в следующем  разделе. Во второй строке обработчика OnCreate задается величина типа HGLRC, т.e. создается контекст воспроизведения. Аргументом функции wglCreateContext является ссылка на контекст устройства, на который будет осуществляться вывод. Сейчас устройством вывода служит окно формы. Для получения этого контекста OpenGL необходима величина типа HDC. Здесь, как и во многих других примерах, мы используем факт, что canvas. Handle и есть ссылка на контекст устройства, связанная с окном формы. Поскольку это первая функция, имеющая непосредственно отношение к OpenGL, то я немного отвлекусь на некоторые общие пояснения. Только начиная с пятой версии Delphi поставляется с системой помощи, удовлетворительно настроенной с точки зрения получения справок по командам OpenGL и функциям API, в предыдущих версиях ее вроде, как и нет. Однако на самом деле такая помощь доступна и в ранних версиях, и самый простой способ ее получения - контекстная подсказка. По командам OpenGL справки мы будем получать точно так же, как и по функциям API, т. e если вам необходима более подробная информация, например, о функции wglcreateContext, то установите курсор на строку с этой функцией и нажмите клавишу <F1>. Функция wgicreateContext физически размещается в файле opengl32 dll, а прототип ее находится в файле windows. pas. В этот файл также помещены прототипы всех функций и процедур, имеющих отношение к реализации OpenGL под Windows, a прототипы собственно команд OpenGL расположены в файле opengl pas функции и процедуры, имеющие отношение только к Windows-версии OpenGL, обычно имеют приставку wgl, как, например, wglcreateContext, но могут и не иметь такой приставки, как, например, SwapBuffers. Собственно команды OpenGL имеют приставки gl или glu в зависимости от размещения в библиотеках opengl32. dll и glu32. dll, соответственно. Итак, контекст воспроизведения создан, и теперь можно осуществлять вывод командами OpenGL. Обработка события onpaint выглядит следующим образом:

wglMakeCurrent (Canvas. Handle, hrc); // установить  контекст

glClearColor (0. 5, 0. 5, 0. 75, 1. 0); // цвет фона

glClear (GL_COLOR_BUFFER_BIT); // очистка буфера цвета

wglMakeCurrent (0, 0); // освободить контекст

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

Замечание 
          Согласно справке, для освобождения контекста воспроизведения оба параметра должны быть установлены в NULL, но хотя компилятор и пропустит такие значения, во время выполнения получим ошибку "Invalid variant type conversion", так что будем всегда для освобождения контекста задавать эти значения нулевыми. Обработка события onDestroy формы состоит из одной строки:

wglDeleteContext (hrc);

Тем самым мы по завершении работы приложения удаляем контекст воспроизведения, освобождая память.

Замечание 
          Очень важно запомнить, что процедуры и функции, имена которых начинаются на gl или glu, т.e. команды OpenGL, имеют какой-либо результат только при установленном контексте воспроизведения

Вернемся к команде glclearcolor, определяющей цвет фона. У нее четыре аргумента, вещественные числа, первые три из которых  задают долю красного, зеленого и синего в результирующем цвете. Четвертый аргумент я задал его значение равным единице. Можете варьировать это значение произвольно, в данном примере это никак не скажется, так что пока можете просто не обращать внимания на этот аргумент. Согласно справке, все четыре аргумента функции glclearColor имеют тип GLclampf, соответствующий вещественным числам в пределах от нуля до единицы. О типах OpenGL подробнее если вы используете Delphi версии три или четыре, вы, возможно, столкнетесь с одной небольшой проблемой. Если запускать проекты, использующие OpenGL, под управлением среды Delphi, программа может случайным образом аварийно завершаться. Оборот "случайным образом" здесь я употребил постольку, поскольку один и тот же проект может привести к аварийному завершению, а может и работать вполне успешно. Я сталкивался с этой проблемой на компьютерах с различной конфигурацией и с различными версиями операционной системы, и, по-видимому, она связана с некорректным взаимодействием среды Delphi c драйверами. Если подобная проблема возникла и у вас, я рекомендую просто не запускать под управлением среды проекты, использующие OpenGL, a запускать собственно откомпилированные модули. В пятой версии Delphi такая ситуация не возникала, так что, по-видимому, этот недостаток разработчиками выявлен и устранен.

Формат пикселя

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

Информация о работе Подключение библиотеки OpenGL в Delphi