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

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

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






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

1. Создайте новое приложение в Visual C++.

2. Добавьте для сборки проекта библиотеки OpenGL. Для этого:

· в меню Project/setting, выберите закладку LINK;

· в строке "Object/Library Modules" добавьте строку "OpenGL32.lib GLu32.lib GLaux.lib"

· для завершения щелкните левой клавишей мыши по кнопке OK.

3. Введите в текст кода следующие строки (они сообщают компилятору какие библиотечные файлы следует использовать):

#include <windows.h> // Заголовочный файл для Windows#include <gl\gl.h> // Заголовочный файл для библиотеки OpenGL32 #include <gl\glu.h> // Заголовочный файл для библиотеки GLu32 #include <gl\glaux.h> // Заголовочный файл для библиотеки GLaux

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

Первые две строки устанавливают контекст воспроизведения (рендеринга) и контекст устройства. Контекст рендеринга OpenGL определен как hRC и связывает вызовы OpenGL с окном Windows. Для того чтобы рисовать в окне, необходимо создать контекст устройства Windows, который определен как hDC. Контекст устройства связывает окно с GDI. Контекст воспроизведения связывает OpenGL с контекстом устройства.

static HGLRC hRC; // Постоянный контекст рендерингаstatic HDC hDC; // Приватный контекст устройства GDI

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

BOOL keys[256]; // Массив для процедуры обработки клавиатуры

6. В следующей секции кода будут произведены все настройки для OpenGL Эта процедура может быть вызвана только после того как будет создано окно OpenGL. Установим цвет, которым будет очищен экран. Все значения могут быть в диапазоне от 0.0f до 1.0f, при этом 0.0 самый темный, а 1.0 самый светлый. Первые три параметра определяют цвет в модели RGB: первый - интенсивность красного, второй – зеленого, третий – синего. Наибольшее значение – 1.0f, является самым ярким значением данного цвета. Последний параметр – альфа-значение (прозрачность) – пока будет равен 0.0f.

GLvoid InitGL(GLsizei Width, GLsizei Height) //Вызвать после создания окна GL{glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Очистка экрана в черный цвет

}

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

GLvoid ReSizeGLScene(GLsizei Width, GLsizei Height)

{ if (Height==0) // Предотвращение деления на ноль, //если окно слишком мало Height=1; glViewport(0, 0, Width, Height); // Сброс текущей области вывода и перспективных преобразований}

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

GLvoid DrawGLScene(GLvoid){ glClear(GL_COLOR_BUFFER_BIT); // очистка экрана }

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

Первые четыре строки делают следующее: переменная hWnd – является указателем на окно. Переменная message – сообщения, передаваемые программе системой. Переменные wParam и lParam содержат информацию, которая посылается вместе с сообщением, например такую как ширина и высота окна.

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

Код между скобками устанавливает формат пикселей. Формат пикселя определяет то, как OpenGL будет выводить в окно. Большая часть кода игнорируется, но тем не менее необходима.

{ RECT Screen; // используется позднее для размеров окна GLuint PixelFormat; static PIXELFORMATDESCRIPTOR pfd= { sizeof(PIXELFORMATDESCRIPTOR), // Размер этой структуры 1, // Номер версии PFD_DRAW_TO_WINDOW | // Формат для Окна PFD_SUPPORT_OPENGL | // Формат для OpenGL PFD_DOUBLEBUFFER, // Формат для двойного буфера PFD_TYPE_RGBA, // Требуется RGBA формат 16, // Выбор 16 бит глубины цвета 0, 0, 0, 0, 0, 0, // Игнорирование цветовых битов 0, // нет буфера прозрачности 0, // Сдвиговый бит игнорируется 0, // Нет буфера аккумуляции 0, 0, 0, 0, // Биты аккумуляции игнорируются 16, // 16 битный Z-буфер (буфер глубины) 0, // Нет буфера трафарета 0, // Нет вспомогательных буферов PFD_MAIN_PLANE, // Главный слой рисования 0, // Резерв 0, 0, 0 // Маски слоя игнорируются };

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

switch (message) // Тип сообщения {

WM_CREATE указывает программе, что сообщение должно быть создано. Сначала следует запросить DC (контекст устройства) для окна – без него рисование в окне невозможно. Затем запрашивается формат пикселя. Компьютер будет выбирать формат, который полностью совпадает или наиболее близок к запрашиваемому формату[2].

case WM_CREATE: hDC = GetDC(hWnd); // Получить контекст устройства для окна PixelFormat = ChoosePixelFormat(hDC, &pfd); // Найти ближайшее совпадение для формата пикселов

Если подходящий формат пикселя не найден, будет выведено сообщение об ошибке.

if (!PixelFormat) { MessageBox(0, "Не найден подходящий формат пиксела.", "Ошибка",MB_OK|MB_ICONERROR);[3] PostQuitMessage(0); // Это сообщение говорит, что программа должна завершится break; // Предтовращение повтора кода }

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

if(!SetPixelFormat(hDC,PixelFormat,&pfd)) { MessageBox(0,"Формат пиксела не установлен.", "Ошибка",MB_OK|MB_ICONERROR); PostQuitMessage(0); break; }

Если код записан, как показано выше, будет создан контекст устройства(DC), и установлен подходящий формат пикселя.

Далее следует создать Контекст Рендеринга (RC), для этого OpenGL использует DC. Функция wglCreateContext захватывает Контекст Рендеринга и сохраняет его в переменной hRC. Если по какой-то причине Контекст Рендеринга недоступен, должно появиться сообщение об ошибке.

hRC = wglCreateContext(hDC); if(!hRC) { MessageBox(0,"Контекст воспроизведения не создан.", "Ошибка",MB_OK|MB_ICONERROR); PostQuitMessage(0); break; }

Необходимо сделать активным Контекст Рендеринга, для того чтобы можно было рисовать в окне средствами OpenGL. Если по какой-либо причине это невозможно, должно появиться сообщение об ошибке.

if(!wglMakeCurrent(hDC, hRC)) { MessageBox(0,"Невозможно активизировать GLRC.", "Ошибка",MB_OK|MB_ICONERROR); PostQuitMessage(0); break; }

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

GetClientRect(hWnd, &Screen); InitGL(Screen.right, Screen.bottom); break;

11. Следующий фрагмент кода необходим для уничтожения окна. Он использует сообщения WM_DESTROY и WM_CLOSE. Программа будет посылать это сообщение при выходе из программы по нажатию ALT-F4 или при ошибке (PostQuitMessage(0)).

Функция ChangeDisplaySettings(NULL,0) восстанавливает разрешение рабочего стола (делая его таким, каким оно было до перехода в полноэкранный режим).

Функция ReleaseDC(hWnd,hDC) уничтожает контекст устройства окна.

Перечисленные действия уничтожают окно OpenGL.

case WM_DESTROY: case WM_CLOSE: ChangeDisplaySettings(NULL, 0); wglMakeCurrent(hDC,NULL); wglDeleteContext(hRC); ReleaseDC(hWnd,hDC); PostQuitMessage(0); break;

12. Опишем обработку сообщений, возникающих при нажатии клавиш.

Сообщение WM_KEYDOWN возникает всякий раз при нажатии клавиши. Клавиша, которая была нажата, сохраняется в переменной wParam. При нажатии клавиши элемент массива, соответствующий коду нажатой клавиши, принимает значение TRUE.

case WM_KEYDOWN: keys[wParam] = TRUE; break;

Сообщение WM_KEYUP вызывается всякий раз при отпускании клавиши. Клавиша, которая отжата, также сохраняется в переменной wParam. При отпускании клавиши соответствующий элемент массива принимает значение FALSE.

case WM_KEYUP: keys[wParam] = FALSE; break;

13. В завершении программы следует обработать изменение размеров окна. Даже при запуске программы в полноэкранном режиме этот код необходим, без него экран OpenGL не появится.

Всякий раз сообщение WM_SIZE посылается Windows с двумя параметрами - новая ширина, и новая высота экрана. Эти параметры сохранены в LOWORD(lParam) и HIWORD(lParam). Вызов функции ReSizeGLScene изменяет размеры экрана, т.е. передает высоту и ширину в эту секцию кода.

case WM_SIZE: ReSizeGLScene(LOWORD(lParam),HIWORD(lParam)); break;

Следующий код необходим для обработки Windows всех поступивших сообщений и завершения процедуры.

default: return (DefWindowProc(hWnd, message, wParam, lParam)); } return (0);}

14. Следующая процедура необходима для создания и регистрации окна Windows.

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow){ MSG msg; // Структура сообщения Windows WNDCLASS wc; // Структура класса Windows для установки типа окна HWND hWnd; // Сохранение дескриптора окна

Флаги стиля CS_HREDRAW и CS_VREDRAW служат для перерисовки окна при его перемещении. CS_OWNDC создает скрытый DC для окна, т.е. DC не может использоваться совместно нескольким приложениями. WndProc - процедура, которая перехватывает сообщения для программы. Свойство hIcon установлено равным нулю, т.е. иконка окна не нужна; для мыши используется стандартный указатель. Фоновый цвет не имеет значения (мы установим его в GL). Если меню в этом окне не требуется, то установим его значение в NULL. Имя класса – это любое имя.

wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC; wc.lpfnWndProc = (WNDPROC) WndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = NULL; wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = NULL; wc.lpszMenuName = NULL; wc.lpszClassName = "OpenGL WinClass";

Если при регистрации класса произошла ошибка, появится соответствующее сообщение.

if(!RegisterClass(&wc)) { MessageBox(0,"Ошибка регистрации класса окна.", "Ошибка",MB_OK|MB_ICONERROR); return FALSE; }

Создадим окно. Однако OpenGL будет вызвана только после того как будет послано сообщение WM_CREATE. Флаги WS_CLIPCHILDREN и WS_CLIPSIBLINGS требуются для OpenGL и должны быть добавлены именно здесь.

hWnd = CreateWindow("OpenGL WinClass", "Это минимальная программа OpenGL", // Заголовок вверху окна WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, // Позиция окна на экране 640, 480, // Ширина и высота окна NULL, NULL, hInstance, NULL);

Далее следует обычная проверка на ошибки. Если окно не было создано по какой-то причине, сообщение об ошибке следует вывести на экран. При этом генерируется окно с сообщением об ошибке и предложением завершить программу.

if(!hWnd) { MessageBox(0,"Ошибка создания окна.","Ошибка",MB_OK|MB_ICONERROR); return FALSE; }

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

DEVMODE dmScreenSettings; // Режим работыmemset(&dmScreenSettings, 0, sizeof(DEVMODE));// Очистка для хранения установокdmScreenSettings.dmSize = sizeof(DEVMODE);// Размер структуры DevmodedmScreenSettings.dmPelsWidth = 640; // Ширина экранаdmScreenSettings.dmPelsHeight = 480; // Высота экранаdmScreenSettings.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;// Режим ПикселаChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN); // Переключение в полный экран

Функция ShowWindow показывает созданное окно.

Функция UpdateWindow обновляет окно, SetFocus делает окно активным, и вызывает wglMakeCurrent(hDC,hRC) чтобы убедиться, что Контекст рендеринга не освобожден.

ShowWindow(hWnd, SW_SHOW); UpdateWindow(hWnd); SetFocus(hWnd);

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

while (1) { // Обработка всех сообщений while (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { if (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } else { return TRUE; } }

Функция DrawGLScene вызывает ту часть программы, которая фактически рисует объекты OpenGL. Пока оставим эту часть секции пустой, все что будет сделано - очистка экрана черным цветом.

SwapBuffers(hDC) очень важная команда. Мы имеем окно с установленной двойной буферизацией. Это означает, что изображение рисуется на скрытом окне (называемым буфером). Затем с помощью команды переключения буферов скрытый буфер копируется на экран. При этом получается плавная анимация без рывков, и зритель не замечает процесс рисования объектов.

DrawGLScene(); // Нарисовать сцену SwapBuffers(hDC); // Переключить буфер экрана if (keys[VK_ESCAPE]) SendMessage(hWnd,WM_CLOSE,0,0); // Если ESC - выйти }}

Важно отметить, что этот код не будет скомпилирован на Cи, он должен быть сохранен как.CPP файл.

  1. Скомпилируйте и выполните проект. Итак, наша программа создает окно, размером 640х480, очищает его черным цветом и ожидает нажатия клавиши ESC (Alt+F4) для закрытия окна.
  2. Попробуем нарисовать что-либо в этом окне. Добавьте в раздел DrawGLScene() следующий код:
{ glClear(GL_COLOR_BUFFER_BIT); // очистка экрана glPointSize(2); //размер точки glBegin(GL_POINTS); glColor3d(1,0,0); glVertex3d(-0.45,-0.4,0); // первая точка glColor3d(0,1,0); glVertex3d(0.4,0.4,0); // вторая точка glColor3d(0,0,1); glVertex3d(-0.35,0.4,0); // третья точка glEnd(); } 17. Скомпилируйте и выполните проект. Сохраните результат вашей работы в своей папке. Этот шаблон будет использоваться в вашей дальнейшей работе.

Контрольные вопросы.

1. Что понимается под контекстом устройства?

2. Что представляет собой контекст воспроизведения?

3. Какие основные фрагменты должна содержать минимальная программа OpenGL.

4. Что входит в понятие формат пиксела?

5. Какие библиотечные файлы должны быть подключены к программе для работы с OpenGL?

6. Какая цветовая модель используется при определении цвета в данной программе?

7. Какие параметры следует указать, чтобы цвет фона был зеленым?

8. Для чего нужна функция масштабирования сцены?

9. В какой секции кода можно записывать команды рисования сцены?

10. Какое правило необходимо соблюдать, чтобы иметь возможность перехода в полноэкранный режим?







Дата добавления: 2015-10-19; просмотров: 636. Нарушение авторских прав; Мы поможем в написании вашей работы!



Аальтернативная стоимость. Кривая производственных возможностей В экономике Буридании есть 100 ед. труда с производительностью 4 м ткани или 2 кг мяса...

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

Расчетные и графические задания Равновесный объем - это объем, определяемый равенством спроса и предложения...

Кардиналистский и ординалистский подходы Кардиналистский (количественный подход) к анализу полезности основан на представлении о возможности измерения различных благ в условных единицах полезности...

Приложение Г: Особенности заполнение справки формы ву-45   После выполнения полного опробования тормозов, а так же после сокращенного, если предварительно на станции было произведено полное опробование тормозов состава от стационарной установки с автоматической регистрацией параметров или без...

Измерение следующих дефектов: ползун, выщербина, неравномерный прокат, равномерный прокат, кольцевая выработка, откол обода колеса, тонкий гребень, протёртость средней части оси Величину проката определяют с помощью вертикального движка 2 сухаря 3 шаблона 1 по кругу катания...

Неисправности автосцепки, с которыми запрещается постановка вагонов в поезд. Причины саморасцепов ЗАПРЕЩАЕТСЯ: постановка в поезда и следование в них вагонов, у которых автосцепное устройство имеет хотя бы одну из следующих неисправностей: - трещину в корпусе автосцепки, излом деталей механизма...

Объект, субъект, предмет, цели и задачи управления персоналом Социальная система организации делится на две основные подсистемы: управляющую и управляемую...

Законы Генри, Дальтона, Сеченова. Применение этих законов при лечении кессонной болезни, лечении в барокамере и исследовании электролитного состава крови Закон Генри: Количество газа, растворенного при данной температуре в определенном объеме жидкости, при равновесии прямо пропорциональны давлению газа...

Ганглиоблокаторы. Классификация. Механизм действия. Фармакодинамика. Применение.Побочные эфффекты Никотинчувствительные холинорецепторы (н-холинорецепторы) в основном локализованы на постсинаптических мембранах в синапсах скелетной мускулатуры...

Studopedia.info - Студопедия - 2014-2024 год . (0.01 сек.) русская версия | украинская версия