МIНIСТЕРСТВО ОСВIТИ І НАУКИ УКРАЇНИ
Національний унiверситет "Львiвська полiтехнiка"
Кафедра САПР
ЗВІТ
до лабораторної роботи N 4
з курсу "Геометричне моделювання у конструюванні інженерних об'єктів і систем"
ДВОМІРНІ ПОБУДОВИ З ВИКОРИСТАННЯМ OPENGL
ЗАСОБАМИ BORLAND DELPHI
МЕТА РОБОТИ
Мета роботи — ознайомлення та практичне освоєння технології й основ роботи з графічними можливостями бібліотеки OpenGL на площині в операційному середовищі Windows. Вивчити способи підключення бібліотеки OpenGL при розробці програмних проектів засобами візуального середовища програмування Borland Delphi. Ознайомитися та засвоїти основні графічні функцій та процедури, набути практичних навиків програмування графіки для Windows-програм на основі OpenGL.
ТЕОРЕТИЧНІ ВІДОМОСТІ
ОСНОВНІ ПОНЯТТЯ
OpenGL — це стандартна бібліотека для усіх 32-розрядних операційних систем, у тому числі і для операційної системи Windows.
OpenGL – не окрема програма, а частина операційної системи. Це означає, що відкомпільована програма, яка використовує OpenGL, не потребує ніяких додаткових програм чи модулів, крім стандартних, що містяться на будь-якому комп'ютері з встановленою операційною системою Windows 95 версії OSR2 та вище.
У склад стандартної поставки Delphi (починаючи з третьої версії) входить заголовочний файл, який дозволяє будувати програми з використанням OpenGL, а також довідковий файл по командах цієї бібліотеки.
OpenGL є на даний момент одним з найпопулярніших програмних інтерфейсів (АРІ) для розробки прикладних програм в області двовимірної й тривимірної графіки. Стандарт OpenGL був розроблений і затверджений в 1992 році провідними фірмами в галузі розробки програмного забезпечення, а його основою стала бібліотека IRIS GL, розроблена Silicon Graphics.
На даний час реалізація OpenGL включає в себе декілька бібліотек (опис базових функцій OpenGL, GLU, GLUT, GLAUX та інші). Характерними особливостями OpenGL, які забезпечили поширення і розвиток цього графічного стандарту, є:
Стабільність. Доповнення і зміни в стандарті реалізовуються таким чином, щоб зберегтисумісність з розробленим раніше програмним забезпеченням.
Надійність і переносимість. Програми, що використовують OpenGL, гарантуютьоднаковий візуальний результат незалежно від типу операційної системи, щовикористовується для організації відображення інформації. Крім того, ці програми можутьвиконуватися як на персональних комп'ютерах, так і на робочих станціях ісуперкомп'ютерах.
Легкість застосування.
Стандарт OpenGL має продуману структуру та інтуїтивно зрозумілий інтерфейс, що дозволяє з меншими витратами створювати ефективні програми, що містять менше рядків коду, ніж з використанням інших графічних бібліотек. Необхідні функції для забезпечення сумісності з різним обладнанням реалізовані на рівні бібліотеки і значно спрощують розробку прикладних програм.
Основні можливості OpenGL :
Набір базових примітивів: точки, лінії, багатокутники тощо.
Видові та координатні перетворення.
Вилучення невидимих ліній і поверхонь (z-буфер).
Використання сплайнів для побудови ліній та поверхонь.
Накладення текстури та застосування освітлення.
Додаткові спеціальні ефекти: туман, зміна прозорості, поєднання кольорів (blending),усунення ступінчатості (anti-aliasing).
Існує реалізація OpenGL для різних платформ, для чого було зручно розділити базові функції графічної системи та функції для відображення графічної інформації і взаємодії з користувачем. Були створені бібліотеки для відображення інформації за допомогою віконної підсистеми для операційних систем Windows і Unix (WGL і GLX відповідно), а також бібліотеки GLAUX та GLUT, які використовуються для створення так званих консольних програм.
Бібліотека GLAUX поступається за популярністю написаній дещо пізніше бібліотеці GLUT, хоч вони надають приблизно однакові можливості. До складу бібліотеки GLU увійшла реалізація більш складних функцій, таких як набір популярних геометричних примітивів (куб, куля, циліндр, диск), функції побудови сплайнів, реалізація додаткових операцій над матрицями тощо. Усі вони реалізовані через базові функції OpenGL.
Архітектура і особливості синтаксису
З точки зору архітектури, графічна система OpenGL є конвейєром, що складається з декількох етапів обробки даних:
Апроксимація кривих і поверхонь.
Обробка вершин і збирання примітивів.
Растеризация і обробка фрагментів.
Операції над пікселями.
Підготовка текстури.
Передача даних в буфер кадру.
Узагалі, OpenGL можна порівняти з кінцевим автоматом, стан якого визначається безліччю значень спеціальних змінних (їхні імена звичайно починаються з символів GL_) і значеннями поточної нормали, кольору та координат текстури. Уся ця інформація буде використана при надходженні в систему координат вершини для побудови фігури, в яку вона входить. Зміна станів відбувається за допомогою команд, які оформляються як виклики функцій.
ПІДКЛЮЧЕННЯ OPENGL
КОНТЕКСТ ГРАФІЧНОГО ПРИСТРОЮ
Графічні функції зі складу API Windows об'єднані в окрему групу — підсистему GDI (Graphic Device Interface, інтерфейс графічного пристрою). Важлива риса підсистеми GDI -апаратна незалежність багатьох функцій від конкретного графічного пристрою.
Контекст графічного пристрою (Device Context) - це важливий елемент графіки в середовищі операційної системи Windows. Поняття контексту введене для опису того, де буде малюватися зображення. Іншими словами, контекст графічного пристрою вказує площину відображення, на яку робиться графічний вивід. Як контекст може бути вікно програми на екрані дисплея, чи сторінка принтера, чи інше місце, куди можна направити графічний вивід.
Якщо ваша програма робить виклик графічних функцій API Windows, таких як малювання крапок, ліній, фігур, тексту тощо, необхідно вказувати ідентифікатор контексту (handle of device context) і координати. Виклик необхідного драйвера - для екрана дисплея, принтера чи іншого пристрою — робить уже сама Windows. Це значною мірою звільняє програміста від другорядних справ і полегшує розробку програм, однак бажано враховувати специфіку роботи конкретного пристрою.
Ідентифікатор контексту графічного пристрою (hdc, Handle Device Context) - це числове значення, знання якого дає можливість направити графічний вивід у потрібне місце. Перед початком малювання необхідно одержати це числове значення. Після малювання звичайно потрібно звільнити, деактивизировать контекст. Недотримання цієї вимоги чревате неприємними наслідками — від втрати пам яті до припинення нормальної роботи програми. Коректне використання контексту графічного пристрою здійснюється в такій послідовності:
Створення, активізація контексту, одержання значення hdc.
Малювання за допомогою графічних функцій API Windows.
Знищення, деактивизация контексту відповідного hdc.
Для того щоб операційна система могла розрізняти вікна для здійснення діалогу з ними, усі вікна при своєму створенні реєструються в операційній системі та отримують унікальний ідентифікатор, який називається "зсилка на вікно". Тип цієї величини в Delphi — HWND (Handle WiNDow). Синонімом терміна "зсилка" є дексриптор.
Зсилка на вікно може використовуватися не лише операційною системою, але й програмами для ідентифікації вікна, з якими необхідно проводити маніпуляції.
ФОРМАТ ПІКСЕЛЯ В OPENGL
Посилання на контекст пристрою містять характеристики пристрою і засобу відображення. Одержавши посилання на контекст пристрою, маємо простий або кольоровий олівець чи пензель з палітрою в мільйони відтінків.
Сервер OpenGL, перш ніж приступати до роботи, також повинний визначитися, на якому устаткуванні йому доведеться працювати Це може бути персональний комп'ютер, а може бути і потужна графічна станція.
Перш ніж одержати контекст відтворення, сервер OpenGL повинний одержати детальні характеристики використовуваного устаткування. Ці характеристики зберігаються в спеціальній структурі, тип якої - TPixelFormatDescriptor (опис формату піксела). Формат піксела визначає конфігурацію буфера кольору і допоміжних буферів.
Отже, зміст структури PixelFormatDescriptor — детальний опис графічної системи, на якій відбувається робота. Опис усіх полів структури TPixelFormatDescriptor робиться в процедурі SetDCPixelFormat, яка викликається між одержанням посилання на контекст пристрою і створенням посилання на контекст відтворення OpenGL. Полям структури присвоюється бажані значення, потім викликом функції ChoosePixelFormat здійснюється запит системі, чи підтримується на даному робочому місці обраний формат піксела, і, нарешті, викликом функції SetPixelFormat установлюється формат піксела в контексті пристрою. Функція ChoosePixelFormat повертає індекс формату пиксела, що нам потрібний як аргумент функції SetPixelFormat.
Заповнивши поля структури TPixelFormatDescriptor, ми визначаємося зі своїми побажаннями до графічної системи, на якій буде відбуватися робота програми, OpenGL підбирає найбільш придатний до наших побажань формат і установлює вже його як формат піксела для наступної роботи. Наші побажання коректуються сервером OpenGL стосовно до реальних характеристик системи.
ТИПИ OPENGL
Бібліотека OpenGL є переносимою по відношенню до платформ, операційних систем і середовищам програмування.
Для забезпечення цієї незалежності в ній визначені власні типи. їхній префікс - "GL", наприклад, GLint.
У кожному середовищі програмування в заголовкових файлах ці типи перевизначаються відповідно до власних типів середовища. Розберемо, як це робиться в Delphi.
Заголовковий файл Delphi opengl.pas починається з визначення типу HGLRC:
type
HGLRC = THandle;
Індивідуальне завдання
Написати програму із застосуванням 2D графічних функцій бібліотеки OpenGL, яка дозволяє візуалізувати у незалежних віконних форма програми ескізне креслення мікрометра для зовнішніх лінійних вимірів (див. рис).
Текст програми
unit Unit1;
interface
uses
Windows, Messages, Forms, Classes, Controls, ExtCtrls, ComCtrls,
StdCtrls, Dialogs, SysUtils,OpenGL;
type
TForm1 = class(TForm) //опис класу форми вікна
procedure FormCreate(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
hrc: HGLRC; // зсилка на контекст відтворення
end;
var
Form1: TForm1; //змінна форми вікна
implementation {$R *.DFM}
{========Рисування картинки==========}
procedure TForm1.FormPaint(Sender: TObject);
var x,y,xm,ym,y1:real;
i:integer;
begin
wglMakeCurrent (Canvas .Handle, hrc);
// встановлюється поточний контекст форми відтворення
{******* Далі РОЗМІЩУЮТЬСЯ КОМАНДИ РИСОВАННЯ OpenGL **************}
glViewPort (0, 0, Form1.ClientWidth, Form1.ClientHeight);
// область виводу ширина, висота розміру форми Forml програми
glClearColor (0.5, 0.5, 0.75, 1.0 ); // колір фону
glClear (GL_COLOR_BUFFER_BIT); // очищення буфера кольору
{--- Мікрометра ---}
x:=0;
y:=0;
glColor3f (0.0, 0.7, 1.0); // поточний колір примітивів
glBegin (GL_TRIANGLES);
glVertex2f (0.7+x, 0.28+y); //1
glVertex2f (0.7+x, 0.170+y);
glVertex2f (0.54+x, 0.170+y);
glEnd;
glBegin (GL_TRIANGLES);
glVertex2f (0.7+x, 0.28+y);
glVertex2f (0.54+x, 0.28+y); //2
glVertex2f (0.54+x, 0.170+y);
glEnd;
glColor3f (0.10, 0.70,0.0); // поточний колір примітивів
glBegin (GL_TRIANGLES);
glVertex2f (0.54+x, 0.32+y);
glVertex2f (0.45+x, 0.32+y); //3
glVertex2f (0.45+x, 0.130+y);
glEnd;
glBegin (GL_TRIANGLES);
glVertex2f (0.54+x, 0.32+y);
glVertex2f (0.54+x, 0.130+y); //4
glVertex2f (0.45+x, 0.130+y);
glEnd;
glColor3f (0.0, 0.7, 1.0); // поточний колір примітивів
glBegin (GL_TRIANGLES);
glVertex2f (0.45+x, 0.14+y);
glVertex2f (0.25+x, 0.14+y); //5
glVertex2f (0.45+x, 0.31+y);
glEnd;
glBegin (GL_TRIANGLES);
glVertex2f (0.25+x, 0.31+y);
glVertex2f (0.25+x, 0.14+y); //6
glVertex2f (0.45+x, 0.31+y);
glEnd;
glColor3f (0.10, 0.70,0.0); // поточний колір примітивів
glBegin (GL_TRIANGLES);
glVertex2f (0.25+x, 0.32+y);
glVertex2f (0.25+x, 0.13+y); //7
glVertex2f (0.04+x, 0.13+y);
glEnd;
glBegin (GL_TRIANGLES);
glVertex2f (0.25+x, 0.32+y);
glVertex2f (0.04+x, 0.32+y); //8
glVertex2f (0.04+x, 0.13+y);
glEnd;
glColor3f (0.0, 0.7, 1.0); // поточний колір примітивів
glBegin (GL_polygon);
glVertex2f (0.04+x, 0.13+y); //9
glVertex2f (0.04+x, 0.32+y);
glVertex2f (-0.01+x, 0.3+y);
glVertex2f (-0.01+x, 0.15+y);
glEnd;
glBegin (GL_polygon);
glVertex2f (-0.05+x, 0.15+y);
glVertex2f (-0.05+x, 0.3+y);
glVertex2f (-0.01+x, 0.3+y);
glVertex2f (-0.01+x, 0.15+y);
glEnd;
glBegin (GL_polygon);
glVertex2f (-0.05+x, 0.3+y);
glVertex2f (-0.22+x, 0.3+y);
glVertex2f (-0.22+x, 0.0+y);
glVertex2f (-0.05+x, 0.0+y);
glEnd;
glColor3f (1.90, 0.7, 1.0); // поточний колір примітивів
glBegin (GL_polygon);
glVertex2f (-0.22+x, 0.18+y);
glVertex2f (-0.22+x, 0.25+y);
glVertex2f (-0.48+x, 0.25+y);
glVertex2f (-0.48+x, 0.18+y);
glEnd;
glBegin (GL_polygon);
glVertex2f (-0.54+x, 0.18+y);
glVertex2f (-0.54+x, 0.25+y);
glVertex2f (-0.5+x, 0.25+y);
glVertex2f (-0.5+x, 0.18+y);
glEnd;
glColor3f (0.0, 0.7, 1.0); // поточний колір примітивів
glBegin (GL_polygon);
glVertex2f (-0.54+x, 0.0+y);
glVertex2f (-0.54+x, 0.27+y);
glVertex2f (-0.66+x, 0.27+y);
glVertex2f (-0.66+x, 0.0+y);
glEnd;
glColor3f (1.0, 0.0, 0.0); // поточний колір примітивів
xm:=0;
for i:= 1 to 9000 do
begin
ym:=sqrt(sqr(0.16)-sqr(xm));
glBegin (GL_points);
glVertex2f (xm-0.38,-ym+0.03);
glVertex2f (-xm-0.38,-ym+0.03);
glEnd;
xm:=xm + 0.001;
end;
xm:=0;
for i:= 1 to 99000 do
begin
ym:=sqrt(sqr(0.35)-sqr(xm));
glBegin (GL_points);
glVertex2f (xm-0.36,-ym-0.05);
glVertex2f (-xm-0.36,-ym-0.05);
glEnd;
xm:=xm + 0.00001;
end;
ym:=0;
for i:= 1 to 18000 do
begin
xm:=sqrt(sqr(0.35)-sqr(ym));
y1:=-xm;
glBegin (GL_points);
glVertex2f (xm-0.36,ym-0.05);
glVertex2f (-xm-0.36,ym-0.05);
glEnd;
ym:=ym + 0.00001;
end;
wglMakeCurrent (0, 0); // перед завершенням роботи необхідно,
// щоб контекст ніким не використовувався
end;
{====Формат пікселя==========}
procedure SetDCPixelFormat (hdc : HDC);
var
pfd : TPixelFormatDescriptor; //дані формату пікселів
nPixelFormat : Integer;
begin
FillChar (pfd, SizeOf (pfd), 0) ;
nPixelFormat := ChoosePixelFormat (hdc, @pfd); // запит системі -чи підтримується вибраний //формат пікселів
SetPixelFormat (hdc, nPixelFormat, @pfd) ; // встановлює формат пікселів у контексті //пристрою
end;
{====Створення форми=====}
procedure TForm1.FormCreate(Sender: TObject); begin
SetDCPixelFormat(Canvas.Handle);
hrc := wglCreateContext(Canvas.Handle); // створює контекст відтворення OpenGL
end;
{===========Кінець роботи програми===========}
procedure TForm1.FormDestroy(Sender: TObject);
begin
wglDeleteContext (hrc) // видалення контексту відтворення
end;
end.
Результат виконання програми
ВИСНОВОК: в даній роботі було ознайомлено та практично освоєно технології роботи з графічними можливостями бібліотеки OpenGL. Ознайомлено та засвоїно основні графічні функцій та процедури, набуто практичних навиків програмування графіки для Windows-програм на основі OpenGL.