OpenGL і Delphi практично
Далее в FormPaint використовуємо підготовлені заздалегідь методи DrawFace і DrawElement (див. лістинг нижче) для отрисовки цього об'єкту. Щодо надання йому більшої «спеки «використовуємо можливостей OpenGL з висвітлення сцени. Далее у вигляді виклику ChoosePixelFormat система вибирає підходящий формат пикселя — і ми привласнюємо його (через SetPixelFormat) нашому вікна. Теперь потрібно… Читати ще >
OpenGL і Delphi практично (реферат, курсова, диплом, контрольна)
OpenGL і Delphi на практике
Издательский Будинок «КОМИЗДАТ «
Любая теорія хороша, якщо може бути реалізована на Delphi :-). Тому пропоную одразу ж у довгу шухляду написати першу програму на OpenGL — і потім, окрылившись успіхом, повернутися до теорії та як слід простудіювати всі українські книжки і сайти по сабжу, щоб уже стати справжніми монстрами тривимірного моделювання.
Для початку доведеться проробити підготовчу роботу:
настроить формат пикселей з урахуванням відображуваної інформації;
создать контекст OpenGL і сам движок OpenGL на роботу.
Формат пикселей зручно винести на окрему процедуру, що її оформимо наступним чином:
procedure SetDCPixelFormat (dc: HDC);
var pfd: TPixelFormatDescriptor;
nPixelFormat: Integer;
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:= 16;
cDepthBits:= 64;
iLayerType:= PFD_MAIN_PLANE;
end;
nPixelFormat:=ChoosePixelFormat (DC,@pfd);
SetPixelFormat (DC, nPixelFormat,@pfd);
end;
Здесь під час заповнення структури TPixelFormatDescriptor ми задаємо параметри майбутнього графічного відображення, зокрема кількість колірних біт, і навіть тип пикселей (iPixelType). Ми також задаємо прапори, які, з назви, вказують, що наш програма підтримуватиме OpenGL, і навіть що ми малювати з вікна і використовувати подвійну буферизацію (параметр, необхідний відтворення рухомих об'єктів).
Далее у вигляді виклику ChoosePixelFormat система вибирає підходящий формат пикселя — і ми привласнюємо його (через SetPixelFormat) нашому вікна.
Теперь потрібно форматувати контекст самого OpenGL у вигляді функцій, що є в модулі Windows, і «зробити додаткову надстройку движка:
procedure TForm1. FormCreate (Sender: TObject);
begin.
H:=Handle;
DC:=GetDC (H);
SetDCPixelFormat (DC);
RC:=wglCreateContext (DC);
wglMakeCurrent (DC, RC);
glClearColor (0.6,0.6,0.6,1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1,1,-1,1,2,20);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
glTranslatef (0.0,-1.0,-6.0);
BeginPaint;
end;
Как бачимо, спочатку ми поставили нашій графіки необхідний формат пикселей. Тепер з допомогою функції wglCreateContext створюємо OpenGL-контекст, а згодом робимо його поточним контекстом. Далі, використовуючи вже універсальні функції**, зробимо настроювання «світу », який будемо створювати. І тому через glClearColor очистимо контекст і заповнимо її 60-процентным чорним. Далі виберемо матрицю проекцій, що визначає, як проектуватимуться тривимірні об'єкти на площину екрана (в віконні координати) і крізь glLoadIdentity встановимо одиничну матрицю і поставимо кордону плану в «світових координатах «з допомогою виклику glFrustum. Після цього завантажимо модельно видову матрицю і зробимо її (glTranslatef).
Что будемо рисовать
Конечно, можна було намалювати просту піраміду або ж куб. Але ми зробимо більше — намалюємо «любов міністра до «** (рис. 1). Спеціально для іноземних цього методом «наукового перебору «розробили модель, яка описувала відповідну криву:
.
Остается лише перевести її з мови математики на нормальний людський.
Прорисовка сцены
.
Подготовку сцени розпочнемо з підключення різних додаткових функцій, без яких подальша робота неможлива. Ці функції прописані в методі BeginPaint, а й у методі FormResize (щоб за зміну величини форми відповідно змінювався розмір об'єкта). І тому використовуємо функцію glEnable з відповідними параметрами.
Далее в FormPaint використовуємо підготовлені заздалегідь методи DrawFace і DrawElement (див. лістинг нижче) для отрисовки цього об'єкту. Щодо надання йому більшої «спеки «використовуємо можливостей OpenGL з висвітлення сцени.
Итог
С погляду складності освоєння OpenGL можна з іншими подібними бібліотеками. Отже з одного боку не має значення, у яких розбиратися І що вивчати. Але з погляду розумного підходу будь-який проект тривимірної графіки повинен принаймні підтримувати OpenGL як один з опцій. Адже серйозні речі не рахуються й визуализируются, зазвичай, під Unix/IRIX/Linux/FreeBSD, й те водночас було неправильним ігнорувати користувачів Windows. Отож OpenGL таки є тією універсальним розумом і загальним знаменником, що дозволяє вашим додатків вільно мігрувати з одного платформи на другую.
Листинг программы
Листинг.
========.
unit MainForm;
interface.
uses.
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,.
Dialogs, OpenGL, StdCtrls, ExtCtrls;
type.
TForm1 = class (TForm).
Timer1: TTimer;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
procedure FormCreate (Sender: TObject);
procedure FormDestroy (Sender: TObject);
procedure Timer1Timer (Sender: TObject);
procedure FormPaint (Sender: TObject);
procedure FormResize (Sender: TObject);
private.
RC:HGLRC;
DC:HDC;
H:THandle;
procedure BeginPaint;
{ Private declarations }.
public.
{ Public declarations }.
end;
var.
Form1: TForm1;
const mat1_dif:Array[0.2] of Single = (0.8,0.8,0.0);
const mat1_amb:Array[0.2] of Single = (0.2,0.2,0.2);
const mat1_spec:Array[0.2] of Single = (0.6,0.6,0.6);
const mat1_shininess = 0.5*128;
procedure DrawElement (A, b, R0,r1:Single);
procedure DrawFace (A, R: Single;Normal:Boolean);
implementation.
procedure SetDCPixelFormat (dc:HDC);
var pfd: TPixelFormatDescriptor;
nPixelFormat:Integer;
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:= 16;
cDepthBits:= 64;
iLayerType:= PFD_MAIN_PLANE;
end;
nPixelFormat:=ChoosePixelFormat (DC,@pfd);
SetPixelFormat (DC, nPixelFormat,@pfd);
end;
procedure TForm1. BeginPaint;
begin.
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glEnable (GL_NORMALIZE);
glEnable (GL_COLOR_MATERIAL);
timer1.enabled:=true;
end;
{$R *.dfm}.
procedure TForm1. FormCreate (Sender: TObject);
begin.
H:=Handle;
DC:=GetDC (H);
SetDCPixelFormat (DC);
RC:=wglCreateContext (DC);
wglMakeCurrent (DC, RC);
glClearColor (0.6,0.6,0.6,1.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1,1,-1,1,2,20);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
glTranslatef (0.0,-1.0,-6.0);
BeginPaint;
end;
procedure TForm1. FormDestroy (Sender: TObject);
begin.
wglMakeCurrent (0,0);
wglDeleteContext (RC);
ReleaseDC (H, DC);
DeleteDC (DC);
end;
procedure TForm1. Timer1Timer (Sender: TObject);
begin.
glRotatef (4.0,0.0,1.0,0.0);
SwapBuffers (DC);
InvalidateRect (H, nil, False);
end;
procedure DrawElement (a, b, r0,r1:Single);
var x1b, y1b: Single;
x1e, y1e: Single;
x0b, y0b: Single;
x0e, y0e: Single;
t0,t1:Single;
dt:single;
begin.
t0:=-3;t1:=3;
dt:=0.06;
while t0<=t1 do.
begin.
x0b:=a*sin (t0)*sin (t0)*sin (t0)*sin (t0)*cos (t0);
y0b:=a*abs (sin (t0)*cos (t0));
x0e:=a*sin (t0+dt)*sin (t0+dt)*sin (t0+dt)*sin (t0+dt)*cos (t0+dt);
y0e:=a*abs (sin (t0+dt)*cos (t0+dt));
x1b:=b*sin (t0)*sin (t0)*sin (t0)*sin (t0)*cos (t0);
y1b:=b*abs (sin (t0)*cos (t0));
x1e:=b*sin (t0+dt)*sin (t0+dt)*sin (t0+dt)*sin (t0+dt)*cos (t0+dt);
y1e:=b*abs (sin (t0+dt)*cos (t0+dt));
glBegin (GL_TRIANGLE_STRIP);
glNormal ((x0b+x1e)/2,(y0b+y1e)/2,(r1+r0)/2);
glVertex3f (x0b, y0b, r0);
glVertex3f (x0e, y0e, r0);
glVertex3f (x1e, y1e, r1);
glVertex3f (x1b, y1b, r1);
glEnd;
t0:=t0+dt;
end;
end;
procedure DrawFace (A, R: Single;Normal:Boolean);
var x, y: single; t0, t1,dt:Single;
begin.
t0:=-3;t1:=3;
dt:=0.06;
glBegin (GL_POLYGON);
while t0<=t1 do.
begin.
x:=a*sin (t0)*sin (t0)*sin (t0)*sin (t0)*cos (t0);
y:=a*abs (sin (t0)*cos (t0));
glVertex3F (x, y, r);
t0:=t0+dt;
end;
t0:=0;
x:=a*sin (t0)*sin (t0)*sin (t0)*sin (t0)*cos (t0);
y:=a*abs (sin (t0)*cos (t0));
if Normal then glNormal3f (x, y,-r) else glNormal3f (x, y, r);
glEnd;
end;
procedure TForm1. FormPaint (Sender: TObject);
var m, n: single;dm:Single;a:Single;df:Single;
begin.
a:=25;
df:=10;
glClear (GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glColor (1.0,0.0,0.0,0.0);
glMaterialfv (GL_FRONT, GL_AMBIENT,@mat1_amb);
glMaterialfv (GL_FRONT, GL_DIFFUSE,@mat1_dif);
glMaterialfv (GL_FRONT, GL_SPECULAR,@mat1_spec);
glMaterialf (GL_FRONT, GL_SHININESS, mat1_shininess);
m:=-1;n:=1;dm:=0.5;
while m<=n do.
begin.
DrawElement (Sqrt (a-m*m), Sqrt (a-(m+dm)*(m+dm)), m/df,(m+dm)/df);
m:=m+dm;
end;
DrawFace (Sqrt (a-(m)*(m)); INSERT INTO `ref` (`id_predmet`, `name_predmet`, `id_ref`, `name_ref`, `text_ref`) VALUES (m)/df, True);
m:=-1;
DrawFace (Sqrt (a-(m)*(m)); INSERT INTO `ref` (`id_predmet`, `name_predmet`, `id_ref`, `name_ref`, `text_ref`) VALUES (m)/df, True);
end;
procedure TForm1. FormResize (Sender: TObject);
const lm: Array[0.3] of Single = (0.5,0.5,0.5,1.0);
const.
light_ambient:array[0.3] of glfloat = (0.0,0.0,0.0,1.0);
light_diffuse:array[0.3] of glfloat = (1.0,1.0,1.0,1.0);
light_specular:array[0.3] of glfloat = (2.0,2.0,2.0,1.0);
light_position:array[0.3] of glfloat = (2.0,1.0,3.0,1.0);
light_emission:array[0.3] of glfloat = (1.0,1.0,1.0,1.0);
light_spotdirection:array[0.3] of glfloat = (1.0,1.0,1.0,1.0);
begin.
wglMakeCurrent (0,0);
wglDeleteContext (RC);
ReleaseDC (H, DC);
DC:=GetDC (H);
SetDCPixelFormat (DC);
RC:=wglCreateContext (DC);
wglMakeCurrent (DC, RC);
glClearColor (0.6,0.6,0.6,0.0);
glMatrixMode (GL_PROJECTION);
glLoadIdentity;
glFrustum (-1,1,-1,1,2,20);
glMatrixMode (GL_MODELVIEW);
glLoadIdentity;
glTranslatef (0.0,-1.0,-6.0);
glLightModel (GL_LIGHT_MODEL_LOCAL_VIEWER, Ord (True));
glLightModelfv (GL_LIGHT_MODEL_AMBIENT,@lm);
glLightfv (GL_LIGHT0,GL_AMBIENT,@light_ambient);
glLightfv (GL_LIGHT0,GL_DIFFUSE,@light_diffuse);
glLightfv (GL_LIGHT0,GL_SPECULAR,@light_specular);
glLightfv (GL_LIGHT0,GL_POSITION,@light_position);
glLightf (GL_LIGHT0,GL_SPOT_EXPONENT, 8);
glLightf (GL_LIGHT0,GL_SPOT_CUTOFF, 170);
glLightfv (GL_LIGHT0,GL_SPOT_DIRECTION,@light_spotdirection);
glEnable (GL_LIGHTING);
glEnable (GL_LIGHT0);
glEnable (GL_DEPTH_TEST);
glEnable (GL_NORMALIZE);
glEnable (GL_COLOR_MATERIAL);
end;
end.
Список литературы
Для підготовки даної праці були використані матеріали із сайту internet.