Ми вже знаємо, що посилання на контекст пристрою - це величина типа HDC. Для її отримання можна викликати функцію GetDC, аргументом якої є посилання на потрібне вікно. Посиланню на контекст пристрою відповідає властивість canvas. Handie форми, принтера і деяких компонентів Delphi. Яке ж все-таки значення контексту пристрою, якщо він і такий пов'язаний з однозначно певним об'єктом - вікном, областю пам'яті або принтером, і навіщо передавати додатково якусь інформацію про однозначно певний об'єкт? Для відповіді на ці питання звернемо увагу на чудову властивість висновку в Windows, що полягає в тому, що одними і тими ж функціями здійснюється висновок на різні пристрої. Рядки програми
Forml. Canvas. Ellipse (0, 0, 100, 100);
І
Printer. BeginDoc;
Printer. Canvas. Ellipse (0, 0, 100, 100);
Printer. EndDoc;
малюють один і той же круг як на поверхні форми, так і в роздруковуваному документі, т. e. на різних пристроях, причому якщо ми виводитимемо різнокольорову картинку на монохромний принтер, він справиться з цією задачею, передаючи кольори відтінками сірого. Навіть якщо ми малюємо тільки на полі форми, ми маємо справу з різними пристроями - нам невідомо, яка графічна платня комп'ютера і які характеристики поточної установки настройок екрану. Наприклад, маючи в своєму розпорядженні більше 16 мільйонів кольорів, додаток не піклується про відображення цієї багатої палітри на екрані, що має свій в розпорядженні всього 256 кольори. Такі питання додаток перекладає на плечі OpenGL Графіка в проектах Delphi раціонної системи, вирішальної їх за допомогою використовування драйверів пристроїв Для того, щоб скористатися функціями відтворення Windows, додатку необхідно тільки вказати посилання на контекст пристрою, що містить засоби і характеристики пристрою висновку. Довідковий файл Win32 Programmer's Reference фірми Microsoft, що поставляється у складі Delphi, про контекст пристрою повідомляє наступне "Контекст пристрою є структурою, яка визначає комплект графічних об'єктів і пов'язаних з ними атрибутів і графічні режими, що впливають на висновок Графічний об'єкт включає олівець для зображення лінії, кисть для зафарбовування і заповнення, растр для копіювання або прокрутки частин екрану, палітру для визначення комплекту доступних кольорів, області для відсікання і інших операцій, маршрут для операцій малювання" В OpenGL є аналогічне посиланню на контекст пристрою поняття посилання на контекст відтворення Графічна система OpenGL, як і будь-який інший додаток Windows (хоча і розміщене в DLL), також потребує посилання на пристрій, на який здійснюватиметься висновок Це спеціальне посилання на контекст відтворення, - величина типа HGLRC (Handle openGL Rendering Context, посилання на контекст відтворення OpenGL).
Контекст пристрою Windows містить інформацію, що відноситься до графічних компонентів GDI, а контекст відтворення містить інформацію, що відноситься до OpenGL, т e грає таку ж роль, що і контекст пристрою для GDIЗокрема, згадані контексти є сховищами стану системи, наприклад, бережуть інформацію про поточний колір олівця.
Після відображення команд в програмі Delphi сфера матиме такий вигляд, який вказаний в моєму завданні нижче на (рис.1, рис.2, рис.3)
рис. №1
рис. № 2
рис. №3
Листинг програми матиме такий вигляд:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OpenGL, Menus;
type
TfrmGL = class (TForm)
procedure FormCreate (Sender: TObject);
procedure FormPaint (Sender: TObject);
procedure FormDestroy (Sender: TObject);
procedure FormKeyDown (Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormResize (Sender: TObject);
procedure FormKeyPress (Sender: TObject; var Key: Char);
private
DC: HDC; // контекст пристрою
hrc: HGLRC; // контекст відображення
ry: GLfloat; // зміна координати по У
tx: GLfloat; // зміна координати по Х
end;
var
frmGL: TfrmGL;
mode: (POINT, LINE, FILL) = FILL; // режими відображення обєкта
mx,my: byte; // коефіцієнти збільшення/зменшення
implementation
uses DGLUT;
{$R *. DFM}
procedure TfrmGL. FormPaint (Sender: TObject);
begin
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); // очищення буферу кольору
glPushMatrix; // заповнюємо систему координат
glScalef (my/mx, my/mx, my/mx); // виконуємо маштабування
glRotatef (ry, 0.0, 1.0, 0.0); // виконуємо потовот
glTranslatef (tx, 0.0, 0.0); // виконуємо перенесення
case mode of // вибираємо режим відображення
POINT: glPolygonMode (GL_FRONT_AND_BACK, GL_POINT);
LINE: glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
FILL: glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
end;
glutSolidSphere (1.5, 20, 20); // будуємо сферу
glScalef (mx/my, mx/my, mx/my); // повертаємо систему в початкове полож
glPopMatrix; // повертаємо систему в попереднє положення
SwapBuffers (DC); // відображуємо на екрані
end;
procedure SetDCPixelFormat (hdc: HDC);
var
pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
begin
FillChar (pfd, SizeOf (pfd), 0);
pfd. dwFlags: = PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or PFD_DOUBLEBUFFER;
nPixelFormat: = ChoosePixelFormat (hdc, @pfd);
SetPixelFormat (hdc, nPixelFormat, @pfd);
end;
procedure TfrmGL. FormCreate (Sender: TObject);
begin
DC: = GetDC (Handle);
SetDCPixelFormat (DC);
hrc: = wglCreateContext (DC);
wglMakeCurrent (DC, hrc);
glClearColor (0.5, 0.5, 0.75, 1.0); // цвет фона
glLineWidth (1.5);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glEnable (GL_COLOR_MATERIAL);
glColor3f (1.0, 0.0, 0.0);
ry: = 0.0;
tx: = 0.0;
mx: =10;
my: =10;
end;
procedure TfrmGL. FormDestroy (Sender: TObject);
begin
wglMakeCurrent (0, 0);
wglDeleteContext (hrc);
ReleaseDC (Handle, DC);
DeleteDC (DC);
end;
procedure TfrmGL. FormKeyDown (Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
If Key = VK_ESCAPE then Close;
If Key = VK_LEFT then begin
ry: = ry + 2.0;
InvalidateRect (Handle, nil, False);
end;
If Key = VK_RIGHT then begin
ry: = ry - 2.0;
InvalidateRect (Handle, nil, False);
end;
If Key = VK_UP then begin
tx: = tx - 0.1;
InvalidateRect (Handle, nil, False);
end;
If Key = VK_DOWN then begin
tx: = tx + 0.1;
InvalidateRect (Handle, nil, False);
end;
If Key = 49 then begin
mode: = POINT;
InvalidateRect (Handle, nil, False);
end;
If Key = 50 then begin
mode: = LINE;
InvalidateRect (Handle, nil, False);
end;
If Key = 51 then begin
mode: = FILL;
InvalidateRect (Handle, nil, False);
end;
end;
procedure TfrmGL. FormResize (Sender: TObject);
begin
glViewport (0, 0, ClientWidth, ClientHeight);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1, 1, - 1, 1, 2,9);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
// этот фрагмент нужен для придания трёхмерности
glTranslatef (0.0, 0.0, - 5.0); // перенос объекта - ось Z
glRotatef (30.0, 1.0, 0.0, 0.0); // поворот объекта - ось X
glRotatef (70.0, 0.0, 1.0, 0.0); // поворот объекта - ось Y
InvalidateRect (Handle, nil, False);
end;
Для попереднього практичного завдання вашого варіанту забезпечити операцію масштабування використовуючи клавіши “+” та “-“
Для попереднього практичного завдання вашого варіанту забезпечити операцію масштабування використовуючи клавіши “+” та “-“
Потім для точного виконання завдання виконала слідуючий алгоритм дій при цьому використала згідно варіанту клавіші "+" та "-", що по умові завдання виконують наближення та відділення фігури на фоні:
procedure TfrmGL. FormKeyPress (Sender: TObject; var Key: Char);
begin
if key = '-' then mx: =mx+1;
if key = '+' then mx: =mx-1;
InvalidateRect (Handle, nil, False);
end;
end.
1. С.В. Глушаков, Г.А. Крабе Компютерная графика, Харьков 2002
2. Блінова Т.О., Порєв В.М. Комп’ютерна графіка / За ред. В.М. Горєва. - К.: Видавництво “Юніор”, 2004.
3. OpenGl, технология ставшая символов, Учебник в примерах.
4. Конспект лекцій.
5. Мережа Інтернет.