Построение 3D модели "Компьютер" (OpenGL)

Тип работы:
Курсовая
Предмет:
Программирование


Узнать стоимость

Детальная информация о работе

Выдержка из работы

СОДЕРЖАНИЕ

  • Введение 2
  • 1. Программирование с использованием библиотеки OpenGL 4
    • 1.1 Назначение OpenGL 4
    • 1.2 Архитектура OpenGL 5
    • 1.3 Преимущества OpenGL 6
    • 1.4 Базовые возможности библиотеки 7
    • 1.5 Преобразование координат 8
    • 1.6 Видовое преобразование 9
    • 1.7 Проекции 10
    • 1.8 Трехмерные объекты GLU 11
    • 1.9 Использование таймера 12
  • 2. Разработка приложения для построения динамического изображения трехмерной модели объекта «Компьютер» 15
    • 2.1 Разработка процедуры визуализации трехмерной сцены 15
    • 2.2 Разработка интерфейса пользователя 17
    • 2.3 Разработка подсистемы управления событиями 18
  • 3. Информационное и программное обеспечение 20
    • 3.1 Общие сведения о программе 20
    • 3.2 Функциональное назначение 20
    • 3.3 Логическая структура и функциональная декомпозиция проекта 21
    • 3.4 Требования к техническому обеспечению программы 23
    • 3.5 Руководство пользователя 23
  • 4. Заключение и выводы 25
  • Список литературы 26
  • Приложение, А 27
  • Приложение Б 36
  • Приложение В 37
  • Приложение Г 38
  • ВВЕДЕНИЕ
  • Сейчас трёхмерные изображения можно увидеть везде, начиная от компьютерных игр и заканчивая системами моделирования в реальном времени. Раньше, когда трёхмерная графика существовала только на суперкомпьютерах, не существовало единого стандарта в области графики. Все программы писались с «нуля» или с использованием накопленного опыта, но в каждой программе реализовывались свои методы для отображения графической информации. С приходом мощных процессоров и графических ускорителей трёхмерная графика стала реальностью для персональных компьютеров. Но в тоже время производители программного обеспечения столкнулись с серьёзной проблемой — это отсутствие каких-либо стандартов, которые позволяли писать программы, независимые от оборудования и операционной системы. Одним из первых таких стандартов, существующий и по сей день является OpenGL.
  • OpenGL — это графический стандарт в области компьютерной графики. На данный момент он является одним из самых популярных графических стандартов во всём мире. Ещё в 1982 г. в Стенфордском университете была разработана концепция графической машины, на основе которой фирма Silicon Graphics в своей рабочей станции Silicon IRIS реализовала конвейер рендеринга. Таким образом была разработана графическая библиотека IRIS GL. На основе библиотеки IRIS GL, в 1992 году был разработан и утверждён графический стандарт OpenGL. Разработчики OpenGL — это крупнейшие фирмы разработчики как оборудования так и программного обеспечения: Silicon Graphics, Inc., Microsoft, IBM Corporation, Sun Microsystems, Inc., Digital Equipment Corporation (DEC), Evans & Sutherland, Hewlett-Packard Corporation, Intel Corporation и Intergraph Corporation.
  • OpenGL переводится как Открытая Графическая Библиотека (Open Graphics Library), это означает, что OpenGL — это открытый и мобильный стандарт. Программы, написанные с помощью OpenGL можно переносить практически на любые платформы, получая при этом одинаковый результат, будь это графическая станция или суперкомпьютер. OpenGL освобождает программиста от написания программ для конкретного оборудования. Если устройство поддерживает какую-то функцию, то эта функция выполняется аппаратно, если нет, то библиотека выполняет её программно.
  • Что же представляет из себя OpenGL? С точки зрения программиста OpenGL — это программный интерфейс для графических устройств, таких как графические ускорители. Он включает в себя около 150 различных команд, с помощью которых программист может определять различные объекты и производить рендеринг. Говоря более простым языком, вы определяете объекты, задаёте их местоположение в трёхмерном пространстве, определяете другие параметры (поворот, масштаб, …), задаёте свойства объектов (цвет, текстура, материал, …), положение наблюдателя, а библиотека OpenGL позаботится о том чтобы отобразить всё это на экране. Поэтому можно сказать, что библиотека OpenGL является только воспроизводящей (Rendering), и занимается только отображением 3D обьектов, она не работает с устройствами ввода (клавиатуры, мыши). Также она не поддерживает менеджер окон.
  • OpenGL имеет хорошо продуманную внутреннюю структуру и довольно простой процедурный интерфейс. Несмотря на это с помощью OpenGL можно создавать сложные и мощные программные комплексы, затрачивая при этом минимальное время по сравнению с другими графическими библиотеками.
  • В некоторых библиотеках OpenGL (например под X Windows) имеется возможность изображать результат не только на локальной машине, но также и по сети. Приложение, которое вырабатывает команды OpenGL называется клиентом, а приложение, которое получает эти команды и отображает результат — сервером. Таким образом, можно строить очень мощные воспроизводящие комплексы на основе нескольких рабочих станций или серверов, соединённых сетью.
  • 1. ПРОГРАММИРОВАНИЕ С ИСПОЛЬЗОВАНИЕМ БИБЛИОТЕКИ OPENGL

1.1 Назначение OpenGL

программирование opengl трехмерный компьютер пользователь

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

Для любого протокола, будь то сетевой протокол или язык описания сцен, важным является вопрос уровня абстракции — то есть того, на каком уровне работает данная система или протокол, что является входными данными и что выходными, какие компоненты будут взаимодействовать в качестве поставщиков и приемников данных. Говоря попросту, нужно определиться по вопросу «что мы делаем и чего не делаем».

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

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

1.2 Архитектура OpenGL

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

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

Растрирование в качестве результата создает список объектов (точек, отрезков и треугольников) в двумерной плоскости. Над отдельными объектами может быть выполнена операция раскрашивания, градиентной заливки или применения мэппинга, то есть наложения фактуры.

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

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

1.3 Преимущества OpenGL

При реализации авторы ставили себе пять ориентиров, важных с точки зрения получаемых результатов.

Производительность. С самого начала в OpenGL была заложена «крайне желательная» возможность отрисовки динамических сцен. Для получения нужных результатов в систему введено множество параметров, или, как говорят, режимов рисования. Если некоторый режим или комбинация режимов на данном оборудовании не в состоянии обеспечить интерактивного взаимодействия и необходимой частоты обновления сцены, то пользователь или сама программа должны быть в состоянии отключать так много дополнительных функций, сколько нужно для получения «живой» картинки.

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

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

Интероперабельность. В сетевом окружении важно передавать данные между разными платформами. Поэтому OpenGL заранее ориентирован на работу в режиме клиент-сервер, даже если и клиент и сервер расположены на одном компьютере.

Расширяемость. Поскольку OpenGL рассчитан на максимальное соответствие возможностям аппаратуры (а аппаратура, как известно, имеет тенденцию развиваться), то в OpenGL также встроены механизмы включения новых функций. С другой стороны, нестабильный интерфейс затрудняет жизнь разработчиков, поэтому новые возможности накапливаются достаточное время и применяются согласованно с выходом новой версии.

1.4 Базовые возможности библиотеки

К базовым возможностям библиотеки можно отнести следующие:

1. Создание геометрических и растровых примитивов. На их основе строятся все объекты. Из геометрических примитивов библиотека предоставляет: точки, линии, полигоны. Из растровых: битовый массив (bitmap) и образ (image).

2. Использование B-сплайнов для рисования кривых по опорным точкам.

3. Видовые и модельные преобразования, позволяющие вращать объекты, располагать их в пространстве, изменять форму, а также изменять положение камеры, из которой ведется наблюдение.

4. Работа с цветом. OpenGL предоставляет возможности работы с цветом в режиме RGBA или используя индексный режим, где цвет выбирается из палитры.

5. Удаление невидимых линий и поверхностей. Z-буферизация.

6. Двойная буферизация, позволяющая устранить мерцание при мультипликации (изображение каждого кадра сначала рисуется во втором буфере, а потом, когда кадр полностью нарисован, весь буфер отображается на экран).

7. Наложение текстуры.

8. Сглаживание (позволяет скрыть ступенчатость).

9. Освещение (задавать источники освещения, их расположение, интенсивность).

10. Атмосферные эффекты, такие как дым, туман.

11. Прозрачность объектов.

12. Использование списков изображений.

Для упрощения работы с OpenGL существуют вспомогательные библиотеки: GLU (в библиотеку вошли функции для работы со сплайнами, реализованы дополнительные операции над матрицами и дополнительные виды проекций), GLUT (предоставляет функции для работы с окнами, клавиатурой и мышкой), GLAUX (во многом схожа с библиотекой GLUT, но немного отстает по своим возможностям).

1.5 Преобразование координат

В OpenGL каждая вершина задается четырьмя координатами, что связано с использованием однородных координат. В однородных координатах положение точки P (x, y, z) записывается как P (W Ч x, WЧ y, WЧz, W).

Для преобразования координат используется матричное представление. В OpenGL существует три типа матриц — видовая, проекций и текстуры. Все они имеют размер 4 Ч4. Для того, чтобы с какой-либо матрицей можно было работать ее нужно сделать текущей, для чего предусмотрена команда: void glMatrixMode (GLenum mode). Параметр mode определяет, с каким набором матриц будут выполняться последующие операции, и может принимать одно из следующих значений: GL_MODELVIEW (последовательность операций над матрицами применяется к видовой матрице), GL_PROJECTION (последовательность операций над матрицами применяется к матрице проекций), GL_TEXTURE (последовательность операций над матрицами применяется к матрице текстуры).

После того как установлена текущая матрица, необходимо определить ее значения. В данном случае полезной может оказаться функция void glLoadIdentity (), которая заменяет текущую матрицу на единичную.

1.6 Видовое преобразование

Для формирования матрицы преобразований можно воспользоваться готовыми командами:

1. Вращение: void glRotate[f, d](GLtype angle, GLtype x, GLtype y, GLtype z). Эта команда рассчитывает матрицу для выполнения вращения вектора против часовой стрелки на угол, определяемый параметром angle, осуществляемого относительно точки (x, y, z). После выполнения этой команды все объекты изображаются повернутыми.

2. Параллельный перенос: void glTranslate[f, d](GLtype x, GLtype y, GLtype z). При помощи этой команды осуществляется перенос объекта на расстояние x по оси Х, на расстояние y по оси Y и на расстояние z по оси Z.

3. Масштабирование: void glScale[f, d](GLtype x, GLtype y, GLtype z). Осуществляет частичное масштабирование вдоль каждой из координатных осей на значения, определяемые соответствующими параметрами.

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

1. 7 Проекции

В OpenGL поддерживаются такие виды проекций как ортографическая и перспективная. Ортографическая (параллельная) проекция представляет пространство параллелепипедом и размер изображаемых фигур не зависит от расстояния, на котором они находятся. Объем отсечения для ортографической проекции представлен на рисунке 1.

Рисунок 1 — Объем отсечения ортографической проекции

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

Рисунок 2 — Объем отсечения перспективной проекции

1. 8 Трехмерные объекты GLU

Создание glu объекта сводится к следующим этапам:

1. Создание объекта типа GLUquadricObj командой gluNewQuadric.

2. Установка свойств созданного объекта командой gluQuadricDrawStyle.

3. Рисование объекта.

4. Удаление объекта командой gluDeleteQuadric.

При программировании с использованием glu доступны следующие команды: void gluQuadricDrawStyle (GLUquadric * qObject, GLenum drawStyle), где qObject — указатель на quadric объект; drawStyle — стиль вывода трехмерного объекта. Возможные значения параметра drawStyle: GLU_FILL — сплошной объект, GLU_LINE — каркасный объект, GLU_POINT — рисуются только точки.

Рассмотрим команды:

1) рисования цилиндра:

void gluCylinder (GLUquadric * qobj, GLdouble baseRadius, GLdouble topRadius, GLdouble height, GLint slices, GLint stacks), где qObject — указатель на quadric объект; baseRadius — радиус первого основания; topRadius — радиус второго основания; height — высота; slices -количество слоев; stacks — количество секторов;

2) рисования диска:

void gluDisk (GLUquadric * qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops), где qObject — указатель на quadric объект; innerRadius — внутренний радиус; s outerRadiu — внешний радиус; slices — количество слоев; loops — количество огибающих;

3) рисования дискового сектора:

void gluPartialDisk (GLUquadric * qobj, GLdouble innerRadius, GLdouble outerRadius, GLint slices, GLint loops, GLdouble startAngle, GLdouble endAngle), где startAngle — начальный угол; endAngle — конечный угол сектора;

4) рисования сферы:

void gluSphere (GLUquadric * qobj, GLdouble radius, GLint slices, GLint loops).

1.9 Использование таймера

Работа виртуального таймера основана на передаче сообщений. Приложение может заказать для любого своего окна несколько таймеров, которые будут периодически посылать в функцию окна сообщение с кодом WM_TIMER.

Есть и другой способ, также основанный на передаче сообщений. При использовании этого способа сообщения WM_TIMER посылаются не функции окна, а специальной функции, описанной с ключевым словом _export. Эта функция напоминает функцию окна и, так же как и функция окна, вызывается не из приложения, а из Windows. Функции, которые вызываются из Windows, имеют специальный пролог и эпилог и называются функциями обратного вызова (callback function). Функция окна и функция, специально предназначенная для обработки сообщений таймера, являются примерами функций обратного вызова.

Для создания виртуального таймера приложение должно использовать функцию SetTimer:

UINT WINAPI SetTimer (HWND hwnd, UINT idTimer, UINT uTimeout, TIMERPROC tmprc);

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

Второй параметр (idTimer) определяет идентификатор таймера (он не должен быть равен нулю). Идентификатор используется только в том случае, если первый параметр функции SetTimer содержит идентификатор окна. Так как для одного окна можно создать несколько таймеров, для того чтобы различать сообщения, приходящие от разных таймеров, приложение при создании должно снабдить каждый таймер собственным идентификатором.

Если первый параметр указан как NULL, второй параметр функции игнорируется, так как для таймера задана специальная функция, получающая сообщения только от этого таймера.

Третий параметр (uTimeout) определяет период следования сообщений от таймера в миллисекундах. Физический таймер тикает приблизительно 18,21 раза в секунду (точное значение составляет 1000/54,925). Поэтому, даже если указать, что таймер должен тикать каждую миллисекунду, сообщения будут приходить с интервалом не менее 55 миллисекунд.

Последний параметр (tmprc) определяет адрес функции, которая будет получать сообщения WM_TIMER (мы будем называть эту функцию функцией таймера). Этот параметр необходимо обязательно указать, если первый параметр функции SetTimer равен NULL.

Если приложение больше не нуждается в услугах таймера, оно должно уничтожить таймер, вызвав функцию KillTimer:

BOOL WINAPI KillTimer (HWND hwnd, UINT idTimer);

Первый параметр функции (hwnd) определяет идентификатор окна, указанный при создании таймера функцией SetTimer.

Второй параметр (idTimer) — идентификатор уничтожаемого таймера. Это должен быть либо тот идентификатор, который был указан при создании таймера (если таймер создавался для окна), либо значение, полученное при создании таймера от функции SetTimer (для таймера, имеющего собственную функцию обработки сообщений).

Функция KillTimer возвращает значение TRUE при успешном уничтожении таймера или FALSE, если она не смогла найти таймер с указанным идентификатором.

Рассмотрим способ работы с таймером — подключение таймера к окну. В этом случае функция окна, к которому подключен таймер, будет получать сообщения от таймера с кодом WM_TIMER.

Этот способ самый простой. Вначале надо вызвать функцию SetTimer, указав ей в качестве параметров идентификатор окна, идентификатор таймера и период, с которым от таймера должны приходить сообщения:

#define FIRST_TIMER 1 int nTimerID; nTimerID = SetTimer (hwnd, FIRST_TIMER, 1000, NULL);

В данном примере создается таймер с идентификатором FIRST_TIMER, который будет посылать сообщения примерно раз в секунду.

Для уничтожения таймера, созданного этим способом, следует вызвать функцию KillTimer, указав параметры следующим образом:

KillTimer (hwnd, FIRST_TIMER);

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

KillTimer (hwnd, FIRST_TIMER); nTimerID = SetTimer (hwnd, FIRST_TIMER, 100, NULL);

2. РАЗРАБОТКА ПРИЛОЖЕНИЯ ДЛЯ ПОСТРОЕНИЯ ДИНАМИЧЕСКОГО ИЗОБРАЖЕНИЯ ТРЕХМЕРНОЙ МОДЕЛИ ОБЪЕКТА «КОМПЬЮТЕР».

2.1 Разработка процедуры визуализации трехмерной сцены

Прорисовка в рабочей области начинается с метода void CLab1View: :OnDraw (CDC* pDC), в котором вызывается функция usr_RenderScene (). Она отвечает за прорисовку функциональных частей и за некоторые важные расчёты, которые связаны с расположением некоторых отдельных деталей. Модель состоит из геометрических примитивов, таких как цилиндр, параллелепипед, дисковой сектор.

Рисование 3D объекта начинается с установления формата пикселей и области вывода в методах BOOL CLab1View: :usr_setuppixelformat () и void CLab1View: :usr_Resize (int x, int y, int width, int heidht) соответственно. Рассмотрим подробнее метод usr_RenderScene (), код которого представлен в приложении Б. В этом методе начинается прорисовка объекта. Модель рисуется с верхней ее части, а именно рисуем монитор компьютера — параллелепипед со сторонами 0,7, 0,4, 1,1 — auxSolidBox ((GLfloat)0. 7,0. 4,1. 1). Роль подставки монитора выполняет целый ряд отдельных деталей, каждая из которых рисовалась после переноса координат на необходимую величину. Первым создан цилиндр со следующими параметрами — основания 0,25 и 0,25, длина 0,2. Следующий объект — дисковый сектор, нарисован с использованием функции gluDisk (quadric, 0,0. 25,16,1). Далее еще один диск, он имеет те же параметры, что и первый. Эти диски были использованы для закрытия пустот. После прорисовки этих элементов переносим координаты функцией glTranslatef (0. 0,0. 0,-0. 4). Рисуем еще один цилиндр с основаниями по 0. 15 — gluCylinder (quadric, 0. 15, 0. 15, 0. 3, 100,40), вновь переносим координаты с использованием glTranslatef и рисуем изображение на мониторе компьютера с помощью функции auxSolidBox ((GLfloat)1,0. 03,1. 38).

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

Переносим координаты и рисуем крышку стола, на котором стоит монитор с помощью функции auxSolidBox ((GLfloat)2. 2,2. 6,0. 3). Далее снова функция — glTranslatef (0,0. 5,-0. 1) и помощью auxSolidBox рисуем клавиатуру компьютера, находящуюся на столе перед монитором. Далее были нарисованы остальные части компьютерного стола, с помощью следующих функций: glTranslatef (1. 1,0. 235,2. 7), glTranslatef (-2. 2,0,0), glTranslatef (-1. 6,0,0), glTranslatef (0. 3,0. 25,1). Размеры этих элементов заданы в функциях — auxSolidBox ((GLfloat)0. 09,2. 6,2. 5), auxSolidBox ((GLfloat)0. 09,2. 6,2. 5), auxSolidBox ((GLfloat)0. 07,2. 6,2. 5), auxSolidBox ((GLfloat)0. 6,2. 03,0. 1).

Затем рисуются два параллелепипеда, которые представляют собой системный блок компьютера. Для самого блока выбраны следующие параметры: auxSolidBox ((GLfloat)0. 3,1. 4,1. 5). Для дисковода: auxSolidBox (0. 5,0. 5, 0. 05). Дисковод анимирован, при нажатии управляющей кнопки он выдвигается и задвигается. Это реализовано с помощью функции — glTranslatef (1. 54, l, 1. 5), l — переменная, которая изменяется со временем.

И, наконец, для придания модели завершенного вида, необходимо дорисовать звуковые колонки, для этого:

— сначала требуется провести смещение системы координат (для отображения в нужном месте);

— рисование цилиндра (задняя часть колонки);

— рисование параллелепипеда (передняя часть);

— рисование дискового сектора (верхняя часть).

Все необходимые операции производятся теми же функциями glTranslatef, auxSolidBox, gluCylinder, gluDisk.

Весь код метода usr_RenderScene () представлен в приложении А.

2.2 Разработка интерфейса пользователя

Для данной программы разработан интерфейс, позволяющий:

— включать и выключать эффект тумана;

— выбирать тип тумана;

— включать и выключать дисковод;

— вращать компьютер;

— задавать скорость и вид движения компьютера;

— выбирать тип и задавать параметры перспективы

— приближать и удалять объект с помощью мышки.

Для добавления данных возможностей было отредактирована панель инструментов приложения, а именно

— добавлена кнопка «Перспектива»;

— добавлена кнопка «Движение».

У всех кнопок имеются всплывающие подсказки, а также подсказки, которые появляются в строке состояния.

В главном меню добавлены пункты:

— «Режим тумана» («View» «Режим тумана») — запуск диалогового окна выбора типа тумана.

— «Выключить туман» («View» «Выключить туман») — устранение эффекта тумана.

— «OnOff» («Move» «OnOff «) — включать и выключать дисковод.

Приложение имеет интуитивно понятный интерфейс, с которым удобно работать.

2.3 Разработка подсистемы управления событиями

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

Таким образом, разработка подсистемы управления событиями занимает особое место в общей системе разработки приложения. К основным событиям, обеспечивающим корректную работу программы, относят:

— WM_DESTROY — освобождение занятых ресурсов;

— WM_SIZE — изменения сцены относительно размеров окна;

— WM_ERASEBKGND — предотвращения мерцания;

— WM_TIMER — используется для создания таймера;

— WM_MOUSEWHEEL — обработка вращения колеса мышки;

— WM_KEYDOWN — обработка нажатия клавиши;

— COMMAND (ID_PERSP, CKarkasView: :OnPersp ()) — обработка события при вызове окна настройки перспективы;

— COMMAND (ID_OPTIONS, CKarkasView: :OnOptions ()) — обработка события при вызове окна настройки типа вращения и скорости движения объекта;

— COMMAND (ID_VIEW1, CKarkasView: :OnView1()) — обработка события выбора типа тумана;

— COMMAND (ID_VIEW_SBROS, CKarkasView: OnVewSbros ()) — обработка события нажатия кнопки «Убрать туман»;

— COMMAND (ID_VIEW_MOVE, CKarkasView: :OnMove ()) — обработка нажатия кнопки «Движение».

3. ИНФОРМАЦИОННОЕ И ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ

3.1 Общие сведения о программе

Программа называется «Трехмерная модель Компьютера». При работе с данной программой у пользователя есть возможность работать с визуальной моделью данного объекта. Вращать ее относительно осей, включать и выключать эффект тумана, а также задавать тип тумана, приближать и удалять с помощью колеса мышки, включать и выключать вращение модели и устанавливать скорость вращения, а также имеется возможность управления дисководом. Программное обеспечение, на котором разработана приложение — Microsoft Visual С++ 6.0 с использованием библиотеки OpenGL.

3.2 Функциональное назначение

Данное приложение обеспечивает следующие возможности:

— изменение положения объекта в пространстве (перемещение относительно осей);

— приближение и удаление объекта;

— включение и выключение эффекта тумана;

— выбор типа тумана;

— изменение проекции;

— управление дисководом;

— включение и выключение вращения сцены;

— установка скорости вращения сцены.

3.3 Логическая структура и функциональная декомпозиция проекта

Инициализация OpenGL происходит в несколько этапов.

1. Выбираем и устанавливаем формат пикселей. В информации о формате пикселей указывается такая информация как глубина цвета, различные флаги поверхности. Вся эта структура представляется в специальной структуре PIXELFORMATDESCRIPTOR. Далее передаем на рассмотрение операционной системе, выбранный формат пикселей. После того, как система просмотрит его, она выберет наиболее совпадающий формат с тем, который поддерживается в контексте устройства. Функцией, осуществляющей такого рода проверку, является ChoosePixelFormat (). После выбора формата пикселей функция SetPixelFormat () устанавливает его в контексте устройства.

2. Создаем контекст вывода для библиотеки OpenGL. Данный контекст создается с помощью функции wglCreateContext (), далее функция wglMakeCurrent () устанавливает текущий контекст. Функция wglGetCurrentDC () необходима для корректного завершения приложения, а wglGetCurrentDC () — для удаления контекста воспроизведения.

Одним из важных методов является usr_ReSize (), который устанавливает перспективу и область вывода.

За отображение сцены отвечает метод usr_RenderScene (), который вызывает в свою очередь функции рисования компьютера.

Функции, вызываемые методом usr_RenderScene () были подробно рассмотрены в разделе «2.1 Разработка процедуры визуализации трехмерной сцены», а важные для логического понимания структуры события программы рассмотрены в разделе «2.3 Разработка подсистемы управления событиями».

Для наглядности приведем таблицу наиболее важных методов — таблица 3.1.

Таблица 3.1 — Основные методы и функции

Метод

Назначение

Назначение параметров

1

PreCreateWindow (CREATESTRUCT& cs)

Инициализация окна

cs — объект структуры CREATESTRUCT.

Производится изменение значений, присвоенных переменным-членам структуры CREATESTRUCT для изменения режима открытия окна и его параметров.

2

usr_bSetupPixelFormat ()

Установка формата пикселей

3

usr_bInitOpenGL ()

Инициализация OpenGL

4

user_DestoryOpenGL ()

Освобождение ресурсов (из-под OpenGL)

5

usr_ReSize (int x, int y, int width, int height)

Корректирует вывод сцены на экран при изменении размера окна

x и y определяют координаты левого нижнего угла вывода, width и height — ширину и высоту области вывода

6

usr_RenderScene ()

Рисует Компьютер целиком

В таблице 3.2 приведены спецификации разработанных классов.

Таблица 3.2 — Спецификации классов

Название

Назначение

СMainframe

Класс главного окна приложения. Используется для управления главным окном

Таблица 3.2 — Спецификации классов (Продолжение)

CKarkasApp

Главный класс приложения. Управляет работой всего приложения. Методы этого класса выполняют инициализацию приложения, обработку цикла сообщений и вызываются при завершении приложения.

CKarkasDoc

Класс документа приложения.

CKarkasView

Класс окна просмотра документа. Служит для отображения в клиентской области класса документа приложения в нашем случае нашей 3D модели.

CAboutDlg

Класс справочной информации о программе

DlgPers

Класс диалогового окна. Служит для настройки и смены перспективы

Mydialog

Класс диалогового окна. Служит для включения и выбора типа режима тумана.

DlgOptions

Класс диалогового окна. Служит для включения различного типа и скорости движения объекта.

3.4 Требования к техническому обеспечению программы

Для успешной эксплуатации программного продукта необходим персональный компьютер со следующими характеристиками: процессор Intel Pentium с тактовой частотой 800 МГц и выше, оперативная память — не менее 64 Мбайт, свободное дисковое пространство — не менее 500 Мбайт, устройство для чтения компакт-дисков, монитор типа Super VGA (число цветов — 256). Программное обеспечение: операционная система WINDOWS 2000/XP и выше.

3.5 Руководство пользователя

Для установки приложения требуется скопировать с установочного диска, прилагаемого к работе файл «Karkas. exe» в любую директорию на жестком диске. Для запуска программы нужно два раза нажать на левую клавишу мыши.

Разработанное приложение имеет интуитивно понятный интерфейс, который схож с другими Windows — приложениями. При запуске программы пользователь 3D модель компьютера, которую он может вращать влево при нажатии клавиши < на дополнительной клавиатуре, вправо при нажатии клавиши >, вверх — клавиша ^ и вниз клавиша — v. Также имеется возможность приближать и удалять модель, это можно сделать, задействовав колесо мыши.

Существует поддержка различных графических эффектов. Для выбора типа и включения тумана пользователи требуется выполнить команду «View» «Режим тумана». При выполнении этой команды перед пользователем откроется диалоговое окно для выбора типа тумана, вид окна приведен в приложении В, рисунок В.3. Для отключения тумана следует выполнить следующую последовательность действий: «View» «Выключить туман».

Приложение имеет поддержку смены перспективы. Можно выбирать из трех видов перспектив: glOrtho, glFrustum, gluPerspective. Для выбора и настройки перспективы следует выполнить команду: «View» «Настройка перспективы» нажать кнопку на панели инструментов. Вид диалогового окна приведен в приложении В.

Не менее интересным для пользователя окажется выбор типа вращения и скорости вращения сцены. Для запуска анимации требуется выполнить команду «View» «Движение» или нажать кнопку на панели инструментов. После указанной последовательности действий модель начнет вращаться выбранным способом. Для отключения движения требуется выполнить ту же самую последовательность действий, что и при включении.

Также в модели имеется дисковод, который может задвигаться и выдвигаться. Для того чтобы его задействовать требуется нажать «Move» «On/Off» или клавишу «O», дисковод выдвинется. Для того чтобы задвинуть его назад требуется еще раз выполнить предыдущую последовательность действий.

4. ЗАКЛЮЧЕНИЕ И ВЫВОДЫ

В ходе разработки данного приложения были получены практические навыки по разработке программ для операционных систем семейства Windows с применением технологий трехмерной графики с использованием библиотеки OpenGL.

Таким образом, можно выделить следующие решенные в рамках данной курсовой работы задачи:

— изучение принципов работы OpenGL в оконной среде Windows;

— получение практических навыков использования средств OpenGL;

— получение навыков программирования динамических трехмерных анимационных сцен;

— получение навыков программирования интерактивных трехмерных приложений.

Также была проведена работа с такими возможностями библиотеки как:

— использование эффекта тумана;

— использование графических примитивов;

— применение освещения;

— применение проекции.

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

СПИСОК ЛИТЕРАТУРЫ

1. Порев В. Н. Компьютерная графика. СПб., BHV, 2002.

2. Херн Бейкер, Компьютерная графика и стандарт OpenGL, 3-е издание.: Пер. с англ. — М.: Издательство дом «Вильямс», 2005. — 1168 с.

3. Шикин А. В., Боресков А. В. Компьютерная графика. Полигональные модели. Москва, ДИАЛОГ-МИФИ, 2001.

4. Тихомиров Ю. Программирование трехмерной графики. СПб, BHV, 1998.

5. OpenGL performance optimization, Siggraph'97 course.

6. Visual Introduction in OpenGL, SIGGRAPH'98.

7. The OpenGL graphics system: a specification (version 1. 1).

8. Программирование GLUT: окна и анимация. Miguel Angel Sepulveda, LinuxFocus.

9. The OpenGL Utility Toolkit (GLUT) Programming Interface, API version 3, specification.

10. Хилл, Ф. OpenGL. Программирование компьютерной графики. Для профессионалов/ Ф. Хилл, — СПб.: «Питер», 2004. — 1088с.

Материалы сайтов:

11. http: //www. helloworld. ru/texts/comp/games/opengl/opengl2/index. html

12. http: //pmg. org. ru/nehe/index. html

ПРИЛОЖЕНИЕ А

ПРОГРАММНЫЙ КОД

Конструктор

CKarkasView: :CKarkasView ()

{

rotates[0]=0;

rotates[1]=0;

rotates[2]=0;

CurDepth=70;

TransX=0;

TransY=0;

FirstTimer=0;

XSceneRot=0;

YSceneRot=0;

scene_rotate_speed=0;

l = 0. 5;

}

Отображение сцены

void CKarkasView: :usr_RenderScene ()

GL_DEPTH_BUFFER_BIT);

glLoadIdentity ();

glTranslatef (0,0,-4);

glTranslatef (TransX, TransY, 0);

glRotatef (XSceneRot, 0,1,0);

glRotatef (YSceneRot, 1,0,0);

glRotatef (rotates[0], 1,0,0);

glRotatef (rotates[1], 0,1,0);

glRotatef (90,1,0,0);

glPopMatrix ();

GLUquadricObj * quadric = gluNewQuadric ();

gluQuadricDrawStyle (quadric, GLU_FILL);

glPushMatrix ();

glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);

glColor3f (0. 8,0. 7,0. 5);

glScalef (3,1,1);

auxSolidBox ((GLfloat)0. 7,0. 4,1. 1);//монитор

glTranslatef (0. 0,0. 0,0. 7);

gluCylinder (quadric, 0. 25, 0. 25, 0. 2, 16,40);

gluDisk (quadric, 0,0. 25,16,1);

glTranslatef (0,0,0. 2);

glRotatef (25. f, 0,0,0);

glColor3f (0,0,0);

gluDisk (quadric, 0,0. 25,16,1);

glTranslatef (0. 0,0. 0,-0. 4);

glRotatef (45. f, 0,0,0);

glColor3f (0,0,0);

gluCylinder (quadric, 0. 15, 0. 15, 0. 3, 100,40);

glColor3f (0. 5,0. 5,0. 5);//стол. крышка

glTranslatef (0,0. 55,0. 8);

auxSolidBox ((GLfloat)2. 2,2. 6,0. 3);

glColor3f (0. 8,0. 7,0. 5);//клавиатура

glTranslatef (0,0. 5,-0. 1);

auxSolidBox ((GLfloat)0. 7,0. 8,0. 3);

glColor3f (0,0,0); //изображение

glTranslatef (0. 0,-0. 73,-1. 5);

auxSolidBox ((GLfloat)1,0. 03,1. 38);

glColor3f (0. 5,0. 5,0. 5);//элементы стола

glTranslatef (1. 1,0. 235,2. 7);

auxSolidBox ((GLfloat)0. 09,2. 6,2. 5);

glColor3f (0. 5,0. 5,0. 5);

glTranslatef (-2. 2,0,0);

auxSolidBox ((GLfloat)0. 09,2. 6,2. 5);

glColor3f (0. 5,0. 5,0. 5);

glTranslatef (1. 6,0,0);

auxSolidBox ((GLfloat)0. 07,2. 6,2. 5);

glColor3f (0. 5,0. 5,0. 5);

glTranslatef (0. 3,0. 25,1);

auxSolidBox ((GLfloat)0. 6,2. 03,0. 1);

glColor3f (0. 8,0. 7,0. 5);//блок

glTranslatef (0,0,-0. 8);

auxSolidBox ((GLfloat)0. 3,1. 4,1. 5);

glScalef (0. 5,1,1);

glColor3f (0. 8,0. 7,0. 5);//1 колонка

glTranslatef (0. 0,-0. 7,-2. 5);

gluCylinder (quadric, 0. 15, 0. 15, 1. 1, 16,40);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0. 0,0. 1,0. 65);

auxSolidBox ((GLfloat)0. 32,0. 1,1. 3);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0,-0. 1,-0. 6);

gluDisk (quadric, 0,0. 14,16,1);

glColor3f (0,0,0);

glTranslatef (0,0. 15,0. 5);

auxSolidBox ((GLfloat)0. 28,0. 03,1);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0. 0,0. 01,0. 48);

auxSolidBox ((GLfloat)0. 3,0. 03,0. 1);

glColor3f (0. 8,0. 7,0. 5);//2 колонка

glTranslatef (-3. 3,-0. 5,-1);

gluCylinder (quadric, 0. 15, 0. 15, 1. 1, 16,40);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0. 0,0. 1,0. 65);

auxSolidBox ((GLfloat)0. 32,0. 1,1. 3);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0,-0. 1,-0. 6);

gluDisk (quadric, 0,0. 14,16,1);

glColor3f (0,0,0);

glTranslatef (0,0. 15,0. 5);

auxSolidBox ((GLfloat)0. 28,0. 03,1);

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (0. 0,0. 01,0. 45);

auxSolidBox ((GLfloat)0. 3,0. 03,0. 1);

glPopMatrix ();

glPushMatrix (); //дисковод

glColor3f (0. 8,0. 7,0. 5);

glTranslatef (1. 54, l, 1. 5);

auxSolidBox (0. 5,0. 5, 0. 05);

glPopMatrix ();

glFinish ();

gluDeleteQuadric (quadric);

SwapBuffers (: :wglGetCurrentDC ());

Установка параметров

void CKarkasView: :usr_PreInit ()

{

glEnable (GL_DEPTH_TEST);

glEnable (GL_COLOR_MATERIAL);

glShadeModel (GL_SMOOTH);

glEnable (GL_LIGHTING);

glEnable (GL_NORMALIZE);

glLightModeli (GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE);

GLfloat light_position[] = { 1. 0, 0. 0, 0. 0, 1.0 }; glLightfv (GL_LIGHT0, GL_POSITION, light_position);

glEnable (GL_LIGHT0);

}

Обработка события вращения колеса мышки

BOOL CKarkasView: :OnMouseWheel (UINT nFlags, short zDelta, CPoint pt)

{

if (zDelta> 0)

CurDepth++;

else CurDepth--;

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective (CurDepth, asp, 1,20);

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

return CView: :OnMouseWheel (nFlags, zDelta, pt);

}

Обработка события нажатия на кнопку «Движение»

void CKarkasView: :OnOptions ()

{

DlgOptions OptObj;

int result = OptObj. DoModal ();

if (result==IDOK)

{

if ((OptObj. m_rotate==true)/*&&(OptObj. m_rotate≠0)*/) //группа вращения сцены активна

{

if (OptObj. m_speed≠0)

scene_rotate_speed=OptObj. m_speed;

else scene_rotate_speed=1;

if (OptObj. m_XRG==true) //вращение по Х (вокруг вертикальной оси) активно

{

if (OptObj. m_XGroup==1) XSceneRot=-1;

else XSceneRot=1;

}

else XSceneRot=0;

if (OptObj. m_YRG==true) //вращение по Y (вокруг горизонтальной оси) активно

{

if (OptObj. m_YGroup==1) YSceneRot=-1;

else YSceneRot=1;

}

else YSceneRot=0;

if (FirstTimer==0) //включаем таймер

{

FirstTimer=1;

SetTimer (1,scene_rotate_speed, NULL);

}

else //ставим таймеру новую скорость

{

KillTimer (1);

SetTimer (1,scene_rotate_speed, NULL);

}

}

else //вращение не активно

{

if (FirstTimer==1)

{

KillTimer (1);

FirstTimer=0;

}

XSceneRot=0;

YSceneRot=0;

}

}

}

Обработка события установки перспективы

void CKarkasView: :OnPersp ()

{

// TODO: Add your command handler code here

DlgPers object;

int result = object. DoModal ();

int array[3]={0,0,0};

if (result==IDOK)

{

switch (object. checked_p)

{

case 1:

{

glMatrixMode (GL_PROJECTION);

glLoadIdentity (); glOrtho (object. m1, object. m2, object. m3, object. m4, object. m5, object. m6;

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

AfxMessageBox («Changed to glOrtho»);

break;

}

case 2:

{

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

glFrustum (object. m1, object. m2, object. m3, object. m4, object. m5, object. _6);

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

AfxMessageBox («Changed to glFrustum»);

break;

}case 3:

{

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective (object. m1, object. m2, object. m3, object. m4);

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

AfxMessageBox («Changed to gluPerspective»);

break;

}

case 4:

{

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluLookAt (object. m1, object. m2, object. m3, object. m4, object. m5, object. m6, object. m7, object. m8, object. m9);

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

AfxMessageBox («Changed to gluLookAt»);

break;

}

default:

glMatrixMode (GL_PROJECTION);

glLoadIdentity ();

gluPerspective (CurDepth, asp, 1,20);

glMatrixMode (GL_MODELVIEW);

CKarkasView: :usr_RenderScene ();

AfxMessageBox («Mode not selected — set to default»);

}

}

elseAfxMessageBox («Canceled»);

}

ПРИЛОЖЕНИЕ Б

ДИАГРАММА КЛАССОВ

Рисунок Б.1 — Диаграмма классов

ПРИЛОЖЕНИЕ В

АЛГОРИТМ ПОСТОРОЕНИЯ ТРЕХМЕРНОГО ОБЪЕКТА «КОМПЬЮТЕР» СРЕДСТВАМИ OPENGL

Рисунок В.1 — Алгоритм построения объекта «Компьютер»

ПРИЛОЖЕНИЕ Г

ТРЕХМЕРНАЯ МОДЕЛЬ ОБЪЕКТА «КОМПЬЮТЕР»

Рисунок Г.1 — Трехмерная модель объекта «Компьютер»

Рисунок Г.2 — Окно настройки перспективы

Рисунок Г.3 — Окно настройки тумана

ПоказатьСвернуть
Заполнить форму текущей работой