background image

Podstawy Informatyki

Grafika komputerowa i OpenGL

mgr inż. Piotr Kaczmarek

Piotr.Kaczmarek@put.poznan.pl

background image

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)

background image

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

]

background image

Podstawy grafiki - translacja

Translacja o wektor [x

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'

]

background image

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 =

[

 − 0

0

0

0

1

]

3D: Rot

Z

=

[

 − 0 0

0 0

0

0

1 0

0

0

0 1

]

Macierz rotacji: 

background image

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''

background image

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)

background image

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

background image

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

background image

OpenGL - prymitywy

Podstawowym elementem prymitywów geometrycznych jest 
wierzchołek – Vertex. Prymityw określa sposób grupowania tych 
wierzchołków

background image

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();

}

background image

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

background image

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

background image

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();
}

background image

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;

background image

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

background image

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

background image

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

background image

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:

Tutorial - Glut

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

background image

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();
}

background image

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

background image

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);
}

background image

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();

}

background image

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;

}
}

background image

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

background image

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) 
{

....

}

}