Podstawy Informatyki
Grafika komputerowa i OpenGL
mgr inż. Piotr Kaczmarek
Podstawy grafiki – układ
współrzędnych
●
Obiekt ma parametry
opisane względem środka
symetrii, wtedy
współrzędne opisane
następującymi wartościami:
x
A
=-b/2;
y
A
=-a/2;
x
D
=b/2;
y
D
=a/2;
●
Prostokąt może być
opisany również za pomocą
współrzędnych 2
wierzchołków (A i D)
A(x
A
,y
A
)
B(x
B
,y
B
)
C(x
C
,y
C
)
D(x
D
,y
D
)
a
b
(0,0)
Podstawy grafiki - rotacja
●
Rotacja wokół środka
symetrii
x
A'
= cos(α) * x
A
– sin(α) * y
A
y
A'
= sin(α) * x
A
+ cos(α) * y
A
zapisując współrzędne jako
wektor o środku w środku
symetrii można napisać:
aa
A'
(x
A'
,y
A'
)
B'
(x
B'
,y
B'
)
C'
(x
C'
,y
C'
)
D'
(x
D'
,y
D'
)
b
(0,
0)
α
A(x
A
,y
A
)
[
x
A '
y
A '
]
=
[
cos sin
sin cos
]
∗
[
x
A
y
A
]
Podstawy grafiki - translacja
●
Translacja o wektor [x
c
y
c
]
x
A''
=x
A'
+x
c
y
A''
=y
A'
+y
c
aa
A'
(x
A'
,y
A'
)
b
(0
,0)
α
A(x
A
,y
A
)
aa
A'
'(x
A'
'
,y
A'
'
)
b
(x
C
,y
C
)
[
x
A ' '
y
A' '
]
=
[
x
C
y
C
]
[
x
A '
y
A'
]
Macierz transformacji
2D:
[
x
y
1
]
3D:
[
x
y
z
1
]
●
Wektor 2D i 3D:
2D:Trandx , dy=
[
1 0 dx
0 1 dy
0 0
1
]
3D: Trandx , dy , dz=
[
1 0 0 dx
0 1 0 dy
0 0 1 dz
0 0 0
1
]
●
Macierz translacji
2D: Rot =
[
c −s 0
s
c
0
0
0
1
]
3D: Rot
Z
=
[
c −s 0 0
s
c
0 0
0
0
1 0
0
0
0 1
]
●
Macierz rotacji:
Złożenia transformacji
●
Kolejność transformacji ma wpływ na wynik przekształcenia
A' =Trandx , dy ∗A
A' ' =Rot ∗A'
A' '=Trandx , dy∗Rot ∗A
A' =Rot ∗A
A' ' =Trandx , dy ∗A'
A' '= Rot ∗Trandx , dy∗A
A
A
A''
A'
A''
Kamera i rzutowanie
●
Obraz przedstawiany na ekranie, zdjęciu, rysunku jest płaski
●
Tworzy się go poprzez rzutowanie sceny widzianej przez „kamerę”
na płaszczyznę
●
Kamera posiadający niezerowy kat widzenia wprowadza perspektywę
●
Zmiana lokalizacji kamery pozwala uzyskać zmianę położenia obrazu
na ekranie (obrót, translację, kadrowanie)
●
Zmiana kata widzenia pozwala uzyskać efekt skalowania obiektów
(zmiana rozmiaru)
OpenGL - wprowadzenie
●
OpenGL jest biblioteką wykorzystywaną w celu tworzenia wysokiej
jakości obrazów złożonych pewnych:
–
prymitywów geometrycznych (tj. punktów, linii, wielokątów)
–
prymitywów obrazowych (bitmap, tekstur itp.)
–
źródeł światła, materiałów, kolorów
●
OpenGl jest niezależna od sprzętu oraz systemu operacyjnego
●
Większość współczesnych kart graficznych umożliwia wykonanie
komend biblioteki na procesorze karty graficznej, tym samym
zmniejsza obciążenie jednostki centralnej i przyspiesza operacje
graficzne
OpenGL - API
●
OpenGL może być
wykorzystywany
bezpośrednio w
programie lub też za
pośrednictwem innych
bibliotek takich jak
GLUT.
●
Efektem jest
wygenerowanie kodu
który może być
wykonany przez
procesor karty
graficznej lub sterownik
karty emulujący funkcje
OpenGL
OpenGL - prymitywy
●
Podstawowym elementem prymitywów geometrycznych jest
wierzchołek – Vertex. Prymityw określa sposób grupowania tych
wierzchołków
OpenGL – tworzenie
prymitywów
●
Prostokąt
void Prostokat(float a, float b)
{
GLfloat
red=1.0,green=0,blue=0;
glColor3f(red,green,blue);
glBegin(GL_POLYGON);
glVertex2f(-a/2,b/2);
glVertex2f(a/2,b/2);
glVertex2f(a/2,-b/2);
glVertex2f(-a/2,-b/2);
glEnd();
}
●
Okręg (przybliżony łamaną
złożoną z 36 odcinków)
void Okrag(float r)
{
glBegin(GL_LINE_LOOP);
for(float kat=0;kat<360;kat+=10)
{
GLfloat x,y;
x=r*cos(kat/180*3.14);
y=r*sin(kat/180*3.14);
glVertex2f(x,y);
}
glEnd();
}
OpenGL – glVertex
Typ współrzędnych oraz ilość współrzędnych definiowanego wierzchołka ma
wpływ na ilość pamięci która jest potrzebna do reprezentacji wierzchołka.
Przy scenach złożonych z wielu wierzchołków efekt jest znaczący
OpenGL – Transformacje
modelu
....
glMatrixMode(GL_MODELVIEW);//wybiera układ współrzędnych
modelu
glPushMatrix(); //zachowuje aktualna macierz transformacji
glLoadIdentity();//ustawia macierz transformacji jako jedynkową
(globalny układ współrzędnych)
glTranslatef(10.0,10.0,0);//przesuwa układ o wektor[10,10,0]
glRotatef(45,0.0,0.0,1.0); rotacja o 45
o
wokół wektora [0,0,1] – oś Z
Kwadrat(3,3); //tworzy kwadrat 3x3 o środku w punkcie 10,10 i kacie
obrotu 45
0
glPopMatrix(); //przywraca poprzednia macierz transformacji
OpenGL - Listy
●
OpenGL umożliwia na
definiowanie standardowych
fragmentów kodu, który
następnie może być
wywołany za pomocą
pojedynczego polecenia.
●
Fragment kodu dodawany jest
do tzw. listy i otrzymuje
określony index
●
Wywołanie listy (glCallList)
powoduje każdorazowe
wykonanie jej kodu w
aktualnej lokalizacji
GLuint ListaID; //identyfikator listy
// Przydziela nr ID
ListaID = glGenLists(1);
// tworzy liste (start)
glNewList(ListaID,GL_COMPILE);
Kwadrat(5,5);
Okrag(3);
// koniec listy
glEndList();
.....
for(int j=-3; j < 3; j++)
{
glPushMatrix();
glTranslatef(j*10.0,j * 10.0,0);
glCallList(ListaID); //rysuje obiekty
glPopMatrix();
}
OpenGL – kamera widok
ortogonalny (bez perspektywy)
glMatrixMode(GL_PROJECTION);//zmienia układ współrzędnych
na układ kamery
glLoadIdentyty();//przechodzi do globalnego układu kamery
glOrtho(x
min
,x
max
,y
min
,y
max
,-z
near
,-z
max
);
//ustawia kamerę w widoku bez perspektywy
oraz prostopadłościan tnący.
Oś optyczna kamery jest taka
jak oś OZ układu współrzędnych
kamery;
OpenGL – kamera widok z
perspektywą (1)
glMatrixMode(GL_PROJECTION);//zmienia układ współrzędnych
na układ kamery
glLoadIdentyty();//przechodzi do globalnego układu kamery
glPerspective(fov, aspect,z_min,zmax); //ustawia określony kat
widzenia kamery i jej aspekt (stosunek szerokości do wysokości
ekranu, oraz płaszczyznę tnącą ostrosłupa obrazu;
Oś optyczna kamery jest taka jak oś OZ
układu współrzędnych kamery;
glViewport(x
0
,y
0
,w,h);
//określa położenie lewego
narożnika oraz szerokość rzutni
OpenGL – kamera widok z
perspektywą (2)
glMatrixMode(GL_PROJECTION);//zmienia układ współrzędnych
na układ kamery
glLoadIdentyty();//przechodzi do globalnego układu kamery
glPerspective(kat_widzenia, aspekt,z_min,zmax);
glViewport(x,y,w,h);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glLookAt(eye
x
,eye
y
,eye
z
,
at
x
,at
y
,at
z
,
up
x
,up
y
,up
z
);
//ustawia położenie i orientację
kamery
OpenGL FrameBuffer i animacje
●
Prymitywy definiowane w
programie istnieją w 3D
przestrzeni modelu,
●
Obraz widziany przez kamerę (2D)
renderowany jest dopiero po
wymuszeniu tego procesu
●
Zrenderowany obraz
przechowywany jest we
FrameBuffer (FB)
●
System może mieć zdefiniowane
jeden albo 2 FB
●
Gdy wykorzystywane są 2 FB,
obraz renderowany jest najpierw w
niewyświetlanym FB, a następnie
FB są przełączane (swap) –
zwiększa to płynność animacji
GLUT - Instalacja
●
Jest nakładka na OpenGL
●
Pozwala na obsługę
klawiatury, myszy i innych
zdarzeń systemowych
●
Pozwala na prostą inicjację
OpenGL
●
Pozwala na tworzenie menu
●
Posiada funkcje tworzące
bryły oraz znaki
●
opis dołączenia biblioteki z
tutorialem:
●
plik glut.dll
skopiować do c:\Windows\System32
c:\Windows\
●
plik glut.lib
skopiować do:
C:\Program Files\Microsoft Visual Studio
8\VC\PlatformSDK\lib
●
plik glut.h
C:\Program Files\Microsoft Visual Studio
8 \VC \ PlatformSDK \ include
●
Ponadto do każdego projektu należy:
–
dołączyć bibliotekę
(proj.properties->linker->input):
opengl32.lib glut32.lib glu32.lib
–
oraz plik nagłówkowy glut.h
GLUT - Inicjacja
void main(int argc, char **argv) {
glutInit(&argc, argv);
//inicjuje OpenGl w trybie podwójnego FrameBuffera
glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);
//Tworzy okno 320x320
glutInitWindowPosition(100,100);
glutInitWindowSize(320,320);
glutCreateWindow("Przykladowy program");
//Rejestruje funkcje zdarzeń
glutDisplayFunc(Przerysuj);
glutReshapeFunc(ZmienRozmiarEkranu);
glutKeyboardFunc(Klawisz);
glutMainLoop();
}
GLUT – Obsługa zdarzeń
●
W celu obsługi zdarzeń
pochodzących z wielu źródeł
funkcja MainLoop odbiera
komunikaty systemowe i
wywołuje funkcje napisane przez
użytkownika
●
System generuje komunikaty o:
–
zdarzeniach związanych z
klawiaturą (wciśnięciu
klawisza)
–
zdarzeniach związanych z
myszy (ruchu myszki,
wciśnięciu/zwolnieniem
przycisku
–
zmianą rozmiaru okna
–
przesłonięciem,
koniecznością przerysowania
SYSTEM OPERACYJNY
Mysz
Klawiatura
Program
MainLoop
Mysz()
Klawisz()
Przerysuj()
komunikat
Obsługa zmiany rozmiaru
ekranu
●
Rejestracja
glutReshapeFunc(ZmienRozmiarEkranu);
●
Funkcja obsługi zdarzenia
void ZmienRozmiarEkranu(int w,int h)
{
float ratio = 1.0* w / h;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glViewport(0, 0, w, h);//ustalenie rzutni
gluPerspective(45,ratio,1,1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0.0,0.0,5.0, 0.0,0.0,-1.0, 0.0f,1.0f,0.0f);
}
Przerysowywanie ekranu
●
Rejestracja:
glutDisplayFunc(Przerysuj);
●
Funkcja obsługi zdarzenia:
void Przerysuj(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glColor3f(red,green,blue);
glBegin(GL_TRIANGLES);
glVertex3f(-0.5,-0.5,0.0);
glVertex3f(0.5,0.0,0.0);
glVertex3f(0.0,0.5,0.0);
glEnd();
glPopMatrix();
glutSwapBuffers();//wyświetlenie dla trybu z podwójnym
buforowaniem dla trybu bez podwójnego FB używa się glFlush();
}
Obsługa klawiatury
●
Rejestracja
glutKeyboardFunc(Klawisz);
●
Funkcja obsługi zdarzenia (wywoływana ilekroć użytkownik
wciśnie przycisk)
void Klawisz(unsigned char key, int x, int y)
{
switch(key)
{
case 27: //wcisnieto escape
exit(0);
case 'a': //zrob cos wcisnieto 'a'
break;
}
}
Obsługa myszki
●
Rejestracja
glutMouseFunc(Mysz); //obsługa wciśnięcia klawisza myszy
glutMotionFunc(processMouseActiveMotion);
//ruch myszy z wciśniętym przyciskiem
glutPassiveMotionFunc(processMousePassiveMotion); //ruch
myszy bez wciśniętych przycisków
glutEntryFunc(processMouseEntry); //funkcja wywoływana gdy
kursor wchodzi opuszcza obszar okna
Obsługa myszki
●
Funkcja obsługi wciśniętego przycisku
void Mysz(int button, int state, int x, int y)
{
specialKey = glutGetModifiers();
if (button == GLUT_LEFT_BUTTON)
{
....
}
else if (button == GLUT_MIDDLE_BUTTON)
{
....
}
}