|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Основні поняття, використовувані в даній лабораторній роботі: контекст пристрою, контекст відтворення, формат пікселаКонтекст графічного пристрою (Device Context) указує площину відображення, на яку здійснюється графічний вивід: вікно програми на екрані дисплея, сторінка принтера або інше місце, куди може бути направлений графічний вивід. Якщо програма викликає різні графічні функції, такі як малювання крапок, ліній, фігур і ін., необхідно указувати ідентифікатор контексту (hdc – handle of device context) і координати. Сенс використання контексту пристрою полягає в тому, що вивід на різні пристрої здійснюється одними і тими ж функціями, змінюється лише значення hDC. «Контекст пристрою є структурою, яка визначає комплект графічних об'єктів і пов'язаних з ними атрибутів і графічні режими, що впливають на вивід». При складанні програми необхідно набути цього числового значення перед малюванням, а після малювання – звільнити контекст. У OPENGL існує поняття контекст відтворення (контекст рендеринга), аналогічне поняттю контекст пристрою. Графічна система OPENGL також потребує посилання на пристрій, на який здійснюватиметься вивід. Це спеціальне посилання на контекст відтворення – величина типа HGLRC (handle openGL rendering context, посилання на контекст відтворення OPENGL) - hRC. Перш ніж отримати|одержувати| контекст відтворення, сервер OPENGL| повинен отримати|одержувати| детальні характеристики використовуваного устаткування|обладнання|. Ці характеристики зберігаються в спеціальній структурі – опис формату піксела. Формат піксела визначає конфігурацію буфера кольору|цвіту| і допоміжних буферів. Порядок|лад| виконання роботи. Програма, яка буде створена в результаті|унаслідок| виконання даної лабораторної роботи, повинна здійснювати наступні|слідуючі| дії: створювати порожнє|пусте| вікно для графічного виводу|висновку| засобами|коштами| 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); 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|);// Розмір структури Devmode|dmScreenSettings|.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 файл. Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.008 сек.) |