Janusz Ganczarski
OpenGL
Światła i materiały
Spis treści
Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1. Światła i materiały . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Włączanie oświetlenia . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Włączanie źródła światła . . . . . . . . . . . . . . . . . . . . . . . .
1
Parametry źródła światła . . . . . . . . . . . . . . . . . . . . . . . .
2
Parametry modelu oświetlenia . . . . . . . . . . . . . . . . . . . . .
5
Materiały . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
. . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
Wektory normalne . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8
Odczyt parametrów źródła światła i materiałów . . . . . . . . . . .
10
. . . . . . . . . . . . . . . . . . . . . . . . .
10
Plik globalne swiatlo otaczajace.cpp . . . . . . . . . . . . . .
13
Plik materials.h . . . . . . . . . . . . . . . . . . . . . . . . .
23
Plik materlaly.cpp . . . . . . . . . . . . . . . . . . . . . . . .
31
Plik wektory normalne.cpp . . . . . . . . . . . . . . . . . . .
42
. . . . . . . . . . . . . . . . . .
55
Plik reflektor.cpp . . . . . . . . . . . . . . . . . . . . . . . .
70
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
86
1. Światła i materiały
Model oświetlenia zastosowany w bibliotece OpenGL opiera się na trzech
rodzajach światła. Pierwszy rodzaj to światło otaczające (ang. ambient li-
ght), które nie pochodzi z żadnego konkretnego kierunku i równomiernie
oświetla wszystkie elementy sceny 3D. Drugim rodzajem światła jest światło
rozproszone (ang. diffuse light), które pada na obiekt z określonego kierunku,
ale jest na nim rozpraszane we wszystkich kierunkach. Ostatnim rodzajem
światła obsługiwanego przez OpenGL jest światło odbite (ang. specular li-
ght), zwane także światłem kierunkowym, które pada na obiekt w określo-
nym kierunku i odbijane jest także w ściśle określonym kierunku.
W bibliotece OpenGL ze światłem ściśle związane jest pojęcia materia-
łów określające właściwości oświetlanych obiektów. Właściwości materiału,
poza reakcją na opisane wyżej trzy rodzaje światła, uwzględniają także moż-
liwość emitowania światła.
1.1. Włączanie oświetlenia
Domyślnie biblioteka OpenGL nie wykonuje obliczeń związanych z oświe-
tleniem. Uruchomienie oświetlenia wymaga wywołania funkcji glEnable
z parametrem GL LIGHTING. Ponadto należy włączyć bufor głębokości. Nie
jest to wprawdzie konieczne ale znacząco wpływa na realizm generowanej
sceny 3D. Oczywiście wyłączenie oświetlenia sprowadza się do wywołania
funkcji glDisable z parametrem GL LIGHTING.
1.2. Włączanie źródła światła
Specyfikacja OpenGL określa, że minimalną ilość źródeł światła, którą
musi obsługiwać każda implementacja biblioteki wynosi 8. Każde źródło
światła ma swój unikatowy numer oznaczony stałą GL LIGHTi, gdzie i za-
wiera się w przedziale [0, 7]. Ilość źródeł światła obsługiwanych przez daną
implementację biblioteki OpenGL zwraca wywołanie funkcji glGetIntegerv
z parametrem GL MAX LIGHTS. Alternatywnie numery źródeł światła można
określić przy pomocy wyrażenia: GL LIGHTi = GL LIGHT0 + i. Jest to
szczególnie przydatne przy źródłach światła o numerach wyższych niż 7,
bowiem pliki nagłówkowe biblioteki OpenGL standardowo nie zawierają
stosownych stałych. Zasada ta odnosi się do każdej funkcji korzystającej
z numeru źródła światła.
Poszczególne źródła światła włączamy i wyłączamy przy użyciu funkcji
glEnable/glDisable z parametrem określającym numer źródła światła.
1. Światła i materiały
2
1.3. Parametry źródła światła
Parametry każdego ze źródła światła można modyfikować niezależnie od
pozostałych źródeł światła. Służą do tego funkcje z grupy glLight, któ-
re można podzielić na dwie podgrupy. Pierwsza pozwala na modyfikację
parametrów źródła światła określanych pojedynczą wartością; druga gru-
pa funkcji przyjmuje wskaźniki na tablice z wartościami parametrów, przy
czym można ich także używać do modyfikacji parametrów źródła światła
określanych pojedynczą wartością.
Zmianę parametru źródła światła określanego pojedynczą wartością umoż-
liwiają funkcje:
void glLightf (GLenum light, GLenum pname, GLfloat param)
void glLighti (GLenum light, GLenum pname, GLint param)
Natomiast zmianę parametru źródła światła określanego tablicą wartości
umożliwiają funkcje:
void glLightfv (GLenum light, GLenum pname,
const GLfloat *params)
void glLightiv (GLenum light, GLenum pname,
const GLint *params)
Parametr light określa numer źródła światła, którego parametry chce-
my zmienić. Numer źródła światła określają omówione już stałe GL LIGHTi.
Parametr pname określa parametr źródła światła, który chcemy zmodyfiko-
wać. Dopuszczalne są następujące wartości tego parametru:
— GL AMBIENT - wartości składowych RGBA światła otaczającego,
— GL DIFFUSE - wartości składowych RGBA światła rozproszonego,
— GL SPECULAR - wartości składowych RGBA światła odbitego,
— GL POSITION – czteroelementowy wektor (x, y, z, w), którego interpre-
tacja zależy od wartości w; jeżeli w ma wartość 1, oznacza to, że trzy
pierwsze współrzędne wektora określają położenie źródła światła; jeżeli
natomiast w ma wartość 0, to źródło światła jest światłem kierunkowym,
a jego promienie padają w kierunku zdefiniowanym przez trzy pierwsze
współrzędne wektora,
— GL SPOT DIRECTION - znormalizowany (długości 1) trójwspółrzędny wek-
tor określający kierunek reflektora,
— GL SPOT EXPONENT - wykładnik tłumienia kątowego reflektora; dopusz-
czalne są wartości z przedziału [0, 128],
— GL SPOT CUTOFF - kąt odcięcia reflektora; dopuszczalne są wartości z prze-
działu [0, 90] oraz 180,
— GL CONSTANT ATTENUATION - stały współczynnik tłumienia światła,
— GL LINEAR ATTENUATION - liniowy współczynnik tłumienia światła,
1. Światła i materiały
3
— GL QUADRATIC ATTENUATION - kwadratowy współczynnik tłumienia świa-
tła.
Wspomniane wyżej reflektory to po prostu światło kierunkowe, którego
promienie rozchodzą się w przestrzeni ograniczonej stożkiem o wierzchoł-
ku znajdującym się w źródle światła. Połowę kąta rozwarcia stożka światła
określa parametr GL SPOT CUTOFF (patrz rysunek 1). Wszystkie obiekty sce-
ny znajdujące się poza stożkiem światła reflektora pozostają nieoświetlone
jego światłem.
Rysunek 1. Parametr GL SPOT CUTOFF
Parametr GL SPOT EXPONENT umożliwia regulację stopnia skupienia świa-
tła reflektora. Jest to wykładnik potęgi wyrażenia stanowiącego kosinus kąta
pomiędzy kierunkiem padania światła, a kierunkiem od źródła światła do
wierzchołka oświetlanego elementu sceny. Domyślna wartość 0 oznacza brak
tłumienia kątowego, czyli równomierne rozchodzenie się światła we wszyst-
kich kierunkach.
Trzy ostatnie parametry źródła światła określają współczynnik tłumienia
światła dany wzorem:
1
a
c
+ a
l
d + a
q
d
2
gdzie d oznacza odległość wierzchołka od źródła światła, a stałe a
c
, a
l
i a
q
od-
powiednio stały (GL CONSTANT ATTENUATION), liniowy (GL LINEAR ATTENUA-
TION) i kwadratowy (GL QUADRATIC ATTENUATION) współczynnik tłumienia.
Przy domyślnych ustawieniach parametrów źródeł światła wartość współ-
czynnika tłumienia wynosi 1, co oznacza, że intensywność strumienie światła
nie zależy od odległości pomiędzy jego źródłem a wierzchołkiem oświetlane-
go obiektu.
1. Światła i materiały
4
Zestawienie domyślnych wartości parametrów źródła światła GL LIGHT0
zawiera tabela 1. Te same dane dla pozostałych źródeł światła przedstawia
tabela 2.
parametr źródła światła
wartość
GL AMBIENT
(0, 0, 0, 1)
GL DIFFUSE
(1, 1, 1, 1)
GL SPECULAR
(1, 1, 1, 1)
GL POSITION
(0, 0, 1, 0)
GL SPOT DIRECTION
(0, 0, −1)
GL SPOT EXPONENT
0
GL SPOT CUTOFF
180
GL CONSTANT ATTENUATION
1
GL LINEAR ATTENUATION
0
GL QUADRATIC ATTENUATION
0
Tabela 1: Domyślne parametry źródła światła GL LIGHT0
parametr źródła światła
wartość
GL AMBIENT
(0, 0, 0, 1)
GL DIFFUSE
(0, 0, 0, 1)
GL SPECULAR
(0, 0, 0, 1)
GL POSITION
(0, 0, 1, 0)
GL SPOT DIRECTION
(0, 0, −1)
GL SPOT EXPONENT
0
GL SPOT CUTOFF
180
GL CONSTANT ATTENUATION
1
GL LINEAR ATTENUATION
0
GL QUADRATIC ATTENUATION
0
Tabela 2: Domyślne parametry źródeł światła GL LIGHT1 -
GL LIGHT7
Jak widzimy na powyższych tabelach światło GL LIGHT0 jest światłem
białym kierunkowym położonym w punkcie o współrzędnych (0, 0, 1). Świa-
tło skierowane jest zgodnie z kierunkiem wyznaczonym przez wektor o współ-
rzędnych [0, 0, −1]. Pomimo kierunkowego charakteru stożek światła GL -
LIGHT0 nie jest w żaden sposób ograniczony (parametr GL SPOT CUTOFF ma
wartość 180
◦
) i światło rozchodzi się każdym kierunku. Przy domyślnych po-
czątkowych ustawieniach układu współrzędnych oraz bryły odcinania źródło
1. Światła i materiały
5
światła GL LIGHT0 znajduje się na środku płaszczyzny monitora (okna) i jest
skierowane prostopadle w głąb monitora.
Źródła światła GL LIGHT1 - GL LIGHT7 różną się do światła GL LIGHT0
tylko barwą światła rozproszonego i odbitego.
1.4. Parametry modelu oświetlenia
Poza zdefiniowaniem właściwości poszczególnych źródeł światła do oświe-
tlenia sceny w bibliotece OpenGL trzeba jeszcze określić parametry stoso-
wanego modelu oświetlenia. Służą do tego funkcje z grupy glLightModel:
void glLightModelf (GLenum pname, GLfloat param)
void glLightModeli (GLenum pname, GLint param)
void glLightModelfv (GLenum pname, const GLfloat *params)
void glLightModeliv (GLenum pname, const GLint *params)
Funkcje te, podobnie jak funkcje z grupy glLight, występują w dwóch wer-
sjach różniących się sposobem przekazywania parametrów.
Parametr pname określa właściwość modelu oświetlenia, który chcemy
zmienić. Dopuszczalne są następujące wartości tego parametru:
— GL LIGHT MODEL LOCAL VIEWER - określenie sposobu obliczania kąta od-
bicia światła; wartość 0 oznacza, że kąt obliczany jest na podstawie kie-
runku od początku układu współrzędnych do oświetlanego wierzchołka
obiektu; wartość różna od 0 oznacza, że kąt odbicia światła obliczany
jest na podstawie kierunku ujemnej osi OZ,
— GL LIGHT MODEL TWO SIDE - określenie czy będą oświetlane obie strony
wielokątów (wartość różna od 0) czy też tylko przednie strony wielokątów
(wartość 0),
— GL LIGHT MODEL AMBIENT - określenie składowych RGBA globalnego świa-
tła otaczającego,
— GL LIGHT MODEL COLOR CONTROL - określenie czy efekt oświetlenia świa-
tłem odbitym będzie nakładany dopiero po nałożeniu tekstury (war-
tość GL SEPARATE SPECULAR COLOR) lub też razem z teksturą (wartość
GL SINGLE COLOR).
Ustawienie wartości składowych RGBA globalnego światła otaczającego
wymaga oczywiście użycia funkcji glLightModelfv lub glLightModeliv.
Parametr GL LIGHT MODEL COLOR CONTROL, będący jednym z elementów tech-
niki nazywanej drugorzędnym kolorem odbicia (ang. secondary specular co-
lor), wprowadzono w wersji 1.2 biblioteki OpenGL. Wcześniej technika ta
opisana była w rozszerzeniu EXT separate specular color. Zostanie to bli-
żej zaprezentowane w jednym z kolejnych odcinków kursu OpenGL.
1. Światła i materiały
6
Tabela 3 przedstawia wartości domyślne parametrów modelu oświetlenia
w bibliotece OpenGL.
parametr modelu oświetlenia
wartość
GL LIGHT MODEL LOCAL VIEWER
0
GL LIGHT MODEL TWO SIDE
0
GL LIGHT MODEL AMBIENT
2
10
,
2
10
,
2
10
, 1
GL LIGHT MODEL COLOR CONTROL
GL SINGLE COLOR
Tabela 3: Domyślne parametry modelu oświetlenia
1.5. Materiały
Integralnym elementem modelu oświetlenia przyjętego w bibliotece
OpenGL jest opis sposobu zachowania się powierzchni obiektów na poszcze-
gólne rodzaje światła, czyli opis właściwości materiałów. Modyfikowanie
właściwości materiałów umożliwiają funkcje z grupy glMaterial:
void glMaterialf (GLenum face, GLenum pname, GLfloat para)
void glMateriali (GLenum face, GLenum pname, GLint para)
void glMaterialfv (GLenum face, GLenum pname,
const GLfloat *params)
void glMaterialiv (GLenum face, GLenum pname,
const GLint *params)
Jak Czytelnik zauważył także i te funkcje występują w dwóch wersjach róż-
niących się sposobem przekazywania parametrów.
Parametr face ustala, którą stronę wielokąta dotyczy modyfikowany pa-
rametr. Dopuszczalne są poznane już wcześniej wartości: GL FRONT - przed-
nia strona wielokąta, GL BACK - tylna strona wielokąta i GL FRONT AND BACK
- obie strony wielokąta.
Parametr pname określa zmienianą wartość parametru materiału. Do-
puszczalne są poniższe wartości:
— GL AMBIENT - składowe RGBA określające stopień odbicia światła ota-
czającego,
— GL DIFFUSE - składowe RGBA określające stopień rozproszenia światła
rozproszonego,
— GL AMBIENT AND DIFFUSE - składowe RGBA określające jednocześnie sto-
pień odbicia światła otaczającego i stopień rozproszenia światła rozpro-
szonego; jest to wartość domyślna,
— GL SPECULAR - składowe RGBA określające stopień odbicia światła od-
bitego,
1. Światła i materiały
7
— GL SHININESS - stała z przedziału [0, 128] określająca wykładnik odbły-
sku światła (ang. specular exponent) czyli regulację stopnia występowania
efektu rozbłysku obiektu; im większa wartość parametru, tym większe
skupienie rozbłysku światła na obiekcie,
— GL EMISSION - składowe RGBA światła emitowanego przez obiekt; taki
obiekt nie staje się źródłem światła i nie oświetla innych obiektów sceny,
wymaga to także utworzenia źródła światła,
— GL COLOR INDEXES - w indeksowym trybie kolorów trzy indeksy do ta-
blicy kolorów określające kolejno składowe RGBA określające reakcję na
światło otaczające, rozproszone i odbite.
Zestawienie domyślnych własności materiałów zawiera tabela 4. Zwróć-
my uwagę, że parametr GL AMBIENT AND DIFFUSE nie posiada domyślnych
wartości.
parametr materiału
wartość
GL AMBIENT
2
10
,
2
10
,
2
10
, 1
GL DIFFUSE
8
10
,
8
10
,
8
10
, 1
GL AMBIENT AND DIFFUSE
-
GL SPECULAR
(0, 0, 0, 1)
GL SHININESS
0
GL EMISSION
(0, 0, 0, 1)
GL COLOR INDEXES
(0, 1, 1)
Tabela 4: Domyślne parametry materiałów
Największy wpływ na kolor obiektu mają składowe GL DIFFUSE
Dobranie materiału o odpowiednich właściwościach nie jest zadaniem
łatwym, choćby z uwagi na dużą ilość niezależnych od siebie parametrów.
Podamy jednak kilka praktycznych rad przy dobieraniu materiałów. Przy
materiałach matowych duże wartości powinny mieć składowe GL DIFFUSE
przy małych wartościach składowych GL SPECULAR. Materiały imitujące two-
rzywa sztuczne także mają wysokie wartości składowych GL DIFFUSE przy
neutralnych (białych) składowych GL SPECULAR. Powierzchnie metaliczne to
małe wartości składowych GL DIFFUSE i jednocześnie duże wartości składo-
wych GL SPECULAR. Stosownie do rodzaju powierzchni trzeba także dobrać
odpowiednią wartość współczynnika GL SHININESS.
Przykładowe definicje materiałów Czytelnik znajdzie w jednym z pro-
gramów testowych.
1. Światła i materiały
8
1.6. Śledzenie kolorów
Biblioteka OpenGL umożliwia także definiowanie parametrów materia-
łów na podstawie kolorów wierzchołków określanych, przypomnijmy, przy
pomocy funkcji z grupy glColor. Technika ta nazywana jest śledzeniem
kolorów (ang. color tracking). Wybór parametrów materiału, które będą
określane poprzez kolory wierzchołków, określa funkcja:
void glColorMaterial (GLenum face, GLenum mode)
Parametr face ustala, którą stronę wielokąta dotyczy modyfikowany pa-
rametr. Dopuszczalne są wszystkie opisane wcześniej wartości: GL FRONT,
GL BACK i GL FRONT AND BACK. Wartością domyślną jest GL FRONT AND BACK.
Parametr mode wskazuje, która z właściwości materiału ma być defi-
niowana zgodnie z bieżącym kolorem wierzchołka. Dopuszczalne są niemal
wszystkie opisane wcześniej własności materiałów: GL EMISSION, GL AMBIENT,
GL DIFFUSE, GL SPECULAR i GL AMBIENT AND DIFFUSE. Wartością domyślną
jest GL AMBIENT AND DIFFUSE.
Śledzenie kolorów jest domyślne wyłączone, stąd przed użyciem funkcji
glColorMaterial trzeba wywołać funkcję glEnable z parametrem GL CO-
LOR MATERIAL. Oczywiście wyłączenie śledzenia kolorów wymaga wywołania
funkcji glDisable z parametrem GL COLOR MATERIAL.
Używanie techniki śledzenie kolorów jest szczególnie użyteczne, gdy na
każdy wierzchołek obiektu zmieniamy tylko jedną właściwość materiału.
1.7. Wektory normalne
Do prawidłowego generowania efektów oświetlenia, a w szczególności
określenia orientacji wierzchołków obiektów względem źródeł światła, biblio-
teka OpenGL wymaga definiowania wektorów normalnych (prostopadłych).
Ponieważ obliczenia związane z oświetleniem OpenGL wykonuje dla każdego
wierzchołka, stąd każdy wierzchołek ma przypisany swój wektor normalny.
Wektor normalny definiują funkcje z grupy glNormal3, które dzielą się
na dwie grupy. Pierwsza grupa posiada trzy parametry określające składowe
wektora normalnego:
void glNormal3b (GLbyte nx, GLbyte ny, GLbyte nz)
void glNormal3d (GLdouble nx, GLdouble ny, GLdouble nz)
void glNormal3f (GLfloat nx, GLfloat ny, GLfloat nz)
void glNormal3i (GLint nx, GLint ny, GLint nz)
void glNormal3s (GLshort nx, GLshort ny, GLshort nz)
Druga grupa funkcji posiada jeden parametr będący wskaźnikiem na tablicę
ze składowymi wektora normalnego:
1. Światła i materiały
9
void glNormal3bv (const GLbyte *v)
void glNormal3dv (const GLdouble *v)
void glNormal3fv (const GLfloat *v)
void glNormal3iv (const GLint *v)
void glNormal3sv (const GLshort *v)
Podobnie jak w przypadku kolorów czy własności materiału dany wek-
tor normalny obowiązuje do czasu zdefiniowania kolejnego. W szczególności
można użyć jednego wektora normalnego do grupy wierzchołków opisujących
płaski obiekt. Początkowa wartość wektora normalnego wynosi [0, 0, 1].
Do wyznaczania wektora normalnego można użyć iloczynu wektorowe-
go. Przy obliczeniach wykorzystujemy wektory utworzone z krawędzi ściany
obiektu, pamiętając o zachowaniu odpowiedniej orientacji. Jeżeli ściany ma-
ją sprawiać wrażenie płaskich, wówczas obliczamy wektor normalny tylko
dla pierwszego wierzchołka. Pozostałe wierzchołki będą korzystały z tego
samego wektora.
Jeżeli natomiast zależy nam na uzyskaniu wrażenia gładkości oświetla-
nego obiektu wykorzystujemy technikę uśredniania wektorów normalnych.
Polega ona na obliczaniu wektora normalnego dla każdego wierzchołka obiek-
tu 3D. Tym razem wektor ten obliczamy nie na podstawie krawędzi jednej
ściany ale wszystkich krawędzi wychodzących z wierzchołka. Można do tego
celu wykorzystać złożenie (sumę) wektorów normalnych wszystkich ścian za-
wierających dany wierzchołek. Technika ta pozwala na zwiększenie realizmu
sceny bez radykalnego zwiększania złożoności renderowanych obiektów.
Aby obliczenia oświetlenia były wykonywane poprawne wektor normalny
musi mieć długość jednostkową, inaczej mówiąc musi być znormalizowany
(jednostkowy). Normalizację wektorów można wykonać programowo, przy
czym należy uwzględniać przekształcenia macierzy modelowania, które mo-
dyfikują także wektory normalne i mogą przy okazji zmienić ich długość.
W szczególności dotyczy to operacji skalowania macierzy modelowania.
Drugim sposobem normalizacji wektorów normalnych jest skorzystanie
z mechanizmu udostępnianego przez OpenGL, który automatycznie norma-
lizuje wektory normalne. W tym celu trzeba wywołać funkcję glEnable
z parametrem GL NORMALIZE. Domyślnie mechanizm ten jest nieaktywny.
Wyłączenie automatycznej normalizacji wektorów normalnych wymaga wy-
wołania funkcji glDisable z parametrem GL NORMALIZE.
Bardzo pomocnym przy stosowaniu wektorów normalnych jest wprowa-
dzony w wersji 1.2 biblioteki OpenGL mechanizm automatycznego skalo-
wania jednostkowych wektorów normalnych. Przy jego zastosowaniu nor-
malizacja wektora normalnego jest wykonywana tylko raz, a późniejsze jego
modyfikacje wykonywane są wyłącznie przy skalowaniu macierzy modelowa-
nia, które, przypomnijmy, zmienia długość wektora normalnego.
1. Światła i materiały
10
Technikę automatycznego skalowania jednostkowych wektorów normal-
nych wprowadzono wcześniej w rozszerzeniu EXT rescale normal, a jej wy-
korzystanie sprowadza się do wywołania funkcji glEnable z parametrem
GL RESCALE NORMAL (lub GL RESCALE NORMAL EXT). Wyłączenie automatycz-
nego skalowania jednostkowych wektorów normalnych wymaga wywołania
funkcji glDisable z parametrem GL RESCALE NORMAL lub GL RESCALE NOR-
MAL EXT.
1.8. Odczyt parametrów źródła światła i materiałów
Odczyt ustawień wybranego źródła światła umożliwiają funkcje z grupy
glGetLight:
void glGetLightfv (GLenum light, GLenum pname, GLfloat *params)
void glGetLightiv (GLenum light, GLenum pname, GLint *params)
Znaczenie parametrów light i pname jest takie same jak analogicznych pa-
rametrów funkcji z grupy glLight. Wartości pobieranych ustawień źródła
światła umieszczane są w tablicy, do której wskaźnik należy podać w para-
metrze params.
Analogicznie wygląda pobieranie ustawień bieżącego materiału, do czego
służą funkcje z grupy glGetMaterial:
void glGetMaterialfv (GLenum face, GLenum pname,
GLfloat *params)
void glGetMaterialiv (GLenum face, GLenum pname,
GLint *params)
Parametry face i pname są odpowiednikami parametrów funkcji z grupy
glMaterial, a wartości pobieranych ustawień bieżącego materiału umiesz-
czane są w tablicy wskazywanej przez parametr params.
Oczywiście przy korzystaniu z powyższych funkcji program musi zapew-
nić wystarczającą ilość miejsca w tablicy, która będzie zawierała pobierane
parametry źródła światła lub materiału.
1.9. Programy przykładowe
Pierwszy przykładowy program (patrz plik globalne swiatlo otacza-
jace.cpp) oświetla scenę wyłącznie przy pomocy globalnego światła otacza-
jącego i pozwala na modyfikację wartości poszczególnych składowych RGB
tego światła. Jak już powiedzieliśmy na wstępie światło otaczające nie po-
chodzi z żadnego konkretnego kierunku i równomiernie oświetla wszystkie
elementy sceny 3D. Przedstawione wcześniej funkcje z grupy glLightModel
umożliwiają modyfikację globalnego światła otaczającego dla całej sceny 3D.
1. Światła i materiały
11
Pozwala to, przy braku innych źródeł światła, na równomierne oświetlenie
całej sceny.
Wartości początkowe składowych tego światła przyjęte w programie od-
powiadają wartościom domyślnym przyjmowanym przez bibliotekę OpenGL.
Początkowy wygląd ścian: czerwonej, niebieskiej i zielonej sześcianu RGB
przedstawia rysunek 2. Jak widać domyślne światło otaczające jest stosunko-
wo ciemne. Dla porównania rysunek 3 przedstawia te same ściany sześcianu
ale przy maksymalnych wartościach składowych RGB globalnego światła
otaczającego. Natomiast efekty oświetlenia obiektu sceny globalnych świa-
tłem otaczającym z wybranymi składowymi RGB o wartościach ujemnych
przedstawiają rysunki 4 i 5.
Rysunek 2. Program Globalne światło otaczające - ściany RGB przy po-
czątkowych (domyślnych) wartościach składowych RGB globalnego światła
otaczającego
1. Światła i materiały
12
Warto także zwrócić uwagę, że przy definiowaniu sześcianu nie były wy-
korzystywane wektory normalne. Nie ma takiej potrzeby, bowiem jak wcze-
śniej napisaliśmy, globalne światło otaczające nie pochodzi z żadnego kon-
kretnego kierunku.
W ramach ćwiczeń Czytelnik może łatwo sprawdzić, że wygląd sześcianu
RGB przedstawiony na rysunku 3, odpowiada wyglądowi tego samego sze-
ścianu ale przy wyłączonych efektach oświetlenia. Oznacza to, że domyślnie
biblioteka OpenGL faktycznie nie wykonuje żadnych obliczeń związanych
z oświetleniem, a obiekty są bezpośrednio rasteryzowane zgodnie z warto-
ściami składowych RGB.
Rysunek 3. Program Globalne światło otaczające - ściany RGB przy mak-
symalnych wartościach składowych RGB globalnego światła otaczającego
1. Światła i materiały
13
Rysunek 4. Program Globalne światło otaczające - ściany RGB przy mini-
malnej wartości składowej czerwonej globalnego światła otaczającego
1.9.1. Plik globalne swiatlo otaczajace.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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e
” c o l o r s . 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
o k n o
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
1. Światła i materiały
14
Rysunek 5. Program Globalne światło otaczające - ściany RGB przy mini-
malnej wartości składowych czerwonej i niebieskiej globalnego światła ota-
czającego
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 = − 2 . 0 ;
const GLdouble
r i g h t = 2 . 0 ;
const GLdouble bottom = − 2 . 0 ;
const GLdouble
t o p = 2 . 0 ;
const GLdouble
n e a r = 3 . 0 ;
const GLdouble
f a r = 7 . 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 ;
//
w s k a ź 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
1. Światła i materiały
15
i n t
b u t t o n x , b u t t o n y ;
//
s k ł a d o w e
g l o b a l n e g o
ś w i a t ł a
o t a c z a j ą c e g o
//
w a r t o ś ć
p o c z ą t k o w a
o d p o w i a d a
w a r t o ś c i
d o m y ś l n e j
//
s k ł a d o w y c h
t e g o
ś w i a t ł a
G L f l o a t
a m b i e n t l i g h t
[ 4 ] =
{
0 . 2 , 0 . 2 , 0 . 2 , 1 . 0
} ;
//
f u n k c j a
r y s u j ą c a
n a p i s w wybranym
m i e j s c u
void
D r a w S t r i n g
( G L f l o a t
x ,
G L f l o a t
y ,
char ∗ s t r i n g )
{
//
p o ł o ż e n i e
n a p i s u
g l R a s t e r P o s 2 f
( x , y ) ;
//
w y ś w i e t l e n i e
n a p i s u
i n t
l e n = s t r l e n
( s t r i n g ) ;
f o r
( i n t
i = 0 ;
i < l e n ;
i ++)
g l u t B i t m a p C h a r a c t e r
( GLUT BITMAP 9 BY 15 , s t r i n g
[ i ] ) ;
}
//
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
i
b u f o r a
g ł ę b o k o ś c i
g l C l e a r
( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(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
s z e ś c i a n 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 ) ;
//
o b r o t y
s z e ś c i a n u
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 ) ;
//
n i e w i e l k i e
p o w i ę k s z e n i e
s z e ś c i a n u
g l S c a l e f
( 1 . 1 5 , 1 . 1 5 , 1 . 1 5 ) ;
//
w ł ą c z e n i e
o ś w i e t l e n i a
g l E n a b l e
( GL LIGHTING ) ;
//
p a r a m e t r y
g l o b a l n e g o
ś w i a t ł a
o t a c z a j ą c e g o
g l L i g h t M o d e l f v
(GL LIGHT MODEL AMBIENT , a m b i e n t l i g h t ) ;
//
w ł ą c z e n i e
o b s ł u g i
w ł a ś c i w o ś c i
m a t e r i a ł ó w
g l E n a b l e
(GL COLOR MATERIAL ) ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u
o k r e ś l o n e
p r z e z
k o l o r
w i e r z c h o ł k ó w
g l C o l o r M a t e r i a l
(GL FRONT, GL AMBIENT ) ;
//
w ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l E n a b l e
(GL DEPTH TEST ) ;
//
r y s o w a n i e
s z e ś c i a n u − 12
t r ó j k ą t ó w
g l B e g i n
(GL TRIANGLES ) ;
g l C o l o r 3 f v
( Red ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l C o l o r 3 f v
( Magenta ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , − 1 . 0 ) ;
1. Światła i materiały
16
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l C o l o r 3 f v
( Cyan ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l C o l o r 3 f v
( Lime ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l C o l o r 3 f v
( B l u e ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , 1 . 0 ) ;
g l C o l o r 3 f v
( Y e l l o w ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( − 1 . 0 , − 1 . 0 , − 1 . 0 ) ;
g l V e r t e x 3 f
( 1 . 0 , 1 . 0 , − 1 . 0 ) ;
//
k o n i e c
d e f i n i c j i
s z e ś c i a n u
g l E n d
( ) ;
//
w y ł ą c z e n i e
o ś w i e t l e n i a
g l D i s a b l e
( GL LIGHTING ) ;
//
w y ł ą c z e n i e
o b s ł u g i
w ł a ś c i w o ś c i
m a t e r i a ł ó w
g l D i s a b l e
(GL COLOR MATERIAL ) ;
//
w y ś w i e t l e n i e
s k ł a d o w y c h
g l o b a l n e g o
ś w i a t ł a
o t a c z a j ą c e g o
char
s t r i n g
[ 1 0 0 ] ;
G L f l o a t
r g b a
[ 4 ] ;
g l C o l o r 3 f v
( B l a c k ) ;
//
p o b r a n i e
w a r t o ś c i
s k ł a d o w y c h
ś w i a t ł a
o t a c z a j ą c e g o
//
( o c z y w i ś c i e
w a r t o ś c i
t e
o d p o w i a d a j ą
t a b l i c y
a m b i e n t l i g h t )
g l G e t F l o a t v
(GL LIGHT MODEL AMBIENT , r g b a ) ;
s p r i n t f
( s t r i n g , ”AMBIENT : R=%f G=%f B=%f A=%f ” , r g b a [ 0 ] , r g b a [ 1 ] , r g b a [ 2 ] , r g b a [ 3 ] ) ;
//
t r z e b a
o d p o w i e d n i o
p r z e k s z t a ł c i ć
u k ł a d
w s p ó ł r z ę d n y c h
//
a b y
n a p i s
z n a j d o w a ł
s i ę
na
s a m e j
” g ó r z e ”
b r y ł y
o b c i n a n i a
g l L o a d I d e n t i t y
( ) ;
g l T r a n s l a t e f
( 0 , 0 , − n e a r ) ;
//
n a r y s o w a n i e
n a p i s u
D r a w S t r i n g
( l e f t , bottom , s t r i n g ) ;
//
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
( ) ;
//
z a m i a n a
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 ( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( 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
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
1. Światła i materiały
17
//
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 ś ć
o k n a
w i ę k s z a
od
w y s o k o ś c i
o k n a
i f
( w i d t h < h e i g h t && w i d t h > 0 )
g l F r u s t u m
( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;
e l s e
//
s z e r o k o ś ć
o k n a
w i ę k s z a
l u b
równa
w y s o k o ś c i
o k n a
i f
( w i d t h >= h e i g h t && h e i g h t > 0 )
g l F r u s t u m
( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;
}
e l s e
g l F r u s t u m
( l e f t , r i g h t , bottom , top , n e a r , 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 )
{
//
z m i a n a
w a r t o ś c i
s k ł a d o w e j R
i f
( k e y == ’R ’ && a m b i e n t l i g h t [ 0 ] < 1 . 0 )
a m b i e n t l i g h t [ 0 ] += 0 . 0 5 ;
e l s e
i f
( k e y == ’ r ’ && a m b i e n t l i g h t [ 0 ] > − 1 . 0 )
a m b i e n t l i g h t [ 0 ] −= 0 . 0 5 ;
//
z m i a n a
w a r t o ś c i
s k ł a d o w e j G
i f
( k e y == ’G ’ && a m b i e n t l i g h t [ 1 ] < 1 . 0 )
a m b i e n t l i g h t [ 1 ] += 0 . 0 5 ;
e l s e
i f
( k e y == ’ g ’ && a m b i e n t l i g h t [ 1 ] > − 1 . 0 )
a m b i e n t l i g h t [ 1 ] −= 0 . 0 5 ;
//
z m i a n a
w a r t o ś c i
s k ł a d o w e j B
i f
( k e y == ’B ’ && a m b i e n t l i g h t [ 2 ] < 1 . 0 )
a m b i e n t l i g h t [ 2 ] += 0 . 0 5 ;
e l s e
i f
( k e y == ’ b ’ && a m b i e n t l i g h t [ 2 ] > − 1 . 0 )
a m b i e n t l i g h t [ 2 ] −= 0 . 0 5 ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
//
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
( k e y )
{
//
k u r s o r w l e w o
c a s e GLUT KEY LEFT :
r o t a t e y −= 1 ;
break ;
//
k u r s o r w g ó r ę
c a s e GLUT KEY UP :
r o t a t e x −= 1 ;
break ;
//
k u r s o r w p r a w o
c a s e GLUT KEY RIGHT :
r o t a t e y += 1 ;
break ;
//
k u r s o r w d ó ł
c a s e GLUT KEY DOWN :
r o t a t e x += 1 ;
break ;
}
//
o d r y s o w a n i e
o k n a
R esh ape
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
1. Światła i materiały
18
}
//
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
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o 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)
{
r o t a t e y += 30
∗ ( 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 ;
r o t a t e x −= 30
∗ ( t o p − 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
o k n o
c a s e FULL WINDOW :
a s p e c t = FULL WINDOW ;
R esha pe
( 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
c a s e ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
R esha pe
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
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
(& a r g c , 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 | GLUT DEPTH ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
#i f d e f WIN32
g l u t C r e a t e W i n d o w
( ” G l o b a l n e
ś w i a t ł o
o t a c z a j ą c e ” ) ;
#e l s e
g l u t C r e a t e W i n d o w
( ” G l o b a l n e
s w i a t l o
o t a c z a j a c e ” ) ;
#e n d i f
//
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 ) ;
1. Światła i materiały
19
//
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
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
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
g l u t K e y b o a r d F u n c
( 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
g l u t M o u s e F u n c
( 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
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
//
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 = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a ł e
okno ” ,FULL WINDOW ) ;
#e l s e
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a l e
okno ” ,FULL WINDOW ) ;
#e n d i f
glutAddMenuEntry
( ” A s p e k t
o b r a z u
1 : 1 ” , ASPECT 1 1 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , 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 ) ;
#e n d i f
//
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 j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Drugi przykładowy program (plik materialy.cpp) prezentuje sposób
wykorzystania materiałów. Definicje materiałów, umieszczone w pliku
materials.h, pochodzą pochodzą z pracy „Advanced Graphics Program-
ming Techniques Using OpenGL” (SIGGRAPH 1998), która dostępna jest
pod adresem:
Do prezentacji materiałów wykorzystamy kwadryki, czyli powierzchnie
stopnia drugiego, udostępniane przez bibliotekę pomocniczą GLU. Nową
kwadrykę tworzymy wywołując funkcję:
GLUquadric* gluNewQuadric ()
Funkcja zwraca wskaźnik do struktury, lub klasy w przypadku użycia ję-
zyka C++, typu GLUquadric, który jest później używany przy wszelkich
operacjach na kwadrykach. Warto zauważyć, że specyfikacja biblioteki GLU
używa przy opisie kwadryk równorzędnego typu GLUquadricObj. Po zakoń-
czeniu używania kwadryki trzeba zwolnić przydzieloną jej pamięć wywołując
funkcję:
1. Światła i materiały
20
void gluDeleteQuadric (GLUquadric *state)
Biblioteka GLU udostępnia cztery rodzaje kwadryk. Są to: kula (sfera),
cylinder, dysk i niepełny dysk, przy czym dwie ostatnie są figurami płaskimi.
Kulę tworzy wywołanie funkcji:
void gluSphere (GLUquadric *quadobj,
GLdouble radius, GLint slices, GLint stacks)
której parametry radius, slices i stacks maję te same znaczenie jak para-
metry opisywanych wcześniej funkcji glutWireSphere i glutSolidSphere.
Parametr quadobj to oczywiście wskaźnik na strukturę (klasę) GLUquadric,
zwrócony przez funkcję gluNewQuadric przy tworzeniu kwadryki.
Cylinder tworzony jest poprzez wywołanie funkcji:
void gluCylinder (GLUquadric *quadobj,
GLdouble baseRadius, GLdouble topRadius,
GLdouble height, GLint slices, GLint stacks)
Parametry baseRadius i topRadius określają odpowiednio promień dolnej
i górnej podstawy cylindra. Promienie mogą oczywiście mieć różną wielkość,
co spowoduje utworzenie stożka ściętego. W szczególnym przypadku jeden
z promieni może mieć wartość 0. Jak się Czytelnik domyśla, otrzymamy wów-
czas stożek. W każdym przypadku obiekt rysowany jest bez górnej i dolnej
podstawy. Można je utworzyć korzystając z opisanego dalej dysku.
Parametry slices i stacks mają takie same znaczenie jak w przypadku
tworzenia kuli. Są to odpowiedniki południków i równoleżników na kuli.
W przypadku cylindra można je określić jako wzdłużne i poprzeczne seg-
menty.
Kolejną kwadryką dostępną w bibliotece GLU jest dysk (koło) tworzony
wywołaniem funkcji:
void gluDisk (GLUquadric *quadobj,
GLdouble innerRadius, GLdouble outerRadius,
GLint slices, GLint loops)
Parametry innerRadius i outerRadius określają promień wewnętrzny i ze-
wnętrzny dysku. Jeżeli promień wewnętrzny jest większy od 0, to dysk za-
wiera w środku okrągły otwór. Taką figurę nazywamy pierścieniem kołowym.
Parametry slices i loops określają ilość sektorów w kierunku obwodowym
i promieniowym, z których składa się dysk.
Ostatnią kwadryką dostępną w bibliotece GLU jest częściowy dysk (wy-
cinek kołowy). Tworzy go wywołanie funkcji:
void gluPartialDisk (GLUquadric *quadobj,
GLdouble innerRadius, GLdouble outerRadius,
1. Światła i materiały
21
GLint slices, GLint loops,
GLdouble startAngle, GLdouble sweepAngle)
Parametry innerRadius, outerRadius, slices i loops mają takie same
znaczenie jak przy tworzeniu dysku za pomocą funkcji gluDisk. Natomiast
parametry startAngle i sweepAngle określają kąt początkowy i kąt środko-
wy dysku. Jeżeli promień wewnętrzny, określony parametrem outerRadius,
jest większy od 0, otrzymamy figurę nazywaną wycinkiem pierścienia koło-
wego.
Biblioteka GLU zawiera cztery funkcje umożliwiające modyfikację sposo-
bu rysowania kwadryk. Trzy z nich zostały wykorzystane w przykładowym
programie, a czwartą obsługującą teksturowanie, wykorzystamy w jednym
z następnych odcinków kursu.
Sposób prezentacji kwadryki określa funkcja:
void gluQuadricDrawStyle (GLUquadric *quadobj,
GLenum drawStyle)
której parametr drawStyle przyjmuje jedną z poniższych wartości:
— GLU POINT - punkty,
— GLU LINE - odcinki,
— GLU FILL - pełna figura (wartość domyślna),
— GLU SILHOUETTE - odcinki, przy czym rysowane są tylko odcinki ze-
wnętrzne (brzegowe) figury.
Druga funkcja określa sposób generowania wektorów normalnych kwa-
dryk:
void gluQuadricNormals (GLUquadric *quadobj, GLenum normals)
Parametr normals przyjmuje jedną z wartości:
— GLU SMOOTH - wektor normalny określany jest dla każdego wierzchołka,
czyli z zastosowaniem opisywanej wcześniej techniki uśredniania wekto-
rów normalnych (wartość domyślna),
— GLU FLAT - wektor normalny określany jest dla każdej ściany,
— GLU NONE - wektory normalne nie są generowane.
Kolejna prezentowana funkcja określa orientację generowanych wektorów
normalnych:
void gluQuadricOrientation (GLUquadric *quadobj,
GLenum orientation)
Parametr orientation przyjmuje jedną z dwóch wartości:
— GLU OUTSIDE - wektory normalne skierowane na zewnątrz (wartość do-
myślna),
— GLU INSIDE - wektory normalne skierowane do wewnątrz.
1. Światła i materiały
22
Oczywiście pojęcia „na zewnątrz” i „do wewnątrz” nabierają różnego zna-
czenia w zależności od rodzaju rysowanej kwadryki. W przypadku figur pła-
skich będzie to po prostu jedna ze stron figury.
Zadaniem ostatniej z opisywanych funkcji jest nałożenie dwuwymiarowej
tekstury na kwadrykę:
void gluQuadricTexture (GLUquadric *quadobj, GLboolean texture)
Parametr quadobj to oczywiście wskaźnik do struktury (klasy) GLUquadric.
Drugi parametr określa czy kwadryka ma być teksturowana bieżącą teksturą
(GL TRUE) czy też nie (GL FALSE).
Ostatnim elementem obługi kwadryk w bibliotece GLU jest możliwość
zdefiniowania funkcji zwrotnej wywoływanej w momencie wystąpienia błędu.
Dołączenie funkcji zwrotnej realizuje funkcja:
void gluQuadricCallback (GLUquadric *quadobj,
GLenum which,
void (*fn)())
której parametr which określa rodzaj błędu obsługiwanego przez funkcję
zwrotną wskazywaną w parametrze fn. Ponieważ jednak w przypadku kwa-
dryk biblioteka GLU nie posiada specjalnego zestawu kodów błędów, jedyną
dopuszczalną wartością parametru which jest stała GLU ERROR.
Wróćmy teraz do możliwości naszego programu. Kwadryki oświetlane
są światłem GL LIGHT0 z parametrami domyślnymi. Program z założenia
nie modyfikuje żadnych ustawień tego źródła światła, umożliwia natomiast
wybór z poziomu menu podręcznego wszystkich opisanych wcześniej opcji
rysowania kwadryk. Z poziomu menu użytkownik może także wybrać ro-
dzaj materiału użytego do narysowania kwadryki. Dodatkowo przy pomocy
przycisków PageUp i PageDown można zmieniać ilość elementów, z których
będzie złożona kwadryka. Wyświetlany cały czas na ekranie wskaźnik FPS
(ang. frames per second) ilości ramek obrazu rysowanych w ciągu jednej
sekundy pozwala na jednoczesną weryfikację stosunku jakości generowane-
go obrazu do szybkości jego generowania. Wartość FPS jest obliczana po
narysowaniu co tysięcznej ramki obrazu.
Przykładowe efekty działania programu przedstawiono na rysunkach 6 -
10. W celu ujednolicenia opisu pod każdym rysunkiem po nazwie rysowanej
kwadryki umieszczono parametry z jaką została narysowana. Są to kolejno:
wektory normalne, orientacja, styl oraz ilość elementów użytych do rysowa-
nia kwadryki (odpowiednio ilość sektorów lub południków i równoleżników
figury). Nie należy tego mylić z ilością trójkątów lub innych prymitywów
graficznych użytych do narysowania figury.
1. Światła i materiały
23
Rysunek
6. Program
Materiały
-
kula:
mosiądz,
GLU SMOOTH,
GLU OUTSIDE, GLU FILL, 10
1.9.2. Plik materials.h
/∗
( 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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i f n d e f
MATERIALS
H
#d e f i n e
MATERIALS
H
#i n c l u d e <GL/ g l . h>
//
m o s i ą d z
const
G L f l o a t
B r a s s A m b i e n t
[ 4 ] =
{
0 . 3 2 9 4 1 2 ,
0 . 2 2 3 5 2 9 ,
0 . 0 2 7 4 5 1 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B r a s s D i f f u s e
[ 4 ] =
{
0 . 7 8 0 3 9 2 ,
0 . 5 6 8 6 2 7 ,
0 . 1 1 3 7 2 5 ,
1 . 0 0 0 0 0 0
} ;
1. Światła i materiały
24
Rysunek
7. Program
Materiały
-
cylinder:
brąz,
GLU SMOOTH,
GLU OUTSIDE, GLU FILL, 30
const
G L f l o a t
B r a s s S p e c u l a r
[ 4 ] =
{
0 . 9 9 2 1 5 7 ,
0 . 9 4 1 1 7 6 ,
0 . 8 0 7 8 4 3 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B r a s s S h i n i n e s s = 2 7 . 8 9 7 4 ;
//
b r ą z
const
G L f l o a t
BronzeAmbient
[ 4 ] =
{
0 . 2 1 2 5 0 0 ,
0 . 1 2 7 5 0 0 ,
0 . 0 5 4 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B r o n z e D i f f u s e
[ 4 ] =
{
0 . 7 1 4 0 0 0 ,
0 . 4 2 8 4 0 0 ,
0 . 1 8 1 4 4 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B r o n z e S p e c u l a r
[ 4 ] =
{
0 . 3 9 3 5 4 8 ,
0 . 2 7 1 9 0 6 ,
0 . 1 6 6 7 2 1 ,
1 . 0 0 0 0 0 0
} ;
1. Światła i materiały
25
Rysunek
8. Program
Materiały
-
dysk:
grafit,
GLU SMOOTH,
GLU OUTSIDE, GLU LINE, 20
const
G L f l o a t
B r o n z e S h i n i n e s s = 2 5 . 6 ;
//
p o l e r o w a n y
b r ą z
const
G L f l o a t
P o l i s h e d B r o n z e A m b i e n t
[ 4 ] =
{
0 . 2 5 0 0 0 0 ,
0 . 1 4 8 0 0 0 ,
0 . 0 6 4 7 5 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d B r o n z e D i f f u s e
[ 4 ] =
{
0 . 4 0 0 0 0 0 ,
0 . 2 3 6 8 0 0 ,
0 . 1 0 3 6 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d B r o n z e S p e c u l a r
[ 4 ] =
{
0 . 7 7 4 5 9 7 ,
0 . 4 5 8 5 6 1 ,
0 . 2 0 0 6 2 1 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d B r o n z e S h i n i n e s s = 7 6 . 8 ;
//
chrom
1. Światła i materiały
26
Rysunek 9. Program Materiały - kula: perła, GLU FLAT, GLU OUTSIDE,
GLU FILL, 40
const
G L f l o a t
ChromeAmbient
[ 4 ] =
{
0 . 2 5 0 0 0 0 ,
0 . 2 5 0 0 0 0 ,
0 . 2 5 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
C h r o m e D i f f u s e
[ 4 ] =
{
0 . 4 0 0 0 0 0 ,
0 . 4 0 0 0 0 0 ,
0 . 4 0 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
C h r o m e S p e c u l a r
[ 4 ] =
{
0 . 7 7 4 5 9 7 ,
0 . 7 7 4 5 9 7 ,
0 . 7 7 4 5 9 7 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
C h r o m e S h i n i n e s s = 7 6 . 8 ;
//
m i e d ź
const
G L f l o a t
CopperAmbient
[ 4 ] =
{
0 . 1 9 1 2 5 0 ,
0 . 0 7 3 5 0 0 ,
0 . 0 2 2 5 0 0 ,
1 . 0 0 0 0 0 0
} ;
1. Światła i materiały
27
Rysunek 10. Program Materiały - częściowy dysk: rubin, GLU FLAT,
GLU OUTSIDE, GLU POINT, 200
const
G L f l o a t
C o p p e r D i f f u s e
[ 4 ] =
{
0 . 7 0 3 8 0 0 ,
0 . 2 7 0 4 8 0 ,
0 . 0 8 2 8 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
C o p p e r S p e c u l a r
[ 4 ] =
{
0 . 2 5 6 7 7 7 ,
0 . 1 3 7 6 2 2 ,
0 . 0 8 6 0 1 4 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
C o p p e r S h i n i n e s s = 1 2 . 8 ;
//
p o l e r o w a n a
m i e d ź
const
G L f l o a t
P o l i s h e d C o p p e r A m b i e n t
[ 4 ] =
{
0 . 2 2 9 5 0 0 ,
0 . 0 8 8 2 5 0 ,
0 . 0 2 7 5 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d C o p p e r D i f f u s e
[ 4 ] =
{
0 . 5 5 0 8 0 0 ,
0 . 2 1 1 8 0 0 ,
0 . 0 6 6 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
1. Światła i materiały
28
const
G L f l o a t
P o l i s h e d C o p p e r S p e c u l a r
[ 4 ] =
{
0 . 5 8 0 5 9 4 ,
0 . 2 2 3 2 5 7 ,
0 . 0 6 9 5 7 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d C o p p e r S h i n i n e s s = 5 1 . 2 ;
//
z ł o t o
const
G L f l o a t
GoldAmbient
[ 4 ] =
{
0 . 2 4 7 2 5 0 ,
0 . 1 9 9 5 0 0 ,
0 . 0 7 4 5 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
G o l d D i f f u s e
[ 4 ] =
{
0 . 7 5 1 6 4 0 ,
0 . 6 0 6 4 8 0 ,
0 . 2 2 6 4 8 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
G o l d S p e c u l a r
[ 4 ] =
{
0 . 6 2 8 2 8 1 ,
0 . 5 5 5 8 0 2 ,
0 . 3 6 6 0 6 5 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
G o l d S h i n i n e s s = 5 2 . 2 ;
//
p o l e r o w a n e
z ł o t o
const
G L f l o a t
P o l i s h e d G o l d A m b i e n t
[ 4 ] =
{
0 . 2 4 7 2 5 0 ,
0 . 2 2 4 5 0 0 ,
0 . 0 6 4 5 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d G o l d D i f f u s e
[ 4 ] =
{
0 . 3 4 6 1 5 0 ,
0 . 3 1 4 3 0 0 ,
0 . 0 9 0 3 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d G o l d S p e c u l a r
[ 4 ] =
{
0 . 7 9 7 3 5 7 ,
0 . 7 2 3 9 9 1 ,
0 . 2 0 8 0 0 6 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d G o l d S h i n i n e s s = 8 3 . 2 ;
//
c y n a
z
o ł o w i e m
( g r a f i t )
const
G L f l o a t
PewterAmbient
[ 4 ] =
{
0 . 1 0 5 8 8 2 ,
0 . 0 5 8 8 2 4 ,
0 . 1 1 3 7 2 5 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P e w t e r D i f f u s e
[ 4 ] =
{
0 . 4 2 7 4 5 1 ,
0 . 4 7 0 5 8 8 ,
0 . 5 4 1 1 7 6 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P e w t e r S p e c u l a r
[ 4 ] =
{
0 . 3 3 3 3 3 3 ,
0 . 3 3 3 3 3 3 ,
0 . 5 2 1 5 6 9 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P e w t e r S h i n i n e s s = 9 . 8 4 6 1 5 ;
//
s r e b r o
const
G L f l o a t
S i l v e r A m b i e n t
[ 4 ] =
{
0 . 1 9 2 2 5 0 ,
0 . 1 9 2 2 5 0 ,
0 . 1 9 2 2 5 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
S i l v e r D i f f u s e
[ 4 ] =
{
0 . 5 0 7 5 4 0 ,
0 . 5 0 7 5 4 0 ,
0 . 5 0 7 5 4 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
S i l v e r S p e c u l a r
[ 4 ] =
{
0 . 5 0 8 2 7 3 ,
0 . 5 0 8 2 7 3 ,
0 . 5 0 8 2 7 3 ,
1 . 0 0 0 0 0 0
} ;
1. Światła i materiały
29
const
G L f l o a t
S i l v e r S h i n i n e s s = 5 1 . 2 ;
//
p o l e r o w a n e
s r e b r o
const
G L f l o a t
P o l i s h e d S i l v e r A m b i e n t
[ 4 ] =
{
0 . 2 3 1 2 5 0 ,
0 . 2 3 1 2 5 0 ,
0 . 2 3 1 2 5 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d S i l v e r D i f f u s e
[ 4 ] =
{
0 . 2 7 7 5 0 0 ,
0 . 2 7 7 5 0 0 ,
0 . 2 7 7 5 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d S i l v e r S p e c u l a r
[ 4 ] =
{
0 . 7 7 3 9 1 1 ,
0 . 7 7 3 9 1 1 ,
0 . 7 7 3 9 1 1 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
P o l i s h e d S i l v e r S h i n i n e s s = 8 9 . 6 ;
//
s z m a r a g d
const
G L f l o a t
EmeraldAmbient
[ 4 ] =
{
0 . 0 2 1 5 0 0 ,
0 . 1 7 4 5 0 0 ,
0 . 0 2 1 5 0 0 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
E m e r a l d D i f f u s e
[ 4 ] =
{
0 . 0 7 5 6 8 0 ,
0 . 6 1 4 2 4 0 ,
0 . 0 7 5 6 8 0 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
E m e r a l d S p e c u l a r
[ 4 ] =
{
0 . 6 3 3 0 0 0 ,
0 . 7 2 7 8 1 1 ,
0 . 6 3 3 0 0 0 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
E m e r a l d S h i n i n e s s = 7 6 . 8 ;
//
j a d e i t
const
G L f l o a t
JadeAmbient
[ 4 ] =
{
0 . 1 3 5 0 0 0 ,
0 . 2 2 2 5 0 0 ,
0 . 1 5 7 5 0 0 ,
0 . 9 5 0 0 0 0
} ;
const
G L f l o a t
J a d e D i f f u s e
[ 4 ] =
{
0 . 5 4 0 0 0 0 ,
0 . 8 9 0 0 0 0 ,
0 . 6 3 0 0 0 0 ,
0 . 9 5 0 0 0 0
} ;
const
G L f l o a t
J a d e S p e c u l a r
[ 4 ] =
{
0 . 3 1 6 2 2 8 ,
0 . 3 1 6 2 2 8 ,
0 . 3 1 6 2 2 8 ,
0 . 9 5 0 0 0 0
} ;
const
G L f l o a t
J a d e S h i n i n e s s = 1 2 . 8 ;
//
o b s y d i a n
( s z k ł o
w u l k a n i c z n e )
const
G L f l o a t
O b s i d i a n A m b i e n t
[ 4 ] =
{
0 . 0 5 3 7 5 0 ,
0 . 0 5 0 0 0 0 ,
0 . 0 6 6 2 5 0 ,
0 . 8 2 0 0 0 0
} ;
const
G L f l o a t
O b s i d i a n D i f f u s e
[ 4 ] =
{
0 . 1 8 2 7 5 0 ,
0 . 1 7 0 0 0 0 ,
0 . 2 2 5 2 5 0 ,
0 . 8 2 0 0 0 0
} ;
const
G L f l o a t
O b s i d i a n S p e c u l a r
[ 4 ] =
{
0 . 3 3 2 7 4 1 ,
0 . 3 2 8 6 3 4 ,
0 . 3 4 6 4 3 5 ,
0 . 8 2 0 0 0 0
} ;
const
G L f l o a t
O b s i d i a n S h i n i n e s s = 3 8 . 4 ;
//
p e r ł a
1. Światła i materiały
30
const
G L f l o a t
P e a r l A m b i e n t
[ 4 ] =
{
0 . 2 5 0 0 0 0 ,
0 . 2 0 7 2 5 0 ,
0 . 2 0 7 2 5 0 ,
0 . 9 2 2 0 0 0
} ;
const
G L f l o a t
P e a r l D i f f u s e
[ 4 ] =
{
1 . 0 0 0 0 0 0 ,
0 . 8 2 9 0 0 0 ,
0 . 8 2 9 0 0 0 ,
0 . 9 2 2 0 0 0
} ;
const
G L f l o a t
P e a r l S p e c u l a r
[ 4 ] =
{
0 . 2 9 6 6 4 8 ,
0 . 2 9 6 6 4 8 ,
0 . 2 9 6 6 4 8 ,
0 . 9 2 2 0 0 0
} ;
const
G L f l o a t
P e a r l S h i n i n e s s = 1 1 . 2 6 4 ;
//
r u b i n
const
G L f l o a t
RubyAmbient
[ 4 ] =
{
0 . 1 7 4 5 0 0 ,
0 . 0 1 1 7 5 0 ,
0 . 0 1 1 7 5 0 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
R u b y D i f f u s e
[ 4 ] =
{
0 . 6 1 4 2 4 0 ,
0 . 0 4 1 3 6 0 ,
0 . 0 4 1 3 6 0 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
R u b y S p e c u l a r
[ 4 ] =
{
0 . 7 2 7 8 1 1 ,
0 . 6 2 6 9 5 9 ,
0 . 6 2 6 9 5 9 ,
0 . 5 5 0 0 0 0
} ;
const
G L f l o a t
R u b y S h i n i n e s s = 7 6 . 8 ;
//
t u r k u s
const
G L f l o a t
T u r q u o i s e A m b i e n t
[ 4 ] =
{
0 . 1 0 0 0 0 0 ,
0 . 1 8 7 2 5 0 ,
0 . 1 7 4 5 0 0 ,
0 . 8 0 0 0 0 0
} ;
const
G L f l o a t
T u r q u o i s e D i f f u s e
[ 4 ] =
{
0 . 3 9 6 0 0 0 ,
0 . 7 4 1 5 1 0 ,
0 . 6 9 1 0 2 0 ,
0 . 8 0 0 0 0 0
} ;
const
G L f l o a t
T u r q u o i s e S p e c u l a r
[ 4 ] =
{
0 . 2 9 7 2 5 4 ,
0 . 3 0 8 2 9 0 ,
0 . 3 0 6 6 7 8 ,
0 . 8 0 0 0 0 0
} ;
const
G L f l o a t
T u r q u o i s e S h i n i n e s s = 1 2 . 8 ;
//
c z a r n y
p l a s t i k
const
G L f l o a t
B l a c k P l a s t i c A m b i e n t
[ 4 ] =
{
0 . 0 0 0 0 0 0 ,
0 . 0 0 0 0 0 0 ,
0 . 0 0 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B l a c k P l a s t i c D i f f u s e
[ 4 ] =
{
0 . 0 1 0 0 0 0 ,
0 . 0 1 0 0 0 0 ,
0 . 0 1 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B l a c k P l a s t i c S p e c u l a r
[ 4 ] =
{
0 . 5 0 0 0 0 0 ,
0 . 5 0 0 0 0 0 ,
0 . 5 0 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B l a c k P l a s t i c S h i n i n e s s = 3 2 ;
//
c z a r n a
guma
const
G L f l o a t
BlackRubberAmbient
[ 4 ] =
{
0 . 0 2 0 0 0 0 ,
0 . 0 2 0 0 0 0 ,
0 . 0 2 0 0 0 0 ,
1 . 0 0 0 0 0 0
1. Światła i materiały
31
} ;
const
G L f l o a t
B l a c k R u b b e r D i f f u s e
[ 4 ] =
{
0 . 0 1 0 0 0 0 ,
0 . 0 1 0 0 0 0 ,
0 . 0 1 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B l a c k R u b b e r S p e c u l a r
[ 4 ] =
{
0 . 0 4 0 0 0 0 ,
0 . 0 4 0 0 0 0 ,
0 . 0 4 0 0 0 0 ,
1 . 0 0 0 0 0 0
} ;
const
G L f l o a t
B l a c k R u b b e r S h i n i n e s s = 1 0 ;
#e n d i f
//
MATERIALS H
1.9.3. Plik materlaly.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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l u . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e <t i m e . h>
#i n c l u d e
” c o l o r s . h ”
#i n c l u d e
” m a t e r i a l s . h ”
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
//
o b i e k t y
SPHERE,
//
k u l a
CYLINDER,
//
c y l i n d e r
DISK ,
//
d y s k
PARTIAL DISK ,
//
c z ę ś c i o w y
d y s k
//
m a t e r i a ł y
BRASS ,
//
m o s i ą d z
BRONZE,
//
b r ą z
POLISHED BRONZE ,
//
p o l e r o w a n y
b r ą z
CHROME,
//
chrom
COPPER,
//
m i e d ź
POLISHED COPPER ,
//
p o l e r o w a n a
m i e d ź
GOLD,
//
z ł o t o
POLISHED GOLD ,
//
p o l e r o w a n e
z ł o t o
PEWTER,
//
g r a f i t
( c y n a
z
o ł o w i e m )
SILVER ,
//
s r e b r o
POLISHED SILVER ,
//
p o l e r o w a n e
s r e b r o
EMERALD,
//
s z m a r a g d
JADE,
//
j a d e i t
OBSIDIAN ,
//
o b s y d i a n
PEARL,
//
p e r ł a
RUBY,
//
r u b i n
TURQUOISE,
//
t u r k u s
BLACK PLASTIC ,
//
c z a r n y
p l a s t i k
BLACK RUBBER,
//
c z a r n a
guma
//
w e k t o r y
n o r m a l n e
NORMALS SMOOTH,
// GLU SMOOTH
NORMALS FLAT,
// GLU FLAT
NORMALS NONE,
// GLU NONE
//
o r i e n t a c j a
ORIENTATION OUTSIDE ,
// GLU OUTSIDE
ORIENTATION INSIDE ,
// GLU INSIDE
//
s t y l
STYLE POINT ,
// GLU POINT
STYLE LINE ,
// GLU LINE
STYLE FILL ,
// GLU FILL
1. Światła i materiały
32
STYLE SILHOUETTE ,
// GLU SILHOUETTE
//
o b s z a r
r e n d e r i n g u
FULL WINDOW,
//
a s p e k t
o b r a z u − c a ł e
o k n o
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 ;
const GLdouble
r i g h t = 1 . 0 ;
const GLdouble bottom = − 1 . 0 ;
const GLdouble
t o p = 1 . 0 ;
const GLdouble
n e a r = 3 . 0 ;
const GLdouble
f a r = 7 . 0 ;
//
k ą t y
o b r o t u
o b i e k 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 ;
//
w s k a ź 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 ;
//
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 5 ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u − d o m y ś l n i e
m o s i ą d z
const
G L f l o a t
∗ a m b i e n t = B r a s s A m b i e n t ;
const
G L f l o a t
∗ d i f f u s e = B r a s s D i f f u s e ;
const
G L f l o a t
∗ s p e c u l a r = B r a s s S p e c u l a r ;
G L f l o a t
s h i n i n e s s = B r a s s S h i n i n e s s ;
//
w y ś w i e t l a n y
o b i e k t
3D
i n t
o b j e c t = SPHERE ;
//
w e k t o r y
n o r m a l n e
i n t
n o r m a l s = NORMALS SMOOTH;
//
o r i e n t a c j a
i n t
o r i e n t a t i o n = GLU OUTSIDE ;
//
s t y l
i n t
s t y l e = GLU FILL ;
//
i l o ś ć
s e g m e n t ó w
o b i e k t u
i n t
s e g m e n t s = 1 0 ;
//
l i c z n i k
ramek
( FPS )
i n t
f r a m e s = 0 ;
//
l i c z n i k
c z a s u
long
s t a r t t i m e = 0 ;
//
t a b l i c a
z n a k ó w
z e
w a r t o ś c i ą
FPS
char
t i m e s t r i n g
[ 1 0 0 ] = ”FPS : ” ;
//
f u n k c j a
r y s u j ą c a
n a p i s w wybranym
m i e j s c u
void
D r a w S t r i n g
( G L f l o a t
x ,
G L f l o a t
y ,
char ∗ s t r i n g )
1. Światła i materiały
33
{
//
p o ł o ż e n i e
n a p i s u
g l R a s t e r P o s 2 f
( x , y ) ;
//
w y ś w i e t l e n i e
n a p i s u
i n t
l e n = s t r l e n
( s t r i n g ) ;
f o r
( i n t
i = 0 ;
i < l e n ;
i ++)
g l u t B i t m a p C h a r a c t e r
( GLUT BITMAP 9 BY 15 , s t r i n g
[ i ] ) ;
}
//
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
( )
{
//
l i c z n i k
c z a s u
i f
( ! f r a m e s ++)
s t a r t t i m e = c l o c k
( ) ;
//
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
i
b u f o r a
g ł ę b o k o ś c i
g l C l e a r
( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(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
( ) ;
//
w ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l E n a b l e
(GL DEPTH TEST ) ;
//
w ł ą c z e n i e
o ś w i e t l e n i a
g l E n a b l e
( GL LIGHTING ) ;
//
w ł ą c z e n i e
ś w i a t ł a
GL LIGHT0 z
p a r a m e t r a m i
d o m y ś l n y m i
g l E n a b l e
( GL LIGHT0 ) ;
//
w ł ą c z e n i e
a u t o m a t y c z n e j
n o r m a l i z a c j i
w e k t o r ó w
n o r m a l n y c h
g l E n a b l e
(GL NORMALIZE ) ;
//
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 ) ;
//
o b r o t y
o b i e k t u
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 ) ;
//
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 ) ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u
g l M a t e r i a l f v
(GL FRONT AND BACK, GL AMBIENT, a m b i e n t ) ;
g l M a t e r i a l f v
(GL FRONT AND BACK, GL DIFFUSE , d i f f u s e ) ;
g l M a t e r i a l f v
(GL FRONT AND BACK, GL SPECULAR, s p e c u l a r ) ;
g l M a t e r i a l f
(GL FRONT AND BACK, GL SHININESS , s h i n i n e s s ) ;
//
u t w o r z e n i e
k w a d r y k i
GLUquadricObj ∗ q u a d o b j = g l u N e w Q u a d r i c ( ) ;
//
s p o s ó b
g e n e r a c j i
w e k t o r ó w
n o r m a l n y c h
g l u Q u a d r i c N o r m a l s
( q u a d o b j , n o r m a l s ) ;
//
s t y l
( ( w y g l ą d )
g e n e r o w a n e j
k w a d r y k i
g l u Q u a d r i c D r a w S t y l e
( q u a d o b j , s t y l e ) ;
//
o k r e ś l e n i e
o r i e n t a c j i
w e k t o r ó w
n o r m a l n y c h
k w a d r y k i
g l u Q u a d r i c O r i e n t a t i o n
( q u a d o b j , o r i e n t a t i o n ) ;
//
w y b ó r
r y s o w a n e g o
o b i e k t u
3D
switch
( o b j e c t )
{
c a s e SPHERE :
g l u S p h e r e
( q u a d o b j , 1 , s e g m e n t s , s e g m e n t s ) ;
break ;
c a s e CYLINDER :
g l u C y l i n d e r
( q u a d o b j , 0 . 5 , 0 . 5 , 1 , s e g m e n t s , s e g m e n t s ) ;
break ;
c a s e DISK :
1. Światła i materiały
34
g l u D i s k
( q u a d o b j , 0 . 5 , 1 . 0 , s e g m e n t s , s e g m e n t s ) ;
break ;
c a s e PARTIAL DISK :
g l u P a r t i a l D i s k
( q u a d o b j , 0 . 5 , 1 . 0 , s e g m e n t s , s e g m e n t s , 9 0 , 1 8 0 ) ;
break ;
}
//
u s u n i ę c i e
k w a d r y k i
g l u D e l e t e Q u a d r i c
( q u a d o b j ) ;
//
w y ł ą c z e n i e
o ś w i e t l e n i a
g l D i s a b l e
( GL LIGHTING ) ;
//
w y ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l D i s a b l e
(GL DEPTH TEST ) ;
//
t r z e b a
o d p o w i e d n i o
p r z e k s z t a ł c i ć
u k ł a d
w s p ó ł r z ę d n y c h
//
a b y
n a p i s
z n a j d o w a ł
s i ę
na
s a m e j
” g ó r z e ”
b r y ł y
o b c i n a n i a
g l L o a d I d e n t i t y
( ) ;
g l T r a n s l a t e f
( 0 , 0 , − n e a r ) ;
//
k o m u n i k a t
o
i l o ś c i
ramek
r y s o w a n y c h
na
s e k u n d ę
( FPS )
g l C o l o r 3 f v
( B l a c k ) ;
i f
( f r a m e s == 1 0 0 0 )
{
f r a m e s = 0 ;
s p r i n t f
( t i m e s t r i n g , ”FPS : %i ” , ( i n t ) ( 1 0 0 0 ∗ CLOCKS PER SEC / ( f l o a t ) ( c l o c k
() − s t a r t t i m e ) ) ) ;
}
//
n a r y s o w a n i e
n a p i s u
D r a w S t r i n g
( l e f t , bottom , t i m e s t r i n g ) ;
//
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
( ) ;
//
z a m i a n a
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 ( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( 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
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(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 ś ć
o k n a
w i ę k s z a
od
w y s o k o ś c i
o k n a
i f
( w i d t h < h e i g h t && w i d t h > 0 )
g l F r u s t u m
( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;
e l s e
//
s z e r o k o ś ć
o k n a
w i ę k s z a
l u b
równa
w y s o k o ś c i
o k n a
i f
( w i d t h >= h e i g h t && h e i g h t > 0 )
g l F r u s t u m
( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;
}
e l s e
g l F r u s t u m
( l e f t , r i g h t , bottom , top , n e a r , 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
( k e y == ’+ ’ )
s c a l e += 0 . 0 5 ;
e l s e
1. Światła i materiały
35
//
k l a w i s z −
i f
( k e y == ’− ’ && s c a l e > 0 . 0 5 )
s c a l e −= 0 . 0 5 ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
//
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
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o 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)
{
r o t a t e y += 30
∗ ( 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 ;
r o t a t e x −= 30
∗ ( t o p − 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
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
( k e y )
{
// PageUp
c a s e GLUT KEY PAGE UP :
s e g m e n t s += 1 0 ;
break ;
// PageDown
c a s e GLUT KEY PAGE DOWN :
i f
( s e g m e n t s > 1 0 )
s e g m e n t s −= 1 0 ;
break ;
}
//
o d r y s o w a n i e
o k n a
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 )
{
//
r y s o w a n y
o b i e k t − k u l a
c a s e SPHERE :
o b j e c t = SPHERE ;
D i s p l a y
( ) ;
break ;
//
r y s o w a n y
o b i e k t − c y l i n d e r
c a s e CYLINDER :
o b j e c t = CYLINDER ;
D i s p l a y
( ) ;
break ;
1. Światła i materiały
36
//
r y s o w a n y
o b i e k t − d y s k
c a s e DISK :
o b j e c t = DISK ;
D i s p l a y
( ) ;
break ;
//
r y s o w a n y
o b i e k t − c z ę ś c i o w y
d y s k
c a s e PARTIAL DISK :
o b j e c t = PARTIAL DISK ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − m o s i ą d z
c a s e BRASS :
a m b i e n t = B r a s s A m b i e n t ;
d i f f u s e = B r a s s D i f f u s e ;
s p e c u l a r = B r a s s S p e c u l a r ;
s h i n i n e s s = B r a s s S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − b r ą z
c a s e BRONZE:
a m b i e n t = BronzeAmbient ;
d i f f u s e = B r o n z e D i f f u s e ;
s p e c u l a r = B r o n z e S p e c u l a r ;
s h i n i n e s s = B r o n z e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n y
b r ą z
c a s e POLISHED BRONZE :
a m b i e n t = P o l i s h e d B r o n z e A m b i e n t ;
d i f f u s e = P o l i s h e d B r o n z e D i f f u s e ;
s p e c u l a r = P o l i s h e d B r o n z e S p e c u l a r ;
s h i n i n e s s = P o l i s h e d B r o n z e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − chrom
c a s e CHROME:
a m b i e n t = ChromeAmbient ;
d i f f u s e = C h r o m e D i f f u s e ;
s p e c u l a r = C h r o m e S p e c u l a r ;
s h i n i n e s s = C h r o m e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − m i e d ź
c a s e COPPER:
a m b i e n t = CopperAmbient ;
d i f f u s e = C o p p e r D i f f u s e ;
s p e c u l a r = C o p p e r S p e c u l a r ;
s h i n i n e s s = C o p p e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n a
m i e d ź
c a s e POLISHED COPPER :
a m b i e n t = P o l i s h e d C o p p e r A m b i e n t ;
d i f f u s e = P o l i s h e d C o p p e r D i f f u s e ;
s p e c u l a r = P o l i s h e d C o p p e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d C o p p e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − z ł o t o
c a s e GOLD:
a m b i e n t = GoldAmbient ;
d i f f u s e = G o l d D i f f u s e ;
s p e c u l a r = G o l d S p e c u l a r ;
s h i n i n e s s = G o l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
z ł o t o
c a s e POLISHED GOLD :
a m b i e n t = P o l i s h e d G o l d A m b i e n t ;
d i f f u s e = P o l i s h e d G o l d D i f f u s e ;
s p e c u l a r = P o l i s h e d G o l d S p e c u l a r ;
1. Światła i materiały
37
s h i n i n e s s = P o l i s h e d G o l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − g r a f i t
( c y n a
z
o ł o w i e m )
c a s e PEWTER:
a m b i e n t = PewterAmbient ;
d i f f u s e = P e w t e r D i f f u s e ;
s p e c u l a r = P e w t e r S p e c u l a r ;
s h i n i n e s s = P e w t e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − s r e b r o
c a s e SILVER :
a m b i e n t = S i l v e r A m b i e n t ;
d i f f u s e = S i l v e r D i f f u s e ;
s p e c u l a r = S i l v e r S p e c u l a r ;
s h i n i n e s s = S i l v e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
s r e b r o
c a s e POLISHED SILVER :
a m b i e n t = P o l i s h e d S i l v e r A m b i e n t ;
d i f f u s e = P o l i s h e d S i l v e r D i f f u s e ;
s p e c u l a r = P o l i s h e d S i l v e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d S i l v e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − s z m a r a g d
c a s e EMERALD:
a m b i e n t = EmeraldAmbient ;
d i f f u s e = E m e r a l d D i f f u s e ;
s p e c u l a r = E m e r a l d S p e c u l a r ;
s h i n i n e s s = E m e r a l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − j a d e i t
c a s e JADE :
a m b i e n t = JadeAmbient ;
d i f f u s e = J a d e D i f f u s e ;
s p e c u l a r = J a d e S p e c u l a r ;
s h i n i n e s s = J a d e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − o b s y d i a n
c a s e OBSIDIAN :
a m b i e n t = O b s i d i a n A m b i e n t ;
d i f f u s e = O b s i d i a n D i f f u s e ;
s p e c u l a r = O b s i d i a n S p e c u l a r ;
s h i n i n e s s = O b s i d i a n S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p e r ł a
c a s e PEARL :
a m b i e n t = P e a r l A m b i e n t ;
d i f f u s e = P e a r l D i f f u s e ;
s p e c u l a r = P e a r l S p e c u l a r ;
s h i n i n e s s = P e a r l S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m e t a r i a ł − r u b i n
c a s e RUBY:
a m b i e n t = RubyAmbient ;
d i f f u s e = R u b y D i f f u s e ;
s p e c u l a r = R u b y S p e c u l a r ;
s h i n i n e s s = R u b y S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − t u r k u s
c a s e TURQUOISE :
a m b i e n t = T u r q u o i s e A m b i e n t ;
d i f f u s e = T u r q u o i s e D i f f u s e ;
1. Światła i materiały
38
s p e c u l a r = T u r q u o i s e S p e c u l a r ;
s h i n i n e s s = T u r q u o i s e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − c z a r n y
p l a s t i k
c a s e BLACK PLASTIC :
a m b i e n t = B l a c k P l a s t i c A m b i e n t ;
d i f f u s e = B l a c k P l a s t i c D i f f u s e ;
s p e c u l a r = B l a c k P l a s t i c S p e c u l a r ;
s h i n i n e s s = B l a c k P l a s t i c S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − c z a r n a
guma
c a s e BLACK RUBBER :
a m b i e n t = BlackRubberAmbient ;
d i f f u s e = B l a c k R u b b e r D i f f u s e ;
s p e c u l a r = B l a c k R u b b e r S p e c u l a r ;
s h i n i n e s s = B l a c k R u b b e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
w e k t o r y
n o r m a l n e − GLU SMOOTH
c a s e NORMALS SMOOTH:
n o r m a l s = GLU SMOOTH ;
D i s p l a y
( ) ;
break ;
//
w e k t o r y
n o r m a l n e − GLU FLAT
c a s e NORMALS FLAT :
n o r m a l s = GLU FLAT ;
D i s p l a y
( ) ;
break ;
//
w e k t o r y
n o r m a l n e − GLU NONE
c a s e NORMALS NONE :
n o r m a l s = GLU NONE ;
D i s p l a y
( ) ;
break ;
//
o r i e n t a c j a − GLU OUTSIDE
c a s e ORIENTATION OUTSIDE :
o r i e n t a t i o n = GLU OUTSIDE ;
D i s p l a y
( ) ;
break ;
//
o r i e n t a c j a − GLU INSIDE
c a s e ORIENTATION INSIDE :
o r i e n t a t i o n = GLU INSIDE ;
D i s p l a y
( ) ;
break ;
//
s t y l − GLU POINT
c a s e STYLE POINT :
s t y l e = GLU POINT ;
D i s p l a y
( ) ;
break ;
//
s t y l − GLU LINE
c a s e STYLE LINE :
s t y l e = GLU LINE ;
D i s p l a y
( ) ;
break ;
//
s t y l − GLU FILL
c a s e STYLE FILL :
s t y l e = GLU FILL ;
D i s p l a y
( ) ;
break ;
//
s t y l − GLU SILHOUETTE
c a s e STYLE SILHOUETTE :
s t y l e = GLU SILHOUETTE ;
D i s p l a y
( ) ;
break ;
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
c a s e FULL WINDOW :
a s p e c t = FULL WINDOW ;
1. Światła i materiały
39
R esha pe
( 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
c a s e ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
R esha pe
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
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
(& a r g c , 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 | GLUT DEPTH ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
#i f d e f WIN32
g l u t C r e a t e W i n d o w
( ” M a t e r i a ł y ” ) ;
#e l s e
g l u t C r e a t e W i n d o w
( ” M a t e r i a l y ” ) ;
#e n d i f
//
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
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
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
g l u t K e y b o a r d F u n c
( 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
g l u t M o u s e F u n c
( 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
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
//
u t w o r z e n i e
podmenu − o b i e k t
i n t
MenuObject = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ” Kula ” ,SPHERE ) ;
glutAddMenuEntry
( ” C y l i n d e r ” ,CYLINDER ) ;
glutAddMenuEntry
( ” Dysk ” , DISK ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” C z ę ś c i o w y
d y s k ” , PARTIAL DISK ) ;
#e l s e
glutAddMenuEntry
( ” C z e s c i o w y
d y s k ” , PARTIAL DISK ) ;
#e n d i f
//
u t w o r z e n i e
podmenu − M a t e r i a ł
i n t
M e n u M a t e r i a l = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” M o s i ą d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r ąz ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r ą z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedź ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d ź ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z ł o t o ” ,GOLD ) ;
1. Światła i materiały
40
glutAddMenuEntry
( ” P o l e r o w a n e
z ł o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r ł a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e l s e
glutAddMenuEntry
( ” M o s i a d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r az ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r a z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedz ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d z ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z l o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z l o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r l a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e n d i f
//
u t w o r z e n i e
podmenu − W e k t o r y
n o r m a l n e
i n t
MenuNormals = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ”GLU SMOOTH” ,NORMALS SMOOTH ) ;
glutAddMenuEntry
( ”GLU FLAT” ,NORMALS FLAT ) ;
glutAddMenuEntry
( ”GLU NONE” ,NORMALS NONE ) ;
//
u t w o r z e n i e
podmenu − O r i e n t a c j a
i n t
M e n u O r i e n t a t i o n = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ”GLU OUTSIDE” ,ORIENTATION OUTSIDE ) ;
glutAddMenuEntry
( ”GLU INSIDE” , ORIENTATION INSIDE ) ;
//
u t w o r z e n i e
podmenu − S t y l
i n t
M e n u S t y l e = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ”GLU POINT” , STYLE POINT ) ;
glutAddMenuEntry
( ”GLU LINE” , STYLE LINE ) ;
glutAddMenuEntry
( ”GLU FILL” , STYLE FILL ) ;
glutAddMenuEntry
( ”GLU SILHOUETTE” ,STYLE SILHOUETTE ) ;
//
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 = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a ł e
okno ” ,FULL WINDOW ) ;
#e l s e
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a l e
okno ” ,FULL WINDOW ) ;
#e n d i f
glutAddMenuEntry
( ” A s p e k t
o b r a z u
1 : 1 ” , ASPECT 1 1 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
glutAddSubMenu
( ” O b i e k t ” , MenuObject ) ;
#i f d e f WIN32
glutAddSubMenu
( ” M a t e r i a ł ” , M e n u M a t e r i a l ) ;
#e l s e
glutAddSubMenu
( ” M a t e r i a l ” , M e n u M a t e r i a l ) ;
#e n d i f
glutAddSubMenu
( ” Wektory
n o r m a l n e ” , MenuNormals ) ;
glutAddSubMenu
( ” O r i e n t a c j a ” , M e n u O r i e n t a t i o n ) ;
glutAddSubMenu
( ” S t y l ” , M e n u S t y l e ) ;
1. Światła i materiały
41
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , 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 ) ;
#e n d i f
//
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 j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
f u n k c j a
b e z c z y n n o ś c i
g l u t I d l e F u n c
( D i s p l a y ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Kolejny program przykładowy (plik wektory normalne.cpp) przedsta-
wia dwa opisane wcześniej sposoby generowania wektorów normalnych. Ale
zanim przejdziemy do opisu obliczania wektorów normalnych popatrzmy na
sposób opisu bryły wyświetlanej przez program - dwudziestościanu forem-
nego.
Dwudziestościan opisany jest przez dwie tablice. Pierwsza tablica vertex
opisuje współrzędne położenia wierzchołków figury. Druga tablica triangles
zawiera opis poszczególnych trójkątów, z których składa się dwudziestościan.
Jedną z cech takiego rodzaju opis bryły jest łatwość obliczania wektorów
normalnych. W przypadku, gdy do obliczamy wektor normalny dla ścia-
ny, wystarczy skorzystać z iloczynu wektorowego, przy czym składniki tego
iloczynu stanowią wektory utworzone z dwóch boków trójkąta. W przykła-
dowym programie realizuje to funkcja Normal. Natomiast w przypadku, gdy
obliczamy wektor normalny dla każdego wierzchołka, program przegląda li-
stę ścian (tablica triangles) wybierając te ściany, w skład których wcho-
dzi bieżący wierzchołek i dokonuje sumowania wektorów normalnych każdej
z wybranych ścian. Wykorzystany do tego celu algorytm jest wprawdzie
prosty, ale także bardzo czasochłonny. Najprostszym sposobem jego opty-
malizacji jest jednokrotne obliczenie wektora normalnego każdej ze ścian
i zapamiętanie wyników w tablicy.
Normalizacja wektorów normalnych realizowana jest w programie na
dwa spsoby. Jeżeli implementacja biblioteki OpenGL obsługuje rozszerzenie
EXT rescale normal, lub jest to wersja co najmniej 1.2, program korzysta
z opisanego wcześniej mechanizmu automatycznego skalowania jednostko-
wych wektorów normalnych. W przeciwnym wypadku całość obliczeń zwią-
zanych z normalizacją wykonuje biblioteka OpenGL, a funkcja Normalize,
która wykonuje normalizację, nie jest wykorzystywana.
Efekty działania programu przedstawiają dwa rysunki. Pierwszy z nich
(rysunek nr 11) przedstawia obiekt z wektorami normalnymi generowany-
mi dla każdego wierzchołka. Na rysunku łatwo można dostrzec charaktery-
styczne linie pokrywające się z krawędziami obiektu. Nieciągłości te, zwane
1. Światła i materiały
42
pasmami Macha, są jedną z wad cieniowania Gourauda zastosowanego w bi-
bliotece OpenGL. Na rysunku nr 12 przedstawiono bryłę w tym samym
powiększeniu i położeniu, ale z wektorami normalnymi generowanymi dla
każdej ściany.
Rysunek 11. Program Wektory normalne - wektory normalne generowane
dla każdego wierzchołka
1.9.4. Plik wektory normalne.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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l e x t . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e <math . h>
#i n c l u d e
” m a t e r i a l s . h ”
1. Światła i materiały
43
Rysunek 12. Program Wektory normalne - wektory normalne generowane
dla ściany
//
w s k a ź n i k
d o s t ę p n o ś c i
r o z s z e r z e n i a
E X T r e s c a l e n o r m a l
bool
r e s c a l e n o r m a l = f a l s e ;
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
BRASS ,
//
m o s i ą d z
BRONZE,
//
b r ą z
POLISHED BRONZE ,
//
p o l e r o w a n y
b r ą z
CHROME,
//
chrom
COPPER,
//
m i e d ź
POLISHED COPPER ,
//
p o l e r o w a n a
m i e d ź
GOLD,
//
z ł o t o
POLISHED GOLD ,
//
p o l e r o w a n e
z ł o t o
PEWTER,
//
g r a f i t
( c y n a
z
o ł o w i e m )
SILVER ,
//
s r e b r o
POLISHED SILVER ,
//
p o l e r o w a n e
s r e b r o
EMERALD,
//
s z m a r a g d
JADE,
//
j a d e i t
OBSIDIAN ,
//
o b s y d i a n
PEARL,
//
p e r ł a
1. Światła i materiały
44
RUBY,
//
r u b i n
TURQUOISE,
//
t u r k u s
BLACK PLASTIC ,
//
c z a r n y
p l a s t i k
BLACK RUBBER,
//
c z a r n a
guma
NORMALS SMOOTH,
//
j e d e n
w e k t o r
n o r m a l n y
na
w i e r z c h o ł e k
NORMALS FLAT,
//
j e d e n
w e k t o r
n o r m a l n y
na
ś c i a n ę
FULL WINDOW,
//
a s p e k t
o b r a z u − c a ł e
o k n o
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 ;
//
u s u n i ę c i e
d e f i n i c j i
makr
n e a r
i
f a r
#i f d e f
n e a r
#undef
n e a r
#e n d i f
#i f d e f
f a r
#undef
f a r
#e n d i f
//
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 ;
const GLdouble
r i g h t = 1 . 0 ;
const GLdouble bottom = − 1 . 0 ;
const GLdouble
t o p = 1 . 0 ;
const GLdouble
n e a r = 3 . 0 ;
const GLdouble
f a r = 7 . 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 ;
//
w s k a ź 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 ;
//
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 ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u − d o m y ś l n i e
m o s i ą d z
const
G L f l o a t
∗ a m b i e n t = B r a s s A m b i e n t ;
const
G L f l o a t
∗ d i f f u s e = B r a s s D i f f u s e ;
const
G L f l o a t
∗ s p e c u l a r = B r a s s S p e c u l a r ;
G L f l o a t
s h i n i n e s s = B r a s s S h i n i n e s s ;
//
w e k t o r y
n o r m a l n e
i n t
n o r m a l s = NORMALS FLAT ;
//
w s p ó ł r z ę d n e
w i e r z c h o ł k ó w
d w u d z i e s t o ś c i a n u
G L f l o a t
v e r t e x
[ 1 2 ∗ 3 ] =
{
0 . 0 0 0 ,
0 . 6 6 7 ,
0 . 5 0 0 ,
//
v 0
0 . 0 0 0 ,
0 . 6 6 7 ,
− 0 . 5 0 0 ,
//
v 1
0 . 0 0 0 ,
− 0 . 6 6 7 ,
− 0 . 5 0 0 ,
//
v 2
0 . 0 0 0 ,
− 0 . 6 6 7 ,
0 . 5 0 0 ,
//
v 3
0 . 6 6 7 ,
0 . 5 0 0 ,
0 . 0 0 0 ,
//
v 4
0 . 6 6 7 ,
− 0 . 5 0 0 ,
0 . 0 0 0 ,
//
v 5
− 0 . 6 6 7 ,
− 0 . 5 0 0 ,
0 . 0 0 0 ,
//
v 6
− 0 . 6 6 7 ,
0 . 5 0 0 ,
0 . 0 0 0 ,
//
v 7
0 . 5 0 0 ,
0 . 0 0 0 ,
0 . 6 6 7 ,
//
v 8
− 0 . 5 0 0 ,
0 . 0 0 0 ,
0 . 6 6 7 ,
//
v 9
− 0 . 5 0 0 ,
0 . 0 0 0 ,
− 0 . 6 6 7 ,
//
v 1 0
0 . 5 0 0 ,
0 . 0 0 0 ,
−0.667
//
v 1 1
} ;
//
o p i s
ś c i a n
d w u d z i e s t o ś c i a n u
1. Światła i materiały
45
i n t
t r i a n g l e s
[ 2 0 ∗ 3 ] =
{
2 ,
1 0 ,
1 1 ,
1 ,
1 1 ,
1 0 ,
1 ,
1 0 ,
7 ,
1 ,
4 ,
1 1 ,
0 ,
1 ,
7 ,
0 ,
4 ,
1 ,
0 ,
9 ,
8 ,
3 ,
8 ,
9 ,
0 ,
7 ,
9 ,
0 ,
8 ,
4 ,
3 ,
9 ,
6 ,
3 ,
5 ,
8 ,
2 ,
3 ,
6 ,
2 ,
5 ,
3 ,
2 ,
6 ,
1 0 ,
2 ,
1 1 ,
5 ,
6 ,
7 ,
1 0 ,
6 ,
9 ,
7 ,
4 ,
5 ,
1 1 ,
4 ,
8 ,
5
} ;
//
o b l i c z a n i e
w e k t o r a
n o r m a l n e g o
d l a
w y b r a n e j
ś c i a n y
void Normal
( G L f l o a t
∗n ,
i n t
i )
{
G L f l o a t
v1 [ 3 ] ,
v2 [ 3 ] ;
//
o b l i c z e n i e
w e k t o r ó w
na
p o d s t a w i e
w s p ó ł r z ę d n y c h
w i e r z c h o ł k ó w
t r ó j k ą t ó w
v1 [ 0 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +1]+0] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 0 ] + 0 ] ;
v1 [ 1 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +1]+1] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 0 ] + 1 ] ;
v1 [ 2 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +1]+2] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 0 ] + 2 ] ;
v2 [ 0 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +2]+0] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 1 ] + 0 ] ;
v2 [ 1 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +2]+1] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 1 ] + 1 ] ;
v2 [ 2 ] = v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i +2]+2] − v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 1 ] + 2 ] ;
//
o b l i c z e n i e
w a k t o r a
n o r m a l n e g o
p r z y
pomocy
i l o c z y n u
w e k t o r o w e g o
n [ 0 ] = v1 [ 1 ] ∗ v2 [ 2 ] − v1 [ 2 ] ∗ v2 [ 1 ] ;
n [ 1 ] = v1 [ 2 ] ∗ v2 [ 0 ] − v1 [ 0 ] ∗ v2 [ 2 ] ;
n [ 2 ] = v1 [ 0 ] ∗ v2 [ 1 ] − v1 [ 1 ] ∗ v2 [ 0 ] ;
}
//
n o r m a l i z a c j a
w e k t o r a
void
N o r m a l i z e
( G L f l o a t
∗v )
{
//
o b l i c z e n i e
d ł u g o ś c i
w e k t o r a
G L f l o a t d = s q r t
( v [ 0 ] ∗ v [ 0 ] + v [ 1 ] ∗ v [ 1 ] + v [ 2 ] ∗ v [ 2 ] ) ;
//
n o r m a l i z a c j a
w e k t o r a
i f
( d )
{
v [ 0 ]
/= d ;
v [ 1 ]
/= d ;
v [ 2 ]
/= d ;
}
}
//
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
i
b u f o r a
g ł ę b o k o ś c i
g l C l e a r
( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(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 ) ;
1. Światła i materiały
46
//
o b r o t y
o b i e k t u
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 ) ;
//
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 ) ;
//
w ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l E n a b l e
(GL DEPTH TEST ) ;
//
w ł ą c z e n i e
o ś w i e t l e n i a
g l E n a b l e
( GL LIGHTING ) ;
//
w ł ą c z e n i e
ś w i a t ł a
GL LIGHT0 z
p a r a m e t r a m i
d o m y ś l n y m i
g l E n a b l e
( GL LIGHT0 ) ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u
g l M a t e r i a l f v
(GL FRONT, GL AMBIENT, a m b i e n t ) ;
g l M a t e r i a l f v
(GL FRONT, GL DIFFUSE , d i f f u s e ) ;
g l M a t e r i a l f v
(GL FRONT, GL SPECULAR, s p e c u l a r ) ;
g l M a t e r i a l f
(GL FRONT, GL SHININESS , s h i n i n e s s ) ;
//
w ł ą c z e n i e
a u t o m a t y c z n e j
n o r m a l i z a c j i
w e k t o r ó w
n o r m a l n y c h
//
l u b
a u t o m a t y c z n e g o
s k a l o w a n i a
j e d n o s t k o w y c h
w e k t o r ó w
n o r m a l n y c h
i f
( r e s c a l e n o r m a l == true )
g l E n a b l e
(GL RESCALE NORMAL ) ;
e l s e
g l E n a b l e
(GL NORMALIZE ) ;
//
p o c z ą t e k
d e f i n i c j i
o b i e k t u
g l B e g i n
(GL TRIANGLES ) ;
//
g e n e r o w a n i e
o b i e k t u
g ł a d k i e g o − j e d e n
u ś r e d n i o n y
//
w e k t o r
n o r m a l n y
na
w i e r z c h o ł e k
i f
( n o r m a l s == NORMALS SMOOTH)
f o r
( i n t
i = 0 ;
i < 2 0 ;
i ++)
{
//
o b l i c z a n i e
w e k t o r a
n o r m a l n e g o
d l a
p i e r w s z e g o
w i e r z c h o ł k a
G L f l o a t n [ 3 ] ;
n [ 0 ] = n [ 1 ] = n [ 2 ] = 0 . 0 ;
//
w y s z u k a n i e
w s z y s t k i c h
ś c i a n
p o s i a d a j ą c y c h
b i e ż ą c y
w i e r z c h o ł e k
f o r
( i n t
j = 0 ;
j < 2 0 ;
j ++)
i f
( 3 ∗ t r i a n g l e s
[ 3 ∗ i +0] == 3∗ t r i a n g l e s
[ 3 ∗ j +0]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +0] == 3∗ t r i a n g l e s
[ 3 ∗ j +1]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +0] == 3∗ t r i a n g l e s
[ 3 ∗ j + 2 ] )
{
//
d o d a w a n i e
w e k t o r ó w
n o r m a l n y c h
p o s z c z e g ó l n y c h
ś c i a n
G L f l o a t
nv [ 3 ] ;
Normal
( nv , j ) ;
n [ 0 ] += nv [ 0 ] ;
n [ 1 ] += nv [ 1 ] ;
n [ 2 ] += nv [ 2 ] ;
}
//
u ś r e d n i o n y
w e k t o r
n o r m a l n y
j e s t
n o r m a l i z o w a n y
t y l k o ,
g d y
b i b l i o t e k a
//
o b s ł u g u j e
a u t o m a t y c z n e
s k a l o w a n i a
j e d n o s t k o w y c h
w e k t o r ó w
n o r m a l n y c h
i f
( r e s c a l e n o r m a l == true )
N o r m a l i z e
( n ) ;
g l N o r m a l 3 f v
( n ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 0 ] ] ) ;
//
o b l i c z a n i e
w e k t o r a
n o r m a l n e g o
d l a
d r u g i e g o
w i e r z c h o ł k a
n [ 0 ] = n [ 1 ] = n [ 2 ] = 0 . 0 ;
//
w y s z u k a n i e
w s z y s t k i c h
ś c i a n
p o s i a d a j ą c y c h
b i e ż ą c y
w i e r z c h o ł e k
f o r
( i n t
j = 0 ;
j < 2 0 ;
j ++)
i f
( 3 ∗ t r i a n g l e s
[ 3 ∗ i +1] == 3∗ t r i a n g l e s
[ 3 ∗ j +0]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +1] == 3∗ t r i a n g l e s
[ 3 ∗ j +1]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +1] == 3∗ t r i a n g l e s
[ 3 ∗ j + 2 ] )
{
//
d o d a w a n i e
w e k t o r ó w
n o r m a l n y c h
p o s z c z e g ó l n y c h
ś c i a n
G L f l o a t
nv [ 3 ] ;
Normal
( nv , j ) ;
n [ 0 ] += nv [ 0 ] ;
n [ 1 ] += nv [ 1 ] ;
n [ 2 ] += nv [ 2 ] ;
}
//
u ś r e d n i o n y
w e k t o r
n o r m a l n y
j e s t
n o r m a l i z o w a n y
t y l k o ,
g d y
b i b l i o t e k a
1. Światła i materiały
47
//
o b s ł u g u j e
a u t o m a t y c z n e
s k a l o w a n i a
j e d n o s t k o w y c h
w e k t o r ó w
n o r m a l n y c h
i f
( r e s c a l e n o r m a l == true )
N o r m a l i z e
( n ) ;
g l N o r m a l 3 f v
( n ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 1 ] ] ) ;
//
o b l i c z a n i e
w e k t o r a
n o r m a l n e g o
d l a
t r z e c i e g o
w i e r z c h o ł k a
n [ 0 ] = n [ 1 ] = n [ 2 ] = 0 . 0 ;
//
w y s z u k a n i e
w s z y s t k i c h
ś c i a n
p o s i a d a j ą c y c h
b i e ż ą c y
w i e r z c h o ł e k
f o r
( i n t
j = 0 ;
j < 2 0 ;
j ++)
i f
( 3 ∗ t r i a n g l e s
[ 3 ∗ i +2] == 3∗ t r i a n g l e s
[ 3 ∗ j +0]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +2] == 3∗ t r i a n g l e s
[ 3 ∗ j +1]
| |
3∗ t r i a n g l e s
[ 3 ∗ i +2] == 3∗ t r i a n g l e s
[ 3 ∗ j + 2 ] )
{
//
d o d a w a n i e
w e k t o r ó w
n o r m a l n y c h
p o s z c z e g ó l n y c h
ś c i a n
G L f l o a t
nv [ 3 ] ;
Normal
( nv , j ) ;
n [ 0 ] += nv [ 0 ] ;
n [ 1 ] += nv [ 1 ] ;
n [ 2 ] += nv [ 2 ] ;
}
//
u ś r e d n i o n y
w e k t o r
n o r m a l n y
j e s t
n o r m a l i z o w a n y
t y l k o ,
g d y
b i b l i o t e k a
//
o b s ł u g u j e
a u t o m a t y c z n e
s k a l o w a n i a
j e d n o s t k o w y c h
w e k t o r ó w
n o r m a l n y c h
i f
( r e s c a l e n o r m a l == true )
N o r m a l i z e
( n ) ;
g l N o r m a l 3 f v
( n ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 2 ] ] ) ;
}
e l s e
//
g e n e r o w a n i e
o b i e k t u
” p ł a s k i e g o ” − j e d e n
w e k t o r
n o r m a l n y
na
ś c i a n ę
f o r
( i n t
i = 0 ;
i < 2 0 ;
i ++)
{
G L f l o a t n [ 3 ] ;
Normal
( n , i ) ;
//
u ś r e d n i o n y
w e k t o r
n o r m a l n y
j e s t
n o r m a l i z o w a n y
t y l k o ,
g d y
b i b l i o t e k a
//
o b s ł u g u j e
a u t o m a t y c z n e
s k a l o w a n i a
j e d n o s t k o w y c h
w e k t o r ó w
n o r m a l n y c h
i f
( r e s c a l e n o r m a l == true )
N o r m a l i z e
( n ) ;
g l N o r m a l 3 f v
( n ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 0 ] ] ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 1 ] ] ) ;
g l V e r t e x 3 f v
(& v e r t e x
[ 3 ∗ t r i a n g l e s
[ 3 ∗ i + 2 ] ] ) ;
}
//
k o n i e c
d e f i n i c j i
o b i e k t u
g l E n d
( ) ;
//
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
( ) ;
//
z a m i a n a
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 ( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( 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
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(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 ś ć
o k n a
w i ę k s z a
od
w y s o k o ś c i
o k n a
i f
( w i d t h < h e i g h t && w i d t h > 0 )
g l F r u s t u m
( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;
e l s e
//
s z e r o k o ś ć
o k n a
w i ę k s z a
l u b
równa
w y s o k o ś c i
o k n a
1. Światła i materiały
48
i f
( w i d t h >= h e i g h t && h e i g h t > 0 )
g l F r u s t u m
( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;
}
e l s e
g l F r u s t u m
( l e f t , r i g h t , bottom , top , n e a r , 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
( k e y == ’+ ’ )
s c a l e += 0 . 0 5 ;
e l s e
//
k l a w i s z −
i f
( k e y == ’− ’ && s c a l e > 0 . 0 5 )
s c a l e −= 0 . 0 5 ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
//
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
( k e y )
{
//
k u r s o r w l e w o
c a s e GLUT KEY LEFT :
r o t a t e y −= 1 ;
break ;
//
k u r s o r w g ó r ę
c a s e GLUT KEY UP :
r o t a t e x −= 1 ;
break ;
//
k u r s o r w p r a w o
c a s e GLUT KEY RIGHT :
r o t a t e y += 1 ;
break ;
//
k u r s o r w d ó ł
c a s e GLUT KEY DOWN :
r o t a t e x += 1 ;
break ;
}
//
o d r y s o w a n i e
o k n a
R esh ape
( 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
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o 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. Światła i materiały
49
i f
( b u t t o n s t a t e == GLUT DOWN)
{
r o t a t e y += 30
∗ ( 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 ;
r o t a t e x −= 30
∗ ( t o p − 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 )
{
//
m a t e r i a ł − m o s i ą d z
c a s e BRASS :
a m b i e n t = B r a s s A m b i e n t ;
d i f f u s e = B r a s s D i f f u s e ;
s p e c u l a r = B r a s s S p e c u l a r ;
s h i n i n e s s = B r a s s S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − b r ą z
c a s e BRONZE:
a m b i e n t = BronzeAmbient ;
d i f f u s e = B r o n z e D i f f u s e ;
s p e c u l a r = B r o n z e S p e c u l a r ;
s h i n i n e s s = B r o n z e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n y
b r ą z
c a s e POLISHED BRONZE :
a m b i e n t = P o l i s h e d B r o n z e A m b i e n t ;
d i f f u s e = P o l i s h e d B r o n z e D i f f u s e ;
s p e c u l a r = P o l i s h e d B r o n z e S p e c u l a r ;
s h i n i n e s s = P o l i s h e d B r o n z e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − chrom
c a s e CHROME:
a m b i e n t = ChromeAmbient ;
d i f f u s e = C h r o m e D i f f u s e ;
s p e c u l a r = C h r o m e S p e c u l a r ;
s h i n i n e s s = C h r o m e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − m i e d ź
c a s e COPPER:
a m b i e n t = CopperAmbient ;
d i f f u s e = C o p p e r D i f f u s e ;
s p e c u l a r = C o p p e r S p e c u l a r ;
s h i n i n e s s = C o p p e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n a
m i e d ź
c a s e POLISHED COPPER :
a m b i e n t = P o l i s h e d C o p p e r A m b i e n t ;
d i f f u s e = P o l i s h e d C o p p e r D i f f u s e ;
s p e c u l a r = P o l i s h e d C o p p e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d C o p p e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − z ł o t o
c a s e GOLD:
a m b i e n t = GoldAmbient ;
d i f f u s e = G o l d D i f f u s e ;
s p e c u l a r = G o l d S p e c u l a r ;
s h i n i n e s s = G o l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
z ł o t o
1. Światła i materiały
50
c a s e POLISHED GOLD :
a m b i e n t = P o l i s h e d G o l d A m b i e n t ;
d i f f u s e = P o l i s h e d G o l d D i f f u s e ;
s p e c u l a r = P o l i s h e d G o l d S p e c u l a r ;
s h i n i n e s s = P o l i s h e d G o l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − g r a f i t
( c y n a
z
o ł o w i e m )
c a s e PEWTER:
a m b i e n t = PewterAmbient ;
d i f f u s e = P e w t e r D i f f u s e ;
s p e c u l a r = P e w t e r S p e c u l a r ;
s h i n i n e s s = P e w t e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − s r e b r o
c a s e SILVER :
a m b i e n t = S i l v e r A m b i e n t ;
d i f f u s e = S i l v e r D i f f u s e ;
s p e c u l a r = S i l v e r S p e c u l a r ;
s h i n i n e s s = S i l v e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
s r e b r o
c a s e POLISHED SILVER :
a m b i e n t = P o l i s h e d S i l v e r A m b i e n t ;
d i f f u s e = P o l i s h e d S i l v e r D i f f u s e ;
s p e c u l a r = P o l i s h e d S i l v e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d S i l v e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − s z m a r a g d
c a s e EMERALD:
a m b i e n t = EmeraldAmbient ;
d i f f u s e = E m e r a l d D i f f u s e ;
s p e c u l a r = E m e r a l d S p e c u l a r ;
s h i n i n e s s = E m e r a l d S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − j a d e i t
c a s e JADE :
a m b i e n t = JadeAmbient ;
d i f f u s e = J a d e D i f f u s e ;
s p e c u l a r = J a d e S p e c u l a r ;
s h i n i n e s s = J a d e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − o b s y d i a n
c a s e OBSIDIAN :
a m b i e n t = O b s i d i a n A m b i e n t ;
d i f f u s e = O b s i d i a n D i f f u s e ;
s p e c u l a r = O b s i d i a n S p e c u l a r ;
s h i n i n e s s = O b s i d i a n S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − p e r ł a
c a s e PEARL :
a m b i e n t = P e a r l A m b i e n t ;
d i f f u s e = P e a r l D i f f u s e ;
s p e c u l a r = P e a r l S p e c u l a r ;
s h i n i n e s s = P e a r l S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m e t a r i a ł − r u b i n
c a s e RUBY:
a m b i e n t = RubyAmbient ;
d i f f u s e = R u b y D i f f u s e ;
s p e c u l a r = R u b y S p e c u l a r ;
s h i n i n e s s = R u b y S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
1. Światła i materiały
51
//
m a t e r i a ł − t u r k u s
c a s e TURQUOISE :
a m b i e n t = T u r q u o i s e A m b i e n t ;
d i f f u s e = T u r q u o i s e D i f f u s e ;
s p e c u l a r = T u r q u o i s e S p e c u l a r ;
s h i n i n e s s = T u r q u o i s e S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − c z a r n y
p l a s t i k
c a s e BLACK PLASTIC :
a m b i e n t = B l a c k P l a s t i c A m b i e n t ;
d i f f u s e = B l a c k P l a s t i c D i f f u s e ;
s p e c u l a r = B l a c k P l a s t i c S p e c u l a r ;
s h i n i n e s s = B l a c k P l a s t i c S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
m a t e r i a ł − c z a r n a
guma
c a s e BLACK RUBBER :
a m b i e n t = BlackRubberAmbient ;
d i f f u s e = B l a c k R u b b e r D i f f u s e ;
s p e c u l a r = B l a c k R u b b e r S p e c u l a r ;
s h i n i n e s s = B l a c k R u b b e r S h i n i n e s s ;
D i s p l a y
( ) ;
break ;
//
w e k t o r y
n o r m a l n e − GLU SMOOTH
c a s e NORMALS SMOOTH:
n o r m a l s = NORMALS SMOOTH;
D i s p l a y
( ) ;
break ;
//
w e k t o r y
n o r m a l n e − GLU FLAT
c a s e NORMALS FLAT :
n o r m a l s = NORMALS FLAT ;
D i s p l a y
( ) ;
break ;
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
c a s e FULL WINDOW :
a s p e c t = FULL WINDOW ;
R esha pe
( 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
c a s e ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
R esha pe
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
void
E x t e n s i o n S e t u p
( )
{
//
p o b r a n i e
numeru
w e r s j i
b i b l i o t e k i
OpenGL
const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g
( GL VERSION ) ;
//
o d c z y t
w e r s j i
OpenGL
i n t
m a j o r = 0 ,
m i n o r = 0 ;
i f
( s s c a n f
( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )
!=
2 )
{
#i f d e f WIN32
p r i n t f
( ” Błędny
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e l s e
p r i n t f
( ” B l e d n y
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e n d i f
e x i t
( 0 ) ;
}
//
s p r a w d z e n i e
c z y
j e s t
c o
n a j m n i e j
w e r s j a
1 . 2
i f
( m a j o r > 1
| |
m i n o r >= 2 )
1. Światła i materiały
52
r e s c a l e n o r m a l = true ;
e l s e
//
s p r a w d z e n i e
c z y
j e s t
o b s ł u g i w a n e
r o z s z e r z e n i e
E X T r e s c a l e n o r m a l
i f
( g l u t E x t e n s i o n S u p p o r t e d
( ” G L E X T r e s c a l e n o r m a l ” ) )
r e s c a l e n o r m a l = true ;
}
i n t
main
( i n t
a r g c ,
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
(& a r g c , 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 | GLUT DEPTH ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t C r e a t e W i n d o w
( ” Wektory
n o r m a l n e ” ) ;
//
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
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
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
g l u t K e y b o a r d F u n c
( 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
g l u t M o u s e F u n c
( 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
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
//
u t w o r z e n i e
podmenu − M a t e r i a ł
i n t
M e n u M a t e r i a l = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” M o s i ą d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r ąz ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r ą z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedź ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d ź ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z ł o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z ł o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r ł a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e l s e
glutAddMenuEntry
( ” M o s i a d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r az ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r a z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedz ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d z ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z l o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z l o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
1. Światła i materiały
53
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r l a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e n d i f
//
u t w o r z e n i e
podmenu − W e k t o r y
n o r m a l n e
i n t
MenuNormals = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” J e d e n
w e k t o r
n o r m a l n y na
w i e r z c h o ł e k ” ,NORMALS SMOOTH ) ;
glutAddMenuEntry
( ” J e d e n
w e k t o r
n o r m a l n y na
ś c i a n ę ” ,NORMALS FLAT ) ;
#e l s e
glutAddMenuEntry
( ” J e d e n
w e k t o r
n o r m a l n y na
w i e r z c h o l e k ” ,NORMALS SMOOTH ) ;
glutAddMenuEntry
( ” J e d e n
w e k t o r
n o r m a l n y na
s c i a n e ” ,NORMALS FLAT ) ;
#e n d i f
//
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 = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a ł e
okno ” ,FULL WINDOW ) ;
#e l s e
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a l e
okno ” ,FULL WINDOW ) ;
#e n d i f
glutAddMenuEntry
( ” A s p e k t
o b r a z u
1 : 1 ” , ASPECT 1 1 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddSubMenu
( ” M a t e r i a ł ” , M e n u M a t e r i a l ) ;
#e l s e
glutAddSubMenu
( ” M a t e r i a l ” , M e n u M a t e r i a l ) ;
#e n d i f
glutAddSubMenu
( ” Wektory
n o r m a l n e ” , MenuNormals ) ;
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , 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 ) ;
#e n d i f
//
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 j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
E x t e n s i o n S e t u p
( ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Czwarty program przykładowy (plik swiatlo kierunkowe.cpp) prezen-
tuje podstawową właściwość światła kierunkowego, czyli możliwość zmiany
kierunku, z którego padają promienie światła. Wektor kierunku źródła świa-
tła jest modyfikowany zgodnie z przekształceniami macierzy modelowania,
stąd, aby zmiana kierunku źródła światła odbywała się w sposób niezależ-
ny od obrotu obiektu umieszczonego na scenie, macierz modelowania należy
odłożyć na stos korzystając z funkcji glPushMatrix. Po wykonaniu niezbęd-
nych przekształceń (w przypadku światła kierunkowego będą to oczywiście
1. Światła i materiały
54
tylko obroty), przywracamy odłożoną na stos macierz modelowania, wywo-
łując funkcję glPopMatrix. Aby przekształcenie kierunku światła zostały
wykonane trzeba jeszcze dla wybranego źródła światła wywołać funkcję
glLightfv (lub inną z tej grupy) podając przy tym tablicę zawierającą
wektor z kierunkiem źródła światła.
W odróżnieniu od drugiego programu przykładowego do rysowania obiek-
tów w omawianym programie użyto funkcji z biblioteki GLUT. Dwie z nich
(rysujące kulę i sześcian) omówiliśmy już wcześniej. Pozostałe funkcje nie
różną się parametrami od ich wcześniej opisywanych wersji rysujących obiek-
ty w postaci siatek krawędzi.
Stożek (rysunek 15), składający się z równoległych do podstawy „po-
łudników” i tworzących biegnących od wierzchołka do krawędzi podstawy
stożka, rysuje funkcja:
void glutSolidCone (GLdouble base, GLdouble height,
GLint slices, GLint stacks)
której parametry oznaczaja:
— base - promień podstawy stożka,
— height - wysokość stożka,
— slices - ilość tworzących,
— stacks - ilość „południków”.
Torus (rysunek 16), składający się z serii walców o nierównoległych pod-
stawach, rysuje funkcja:
void glutSolidTorus (GLdouble innerRadius, GLdouble outerRadius,
GLint sides, GLint rings)
której parametry oznaczają odpowiednio:
— innerRadius - promień koła tworzącego torus,
— outerRadius - promień torusa,
— sides - ilość ścian bocznych, z których składa się pojedynczy walec,
— rings - ilość walców, z których składa sie torus.
Czajnik o wielkości regulowanej parametrem size rysuje funkcja:
void glutSolidTeapot (GLdouble size)
Pozostałe użyte w programie funkcje rysują bryły Platońskie. Są to kolej-
no: dwunastościan (rysunek 17), ośmiościan, czworościan i dwudziestościan:
void glutSolidDodecahedron ()
void glutSolidOctahedron ()
void glutSolidTetrahedron ()
void glutSolidIcosahedron ()
Ponadto w programie wykorzystano funkcję glWindowPos2i wprowadzo-
ną w wersji 1.4 biblioteki OpenGL, a wcześniej dostępną w opisywanym już
1. Światła i materiały
55
rozszerzeniu ARB window pos. Funkcja ta została zastosowana do pozycjo-
nowania tekstów wyświetlanych w oknie programu. A są to współrzędne
określające kierunek źródła światła oraz kąty obrotu kierunku źródła świa-
tła.
Rysunek 13. Program Światło kierunkowe - rubinowy czajnik
1.9.5. Plik swiatlo kierunkowe.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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l e x t . h>
#i f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
#i n c l u d e <GL/ g l x . h>
#d e f i n e
w g l G e t P r o c A d d r e s s
glXGetProcAddressARB
#e n d i f
#i n c l u d e < s t d l i b . h>
1. Światła i materiały
56
Rysunek 14. Program Światło kierunkowe - jadeitowa kula
#i n c l u d e < s t r i n g . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e
” c o l o r s . h ”
#i n c l u d e
” m a t e r i a l s . h ”
//
w s k a ź n i k
na
f u n k c j ę
g l W i n d o w P o s 2 i
PFNGLWINDOWPOS2IPROC g l W i n d o w P o s 2 i = NULL ;
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
//
o b i e k t y
SPHERE,
//
k u l a
TEAPOT,
//
c z a j n i k
CONE,
//
s t o ż e k
TORUS,
//
t o r u s
CUBE,
//
s z e ś c i a n
DODECAHEDRON,
//
d w u n a s t o ś c i a n
OCTAHEDRON,
//
o ś m i o ś c i a n
TETRAHEDRON,
//
c z w o r o ś c i a n
ICOSAHEDRON,
//
d w u d z i e s t o ś c i a n
//
m a t e r i a ł y
BRASS ,
//
m o s i ą d z
1. Światła i materiały
57
Rysunek 15. Program Światło kierunkowe - złoty stożek
BRONZE,
//
b r ą z
POLISHED BRONZE ,
//
p o l e r o w a n y
b r ą z
CHROME,
//
chrom
COPPER,
//
m i e d ź
POLISHED COPPER ,
//
p o l e r o w a n a
m i e d ź
GOLD,
//
z ł o t o
POLISHED GOLD ,
//
p o l e r o w a n e
z ł o t o
PEWTER,
//
g r a f i t
( c y n a
z
o ł o w i e m )
SILVER ,
//
s r e b r o
POLISHED SILVER ,
//
p o l e r o w a n e
s r e b r o
EMERALD,
//
s z m a r a g d
JADE,
//
j a d e i t
OBSIDIAN ,
//
o b s y d i a n
PEARL,
//
p e r ł a
RUBY,
//
r u b i n
TURQUOISE,
//
t u r k u s
BLACK PLASTIC ,
//
c z a r n y
p l a s t i k
BLACK RUBBER,
//
c z a r n a
guma
//
o b s z a r
r e n d e r i n g u
FULL WINDOW,
//
a s p e k t
o b r a z u − c a ł e
o k n o
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
1. Światła i materiały
58
Rysunek 16. Program Światło kierunkowe - szmaragdowy torus
i n t
a s p e c t = FULL WINDOW ;
//
u s u n i ę c i e
d e f i n i c j i
makr
n e a r
i
f a r
#i f d e f
n e a r
#undef
n e a r
#e n d i f
#i f d e f
f a r
#undef
f a r
#e n d i f
//
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 = − 2 . 0 ;
const GLdouble
r i g h t = 2 . 0 ;
const GLdouble bottom = − 2 . 0 ;
const GLdouble
t o p = 2 . 0 ;
const GLdouble
n e a r = 3 . 0 ;
const GLdouble
f a r = 7 . 0 ;
//
k ą t y
o b r o t u
o b i e k 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 ;
1. Światła i materiały
59
Rysunek 17. Program Światło kierunkowe - grafitowy dwunastościan
//
w s k a ź 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 ;
//
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 ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u − d o m y ś l n i e
m o s i ą d z
const
G L f l o a t
∗ a m b i e n t = B r a s s A m b i e n t ;
const
G L f l o a t
∗ d i f f u s e = B r a s s D i f f u s e ;
const
G L f l o a t
∗ s p e c u l a r = B r a s s S p e c u l a r ;
G L f l o a t
s h i n i n e s s = B r a s s S h i n i n e s s ;
//
w y ś w i e t l a n y
o b i e k t
3D
i n t
o b j e c t = SPHERE ;
//
k i e r u n e k
ź r ó d ł a
ś w i a t ł a
G L f l o a t
l i g h t p o s i t i o n
[ 4 ] =
1. Światła i materiały
60
{
0 . 0 , 0 . 0 , 2 . 0 , 0 . 0
} ;
//
k ą t y
o b r o t u
k i e r u n k u
ź r ó d ł a
ś w i a t ł a
G L f l o a t
l i g h t r o t a t e x = 0 . 0 ;
G L f l o a t
l i g h t r o t a t e y = 0 . 0 ;
//
f u n k c j a
r y s u j ą c a
n a p i s w wybranym
m i e j s c u
//
( w e r s j a
k o r z y s t a j ą c a
z
f u n k c j i
g l W i n d o w P o s 2 i )
void
D r a w S t r i n g
( GLint x ,
GLint y ,
char ∗ s t r i n g )
{
//
p o ł o ż e n i e
n a p i s u
g l W i n d o w P o s 2 i
( x , y ) ;
//
w y ś w i e t l e n i e
n a p i s u
i n t
l e n = s t r l e n
( s t r i n g ) ;
f o r
( i n t
i = 0 ;
i < l e n ;
i ++)
g l u t B i t m a p C h a r a c t e r
( GLUT BITMAP 9 BY 15 , s t r i n g
[ i ] ) ;
}
//
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 S c e n e
( )
{
//
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
i
b u f o r a
g ł ę b o k o ś c i
g l C l e a r
( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(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
( ) ;
//
w ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l E n a b l e
(GL DEPTH TEST ) ;
//
w ł ą c z e n i e
o ś w i e t l e n i a
g l E n a b l e
( GL LIGHTING ) ;
//
w ł ą c z e n i e
ś w i a t ł a
GL LIGHT0
g l E n a b l e
( GL LIGHT0 ) ;
//
w ł ą c z e n i e
a u t o m a t y c z n e j
n o r m a l i z a c j i
w e k t o r ó w
n o r m a l n y c h
g l E n a b l e
(GL NORMALIZE ) ;
//
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 ) ;
//
o b r o t y
o b i e k t u
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 ) ;
//
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 ) ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u
g l M a t e r i a l f v
(GL FRONT, GL AMBIENT, a m b i e n t ) ;
g l M a t e r i a l f v
(GL FRONT, GL DIFFUSE , d i f f u s e ) ;
g l M a t e r i a l f v
(GL FRONT, GL SPECULAR, s p e c u l a r ) ;
g l M a t e r i a l f
(GL FRONT, GL SHININESS , s h i n i n e s s ) ;
//
z m i a n a
k i e r u n k u
ź r ó d ł a
ś w i a t ł a
j e s t
wykonywana
n i e z a l e ż n i e
//
od
o b r o t ó w
o b i e k t u ,
s t ą d
o d ł o ż e n i e
na
s t o s
m a c i e r z y
m o d e l o w a n i a
g l P u s h M a t r i x
( ) ;
//
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
( ) ;
//
o b r o t y
k i e r u n k u
ź r ó d ł a
ś w i a t ł a − k l a w i s z e
k u r s o r a
g l R o t a t e f
( l i g h t r o t a t e x , 1 . 0 , 0 , 0 ) ;
g l R o t a t e f
( l i g h t r o t a t e y , 0 , 1 . 0 , 0 ) ;
//
u s t a l e n i e
k i e r u n k u
ź r ó d ł a
ś w i a t ł a
g l L i g h t f v
( GL LIGHT0 , GL POSITION , l i g h t p o s i t i o n ) ;
1. Światła i materiały
61
//
p r z y w r ó c e n i e
p i e r w o t n e j
m a c i e r z y
m o d e l o w a n i a
g l P o p M a t r i x
( ) ;
//
r y s o w a n i e
w y b r a n e g o
o b i e k t u
3D
switch
( o b j e c t )
{
//
k u l a
c a s e SPHERE :
g l u t S o l i d S p h e r e
( 1 . 0 , 5 0 , 4 0 ) ;
break ;
//
c z a j n i k
c a s e TEAPOT:
g l u t S o l i d T e a p o t
( 1 ) ;
break ;
//
s t o ż e k
c a s e CONE:
g l u t S o l i d C o n e
( 1 , 1 , 5 0 , 4 0 ) ;
break ;
//
t o r u s
c a s e TORUS :
g l u t S o l i d T o r u s
( 0 . 3 , 1 , 4 0 , 5 0 ) ;
break ;
//
s z e ś c i a n
c a s e CUBE :
g l u t S o l i d C u b e
( 1 ) ;
break ;
//
d w u n a s t o ś c i a n
c a s e DODECAHEDRON:
g l u t S o l i d D o d e c a h e d r o n
( ) ;
break ;
//
o ś m i o ś c i a n
c a s e OCTAHEDRON:
g l u t S o l i d O c t a h e d r o n
( ) ;
break ;
//
c z w o r o ś c i a n
c a s e TETRAHEDRON:
g l u t S o l i d 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
c a s e ICOSAHEDRON :
g l u t S o l i d I c o s a h e d r o n
( ) ;
break ;
}
//
i n f o r m a c j e
o
m o d y f i k o w a n y c h
w a r t o ś c i a c h
//
p a r a m e t r ó w
ź r ó d ł a
ś w i a t a ł a
GL LIGHT0
char
s t r i n g
[ 2 0 0 ] ;
G L f l o a t
v e c
[ 4 ] ;
g l C o l o r 3 f v
( B l a c k ) ;
//
k i e r u n e k
ź r ó d ł a
ś w i a t ł a
g l G e t L i g h t f v
( GL LIGHT0 , GL POSITION , v e c ) ;
s p r i n t f
( s t r i n g , ”GL POSITION = (% f ,% f ,% f ,% f ) ” , v e c [ 0 ] , v e c [ 1 ] , v e c [ 2 ] , v e c [ 3 ] ) ;
D r a w S t r i n g
( 2 , 2 , s t r i n g ) ;
//
k ą t y
o b r o t u
k i e r u n k u
ź r ó d ł a
ś w i a t ł a
s p r i n t f
( s t r i n g , ” l i g h t r o t a t e x = %f ” , l i g h t r o t a t e x ) ;
D r a w S t r i n g
( 2 , 1 6 , s t r i n g ) ;
s p r i n t f
( s t r i n g , ” l i g h t r o t a t e y = %f ” , l i g h t r o t a t e y ) ;
D r a w S t r i n g
( 2 , 3 0 , s t r i n g ) ;
//
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
( ) ;
//
z a m i a n a
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 ( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( i n t
width ,
i n t
h e i g h t )
{
1. Światła i materiały
62
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(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 ś ć
o k n a
w i ę k s z a
od
w y s o k o ś c i
o k n a
i f
( w i d t h < h e i g h t && w i d t h > 0 )
g l F r u s t u m
( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;
e l s e
//
s z e r o k o ś ć
o k n a
w i ę k s z a
l u b
równa
w y s o k o ś c i
o k n a
i f
( w i d t h >= h e i g h t && h e i g h t > 0 )
g l F r u s t u m
( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;
}
e l s e
g l F r u s t u m
( l e f t , r i g h t , bottom , top , n e a r , 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 S c e n e
( ) ;
}
//
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 )
{
switch
( k e y )
{
//
k l a w i s z
”+” − p o w i ę k s z e n i e
o b i e k t u
c a s e
’+ ’ :
s c a l e += 0 . 0 5 ;
break ;
//
k l a w i s z
”−” − z m n i e j s z e n i e
o b i e k t u
c a s e
’− ’ :
i f
( s c a l e > 0 . 0 5 )
s c a l e −= 0 . 0 5 ;
break ;
}
//
n a r y s o w a n i e
s c e n y
D i s p l a y S c e n e
( ) ;
}
//
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
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o 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)
{
r o t a t e y += 30
∗ ( 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 ;
r o t a t e x −= 30
∗ ( t o p − 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
( ) ;
}
1. Światła i materiały
63
}
//
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
( k e y )
{
//
k u r s o r w l e w o
c a s e GLUT KEY LEFT :
l i g h t r o t a t e y −= 5 ;
break ;
//
k u r s o r w p r a w o
c a s e GLUT KEY RIGHT :
l i g h t r o t a t e y += 5 ;
break ;
//
k u r s o r w d ó ł
c a s e GLUT KEY DOWN :
l i g h t r o t a t e x += 5 ;
break ;
//
k u r s o r w g ó r ę
c a s e GLUT KEY UP :
l i g h t r o t a t e x −= 5 ;
break ;
}
//
o d r y s o w a n i e
o k n a
D i s p l a y S c e n e
( ) ;
}
//
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 )
{
//
r y s o w a n y
o b i e k t − k u l a
c a s e SPHERE :
o b j e c t = SPHERE ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − c z a j n i k
c a s e TEAPOT:
o b j e c t = TEAPOT;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − s t o ż e k
c a s e CONE:
o b j e c t = CONE;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − t o r u s
c a s e TORUS :
o b j e c t = TORUS ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − s z e ś c i a n
c a s e CUBE :
o b j e c t = CUBE ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − d w u n a s t o ś c i a n
c a s e DODECAHEDRON:
o b j e c t = DODECAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − o ś m i o ś c i a n
c a s e OCTAHEDRON:
o b j e c t = OCTAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
1. Światła i materiały
64
//
r y s o w a n y
o b i e k t − c z w o r o ś c i a n
c a s e TETRAHEDRON:
o b j e c t = TETRAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − d w u d z i e s t o ś c i a n
c a s e ICOSAHEDRON :
o b j e c t = ICOSAHEDRON ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − m o s i ą d z
c a s e BRASS :
a m b i e n t = B r a s s A m b i e n t ;
d i f f u s e = B r a s s D i f f u s e ;
s p e c u l a r = B r a s s S p e c u l a r ;
s h i n i n e s s = B r a s s S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − b r ą z
c a s e BRONZE:
a m b i e n t = BronzeAmbient ;
d i f f u s e = B r o n z e D i f f u s e ;
s p e c u l a r = B r o n z e S p e c u l a r ;
s h i n i n e s s = B r o n z e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n y
b r ą z
c a s e POLISHED BRONZE :
a m b i e n t = P o l i s h e d B r o n z e A m b i e n t ;
d i f f u s e = P o l i s h e d B r o n z e D i f f u s e ;
s p e c u l a r = P o l i s h e d B r o n z e S p e c u l a r ;
s h i n i n e s s = P o l i s h e d B r o n z e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − chrom
c a s e CHROME:
a m b i e n t = ChromeAmbient ;
d i f f u s e = C h r o m e D i f f u s e ;
s p e c u l a r = C h r o m e S p e c u l a r ;
s h i n i n e s s = C h r o m e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − m i e d ź
c a s e COPPER:
a m b i e n t = CopperAmbient ;
d i f f u s e = C o p p e r D i f f u s e ;
s p e c u l a r = C o p p e r S p e c u l a r ;
s h i n i n e s s = C o p p e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n a
m i e d ź
c a s e POLISHED COPPER :
a m b i e n t = P o l i s h e d C o p p e r A m b i e n t ;
d i f f u s e = P o l i s h e d C o p p e r D i f f u s e ;
s p e c u l a r = P o l i s h e d C o p p e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d C o p p e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − z ł o t o
c a s e GOLD:
a m b i e n t = GoldAmbient ;
d i f f u s e = G o l d D i f f u s e ;
s p e c u l a r = G o l d S p e c u l a r ;
s h i n i n e s s = G o l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
z ł o t o
c a s e POLISHED GOLD :
a m b i e n t = P o l i s h e d G o l d A m b i e n t ;
d i f f u s e = P o l i s h e d G o l d D i f f u s e ;
1. Światła i materiały
65
s p e c u l a r = P o l i s h e d G o l d S p e c u l a r ;
s h i n i n e s s = P o l i s h e d G o l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − g r a f i t
( c y n a
z
o ł o w i e m )
c a s e PEWTER:
a m b i e n t = PewterAmbient ;
d i f f u s e = P e w t e r D i f f u s e ;
s p e c u l a r = P e w t e r S p e c u l a r ;
s h i n i n e s s = P e w t e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − s r e b r o
c a s e SILVER :
a m b i e n t = S i l v e r A m b i e n t ;
d i f f u s e = S i l v e r D i f f u s e ;
s p e c u l a r = S i l v e r S p e c u l a r ;
s h i n i n e s s = S i l v e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
s r e b r o
c a s e POLISHED SILVER :
a m b i e n t = P o l i s h e d S i l v e r A m b i e n t ;
d i f f u s e = P o l i s h e d S i l v e r D i f f u s e ;
s p e c u l a r = P o l i s h e d S i l v e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d S i l v e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − s z m a r a g d
c a s e EMERALD:
a m b i e n t = EmeraldAmbient ;
d i f f u s e = E m e r a l d D i f f u s e ;
s p e c u l a r = E m e r a l d S p e c u l a r ;
s h i n i n e s s = E m e r a l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − j a d e i t
c a s e JADE :
a m b i e n t = JadeAmbient ;
d i f f u s e = J a d e D i f f u s e ;
s p e c u l a r = J a d e S p e c u l a r ;
s h i n i n e s s = J a d e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − o b s y d i a n
c a s e OBSIDIAN :
a m b i e n t = O b s i d i a n A m b i e n t ;
d i f f u s e = O b s i d i a n D i f f u s e ;
s p e c u l a r = O b s i d i a n S p e c u l a r ;
s h i n i n e s s = O b s i d i a n S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p e r ł a
c a s e PEARL :
a m b i e n t = P e a r l A m b i e n t ;
d i f f u s e = P e a r l D i f f u s e ;
s p e c u l a r = P e a r l S p e c u l a r ;
s h i n i n e s s = P e a r l S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m e t a r i a ł − r u b i n
c a s e RUBY:
a m b i e n t = RubyAmbient ;
d i f f u s e = R u b y D i f f u s e ;
s p e c u l a r = R u b y S p e c u l a r ;
s h i n i n e s s = R u b y S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − t u r k u s
c a s e TURQUOISE :
a m b i e n t = T u r q u o i s e A m b i e n t ;
1. Światła i materiały
66
d i f f u s e = T u r q u o i s e D i f f u s e ;
s p e c u l a r = T u r q u o i s e S p e c u l a r ;
s h i n i n e s s = T u r q u o i s e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − c z a r n y
p l a s t i k
c a s e BLACK PLASTIC :
a m b i e n t = B l a c k P l a s t i c A m b i e n t ;
d i f f u s e = B l a c k P l a s t i c D i f f u s e ;
s p e c u l a r = B l a c k P l a s t i c S p e c u l a r ;
s h i n i n e s s = B l a c k P l a s t i c S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − c z a r n a
guma
c a s e BLACK RUBBER :
a m b i e n t = BlackRubberAmbient ;
d i f f u s e = B l a c k R u b b e r D i f f u s e ;
s p e c u l a r = B l a c k R u b b e r S p e c u l a r ;
s h i n i n e s s = B l a c k R u b b e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
c a s e FULL WINDOW :
a s p e c t = FULL WINDOW ;
R esha pe
( 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
c a s e ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
R esha pe
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
void
E x t e n s i o n S e t u p
( )
{
//
p o b r a n i e
numeru
w e r s j i
b i b l i o t e k i
OpenGL
const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g
( GL VERSION ) ;
//
o d c z y t
w e r s j i
OpenGL
i n t
m a j o r = 0 ,
m i n o r = 0 ;
i f
( s s c a n f
( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )
!=
2 )
{
#i f d e f WIN32
p r i n t f
( ” Błędny
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e l s e
p r i n t f
( ” B l e d n y
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e n d i f
e x i t
( 0 ) ;
}
//
s p r a w d z e n i e
c z y
j e s t
c o
n a j m n i e j
w e r s j a
1 . 4
i f
( m a j o r > 1
| |
m i n o r >= 4 )
{
//
p o b r a n i e
w s k a ź n i k a
w y b r a n e j
f u n k c j i
OpenGL
1 . 4
g l W i n d o w P o s 2 i = (PFNGLWINDOWPOS2IPROC) w g l G e t P r o c A d d r e s s
( ” g l W i n d o w P o s 2 i ” ) ;
}
e l s e
//
s p r a w d z e n i e
c z y
j e s t
o b s ł u g i w a n e
r o z s z e r z e n i e
A R B w i n d o w p o s
i f
( g l u t E x t e n s i o n S u p p o r t e d
( ” GL ARB window pos ” ) )
{
//
p o b r a n i e
w s k a ź n i k a
w y b r a n e j
f u n k c j i
r o z s z e r z e n i a
A R B w i n d o w p o s
g l W i n d o w P o s 2 i = (PFNGLWINDOWPOS2IPROC) w g l G e t P r o c A d d r e s s
( ” glWindowPos2iARB ” ) ;
}
e l s e
{
p r i n t f
( ” Brak
r o z s z e r z e n i a
ARB window pos ! \ n ” ) ;
1. Światła i materiały
67
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
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
(& a r g c , 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 | GLUT DEPTH ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
#i f d e f WIN32
g l u t C r e a t e W i n d o w
( ” Ś w i a t ł o
k i e r u n k o w e ” ) ;
#e l s e
g l u t C r e a t e W i n d o w
( ” S w i a t l o
k i e r u n k o w e ” ) ;
#e n d i f
//
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 S c e n e ) ;
//
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
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
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
g l u t K e y b o a r d F u n c
( 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
g l u t M o u s e F u n c
( 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
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
//
u t w o r z e n i e
podmenu − o b i e k t
i n t
MenuObject = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ” Kula ” ,SPHERE ) ;
glutAddMenuEntry
( ” C z a j n i k ” ,TEAPOT ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” S t o ż e k ” ,CONE ) ;
glutAddMenuEntry
( ” T o r u s ” ,TORUS ) ;
glutAddMenuEntry
( ” S z e ś c i a n ” ,CUBE ) ;
glutAddMenuEntry
( ” D w u n a s t o ś c i a n ” ,DODECAHEDRON) ;
glutAddMenuEntry
( ” O ś m i o ś c i a n ” ,OCTAHEDRON) ;
glutAddMenuEntry
( ” C z w o r o ś c i a n ” ,TETRAHEDRON) ;
glutAddMenuEntry
( ” D w u d z i e s t o ś c i a n ” ,ICOSAHEDRON ) ;
#e l s e
glutAddMenuEntry
( ” S t o z e k ” ,CONE ) ;
glutAddMenuEntry
( ” T o r u s ” ,TORUS ) ;
glutAddMenuEntry
( ” S z e s c i a n ” ,CUBE ) ;
glutAddMenuEntry
( ” D w u n a s t o s c i a n ” ,DODECAHEDRON) ;
glutAddMenuEntry
( ” O s m i o s c i a n ” ,OCTAHEDRON) ;
glutAddMenuEntry
( ” C z w o r o s c i a n ” ,TETRAHEDRON) ;
glutAddMenuEntry
( ” D w u d z i e s t o s c i a n ” ,ICOSAHEDRON ) ;
#e n d i f
//
u t w o r z e n i e
podmenu − M a t e r i a ł
i n t
M e n u M a t e r i a l = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” M o s i ą d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r ąz ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r ą z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedź ” ,COPPER ) ;
1. Światła i materiały
68
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d ź ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z ł o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z ł o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r ł a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e l s e
glutAddMenuEntry
( ” M o s i a d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r az ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r a z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedz ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d z ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z l o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z l o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r l a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e n d i f
//
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 = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a ł e
okno ” ,FULL WINDOW ) ;
#e l s e
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a l e
okno ” ,FULL WINDOW ) ;
#e n d i f
glutAddMenuEntry
( ” A s p e k t
o b r a z u
1 : 1 ” , ASPECT 1 1 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
glutAddSubMenu
( ” O b i e k t ” , MenuObject ) ;
#i f d e f WIN32
glutAddSubMenu
( ” M a t e r i a ł ” , M e n u M a t e r i a l ) ;
#e l s e
glutAddSubMenu
( ” M a t e r i a l ” , M e n u M a t e r i a l ) ;
#e n d i f
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , 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 ) ;
#e n d i f
//
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 j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
E x t e n s i o n S e t u p
( ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
1. Światła i materiały
69
Ostatni program przykładowy (plik reflektor.cpp) prezentuje sposób
wykorzystania punktowego światła kierunkowego, tzw. reflektora. Ponadto
program umożliwia zmianę wybranych parametrów pracy reflektora. Warto-
ści wszystkich modyfikowanych parametrów źródła światła wyświetlane są
na dole okna programu.
W celu łatwiejszej interpretacji uzyskanego efektu oświetlenia obiektu
w miejscu położenia źródła światła program rysuje niewielką czerwoną kulę
(barwa kuli nie ma nic wspólnego z kolorem źródła światła). Jednym ze spo-
sobów aby kula otrzymała tę barwę jest chwilowe wyłączenie źródła światła
GL LIGHT0. Najłatwiej jest to zrealizować odkładając na stos zmienne stanu
dotyczące oświetlenia, a następnie po modyfikacji wybranych parametrów
materiału i narysowaniu kuli pobrać ze stosu wcześniej odłożone zmienne.
Odłożenie na stos wybranych grup zmiennych stanu realizuje funkcja:
void glPushAttrib (GLbitfield mask)
Parametr mask to maska bitowa określająca jaka grupa lub grupy stanu mają
zostać odłożone na stos. Grupy zmiennych stanu określają następujące stałe:
— GL ACCUM BUFFER BIT - wartość bufora akumulacyjnego,
— GL COLOR BUFFER BIT - ustawienia bufora koloru,
— GL CURRENT BIT - aktualne kolory i współrzędne, w tym m.in. wektor
normalny,
— GL DEPTH BUFFER BIT - ustawienia bufora głębokości,
— GL ENABLE BIT - wartości znaczników,
— GL EVAL BIT - ustawienia mechanizmu automatycznego obliczania war-
tości,
— GL FOG BIT - ustawienia mgły,
— GL HINT BIT - ustawienia wskazówek renderingu,
— GL LIGHTING BIT - ustawienia oświetlenia (stała użyta w przykładowym
programie),
— GL LINE BIT - ustawienia renderingu linii,
— GL LIST BIT - ustawienia list wyświetlania,
— GL MULTISAMPLE BIT - ustawienia wielopróbkowania (multisamlingu),
— GL PIXEL MODE BIT - ustawienia przekształceń pikseli,
— GL POINT BIT - ustawienia renderingu punktów,
— GL POLYGON BIT - ustawienia renderingu wielokątów,
— GL POLYGON STIPPLE BIT - wzór wypełnienia wielokątów,
— GL SCISSOR BIT - ustawienia obcinania obrazu,
— GL STENCIL BUFFER BIT - ustawienia bufora szablonowego,
— GL TEXTURE BIT - ustawienia teksturowania,
— GL TRANSFORM BIT - ustawienia przekształceń i bryły obcinania,
— GL VIEWPORT BIT - ustawienia widoku,
1. Światła i materiały
70
— GL ALL ATTRIB BITS - wszystkie grupy zmiennych maszyny stanu biblio-
teki OpenGL.
Stałe te można w razie potrzeby łączyć przy pomocy bitowych operato-
rów logicznych. Zauważmy, że dwie spośród wymienionych stałych używa-
my już od dłuższego czasu w każdym przykładowym programie. Są to stałe:
GL COLOR BUFFER BIT i GL DEPTH BUFFER BIT.
Przywrócenie wartości zmiennych stanu wcześniej odłożonych na stos
realizuje funkcja:
void glPopAttrib ()
Dodajmy jeszcze, że stała GL MULTISAMPLE BIT została wprowadzona
w wersji 1.3 biblioteki OpenGL. Wcześniej technikę wielopróbkowania ob-
sługiwały rozszerzenia ARB multisample i SGIS multisample, przy czym
opisywana stała miała odpowiednio oznaczenia: GL MULTISAMPLE BIT ARB
i GL MULTISAMPLE BIT EXT.
Efekty działania programu ilustrują trzy rysunki. Pierwszy rysunek (18)
przedstawia oświetlenie obiektu silnie skupioną i zarazem wąską wiązką świa-
tła. Efekt jest zgodny z oczekiwaniami. Także drugi rysunek (19), przedsta-
wiający oświetlenie obiektu wąską ale słabo skupiona wiązką światła, daje
spodziewany efekt. Jednak na trzecim rysunku (20) widzimy, że próba oświe-
tlenia światłem kierunkowym obiektu posiadającego małą ilość wierzchołków
może dać w efekcie brak oświetlenia. Jest to związane z modelem oświetle-
nia Gourauda przyjętym w bibliotece OpenGL, który wylicza oświetlenie
wyłącznie dla wierzchołków. Jeżeli zatem w wiązce światła reflektora nie
znajdzie się żaden wierzchołek oświetlanego obiektu, OpenGL nie wykona
dla tego obiektu obliczeń związanych z oświetleniem.
Choć opisanej wady modelu oświetlenia biblioteki OpenGL nie można
usunąć, to stosunkowo łatwo można uniknąć związanych z tym objawów.
Najprostszą i najabardziej skuteczną metodą jest zwiększenie ilości wierz-
chołków, z których składa się obiekt.
1.9.6. Plik reflektor.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 . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l e x t . h>
#i f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
#i n c l u d e <GL/ g l x . h>
#d e f i n e
w g l G e t P r o c A d d r e s s
glXGetProcAddressARB
#e n d i f
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e
” c o l o r s . h ”
#i n c l u d e
” m a t e r i a l s . h ”
1. Światła i materiały
71
Rysunek 18. Program Reflektor - silnie skupiona i wąska wiązka światła
//
w s k a ź n i k
na
f u n k c j ę
g l W i n d o w P o s 2 i
PFNGLWINDOWPOS2IPROC g l W i n d o w P o s 2 i = NULL ;
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
//
o b i e k t y
SPHERE,
//
k u l a
TEAPOT,
//
c z a j n i k
CONE,
//
s t o ż e k
TORUS,
//
t o r u s
CUBE,
//
s z e ś c i a n
DODECAHEDRON,
//
d w u n a s t o ś c i a n
OCTAHEDRON,
//
o ś m i o ś c i a n
TETRAHEDRON,
//
c z w o r o ś c i a n
ICOSAHEDRON,
//
d w u d z i e s t o ś c i a n
//
m a t e r i a ł y
BRASS ,
//
m o s i ą d z
BRONZE,
//
b r ą z
POLISHED BRONZE ,
//
p o l e r o w a n y
b r ą z
CHROME,
//
chrom
COPPER,
//
m i e d ź
1. Światła i materiały
72
Rysunek 19. Program Reflektor - wąska ale słabo skupiona wiązka światła
POLISHED COPPER ,
//
p o l e r o w a n a
m i e d ź
GOLD,
//
z ł o t o
POLISHED GOLD ,
//
p o l e r o w a n e
z ł o t o
PEWTER,
//
g r a f i t
( c y n a
z
o ł o w i e m )
SILVER ,
//
s r e b r o
POLISHED SILVER ,
//
p o l e r o w a n e
s r e b r o
EMERALD,
//
s z m a r a g d
JADE,
//
j a d e i t
OBSIDIAN ,
//
o b s y d i a n
PEARL,
//
p e r ł a
RUBY,
//
r u b i n
TURQUOISE,
//
t u r k u s
BLACK PLASTIC ,
//
c z a r n y
p l a s t i k
BLACK RUBBER,
//
c z a r n a
guma
//
o b s z a r
r e n d e r i n g u
FULL WINDOW,
//
a s p e k t
o b r a z u − c a ł e
o k n o
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 ;
//
u s u n i ę c i e
d e f i n i c j i
makr
n e a r
i
f a r
1. Światła i materiały
73
Rysunek 20. Program Reflektor - efektu braku oświetlenia powierzchni
#i f d e f
n e a r
#undef
n e a r
#e n d i f
#i f d e f
f a r
#undef
f a r
#e n d i f
//
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 = − 2 . 0 ;
const GLdouble
r i g h t = 2 . 0 ;
const GLdouble bottom = − 2 . 0 ;
const GLdouble
t o p = 2 . 0 ;
const GLdouble
n e a r = 3 . 0 ;
const GLdouble
f a r = 7 . 0 ;
//
k ą t y
o b r o t u
o b i e k 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 ;
//
w s k a ź 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 ;
1. Światła i materiały
74
//
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 ;
//
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 ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u − d o m y ś l n i e
m o s i ą d z
const
G L f l o a t
∗ a m b i e n t = B r a s s A m b i e n t ;
const
G L f l o a t
∗ d i f f u s e = B r a s s D i f f u s e ;
const
G L f l o a t
∗ s p e c u l a r = B r a s s S p e c u l a r ;
G L f l o a t
s h i n i n e s s = B r a s s S h i n i n e s s ;
//
w y ś w i e t l a n y
o b i e k t
3D
i n t
o b j e c t = SPHERE ;
//
k i e r u n e k
ź r ó d ł a
ś w i a t ł a
G L f l o a t
l i g h t p o s i t i o n
[ 4 ] =
{
0 . 0 , 0 . 0 , 2 . 0 , 1 . 0
} ;
//
k ą t y
o b r o t u
p o ł o ż e n i a
ź r ó d ł a
ś w i a t ł a
G L f l o a t
l i g h t r o t a t e x = 0 . 0 ;
G L f l o a t
l i g h t r o t a t e y = 0 . 0 ;
//
k i e r u n e k
r e f l e k t o r a
G L f l o a t
s p o t d i r e c t i o n
[ 3 ] =
{
0 . 0 , 0 . 0 , − 1 . 0
} ;
//
k ą t
o d c i ę c i a
r e f l e k t o r a
G L f l o a t
s p o t c u t o f f = 1 8 0 . 0 ;
//
w y k ł a d n i k
t ł u m i e n i a
k ą t o w e g o
r e f l e k t o r a
G L f l o a t
s p o t e x p o n e n t = 1 2 8 . 0 ;
//
s t a ł y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
G L f l o a t
c o n s t a n t a t t e n u a t i o n = 1 . 0 ;
//
l i n i o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
G L f l o a t
l i n e a r a t t e n u a t i o n = 0 . 0 ;
//
k w a d r a t o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
G L f l o a t
q u a d r a t i c a t t e n u a t i o n = 0 . 0 ;
//
f u n k c j a
r y s u j ą c a
n a p i s w wybranym
m i e j s c u
//
( w e r s j a
k o r z y s t a j ą c a
z
f u n k c j i
g l W i n d o w P o s 2 i )
void
D r a w S t r i n g
( GLint x ,
GLint y ,
char ∗ s t r i n g )
{
//
p o ł o ż e n i e
n a p i s u
g l W i n d o w P o s 2 i
( x , y ) ;
//
w y ś w i e t l e n i e
n a p i s u
i n t
l e n = s t r l e n
( s t r i n g ) ;
f o r
( i n t
i = 0 ;
i < l e n ;
i ++)
g l u t B i t m a p C h a r a c t e r
( GLUT BITMAP 9 BY 15 , s t r i n g
[ i ] ) ;
}
//
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 S c e n e
( )
{
//
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
i
b u f o r a
g ł ę b o k o ś c i
1. Światła i materiały
75
g l C l e a r
( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(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
( ) ;
//
w ł ą c z e n i e
t e s t u
b u f o r a
g ł ę b o k o ś c i
g l E n a b l e
(GL DEPTH TEST ) ;
//
w ł ą c z e n i e
o ś w i e t l e n i a
g l E n a b l e
( GL LIGHTING ) ;
//
w ł ą c z e n i e
ś w i a t ł a
GL LIGHT0
g l E n a b l e
( GL LIGHT0 ) ;
//
w ł ą c z e n i e
a u t o m a t y c z n e j
n o r m a l i z a c j i
w e k t o r ó w
n o r m a l n y c h
g l E n a b l e
(GL NORMALIZE ) ;
//
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 ) ;
//
o b r o t y
o b i e k t u
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 ) ;
//
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 ) ;
//
w ł a ś c i w o ś c i
m a t e r i a ł u
g l M a t e r i a l f v
(GL FRONT, GL AMBIENT, a m b i e n t ) ;
g l M a t e r i a l f v
(GL FRONT, GL DIFFUSE , d i f f u s e ) ;
g l M a t e r i a l f v
(GL FRONT, GL SPECULAR, s p e c u l a r ) ;
g l M a t e r i a l f
(GL FRONT, GL SHININESS , s h i n i n e s s ) ;
//
k ą t
o d c i ę c i a
r e f l e k t o r a
g l L i g h t f
( GL LIGHT0 , GL SPOT CUTOFF , s p o t c u t o f f ) ;
//
w y k ł a d n i k
t ł u m i e n i a
k ą t o w e g o
r e f l e k t o r a
g l L i g h t f
( GL LIGHT0 , GL SPOT EXPONENT, s p o t e x p o n e n t ) ;
//
s t a ł y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a ,
g l L i g h t f
( GL LIGHT0 , GL CONSTANT ATTENUATION, c o n s t a n t a t t e n u a t i o n ) ;
//
l i n i o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
g l L i g h t f
( GL LIGHT0 , GL LINEAR ATTENUATION , l i n e a r a t t e n u a t i o n ) ;
//
k w a d r a t o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
g l L i g h t f
( GL LIGHT0 , GL QUADRATIC ATTENUATION, q u a d r a t i c a t t e n u a t i o n ) ;
//
z m i a n a
p o ł o ż e n i a
ź r ó d ł a
ś w i a t ł a
j e s t
wykonywana
n i e z a l e ż n i e
//
od
o b r o t ó w
o b i e k t u ,
s t ą d
o d ł o ż e n i e
na
s t o s
m a c i e r z y
m o d e l o w a n i a
g l P u s h M a t r i x
( ) ;
//
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
ź r ó d ł a
ś w i a t ł a
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 ) ;
//
o b r o t y
p o ł o ż e n i a
ź r ó d ł a
ś w i a t ł a − k l a w i s z e
k u r s o r a
g l R o t a t e f
( l i g h t r o t a t e x , 1 . 0 , 0 , 0 ) ;
g l R o t a t e f
( l i g h t r o t a t e y , 0 , 1 . 0 , 0 ) ;
//
p r z e s u n i ę c i e
ź r ó d ł a
ś w i a t ł a
g l T r a n s l a t e f
( l i g h t p o s i t i o n [ 0 ] , l i g h t p o s i t i o n [ 1 ] , l i g h t p o s i t i o n [ 2 ] ) ;
//
u s t a l e n i e
p o z y c j i
ź r ó d ł a
ś w i a t ł a
g l L i g h t f v
( GL LIGHT0 , GL POSITION , l i g h t p o s i t i o n ) ;
//
u s t a l e n i e
k i e r u n k u
r e f l e k t o r a
g l L i g h t f v
( GL LIGHT0 , GL SPOT DIRECTION , s p o t d i r e c t i o n ) ;
//
o d ł o ż e n i e
na
s t o s
z m i e n n y c h
s t a n u
z w i ą z a n y c h
z
o ś w i e t l e n i e m
s c e n y
g l P u s h A t t r i b
( GL LIGHTING BIT ) ;
//
w y ł a c z n i e
ź r ó d ł a
ś w i a t ł a
GL LIGHT0
g l D i s a b l e
( GL LIGHT0 ) ;
1. Światła i materiały
76
//
m a t e r i a ł
i m i t u j ą c y
ś w i e c e n i e
k u l i
na
c z e r w o n o
g l M a t e r i a l f v
(GL FRONT, GL EMISSION , Red ) ;
//
n a r y s o w a n i e
k u l i
p o ł o ż o n e j w p o c z ą t k u
ź r ó d ł a
ś w i a t ł a
g l u t S o l i d S p h e r e
( 0 . 1 , 3 0 , 2 0 ) ;
//
p r z y w r ó c e n i e
z m i e n n y c h
s t a n u
z w i ą z a n y c h
z
o ś w i e t l e n i e m
s c e n y
g l P o p A t t r i b
( ) ;
//
p r z y w r ó c e n i e
p i e r w o t n e j
m a c i e r z y
m o d e l o w a n i a
g l P o p M a t r i x
( ) ;
//
r y s o w a n i e
w y b r a n e g o
o b i e k t u
3D
switch
( o b j e c t )
{
//
k u l a
c a s e SPHERE :
g l u t S o l i d S p h e r e
( 1 . 0 , 5 0 , 4 0 ) ;
break ;
//
c z a j n i k
c a s e TEAPOT:
g l u t S o l i d T e a p o t
( 1 ) ;
break ;
//
s t o ż e k
c a s e CONE:
g l u t S o l i d C o n e
( 1 , 1 , 5 0 , 4 0 ) ;
break ;
//
t o r u s
c a s e TORUS :
g l u t S o l i d T o r u s
( 0 . 3 , 1 , 4 0 , 5 0 ) ;
break ;
//
s z e ś c i a n
c a s e CUBE :
g l u t S o l i d C u b e
( 1 ) ;
break ;
//
d w u n a s t o ś c i a n
c a s e DODECAHEDRON:
g l u t S o l i d D o d e c a h e d r o n
( ) ;
break ;
//
o ś m i o ś c i a n
c a s e OCTAHEDRON:
g l u t S o l i d O c t a h e d r o n
( ) ;
break ;
//
c z w o r o ś c i a n
c a s e TETRAHEDRON:
g l u t S o l i d 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
c a s e ICOSAHEDRON :
g l u t S o l i d I c o s a h e d r o n
( ) ;
break ;
}
//
i n f o r m a c j e
o
w a r t o ś c i a c h
m o d y f i k o w a n y c h
//
p a r a m e t r ó w
ź r ó d ł a
ś w i a t a ł a
GL LIGHT0
char
s t r i n g
[ 2 0 0 ] ;
G L f l o a t
v e c
[ 4 ] ;
g l C o l o r 3 f v
( B l a c k ) ;
//
k i e r u n e k
ź r ó d ł a
ś w i a t ł a
g l G e t L i g h t f v
( GL LIGHT0 , GL POSITION , v e c ) ;
s p r i n t f
( s t r i n g , ”GL POSITION = (% f ,% f ,% f ,% f ) ” , v e c [ 0 ] , v e c [ 1 ] , v e c [ 2 ] , v e c [ 3 ] ) ;
D r a w S t r i n g
( 2 , 2 , s t r i n g ) ;
g l G e t L i g h t f v
( GL LIGHT0 , GL SPOT DIRECTION , v e c ) ;
s p r i n t f
( s t r i n g , ”GL SPOT DIRECTION = (% f ,% f ,% f ) ” , v e c [ 0 ] , v e c [ 1 ] , v e c [ 2 ] ) ;
D r a w S t r i n g
( 2 , 1 6 , s t r i n g ) ;
//
k ą t
o d c i ę c i a
r e f l e k t o r a
g l G e t L i g h t f v
( GL LIGHT0 , GL SPOT CUTOFF , v e c ) ;
s p r i n t f
( s t r i n g , ”GL SPOT CUTOFF = %f ” , v e c [ 0 ] ) ;
D r a w S t r i n g
( 2 , 3 0 , s t r i n g ) ;
1. Światła i materiały
77
//
w y k ł a d n i k
t ł u m i e n i a
k ą t o w e g o
r e f l e k t o r a
g l G e t L i g h t f v
( GL LIGHT0 , GL SPOT EXPONENT, v e c ) ;
s p r i n t f
( s t r i n g , ”GL SPOT EXPONENT = %f ” , v e c [ 0 ] ) ;
D r a w S t r i n g
( 2 , 4 4 , s t r i n g ) ;
//
s t a ł y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a ,
g l G e t L i g h t f v
( GL LIGHT0 , GL CONSTANT ATTENUATION, v e c ) ;
s p r i n t f
( s t r i n g , ”GL CONSTANT ATTENUATION = %f ” , v e c [ 0 ] ) ;
D r a w S t r i n g
( 2 , 5 8 , s t r i n g ) ;
//
l i n i o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
g l G e t L i g h t f v
( GL LIGHT0 , GL LINEAR ATTENUATION , v e c ) ;
s p r i n t f
( s t r i n g , ”GL LINEAR ATTENUATION = %f ” , v e c [ 0 ] ) ;
D r a w S t r i n g
( 2 , 7 2 , s t r i n g ) ;
//
k w a d r a t o w y
w s p ó ł c z y n n i k
t ł u m i e n i a
ś w i a t ł a
g l G e t L i g h t f v
( GL LIGHT0 , GL QUADRATIC ATTENUATION, v e c ) ;
s p r i n t f
( s t r i n g , ”GL QUADRATIC ATTENUATION = %f ” , v e c [ 0 ] ) ;
D r a w S t r i n g
( 2 , 8 6 , s t r i n g ) ;
//
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
( ) ;
//
z a m i a n a
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 ( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( 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
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(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 ś ć
o k n a
w i ę k s z a
od
w y s o k o ś c i
o k n a
i f
( w i d t h < h e i g h t && w i d t h > 0 )
g l F r u s t u m
( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;
e l s e
//
s z e r o k o ś ć
o k n a
w i ę k s z a
l u b
równa
w y s o k o ś c i
o k n a
i f
( w i d t h >= h e i g h t && h e i g h t > 0 )
g l F r u s t u m
( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;
}
e l s e
g l F r u s t u m
( l e f t , r i g h t , bottom , top , n e a r , 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 S c e n e
( ) ;
}
//
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 )
{
switch
( k e y )
{
//
k l a w i s z
”+” − p o w i ę k s z e n i e
o b i e k t u
c a s e
’+ ’ :
s c a l e += 0 . 0 5 ;
break ;
//
k l a w i s z
”−” − z m n i e j s z e n i e
o b i e k t u
c a s e
’− ’ :
i f
( s c a l e > 0 . 0 5 )
s c a l e −= 0 . 0 5 ;
break ;
//
k l a w i s z
” S ” − z w i ę k s z e n i e
k ą t a
o b c i ę c i a
r e f l e k t o r a
c a s e
’ S ’ :
i f
( s p o t c u t o f f == 9 0 )
1. Światła i materiały
78
s p o t c u t o f f = 1 8 0 ;
e l s e
i f
( s p o t c u t o f f < 9 0 )
s p o t c u t o f f ++;
break ;
//
k l a w i s z
” s ” − z m n i e j s z e n i e
k ą t a
o b c i ę c i a
r e f l e k t o r a
c a s e
’ s ’ :
i f
( s p o t c u t o f f == 1 8 0 )
s p o t c u t o f f = 9 0 ;
e l s e
i f
( s p o t c u t o f f > 0 )
s p o t c u t o f f −−;
break ;
//
k l a w i s z
”E” − z w i ę k s z e n i e
w y k ł a d n i k a
t ł u m i e n i a
k ą t o w e g o
r e f l e k t o r a
c a s e
’E ’ :
i f
( s p o t e x p o n e n t < 1 2 8 )
s p o t e x p o n e n t ++;
break ;
//
k l a w i s z
” e ” − z m n i e j s z e n i e
w y k ł a d n i k a
t ł u m i e n i a
k ą t o w e g o
r e f l e k t o r a
c a s e
’ e ’ :
i f
( s p o t e x p o n e n t > 0 )
s p o t e x p o n e n t −−;
break ;
//
k l a w i s z
”C” − z w i ę k s z e n i e
s t a ł e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’C ’ :
c o n s t a n t a t t e n u a t i o n += 0 . 1 ;
break ;
//
k l a w i s z
” c ” − z m n i e j s z e n i e
s t a ł e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’ c ’ :
i f
( c o n s t a n t a t t e n u a t i o n > 0 )
c o n s t a n t a t t e n u a t i o n −= 0 . 1 ;
break ;
//
k l a w i s z
”L” − z w i ę k s z e n i e
l i n i o w e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’ L ’ :
l i n e a r a t t e n u a t i o n += 0 . 1 ;
break ;
//
k l a w i s z
” l ” − z m n i e j s z e n i e
l i n i o w e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’ l ’ :
i f
( l i n e a r a t t e n u a t i o n > 0 )
l i n e a r a t t e n u a t i o n −= 0 . 1 ;
break ;
//
k l a w i s z
”Q” − z w i ę k s z e n i e
k w a d r a t o w e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’Q ’ :
q u a d r a t i c a t t e n u a t i o n += 0 . 1 ;
break ;
//
k l a w i s z
” q ” − z m n i e j s z e n i e
k w a d r a t o w e g o
w s p ó ł c z y n n i k a
t ł u m i e n i a
ś w i a t ł a
c a s e
’ q ’ :
i f
( q u a d r a t i c a t t e n u a t i o n > 0 )
q u a d r a t i c a t t e n u a t i o n −= 0 . 1 ;
break ;
}
//
n a r y s o w a n i e
s c e n y
D i s p l a y S c e n e
( ) ;
}
//
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
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o 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 ;
}
1. Światła i materiały
79
}
}
//
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)
{
r o t a t e y += 30
∗ ( 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 ;
r o t a t e x −= 30
∗ ( t o p − 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
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
( k e y )
{
//
k u r s o r w l e w o
c a s e GLUT KEY LEFT :
l i g h t r o t a t e y −= 5 ;
break ;
//
k u r s o r w p r a w o
c a s e GLUT KEY RIGHT :
l i g h t r o t a t e y += 5 ;
break ;
//
k u r s o r w d ó ł
c a s e GLUT KEY DOWN :
l i g h t r o t a t e x += 5 ;
break ;
//
k u r s o r w g ó r ę
c a s e GLUT KEY UP :
l i g h t r o t a t e x −= 5 ;
break ;
}
//
o d r y s o w a n i e
o k n a
D i s p l a y S c e n e
( ) ;
}
//
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 )
{
//
r y s o w a n y
o b i e k t − k u l a
c a s e SPHERE :
o b j e c t = SPHERE ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − c z a j n i k
c a s e TEAPOT:
o b j e c t = TEAPOT;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − s t o ż e k
c a s e CONE:
o b j e c t = CONE;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − t o r u s
c a s e TORUS :
o b j e c t = TORUS ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − s z e ś c i a n
c a s e CUBE :
1. Światła i materiały
80
o b j e c t = CUBE ;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − d w u n a s t o ś c i a n
c a s e DODECAHEDRON:
o b j e c t = DODECAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − o ś m i o ś c i a n
c a s e OCTAHEDRON:
o b j e c t = OCTAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − c z w o r o ś c i a n
c a s e TETRAHEDRON:
o b j e c t = TETRAHEDRON;
D i s p l a y S c e n e
( ) ;
break ;
//
r y s o w a n y
o b i e k t − d w u d z i e s t o ś c i a n
c a s e ICOSAHEDRON :
o b j e c t = ICOSAHEDRON ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − m o s i ą d z
c a s e BRASS :
a m b i e n t = B r a s s A m b i e n t ;
d i f f u s e = B r a s s D i f f u s e ;
s p e c u l a r = B r a s s S p e c u l a r ;
s h i n i n e s s = B r a s s S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − b r ą z
c a s e BRONZE:
a m b i e n t = BronzeAmbient ;
d i f f u s e = B r o n z e D i f f u s e ;
s p e c u l a r = B r o n z e S p e c u l a r ;
s h i n i n e s s = B r o n z e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n y
b r ą z
c a s e POLISHED BRONZE :
a m b i e n t = P o l i s h e d B r o n z e A m b i e n t ;
d i f f u s e = P o l i s h e d B r o n z e D i f f u s e ;
s p e c u l a r = P o l i s h e d B r o n z e S p e c u l a r ;
s h i n i n e s s = P o l i s h e d B r o n z e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − chrom
c a s e CHROME:
a m b i e n t = ChromeAmbient ;
d i f f u s e = C h r o m e D i f f u s e ;
s p e c u l a r = C h r o m e S p e c u l a r ;
s h i n i n e s s = C h r o m e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − m i e d ź
c a s e COPPER:
a m b i e n t = CopperAmbient ;
d i f f u s e = C o p p e r D i f f u s e ;
s p e c u l a r = C o p p e r S p e c u l a r ;
s h i n i n e s s = C o p p e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n a
m i e d ź
c a s e POLISHED COPPER :
a m b i e n t = P o l i s h e d C o p p e r A m b i e n t ;
d i f f u s e = P o l i s h e d C o p p e r D i f f u s e ;
s p e c u l a r = P o l i s h e d C o p p e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d C o p p e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
1. Światła i materiały
81
break ;
//
m a t e r i a ł − z ł o t o
c a s e GOLD:
a m b i e n t = GoldAmbient ;
d i f f u s e = G o l d D i f f u s e ;
s p e c u l a r = G o l d S p e c u l a r ;
s h i n i n e s s = G o l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
z ł o t o
c a s e POLISHED GOLD :
a m b i e n t = P o l i s h e d G o l d A m b i e n t ;
d i f f u s e = P o l i s h e d G o l d D i f f u s e ;
s p e c u l a r = P o l i s h e d G o l d S p e c u l a r ;
s h i n i n e s s = P o l i s h e d G o l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − g r a f i t
( c y n a
z
o ł o w i e m )
c a s e PEWTER:
a m b i e n t = PewterAmbient ;
d i f f u s e = P e w t e r D i f f u s e ;
s p e c u l a r = P e w t e r S p e c u l a r ;
s h i n i n e s s = P e w t e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − s r e b r o
c a s e SILVER :
a m b i e n t = S i l v e r A m b i e n t ;
d i f f u s e = S i l v e r D i f f u s e ;
s p e c u l a r = S i l v e r S p e c u l a r ;
s h i n i n e s s = S i l v e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p o l e r o w a n e
s r e b r o
c a s e POLISHED SILVER :
a m b i e n t = P o l i s h e d S i l v e r A m b i e n t ;
d i f f u s e = P o l i s h e d S i l v e r D i f f u s e ;
s p e c u l a r = P o l i s h e d S i l v e r S p e c u l a r ;
s h i n i n e s s = P o l i s h e d S i l v e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − s z m a r a g d
c a s e EMERALD:
a m b i e n t = EmeraldAmbient ;
d i f f u s e = E m e r a l d D i f f u s e ;
s p e c u l a r = E m e r a l d S p e c u l a r ;
s h i n i n e s s = E m e r a l d S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − j a d e i t
c a s e JADE :
a m b i e n t = JadeAmbient ;
d i f f u s e = J a d e D i f f u s e ;
s p e c u l a r = J a d e S p e c u l a r ;
s h i n i n e s s = J a d e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − o b s y d i a n
c a s e OBSIDIAN :
a m b i e n t = O b s i d i a n A m b i e n t ;
d i f f u s e = O b s i d i a n D i f f u s e ;
s p e c u l a r = O b s i d i a n S p e c u l a r ;
s h i n i n e s s = O b s i d i a n S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − p e r ł a
c a s e PEARL :
a m b i e n t = P e a r l A m b i e n t ;
d i f f u s e = P e a r l D i f f u s e ;
s p e c u l a r = P e a r l S p e c u l a r ;
s h i n i n e s s = P e a r l S h i n i n e s s ;
1. Światła i materiały
82
D i s p l a y S c e n e
( ) ;
break ;
//
m e t a r i a ł − r u b i n
c a s e RUBY:
a m b i e n t = RubyAmbient ;
d i f f u s e = R u b y D i f f u s e ;
s p e c u l a r = R u b y S p e c u l a r ;
s h i n i n e s s = R u b y S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − t u r k u s
c a s e TURQUOISE :
a m b i e n t = T u r q u o i s e A m b i e n t ;
d i f f u s e = T u r q u o i s e D i f f u s e ;
s p e c u l a r = T u r q u o i s e S p e c u l a r ;
s h i n i n e s s = T u r q u o i s e S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − c z a r n y
p l a s t i k
c a s e BLACK PLASTIC :
a m b i e n t = B l a c k P l a s t i c A m b i e n t ;
d i f f u s e = B l a c k P l a s t i c D i f f u s e ;
s p e c u l a r = B l a c k P l a s t i c S p e c u l a r ;
s h i n i n e s s = B l a c k P l a s t i c S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
m a t e r i a ł − c z a r n a
guma
c a s e BLACK RUBBER :
a m b i e n t = BlackRubberAmbient ;
d i f f u s e = B l a c k R u b b e r D i f f u s e ;
s p e c u l a r = B l a c k R u b b e r S p e c u l a r ;
s h i n i n e s s = B l a c k R u b b e r S h i n i n e s s ;
D i s p l a y S c e n e
( ) ;
break ;
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
c a s e FULL WINDOW :
a s p e c t = FULL WINDOW ;
R esha pe
( 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
c a s e ASPECT 1 1 :
a s p e c t = ASPECT 1 1 ;
R esha pe
( g l u t G e t
(GLUT WINDOW WIDTH) , g l u t G e t
(GLUT WINDOW HEIGHT ) ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
void
E x t e n s i o n S e t u p
( )
{
//
p o b r a n i e
numeru
w e r s j i
b i b l i o t e k i
OpenGL
const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g
( GL VERSION ) ;
//
o d c z y t
w e r s j i
OpenGL
i n t
m a j o r = 0 ,
m i n o r = 0 ;
i f
( s s c a n f
( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )
!=
2 )
{
#i f d e f WIN32
p r i n t f
( ” Błędny
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e l s e
p r i n t f
( ” B l e d n y
f o r m a t
w e r s j i
OpenGL\n ” ) ;
#e n d i f
e x i t
( 0 ) ;
}
//
s p r a w d z e n i e
c z y
j e s t
c o
n a j m n i e j
w e r s j a
1 . 4
i f
( m a j o r > 1
| |
m i n o r >= 4 )
1. Światła i materiały
83
{
//
p o b r a n i e
w s k a ź n i k a
w y b r a n e j
f u n k c j i
OpenGL
1 . 4
g l W i n d o w P o s 2 i = (PFNGLWINDOWPOS2IPROC) w g l G e t P r o c A d d r e s s
( ” g l W i n d o w P o s 2 i ” ) ;
}
e l s e
//
s p r a w d z e n i e
c z y
j e s t
o b s ł u g i w a n e
r o z s z e r z e n i e
A R B w i n d o w p o s
i f
( g l u t E x t e n s i o n S u p p o r t e d
( ” GL ARB window pos ” ) )
{
//
p o b r a n i e
w s k a ź n i k a
w y b r a n e j
f u n k c j i
r o z s z e r z e n i a
A R B w i n d o w p o s
g l W i n d o w P o s 2 i = (PFNGLWINDOWPOS2IPROC) w g l G e t P r o c A d d r e s s
( ” glWindowPos2iARB ” ) ;
}
e l s e
{
p r i n t f
( ” Brak
r o z s z e r z e n i a
ARB window pos ! \ n ” ) ;
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
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
(& a r g c , 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 | GLUT DEPTH ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t C r e a t e W i n d o w
( ” R e f l e k t o r ” ) ;
//
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 S c e n e ) ;
//
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
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
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
g l u t K e y b o a r d F u n c
( 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
g l u t M o u s e F u n c
( 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
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
u t w o r z e n i e
menu
p o d r ę c z n e g o
g l u t C r e a t e M e n u
( Menu ) ;
//
u t w o r z e n i e
podmenu − o b i e k t
i n t
MenuObject = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ” Kula ” ,SPHERE ) ;
glutAddMenuEntry
( ” C z a j n i k ” ,TEAPOT ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” S t o ż e k ” ,CONE ) ;
glutAddMenuEntry
( ” T o r u s ” ,TORUS ) ;
glutAddMenuEntry
( ” S z e ś c i a n ” ,CUBE ) ;
glutAddMenuEntry
( ” D w u n a s t o ś c i a n ” ,DODECAHEDRON) ;
glutAddMenuEntry
( ” O ś m i o ś c i a n ” ,OCTAHEDRON) ;
glutAddMenuEntry
( ” C z w o r o ś c i a n ” ,TETRAHEDRON) ;
glutAddMenuEntry
( ” D w u d z i e s t o ś c i a n ” ,ICOSAHEDRON ) ;
#e l s e
glutAddMenuEntry
( ” S t o z e k ” ,CONE ) ;
glutAddMenuEntry
( ” T o r u s ” ,TORUS ) ;
glutAddMenuEntry
( ” S z e s c i a n ” ,CUBE ) ;
glutAddMenuEntry
( ” D w u n a s t o s c i a n ” ,DODECAHEDRON) ;
glutAddMenuEntry
( ” O s m i o s c i a n ” ,OCTAHEDRON) ;
glutAddMenuEntry
( ” C z w o r o s c i a n ” ,TETRAHEDRON) ;
glutAddMenuEntry
( ” D w u d z i e s t o s c i a n ” ,ICOSAHEDRON ) ;
#e n d i f
//
u t w o r z e n i e
podmenu − M a t e r i a ł
1. Światła i materiały
84
i n t
M e n u M a t e r i a l = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” M o s i ą d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r ąz ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r ą z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedź ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d ź ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z ł o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z ł o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r ł a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e l s e
glutAddMenuEntry
( ” M o s i a d z ” ,BRASS ) ;
glutAddMenuEntry
( ” B r az ” ,BRONZE ) ;
glutAddMenuEntry
( ” P o l e r o w a n y
b r a z ” ,POLISHED BRONZE ) ;
glutAddMenuEntry
( ”Chrom” ,CHROME) ;
glutAddMenuEntry
( ” Miedz ” ,COPPER ) ;
glutAddMenuEntry
( ” P o l e r o w a n a
m i e d z ” ,POLISHED COPPER ) ;
glutAddMenuEntry
( ” Z l o t o ” ,GOLD ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
z l o t o ” ,POLISHED GOLD ) ;
glutAddMenuEntry
( ” G r a f i t
( c y n a
z
o ł o w i e m ) ” ,PEWTER) ;
glutAddMenuEntry
( ” S r e b r o ” , SILVER ) ;
glutAddMenuEntry
( ” P o l e r o w a n e
s r e b r o ” , POLISHED SILVER ) ;
glutAddMenuEntry
( ” Szmaragd ” ,EMERALD) ;
glutAddMenuEntry
( ” J a d e i t ” ,JADE ) ;
glutAddMenuEntry
( ” O b s y d i a n ” , OBSIDIAN ) ;
glutAddMenuEntry
( ” P e r l a ” ,PEARL ) ;
glutAddMenuEntry
( ” Rubin ” ,RUBY ) ;
glutAddMenuEntry
( ” Turkus ” ,TURQUOISE ) ;
glutAddMenuEntry
( ” Czarny
p l a s t i k ” , BLACK PLASTIC ) ;
glutAddMenuEntry
( ” Czarna guma” ,BLACK RUBBER ) ;
#e n d i f
//
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 = g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a ł e
okno ” ,FULL WINDOW ) ;
#e l s e
glutAddMenuEntry
( ” A s p e k t
o b r a z u − c a l e
okno ” ,FULL WINDOW ) ;
#e n d i f
glutAddMenuEntry
( ” A s p e k t
o b r a z u
1 : 1 ” , ASPECT 1 1 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
glutAddSubMenu
( ” O b i e k t ” , MenuObject ) ;
#i f d e f WIN32
glutAddSubMenu
( ” M a t e r i a ł ” , M e n u M a t e r i a l ) ;
#e l s e
glutAddSubMenu
( ” M a t e r i a l ” , M e n u M a t e r i a l ) ;
#e n d i f
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , 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 ) ;
#e n d i f
//
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 j
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
1. Światła i materiały
85
//
s p r a w d z e n i e
i
p r z y g o t o w a n i e
o b s ł u g i
w y b r a n y c h
r o z s z e r z e ń
E x t e n s i o n S e t u p
( ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Literatura
86
Literatura
[1] Mark Segal, Kurt Akeley: The OpenGL Graphics System. A Specification
Version 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,
[6] Piotr Andrzejewski, Jakub Kurzak: Wprowadzenie do OpenGL. Programowa-
nie 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
[9] Mark J. Kilgard: All About OpenGL Extensions,
resources/features/OGLextensions/
[10] Jon Leech: How to Create OpenGL Extensions,
projects/ogl-sample/registry/doc/rules.html
[11] Silicon Graphics, Inc: OpenGL
R
Extension Registry,