Janusz Ganczarski
OpenGL
NURBS
Spis treści
Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Obiekt NURBS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Krzywe NURBS . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
Powierzchnie NURBS . . . . . . . . . . . . . . . . . . . . . . . . . .
2
Funkcje zwrotne . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
3
Właściwości NURBS . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
Właściwość GLU NURBS MODE . . . . . . . . . . . . . . .
6
Właściwość GLU CULLING . . . . . . . . . . . . . . . . . .
6
Właściwość GLU SAMPLING METHOD . . . . . . . . . . .
8
Właściwość GLU SAMPLING TOLERANCE . . . . . . . .
8
Właściwość GLU PARAMETRIC TOLERANCE . . . . . .
8
Właściwości GLU U STEP i GLU V STEP
. . . . . . . . .
8
Właściwość GLU AUTO LOAD MATRIX . . . . . . . . . .
9
Właściwość GLU DISPLAY MODE . . . . . . . . . . . . . .
9
Pobieranie właściwości NURBS . . . . . . . . . . . . . . . . . . . . .
9
Wycinanie fragmentów powierzchni
. . . . . . . . . . . . . . . . . .
10
. . . . . . . . . . . . . . . . . . . . . . . . .
11
. . . . . . . . . . . . . . . . . . . . .
12
Plik powierzchnia nurbs.cpp . . . . . . . . . . . . . . . . . .
18
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35
1. NURBS
Opisane w poprzednim odcinku kursu krzywe i powierzchnie B´
eziera nie
są niestety pozbawione wad. Uzależnienie kształtu krzywej lub powierzchni
od wszystkich punktów kontrolnych utrudnia kontrolę na kształtem obiektu,
zwłaszcza przy rosnącym stopniu krzywej lub powierzchni. Utrudnione jest
także gładkie łączenie wielu obiektów w jedną całość.
Wymienionych wad pozbawione są krzywe i powierzchnie NURBS (ang.
Non-Uniform Rational B-Spline), których obsługę zawiera biblioteka GLU.
W szczególności stopień obiektów NURBS nie rośnie wraz ze wzrostem liczby
punktów kontrolnych, bowiem krzywa (powierzchnia) NURBS składa się z
segmentów. Kształt ewaluowanej krzywej lub powierzchni zależy od pewnej
liczby punktów kontrolnych w sąsiedztwie oraz od tzw. węzłów (ang. knots)
określających wpływ kolejnych punktów kontrolnych na kształt segmentu
krzywej lub powierzchni. Na każdy punkt kontrolny przypadają dwa węzły,
a im mniejsza różnica wartości pomiędzy nimi, tym mniejsza jest krzywizna
segmentu krzywej lub powierzchni.
W praktyce obiekty NURBS pozwalają na modelowanie zarówno pod-
stawowych obiektów geometrycznych (linie, koła, elipsy, kule) jak i dowolnie
skomplikowanych kształtów.
1.1. Obiekt NURBS
Krzywą lub powierzchnię NURBS reprezentuje struktura (w przypad-
ku języka C++ klasa) GLUnurbs. Dostępna jest także alternatywna nazwa
struktury/klasy GLUnurbsObj.
Obiekt NURBS tworzy wywołanie funkcji gluNewNurbsRenderer:
GLUnurbs *gluNewNurbsRenderer (void)
która zwraca wskaźnik do struktury (klasy) GLUnurbs, niezbędny w wywoła-
niach pozostałych funkcji obsługujących krzywe i powierzchnie NURBS. Po
zakończeniu operacji na danym obiekcie NURBS należy zwolnić przydzieloną
mu pamięć wywołując funkcję:
void gluDeleteNurbsRenderer (GLUnurbs *nurb)
1.2. Krzywe NURBS
Definicję krzywej NURBS rozpoczyna wywołanie funkcji gluBeginCurve:
void gluBeginCurve (GLUnurbs *nurb)
której jedynym parametrem jest wskaźnik do struktury (klasy) GLUnurbs.
Kształ krzywej NURBS definiuje funkcja gluNurbsCurve:
1. NURBS
2
void gluNurbsCurve (GLUnurbs *nurb,
GLint knotCount,
GLfloat *knots,
GLint stride,
GLfloat *control,
GLint order,
GLenum type)
Parametr knotCount określa ilość węzłów, których wartości zawiera ta-
blica knots, natomiast ilość punktów kontrolnych zawartych w tablicy con-
trol określa parametr order. Odstęp pomiędzy wartościami kolejnych punk-
tów kontrolnych zawiera parametr stride.
Ostatni parametr type określa typ generowanych danych krzywej. Ak-
ceptowane są wszystkie jednowymiarowe ewaluatory zdefiniowane dla krzy-
wych B´
eziera: GL MAP1 VERTEX 3, GL MAP1 VERTEX 4, GL MAP1 INDEX, GL -
MAP1 COLOR 4, GL MAP1 NORMAL, GL MAP1 TEXTURE COORD 1, GL MAP1 TEX-
TURE COORD 2, GL MAP1 TEXTURE COORD 3 i GL MAP1 TEXTURE COORD 4.
Po zakończeniu definiowania krzywej NURBS trzeba wywołać funkcję
gluEndCurve:
void gluEndCurve (GLUnurbs *nurb)
1.3. Powierzchnie NURBS
Definicję powierzchni NURBS rozpoczyna wywołanie funkcji gluBegin-
Surface:
void gluBeginSurface (GLUnurbs *nurb)
Kształt powierzchni NURBS określa funkcja gluNurbsSurface:
void gluNurbsSurface (GLUnurbs *nurb,
GLint sKnotCount,
GLfloat *sKnots,
GLint tKnotCount,
GLfloat *tKnots,
GLint sStride,
GLint tStride,
GLfloat *control,
GLint sOrder,
GLint tOrder,
GLenum type)
Parametry sKnotCount i tKnotCount określają ilości węzłów dla kierun-
ku s i t, których wartości zawierają odpowiednio tablice sKnots i tKnots.
1. NURBS
3
Ilości punktów kontrolnych dla kierunku s i t zawierają parametry sOrder
i tOrder. Same punkty kontrole są zawarte w tablicy control, przy czym
odstępy pomiędzy wartościami poszczególnych punktów kontrolnych w kie-
runkach s i t określają parametry sStride i tStride.
Ostatni parametr type określa typ generowanych danych powierzchni.
Dopuszczalne są wszystkie dwuwymiarowe ewaluatory zdefiniowane dla po-
wierzchni B´
eziera: GL MAP2 VERTEX 3, GL MAP2 VERTEX 4, GL MAP2 INDEX,
GL MAP2 COLOR 4, GL MAP2 NORMAL, GL MAP2 TEXTURE COORD 1, GL MAP2 TEX-
TURE COORD 2, GL MAP2 TEXTURE COORD 3 i GL MAP2 TEXTURE COORD 4.
Po zakończeniu definiowania krzywej NURBS trzeba wywołać funkcję
gluEndSurface:
void gluEndSurface (GLUnurbs *nurb)
1.4. Funkcje zwrotne
Biblioteka GLU zawiera obsługę funkcji zwrotnych wywoływanych na
różnym etapie tworzenia krzywych i powierzchni NURBS. Dołączenie funkcji
zwrotnej realizuje funkcja:
void gluNurbsCallback (GLUnurbs *nurb,
GLenum which,
void (*fn)())
której parametr which określa rodzaj wykonywanej czynności lub rodzaj
generowanych danych podczas renderingu obiektu NURBS, a odpowiednia
funkcja zwrotna wskazywana jest w parametrze fn.
Funkcje zwrotne występują w dwóch wersjach. Pierwsza z nich zwra-
ca tylko dane związane z charakterem swojego działania (np. współrzędne
wierzchołków prymitywów). Wersje alternatywne zwracają dodatkowo dane
użytkownika przekazane w parametrze userData funkcji:
void gluNurbsCallbackData (GLUnurbs *nurb,
GLvoid *userData)
Funkcje zwrotne renderera obiektów NURBS określone są następującymi
stałymi:
— GLU NURBS BEGIN, GLU NURBS BEGIN DATA - początek rysowania prymi-
tywów graficznych, z których składa się obiekt NURBS; funkcje zwrotne
mają postać:
void begin (GLenum type)
void beginData (GLenum type, void *userData)
1. NURBS
4
gdzie parametr type określa rodzaj rysowanych prymitywów i przyjmuje
jedną z wartości: GL LINES, GL LINE STRIP, GL TRIANGLE FAN, GL TRI-
ANGLE STRIP, GL TRIANGLES i GL QUAD STRIP,
— GLU NURBS VERTEX, GLU NURBS VERTEX DATA - współrzędne (x, y, z) wierz-
chołków prymitywów, które są zwracane w parametrze vertex funkcji:
void vertex (GLfloat *vertex)
void vertexData (GLfloat *vertex, void *userData)
— GLU NURBS NORMAL, GLU NURBS NORMAL DATA - współrzędne (x, y, z) wek-
torów normalnych, które są zwracane w parametrze normal funkcji:
void normal (GLfloat *normal)
void normalData (GLfloat *normal, void *userData)
— GLU NURBS COLOR, GLU NURBS COLOR DATA - składowe RGBA kolorów
wierzchołków prymitywów, które są zwracane w parametrze color funk-
cji:
void color (GLfloat *color)
void colorData (GLfloat *color, void *userData)
— GLU NURBS TEXTURE COORD, GLU NURBS TEXTURE COORD DATA - współrzęd-
ne tekstury; ilość współrzędnych zależy od rodzaju wybranego ewaluato-
ra; funkcje zwrotne mają postać:
void texCoord (GLfloat *tex_coord)
void texCoordData (GLfloat *tex_coord, void *userData)
— GLU NURBS END, GLU NURBS END DATA - koniec rysowania prymitywów;
funkcje zwrotne mają postać:
void end (void)
void endData (void *userData)
— GLU NURBS ERROR, GLU ERROR - wystąpienie błędu podczas tworzenia krzy-
wej lub powierzchni NURBS; kod błędu (patrz tabela 1) zwracany jest
w parametrze errno funkcji zwrotnej:
void error (GLenum errno)
Początkowo wszystkie funkcje zwrotne są niezdefiniowane (wartość NULL).
Oprócz GLU NURBS ERROR (GLU ERROR) wszystkie funkcje zwrotne zostały
wprowadzone w wersji 1.3 biblioteki, a wcześniej w rozszerzeniu EXT nurbs -
tessellator. Funkcje zwrotne wprowadzone w wersji 1.3 są aktywne tyl-
ko wtedy, gdy tryb renderingu obiektu NURBS (GLU NURBS MODE) wynosi
GLU NURBS TESSELLATOR.
1. NURBS
5
numer błędu
opis błędu
GLU NURBS ERROR1
nieobsługiwana kolejność krzywej sklejanej
GLU NURBS ERROR2
zbyt mała ilość węzłów
GLU NURBS ERROR3
poprawny zakres węzłów jest pusty
GLU NURBS ERROR4
ciąg węzłów zawiera zmniejszające się
wartości węzłów
GLU NURBS ERROR5
wielokrotność węzłów jest większa niż rząd
krzywej sklejanej
GLU NURBS ERROR6
gluEndCurve musi być za gluBeginCurve
GLU NURBS ERROR7
gluBeginCurve musi poprzedzać gluEndCurve
GLU NURBS ERROR8
brakujące lub nadmiarowe dane geometryczne
GLU NURBS ERROR9
nie można narysować krzywych wycinających
GLU NURBS ERROR10
brakujące lub nadmiarowe dane dziedziny
GLU NURBS ERROR11
brakujące lub nadmiarowe dane dziedziny
GLU NURBS ERROR12
gluEndTrim musi poprzedzać gluEndSurface
GLU NURBS ERROR13
gluBeginSurface musi poprzedać
gluEndSurface
GLU NURBS ERROR14
krzywa niepoprawnego typu przekazana jako
krzywa wycinająca
GLU NURBS ERROR15
gluBeginSurface musi poprzedzać
gluBeginTrim
GLU NURBS ERROR16
gluEndTrim musi być za gluBeginTrim
GLU NURBS ERROR17
gluBeginTrim musi poprzedzać gluEndTrim
GLU NURBS ERROR18
błędna lub brak krzywej wycinającej
GLU NURBS ERROR19
gluBeginTrim musi poprzedzać gluPwlCurve
GLU NURBS ERROR20
podwójne odniesienie do krzywej wycinającej
GLU NURBS ERROR21
połączenie krzywej wycinającej z krzywą NURBS
GLU NURBS ERROR22
nieprawidłowe użycie danych krzywej wycinającej
GLU NURBS ERROR23
podwójne odniesienie do krzywej NURBS
GLU NURBS ERROR24
połączenie krzywej NURBS z krzywą wycinającą
GLU NURBS ERROR25
podwójne odniesienie do powierzchni NURBS
GLU NURBS ERROR26
błędna właściwość
GLU NURBS ERROR27
gluEndSurface musi być za gluBeginSurface
GLU NURBS ERROR28
przecinające się lub źle zorientowane krzywe
wycinające
GLU NURBS ERROR29
przecinające się krzywe wycinające
GLU NURBS ERROR30
kod błędu nieużywany
GLU NURBS ERROR31
rozłączne krzywe wycinające
GLU NURBS ERROR32
nieznany błąd węzła
GLU NURBS ERROR33
ujemna wartość licznika wierzchołków
1. NURBS
6
numer błędu
opis błędu
GLU NURBS ERROR34
ujemne przesunięcie bajtów danych
GLU NURBS ERROR35
nieznany typ deskryptora
GLU NURBS ERROR36
referencja do pustego punktu kontrolnego
GLU NURBS ERROR37
podwojenie punktu w krzywej wycinającej
Tabela 1: Zestawienie kodów błędów obiektów NURBS
1.5. Właściwości NURBS
Modyfikcję właściwości krzywej lub powierzchni NURBS umożliwia funk-
cja gluNurbsProperty:
void gluNurbsProperty (GLUnurbs *nurb,
GLenum property,
GLfloat value)
Parametr property określa rodzaj modyfikowanej właściwości obiektu
NURBS wskazywanego w parametrze nurb. Nową wartość właściwości za-
wiera oczywiście parametr value. Zestawienie dopuszczalnych wartości wła-
ściwości obiektów NURBS wraz z wartościami domyślnymi przedstawiono
w tabeli 2.
1.5.1. Właściwość GLU NURBS MODE
Właściwość GLU NURBS MODE określa tryb renderingu obiektu NURBS.
Możliwe są dwa tryby renderingu:
— GLU NURBS TESSELLATOR - tryb kafelkowania, w którym obiekt NURBS
jest dzielony (kafelkowany) na sekwencję prymitywów, ale współrzędne
wierzchołków, wektorów normalnych i tekstur oraz składowe kolorów do-
stępne są wyłącznie za pośrednictwem funkcji zwrotnych,
— GLU NURBS RENDERER - tryb renderowania krzywej lub powierzchni (war-
tość domyślna).
Stałe GLU NURBS MODE, GLU NURBS TESSELLATOR i GLU NURBS RENDERER
zostały wprowadzone w wersji 1.3 biblioteki GLU, a wcześniej w rozszerzeniu
EXT nurbs tessellator.
1.5.2. Właściwość GLU CULLING
Przyjmująca wartości logiczne właściwość GLU CULLING decyduje czy krzy-
wa lub powierzchnia NURBS ma być renderowana, gdy jej punkty kontrolne
znajdują się poza obszarem renderingu. Domyślnie jest to wyłączone - war-
tość GL FALSE.
1. NURBS
7
par
am
etr
dop
usz
czalne
w
artośc
i
w
artość
p
o
c
zątk
o
w
a
GLU
NURB
S
MO
DE
GLU
NURBS
RENDE
RER,
GLU
NURBS
RENDE
RER
GLU
NURBS
TES
SE
LLA
TOR
GLU
CULLING
GL
TR
UE
,
GL
F
ALS
E
GL
F
ALS
E
GLU
SAM
PLING
ME
TH
O
D
GLU
P
A
TH
LENG
T
H,
GLU
P
ARAMETRIC
ERR
OR,
GLU
DOM
AIN
DIST
ANC
E
,
GLU
P
A
TH
LENG
T
H
GLU
OBJECT
P
ARAMETRIC
ERR
OR,
GLU
OBJECT
P
A
TH
LENG
T
H
GLU
SAM
PLING
TOLERANCE
w
artość
do
d
atni
a
50
GLU
P
ARAMETRIC
TOLERANCE
w
artość
do
d
atni
a
0,5
GLU
U
STE
P
w
artość
do
d
atni
a
100
GLU
V
STE
P
w
artość
do
d
atni
a
100
GLU
A
UTO
LO
AD
MA
T
RIX
GL
TR
UE
,
GL
F
ALS
E
GL
TR
UE
GLU
DISP
LA
Y
MO
DE
GLU
FILL,
GLU
OUTLINE
PO
L
YGON,
GLU
FILL
GLU
OUTLINE
P
A
TCH
T
ab
e
la
2:
Zes
ta
wie
n
ie
właśc
iw
oś
ci
obi
e
któ
w
NUR
BS
1. NURBS
8
1.5.3. Właściwość GLU SAMPLING METHOD
Właściwość GLU SAMPLING METHOD określa metodę podziału powierzchni
NURBS na wielokąty. Dopuszczalnych jest pięć metod:
— GLU PATH LENGTH - długość boków, w pikselach, wielokątów składających
się na renderowaną powierzchnię nie może przekraczać wartości określo-
nej we właściwości GLU SAMPLING TOLERANCE; jest to wartość domyślna,
— GLU PARAMETRIC ERROR - powierzchnia jest dzielona z użyciem właści-
wości GLU PARAMETRIC TOLERANCE, określającej maksymalną odległość,
w pikselach, pomiędzy wielokątami podziału a całą powierzchnią,
— GLU DOMAIN DISTANCE - ilość punktów próbkowania dla jednostki długo-
ści dla parametrów u i v określają stałe GLU U STEP i GLU V STEP,
— GLU OBJECT PARAMETRIC ERROR - powierzchnia jest dzielona z użyciem
właściwości GLU PARAMETRIC TOLERANCE, określającej maksymalną od-
ległość, w przestrzeni obiektu, pomiędzy wielokątami podziału a całą
powierzchnią,
— GLU OBJECT PATH LENGTH - długość boków, w przestrzeni obiektu, wielo-
kątów składających się na renderowaną powierzchnię nie może przekra-
czać wartości określonej we właściwości GLU SAMPLING TOLERANCE.
Metody GLU OBJECT PARAMETRIC ERROR i GLU OBJECT PATH LENGTH zo-
stały wprowadzone w wersji 1.3 biblioteki GLU w oparciu o rozszerzenie
EXT object space tess.
1.5.4. Właściwość GLU SAMPLING TOLERANCE
Właściwość GLU SAMPLING TOLERANCE ustala maksymalną długość, w pik-
selach lub w przestrzeni obiektu, boków wielokątów składających się na ren-
derowaną powierzchnię. Właściwość ta jest używana, gdy metodą podziału
powierzchni NURBS jest GLU PATH LENGTH lub GLU OBJECT PATH LENGTH.
1.5.5. Właściwość GLU PARAMETRIC TOLERANCE
Właściwość GLU PARAMETRIC TOLERANCE jest używana, gdy metodą po-
działu powierzchni NURBS jest GLU PARAMETRIC ERROR lub GLU OBJECT -
PARAMETRIC ERROR i określa maksymalną odległość, w pikselach lub w prze-
strzeni obiektu, pomiędzy wielokątami podziału a całą renderowaną po-
wierzchnią.
1.5.6. Właściwości GLU U STEP i GLU V STEP
Właściwości GLU U STEP i GLU V STEP określają ilość punktów próbko-
wania na jednostkę długości odpowiednio dla parametru u i v funkcji pa-
rametrycznej. Wartości te używane są, gdy metodą podziału powierzchni
NURBS na wielokąty jest GLU DOMAIN DISTANCE.
1. NURBS
9
1.5.7. Właściwość GLU AUTO LOAD MATRIX
Właściwość GLU AUTO LOAD MATRIX przyjmuje wartości logiczne określa-
jące, czy macierz próbkowania używana przy podziale obiektów NURBS oraz
macierz obcinania służąca do usuwania niewidocznych elementów NURBS
mają być automatycznie obliczane przez bibliotekę GLU (GL FALSE), czy
też potrzebne do jej obliczenia elementy, tj. macierz modelowania, macierz
rzutowania oraz obszar renderingu zostaną wskazane przez użytkownika
(GL TRUE).
Wartości potrzebne do obliczenia macierzy próbkowania i obcinania prze-
kazuje funkcja:
void gluLoadSamplingMatrices (GLUnurbs *nurb,
const GLfloat *model,
const GLfloat *perspective,
const GLint *view)
gdzie model to wskaźnik na macierz modelowania, perspective wskaźnik na
macierz rzutowania, a view jest wskaźnikiem do danych obszaru renderingu.
1.5.8. Właściwość GLU DISPLAY MODE
Właściwość GLU DISPLAY MODE reguluje sposób renderowania powierzch-
ni NURBS. Możliwe są trzy sposobu renderingu określane stałymi:
— GLU FILL - rysowane są wypełnione wielokąty,
— GLU OUTLINE POLYGON - rysowane są krawędzie brzegowe (kontury) wie-
lokątów składających się na powierzchnię,
— GLU OUTLINE PATCH - rysowane są krzywe wycinania zdefiniowane przez
użytkownika (domyślnie będzie to krzywa obejmująca brzeg całej po-
wierzchni).
1.6. Pobieranie właściwości NURBS
Pobieranie właściwości obiektu NURBS umożliwia funkcja gluGetNurbs-
Property:
void gluGetNurbsProperty (GLUnurbs *nurb,
GLenum property,
GLfloat *data)
której parametr property określa jakiego rodzaju właściwość krzywej lub
powierzchni NURBS ma zostać zwrócona. Zakres wartości tego parametru
jest taki sam jak dopuszczalne wartości analogicznego parametru funkcji
gluNurbsProperty.
1. NURBS
10
1.7. Wycinanie fragmentów powierzchni
Do wycinania fragmentów powierzchni NURBS można użyć krzywej
NURBS definiowanej przy użyciu funkcji gluNurbsCurve lub funkcji gluPwl-
Curve określającej krzywą PWL (ang. piecewise linear), czyli krzywej od-
cinkami liniowej:
void gluPwlCurve (GLUnurbs *nurb,
GLint count,
GLfloat *data,
GLint stride,
GLenum type)
Parametr count określa ilość punktów krzywej PWL, których współ-
rzędne zawiera tablica data. Odstęp pomiędzy danymi kolejnych punktów
krzywej określa parametr stride.
Ostatni parametr type określa rodzaj współrzędnych krzywej PWL. Moż-
liwe są dwie wartości:
— GLU MAP1 TRIM 2 - współrzędne odcinków krzywej zdefiniowane w dwu-
wymiarowej przestrzeni parametrycznej (s, t),
— GLU MAP1 TRIM 3 - współrzędne odcinków krzywej zdefiniowane w dwu-
wymiarowej przestrzeni parametrycznej (s, t, q), gdzie parametr q jest
współczynnikiem skalowania.
Krzywe wycinające można łączyć, przy czym musi zachodzić warunek
współdzielenia punktów końcowych a cały zdefiniowany obszar wycinania
jest zamknięty (pierwszy punkt krzywej musi być równy ostatniemu punk-
towi). Krzywa wycinająca nie może mieć wewnętrznych przecięć. Krzywa
lub krzywe określone zgodnie z ruchem wskazówek zegara powodują wycię-
cie dziury w powierzchni. Natomiast krzywa określona przeciwnie do ruchów
wskazówek zegara powoduje usunięcie zewnętrznego obszaru. Zazwyczaj naj-
pierw definiuje się krzywą określającą wycięcie zewnętrzne (w szczególności
może to być cała powierzchnia NURBS), a następnie określa krzywe wyci-
nające dziury w powierzchni.
Funkcje gluNurbsCurve i gluPwlCurve lub ich sekwencje muszą zostać
wywołane pomiędzy funkcjami gluBeginTrim i gluEndTrim:
void gluBeginTrim (GLUnurbs *nurb)
void gluEndTrim (GLUnurbs *nurb)
przy czym każda grupa funkcji gluNurbsCurve i gluPwlCurve określają-
ca odrębny fragment wycinanej powierzchni NURBS musi być umieszczona
w odrębnym wywołaniu pary funkcji gluBeginTrim i gluEndTrim.
1. NURBS
11
1.8. Programy przykładowe
Pierwszy program przykładowy (plik krzywa nurbs.cpp) przedstawia
krzywą NURBS opartą o pięć punktów kontrolnych i dziesięć węzłów. Po-
dobnie jak w programie przykładowym z poprzedniego odcinka kursu rysu-
jący krzywą B´
eziera, tutaj także użytkownik może zmieniać położenie punk-
tów kontrolnych. Dodatkowo możliwa jest modyfikacja wartości parametru
GLU SAMPLING TOLERANCE, który ma bezpośredni wpływ na wygląd rendero-
wanej krzywej (wartość parametru jest wyświetlana na dole okna programu).
Przy wartości 10 krzywa jest optycznie gładka (patrz rysunek 1), natomiast
przy większych wartościach tego parametru krzywa przechodzi w łamaną -
patrz rysunek 2, gdzie wartość GLU SAMPLING TOLERANCE wynosi 150.
Rysunek 1. Program Krzywa NURBS - wartość GLU SAMPLING TOLERANCE
równa 10
1. NURBS
12
Rysunek 2. Program Krzywa NURBS - wartość GLU SAMPLING TOLERANCE
równa 150
1.8.1. Plik krzywa nurbs.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 d i o . h>
#i n c l u d e < s t r i n g . 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
{
EXIT
//
w y j ś c i e
} ;
//
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. NURBS
13
//
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 ;
//
p u n k t y
k o n t r o l n e
k r z y w e j
G L f l o a t
p o i n t s
[ 5 ∗ 3 ] =
{
5 0 . 0 , 5 0 . 0 , 0 . 0 ,
2 5 0 . 0 , 2 5 0 . 0 , 0 . 0 ,
5 0 . 0 , 4 5 0 . 0 , 0 . 0 ,
4 5 0 . 0 , 5 0 . 0 , 0 . 0 ,
4 5 0 . 0 , 4 5 0 . 0 , 0 . 0
} ;
//
w ę z ł y
G L f l o a t
k n o t s
[ 5 ∗ 2 ] =
{
0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0
} ;
//
w a r t o ś ć
w ł a ś c i w o ś c i GLU SAMPLING TOLERANCE
G L f l o a t
s a m p l i n g t o l e r a n c e = 2 0 . 0 ;
//
i d e n t y f i k a t o r y
w y ś w i e t l a n y c h
o b i e k t ó w
enum
{
NONE,
CURVE,
POINT 0 ,
POINT 1 ,
POINT 2 ,
POINT 3 ,
POINT 4
} ;
//
i d e n t y f i k a t o r
w y b r a n e g o
o b i e k t u
i n t
s e l e c t o b j e c t = NONE;
//
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
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
i n i c j a l i z a c j a
s t o s u
nazw
o b i e k t ó w
g l I n i t N a m e s
( ) ;
//
u m i e s z c z e n i e
n a z w y
na
s t o s i e
nazw ,
a b y
n i e
b y ł
on
p u s t y
glPushName
(NONE ) ;
//
o b i e k t CURVE
glLoadName
(CURVE ) ;
//
u s t a w i e n i e
g r u b o ś c i
l i n i i
g l L i n e W i d t h
( 2 . 0 ) ;
//
k o l o r
k r z y w e j
g l C o l o r 3 f v
( B l a c k ) ;
//
u t w o r z e n i e
o b i e k t u NURBS
GLUnurbsObj ∗ n u r b s = g l u N e w N u r b s R e n d e r e r
( ) ;
1. NURBS
14
//
p o c z ą t e k
d e f i n i c j i
k r z y w e j NURBS
g l u B e g i n C u r v e
( n u r b s ) ;
//
u s t a w i e n i e
w ł a ś c i w o ś c i GLU SAMPLING TOLERANCE
g l u N u r b s P r o p e r t y
( n u r b s , GLU SAMPLING TOLERANCE, s a m p l i n g t o l e r a n c e ) ;
//
e w a l u a c j a
k r z y w e j
g l u N u r b s C u r v e
( n u r b s , 1 0 , k n o t s , 3 , p o i n t s , 5 , GL MAP1 VERTEX 3 ) ;
//
k o n i e c
d e f i n i c j i
k r z y w e j
gluEndCurve
( n u r b s ) ;
//
u s u n i ę c i e
o b i e k t u NURBS
g l u D e l e t e N u r b s R e n d e r e r
( n u r b s ) ;
//
k o l o r
p u n k t ó w
g l C o l o r 3 f v
( Red ) ;
//
n a r y s o w a n i e
p u n k t ó w
k o n t r o l n y c h
f o r
( i n t
i = 0 ;
i < 5 ;
i ++)
{
//
n a zw a
o b i e k t u
glLoadName
( POINT 0+ i ) ;
//
p u n k t
k o n t r o l n y
g l R e c t f
( p o i n t s
[ i ∗ 3 ] − 5 , p o i n t s
[ i ∗3+1] −5 , p o i n t s
[ i ∗ 3 ] + 5 , p o i n t s
[ i ∗ 3 + 1 ] + 5 ) ;
}
//
w y ś w i e t l e n i e
w a r t o ś c i
w ł a ś c i w o ś c i GLU SAMPLING TOLERANCE
char
s t r i n g
[ 1 0 0 ] ;
g l C o l o r 3 f v
( B l a c k ) ;
s p r i n t f
( s t r i n g , ”GLU SAMPLING TOLERANCE = %f ” , s a m p l i n g t o l e r a n c 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
( 2 , 2 , 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
( ) ;
//
r z u t o w a n i e
p r o s t o k ą t n e
g l u O r t h o 2 D
( 0 , width , 0 , h e i g h t ) ;
//
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
s e l e k c j i
o b i e t k ó w
void
S e l e c t i o n
( i n t x ,
i n t
y )
{
//
w i e l k o ś ć
b u f o r a
s e l e k c j i
const
i n t BUFFER LENGTH = 6 4 ;
//
b u f o r
s e l e k c j i
GLuint
s e l e c t b u f f e r
[ BUFFER LENGTH ] ;
//
p r z y g o t o w a n i e
b u f o r a
s e l e k c j i
g l S e l e c t B u f f e r
(BUFFER LENGTH, s e l e c t b u f f e r ) ;
//
p o b r a n i e
o b s z a r u
r o z m i a r u
r e n d e r i n g u
i n t
v i e w p o r t [ 4 ] ;
g l G e t I n t e g e r v
(GL VIEWPORT, v i e w p o r t ) ;
1. NURBS
15
//
s z e r o k o ś ć
i
w y s o k o ś ć
o b s z a r u
r e n d e r i n g u
i n t
w i d t h = v i e w p o r t
[ 2 ] ;
i n t
h e i g h t = v i e w p o r t
[ 3 ] ;
//
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 ) ;
//
o d ł o ż e n i e
m a c i e r z y
r z u t o w a n i a
na
s t o s
g l P u s h M a t r i x
( ) ;
//
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 − j e d n o s t k o w a
k o s t k a
d o o k o ł a
p u n k t u
w s k a ź n i k a
//
m y s z y
( x , y )
r o z c i ą g a j ą c e j
s i ę
na dwa
p i k s e l e
w p o z i o m i e
i
w
p i o n i e
g l u P i c k M a t r i x
( x , h e i g h t −y , 2 , 2 , v i e w p o r t ) ;
//
r z u t o w a n i e
p r o s t o k ą t n e
g l u O r t h o 2 D
( 0 , width , 0 , h e i g h t ) ;
//
w ł ą c z e n i e
t r y b u
s e l e k c j i
glRenderMode
( GL SELECT ) ;
//
g e n e r o w a n i e
s c e n y
3D
D i s p l a y
( ) ;
//
z l i c z e n i e
i l o ś c i
r e k o r d ó w
t r a f i e ń ,
p o w r ó t
do
d o m y ś l n e g o
t r y b u
r e n d e r i n g u
GLint
h i t s = glRenderMode
(GL RENDER ) ;
//
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 ) ;
//
z d j ę c i e
m a c i e r z y
r z u t o w a n i a
z e
s t o s u
g l P o p M a t r i x
( ) ;
//
d o m y ś l n i e w w y n i k u
s e l e k c j i
n i e
w y b r a n o
ż a d n e g o
p u n k t u
k o n t r o l n e g o
s e l e c t o b j e c t = NONE;
// w w y n i k u
s e l e k c j i
w y b r a n o
c o
n a j m n i e j
j e d e n
o b i e k t
//
d l a
u p r o s z c z e n i a
s p r a w d z a m y
t y l k o
p i e r w s z y
o b i e k t
na
s t o s i e
i f
( h i t s > 0 )
i f
( s e l e c t b u f f e r
[ 3 ] > CURVE)
s e l e c t o b j e c t = s e l e c t b u f f e r
[ 3 ] ;
}
//
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)
{
//
o b s ł u g a
s e l e k c j i
o b i e k t ó w
S e l e c t i o n
( x , y ) ;
g l u t P o s t R e d i s p l a y
( ) ;
//
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 )
{
//
s p r a w d z e n i e
c z y
w s k a ź n i k
m y s z y
n i e
z n a j d u j e
s i ę
p o z a
o b s z a r e m
o k n a
i f
( x > 0 & x < g l u t G e t
(GLUT WINDOW WIDTH) & y > 0 & y < g l u t G e t
(GLUT WINDOW HEIGHT) )
i f
( b u t t o n s t a t e == GLUT DOWN)
{
//
z m i a n a
w s p ó ł r z ę d n y c h
p u n k t ó w
switch
( s e l e c t o b j e c t )
{
c a s e POINT 0 :
1. NURBS
16
p o i n t s
[ 0 ] += x − b u t t o n x ;
p o i n t s
[ 1 ] += b u t t o n y − y ;
break ;
c a s e POINT 1 :
p o i n t s
[ 3 ] += x − b u t t o n x ;
p o i n t s
[ 4 ] += b u t t o n y − y ;
break ;
c a s e POINT 2 :
p o i n t s
[ 6 ] += x − b u t t o n x ;
p o i n t s
[ 7 ] += b u t t o n y − y ;
break ;
c a s e POINT 3 :
p o i n t s
[ 9 ] += x − b u t t o n x ;
p o i n t s
[ 1 0 ] += b u t t o n y − y ;
break ;
c a s e POINT 4 :
p o i n t s
[ 1 2 ] += x − b u t t o n x ;
p o i n t s
[ 1 3 ] += b u t t o n y − y ;
break ;
}
//
a k t u a l i z a c j a
p o ł o ż e n i a
m y s z k i
b u t t o n x = x ;
b u t t o n y = y ;
//
w y ś w i e t l e n i e
s c e n 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 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
”+” −
c a s e
’+ ’ :
s a m p l i n g t o l e r a n c e += 1 0 . 0 ;
break ;
//
k l a w i s z
”−” −
c a s e
’− ’ :
i f
( s a m p l i n g t o l e r a n c e > 1 0 . 0 )
s a m p l i n g t o l e r a n c e −= 1 0 . 0 ;
break ;
}
//
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
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 )
{
//
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 ) ;
//
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
( ” Krzywa NURBS” ) ;
//
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. NURBS
17
//
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 ) ;
//
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 ) ;
// 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
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 program przykładowy (plik powierzchnia nurbs.cpp) wyświe-
tla przykładową powierzchnię NURBS, która opcjonalnie może mieć wy-
ciętą dziurę. Ponadto powierzchnię można renderować z różnymi metoda-
mi podziału na wielokąty, przy czym program wykrywa wersję biblioteki
GLU i gdy jest to wersja 1.3, zawartość menu jest uzupełniana o opcje
GLU OBJECT PARAMETRIC ERROR i GLU OBJECT PATH LENGTH.
Porównajmy zatem jak wygląda przykładowa powierzchnia NURBS ry-
sowana trzema metodami podziału na wielokąty dostępnymi w wersji 1.2 bi-
blioteki GLU, przy czym należy pamiętać, że program nie zmienia właściwo-
ści wpływających na sposób tego podziału. Właściwości: GLU SAMPLING TO-
LERANCE, GLU PARAMETRIC TOLERANCE, GLU U STEP i GLU V STEP przyjmują
wartości domyślne. Dla czytelności efektów podziału rysunki 3 - 8 przedsta-
wiają powierzchnię NURBS renderowaną w postaci siatki krawędzi wieloką-
tów.
Przy powiększeniu (rysunki 3 - 5) wszystkie powierzchnie wyglądają
podobnie, choć wyraźnie widać, że metoda podziału GLU DOMAIN DISTANCE
przy parametrach domyślnych wygenerowała większą ilość wielokątów. Więk-
sze różnice widać dopiero przy znacznym zmniejszeniu renderowanej po-
wierzchni (rysunki 6 - 8). Ponownie wyróżnia się metoda podziału GLU DO-
MAIN DISTANCE, która przypomnijmy ma stałą liczbę punktów podziału i przy
domyślnych wartościach parametrów GLU U STEP i GLU V STEP, nie nadaje
się najlepiej do renderingu małej powierzchni.
Program umożliwia także rendering wypełnionej powierzchni z możli-
wością wyboru rodzaju materiału. Przykładowy wygląd takiej powierzch-
1. NURBS
18
ni przedstawia rysunek 9. Ta sama powierzchnia ale już z wyciętą dziu-
rą została przedstawiona na rysunku 10. Ostatni rysunek - 11 - przedsta-
wia efekt rysowania powierzchni NURBS z dziurą, gdy rysowane są zdefi-
niowane w programie krzywe wycinania (sposób renderowania powierzchni
GLU OUTLINE PATCH).
Rysunek 3. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU PATH LENGTH
1.8.2. Plik powierzchnia nurbs.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 <GL/ g l e x t . h>
#i f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
1. NURBS
19
Rysunek 4. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU PARAMETRIC ERROR
#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 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
{
HOLE,
//
d z i u r a
//
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 ź
1. NURBS
20
Rysunek 5. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU DOMAIN DISTANCE
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. NURBS
21
Rysunek 6. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU PATH LENGTH (obiekt pomniejszony)
#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
1. NURBS
22
Rysunek 7. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU PARAMETRIC ERROR (obiekt pomniejszony)
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 ;
//
m e t o d a
p o d z i a ł u
p o w i e r z c h n i NURBS na
w i e l o k ą t y
i n t
s a m p l i n g m e t h o d = GLU PATH LENGTH ;
//
s p o s ó b
r e n d e r o w a n i a
p o w i e r z c h n i NURBS
i n t
d i s p l a y m o d e = GLU FILL ;
1. NURBS
23
Rysunek 8. Program Powierzchnia NURBS - metoda podziału na wielokąty
GLU DOMAIN DISTANCE (obiekt pomniejszony)
//
w s p ó ł r z ę d n e
p u n k t ó w
k o n t r o l n y c h
p o w i e r z c h n i
G L f l o a t
p o i n t s
[ 4 ∗ 4 ∗ 3 ] =
{
− 1 . 0 , − 1 . 0 , 0 . 0 ,
− 1 . 0 , − 0 . 5 , 0 . 0 ,
− 1 . 0 , 0 . 5 , 0 . 0 ,
− 1 . 0 , 1 . 0 , 0 . 0 ,
− 0 . 5 , − 1 . 0 , 0 . 0 ,
− 0 . 5 , − 0 . 5 , 1 . 5 ,
− 0 . 5 , 0 . 5 , 1 . 5 ,
− 0 . 5 , 1 . 0 , 0 . 0 ,
0 . 5 , − 1 . 0 , 0 . 0 ,
0 . 5 , − 0 . 5 , 1 . 5 ,
0 . 5 , 0 . 5 , 1 . 5 ,
0 . 5 , 1 . 0 , 0 . 0 ,
1 . 0 , − 1 . 0 , 0 . 0 ,
1 . 0 , − 0 . 5 , 0 . 0 ,
1 . 0 , 0 . 5 , 0 . 0 ,
1 . 0 , 1 . 0 , 0 . 0
} ;
//
w ę z ł y
G L f l o a t
k n o t s
[ 4 ∗ 2 ] =
{
0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0
} ;
//
w s p ó ł r z ę d n e
z e w n ę t r z n e j
k r z y w e j PWL
G L f l o a t
o u t l i n e p w l
[ 1 0 ] =
{
0 . 0 , 0 . 0 ,
1 . 0 , 0 . 0 ,
1 . 0 , 1 . 0 ,
0 . 0 , 1 . 0 ,
0 . 0 , 0 . 0
} ;
1. NURBS
24
Rysunek 9. Program Powierzchnia NURBS - powierzchnia wypełniona
//
w s p ó ł r z ę d n e
k r z y w e j PWL o p i s u j ą c e j
w y c i n a n y
f r a g m e n t
p o w i e r z c h n i
G L f l o a t
h o l e p w l
[ 1 0 ] =
{
0 . 2 5 , 0 . 2 5 ,
0 . 2 5 , 0 . 7 5 ,
0 . 7 5 , 0 . 7 5 ,
0 . 7 5 , 0 . 2 5 ,
0 . 2 5 , 0 . 2 5
} ;
//
z n a c z n i k
d o s t ę p n o ś c i
b i b l i o t e k i
GLU w
w e r s j i
1 . 3
bool GLU 1 3 = f a l s e ;
//
d e f i n i c j e
m e t o d
p o d z i a ł u
p o w i e r z c h n i NURBS na
//
w i e l o k ą t y
w p r o w a d z o n e w
w e r s j i
1 . 3
b i b l i o t e k i
GLU
#i f n d e f
GLU OBJECT PARAMETRIC ERROR
#d e f i n e GLU OBJECT PARAMETRIC ERROR
1 0 0 2 0 8
#e n d i f
#i f n d e f GLU OBJECT PATH LENGTH
1 0 0 2 0 9
#d e f i n e GLU OBJECT PATH LENGTH
1 0 0 2 0 9
#e n d i f
//
z n a c z n i k
c z y
w y c i n a ć
f r a g m e n t
p o w i e r z c h n i NURBS
bool
h o l e = f a l s e ;
1. NURBS
25
Rysunek 10. Program Powierzchnia NURBS - powierzchnia wypełniona z
dziurą
//
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 ) ;
1. NURBS
26
Rysunek 11. Program Powierzchnia NURBS - powierzchnia z zaznaczonymi
krzywymi wycinania
//
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 ) ;
//
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 ł ą c z e n i e
e f e k t ó w
o ś w i e t l e n i a ,
g r y
r e n d e r o w a n a
j e s t
w y p e ł n i o n a
p o w i e r z c h n i a
i f
( d i s p l a y m o d e == GLU FILL )
{
//
w ł ą c z e n i e
o ś w i e t l e n i a
1. NURBS
27
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 ) ;
//
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 ) ;
//
w ł ą c z e n i e
a u t o m a t y c z n e g o
g e n e r o w a n i a
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 AUTO NORMAL ) ;
}
//
k o l o r
k r a w ę d z i
g l C o l o r 3 f v
( B l a c k ) ;
//
u t w o r z e n i e
o b i e k t u NURBS
GLUnurbsObj ∗ n u r b s = g l u N e w N u r b s R e n d e r e r
( ) ;
//
p o c z ą t e k
d e f i n i c j i
p o w i e r z c h n i NURBS
g l u B e g i n S u r f a c e
( n u r b s ) ;
//
s p o s ó b
r e n d e r o w a n i a
p o w i e r z c h n i NURBS
g l u N u r b s P r o p e r t y
( n u r b s , GLU DISPLAY MODE , d i s p l a y m o d e ) ;
//
m e t o d a
p o d z i a ł u
p o w i e r z c h n i NURBS na
w i e l o k ą t y
g l u N u r b s P r o p e r t y
( n u r b s , GLU SAMPLING METHOD, s a m p l i n g m e t h o d ) ;
//
n a r y s o w a n i e
p o w i e r z c h n i
g l u N u r b s S u r f a c e
( n u r b s , 8 , k n o t s , 8 , k n o t s , 4 ∗ 3 , 3 , p o i n t s , 4 , 4 , GL MAP2 VERTEX 3 ) ;
//
r y s o w a n i e
d z i u r y w p o w i e r z c h n i NURBS
i f
( h o l e )
{
//
z e w n ę t r z n a
k r z y w a
w y c i n a j ą c a
g l u B e g i n T r i m
( n u r b s ) ;
g l u P w l C u r v e ( n u r b s , 5 , o u t l i n e p w l , 2 , GLU MAP1 TRIM 2 ) ;
gluEndTrim
( n u r b s ) ;
//
w e w n ę t r z n a
k r z y w a
w y c i n a j ą c a
g l u B e g i n T r i m
( n u r b s ) ;
g l u P w l C u r v e ( n u r b s , 5 , h o l e p w l , 2 , GLU MAP1 TRIM 2 ) ;
gluEndTrim
( n u r b s ) ;
}
//
k o n i e c
d e f i n i c j i
p o w i e r z c h n i
g l u E n d S u r f a c e
( n u r b s ) ;
//
u s u n i ę c i e
o b i e k t u NURBS
g l u D e l e t e N u r b s R e n d e r e r
( n u r b s ) ;
//
w y ł ą c z e n i e
a u t o m a t y c z n e g o
g e n e r o w a n i a
w e k t o r ó w
n o r m a l n y c h
g l D i s a b l e
(GL AUTO NORMAL ) ;
//
w y ł ą 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 D i s a b l e
(GL NORMALIZE ) ;
//
w y ł ą c z e n i e
ś w i a t ł a
GL LIGHT0
g l D i s a b l e
( GL LIGHT0 ) ;
//
w y ł a 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 ) ;
//
k o l o r
p u n k t ó w
g l C o l o r 3 f v
( B l u e ) ;
//
r o z x m i a r
p u n k t ó w
g l P o i n t S i z e
( 6 . 0 ) ;
//
n a r y s o w a n i e
p u n k t ó w
k o n t r o l n y c h
g l B e g i n
( GL POINTS ) ;
f o r
( i n t
i = 0 ;
i < 1 2 ;
i ++)
g l V e r t e x 3 f v
( p o i n t s + i ∗ 3 ) ;
g l E n d
( ) ;
1. NURBS
28
//
w y ś w i e t l e n i e
i n f o r m a c j i
o
w y b r a n y c h
w ł a ś c i w o ś c i a c h
p o w i e r z c h n i NURBS
g l C o l o r 3 f v
( B l a c k ) ;
//
m e t o d a
p o d z i a ł u
p o w i e r z c h n i NURBS na
w i e l o k ą t y
i f
( s a m p l i n g m e t h o d == GLU PATH LENGTH)
D r a w S t r i n g
( 2 , 2 , ”GLU SAMPLING METHOD = GLU PATH LENGTH” ) ;
e l s e
i f
( s a m p l i n g m e t h o d == GLU PARAMETRIC ERROR)
D r a w S t r i n g
( 2 , 2 , ”GLU SAMPLING METHOD = GLU PARAMETRIC ERROR” ) ;
e l s e
i f
( s a m p l i n g m e t h o d == GLU DOMAIN DISTANCE)
D r a w S t r i n g
( 2 , 2 , ”GLU SAMPLING METHOD = GLU DOMAIN DISTANCE” ) ;
//
m e t o d y
p o d z i a ł u
w p r o w a d z o n e w
w e r s j i
1 . 3
b i b l i o t e k i
GLU
i f
( GLU 1 3 )
{
i f
( s a m p l i n g m e t h o d == GLU OBJECT PARAMETRIC ERROR)
D r a w S t r i n g
( 2 , 2 , ”GLU SAMPLING METHOD = GLU OBJECT PARAMETRIC ERROR” ) ;
e l s e
i f
( s a m p l i n g m e t h o d == GLU OBJECT PATH LENGTH)
D r a w S t r i n g
( 2 , 2 , ”GLU SAMPLING METHOD = GLU OBJECT PATH LENGTH” ) ;
}
//
s p o s ó b
r e n d e r o w a n i a
p o w i e r z c h n i NURBS
i f
( d i s p l a y m o d e == GLU FILL )
D r a w S t r i n g
( 2 , 1 6 , ”GLU DISPLAY MODE = GLU FILL” ) ;
e l s e
i f
( d i s p l a y m o d e == GLU OUTLINE PATCH)
D r a w S t r i n g
( 2 , 1 6 , ”GLU DISPLAY MODE = GLU OUTLINE PATCH” ) ;
e l s e
i f
( d i s p l a y m o d e == GLU OUTLINE POLYGON)
D r a w S t r i n g
( 2 , 1 6 , ”GLU DISPLAY MODE = GLU OUTLINE POLYGON” ) ;
//
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 )
{
//
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. NURBS
29
//
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 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
( ) ;
}
}
//
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 )
{
// GLU DISPLAY MODE
c a s e GLU FILL :
c a s e GLU OUTLINE PATCH :
c a s e GLU OUTLINE POLYGON :
d i s p l a y m o d e = v a l u e ;
D i s p l a y S c e n e
( ) ;
break ;
// GLU SAMPLING METHOD
c a s e GLU PATH LENGTH :
c a s e GLU PARAMETRIC ERROR :
c a s e GLU DOMAIN DISTANCE :
c a s e GLU OBJECT PARAMETRIC ERROR :
c a s e GLU OBJECT PATH LENGTH :
s a m p l i n g m e t h o d = v a l u e ;
D i s p l a y S c e n e
( ) ;
break ;
//
d z i u r a
w ł ą c z / w y ł ą c z
c a s e HOLE :
h o l e = ! h o l e ;
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 ;
1. NURBS
30
//
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 ;
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 ;
1. NURBS
31
//
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 ;
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
( ) ;
1. NURBS
32
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 ” ) ;
e x i t
( 0 ) ;
}
}
//
s p r a w d z e n i e
numeru
w e r s j i
b i b l i o t e k i
GLU
void GLUSetup
( )
{
//
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
GLU
const char ∗ v e r s i o n = ( char ∗ ) g l u G e t S t r i n g
(GLU VERSION ) ;
//
s p r a w d z e n i e
numeru
w e r s j i
b i b l i o t e k i
GLU
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 GLU\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 GLU\n ” ) ;
#e n d i f
1. NURBS
33
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 . 3
b i b l i o t e k i
GLU
i f
( m a j o r > 1
| |
m i n o r >= 3 )
GLU 1 3 = 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
( ” P o w i e r z c h n i a NURBS” ) ;
//
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 ) ;
//
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 ) ;
//
s p r a w d z e n i e
numeru
w e r s j i
b i b l i o t e k i
GLU
GLUSetup
( ) ;
//
u t w o r z e n i e
podmenu − GLU DISPLAY MODE
i n t
MenuDisplayMode = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ”GLU FILL” , GLU FILL ) ;
glutAddMenuEntry
( ”GLU OUTLINE PATCH” ,GLU OUTLINE PATCH ) ;
glutAddMenuEntry
( ”GLU OUTLINE POLYGON” ,GLU OUTLINE POLYGON ) ;
//
u t w o r z e n i e
podmenu − GLU SAMPLING METHOD
i n t
MenuSamplingMethod = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ”GLU PATH LENGTH” ,GLU PATH LENGTH ) ;
glutAddMenuEntry
( ”GLU PARAMETRIC ERROR” ,GLU PARAMETRIC ERROR ) ;
glutAddMenuEntry
( ”GLU DOMAIN DISTANCE” ,GLU DOMAIN DISTANCE ) ;
//
e l e m e n t y
munu
d o s t ę p n e w
w e r s j i
1 . 3
b i b l i o t e k i
GLU
i f
( GLU 1 3 )
{
glutAddMenuEntry
( ”GLU OBJECT PARAMETRIC ERROR” ,GLU OBJECT PARAMETRIC ERROR ) ;
glutAddMenuEntry
( ”GLU OBJECT PATH LENGTH” ,GLU OBJECT PATH LENGTH ) ;
}
//
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 ) ;
1. NURBS
34
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
( ”GLU DISPLAY MODE” , MenuDisplayMode ) ;
glutAddSubMenu
( ”GLU SAMPLING METHOD” , MenuSamplingMethod ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” D z i u r a
w ł ą c z / w y ł ą c z ” ,HOLE ) ;
glutAddSubMenu
( ” M a t e r i a ł ” , M e n u M a t e r i a l ) ;
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , MenuAspect ) ;
glutAddMenuEntry
( ” W y j ś c i e ” , EXIT ) ;
#e l s e
glutAddMenuEntry
( ” D z i u r a
w l a c z / w y l a c z ” ,HOLE ) ;
glutAddSubMenu
( ” M a t e r i a l ” , M e n u M a t e r i a l ) ;
glutAddSubMenu
( ” A s p e k t
o b r a z u ” , MenuAspect ) ;
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 ;
}
Literatura
35
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,