Міністерство освіти та науки України
Національний університет «Львівська політехніка»
Кафедра автоматизованих систем управління
/
Розрахунково – графічна робота
з дисципліни
«Комп’ютерна графіка»
на тему:
“Моделювання об’єктів на сцені”
Виконав:
Студент гр. КН-41
Перевірив:
Львів – 2011
Зміст
Вступ
Теоретичні відомості
Код програми
Інформація користувачу
Висновок
Список використаної літератури
Вступ
Delphi - надзвичайно потужна система розробки прикладних програм для Windows. Вона все впевненіше завойовує провідні позиції в нашій країні як серед професійних програмістів, так і серед людей, які ніколи професійно програмуванням що не займалися. Професіонали використовують Delphi для побудови складних застосувань з розподіленими базами даних і для багатьох інших цілей. Фахівці самих різних спеціальностей (не програмісти) створюють за допомогою Delphi невеликі прикладні програми для вирішення своїх професійних завдань і радіють, що, не володіючи серйозно програмуванням, можуть створювати інтерфейс, невідмітний від звичного інтерфейсу Windows.
В даній розрахунковій роботі потрібно змоделювати об’єкт, яким можна керувати за допомогою контекстного меню. Так як це можна зробити в тривимірному просторі, то я використала Open Gl.
Теоретична частина
OpenGL — (англ. Open Graphics Library — відкрита графічна бібліотека) — специфікація, що визначає незалежний від мови програмування крос-платформовий програмний інтерфейс (API) для написання застосунків, що використовують 2D та 3D комп'ютерну графіку. Даний інтерфейс містить понад 250 функцій, які можуть використовуватися для малювання складних тривимірних сцен з простих примітивів. Широко застосовується індустрією комп'ютерних ігор і віртуальної реальності, у графічних інтерфейсах (Compiz, Clutter), при візуалізації наукових даних, в системах автоматизованого проектування тощо.
Розглядаючи будь-який тривимірний об'єкт, ми завжди визначаємо його розташування і розміри щодо деякої звичної, і зручною зараз системи координат, пов'язаної з реальним світом. Така вихідна система координат в комп'ютерній графіці є правобічної і називається світовою системою координат.
Для того, щоб можна було зобразити об'єкт на екрані, його необхідно попередньо перевести (або перетворити) в іншу систему координат, яка пов'язана з точкою спостереження і носить назву видовий системи координат. Ця система координат є лівосторонньої. І, нарешті, будь-яке тривимірне зображення ми завжди малюємо на двовимірному екрані, який має свою екранну систему координат.
За замовчуванням, площину xOy паралельна екрану, а вісь Z спрямована у світових координатах до нас, у видових - від нас.
У OpenGL всі об'єкти малюються на початку координат, тобто в точці (0,0,0). Для того, щоб зобразити об'єкт в точці (x1, y1, z1), треба перемістити початок координат в цю точку, тобто перейти до нових координатах. Для цього в OpenGL визначені дві процедури:
glTranslate [fd] (Dx, Dy, Dz) - зрушує початок координат на (Dx, Dy, Dz)
glRotate [fd] (j, x, y, z) - повертає систему координат на кут j (в градусах) проти годинникової стрілки навколо вектора (x, y, z)
ПРИМІТКА: [fd] - означає, що в кінці може бути або буква "f", або "d".
Тепер варто сказати ще про дві процедури:
glPushMatrix
glPopMatrix
Перша призначена, для збереження, а другий - для відновлення поточних координат. Дуже зручно за допомогою glPushMatrix зберегти поточні координати, потім зрушуватися і звертатися як завгодно, а після, викликом glPopMatrix, повернутися до вихідних координатах. Параметрів у цих процедур немає.
Windows Api (application programming interfaces) — загальне найменування для цілого набору базових функцій інтерфейсів програмування застосунків операційних систем сімейств Windowsкорпорації Майкрософт. Є найпрямішим способом взаємодії застосунків з Windows. Для створення програм, що використовують Windows API, Майкрософт випускає SDK, який називається Platform SDK і містить документацію, набір бібліотек, утиліт і інших інструментальних засобів.
Код програми
unit mgl;
interface
uses
Windows, Messages, Classes, Graphics, Forms, ExtCtrls, OpenGL, StdCtrls,
Controls, SysUtils, Spin, Menus, Dialogs;
type
TForm1 = class(TForm)
Timer1: TTimer;
PopupMenu1: TPopupMenu;
Rotatespeed1: TMenuItem;
x1: TMenuItem;
y1: TMenuItem;
z1: TMenuItem;
X2: TMenuItem;
Y2: TMenuItem;
Z2: TMenuItem;
procedure FormCreate(Sender: TObject);
procedure FormResize(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
procedure FormKeyPress(Sender: TObject; var Key: Char);
procedure Rotatespeed1Click(Sender: TObject);
procedure x1Click(Sender: TObject);
procedure y1Click(Sender: TObject);
procedure z1Click(Sender: TObject);
procedure Z2Click(Sender: TObject);
procedure X2Click(Sender: TObject);
procedure Y2Click(Sender: TObject);
private
DC : HDC;
hrc : HGLRC;
Angle, AngleX, AngleY, AngleZ: GLfloat;
procedure DrawScene;
procedure InitializeRC;
procedure SetDCPixelFormat;
protected
//Обробка повідомлення WM_PAINT - аналог події OnPaint
procedure WMPaint(var Msg: TWMPaint); message WM_PAINT;
end;
var
Form1: TForm;
ch, c, i: integer;
s: string;
ShowHelp: boolean=true;
implementation
{$R *.DFM}
const
// масив властивостей матеріалу
MaterialColor: Array [0..3] of GLfloat = (0.5, 0.0, 1.0, 1.0);
// Процедура ініціалізації джерела кольору
procedure TForm1.InitializeRC;
begin
glEnable(GL_DEPTH_TEST); // дозволяємо тест глибини
glEnable(GL_LIGHTING); // дозволяємо роботу зі освітленістю
glEnable(GL_LIGHT0); // включаємо джерело світла 0
end;
// картинки
procedure TForm1.DrawScene;
begin
// очищення буфера кольору і буфера глибини
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
// тривимірність
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;
glTranslatef(0.0, 0.0, -8.0); // вліво/вправо, вверх/вниз, назад/вперед
glRotatef(AngleX, 1.0, 0.0, 0.0); // поворот на кут X
glRotatef(AngleY, 0.0, 1.0, 0.0); // поворот на кут Y
glRotatef(AngleZ, 0.0, 0.0, 1.0); // поворот на кут Z
// Шість сторін куба
glBegin(GL_POLYGON);
glNormal3f(0.0, 0.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glEnd;
glBegin(GL_POLYGON);
glNormal3f(0.0, 0.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, 1.0, -1.0);
glEnd;
glBegin(GL_POLYGON);
glNormal3f(-1.0, 0.0, 0.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(-1.0, -1.0, 1.0);
glEnd;
glBegin(GL_POLYGON);
glNormal3f(1.0, 0.0, 0.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(1.0, 1.0, -1.0);
glEnd;
glBegin(GL_POLYGON);
glNormal3f(0.0, 1.0, 0.0);
glVertex3f(-1.0, 1.0, -1.0);
glVertex3f(-1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, 1.0);
glVertex3f(1.0, 1.0, -1.0);
glEnd;
glBegin(GL_POLYGON);
glNormal3f(0.0, -1.0, 0.0);
glVertex3f(-1.0, -1.0, -1.0);
glVertex3f(1.0, -1.0, -1.0);
glVertex3f(1.0, -1.0, 1.0);
glVertex3f(-1.0, -1.0, 1.0);
glEnd;
SwapBuffers(DC); // кінець роботи
end;
// Обробка таймера
procedure TForm1.Timer1Timer(Sender: TObject);
begin
Angle:=Angle+1.0;
if (Angle>=90.0)
then Angle:=0.0;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
// Дальше звичайні для OpenGL дії, Створення вікна
procedure TForm1.FormCreate(Sender: TObject);
begin
Form1.PopupMenu:=PopupMenu1;
Angle:=0;
AngleX:=30;
AngleY:=0;
AngleZ:=0;
c:=1;
DC:=GetDC(Handle);
SetDCPixelFormat;
hrc:=wglCreateContext(DC);
wglMakeCurrent(DC, hrc);
InitializeRC;
// Визначаємо властивості матеріалу- лицьові сторони - розсіяні
// колір матеріалу і диффузне відбиття матеріалу - значення з масиву
glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, @MaterialColor);
end;
// Встановлення формату пікселів
procedure TForm1.SetDCPixelFormat;
var
nPixelFormat: integer;
pfd: TPixelFormatDescriptor;
begin
FillChar(pfd, SizeOf(pfd), 0);
with pfd do
begin
nSize :=sizeof(pfd);
nVersion:=1;
dwFlags :=PFD_DRAW_TO_WINDOW or PFD_SUPPORT_OPENGL or
PFD_DOUBLEBUFFER;
iPixelType:=PFD_TYPE_RGBA;
cColorBits:=24; // 24
cDepthBits:=32; // 32
iLayerType:= PFD_MAIN_PLANE;
end;
nPixelFormat := ChoosePixelFormat(DC, @pfd);
SetPixelFormat(DC, nPixelFormat, @pfd);
end;
// Зміна розмерів вікна
procedure TForm1.FormResize(Sender: TObject);
begin
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPerspective(30.0, Width/Height, 1.0, 10.0);
glViewport(0, 0, Width, Height);
glMatrixMode(GL_MODELVIEW);
InvalidateRect(Handle, nil, False);
end;
// Оброблення повідомлень WM_PAINT, малювання вікна
procedure TForm1.WMPaint(var Msg: TWMPaint);
var
ps: TPaintStruct;
begin
BeginPaint(Handle, ps);
DrawScene;
EndPaint(Handle, ps);
end;
// Кінець роботи програми
procedure TForm1.FormDestroy(Sender: TObject);
begin
Timer1.Enabled:=False;
wglMakeCurrent(0, 0);
wglDeleteContext(hrc);
ReleaseDC(Handle, DC);
end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char);
begin
if (key='x') then c:=1;
if (key='y') then c:=3;
if (key='z') then c:=5;
if (key='X') then c:=2;
if (key='Y') then c:=4;
if (key='Z') then c:=6;
if ord(key)=27 then Application.Terminate; // Esc
//
if key='h' then
begin
ShowHelp:=not(ShowHelp);
key:='g';
end;
//
FormResize(nil);
end;
procedure TForm1.Rotatespeed1Click(Sender: TObject);
begin
ch:=StrToInt(InputBox('Rotate','Sleep:','0'));
i:=1;
if Form1.CanFocus then Form1.SetFocus;
while i=1 do
case c of
1:
begin
AngleX:=AngleX-1.0;
if (AngleX>=90.0)
then AngleX:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
2:
begin
AngleX:=AngleX+1.0;
if (AngleX>=90.0)
then AngleX:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання(Windows API)
end;
3:
begin
AngleY:=AngleY-1.0;
if (AngleY>=90.0)
then AngleY:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
4:
begin
AngleY:=AngleY+1.0;
if (AngleY>=90.0)
then AngleY:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
5:
begin
AngleZ:=AngleZ-1.0;
if (AngleZ>=90.0)
then AngleZ:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
6:
begin
AngleZ:=AngleZ+1.0;
if (AngleZ>=90.0)
then AngleZ:=0.0;
Sleep(ch);
if Application.Terminated then Break;
Application.ProcessMessages;
InvalidateRect(Handle, nil, False); // перемалювання (Windows API)
end;
end;
end;
procedure TForm1.x1Click(Sender: TObject);
begin
c:=2;
end;
procedure TForm1.y1Click(Sender: TObject);
begin
c:=1;
end;
procedure TForm1.z1Click(Sender: TObject);
begin
c:=3;
end;
procedure TForm1.Z2Click(Sender: TObject);
begin
c:=6;
end;
procedure TForm1.X2Click(Sender: TObject);
begin
c:=4;
end;
procedure TForm1.Y2Click(Sender: TObject);
begin
c:=5;
end;
end.
Інформація користувачу
Коли ви відкриєте дану програму, ви побачите фіолетовий кубік, якого можна обертати за допомогою певних комбінацій.
/
Тоді натискаємо праву клавішу миші, щоб викликати меню.
/
За допомогою даного меню можна керувати кубом. Щоб даний куб почав крутитися, необхідно викликати Rotate speed, і задати певне значення. Чим більше значення – тим менша швидкість обертання. Пункти меню – це напрям обертання куба, а ±1 це додатня чи від’ємна вісь.
/
/
Висновок
OpenGL —специфікація, що визначає незалежний від мови програмування крос-платформовий програмний інтерфейс (API) для написання застосунків, що використовують 2D та 3D комп'ютерну графіку.
В даній розрахунковій роботі, я змоделювала об’єкт, куб, який обертається навколо осі. Також можна керувати кубом за допомогою контекстного меню.
Список використаної літератури
Сухарев М.В. Основы Делфи. изд-во "Наука и техника", С-П, 2004
Хомоненко А. и др. Делфи 7, С-П. "БХВ-Петербург", 2006
Галисеев Г.В. Компоненты в Делфи 7. изд-во "Диалектика", С-П, 2004
Ф.В. Левитин, Алгоритмы: введение в разработку и анализ, М.”Вильямс”, 2006.