Janusz Ganczarski
OpenGL
Przekształcenia geometryczne
Spis treści
Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1. Przekształcenia geometryczne . . . . . . . . . . . . . . . . . . . . . . 1
1.1. Obrót . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Skalowanie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3. Przesunięcie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.4. Mnożenie macierzy . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.5. Aadowanie macierzy . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.6. Składanie przekształceń . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6.1. Kula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6.2. Sześcian . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6.3. Stożek . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.6.4. Torus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.6.5. Dwunastościan . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.6. Czajnik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.7. Ośmiościan . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.6.8. Czworościan . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.9. Dwudziestościan . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.10. Obsługa myszki . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.6.11. Menu wielopoziomowe . . . . . . . . . . . . . . . . . . . . . . 8
1.6.12. Odrysowanie okna . . . . . . . . . . . . . . . . . . . . . . . . 8
1.6.13. Plik przeksztalcenia.cpp . . . . . . . . . . . . . . . . . . . . . 8
1.7. Stos macierzy modelowania . . . . . . . . . . . . . . . . . . . . . . . 14
1.7.1. Operacje na stosie . . . . . . . . . . . . . . . . . . . . . . . . 14
1.7.2. Plik stos modelowania.cpp . . . . . . . . . . . . . . . . . . . 16
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1. Przekształcenia geometryczne
W tym odcinku kursu poznamy mechanizmy biblioteki OpenGL umoż-
liwiające dowolne przekształcenia geometryczne obiektów. Wykorzystamy
także stos macierzy w celu modelowania sceny 3D zawierającej wiele ele-
mentów.
1.1. Obrót
Obrót w OpenGL wykonują funkcjeglRotatediglRotatef:
void glRotated (GLdouble angle,
GLdouble x, GLdouble y, GLdouble z)
void glRotatef (GLfloat angle,
GLfloat x, GLfloat y, GLfloat z)
których parametry oznaczają:
angle- kÄ…t obrotu w stopniach,
x,y,z- współrzędne wektora określającego oś obrotu.
Obrót realizowany jest w kierunku przeciwnym do ruchu wskazówek zega-
ra w kierunku prostej wyznaczonej przez wektor [x, y, z] zaczepionym w po-
czątku układu współrzędnych. Jeżeli wektor ma długość różną od 1 wektor
jest normalizowany.
FunkcjeglRotatediglRotatefmnożą bieżącą macierz przez przez ma-
cierz obrotu, która ma następującą postać (parametr angle zamieniono
naa):
ëÅ‚ öÅ‚
x2 (1 - cos a) + cos a xy (1 - cos a) - z sin a xz (1 - cos a) + y sin a 0
ìÅ‚ ÷Å‚
yx (1
ìÅ‚ - cos a) + z sin a y2 (1 - cos a) + cos a yz (1 - cos a) - x sin a 0
÷Å‚
ìÅ‚ ÷Å‚
íÅ‚ xz (1 - cos a) - y sin a yz (1 - cos a) + x sin a z2 (1 - cos a) + cos a 0 Å‚Å‚
0 0 0 1
1.2. Skalowanie
Skalowanie wykonują następujące funkcje:
void glScalef (GLfloat x, GLfloat y, GLfloat z)
void glScalex (GLfixed x, GLfixed y, GLfixed z)
gdziex,y,zsą współczynnikami skalowania względem kolejnych osi układu
współrzędnych. Funkcje te mnożą bieżącą macierz przez macierz skalowania,
która ma postać:
ëÅ‚ öÅ‚
x 0 0 0
ìÅ‚ ÷Å‚
0 y 0 0
ìÅ‚ ÷Å‚
ìÅ‚ ÷Å‚
íÅ‚ 0 0 z 0 Å‚Å‚
0 0 0 1
1. Przekształcenia geometryczne 2
1.3. Przesunięcie
Trzecią z podstawowych operacji geometrycznych jest przesunięcie o wek-
tor (transalcja), którą realizuja funkcje:
void glTranslatef (GLfloat x, GLfloat y, GLfloat z)
void glTranslatex (GLfixed x, GLfixed y, GLfixed z)
gdziex,y,zsą współrzędnymi wektora przesunięcia. Podobnie jak poprzed-
nio opisane funkcje,glTranslatefiglTranslatexmnożą bieżącą macierz
przez macierz translacji, która ma postać:
ëÅ‚ öÅ‚
1 0 0 x
ìÅ‚ ÷Å‚
0 1 0 y
ìÅ‚ ÷Å‚
ìÅ‚ ÷Å‚
íÅ‚ 0 0 1 z Å‚Å‚
0 0 0 1
1.4. Mnożenie macierzy
W przypadku, gdy zestaw standardowych przekształceń macierzowych
okazuje się niewystarczający, biblioteka OpenGL udostępnia możliwość prze-
mnożenia bieżącej macierzy przez macierz określoną funkcją z grupyglMult-
Matrix:
void glMultMatrixd (const GLdouble *m)
void glMultMatrixf (const GLfloat *m)
Parametrmobu funkcji zawiera wskaznik na dane macierzy o rozmia-
rach 4 × 4, które muszÄ… być uÅ‚ożone kolejno kolumnami, tj. w kolejnoÅ›ci
transponowanej w stosunku do przyjętej w językach C i C++:
ëÅ‚ öÅ‚
a0 a4 a8 a12
ìÅ‚
a1 a5 a9 a13 ÷Å‚
ìÅ‚ ÷Å‚
ìÅ‚ ÷Å‚
íÅ‚ a2 a6 a10 a14 Å‚Å‚
a3 a7 a11 a15
1.5. Aadowanie macierzy
Ostatnią z opisywanych operacji na macierzach jest zastępowanie bieżą-
cej macierzy przez dowolnie okreÅ›lonÄ… macierz o rozmiarach 4 × 4. OperacjÄ™
tÄ™ wykonujÄ… funkcje z grupyglLoadMatrix:
void glLoadMatrixd (const GLdouble *m)
void glLoadMatrixf (const GLfloat *m)
Format danych Å‚adowanej macierzy jest taki sam jak w przedstawionych
wyżej funkcjachglMultMatrixdiglMultMatrixf.
1. Przekształcenia geometryczne 3
1.6. Składanie przekształceń
Macierzowy opis przekształceń geometrycznych znacznie ułatwia skła-
danie kilku różnych przekształceń obiektów. Wywołując funkcje generujące
macierze odpowiednich przekształceń dokonujemy jednocześnie ich składa-
nia. W tej sytuacji jedyną rzeczą, o której należy pamiętać, to kolejność
przekształceń, bowiem od tego zależy końcowy efekt.
Przykładowy program (plikprzeksztalcenia.cpp) przedstawia prze-
kształcenia geometryczne dostępne w bibliotece OpenGL. Scena 3D zawiera
pojedynczy obiekt geometryczny zawarty w bibliotece GLUT. Klawisze kur-
sora pozwalają na obracanie wyświetlanego obiektu, przyciski + i - na
jego skalowanie, a lewy przycisk myszki przesuwa obiekt. W ramach ekspe-
rymentu Czytelnik może w programie zamienić kolejność składania wyko-
nywanych tam przekształceń (funkcjaDisplay) np. przesunięcia i obrotu.
Poznajmy jeszcze nowe elementy biblioteki GLUT wykorzystanie w przy-
kładowym programie tj. sposób obsługi myszki i zdefiniowane obiekty geo-
metryczne. Biblioteka GLUT udostępnia obiekty 3D w wersji szkieletowej
(tzw. druciaki ) oraz w wersji pełnej. W najbliższych przykładowych pro-
gramach wykorzystamy wersje szkieletowe obiektów.
1.6.1. Kula
Powierzchnia kuli rysowana jest jako szkielet składający się z południków
i równoleżników (rysunek 1). Powierzchnię kuli, której środek znajduje się
w początku układu współrzędnych rysuje funkcja:
void glutWireSphere (GLdouble radius, GLint slices, GLint stacks)
której parametry oznaczają:
radius- promień kuli,
slices- ilość południków,
stacks- ilość równoleżników.
1.6.2. Sześcian
Sześcian o boku długościsizei środku położonym w początku układu
współrzędnych rysuje funkcja:
void glutWireCube (GLdouble size)
1.6.3. Stożek
Stożek rysowany jest podobnie jak kula - jako szkielet oparty na równo-
ległe do podstawy południki i tworzące biegnące od wierzchołka stożka do
krawędzi jego podstawy (rysunek 2). Stożek ze środkiem podstawy umiesz-
czonym w początku układu współrzędnych i wierzchołkiem umieszczonym
na dodatniej półosi OZ rysuje funkcja:
1. Przekształcenia geometryczne 4
Rysunek 1. Program Przekształcenia - kula
void glutWireCone (GLdouble base, GLdouble height,
GLint slices, GLint stacks)
której parametry oznaczają:
base- promień podstawy stożka,
height- wysokość stożka,
slices- ilość tworzących,
stacks- ilość południków .
1.6.4. Torus
Kolejna bryłą obrotową dostępną w bibliotece GLUT jest torus rysowany
jako seria walców o nierównoległych podstawach (rysunek 3) i osi obrotu
pokrywajÄ…cej siÄ™ z osiÄ… OZ. Torus rysuje funkcja:
void glutWireTorus (GLdouble innerRadius, GLdouble outerRadius,
GLint sides, GLint rings)
której parametry oznaczają odpowiednio:
innerRadius- promień koła tworzącego torus,
outerRadius- promień torusa,
1. Przekształcenia geometryczne 5
Rysunek 2. Program Przekształcenia - stożek
sides- ilość ścian bocznych, z których składa się pojedynczy walec,
rings- ilość walców, z których składa się torus.
1.6.5. Dwunastościan
Dwunastościan o środku położonym w początku układu współrzędnych
rysuje funkcja:
void glutWireDodecahedron (void)
1.6.6. Czajnik
Klasycznym obiektem 3D dostępnym w bibliotece GLUT jest opracowa-
ny w 1975 roku przez Martina Newella czajnik - przedstawiony na rysunku 4.
Czajnik o wielkości regulowanej parametremsizerysuje funkcja:
void glutWireTeapot (GLdouble size)
1.6.7. Ośmiościan
Ośmiościan o środku położonym w początku układu współrzędnych ry-
suje funkcja:
1. Przekształcenia geometryczne 6
Rysunek 3. Program Przekształcenia - torus
void glutWireOctahedron (void)
1.6.8. Czworościan
Czworościan o środku położonym w początku układu współrzędnych ry-
suje funkcja:
void glutWireTetrahedron (void)
1.6.9. Dwudziestościan
Dwudziestościan o środku położonym w początku układu współrzędnych
rysuje funkcja:
void glutWireIcosahedron (void)
1.6.10. Obsługa myszki
Obsługa myszki składa się z dwóch etapów i jest wykonywana przez dwie
funkcje. Pierwsza z nich to:
void MouseButton (int button, int state, int x, int y)
1. Przekształcenia geometryczne 7
Rysunek 4. Program Przekształcenia - czajnik
która wykrywa naciśnięcie i zwolnienie lewego przycisku myszki. W zależ-
ności od stanu lewego przycisku myszki ustawiana jest wartość zmiennej
globalnejbuttonstatena przekazanÄ… przez parametrstate. Druga funk-
cja:
void MouseMotion (int x, int y)
wywoływana jest podczas ruchu kursora myszki a jej zadaniem jest odpo-
wiednie (dobrane częściowo doświadczalnie) przeliczenie ruchu myszki na
przesunięcie obiektu znajdującego się na scenie. Efekt przeliczeń ruchu kur-
sora myszki umieszczony jest w zmiennych globalnychtranslatexitrans-
latey, które są bezpośredni przekazywane jako parametry funkcjiglTrans-
latef.
Parametryxiyobu funkcji oznaczają współrzędne kursora myszki w od-
niesieniu do układu współrzędnych okna, które oczywiście nie mają nic
wspólnego ze współrzędnymi określonymi w scenie 3D. Parametrbutton
funkcjiMouseButtonokreśla który przycisk myszki został naciśnięty lub
zwolniony. Parametr ten przyjmuje jedną z wartości:
GLUTLEFTBUTTON- lewy przycisk myszki,
1. Przekształcenia geometryczne 8
GLUTMIDDLEBUTTON- środkowy przycisk myszki,
GLUTRIGHTBUTTON- prawy przycisk myszki.
Jeżeli w danym systemie myszka ma tylko dwa przyciski, wartośćGLUTMID-
DLEBUTTONnie będzie generowana. Natomiast w przypadku myszki z jed-
nym przyciskiem funkcja generuje jedynie wartośćGLUTLEFTBUTTON. Ostat-
ni nieopisany parametr funkcjiMouseButtontostate, który określa czy
przycisk myszki został naciśnięty (stałaGLUTUP) czy zwolniony (stałaGLUT-
DOWN).
Aby opisane funkcje obsługi myszki działały należy je dołączyć do listy
funkcji zwrotnych wywołując odpowiednio:
void glutMouseFunc (void (*func)(int button, int state,
int x, int y))
void glutMotionFunc (void (*func)(int x, int y))
1.6.11. Menu wielopoziomowe
W programie został użyty nowy element biblioteki GLUT wielopo-
ziomowe menu podręczne. Część menu podręcznego, które będzie znajdo-
wało się na drugim (lub wyższym) poziomie tworzymy w taki sam spo-
sób jak dotychczas tworzyliśmy główne menu, czyli przy użyciu funkcji
glutCreateMenuiglutAddMenuEntry. Tak utworzorzony fragment menu
umieszczamy w menu głównym (nadrzędnym) używając funkcji:
void glutAddSubMenu (const char *label, int submenu)
Parametrlabelokreśla nazwę menu podręcznego, asubmenujego identyfi-
kator zwrócony przez funkcjęglutCreateMenu.
1.6.12. Odrysowanie okna
Aby zmiany sceny 3D zostały wyświetlone na ekranie potrzebne jest
odrysowanie bieżącego okna. Można to zrealizować wywołując funkcję:
void glutPostRedisplay (void)
1.6.13. Plik przeksztalcenia.cpp
/"
( c ) J a n u s z G a n c z a r s k i
h t t p : / / www . j a n u s z g . hg . p l
J a nu s zG @ e nter . n e t . p l
"/
#include
#include < s t d l i b . h>
// s t a Å‚ e do o b s Å‚ u g i menu p o d r Ä™ c z n e g o
enum
{
FULL WINDOW, // a s p e k t o b r a z u - c a Å‚ e okno
ASPECT 1 1 , // a s p e k t o b r a z u 1 : 1
WIRE SPHERE, // k u l a
1. Przekształcenia geometryczne 9
WIRE CONE, // s t o ż e k
WIRE CUBE, // s z e Å› c i a n
WIRE TORUS, // t o r u s
WIRE DODECAHEDRON, // d w u n a s t o Å› c i a n
WIRE TEAPOT, // c z a j n i k
WIRE OCTAHEDRON, // o Å› m i o Å› c i a n
WIRE TETRAHEDRON, // c z w o r o Å› c i a n
WIRE ICOSAHEDRON, // d w u d z i e s t o Å› c i a n
EXIT // w y j Å› c i e
} ;
// a s p e k t o b r a z u
i n t a s p e c t = FULL WINDOW;
// r o d z a j o b i e k t u
i n t o b j e c t = WIRE SPHERE ;
// r o z m i a r y b r y Å‚ y o b c i n a n i a
const GLdouble l e f t = -1 0. 0;
const GLdouble r i g h t = 1 0 . 0 ;
const GLdouble bottom = - 10 .0 ;
const GLdouble top = 1 0 . 0 ;
const GLdouble n e a r = 5 0 . 0 ;
const GLdouble f a r = 7 0 . 0 ;
// w s p ó ł c z y n n i k s k a l o w a n i a
G L f l o a t s c a l e = 1 . 0 ;
// k Ä… t y o b r o t u
G L f l o a t r o t a t e x = 0 . 0 ;
G L f l o a t r o t a t e y = 0 . 0 ;
// p r z e s u n i Ä™ c i e
G L f l o a t t r a n s l a t e x = 0 . 0 ;
G L f l o a t t r a n s l a t e y = 0 . 0 ;
// w s k a z n i k n a c i Å› n i Ä™ c i a l e w e g o p r z y c i s k u m y s z k i
i n t b u t t o n s t a t e = GLUT UP ;
// p o ł o ż e n i e k u r s o r a m y s z k i
i n t b u t t o n x , b u t t o n y ;
// f u n k c j a g e n e r u j Ä… c a s c e n Ä™ 3D
void D i s p l a y ( )
{
// k o l o r t ł a - z a w a r t o ś ć b u f o r a k o l o r u
g l C l e a r C o l o r ( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
// c z y s z c z e n i e b u f o r a k o l o r u
g l C l e a r (GL COLOR BUFFER BIT ) ;
// wyb ór m a c i e r z y m o d e l o w a n i a
glMatrixMode (GL MODELVIEW ) ;
// m a c i e r z m o d e l o w a n i a = m a c i e r z j e d n o s t k o w a
g l L o a d I d e n t i t y ( ) ;
// p r z e s u n i ę c i e u k ł a d u w s p ó ł r z ę d n y c h o b i e k t u do ś r o d k a b r y ł y o d c i n a n i a
g l T r a n s l a t e f ( 0 , 0 , - ( n e a r+f a r ) / 2 ) ;
// p r z e s u n i Ä™ c i e o b i e k t u - r u c h myszkÄ…
g l T r a n s l a t e f ( t r a n s l a t e x , t r a n s l a t e y , 0 . 0 ) ;
// s k a l o w a n i e o b i e k t u - k l a w i s z e + i -
g l S c a l e f ( s c a l e , s c a l e , s c a l e ) ;
// o b r o t y o b i e k t u - k l a w i s z e k u r s o r a
g l R o t a t e f ( r o t a t e x , 1 . 0 , 0 , 0 ) ;
g l R o t a t e f ( r o t a t e y , 0 , 1 . 0 , 0 ) ;
// k o l o r k r a w Ä™ d z i o b i e k t u
1. Przekształcenia geometryczne 10
g l C o l o r 3 f ( 0 . 0 , 0 . 0 , 0 . 0 ) ;
// r y s o w a n i e o b i e k t u
switch ( o b j e c t )
{
// k u l a
case WIRE SPHERE :
g l u t W i r e S p h e r e ( 1 . 0 , 2 0 , 1 0 ) ;
break ;
// s t o ż e k
case WIRE CONE :
glutWireCone ( 1 . 0 , 2 . 0 , 2 0 , 1 0 ) ;
break ;
// s z e Å› c i a n
case WIRE CUBE :
glutWireCube ( 1 . 0 ) ;
break ;
// t o r u s
case WIRE TORUS :
g l u t W i r e T o r u s ( 0 . 2 , 1 , 1 0 , 2 0 ) ;
break ;
// d w u n a s t o Å› c i a n
case WIRE DODECAHEDRON:
gl utW ireDo de c ah ed r on ( ) ;
break ;
// c z a j n i k
case WIRE TEAPOT :
g l u t W i r e T e a p o t ( 1 . 0 ) ;
break ;
// o Å› m i o Å› c i a n
case WIRE OCTAHEDRON:
g l u t W i r e O c t a h e d r o n ( ) ;
break ;
// c z w o r o Å› c i a n
case WIRE TETRAHEDRON:
g l u t W i r e T e t r a h e d r o n ( ) ;
break ;
// d w u d z i e s t o Å› c i a n
case WIRE ICOSAHEDRON :
g l u t W i r e I c o s a h e d r o n ( ) ;
break ;
}
// s k i e r o w a n i e p o l e c e Å„ do w y k o n a n i a
g l F l u s h ( ) ;
// zamiana b u f o r ó w k o l o r u
g l u t S w a p B u f f e r s ( ) ;
}
// zmiana w i e l k o Å› c i okna
void Reshape ( i n t width , i n t h e i g h t )
{
// o b s z a r r e n d e r i n g u - c a Å‚ e okno
g l V i e w p o r t ( 0 , 0 , width , h e i g h t ) ;
// wyb ór m a c i e r z y r z u t o w a n i a
glMatrixMode (GL PROJECTION ) ;
// m a c i e r z r z u t o w a n i a = m a c i e r z j e d n o s t k o w a
g l L o a d I d e n t i t y ( ) ;
// p a r a m e t r y b r y Å‚ y o b c i n a n i a
i f ( a s p e c t == ASPECT 1 1 )
{
// w y s o k o ś ć okna w i ę k s z a od w y s o k o ś c i okna
i f ( width < h e i g h t && width > 0 )
glFrustum ( l e f t , r i g h t , bottom " h e i g h t / width , top " h e i g h t / width , near , f a r ) ;
e l s e
// s z e r o k o ś ć okna w i ę k s z a l u b równa w y s o k o ś c i okna
1. Przekształcenia geometryczne 11
i f ( width >= h e i g h t && h e i g h t > 0 )
glFrustum ( l e f t " width / h e i g h t , r i g h t " width / h e i g h t , bottom , top , near , f a r ) ;
}
e l s e
glFrustum ( l e f t , r i g h t , bottom , top , near , f a r ) ;
// g e n e r o w a n i e s c e n y 3D
D i s p l a y ( ) ;
}
// o b s Å‚ u g a k l a w i a t u r y
void Keyboard ( unsigned char key , i n t x , i n t y )
{
// k l a w i s z +
i f ( key == + )
s c a l e += 0 . 1 ;
e l s e
// k l a w i s z -
i f ( key == - && s c a l e > 0 . 1 )
s c a l e -= 0 . 1 ;
// o d r y s o w a n i e okna
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
}
// o b s Å‚ u g a k l a w i s z y f u n k c y j n y c h i k l a w i s z y k u r s o r a
void S p e c i a l K e y s ( i n t key , i n t x , i n t y )
{
switch ( key )
{
// k u r s o r w l e w o
case GLUT KEY LEFT :
r o t a t e y -= 1 ;
break ;
// k u r s o r w g ó r ę
case GLUT KEY UP :
r o t a t e x -= 1 ;
break ;
// k u r s o r w prawo
case GLUT KEY RIGHT :
r o t a t e y += 1 ;
break ;
// k u r s o r w d ó ł
case GLUT KEY DOWN:
r o t a t e x += 1 ;
break ;
}
// o d r y s o w a n i e okna
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
}
// o b s ł u g a p r z y c i s k ó w m y s z k i
void MouseButton ( i n t button , i n t s t a t e , i n t x , i n t y )
{
i f ( bu t to n == GLUT LEFT BUTTON)
{
// z a p a m i Ä™ t a n i e s t a n u l e w e g o p r z y c i s k u m y s z k i
b u t t o n s t a t e = s t a t e ;
// z a p a m i ę t a n i e p o ł o ż e n i a k u r s o r a m y s z k i
i f ( s t a t e == GLUT DOWN)
{
b u t t o n x = x ;
b u t t o n y = y ;
}
}
}
// o b s Å‚ u g a r u c h u k u r s o r a m y s z k i
void MouseMotion ( i n t x , i n t y )
{
1. Przekształcenia geometryczne 12
i f ( b u t t o n s t a t e == GLUT DOWN)
{
t r a n s l a t e x += 1 . 1 "( r i g h t - l e f t ) / g l u t G e t (GLUT WINDOW WIDTH) " ( x - b u t t o n x ) ;
b u t t o n x = x ;
t r a n s l a t e y += 1 . 1 "( top - bottom ) / g l u t G e t (GLUT WINDOW HEIGHT) " ( b u t t o n y - y ) ;
b u t t o n y = y ;
g l u t P o s t R e d i s p l a y ( ) ;
}
}
// o b s Å‚ u g a menu p o d r Ä™ c z n e g o
void Menu ( i n t v a l u e )
{
switch ( v a l u e )
{
// o b s z a r r e n d e r i n g u - c a Å‚ e okno
case FULL WINDOW:
a s p e c t = FULL WINDOW;
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
break ;
// o b s z a r r e n d e r i n g u - a s p e k t 1 : 1
case ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
break ;
// k u l a
case WIRE SPHERE :
o b j e c t = WIRE SPHERE ;
D i s p l a y ( ) ;
break ;
// c y l i n d e r
case WIRE CONE :
o b j e c t = WIRE CONE ;
D i s p l a y ( ) ;
break ;
// s z e Å› c i a n
case WIRE CUBE :
o b j e c t = WIRE CUBE ;
D i s p l a y ( ) ;
break ;
// t o r u s
case WIRE TORUS :
o b j e c t = WIRE TORUS ;
D i s p l a y ( ) ;
break ;
// d w u n a s t o Å› c i a n
case WIRE DODECAHEDRON:
o b j e c t = WIRE DODECAHEDRON;
D i s p l a y ( ) ;
break ;
// c z a j n i k
case WIRE TEAPOT :
o b j e c t = WIRE TEAPOT ;
D i s p l a y ( ) ;
break ;
// o Å› m i o Å› c i a n
case WIRE OCTAHEDRON:
o b j e c t = WIRE OCTAHEDRON;
D i s p l a y ( ) ;
break ;
// c z w o r o Å› c i a n
case WIRE TETRAHEDRON:
o b j e c t = WIRE TETRAHEDRON;
D i s p l a y ( ) ;
break ;
// d w u d z i e s t o Å› c i a n
case WIRE ICOSAHEDRON :
o b j e c t = WIRE ICOSAHEDRON ;
D i s p l a y ( ) ;
1. Przekształcenia geometryczne 13
break ;
// w y j Å› c i e
case EXIT :
e x i t ( 0 ) ;
}
}
i n t main ( i n t a r gc , char " a r g v [ ] )
{
// i n i c j a l i z a c j a b i b l i o t e k i GLUT
g l u t I n i t (& argc , a r g v ) ;
// i n i c j a l i z a c j a b u f o r a r a m k i
g l u t I n i t D i s p l a y M o d e (GLUT DOUBLE | GLUT RGB ) ;
// r o z m i a r y g ł ó w n e g o okna programu
g l u t I n i t W i n d o w S i z e ( 4 0 0 , 4 0 0 ) ;
// u t w o r z e n i e g ł ó w n e g o okna programu
#i f d e f WIN32
glutCreateWindow ( P r z e k s z t a Å‚ c e n i a ) ;
#e l s e
glutCreateWindow ( P r z e k s z t a l c e n i a ) ;
#end if
// d o Å‚ Ä… c z e n i e f u n k c j i g e n e r u j Ä… c e j s c e n Ä™ 3D
g l u t D i s p l a y F u n c ( D i s p l a y ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i w y w o Å‚ y w a n e j p r z y z m i a n i e r o z m i a r u okna
glutRe shapeFunc ( Reshape ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i o b s Å‚ u g i k l a w i a t u r y
glutKeyboardFunc ( Keyboard ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i o b s Å‚ u g i k l a w i s z y f u n k c y j n y c h i k l a w i s z y k u r s o r a
g l u t S p e c i a l F u n c ( S p e c i a l K e y s ) ;
// o b s ł u g a p r z y c i s k ó w m y s z k i
glutMouseFunc ( MouseButton ) ;
// o b s Å‚ u g a r u c h u k u r s o r a m y s z k i
glutMotionFunc ( MouseMotion ) ;
// u t w o r z e n i e podmenu - a s p e k t o b r a z u
i n t MenuAspect = glutCreateMenu (Menu ) ;
#i f d e f WIN32
glutAddMenuEntry ( Aspekt ob r a z u - c a Å‚ e okno ,FULL WINDOW) ;
#e l s e
glutAddMenuEntry ( Aspekt ob r a z u - c a l e okno ,FULL WINDOW) ;
#end if
glutAddMenuEntry ( Aspekt ob r a z u 1 : 1 , ASPECT 1 1 ) ;
// u t w o r z e n i e podmenu - o b i e k t
i n t MenuObject = glutCreateMenu (Menu ) ;
glutAddMenuEntry ( Kula ,WIRE SPHERE ) ;
#i f d e f WIN32
glutAddMenuEntry ( S t o ż e k ,WIRE CONE ) ;
glutAddMenuEntry ( S z e Å› c i a n ,WIRE CUBE ) ;
glutAddMenuEntry ( Torus ,WIRE TORUS ) ;
glutAddMenuEntry ( DwunastoÅ› cian ,WIRE DODECAHEDRON) ;
glutAddMenuEntry ( C z a j n i k ,WIRE TEAPOT ) ;
glutAddMenuEntry ( O ś mio śc i an ,WIRE OCTAHEDRON) ;
glutAddMenuEntry ( C z w o r o Å› c i a n ,WIRE TETRAHEDRON) ;
glutAddMenuEntry ( D w u d z i e s t o Å› c i a n ,WIRE ICOSAHEDRON ) ;
#e l s e
glutAddMenuEntry ( S t o z e k ,WIRE CONE ) ;
glutAddMenuEntry ( S z e s c i a n ,WIRE CUBE ) ;
glutAddMenuEntry ( Torus ,WIRE TORUS ) ;
glutAddMenuEntry ( Dwunastos cian ,WIRE DODECAHEDRON) ;
glutAddMenuEntry ( C z a j n i k ,WIRE TEAPOT ) ;
glutAddMenuEntry ( O s mio sc i an ,WIRE OCTAHEDRON) ;
glutAddMenuEntry ( C z w o r o s c i a n ,WIRE TETRAHEDRON) ;
1. Przekształcenia geometryczne 14
glutAddMenuEntry ( D w u d z i e s t o s c i a n ,WIRE ICOSAHEDRON ) ;
#end if
// menu g ł ó w n e
glutCreateMenu ( Menu ) ;
glutAddSubMenu ( Aspekt o br azu , MenuAspect ) ;
glutAddSubMenu ( Obiekt , MenuObject ) ;
#i f d e f WIN32
glutAddMenuEntry ( W y j Å› c i e ,EXIT ) ;
#e l s e
glutAddMenuEntry ( W y j s c i e ,EXIT ) ;
#end if
// o k r e Å› l e n i e p r z y c i s k u m y s z k i o b s Å‚ u g u j Ä… c e g o menu p o d r Ä™ c z n e
glutAttachMenu (GLUT RIGHT BUTTON ) ;
// w p r o w a d z e n i e programu do o b s ł u g i p ę t l i k o m un i kat ów
glutMainLoop ( ) ;
return 0 ;
}
1.7. Stos macierzy modelowania
Do składania przekształceń biblioteka OpenGL wykorzystuje wspomnia-
ny już wcześniej stos macierzy modelowania. W dotychczasowych progra-
mach, oraz pierwszym z przykładowych programów z tego odcinka kursu,
mechanizm stosu nie był faktycznie wykorzystywany. Wszystkie operacje
związane ze stosem macierzy modelowania wykonywane były na macierzy
położonej na szczycie stosu. Pozwala to jednak na efektywną manipulację
jedynie jednym obiektem na scenie. Oczywiście obsługa wielu obiektów tak-
że jest możliwa, ale wymaga to stosowania mniej wygodnych i efektywnych
mechanizmów. W szczególności mogło by się okazać konieczne przechowy-
wanie macierzy modelowania - czyli dublowanie możliwości oferowanej przez
mechanizm stosu.
Po lekturze powyższego wstępu Czytelnik zastanawia się zapewne jak
w praktyce efektywnie można wykorzystać mechanizm stosu macierzy mo-
delowania. Klasycznym przykładem jest budowa obiektów złożonych z wielu
obiektów podstawowych (np. takich jak wyżej opisane obiekty 3D dostępne
w bibliotece GLUT). Drugim, równie często wykorzystywanym przykładem,
jest animacja sceny składającej się z wielu obiektów 3D.
1.7.1. Operacje na stosie
Specyfikacja biblioteki OpenGL przewiduje, że stos macierzy modelo-
wania przechowuje co najmniej 32 macierze. Oczywiście konkretne imple-
mentacje OpenGL mogą dowolnie zwiększać maksymalną pojemność tego
stosu. Opisane poniżej funkcje służą do operacji na każdym rodzaju stosu
dostępnym w OpenGL. Operacja zawsze zostanie wykonana na aktualnie
wybranym rodzaju stosu. Operację odłożenia bieżącej macierzy na stos re-
alizuje funkcja:
1. Przekształcenia geometryczne 15
void glPushMatrix (void)
Natomiast operację zdjęcia macierzy ze stosu wykonuje funkcja:
void glPopMatrix (void)
Próba wykonania niedozwolonej operacji na stosie spowoduje wygenero-
wanie kodu błędu zwracanego przez funkcjęglGetError:
GLSTACKUNDERFLOW- próba pobrania elementu z pustego stosu (niedo-
bór stosu),
GLSTACKOVERFLOW- przepełnienie stosu.
Przykładowy program (plikstosmodelowania.cpp) opiera się na po-
przednim przykładzie. Podstawową różnicą jest rysowanie jednego obiektu -
piramidy, ale złożonego z dużej ilości elementów podstawowych - sześcianów.
Dla ułatwienia pracy program zawiera dwie funkcje rysujące części piramidy
w postaci bloków 3 × 3 (funkcjaCube3x3) i bloków 2 × 2 (funkcjaCube2x2).
Pierwszy poziom piramidy ma rozmiary 6 × 6 i jest rysowany z czterech
bloków 3 × 3 (funkcjaPyramid). Przed narysowaniem każdego z elemen-
tów pierwszego poziomu macierz modelowania odkładana jest na stos - po
zakończeniu rysowania następuje zdjęcie macierzy ze stosu.
Przy rysowaniu drugiego i trzeciego poziomu piramidy następuje dwu-
krotne odłożenie macierzy modelowania na stos. Po pierwszym przesuwamy
układ współrzędnych od odpowiednią ilość jednostek do góry. Drugie w ko-
lejności odkładanie macierzy na stos wiąże się już bezpośrednio z rysowaniem
kolejnych elementów danego poziomu piramidy.
Rysowanie kolejnych poziomów nie wymaga już dodatkowego opisu - wy-
starcza jednokrotne odłożenie macierzy modelowania na stos. Przykładowy
efekt tych wszystkich przekształceń zawiera rysunek 5.
Oczywiście uzyskanie takiej figury nie wymaga stosowania mechanizmu
stosu macierzy modelowania. Jednak już w tak prostym przykładzie wi-
doczne są korzyści wynikające z takiego rozwiązania. Po pierwsze wszystkie
elementy obiektu 3D, w tym wypadku poziomy piramidy, sÄ… od siebie nie-
zależne. Czytelnik może to łatwo sprawdzić odpowiednio modyfikując tekst
zródłowy programu. Trudno nie docenić takiej cechy przy tworzeniu bardziej
skomplikowanych obiektów. Drugą zaletą jest duża przejrzystość rozwiąza-
nia, co ułatwia pózniejszą modyfikację programu i usuwanie ewentualnych
błędów. Warto także dodać, że mechanizm stosu jest bardzo szybki i dotyczy
to wszystkich implementacji biblioteki OpenGL, nie tylko sprzętowych.
1. Przekształcenia geometryczne 16
Rysunek 5. Program Stos modelowania
1.7.2. Plik stos modelowania.cpp
/"
( c ) J a n u s z G a n c z a r s k i
h t t p : / / www . j a n u s z g . hg . p l
J a nu s zG @ e nter . n e t . p l
"/
#include
#include < s t d l i b . h>
// s t a Å‚ e do o b s Å‚ u g i menu p o d r Ä™ c z n e g o
enum
{
FULL WINDOW, // a s p e k t o b r a z u - c a Å‚ e okno
ASPECT 1 1 , // a s p e k t o b r a z u 1 : 1
EXIT // w y j Å› c i e
} ;
// a s p e k t o b r a z u
i n t a s p e c t = FULL WINDOW;
// r o z m i a r y b r y Å‚ y o b c i n a n i a
const GLdouble l e f t = -1 0. 0;
1. Przekształcenia geometryczne 17
const GLdouble r i g h t = 1 0 . 0 ;
const GLdouble bottom = - 10 .0 ;
const GLdouble top = 1 0 . 0 ;
const GLdouble n e a r = 5 0 . 0 ;
const GLdouble f a r = 7 0 . 0 ;
// w s p ó ł c z y n n i k s k a l o w a n i a
G L f l o a t s c a l e = 1 . 0 ;
// k Ä… t y o b r o t u
G L f l o a t r o t a t e x = 0 . 0 ;
G L f l o a t r o t a t e y = 0 . 0 ;
// p r z e s u n i Ä™ c i e
G L f l o a t t r a n s l a t e x = 0 . 0 ;
G L f l o a t t r a n s l a t e y = 0 . 0 ;
// w s k a z n i k n a c i Å› n i Ä™ c i a l e w e g o p r z y c i s k u m y s z k i
i n t b u t t o n s t a t e = GLUT UP ;
// p o ł o ż e n i e k u r s o r a m y s z k i
i n t b u t t o n x , b u t t o n y ;
// f u n k c j a r y s u j Ä… c a b l o k 3 x3
void Cube3x3 ( )
{
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 0 . 0 , - 1 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( - 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( - 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 0 . 0 , 1 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 0 . 0 , 1 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
}
// f u n k c j a r y s u j Ä… c a b l o k 2 x2
void Cube2x2 ( )
{
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( 0 . 0 , - 1 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
g l T r a n s l a t e f ( - 1 . 0 , 0 . 0 , 0 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
}
// f u n k c j a r y s u j ą c a p i r a m i d ę z s z e ś c i a n ó w
void Pyramid ( )
{
// p o d s t a w a 6 x6
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 1 . 5 , 1 . 5 , 0 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 1 . 5 , - 1 . 5 , 0 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 1 . 5 , - 1 . 5 , 0 . 0 ) ;
Cube3x3 ( ) ;
1. Przekształcenia geometryczne 18
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 1 . 5 , 1 . 5 , 0 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
// d r u g i pozi om 5 x5
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 0 , 0 . 0 , 1 . 0 ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 1 . 0 , 1 . 0 , 0 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 1 . 0 , - 1 . 0 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 2 . 0 , 2 . 0 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 1 . 0 , - 1 . 0 , 0 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
gl PopMatri x ( ) ;
// t r z e c i po zio m 4 x4
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 0 , 0 . 0 , 2 . 0 ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 5 , - 0 . 5 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 5 , 1 . 5 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 1 . 5 , 1 . 5 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( - 1 . 5 , - 0 . 5 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
gl PopMatri x ( ) ;
// c z w a r t y p oz iom 3 x3
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 0 , 0 . 0 , 3 . 0 ) ;
Cube3x3 ( ) ;
gl PopMatri x ( ) ;
// p i Ä… t y pozi om 2 x2
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 0 , 0 . 0 , 4 . 0 ) ;
g l T r a n s l a t e f ( - 0 . 5 , 0 . 5 , 0 . 0 ) ;
Cube2x2 ( ) ;
gl PopMatri x ( ) ;
// s z ó s t y po zio m 1 x1
g l P u s h M a t r i x ( ) ;
g l T r a n s l a t e f ( 0 . 0 , 0 . 0 , 5 . 0 ) ;
glutWireCube ( 1 . 0 ) ;
gl PopMatri x ( ) ;
}
// f u n k c j a g e n e r u j Ä… c a s c e n Ä™ 3D
void D i s p l a y ( )
{
// k o l o r t ł a - z a w a r t o ś ć b u f o r a k o l o r u
g l C l e a r C o l o r ( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
// c z y s z c z e n i e b u f o r a k o l o r u
g l C l e a r (GL COLOR BUFFER BIT ) ;
// wyb ór m a c i e r z y m o d e l o w a n i a
glMatrixMode (GL MODELVIEW ) ;
1. Przekształcenia geometryczne 19
// m a c i e r z m o d e l o w a n i a = m a c i e r z j e d n o s t k o w a
g l L o a d I d e n t i t y ( ) ;
// p r z e s u n i ę c i e u k ł a d u w s p ó ł r z ę d n y c h o b i e k t u do ś r o d k a b r y ł y o d c i n a n i a
g l T r a n s l a t e f ( 0 , 0 , - ( n e a r+f a r ) / 2 ) ;
// p r z e s u n i Ä™ c i e o b i e k t u - r u c h myszkÄ…
g l T r a n s l a t e f ( t r a n s l a t e x , t r a n s l a t e y , 0 . 0 ) ;
// s k a l o w a n i e o b i e k t u - k l a w i s z e + i -
g l S c a l e f ( s c a l e , s c a l e , s c a l e ) ;
// o b r o t y o b i e k t u - k l a w i s z e k u r s o r a
g l R o t a t e f ( r o t a t e x , 1 . 0 , 0 , 0 ) ;
g l R o t a t e f ( r o t a t e y , 0 , 1 . 0 , 0 ) ;
// k o l o r k r a w Ä™ d z i o b i e k t u
g l C o l o r 3 f ( 0 . 0 , 0 . 0 , 0 . 0 ) ;
// r y s o w a n i e p i r a m i d y
Pyramid ( ) ;
// s k i e r o w a n i e p o l e c e Å„ do w y k o n a n i a
g l F l u s h ( ) ;
// zamiana b u f o r ó w k o l o r u
g l u t S w a p B u f f e r s ( ) ;
}
// zmiana w i e l k o Å› c i okna
void Reshape ( i n t width , i n t h e i g h t )
{
// o b s z a r r e n d e r i n g u - c a Å‚ e okno
g l V i e w p o r t ( 0 , 0 , width , h e i g h t ) ;
// wyb ór m a c i e r z y r z u t o w a n i a
glMatrixMode (GL PROJECTION ) ;
// m a c i e r z r z u t o w a n i a = m a c i e r z j e d n o s t k o w a
g l L o a d I d e n t i t y ( ) ;
// p a r a m e t r y b r y Å‚ y o b c i n a n i a
i f ( a s p e c t == ASPECT 1 1 )
{
// w y s o k o ś ć okna w i ę k s z a od w y s o k o ś c i okna
i f ( width < h e i g h t && width > 0 )
glFrustum ( l e f t , r i g h t , bottom " h e i g h t / width , top " h e i g h t / width , near , f a r ) ;
e l s e
// s z e r o k o ś ć okna w i ę k s z a l u b równa w y s o k o ś c i okna
i f ( width >= h e i g h t && h e i g h t > 0 )
glFrustum ( l e f t " width / h e i g h t , r i g h t " width / h e i g h t , bottom , top , near , f a r ) ;
}
e l s e
glFrustum ( l e f t , r i g h t , bottom , top , near , f a r ) ;
// g e n e r o w a n i e s c e n y 3D
D i s p l a y ( ) ;
}
// o b s Å‚ u g a k l a w i a t u r y
void Keyboard ( unsigned char key , i n t x , i n t y )
{
// k l a w i s z +
i f ( key == + )
s c a l e += 0 . 1 ;
e l s e
// k l a w i s z -
i f ( key == - && s c a l e > 0 . 1 )
s c a l e -= 0 . 1 ;
// o d r y s o w a n i e okna
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
}
// o b s Å‚ u g a k l a w i s z y f u n k c y j n y c h i k l a w i s z y k u r s o r a
1. Przekształcenia geometryczne 20
void S p e c i a l K e y s ( i n t key , i n t x , i n t y )
{
switch ( key )
{
// k u r s o r w l e w o
case GLUT KEY LEFT :
r o t a t e y -= 1 ;
break ;
// k u r s o r w g ó r ę
case GLUT KEY UP :
r o t a t e x -= 1 ;
break ;
// k u r s o r w prawo
case GLUT KEY RIGHT :
r o t a t e y += 1 ;
break ;
// k u r s o r w d ó ł
case GLUT KEY DOWN:
r o t a t e x += 1 ;
break ;
}
// o d r y s o w a n i e okna
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
}
// o b s ł u g a p r z y c i s k ó w m y s z k i
void MouseButton ( i n t button , i n t s t a t e , i n t x , i n t y )
{
i f ( bu t to n == GLUT LEFT BUTTON)
{
// z a p a m i Ä™ t a n i e s t a n u l e w e g o p r z y c i s k u m y s z k i
b u t t o n s t a t e = s t a t e ;
// z a p a m i ę t a n i e p o ł o ż e n i a k u r s o r a m y s z k i
i f ( s t a t e == GLUT DOWN)
{
b u t t o n x = x ;
b u t t o n y = y ;
}
}
}
// o b s Å‚ u g a r u c h u k u r s o r a m y s z k i
void MouseMotion ( i n t x , i n t y )
{
i f ( b u t t o n s t a t e == GLUT DOWN)
{
t r a n s l a t e x += 1 . 1 "( r i g h t - l e f t ) / g l u t G e t (GLUT WINDOW WIDTH) " ( x - b u t t o n x ) ;
b u t t o n x = x ;
t r a n s l a t e y += 1 . 1 "( top - bottom ) / g l u t G e t (GLUT WINDOW HEIGHT) " ( b u t t o n y - y ) ;
b u t t o n y = y ;
g l u t P o s t R e d i s p l a y ( ) ;
}
}
// o b s Å‚ u g a menu p o d r Ä™ c z n e g o
void Menu ( i n t v a l u e )
{
switch ( v a l u e )
{
// o b s z a r r e n d e r i n g u - c a Å‚ e okno
case FULL WINDOW:
a s p e c t = FULL WINDOW;
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
break ;
// o b s z a r r e n d e r i n g u - a s p e k t 1 : 1
case ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
Reshape ( g l u t G e t (GLUT WINDOW WIDTH) , g l u t G e t (GLUT WINDOW HEIGHT ) ) ;
break ;
1. Przekształcenia geometryczne 21
// w y j Å› c i e
case EXIT :
e x i t ( 0 ) ;
}
}
i n t main ( i n t a r gc , char " a r g v [ ] )
{
// i n i c j a l i z a c j a b i b l i o t e k i GLUT
g l u t I n i t (& argc , a r g v ) ;
// i n i c j a l i z a c j a b u f o r a r a m k i
g l u t I n i t D i s p l a y M o d e (GLUT DOUBLE | GLUT RGB ) ;
// r o z m i a r y g ł ó w n e g o okna programu
g l u t I n i t W i n d o w S i z e ( 4 0 0 , 4 0 0 ) ;
// u t w o r z e n i e g ł ó w n e g o okna programu
glutCreateWindow ( S t o s modelowania ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i g e n e r u j Ä… c e j s c e n Ä™ 3D
g l u t D i s p l a y F u n c ( D i s p l a y ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i w y w o Å‚ y w a n e j p r z y z m i a n i e r o z m i a r u okna
glutRe shapeFunc ( Reshape ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i o b s Å‚ u g i k l a w i a t u r y
glutKeyboardFunc ( Keyboard ) ;
// d o Å‚ Ä… c z e n i e f u n k c j i o b s Å‚ u g i k l a w i s z y f u n k c y j n y c h i k l a w i s z y k u r s o r a
g l u t S p e c i a l F u n c ( S p e c i a l K e y s ) ;
// o b s ł u g a p r z y c i s k ó w m y s z k i
glutMouseFunc ( MouseButton ) ;
// o b s Å‚ u g a r u c h u k u r s o r a m y s z k i
glutMotionFunc ( MouseMotion ) ;
// u t w o r z e n i e podmenu - a s p e k t o b r a z u
i n t MenuAspect = glutCreateMenu (Menu ) ;
#i f d e f WIN32
glutAddMenuEntry ( Aspekt ob r a z u - c a Å‚ e okno ,FULL WINDOW) ;
#e l s e
glutAddMenuEntry ( Aspekt ob r a z u - c a l e okno ,FULL WINDOW) ;
#end if
glutAddMenuEntry ( Aspekt ob r a z u 1 : 1 , ASPECT 1 1 ) ;
// menu g ł ó w n e
glutCreateMenu ( Menu ) ;
glutAddSubMenu ( Aspekt o br azu , MenuAspect ) ;
#i f d e f WIN32
glutAddMenuEntry ( W y j Å› c i e ,EXIT ) ;
#e l s e
glutAddMenuEntry ( W y j s c i e ,EXIT ) ;
#end if
// o k r e Å› l e n i e p r z y c i s k u m y s z k i o b s Å‚ u g u j Ä… c e g o menu p o d r Ä™ c z n e
glutAttachMenu (GLUT RIGHT BUTTON ) ;
// w p r o w a d z e n i e programu do o b s ł u g i p ę t l i k o m un i kat ów
glutMainLoop ( ) ;
return 0 ;
}
Literatura 22
Literatura
[1] Mark Segal, Kurt Akeley: The OpenGL Graphics System. A Specification Ver-
sion 2.0
[2] Jackie Neider, Tom Davis, Mason Woo: OpenGL Programming Guide The
Red Book
[3] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta, Helion 1999
[4] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta Wydanie III,
Helion 2005
[5] The official OpenGL web page,http://www.opengl.org
[6] Piotr Andrzejewski, Jakub Kurzak: Wprowadzenie do OpenGL. Programowanie
zastosowań graficznych, Kwantum 2000
[7] Kevin Hawkins, Dave Astle: OpenGL. Programowanie gier, Helion 2003
[8] Mark J. Kilgard: The OpenGL Utility Toolkit (GLUT) Programming Interface
API Version 3. Silicon Graphics, Inc. 1996
Wyszukiwarka
Podobne podstrony:
Przekształcenia geometryczne powtórzenie
GK 9 Przekształcenia geometryczne
opengl elementarne obiekty geometryczne
GeometricProbabilityDistribution
07 GIMP od podstaw, cz 4 Przekształcenia
2 Charakterystyki geometryczne figur płaskich (2)
120123 IK wykład 4 WO SŻ kształt ukł geomet
3 4 BK Przeksztalcenia gramatyk
Przekształcenia liniowe zadania i przykłady
geometria zadania powtórzeniowe
więcej podobnych podstron