Автор: Пользователь скрыл имя, 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 “Windows-приложения“__________
1.1. Событие, сообщение, ссылка
___________________________
1.2. Перехват сообщений_____________________
2. Раздел 2 “Подключение OpenGL”_____________________17
2.1. Минимальная программа OpenGL_____________________
2.2. Вывод на компоненты Delphi средствами OpenGL _______27стр.
Введение
Эта работа посвящена компьютерной графике, а именно тому, как использовать OpenGL в Delphi. OpenGL - это стандартная библиотека для всех 32-разрядных операционных систем, в том числе и для операционной системы Windows. OpenGL - не отдельная программа, а часть операционной системы. Это означает, что откомпилированное приложение, использующее OpenGL, не нуждается ни в каких дополнительных программах и модулях, кроме стандартных, содержащихся на любом компьютере с установленной операционной системой Windows 95 версии OSR2 и выше. Вообще говоря, в этой курсовой работе идет речь о программировании приложений, использующих графический акселератор, однако все приводимые программы будут работать и на компьютере, не оснащенном ускорителем. Для программистов, использующих язык С, существует множество источников, из которых можно почерпнуть сведения о том, как использовать библиотеку OpenGL, для программистов же, работающих с Delphi, таких источников крайне мало. Данная работа призвана восполнить этот недостаток информации. В состав стандартной поставки Delphi (начиная с третьей версии) входит заголовочный файл, позволяющий строить приложения с использованием OpenGL, a также справочный файл по командам этой библиотеки. Однако инсталляция Delphi не снабжается ни одним примером по использованию OpenGL, a из файла справок новичку трудно понять, как это сделать. Поэтому основная цель курсовой работы - помочь программистам, в том числе и опытным, разобраться в этой теме. Многие примеры в работе представляют собой "перевод" свободно распространяемых программ, изначально написанных на С.
Хотелось бы отметить следующие особенности курсовой работы:
1. Отсутствует описание математического аппарата компьютерной графики.
Мне не стоило бы большого
труда в очередной раз
2. Эта курсовая
работа не заменит
3. Работа рассчитана на новичка в области машинной графики, но не новичка в программировании на Delphi. При изложении материала подразумевается, что читатель имеет навыки работы в Delphi, и чем увереннее он чувствует себя здесь, тем больше пользы сможет извлечь из этой работы. Heкоторые разделы, например функции API, могут показаться поначалу трудными. Однако в подавляющей части примеров особо сложные приемы программирования не используются, и они достаточно легко поддаются освоению.
Раздел 1 “Windows-приложения“
Здесь дается представление о том, как в действительности работает Windows-приложение. Для понимания действий, требуемых для подключения OpenGL, необходимо иметь представление о важнейших понятиях операционной системы Windows, завуалированных в Delphi и напрямую обычно не используемых программистом. В качестве примера подробно разбирается минимальная программа, использующая OpenGL.
1.1. Событие, сообщение, ссылка
С понятием "событие" знаком каждый программист, использующий Delphi. Термин "сообщение" напрямую в концепции Delphi не используется. Код, написанный в проекте Delphi как обработчик события OnCreate, выполняется при получении приложением сообщения WM_CREATE, сообщению WM_PAINT соответствует событие OnPaint и т.д. Такие события - аналоги сообщений операционной системы - используют мнемонику, сходную с мнемоникой сообщений, т.e. сообщения начинаются с префикса "WM_" (Windows Message), a аналогичные события начинаются с префикса "On". Для того чтобы операционная система могла различать окна для осуществления диалога с ними, все окна при своем создании регистрируются в опе- рационной системе и получают уникальный идентификатор, называемый "ссылка на окно". Тип этой величины в Delphi - HWND (Handle WiNDow). Синонимом термина "ссылка" является дескриптор. Ссылка на окно может использоваться не только операционной системой, но и приложениями для идентификации окна, с которым необходимо производить манипуляции. Попробуем проиллюстрировать смысл ссылки на окно на несложном примере. Откомпилируйте минимальное приложение Delphi и начните новый проект. Форму назовите Form2, разместите на ней кнопку.
Теперь при нажатии кнопки выдается сообщение, открыто ли окно класса, зарегистрированного в операционной системе как 'TForml1', имеющее заголовок 'Form1'. Если одновременно запустить обе наши программы, то при нажатии кнопки будет выдано одно сообщение, а если окно с заголовком 'Form1' закрыть, то другое. Здесь мы используем функцию FindWindow, возвращающую величину типа HWND - ссылку на найденное окно либо ноль, если такое окно не найдено. Аргументы функции - класс окна и его заголовок. Если заголовок искомого окна безразличен, вторым аргументом нужно задать nil. Итак, ссылка на окно однозначно определяет окно. Свойство Handle формы и есть эта ссылка, а тип THandle в точности соответствует типу HWND, так что в предыдущем примере переменную Н можно описать как переменную типа THandle. Рассмотрим подробнее некоторые выводы. Класс окна минимального приложения, созданного в Delphi, имеет значение 'TForm1', что полностью соответствует названию класса формы в проекте. Следовательно, то, как мы называем формы в проектах Delphi, имеет значение не только в период проектирования приложения, но и во время его работы. Начните новый проект, назовите форму каким-нибудь очень длинным именем и откомпилируйте проект. Сравните размер откомпилированного модуля с размером самого первого проекта, и убедитесь, что он увеличился - вырос только за счет длинного имени класса. Также очень важно уяснить, что, если вы собираетесь распространять какие-либо приложения, необходимо взять за правило называть формы отлично от значения, задаваемого Delphi по умолчанию. Лучше, если эти названия будут связаны по смыслу с работой вашего приложения. Так, например, головную форму в примерах этой работы я буду называть, как правило, frmGL. Имея ссылку на окно, операционная система общается с ним путем посылки сообщений - сигналов о том, что произошло какое-либо событие, имеющее отношение именно к данному окну. Если окно имеет намерение отреагировать на событие, операционная система совместно с окном осуществляет эту реакцию.Окно может и, не имея фокус, получать сообщения и реагировать на них.
При движении курсора мыши в заголовке формы выводятся его координаты. Запустите два экземпляра программы и обратите внимание, что окно, не имеющее фокус, т. е. неактивное, тоже реагирует на перемещение указателя по своей поверхности и выводит в заголовке текущие координаты курсора в своей системе координат. Имея ссылку на окно, приложение может производить с ним любые (почти) действия путем посылки ему сообщений. Если имеется окно класса 'TForm1' с заголовком 'Form1', наше приложение посылает ему сообщение WM_CLOSE - пытается закрыть окно. Для посылки сообщения используем функцию операционной системы (функцию API) SendMessage. Функция postMessage имеет сходное назначение, но отличается тем, что не дожидается, пока посланное сообщение будет отработано. У этих функций четыре аргумента - ссылка на окно, которому посылаем сообщение, константа, соответствующая посылаемому сообщению, и два параметра сообщения, смысл которых определяется в каждом конкретном сообщении по-своему. Параметры сообщения называются wParam и lParam. При обработке сообщения WM_CLOSE эти значения никак не используются, поэтому здесь их можно задавать произвольно. Заметим, что одновременно могут быть зарегистрированы несколько окон класса 'TForm1', и необходимо закрыть их все. Пока наше приложение закрывает окна поодиночке при каждом нажатии на кнопку. Автоматизировать процесс можно разными способами, простейший из них используется в проекте подкаталога Ex04 и заключается в том, что вызов Findwindow заключен в цикл, работающий до тех пор, пока значение переменной H не станет равным нулю.
В заключение раздела, необходимо сказать, что ссылки, в зависимости от версии Delphi, соответствуют типам Integer или LongWord и описываются в модуле windows. pas.
Почему приложения Delphi имеют большой размер
Этот вопрос часто задают начинающие программисты при сравнении приложений, созданных в различных средах программирования. Действительно, минимальное приложение, созданное в различных версиях Delphi, может достигать от 170 до 290 Кбайт. Это очень большая цифра для операционной среды Windows, в компиляторах C++ она составляет порядка 40 Кбайт. Конечно, это не катастрофическая проблема, когда емкости накопителей измеряются гигабайтами, и средний пользователь, как правило, не обращает внимания на размер файла. Неудобства возникают, например, при распространении приложений по сети. Использование пакетов значительно снимает остроту проблемы для масштабных проектов, но суммарный вес приложения и используемых пакетов все равно значителен. Краткий ответ на вопрос, поставленный в заголовке раздела, состоит в том, что большой размер откомпилированных приложений является платой за невероятное удобство проектирования, предоставляемое Delphi. Архитектура среды программирования, RTTI, компонентный подход - все это превращает Delphi в поразительно мощный инструмент. С помощью Delphi легко написать приложения, в которых, например, динамически создаются интерфейсные элементы любого типа (класса).
Программирование на Delphi без VCL
После того как мы прикоснулись к основополагающим терминам и понятиям операционной системы Windows "сообщение" и "ссылка на окно", мы сможем опуститься ниже уровня объектно-ориентированного программирования, VCL и RAD-технологий. Требуется это по четырем причинам. Во-первых, приложения, активно использующие графику, чаще всего не нуждаются и не используют богатство библиотеки классов Delphi. Таким приложениям, как правило, достаточно окна в качестве холста, таймера и обработчиков мыши и клавиатуры. Во-вторых, при программировании, основанном только на использовании функций API, получаются миниатюрные приложения. Откомпилированный модуль не отягощается кодом описания компонентов и кодом, связанным с концепциями ООП. В-третьих, для понимания приемов, используемых для увеличения скорости воспроизведения, нужно иметь представление о подлинном устройстве Windows-программы. Например, чтобы команды перерисовки окна выполнялись быстрее, мы будем избегать использования методов Refresh и paint формы. В-четвертых, это необходимо для понимания действий, производимых для подключения OpenGL. Эта библиотека создавалась в эпоху становления ООП, и ее пока не коснулись последующие нововведения в технологии программирования.
Вывод с использованием функций GDI
В первом разделе мы рассмотрели, как, получив ссылку на чужое окно, можно производить с ним некоторые действия, например, закрыть его. Точно так же, если необходимо нарисовать что-либо на поверхности чужого окна, первым делом нужно получить ссылку на него. Для начала попробуем рисовать на поверхности родного окна. Разместите еще одну кнопку, обработку щелчка которой приведите к следующему виду:
procedure TForma2.
Button2Click(Sender: TObject);
var dc: HDC; // ссылка на контекст устройства
begin dc: = GetDC (Handle); // задаем значение ссылки
Rectangle (dc, 10, 10, 110, 110); // рисуем прямоугольник
ReleaseDC (Handle, dc); // освобождение ссылки
DeleteDC (dc); // удаление ссьшки, освобождение памяти end;
Запустите приложение. После щелчка на добавленной кнопке на поверхности окна рисуется квадрат. Для рисования в этом примере используем низкоуровневые функции вывода Windows, так называемые функции GDI (Graphic Device Interface, интерфейс графического устройства). Эти функции требуют в качестве одного из своих аргументов ссылку на контекст устройства. Тип такой величины - hdc (Handle Device Context, ссылка на контекст устройства), значение ее можно получить вызовом функции API GetDC с аргументом-ссылкой на устройство вывода. В нашем примере в качестве аргумента указана ссылка на окно. После получения ссылки на контекст устройства обращаемся собственно к функции, строящей прямоугольник. Первым аргументом этой функции является ссылка на контекст устройства. После использования ссылки ее необходимо освободить, а в конце работы приложения - удалить для освобождения памяти.
1.2. Перехват сообщений
Большинство событий формы и
компонентов являются аналогами
соответствующих сообщений
Замечание
В угоду
программистам, до сих пор использующим
третью версию Delphi для получения сравнительно
небольших по объему исполняемых модулей,
все примеры данной книги я разрабатывал
именно в этой версии, но все они прекрасно
компилируются и в более старших версиях
У программистов всегда будет возникать
потребность обрабатывать сообщения,
не имеющие аналогов в списке событий,
либо самостоятельно перехватывать сообщения,
для которых есть аналоги среди событий
формы и компонентов. Как увидим ниже,
сделать это несложно. Например, мы программируем
без VCL. Задача состоит в том, чтобы при
двойном щелчке левой кнопкой мыши выводились
текущие координаты указателя. Прежде
всего, обратите внимание, что в стиль
окна добавилась константа cs_Dblclks, чтобы
окно могло реагировать на двойной щелчок,
а оконная функция дополнилась обработкой
сообщения wm_LButtonDblclk, в которой выводятся
координаты курсора. Теперь создадим обработчик
этого же сообщения в проекте Delphi обычного
типа. Описание класса формы я дополнил
разделом protected, в который поместил forward-описание
соответствующей процедуры: