Professional Documents
Culture Documents
O
autorach...............................................................................................................
21
Przedmowa
..............................................................................................................23
Wprowadzenie......................................................................................................
.... 25
Dla kogo jest ta ksika?............................................................................................................26
System wymagany dla OpenGL.................................................................................................26
Jzyk...........................................................................................................................................26
Kompilatory ...............................................................................................................................27
Co znajdziesz w tej ksice........................................................................................................27
Cz I: Wprowadzenie do OpenGL....................................................................................28
Cz II: Uywanie OpenGL ...............................................................................................28
Cz III: Tematy zaawansowane i efekty specjalne............................................................29
Cz IV: OpenGL i... .........................................................................................................30
Dodatki..............................................................................................:..................................31
Pytka CD-ROM doczona do ksiki.......................................................................................31
Do dziea!...................................................................................................................................32
Cz l
Wprowadzenie do OpenGL.................................................................. 33
Rozdzia 1.
Co to jest OpenGL?.................................................................................................. 35
O OpenGL..................................................................................................................................36
Historia OpenGL..................................................................................................................36
Dalszy rozwj OpenGL........................................................................................................37
Jak dziaa OpenGL.....................................................................................................................37
OpenGL w Windows..................................................................................................................38
Architektura graficzna: oprogramowanie kontra sprzt .......................................................38
Ograniczenia oglnej implementacji....................................................................................40
Dalsze perspektywy OpenGL w Windows.................................................................................40
Rozdzia 2.
Podstawy grafiki
3D................................................................................................. 41
Postrzeganie w trzech wymiarach ..............................................................................................41
2D + Perspektywa = 3D.......................................................................................................42
Usuwanie niewidocznych linii .............................................................................................43
Kolory i cieniowanie............................................................................................................43
wiata i cienie.....................................................................................................................44
OpenGL - ksiga eksperta
auxSolidSphere .................................................................................................................... 89
auxSolidTeapot .................................................................................................................... 89
auxSolidTetrahedron.. ..................................................................................................... .....90
auxWireCone ....................................................................................................................... 9 1
auxWireCube ..................................................................................................................... ..92
auxWire!cosahedron ............................................................................................................93
auxWireOctahedron ............................................................................................................. 94
auxWireSphere.....................................................................................................................94
auxWireTeapot.. ................................................................................................................ ...95
auxWireTetrahedron ............................................................................................................95
auxWireTorus. ...................................................................................................................... 95
glYiewport...........................................................................................................................97
glRect...................................................................................................................................98
Rozdzia 4.
OpenGL for Windows: OpenGL + Win32 = Wiggle..................................................... 101
Rysowanie w oknach Windows................................................................................................ 102
Konteksty urzdze GDI....................................................................................................102
Konteksty renderowania OpenGL......................................................................................l 05
Korzystanie z funkcji Wiggle................................................................................................... 106
Tworzenie i wybieranie kontekstu renderowania............................................................... 106
Rysowanie przy uyciu OpenGL........................................................................................ 106
Przygotowanie okna dla OpenGL.............................................................................................l 08
Style okien .........................................................................................................................108
Formaty pikseli ..................................................................................................................108
Powrt odbijajcego si kwadratu............................................................................................ 111
Skalowanie do okna........................................................................................................... 114
Tykniciatimera.................................................................................................................ll4
wiata, kamera, akcja!................................................................................................
15
Podsumowanie. 16 16 16 18 GetPixelFormat
Podrcznik........ ..................................................................................................................
ChoosePixelFormat... 122
DescribePixelFormat. SetPixelFormat.. ......................................................................................
........................... 122
SwapBuffers.... ............................................................................................................... ....123
wglCreateContext...........................................................................................,...................124
wglDeleteContext.. ............................................................................................................. 125
wglGetCurrentContext.. ................................................................................................... ..125
wglGetCurrentDC .............................................................................................................. 126
wglGetProcAddress..... .................................................................................................. .....126
10______________________________________OpenGL - ksiga eksperta
wglMakeCurrent.....................................................................................................
........... 127
wglShareLists..........................................................................................................
........... 128
wglUseFontBitmaps...............................................................................................
............ 129
wglUseFontOutlines.............................................................................................
..............130
Rozdzia 5.
Bdy i inne komunikaty
OpenGL............................................................................. 133
Gdy dobremu programowi przydarzaj si ze przygody
........................................................134
Kim jestem i co potrafi?
.........................................................................................................135
Rozszerzenia
OpenGL........................................................................................................ 136
Udzielanie wskazwek za pomoc funkcji
glHint................................................................... 137
Podsumowanie
.........................................................................................................................138
Podrcznik...................................................................................................................
............. 138
glGetLastError.....................................................................................................
..............138
glGetLastError.......................................................................................................
............ 138
glGetString...........................................................................................................
..............139
glHint......................................................................................................................
........... 140
gluErrorString......................................................................................................
..............141
gluGetString...........................................................................................................
............141
Cz II
Uywanie OpenGL............................................................................ 143
Rozdzia 6.
Rysowanie w trzech wymiarach: linie, punkty i
wielokaty.........................................145
Rysowanie punktw w przestrzeni
trjwymiarowej................................................................ 146
Przygotowanie trjwymiarowej
osnowy............................................................................ 146
Trjwymiarowy punkt: wierzchoek
.................................................................................. 148
Narysujmy co!
..................................................................................................................149
Rysowanie
punktw...........................................................................................................14
9
Ustalanie rozmiaru
punktu................................................................................................. 152
Rysowanie linii w trzech
wymiarach........................................................................................ 155
amane i amane
zamknite............................................................................................... 156
Przyblianie krzywych
odcinkami..................................................................................... 157
Ustalanie gruboci
linii...................................................................................................... 158
Linie
przerywane.............................................................................................................
... 160
Rysowanie trjktw w przestrzeni
3D.................................................................................... 162
Trjkt: twj pierwszy
wielokt......................................................................................... 162
Kierunek.................................................................................................................
............ 163
Paski
trjktw..............................................................................................................
.....164
Wachlarze
trjktw..........................................................................................................
165
Budowanie jednolitych
obiektw............................................................................................. 166
Ustawianie kolorw
wieloktw........................................................................................ 169
Korzystanie z bufora
gbokoci........................................................................................ 169
Ukrywanie niewidocznych
powierzchni............................................................................ 171
Tryby
wieloktw.............................................................................................................
. 173
Inne prymitywy
........................................................................................................................174
Czworokty
........................................................................................................................174
Paski
czworoktw........................................................................................................
.....l75
Oglne
wielokty.............................................................................................................
..l75
Wypenianie
wieloktw....................................................................................................l75
Reguy konstruowania
wieloktw.................................................................................... 179
Podzia
wielokta...............................................................................................................
181
Podsumowanie
.........................................................................................................................183
Spis treci
Rozdzia 8.
Kolory i
cieniowanie...............................................................................................
235
Czym jest kolor?.......................................................................................................................236
wiato jako fala.................................................................................................................236
wiato jako czsteczka......................................................................................................237
Twj osobisty wykrywacz fotonw....................................................................................237
Komputer jako generator fotonw .....................................................................................238
Sprzt grafiki kolorowej...........................................................................................................239
Tryby graficzne w komputerach osobistych............................................................................241
Rozdzielczoci ekranu........................................................................................................241
Gboko koloru...............................................................................................................241
Kolor 4-bitowy...................................................................................................................242
Kolor 8-bitowy................................................................................................................... 242
Kolor 24-bitowy.................................................................................................................242
Inne gbokoci koloru.......................................................................................................242
Wybr koloru...........................................................................................................................243
Kostka kolorw..................................................................................................................243
Ustalanie koloru rysowania................................................................................................245
Cieniowanie .......................................................................................................................246
Ustawianie trybu cieniowania ............................................................................................248
Palety Windows........................................................................................................................249
Dopasowywanie kolorw.............,.....................................................................................249
Dithering............................................................................................................................250
Korzyci ze stosowania palety w trybie 8-bitowym ...........................................................251
Tworzenie palety......................................................................................................................253
Czy potrzebujesz palety?....................................................................................................254
Struktura palety..................................................................................................................254
Paleta 3-3-2........................................................................................................................255
Tworzenie i usuwanie palety..............................................................................................258
Pewne ograniczenia..................:.........................................................................................259
Tryb indeksu koloru .................................................................................................................259
Kiedy uywa trybu indeksu koloru?.................................................................................259
Uycie trybu indeksu koloru ..............................................................................................260
Podsumowanie .........................................................................................................................262
Podrcznik................................................................................................................................ 263
glClearIndex.......................................................................................................................263
glColor...............................................................................................................................263
glColorMask......................................................................................................................265
gllndex...............................................................................................................................265
gl!ndexMask.......................................................................................................................266
glLogicOp..........................................................................................................................267
glShadeModel....................................................................................................................268
Rozdzia 9.
Owietlenie i rda
wiata.................................................................................... 271
wiato w rzeczywistym wiecie..............................................................................................272
wiato otaczajce..............................................................................................................273
wiato rozproszone...........................................................................................................273
wiato odbyskw.............................................................................................................273
Zmy to razem ................................................................................................................274
Materiay w rzeczywistym wiecie...........................................................................................275
Waciwoci materiau .......................................................................................................275
Owietlanie materiaw......................................................................................................275
Spis treci
glLightModel ..................................................................................................................... 3 15
glMaterial.................................................................................................................... ....... 3 17
glNormal ............................................................................................................................ 3 18
Rozdzia 10.
Modelowanie i kompozycja obiektw 3D
................................................................. 321
Okrelenie zadania ................................................................................................................... 32 1
Wybr rzutowania.............................................................................................................. 322
Wybr owietlenia i waciwoci materiau .......................................................................323
Wywietlanie rezultatu....................................................................................................... 324
Konstruowanie modelu po kawaku .........................................................................................325
Gwka............................................................................................................................... 325
Trzpie................................................................................................... ............................ 328
Gwint ................................................................................................................................. 332
Skadanie modelu w cao ................................................................................................335
Test szybkoci.......................................................................................................................... 336
14 _____________________________________ OpenGL - ksiga eksperta
gluQuadricTexture .............................................................................................................456
gluSphere ...................................................................................................................... .....456
Cz III
Tematy zaawansowane i efekty specjalne......................................... 459
Rozdzia 14.
Maszyna stanu OpenGL
.......................................................................................... 461
Podstawowe zmienne stanu OpenGL....................................................................................... 46 1
Zachowywanie i odtwarzanie zmiennych stanu .......................................................................462
Stan rysowania.. ................................................................................................................. 464
Stan bufora gbokoci. ...................................................................................................... 465
Stan bufora szablonu.......................................................................................................... 465
Stan owietlenia ............................................................................................................ .....465
Stan teksturowania............. .............................................................................................. ..466
Stan pikseli...... ............................................................................................................... ....467
Podrcznik.............. ................................................................................................................. .468
glDisable/glEnable...... ................................................................................................. ....468
gllsEnabled ................................................................................................................... .....470
16 _________________________________________ OpenGL - ksiga eksperta
Rozdzia 19.
Grafika interaktywna
.............................................................................................. 587
Selekcja. .............................................................................................................................. .....588
Nazywanie prymityww ....................................................................................................588
Praca w trybie selekcji.. ................................................................................................. .....590
Bufor selekcji ..................................................................................................................... 590
Wybieranie. ....................................................................................................................... .592
Wybr hierarchiczny.......................................................................................................... 594
Sprzenie zwrotne................................................................................................................... 598
Bufor sprzenia zwrotnego. .............................................................................................. 598
Dane sprzenia zwrotnego................................................................................................ 599
Znaczniki uytkownika ......................................................................................................600
Przykad.................................................................................................................................... 600
Nadawanie obiektom etykiet na potrzeby sprzenia zwrotnego ......................................601
Krok 1: wybranie obiektu................................................................................................... 602
Krok 2: pobieranie informacji o narysowanych obiektach. ............................................... 603
Podsumowanie .........................................................................................................................605
Podrcznik..:................................ ............................................................................................. 605
Instalacja............................................................................................................................ 61 8
Tryb spacerowy.................................................................................................................. 61 8
Tryb ogldania .................................................................................................................. .620
Open Inventor i VRML . ........................................................................................................ ...622
Podsumowanie .........................................................................................................................622
Cz IV
OpenGL i... ..................................................................................... 625
Rozdzia 21.
OpenGL i MFC....................................
............................................................... .....627
Wydzielenie kodu zwizanego z OpenGL. .............................................................................. .628
Zaczynamy od AppWizarda... ................................................................................................ ..629
Budowanie szkieletu .......................................................................................................... 629
Dodawanie bibliotek ..........................................................................................................630
Przygotowanie klasy widoku dla OpenGL...............................................................................631
Format pikseli i kontekst renderowania... .............................................................................. ...632
Usuwanie kontekstu renderowania.. ............................................................................... ....634
Obsuga zmiany rozmiaru okna. ............................................................................................... 634
. Spis treci_______________________________________________19
Renderowanie sceny.................................................................................................................634
7 Unikanie niepotrzebnego czyszczenia
okna.......................................................................635
8 Obsuga
palety..........................................................................................................................635
8
Podsumowanie............................................................................................................
.............639
O
O Rozdzia 22.
2 OpenGL i OWL........................................................................................................ 641
^ Wydzielenie kodu zwizanego z OpenGL........................................
8 Zaczynamy od AppExperta...............................................................
8 Budowanie szkieletu ......................................................................
3 Dodawanie nagwkw..................................................................
3 Dodawanie procedur obsugi komunikatw..................................
3 Wypenianie szkieletu aplikacji.........................................................
l Przygotowanie klasy widoku dla OpenGL....................................
l Format pikseli i kontekst renderowania............................................
j Usuwanie kontekstu renderowania.................................................
; Obsuga zmiany rozmiaru okna.........................................................
; Renderowanie sceny..........................................................................
i Unikanie niepotrzebnego czyszczenia okna...................................
j Niech si krci................................................................................
i Obsuga palety...................................................................................
! Podsumowanie..................................................................................
' Rozdzia 23.
, OpenGL w Visual Basic i
4GL..................................................................................657
, Wymagany dostp niskiego
poziomu.......................................................................................657
'. Magia
obiektw........................................................................................................................658
Pug and
Play.....................................................................................................................
659
Wydzielenie kodu
OpenGL................................................................................................659
l Dziaanie i sposb uycia kontrolki
WaiteGL.OCX.................................................................659
Znaczniki
OpenGL.............................................................................................................6
60
i Instalacja i uycie kontrolki WaiteGL w Yisual Basicu
6.0.....................................................661
Instalowanie
kontrolki........................................................................................................661
Przykad w Yisual Basicu
..................................................................................................662
Malowanie w oknie OpenGL
.............................................................................................663
Troch
ruchu....................................................................................................................
..664
Wykorzystanie kontrolki OCX w Delphi 2.0
..........................................................................665
Instalowanie
kontrolki........................................................................................................665
Przykad w
Delphi..............................................................................................................665
Malowanie w oknie
OpenGL.............................................................................................667
Troch
ruchu....................................................................................................................
..667
Par uwag na temat kodu
rdowego......................................................................................668
Podsumowanie
.........................................................................................................................669
Rozdzia 24.
Przyszo OpenGL w Windows ...............................................................................
671
Wnioski....................................................................................................................................674
Dodatki........................................................................................... 677
Dodatek A
Poprawianie wydajnoci OpenGL w
Windows........................................................... 679
Listy
wywietlania......................................................................................................
.......679
Operacje na macierzach .....................................................................................................680
20______________________________________OpenGL - ksiga eksperta
Operacje zwizane z
owietleniem.....................................................................................680
Konstruowanie
obiektw....................................................................................................680
Inne rady
............................................................................................................................6
81
Dodatek B
Dalsza
lektura........................................................................................................6
83
Ksiki na temat programowania
Windows.......................................................................683
Ksiki i materiay na temat
OpenGL................................................................................684
Ksiki komputerowe na temat programowania grafiki (w szczeglnoci
3D)..................684
Serwery FTP i WWW zwizane z
OpenGL.......................................................................684
Skadnice
VRML...............................................................................................................685
Dodatek C
OpenGL wersja 1.1.................................................................................................687
Dodatek D
Sownik..................................................................................................................689
Skorowidz....................................................................................................
.......... 695
>erta
.68 O autorach
0
.68
0
.681
583
683
684
684
684
685
Michael Sweet pracuje dla Chesapeake Test Rang w Patuxent River w stanie Maryland; jest
take wspwacicielem Easy Software Products, maej firmy programistycznej
specjalizujcej si w tworzeniu grafiki komputerowej na stacjach roboczych Silicon
Graphics. Przy komputerze pierwszy raz zasiad w wieku szeciu lat, za pierwszy program
sprzeda, gdy mia lat dwanacie. Pod koniec studiw w SUNY Institute of Technology w
Nowym Jorku Michael pracowa jako konsultant do spraw grafiki komputerowej. Tu
po studiach przenis si do Marylandu. W wolnych chwilach uwielbia jedzi na
rowerze, fotografowa i gra na trbce.
Przedmowa
Z powodu bardzo duych wymaga co do sprztu i mocy obliczeniowej, trjwymiarowa
grafika komputerowa dotd bya dostpna jedynie na specjalizowanych stacjach robo-
czych, mimp e sama technologia jej tworzenia jest znana od dziesitek lat. Dzisiejsze
komputery osobiste stay si jednak na tyle wydajne, e z powodzeniem mona ich uywa
do tworzenia trjwymiarowej grafiki. Obecnie przecitny komputer jest wydajniejszy ni
stacja graficzna sprzed kilku lat, kosztujc jednoczenie duo mniej.
OpenGL to standard, ktry powsta w celu umoliwienia przeniesienia grafiki kompute-
rowej, tradycyjnie dostpnej jedynie na stacjach graficznych, do zwykego komputera
osobistego. Gdy tylko powstaa ta technologia, uzyskaa znaczne wsparcie ze strony
Microsoftu.
W tym czasie Czerwona Ksiga bya jedyn pozycj zwizan z nauk OpenGL. Mimo e
zawieraa dokadny opis funkcji OpenGL, brakowao jej dwch wanych elementw. Po
pierwsze, nie bya dla pocztkujcych. Moe takie byy intencje autorw, lecz do lektury tej
ksiki potrzebna bya oglna wiedza o grafice trjwymiarowej. Drug wad bya jej
niezaleno od platformy. Jako programista Windows, potrzebowaem odpowiedzi na
pewne wane pytania, na przykad takie, jak wykorzysta pliki .BMP jako tekstury, jak
w OpenGL stworzy palet przeznaczon do wykorzystania na 8-bitowej karcie
graficznej, czy jak korzysta z dorzuconych przez Microsoft funkcji wiggle".
W naszej ksice nie s opisywane inne biblioteki OpenGL, przeznaczone dla 32- lub
16-bitowych systemw. Od strony programowej, OpenGL uywane w Windows 95 nie
rni si od swojego odpowiednika dla Windows NT. Pierwszy zestaw bibliotek DLL
wydany przez Microsoft dla Windows NT obejmuje wszystkie funkcje OpenGL 1.0; s
one dostpne w Windows NT 3.5 i 3.51. Do Windows NT 4.0 zostay dodane funkcje
OpenGL 1.1, a w momencie gdy ta ksika znajdzie si na rynku, powinny by ju do-
stpne takie funkcje rwnie dla Windows 95. Najwiesze informacje znajdziesz w pliku
readme.txt na pytce CD-ROM doczonej do ksiki.
Jzyk
Z wyjtkiem dwch rozdziaw powiconych pakietom klas C++, cay kod rdowy
zosta napisany w C. Wybr pomidzy C a C++ moe prowadzi niemal do krucjaty re-
Wprowadzenie
Kompilatory
Cay kod rdowy by oryginalnie opracowywany przy pomocy Microsoft Yisual C++
4.0. (Tak, z jego pomoc mona kompilowa take programy C!) Przy kadym przy-
kadzie znajdziesz pliki projektu Yisual C++.
Dla programistw wolcych biblioteki klas C++, takie jak MFC czy OWL, doczono
rozdziay dotyczce wanie tych bibliotek. Dodatkowo, wiele przykadw C zostao
doczonych take w wersji MFC (Yisual C++) oraz OWL (Borland C++). Te przykady
mona znale w kartotekach \MFC i \OWL na pytce CD-ROM. Pliki projektw do tych
przykadw przygotowano take w wersji dla kompilatora Borlanda (za pomoc Borland
C++ 5.0).
Cz I: Wprowadzenie do OpenGL
Rozdzia 1. - Co to jest OpenGL?
W tym rozdziale przedstawimy na przykadach, czym jest OpenGL, skd si wzio i
dokd zmierza. Omwimy take waniejsze rnice i zgodnoci OpenGL z systemem
graficznym Microsoft Windows.
W tym rozdziale poznamy jzyk VRML (Yirtual Reality Modeling Language) oraz jego
histori w OpenGL. Omwimy take klasy biblioteki Open Inventor oraz ich powizania z
OpenGL i VRML.
Ten rozdzia jest przeznaczony dla programistw C++ uywajcych biblioteki klas
MFC Microsoftu. Pokaemy, jak uywa OpenGL w aplikacjach MFC oraz jak doda
moliwoci renderowania OpenGL do okien wyprowadzonych z klasy CWnd.
Rozdzia 22. - OpenGL i OWL
Ten rozdzia jest przeznaczony dla programistw C++ uywajcych biblioteki klas
OWL Borlanda. Pokaemy, jak doda moliwoci renderowania OpenGL do okien OWL
wyprowadzonych z klasy TWindow.
>erta Wprowadzenie
Dodatki
3ze Dodatek A - Polepszanie wydajnoci OpenGL w Windows
Znajdziesz tutaj kilka oglnych rad dotyczcych poprawy szybkoci dziaania OpenGL w
Windows NT i Windows 95.
Dodatek D - Sownik
las Sownik popularnych terminw zwizanych z OpenGL i grafik trjwymiarow.
la
Kady rozdzia posiada wasn kartotek wewntrz kartoteki Book. W kadej kartotece
rozdziau znajduj si dodatkowe kartoteki, dla kadego przykadu osobno. Na przykad,
program odbijajcego si prostokta z rozdziau trzeciego znajduje si w kartotece
X:\Book\R03\bounce (gdzie X oznacza liter twojego napdu CD-ROM).
Pamitaj, aby sprawdzi zawarto pliku readme.txt w gwnej kartotece w celu po-
znania najbardziej aktualnych informacji o zawartoci pytki CD-ROM. Ten plik zawiera
take peny listing wszystkich plikw i programw zawartych na tej pytce.
Do dziea!
Jeli dopiero zaczynasz poznawa grafik trjwymiarow lub bibliotek OpenGL, szczerze
ci zazdroszcz. Nic nie daje wikszej satysfakcji i zwykej radoci ni poznawanie nowej
technologii lub narzdzia. Cho OpenGL ma korzenie w naukowym modelowaniu i
symulacji, nie musisz by naukowcem, aby je opanowa. Szczegowe, krok po kroku
opisywane przykady zawarte w tej ksice poprowadz ci na nowy poziom
umiejtnoci programowania.
Nauka OpenGL jest porwnywalna z nauk SQL przy programowaniu baz danych. Zanim
poznaem SQL, nawet nie wyobraaem sobie, jak potg moe wada programista baz
danych. Jeli tylko po amatorsku zajmowae si trjwymiarow grafik lub po prostu
chciaby j pozna, przekonasz si, jak wiele w tym wzgldzie ma do zaoferowania
biblioteka OpenGL!
RichardS. Wrightjr.
Wprowadzenie do OpenGL
Pierwsza cz tej ksiki zawiera wprowadzenie do trjwymiarowej grafiki i programowania w OpenGL.
Zaczniemy j od krtkiego omwienia biblioteki OpenGL, jej pochodzenia, przeznaczenia oraz sposobu
dziaania. Nastpnie, zanim przystpimy do pisania kodu, pomwimy oglnie o grafice 3D w komputerach,
wyjanimy, jak i dlaczego widzimy w trzech wymiarach oraz jak okrela si pooenie i orientacj obiektu w
trjwymiarowej przestrzeni. W ten sposb zapoznasz si z podstawowymi zagadnieniami i wyraeniami
wykorzystywanymi w caej dalszej czci ksiki.
W rozdziale trzecim rozpoczniesz tworzenie swoich pierwszych programw OpenGL. Poznasz wymagane
biblioteki i pliki nagwkowe, a take konwencje nazw bibliotek i funkcji OpenGL. Na pocztku poznamy
bibliotek AUX, stanowic zestaw narzdzi do nauki OpenGL niezalenie od platformy programowej i
sprztowej. Dopiero pniej, w rozdziale czwartym, przejdziemy do pisania programw uywajcych OpenGL
bezporednio w Windows 95 i Windows NT. Poznamy rozszerzenia interfejsu GDI w Windows, umoliwiajce
uycie OpenGL w Windows; opiszemy take sposoby ich wykorzystania. W rozdziale pitym uzyskasz
konieczne informacje dotyczce obsugi i zgaszania bdw. Dowiesz si, jak od pyta bibliotek AUX o jej
tosamo i twrc, a take jak poprawi jej wydajno. Posiadajc t wiedz, bdziesz dobrze przygotowany
do opanowania wiedz^z czci drugiej, w ktrej przykady bd znacznie bardziej skomplikowane!
(zdzia 1.
o to jest OpenGL?
OpenGL mona zdefiniowa jako programowy interfejs sprztu graficznego". Jest to
biblioteka przeznaczona do tworzenia trjwymiarowej grafiki, bardzo szybka i atwo
przenaszalna pomidzy rnymi systemami. Uywajc OpenGL moesz tworzy ele-
ganck i interesujc grafik 3D, o jakoci nie ustpujcej programom typu ray-trace.
Najwiksz zalet korzystania z biblioteki OpenGL jest jej szybko dziaania, o rzdy
wielkoci wysza od programw typu ray-trace. W OpenGL zastosowano algorytmy
opracowane i dopieszczone przez Silicon Graphics (SGI), niekwestionowanego lidera w
dziedzinie animacji i grafiki komputerowej.
OpenGL jest uywane do rnych celw, od programw typu CAD, przez aplikacje ar-
chitektoniczne a do generowania komputerowych dinozaurw w najnowszych filmach.
Wprowadzenie przemysowego API 3D na masowy rynek systemw operacyjnych, takich
jak Microsoft Windows, take obiecuje pewne ekscytujce moliwoci. Gdy powszechna
stanie si akceleracja sprztowa i szybkie procesory, grafika 3D wkrtce stanie si
typowym skadnikiem kadej aplikacji i nie bdzie ju stanowi domeny gier i aplikacji
naukowych.
Kto jeszcze pamita czasy, kiedy arkusze kalkulacyjne mogy prezentowa dane w postaci
paskiego, dwuwymiarowego wykresu? Jeli sdzisz, e dodanie trzeciego wymiaru do
zwykej aplikacji jest ekstrawagancj, przypomnij sobie firmy, ktre pierwsze
zastosoway ten pomys w praktyce. Quattro Pro, jedna z pierwszych aplikacji pozwala-
jcych na atwe tworzenie trjwymiarowych wykresw, niemal cakowicie zdominowaa
rynek arkuszy kalkulacyjnych. Obecnie paska, dwuwymiarowa grafika nie moe
zapewni sukcesu adej powanej aplikacji.
Nie chodzi o to, e OpenGL suy wycznie tworzeniu wykresw w aplikacjach biuro-
wych. Zastosowa jest mnstwo. Sukces lub poraka produktu czsto w ogromnym
stopniu zaley od jego wygldu, mimo e we wszystkich innych aspektach program nie
ustpuje lub nawet wyprzedza konkurencj. A dobra grafika 3D moe znacznie po-
dnie walory wizualne programu!
O OpenGL
Powiedzmy sobie teraz par sw na temat pochodzeniu biblioteki OpenGL, jej twrcach
oraz o jej zastosowaniach i perspektywach. Poznamy take podstawowe aspekty
implementacji OpenGL.
Historia OpenGL
OpenGL jest wzgldnie nowym standardem przemysowym, opracowanym zaledwie
kilka lat temu, jednak ju powszechnie zaakceptowanym. Przodkiem OpenGL by wasny
jzyk GL firmy Silicon Graphics. IRIS GL" byo interfejsem API grafiki 3D dla stacji
roboczych IRIS tej samej firmy. Te komputery nie miay jedynie oglnego prze-
Rozdzia 1. * Co to jest OpenGL?__________________________________37
wygldu lub efektu. Te kroki" stanowi wywoania funkcji wysoce przenaszalnego in-
terfejsu API, zawierajcego okoo 120 polece i funkcji. Su one rysowaniu prymityww
graficznych, takich jak punkty, odcinki i wielokty w trzech wymiarach. Ponadto OpenGL
obsuguje owietlenie i cieniowanie, mapowanie tekstur, animacj oraz dodatkowe efekty
specjalne.
OpenGL nie zawiera adnych funkcji przeznaczonych do zarzdzania oknami, interakcji z
uytkownikiem czy operacji wejcia/wyjcia. Kade systemowe rodowisko (takie jak
Microsoft Windows) posiada do tego celu wasne funkcje i jest odpowiedzialne za za-
pewnienie sposobw przeniesienia rysunkw OpenGL do okna lub na bitmap.
OpenGL w Windows
OpenGL zadebiutowa w Windows NT 3.51. Wkrtce po powstaniu Windows 95 pojawi
si rwnie zestaw bibliotek DLL umoliwiajcych korzystanie z OpenGL take w tym
systemie. Ta ksika odnosi si wanie do tej oglnej implementacji OpenGL. Ty,
programista, zostaniesz w niej poprowadzony przez podstawy grafiki trjwymiarowej, a
nastpnie dowiesz si, jak kompilowa i czy programy OpenGL w Windows NT i
Windows 95. Przechodzc dalej, omwimy funkcje dostarczone przez Microsoft -
stanowice spoiwo umoliwiajce dziaanie OpenGL z interfejsem GDI Microsoftu. Od
tego momentu zaczniesz poznawa pozostae elementy OpenGL API, wszystko to w
kontekcie Microsoft Windows NT i Windows 95.
Rysunek 1.1.
Schemat dziaania
akceleracji
sprztowej \v
Windows
Direct Draw jest zoptymalizowany pod ktem dostpu do sprztu graficznego. Cakowicie
pomija GDI i komunikuje si bezporednio z kart graficzn, by moe za porednictwem
cienkiej warstwy HAL (Hardware Abstraction Layer - warstwy abstrakcji sprztu) i
oprogramowania emulujcego funkcje nieobsugiwane przez sprzt. Direct Draw jest
zwykle uywany w grach, umoliwiajc bezporednie manipulacje w pamici graficznej w
celu osignicia ultraszybkiej grafiki i animacji 2D.
Po prawej stronie rysunku 1.1 znajduj si wywoania OpenGL i innych API 3D, prze-
kazywane poprzez interfejs sterownika grafiki trjwymiarowej (3D DDI). 3D DDI jest
opracowany tak, aby umoliwi producentom sprztu akceleracj OpenGL i innych trj-
wymiarowych API, takich jak Reality Labs API. (Dyskusja na temat OpenGL i API firmy
Reality Labs zostaa zawarta w rozdziale 24). Oprcz tego, dostawcy akceleratorw
40_________________________________Cz l Wprowadzenie do OpenGL
sprztowych przeznaczonych specjalnie dla OpenGL (takich jak chipset GLINT) mog
instalowa wasne sterowniki klienta OpenGL, a take specjalizowane sterowniki interfejsu
producenta.
Rysunek 2.1.
Jak oczy widz'
trzeci wymiar
Na rysunku 2.1 kt 9 pomidzy obrazami staje si tym mniejszy, im bardziej obiekt oddala si
od oczu. W zwizku z tym efekt trjwymiarowoci zwiksza si wraz ze wzrostem kta
pomidzy dwoma obrazami. Stereoskopy (te rczne przegldarki trjwymiarowych
slajdw, ktrymi z pewnoci bawie si w dziecistwie) i trjwymiarowe kina wyko-
rzystuj wanie ten efekt, przekazujc kademu z oczu odmienny obraz, czy to przez
oddzielne soczewki, czy te przez kolorowe okulary przepuszczajce wybrane fragmenty
obrazu. W tych obrazach zwykle stosuje si wikszy kt pomidzy oboma widokami, w
celu osignicia wyraniejszego efektu trjwymiarowoci.
Co si stanie gdy zakryjesz jedno oko? By moe mylisz, e dalej bdziesz widzia
trjwymiarowo, ale sprbuj przeprowadzi taki oto eksperyment: Umie szklank lub
jaki inny obiekt na wycignicie rki, po lewej stronie od siebie. Praw rk zaso
prawe oko i sprbuj sign po ten przedmiot. (Powiniene uy plastikowej szklanki!)
Zwr uwag e tym razem masz duo wicej trudnoci z signiciem i trafieniem w
szklank. Teraz odkryj prawe oko i jeszcze raz sprbuj chwyci szklank; przekonasz si,
jaka jest rnica. Wanie z tego powodu ludzie, ktrzy stracili jedno oko, czsto maj
problemy z ocen odlegoci.
2D + Perspektywa = 3D
Powd, dla ktrego po zasoniciu jednego oka wiat nie staje si natychmiast paski,
wynika z faktu, e wiele z efektw wiata trjwymiarowego obowizuje take w wiecie
dwch wymiarw. Najoczywistszym z nich jest to, e obiekty blisze wydaj si
wiksze od obiektw pooonych dalej. Ten efekt jest nazywany perspektyw. Za per-
spektywa plus zmiany w barwie, teksturze, owietleniu, cieniowaniu i rnych intensy-
wnociach koloru (w zwizku z owietleniem) cznie tworz wraenie trjwymiarowoci.
Rysunek 2.2.
Ten prosty
szkieletowy szecian
demonstruje efekt
perspektywy
Rysunek 2.3.
Ta sama kostka po
usuniciu
niewidocznych linii
Kolory i cieniowanie
Rysunek 2.3 wci nie daje wraenia rzeczywistego obiektu. cianki kostki maj dokadnie
ten sam kolor, co to, za wszystko, co wida, to przednie cianki. Rzeczywista kostka
miaaby pewien kolor i tekstur; na przykad w drewnianej kostce widoczne byyby kolor i
tekstura drewna. W komputerze (lub na papierze), jeli jedynie pokolorujemy kostk i
narysujemy j w dwch wymiarach, otrzymamy rysunek podobny do rysunku 2.4.
Wrcilimy wic do obiektu wygldajcego na paski i dopki nie narysujemy krawdzi
innym kolorem, w ogle nie osigniemy efektu trjwymiarowoci. Aby odzyska
wraenie trzech wymiarw (bez rysowania krawdzi w innym kolorze), kad z trzech
widocznych cianek musimy zamalowa innym kolorem lub tym samym kolorem o rnym
nateniu, co daje wraenie owietlenia obiektu. Na rysunku 2.5 widzimy obiekt, w
ktrym cianki zostay zamalowane rnymi kolorami lub odcieniami.
44 Cz l 4 Wprowadzenie do OpenGL
Rysunek 2.4.
Pokolorowana
kostka, ale bez
cieniowania
Rysunek 2.5.
Kostka ze ciankami
zamalowanymi
rnymi kolorami
wiata i cienie
Musimy powiedzie take par sw o owietleniu. Owietlenie daje dwa wane efekty w
przypadku obiektw ogldanych w trzech wymiarach. Po pierwsze, powoduje, e po-
wierzchnie o jednakowym kolorze, po owietleniu z boku, wydaj si mie rne cienio-
wanie. Po drugie, obiekty nie przepuszczajce wiata (czyli wikszo wypenionych
obiektw) po owietleniu rzucaj cie (rysunek 2.6).
Rysunek 2.6.
Kostka owietlona
pojedynczym
rdem wiata
Na nasz trjwymiarowy obiekt maj wpyw dwa rda wiata. wiato otoczenia, po-
zbawione kierunku, to po prostu jednolite owietlenie mogce powodowa efekt cieniowania
na jednolitych obiektach; wiato otoczenia powoduje, e bardziej odlege krawdzie
wydaj si ciemniejsze. Drugim rdem wiata moe by na przykad lampa. Lampy w
grafice trjwymiarowej s uywane do zmiany cieniowania jednolitych obiektw oraz
uzyskiwania efektw cienia.
Ukady wsprzdnych
Gdy wiesz ju, jak oko moe postrzega trzy wymiary na dwuwymiarowej paszczynie
(ekranie komputera), zastanwmy si, jak narysowa obiekty na tym ekranie. Gdy rysujesz
punkty, linie czy inne ksztaty na ekranie, zwykle okrelasz ich pooenie w odnie-
Rozdzia 2. 4 Podstawy grafiki 3D 45
-y
Obcinanie wsprzdnych
Okno jest mierzone fizycznie w pikselach. Zanim zaczniesz rysowa w oknie punkty,
odcinki i inne ksztaty, musisz najpierw poinformowa OpenGL, jak ma zamienia podane
pary wsprzdnych na fizyczne wsprzdne okna. Odbywa si to poprzez okrelenie
regionu przestrzeni kartezjaskiej zajmowanego przez okno; ten region nosi nazw obszaru
obcinania. W dwuwymiarowej przestrzeni obszar obcinania jest okrelony przez
minimalne i maksymalne wartoci wsprzdnych x i y punktw nalecych do okna.
Mona spojrze na to take inaczej, okrelajc pooenie pocztku w stosunku do okna.
Rysunek 2.8 przedstawia dwa przykady obszarw obcinania.
Rysunek 2.8.
Dwa obszary
obcinania
100
Obszar
roboczy
okna
(0,0) 150
widok jest zdefiniowany jako cale okno, ale nie jest to wymagane - na przykad moesz
zechcie rysowa tylko w dolnej czci okna.
Rysunek 2.9 przedstawia due okno, 300 x 200 pikseli, z widokiem obejmujcym cay
obszar roboczy. Gdyby obszar obcinania dla tego okna zostaby ustawiony na od O do
150 w osi x i od O do 100 w osi y, to wsprzdne logiczne byyby odwzorowane na
wiksze wsprzdne ekranowe okna. Kade zwikszenie wsprzdnej logicznej powo-
dowaoby dwukrotne zwikszenie odpowiedniej wsprzdnej (wsprzdnej piksela) w
oknie.
Rysunek 2.9.
Widok zdefiniowany
jako dwukrotne
powikszenie Obszot roboczy okna
obszaru obcinania 300x200 pikseli
Widok = 300x200
Rysunek 2.10.
Widok o tych samych
rozmiarach, co
obszar obcinania
Rysowanie prymityww
Zarwno w dwch, jak i w trzech wymiarach, gdy rysujesz obiekt, w rzeczywistoci
skadasz go z serii mniejszych ksztatw, zwanych prymitywami. Prymitywy to proste
obiekty, takie jak punkty, odcinki i paskie wielokty skadane w przestrzeni 3D w celu
utworzenia trjwymiarowych obiektw. Na przykad, trjwymiarowa kostka z rysunku 2.5
skada si z szeciu dwuwymiarowych kwadratw, z ktrych kady jest umie-
48 Cz l * Wprowadzenie do OpenGL
rowego obiektu w oddali. Gdy usuniemy obiekt lub przeniesiemy szyb, w dalszym cigu
pozostaj na niej kontury obiektu. Na rysunku 2.12 dom w tle jest rzutowany na paski
kawaek szka. Okrelajc rzutowanie, okrelasz bryle obcinania (pamitasz obszary
obcinania?), ktr chcesz wywietli w oknie, a take sposb przeksztacania jej
wsprzdnych.
Rysunek 2.12.
Trjwym iarowy
obiekt rzutowany na
pask szyb (ekran)
Rzuty rwnolege
W OpenGL zwykle bdziesz mia do czynienia z dwoma gwnymi rodzajami rzutw.
Pierwszy rodzaj to rzuty rwnolege. Tego typu rzutowanie okrela si stosujc prosto-
ktn lub szecienn bry rzutowania. Nic, co znajduje si poza t bry, nie jest rzuto-
wane. Co wicej, wszystkie obiekty o tych samych rozmiarach s rysowane w tych
samych rozmiarach, bez wzgldu na to, czy znajduj si dalej czy bliej. Ten rodzaj
rzutowania (przedstawiony na rysunku 2.13) jest czsto uywany w projektowaniu ar-
chitektonicznym i programach CAD (Computer Aided Design - projektowanie wspo-
magane komputerem).
Prawa
Blisza
Dolna
Bry obcinania rzutu rwnolegego okrela si podajc blisz, dalsz, lew, praw,
grn oraz doln paszczyzn obcinania. Obiekty znajdujce si wewntrz takiej bryy
obcinania s wywietlane (z wziciem pod uwag ich orientacji) na dwuwymiarowym
obrazie wywietlanym na ekranie.
50 Cz l * Wprowadzenie do OpenGL
Rzuty perspektywiczne
Drugim, popularniejszym typem rzutowania s rzuty perspektywiczne. To rzutowanie po-
woduje postanie efektu zmniejszenia rozmiarw bardziej odlegych obiektw. Brya widzenia
(rysunek 2.14) przypomina piramid ze citym wierzchokiem. Obiekty bdce bliej
paszczyzny rzutowania maj rozmiary zblione do oryginalnych, podczas gdy obiekty znaj-
dujce si dalej, wraz ze wzrostem oddalenia maj coraz mniejsze rozmiary. Ten rodzaj rzu-
towania odgrywa najwaniejsz rol w nadawaniu realizmu symulacjom i animacjom 3D.
Prowa
Podsumowanie
W tym rozdziale zapoznalimy si z podstawami trjwymiarowej grafiki. Wiesz ju, e aby
zobaczy prawdziwy trjwymiarowy widok, musisz widzie dwa obrazy tego samego
obiektu, nieco przesunite wzgldem siebie. Widziae take, jak tworzy si iluzj
trjwymiarowoci paskich obiektw, przez dodanie perspektywy, usunicie niewidocznych
linii, pokolorowanie, wycieniowanie oraz owietlenie. Zapoznae si z kartezjaskim
ukadem dwu- i trjwymiarowych wsprzdnych, poznae take dwie metody stosowane
przez OpenGL do rzutowania trjwymiarowych scen na dwuwymiarow powierzchni.
pisany w OpenGL lub jest aplikacj OpenGL, rozumiemy przez to, e jest napisany w
jakim jzyku programowania (takim jak C czy C++) i wywouje funkcje jednej lub kilku
bibliotek OpenGL. Nie twierdzimy, e programy uywaj OpenGL wycznie do rysowania,
gdy mona w nich czy wybrane elementy rnych pakietw graficznych. Mona te
uywa OpenGL wycznie do specyficznych zada, za grafiki specyficznej dla systemu
(na przykad Windows GDI) do innych.
Jako API, biblioteka OpenGL jest zgodna z konwencj wywoa funkcji C. To oznacza, e
programy w C mog wprost wywoywa funkcje OpenGL, poniewa albo sama funkcja jest
napisana w C, albo posiada specjaln funkcj poredni C do kodu napisanego w asemblerze
lub jakim innym jzyku. W tej ksice programy s pisane w C lub C++ i s przeznaczone
do pracy w rodowisku Windows NT lub Windows 95. Programy C++ mog atwo
korzysta z funkcji C i interfejsu API, wymaga to jedynie wprowadzenia bardzo drobnych
poprawek. Inne jzyki programowania -midzy innymi tak zwane 4GL-e (j?zyki czwartej
generacji), na przykad Yisual Basic - mogce wywoywa funkcje w bibliotekach C, take
mog korzysta z OpenGL. Wicej szczegw na ten temat znajduje si w rozdziale 23.
Tabela 3.1.
Biblioteki i pliki nagwkowe OpenGL
Gdy jako podstawy dla aplikacji uywasz biblioteki AUX (a wanie na tym skupimy si
w tym rozdziale), masz do dyspozycji take wszystkie funkcje bibliotek opengI32.dll i
glu32.dll. W ten sposb bdziesz mg pozna podstawy OpenGL, a take kilka polece z
biblioteki gl.
Tabela 3.2 zawiera list typw danych OpenGL, odpowiadajcych im typw danych C w
32-bitowym rodowisku Windows (Win32) oraz odpowiednie przyrostki dla nazw
zmiennych. W tej ksice kada zmienna posiada odpowiedni przyrostek; przekonasz
si, e takie przyrostki posiada take wiele nazw funkcji OpenGL.
54 Cz l Wprowadzenie do OpenGL
Tabela 3.2.
Typy zmiennych OpenGL oraz odpowiadajce im typy zmiennych w C
Typ danych w OpenGL Wewntrzna reprezentacja Zdefiniowane jako Przyrostek nazwy
typ C zmiennej w C
GLbyte 8-bitowa liczba cakowita signed char b
GLshort 16-bitowa liczba cakowita short s
GLint, GLsizei 32-bitowa liczba cakowita long 1
GLfloat, GLclampf 32-bitowa liczba float f
zmiennoprzecinkowa
GLdouble, GLclampd 64-bitowa liczba double ub
zmiennoprzecinkowa
GLubyte, GLboolean 8-bitowa liczba cakowita bez unsigned char us
znaku
GLushort 1 6-bitowa liczba cakowita bez unsigned short ui
znaku
GLuint, GLenum, GLbitfield 32-bitowa liczba cakowita bez unsigned long
znaku
Wskaniki i tablice nie s traktowane w aden specjalny sposb. Tablica zmiennych ty-f
pu GLshort moe zosta zadeklarowana po prostu jako: [
GLshort shorts[10];
Elementy nazwy funkcji OpenGL ilustruje rysunek 3.1. Ta prosta funkcja z przyrostkiem 3f
wymaga podania trzech argumentw zmiennoprzecinkowych. Inne odmiany wymagaj
podania trzech liczb cakowitych (glColor3i()), trzech liczb podwjnej precyzji
(glColor3d()) itd. Ta konwencja dodawania na kocu nazwy funkcji iloci i typu argu-
mentw bardzo uatwia zapamitanie listy argumentw danej funkcji, bez koniecznoci
zagldania do dokumentacji. Pewne wersje funkcji glColor wymagaj podania czterech
argumentw; dodatkowy argument oznacza skadnik alfa.
Rysunek 3.1.
Elementy nazwy
funkcji OpenGL
glColor3f(...)
nazwy Liczba Typ
argumentw argumentw
Czysto kodu
Wiele kompilatorw C/C++ zakada, e literay
zmiennoprzecinkowe s typu double, chyba e przy pomocy
przyrostka jawnie okreli si inny typ. Gdy jako argumentw
zmiennoprzecinkowych uyjesz literaw i nie okrelisz, e te
literay s typu float, a nie double, kompilator zgosi
ostrzegawczy komunikat, informujc o moliwej utracie
precyzji w wyniku konwersji. W miar wzrostu objtoci
programu OpenGL, ilo ostrzee zaczyna i w setki i
trudno jest wrd nich spostrzec rzeczywiste bdy skadni.
Moesz wyczy ostrzeenia uywajc odpowiedniej opcji
kompilatora -jednak nie zalecamy tego rozwizania.
56 Cz l Wprowadzenie do OpenGL
Biblioteka AUX
W pozostaej czci rozdziau zajmiemy si bibliotek Auxiliary (AUX), znacznie ua-
twiajc opanowanie OpenGL. Ta biblioteka zostaa stworzona w celu umoliwienia
nauki pisania programw OpenGL bez koniecznoci zawracania sobie gowy szczegami
dotyczcymi danego rodowiska systemowego, czy to bdzie UNIX, czy Windows czy
cokolwiek innego. Przy uyciu biblioteki AUX nie pisze si finalnego" kodu; uywa si
jej gwnie we wstpnej fazie, do przetestowania swoich pomysw. Brak podstawowych
elementw graficznego interfejsu uytkownika uniemoliwia zastosowanie tej biblioteki
przy tworzeniu bardziej uytecznych aplikacji.
Zestaw gwnych funkcji biblioteki AUX jest dostpny w prawie wszystkich implemen-
tacjach OpenGL. Te funkcje obsuguj tworzenie okien i manipulowanie nimi, a take
wejciem ze strony uytkownika. Pozostae funkcje rysuj pewne kompletne obiekty
3D, w postaci szkieletowej lub jednolitej. Uywajc biblioteki AUX do stworzenia i
obsugi okna oraz OpenGL w celu rysowania w tym oknie, mona tworzy programy
tworzce nawet bardzo skomplikowane rysunki. Po przekompilowaniu moesz bez wi-
kszych problemw przenosi te programy do innych rodowisk.
Niestety, mao prawdopodobne jest, aby wikszo funkcji uytecznej aplikacji spro-
wadzaa si wycznie do rysowania trjwymiarowych scen, nie moesz wic uywa
biblioteki AUX do wszystkiego. Jednak mimo wszystko, ta biblioteka jest niezastpiona
jeli chodzi o nauk i opanowywanie OpenGL, a w przypadku pewnych programw, zanim
stworzysz pen aplikacj, moesz uy biblioteki AUX do dopieszczenia kodu zajmujcego
si samym rysowaniem.
Rozdzia 3. 4 Nauka OpenGL z uyciem biblioteki AUX_______________________57
Niezaleno od platformy
OpenGL to wydajne i wymylne API przeznaczone do tworzenia trjwymiarowej grafiki, z
ponad 300 poleceniami, umoliwiajcymi okrelenie wszystkich elementw sceny, od
ustawienia koloru i waciwoci materiau, a po przeprowadzanie obrotw i innych
zoonych transformacji obiektw. By moe zdziwi ci to, e OpenGL nie posiada po-
jedynczej funkcji czy polecenia zwizanego z zarzdzaniem oknem czy ekranem. Nie
ma take funkcji przeznaczonych do odczytu klawiatury czy pooenia myszki. We jednak
pod uwag, e jednym z gwnych zaoe twrcw tego systemu bya jego niezaleno
od platformy. Tworzenie i otwieranie okna przebiega zupenie inaczej na rnych
platformach. Nawet gdyby OpenGL zawierao polecenie otwierajce okno, uyby wanie
jego, czy raczej specjalizowanej funkcji wbudowanej w system operacyjny?
Biblioteka AUX zawiera tylko kilka funkcji przeznaczonych do obsugi okien, klawiatury i
myszy, jednak i tak oszczdza ci znacznego kopotu zwizanego z ich obsug w
czystym C/C++ lub przez API Windows. Biblioteka zawiera take funkcje przeznaczone
do rysowania kilku stosunkowo prostych trjwymiarowych obiektw, takich jak okrg,
szecian, torus czy nawet imbryk do herbaty. Przy bardzo maym wysiku moesz uy
biblioteki AUX do wywietlenia okna i wykonania w nim kilku operacji OpenGL.
Cho biblioteka AUX w rzeczywistoci nie stanowi czci specyfikacji OpenGL,
wyglda na to, e zostaa zaimplementowana dla wszystkich platform, dla ktrych
zaimplementowano OpenGL. Windows take nie stanowi wyjtku, za kod rdowy
biblioteki AUX jest dostpny za darmo jako cz Win32 SDK Microsoftu.
58 Cz l * Wprowadzenie do OpenGL
Rysunek 3.2.
Wynik dziaania
programu shortest.c
// shortest.c
// N a j k r t s z y w wiecie program OpenGL
void main(void)
glFlushO ;
Tryby konsoli
Aplikacja konsoli to program Win32 dziaajcy w oknie trybu
tekstowego. Taki program bardzo przypomina program DOS-a
uruchomiony w Windows NT lub Windows 95, z tym e jest w
peni 32-bitowa aplikacja i ma dostp do caego API Win32.
Programy konsoli nie s ograniczone do trybu tekstowego. W
rzeczywistoci mog tworzy wasne okienka (w powyszym
programie sprbuj uy funkcji MessageBox() z wartoci
IMULL podan w miejscu uchwytu okna), za aplikacje GUI
(Graphics User Interface - graficzny interfejs uytkownika)
mog w razie potrzeby tworzy okna konsoli. Biblioteka AUX
umoliwia atwe pisanie programw konsoli, zawierajcych
funkcj main(), ktra tworzy pomocnicze okno GUI dla rysunku
tworzonego w OpenGL.
Aby zbudowa ten program, musisz ustawi opcje kompilatora i linkera tak, aby po-
wstaa aplikacja konsoli Win32. Musisz doczy bibliotek AUX, glaux.lib, oraz bi-
bliotek importow OpenGL, openg!32.1ib. Szczegowe instrukcje na temat kompilacji i
czenia programw znajdziesz w dokumentacji kompilatora.
Program shortest.c nie czyni zbyt wiele. Gdy uruchomisz go w linii polece, tworzy
standardowe okno GUI z tytuem Mj pierwszy program OpenGL" oraz czystym nie-
bieskim tem. Nastpnie w oknie konsoli wywietla komunikat Wcinij jaki klawisz,
aby zamkn okno". Okno GUI nie reaguje na klawiatur ani mysz; to okno konsoli
oczekuje na wcinicie jakiego klawisza w celu zakoczenia dziaania (musisz w tym
celu przeczy si z powrotem do okna konsoli). Nie moesz take przesun okna
OpenGL ani zmieni jego rozmiaru, za samo okno nawet si nie odrysowuje. Jeli
przesonisz okno, a nastpnie je odsonisz, przekonasz si, e obszar roboczy sta si
czarny.
Ten prosty program zawiera trzy funkcje biblioteki AUX (poprzedzone przedrostkiem
aux) oraz trzy prawdziwe" funkcje OpenGL (poprzedzone przedrostkiem gl). Przej-
rzyjmy ten program linia po linii, a nastpnie przejdmy do omwienia innych funkcji,
poprawiajcych dziaanie naszego programu.
Cz nagwkowa
S do niej wczone nastpujce pliki:
tfinclude <windows.h>
#include <conio.h>
include <gl\gl.h>
tinclude <gl\glaux.h>
60_________________________________Cz l Wprowadzenie do OpenGL
Ciao programu
Nastpnie mamy do czynienia z gwn czci programu:
void main(void) {
informuje bibliotek AUX o trybie wywietlania, jaki ma zosta uyty podczas tworzenia
okna. Zastosowane przez nas znaczniki nakazuj uycie okna z pojedynczym buforem
(AUX_SINGLE) oraz trybu kolorw RGBA (AUX_RGBA). Okno z pojedynczym
buforem oznacza, e wszystkie polecenia rysowania s wykonywane bezporednio w
wywietlanym oknie. Alternatyw stanowi okno z podwjnym buforem, w ktrym
polecenia rysowania s realizowane w niewidocznym buforze, ktry nastpnie jest
szybko przerzucany do okna na ekranie. Ta technika jest stosowana najczciej przy
tworzeniu animacji, co zademonstrujemy w dalszej czci rozdziau. Tryb koloru RGBA
oznacza, e wartoci kolorw s podawane jako oddzielne wartoci barw skadowych:
czerwonej, zielonej i niebieskiej (ang. red, green i blue) - wicej informacji na ten
temat znajdziesz w rozdziale 8.
Pozycjonowanie okna
Po ustawieniu trybu wywietlania, musimy poinformowa bibliotek AUX o pooeniu i
rozmiarach okna. Suy do tego nastpna linia kodu:
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 61
aux!nitPosition(100,100,250,250);
Parametry reprezentuj pooenie lewego grnego rogu okna oraz jego szeroko i wy-
soko. Powysza linia nakazuje umieszczenie lewego grnego rogu okna w miejscu o
wsprzdnych (100, 100) oraz nadanie oknu szerokoci 250 pikseli i wysokoci take 250
pikseli. Przy standardowej rozdzielczoci VGA (640 x 480), okno zajmie do du cz
ekranu. Przy rozdzielczociach Super VGA (800 x 600 i wyszych) okno zajmie mniej
miejsca, gdy ilo pikseli pozostanie taka sama (250 x 250).
Typy danych GLint i GLsizei s zdefiniowane jako liczby cakowite (zostay one om-
wione w sekcji dotyczcej typw danych we wczeniejszej czci rozdziau). Parametr x
okrela ilo pikseli liczonych od lewej krawdzi ekranu, za parametr y - ilo pikseli
liczonych od grnej krawdzi. Wanie tak Windows domylnie konwertuje wsprzdne
ekranu na wsprzdne fizyczne. Domylna metoda liczenia wsprzdnej x w OpenGL jest
taka sama; jednak w przypadku wsprzdnej y jest ona liczona od dolu do gry - przeciwnie
do kierunku wzrostu tej wsprzdnej w Windows. Spjrz na rysunki 3.3 oraz 3.4.
Rysunek 3.3.
Domylne Wsprzdne ektranu w Windows
odwzorowanie
wsprzdnych Kierunek dodatni
ekranu \v Windows (100,100)
Kierunek dodatni
tworzy okno oraz nadaje mu tytu Mj pierwszy program OpenGL". Oczywicie, poje-
dynczym argumentem tej funkcji jest wanie tytu okna. Gdybymy zatrzymali si w
tym miejscu, program stworzyby puste okno (domylnie o czarnym tle) z podanym
tytuem, a nastpnie zakoczyby dziaanie natychmiast zamykajc okno OpenGL. Do-
danie ostatniej instrukcji getch() zabezpieczy nas przed zamkniciem okna, jednak w
dalszym cigu w samym oknie nie dzieje si nic interesujcego.
to twoje pierwsze wywoanie prawdziwej funkcji OpenGL. Ta funkcja ustala kolor uy-
wany podczas czyszczenia okna. Jej prototyp to:
void glClearColor (GLclampf red, GLclampf green, GLclampf blue,
OGLclampf alpha) ;
Tabela 3.3 zawiera list niektrych czciej wykorzystywanych kolorw oraz odpowia-
dajce im wartoci poszczeglnych barw. Te wartoci mog by uyte we wszystkich
funkcjach OpenGL zwizanych z kolorem.
Tabela 3.3.
Stosunki barw skadowych czciej uywanych kolorw
Kolor wynikowy Barwa czerwona Barwa zielona Barwa niebieska
Czarny 0,0 0,0 0,0
Czerwony 1,0 0,0 0,0
Zielony 0,0 1,0 0,0
ty 1,0 1,0 0,0
Niebieski 0,0 0,0 1,0
Fioletowy 1,0 0,0 1,0
Bkitny 0,0 1,0 1,0
Ciemny szary 0,25 0,25 0,25
Jasny szary 0,75 0,75 0,75
Brzowy 0,60 0,40 0,12
Pomaraczowy 0,98 0,625 0,12
Rowy 0,98 0,04 0,70
Purpura 0,60 0,40 0,70
Biay 1,0 1,0 1,0
Ostatnim argumentem funkcji flClearColor() jest skadnik alfa. Skadnik alfa jest uy-
wany przy przezroczystoci oraz przy efektach specjalnych takich jak przejrzysto.
Przejrzysto odnosi si do waciwoci obiektu umoliwiajcej wiatu przechodzenie
przez obiekt. Przypumy, e prezentujesz kawaek czerwonego witrau, lecz owietlonego
niebieskim wiatem. Niebieskie wiato wpynie na wygld czerwieni w szkle
(czerwony + niebieski = fioletowy). Moesz uy skadnika alfa w celu uczynienia
koloru niebieskiego pprzejrzystym, tak aby wyglda na przykad jak warstwa wody,
ukazujca znajdujce si pod ni obiekty. Na temat tego rodzaju efektw mona po-
wiedzie o wiele wicej ni tylko o wartoci alfa; w rozdziale 16 napiszemy przykadowy
program demonstrujcy te zagadnienia, a na razie pozostaw t warto jako 1.
64 Cz l Wprowadzenie do OpenGL
Samoczyszczenie okna
Gdy poinformowalimy OpenGL o kolorze, jakiego ma uy do czyszczenia, moemy
uy instrukcji wykonujcej samoczyszczenie. Suy do tego linia
glClear(GL_COLOR_BUFFER_BIT);
Funkcja glClear() czyci dany bufor lub kombinacj buforw. Bufor to miejsce, gdzie
przechowywana jest informacja o obrazie. Skadniki czerwony, zielony i niebieski po-
siadaj wewntrznie osobne bufory, jednak w caoci traktujemy je jako pojedynczy
bufor kolorw.
Bufory to bardzo uyteczny element OpenGL; szczegowo omwimy je w rozdziale 15.
Przed lektur nastpnych kilku rozdziaw jedyne, co musimy zapamita o buforze ko-
lorw, to informacja e jest w nim wewntrznie przechowywany rysowany obraz, za
wyczyszczenie bufora funkcj glClear() powoduje usunicie rysunku z okna.
// friendly.c
// Bardziej przyjazny program OpenGL
void main(void) {
// Przygotowanie trybu rysowania i okna za pomoc biblioteki AUX
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
aux!nitPosition(100,100,250,250); auxlnitWindow("Mj drugi program
OpenGL");
Pierwsza zmiana dotyczy plikw nagwkowych. Nie ma tu pliku conio.h, gdy nie
uywamy ju funkcji getch() ani cprintf().
Funkcja renderujca
W programie wystpuje nowa funkcja, RenderScene().
// Wywoywane przez bibliotek AUX w celu narysowania sceny void
CALLBACK RenderScene(void)
W tej funkcji umiecilimy cay kod odpowiedzialny za rysowanie w oknie. Proces ry-
sowania w OpenGL czsto jest nazywany renderowaniem, uylimy wic adekwatnej do
tego nazwy funkcji. W nastpnych przykadach wikszo kodu rysunkowego znajdzie si
wanie w tej funkcji.
Rysowanie prostokta
Poprzednim razem wszystkie dziaania programu sprowadzay si jedynie do wyczy-
szczenia ekranu. Teraz do kodu rysunkowego dodalimy dwie ponisze linie:
// Kolor rysowania czerwony
//
R G
B
glColor3f( l . O f , O . O f , O . O f ) ;
Pierwsza linia ustawia kolor uywany w nastpnych operacjach rysowania (linii i wy-
penie); suy do tego funkcja glColor3f(). Druga linia, wywoujca funkcj glRectf(),
suy do narysowania wypenionego prostokta.
Funkcja glColor3f() wybiera kolor w ten sam sposb, co glClearColor(), z tym e nie
trzeba podawa wartoci skadnika alfa:
void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
Funkcja glRectf() wymaga parametrw typu float, o czym informuje kocowa litera f
nazwie funkcji. W tym wypadku w nazwie nie ujmuje si iloci argumentw, gdy
wszystkie odmiany tej funkcji wymagaj podania czterech argumentw. Cztery argu-
menty funkcji glRectf():
void glRectf(GLfloat xl, GLfloat yl, GLfloat x2, GLfloat y 2 ) ;
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX_______________________67
reprezentuj dwie pary wsprzdnych: (xl, yl) oraz (x2, y2). Pierwsza para reprezentuje
lewy grny rg prostokta, za druga para - rg prawy dolny. Jeli chcesz sobie
przypomnie odwzorowanie wsprzdnych w OpenGL, spjrz na rysunek 3.4.
Inicjowanie
Gwna funkcja programu friendly.c rozpoczyna si tak samo jak w naszym pierwszym
przykadzie:
void main(void) {
// Przygotowanie trybu rysowania i okna za pomocy biblioteki AUX
auxInitDisplayMode(AUX_SINGLE | AUX_RGBA);
auxInitPosition(100,100,250,250); aux!nitWindow("Mj drugi program
OpenGL");
// Przygotowanie funkcji wywoywanej w razie koniecznoci //
odwieenia okna auxMainLoop(RenderScene); }
Jak wczeniej, trzy wywoania auxlnito* przygotowuj i tworz okno, w ktrym bdzie si
odbywa rysowanie. W ostatniej linii funkcji auxMainLoop() znajduje si nazwa funkcji,
ktra bdzie uywana do rysowania, funkcji RenderScene(). Funkcja Main-Loop()
biblioteki AUX po prostu podtrzymuje dziaanie programu do momentu, a uytkownik
zamknie okno. Pojedynczym argumentem funkcji jest wskanik do innej funkcji, ktra ma
by wywoywana za kadym razem, gdy okno wymaga aktualizacji. Ta funkcja zwrotna
zostanie wywoana podczas pierwszego wywietlenia okna, gdy zostanie ono przesunite
lub przeskalowane, a take gdy zostanie odsonite przez inne okno.
// Wywoywane przez bibliotek AUX w celu narysowania sceny void
CALLBACK RenderScene(void)
{
// Kolor ta: Niebieski
glClearColor( O . O f , O.Of, l . O f , l . O f ) ;
// Wyczyszczenie okna
glClear(GL_COLOR_BUFFER_BIT);
glFlushf) ; }
o wsprzdnych (100, 150, 150, 100). W oryginalnym oknie byo to dokadnie na rodku;
w oknie wikszym te wsprzdne wskazuj lewy dolny rg okna (rysunek 3.5).
Rysunek 3.5.
Efekty zmiany rozmiaru okna
250
Skalowanie do
rozmiarw okna
W praktycznie wszystkich rodowiskach okienkowych uytkownik moe w dowolnej
chwili zmieni rozmiary okna. Gdy tak si dzieje, okno zwykle odpowiada odrysowaniem
swej zawartoci, biorc pod uwag nowy rozmiar. Czasem zechcesz po prostu obci
obraz do nowych wymiarw lub wywietli cay obraz w wikszym oknie. Do naszych
celw zwykle jednak zechcemy tak przeskalowa rysunek, aby w peni mieci si w
oknie, bez wzgldu na rozmiar rysunku lub okna. Tak wic bardzo mae okno bdzie
zawierao peny, lecz bardzo may rysunek, za wiksze okno bdzie zawierao podobny,
lecz wikszy rysunek. Wida to w wikszoci programw rysunkowych, gdy zmniejszasz
okno, lecz nie powikszasz samego rysunku. Zmniejszenie okna zwykle nie zmienia
rozmiaru rysunku, jednak powikszenie rysunku zwykle zwiksza rozmiar okna.
Rysunek 3.6.
Widok i brya
obcinania dla (250,250,-!)
program u friendly. c
(250,250,1)
(100,150,0)
(150,100,0
Nazw ChangeSize (zmie rozmiar) wybralimy jako nazw opisow i bdziemy si jej
trzyma take w nastpnych przykadach.
Funkcja ChangeSize() otrzymuje now szeroko i wysoko okna za kadym razem,
gdy zmienia si ktry z wymiarw okna. Moemy uy tej informacji do zmodyfiko-
wania odwzorowania naszego ukadu wsprzdnych na ukad wsprzdnych ekranu, za
pomoc dwch funkcji OpenGL: glViewport() oraz glOrtho(). Listing 3.3 przedstawia
nasz poprzedni przykad modyfikowany tak, aby bra pod uwag zmian rozmiaru okna.
Na listingu zostaa przedstawiona jedynie zmodyfikowana funkcja main() oraz nowa
funkcja ChangeSize().
70_________________________________Cz l Wprowadzenie do OpenGL
Teraz, gdy zmienisz wymiary okna, prostokt take zmieni swj rozmiar. Znacznie wiksze
okno bdzie zawierao duo wikszy prostokt, za o wiele mniejsze okno bdzie
zawierao znacznie mniejszy prostokt. Jeli wyduysz okno w poziomie, prostokt zostanie
wyrodkowany w pionie, daleko na lewo od rodka. Jeli wyduysz okno w pionie,
prostokt zostanie wyrodkowany w poziomie, bliej dou okna. Zwr uwag e
prostokt zawsze pozostaje kwadratem. Aby zobaczy jak zmienia si rozmiar prostokta
wraz z rozmiarami okna, spjrz na rysunki 3.7a i 3.7b.
Rozdzia 3. Nauka OpenGL z uyciem biblioteki AUX 71
Rysunek 3.7a.
Obraz
przeskalowany do
wymiarw okna
Rysunek 3.7b.
Prostokt zmienia
rozmiar wraz
z wymiarami okna
Definiowanie widoku
Aby zrozumie, jak definiuje si widok, przyjrzyjmy si bliej funkcji ChangeSize(). Na
pocztku wywouje ona funkcj glViewport() z now szerokoci i wysokoci okna.
Funkcja glViewport() jest zdefiniowana jako
void glviewport(GLint x, GLint y, GLint width, GLint h e i g h t ) ;
Rysunek 3.8.
Odwzorowanie
widoku na okno
GrViewport(0,0,125,125)
125X
glVjewport(0,0,250,250)
11
250 N- 250
-H
-H
Widok i okno maj te same rozmiary
Widok stanowi poow rozmiaru okna
Jeli widokowi zostanie przypisany stosunek wsprzdnych rny od 1,0 i widok zo-
stanie odwzorowany w prostoktn bry obcinania, spowoduje to, e obrazy bd znie-
ksztacone. Na przykad, widok dostosowany do wymiarw okna, lecz odwzorowany w
prostoktn bry obcinania spowoduje, e obrazy bd wskie i wysokie w wskich i
wysokich oknach, a niskie i szerokie w niskich i szerokich oknach. W naszym przypadku
kwadrat tylko wtedy byby kwadratowy, gdyby samo okno byo kwadratowe.
Rysunek 3.9.
Przestrze
kartezjaska
H
250
Ta funkcja jest cay czas regularnie wywoywana przez bibliotek AUX, chyba e okno
jest akurat przemieszczane lub skalowane.
// bounce.c
// Odbijajcy si kwadrat
else
windowWidth = 250.0f*w/h;
windowHeight = 250. Of;
glFlush() ;
76 _________________________________ Cz l * Wprowadzenie do OpenGL
Animacja tworzona przez ten przykad jest kiepska, nawet w bardzo szybkim komputerze.
Poniewa przed narysowaniem prostokta jest czyszczona zawarto caego okna, cay
czas kwadrat migocze i wyranie wida, e w rzeczywistoci jest rysowany jako dwa
trjkty. Aby stworzy pynniejsz animacj, musimy wykorzysta mechanizm zwany
podwjnym buforowaniem.
Rozdzia 3. Nauka OpenGL z uyciem biblioteki AUX __ __ 77
Podwjne buforowanie
Jedn z najwaniejszych cech kadego pakietu graficznego jest obsuga podwjnego bu-
forowania. Ta funkcja umoliwia tworzenie rysunku w niewidocznym buforze, a na-
stpnie byskawiczne przerzucenie zawartoci tego bufora do okna na ekranie.
Jak ju wspomniano, cay czas rysowalimy obiekty w przestrzeni 3D, jednak rzut pro-
stokta by prostopady do bryy obcinania. Gdybymy mogli po prostu obrci bry
obcinania w stosunku do obserwatora, by moe ujrzelibymy jakie elementy trzeciego
wymiaru. W tym momencie jednak, a do rozdziau 7, nie mamy zamiaru zagbia si w
obroty i transformacje wsprzdnych. A nawet gdybymy sprbowali tego teraz,
kwadrat, nawet obrcony, nie jest zbyt ciekawy.
Aby ujrze gboko, musimy narysowa obiekt, ktry nie jest paski. Biblioteka AUX
zawiera prawie tuzin trjwymiarowych obiektw - od kuli a po imbryk na herbat - ktre
mona stworzy jednym wywoaniem funkcji. Te funkcje maj posta auxSolidrra:() lub
auxWirexxx;e(), gdzie xxxx oznacza, nazw jednolitego lub szkieletowego obiektu, ktry
ma zosta stworzony. Na przykad, ponisze polecenie rysuje szkieletowy imbryk do kawy
o rednicy wynoszcej, w przyblieniu, 50 jednostek:
auxWireTeapot( 5 0 . Of);
Jeli bymy zdefiniowali bry obcinania na zakres od -100 do 100 we wszystkich trzech
osiach, otrzymalibymy imbryk do kawy przedstawiony na rysunku 3.12. Imbryk do
kawy jest w tym momencie chyba najlepszym przykadem, poniewa pozostae obiekty
ogldane w rzucie rwnolegym nadal sprawiaj wraenie paskich. Program rysujcy
ten imbryk do herbaty znajduje si w osobnym podrozdziale na pytce CD-ROM, w
pliku teapot.c.
Rysunek 3.12.
Szkieletowy imbryk do herbaty
Podsumowanie
W tym rozdziale zostalimy wprowadzeni do narzdziowej biblioteki AUX oraz pozna-
limy podstawy pisania programw korzystajcych z OpenGL. Uylimy biblioteki
AUX do pokazania najprostszego sposobu utworzenia okna i rysowania w nim przy
pomocy polece OpenGL. Nauczye si uywa biblioteki AUX do tworzenia okien,
ktre mog zmienia rozmiary, a take prezentowa w nich proste animacje. Oprcz
tego znasz ju proces uywania OpenGL przy rysowaniu - komponowanie i wybieranie
kolorw, czyszczenie ekranu, rysowanie prostokta, a take ustawianie widoku oraz
bryy obcinania tak, aby dopasowa je do rozmiaru okna. Omwilimy take rne typy
danych, jak rwnie pliki nagwkowe i biblioteki wymagane przy budowie programw
OpenGL.
Biblioteka AUX zawiera jeszcze wiele innych funkcji obsugujcych take klawiatur i
mysz. Implementacja biblioteki stworzona przez Microsoft zawiera specyficzne dla
Windows funkcje umoliwiajce dostp do uchwytw okien i kontekstw urzdze.
Przejrzyj umieszczon poniej sekcj podrcznika, aby samemu odkry pozostae ele-
menty i zastosowania biblioteki AUX. Przejrzyj take inne przykady do rozdziau trze-
ciego, zamieszczonych na pytce CD-ROM doczonej do ksiki.
Podrcznik
auxldleFunc
Przeznaczenie Ustawia funkcj zwrotn wywoywan w czasie bezczynnoci.
Plik nagwkowy <glaux.h>
Skadnia void aux!dleFunc(AUXIDLEPROC func);
Opis Okrela, e funkcja bezczynnoci func() bdzie regularnie wywoywana
w momencie braku innej aktywnoci okna. Gdy program nie jest zajty
renderowaniem sceny, funkcja zmienia pewne parametry uywane przez
funkcje rysunkowe przy tworzeniu nastpnego obrazu.
80 Cz l Wprowadzenie do OpenGL
Parametry
func Prototypem tej funkcji jest
Zwracana void CALLBACK IdleFunc(void);
Definiowana przez uytkownika funkcja regularnie wywoywana w
warto czasie bezczynnoci programu. Przekazanie wartoci NULL jako
Przykad Patrz adresu funkcji zatrzymuje przetwarzanie czasu wolnego.
take Brak.
Przykady BOUNCE i BOUNCE2 do tego rozdziau.
auxSwapBuffers, auxMainLoop, auxReshapeFunc
auxlnitDisplayMode
Przeznaczenie Inicjuje tryb wywietlania biblioteki AUX dla okna OpenGL.
Plik <glaux.h>
nagwkowy void auxInitDisplayMode(GLbitfield mask);
Skadnia Opis To pierwsza funkcja, jaka musi by wywoana w programie korzystajcym z
biblioteki AUX. Suy do przygotowania okna OpenGL. Ta funkcja ustala
charakterystyk okna uywanego przez OpenGL w operacjach
rysunkowych.
Parametry
mask GLbitfield: Maska lub kombinacja bitowa masek z tabeli 3.4. Te wartoci
masek mog by czone przy pomocy bitowego operatora OR. Na
Zwracana przykad, aby przygotowa okno posiadajce podwjny bufor i korzystajce
warto z indeksowanego trybu kolorw, wywoaj
Przykad Patrz aux!nitDisplayMode(AUX_DOUBLE | AUX_INDEX)
take Brak.
Kady przykadowy program w tym rozdziale.
aux!nitPosition, aux!nitWindow
Tabela 3.4.
Wartoci masek dla rnych charakterystyk okna
Tabela 3.4.
Wartoci masek dla rnych charakterystyk okna cig dalszy
Warto maski Znaczenie
auxlnitPosition
Przeznaczenie Ustala pozycj okna przygotowanego przez aux!nitWindow().
Plik nagwkowy <glaux.h>
Skadnia void aux!nitPosition(GLint x, GLint y, GLsizei width, GLsizei height);
Opis Ta funkcja informuje bibliotek AUX o miejscu, gdzie ma zosta otwarte
gwne okno graficzne.
Paramet
ry x GLint: Odlego lewego grnego rogu okna od lewej krawdzi ekranu,
mierzona w pikselach.
auxlnitWindow
Przeznaczenie Inicjuje i wywietla okno renderowania OpenGL.
Plik <glaux.h>
nagwkowy void aux!nitWindow(BYTE *titleString);
82 Cz l Wprowadzenie do OpenGL
Opis Ta funkcja otwiera okno, ktre bdzie uywane przez OpenGL przy
operacjach graficznych.
Przed wywoaniem okna naley okreli jego charakterystyk za pomoc
funkcji aux!nitDisplayMode() oraz aux!nitPosition().
Parametry
titleString GLBYTE: Wskanik do acucha znakw, ktry zostanie uyty jako tytu
okna, wywietlany na belce tytuowej.
Zwracana warto Brak.
Przykad Kady przykadowy program w tym rozdziale.
Patrz take aux!nitDisplayMode, aux!nitPosition
auxKeyFunc
Przeznaczenie Wie funkcj zwrotn z wciniciem danego klawisza.
Plik <glaux.h>
nagwkowy void auxKeyFunc(GLint key, void(*function(void));
Skadnia Opis Ustala funkcj zwrotn {function), ktra bdzie wywoywana przez
bibliotek AUX za kadym razem, gdy zostanie wcinity klawisz
o numerze key. Po przetworzeniu klawisza nastpuje odwieenie okna.
Parametry
key GLint: Numer klawisza, jaki ma by powizany z dan funkcj. Moe to
by jedna z wartoci z tabeli 3.5.
function Ta funkcja zwrotna ma nastpujcy prototyp: void
Zwracana CALLBACK KeyFunc(void);
warto Ta funkcja jest wywoywana przez bibliotek AUX za kadym razem, gdy
Przykad zostanie wcinity dany klawisz. Gdy jako ten parametr zostanie
przekazana warto NULL, nastpuje wstrzymanie wywoywania funkcji
zwrotnej.
Patrz take
Brak.
Dodatkowy przykadowy program KEYMOYE na pytce CD-ROM, w
folderze tego rozdziau.
auxMouseFunc
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 83
Tabela 3.5.
Definicje klawiszy w bibliotece A UX
Warto Opis
AUX_ESCAPE Klawisz Esc Klawisz spacji Klawisz
AUX_SPACE Enter Klawisz kursor w lewo
AUX_RETURN Klawisz kursor w prawo Klawisz
AUX_LEFT kursor w gr Klawisz kursor w d
AUX_RJGHT Klawisze od A do Z (wielkie litery)
AUX_UP Klawisze od a do z (mae litery)
AUX_DOWN Klawisze numeryczne od O do 9
AUX_A do AUX_Z
AUX_a do AUX_z
AUX OdoAUX 9
auxMainLoop
Przeznaczenie Okrela funkcj, ktra powinna zosta uyta do odwieenia zawartoci okna
OpenGL,
Plik nagwkowy <glaux.h>
Skadnia void auxMainLoop(AUXMAINPROC func);
Opis Ta funkcja jest uywana do okrelenia funkcji, ktra ma by wywoywana za
kadym razem, gdy okno OpenGL wymaga aktualizacji. Ta funkcja nie
zwraca sterowania a do momentu zamknicia okna OpenGL.
Parametry
func Ta funkcja ma nastpujcy prototyp
Zwracana warto void CALLBACK MainFunc(void);
Ta funkcja jest uywana do aktualizacji zawartoci okna i powinna zawiera
Przykad Patrz instrukcje rysunkowe.
take Brak.
Kady przykadowy program w tym rozdziale.
aux!dleFunc, auxReshapeFunc
84 Cz l Wprowadzenie do OpenGL
auxMouseFunc
Przeznaczenie Wie funkcje zwrotn z klikniciami przyciskw myszy
Plik nagwkowy <glaux.h>
Skadnia Opis void auxMouseFunc(int button, int mod, AUXMOUSEPROC func);
Suy do ustawienia funkcji/Mc jako funkcji wywoywanej w momencie
kliknicia lub zwolnienia przycisku myszy. Przycisk myszy jest okrelany
przez jedn z podanych niej wartoci. Tryb wywoywania okrela, czy
funkcja ma by wywoywana w momencie, gdy przycisk jest wciskany lub
zwalniany.
Parametry
button int: Przycisk, z ktrym ma by powizana funkcja zwrotna; moe to by
mod jedna z nastpujcych wartoci: AUX_LEFTBUTTON (lewy),
func AUX_MIDDLEBUTTON (rodkowy) lub AUX_RIGHTBUTTON (prawy).
int: Tryb wywoywania funkcji zwrotnej. Moe nim by
AUX_MOUSEDOWN (funkcja jest wywoywana w momencie klinicia
przyciskiem myszy) lub AUX_MOUSEUP (funkcja jest wywoywana w
momencie zwolnienia przycisku myszy).
Ta funkcja ma nastpujcy prototyp
void CALLBACK MouseFunc(AUX_EVENTREC *event); Struktura event
zawiera wsprzdne wskanika myszy w momencie wystpienia
zdarzenia.
typedef struct _AUX_EVENTREC {
GLint event;
GLINT data [ 4 ] ; }
AUX_EVENTREC;
event: GLint: Okrela zdarzenie, jakie nastpio (AUX_MOUSEUP lub
AUX_MOUSEDOWN)
data[4]\ GLint: zawiera dane specyficzne dla zdarzenia
data[AUX_MOUSEX] = pozioma wsprzdna wskanika myszy
data[AUX_MOUSEY] = pionowa wsprzdna wskanika myszy
data[MOUSE_STATUS] = przycisk myszy (z parametru button)
Brak.
Zwracana warto Program MBOUNCE na pytce CD-ROM, w folderze tego rozdziau.
Przykad Patrz auxKeyFunc
take
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 85
auxReshapeFunc
Przeznaczenie Ustanawia funkcj, ktra bdzie wywoywana w momencie, gdy zmieni si
rozmiar okna.
Plik nagwkowy <glaux.h>
Skadnia void auxReshapeFunc(AUXRESHAPEPROC func);
Opis Ta funkcja jest uywana do okrelenia funkcji, ktra ma by wywoywana za
kadym razem, gdy zmieni si rozmiar okna OpenGL. Zwykle w tej funkcji
Parametry s modyfikowane ustawienia widoku i bryy obcinania tak, aby prawidowo
func przeskalowa obraz.
auxSetOneColor
Przeznaczenie Plik Ustala pojedynczy kolor w indeksowanej palecie kolorw
nagwkowy <glaux.h>
Skadnia Opis void auxSetOneColor(int index, float red, float green, float blue);
Parametry Ta funkcja jest uywana w indeksowanych trybach kolorw. W takim trybie,
zamiast okrelania koloru za pomoc wartoci RGB, tworzona jest paleta
index kolorw. Kolory s przypisywane obiektom przez podanie indeksu w
red palecie. Ta funkcja ustala wartoci RGB koloru reprezentowanego przez
dany indeks palety.
green
blue Zwracana
int: Indeks w palecie kolorw.
warto
float: Czerwona skadowa danego koloru.
float: Zielona skadowa danego koloru.
float: Niebieska skadowa danego koloru.
Brak.
86_________________________________Cz l * Wprowadzenie do OpenGL
auxSolidBox________________________
Przeznaczenie Rysuje jednolity prostopadocian.
Plik nagwkowy <glaux.h>
Skadnia void auxSolidBox(GLdouble width, GLdouble height, GLdouble depth);
Opis Rysuje jednolity prostopadocian ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Alternatywn form tej funkcji jest
auxSolidCube. Uywana gwnie do demonstracji.
Parametry
width GLdouble: Szeroko prostopadocianu.
height GLdouble: Wysoko prostopadocianu.
depth GLdouble: Gboko prostopadocianu.
Zwracana warto Brak.
Przykad Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
Patrz take auxWireBox, auxSolidCube
auxSolidCone_______________________
Przeznaczenie Rysuje jednolity stoek.
Plik nagwkowy <glaux.h>
Skadnia void auxSolidCone(GLdouble radius, GLdouble height);
Opis Rysuje jednolity stoek ze rodkiem w centrum ukadu wsprzdnych
(O, O, 0). Uywana gwnie do demonstracji.
Parametry
radius GLdouble: Promie podstawy stoka.
height GLdouble: Wysoko stoka.
Zwracana warto Brak.
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 87
auxSolidCube
Przeznaczenie Plik Rysuje jednolity szecian.
nagwkowy <glaux.h>
Skadnia Opis void auxSolidCube(GLdouble width);
Rysuje jednolity szecian ze rodkiem w centrum ukadu wsprzdnych
(O, O, 0). Alternatywna forma funkcji auxSolidBox Uywana gwnie do
Parametry demonstracji.
width
Zwracana warto GLdouble: Dugo krawdzi szecianu.
Przykad Brak.
Patrz take Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze
dotyczcym tego rozdziau. Umieszczony tam program zawiera przykady
tworzenia wszystkich predefmiowanych jednolitych obiektw z biblioteki
AUX.
auxWireCube, auxSolidBox
AuxSolidCylinder
Przeznaczenie Plik Rysuje jednolity cylinder.
nagwkowy <glaux.h>
Skadnia Opis void auxSolidCylinder(GLdouble radius, GLdouble height);
Rysuje jednolity cylinder ze rodkiem w centrum ukadu wsprzdnych (O,
Parametry O, 0). Uywana gwnie do demonstracji.
radius
height GLdouble: Promie podstawy cylindra.
Zwracana warto GLdouble: Wysoko cylindra. Brak.
Przykad Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
wszystkich predefmiowanych jednolitych obiektw.z biblioteki AUX.
Patrz take auxWireCylinder
88 Cz l * Wprowadzenie do OpenGL
auxSolidDodecahedron
Przeznaczenie Plik Rysuje jednolity dwunastocian.
nagwkowy <glaux.h>
Skadnia Opis void auxSolidDodecahedron(GLdouble radius);
Rysuje jednolity dwunastocian foremny ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). cianki dwunastocianu s picioktami foremnymi.
Parametry Uywana gwnie do demonstracji.
radius
Zwracana warto GLdouble: Promie dwunastocianu.
Przykad Brak.
Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Patrz take wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxWireDodecahedron
auxSolidlcosahedron
Przeznaczenie Plik Rysuje jednolity dwudziestocian.
nagwkowy <glaux.h>
Skadnia Opis void auxSolid!cosahedron(GLdouble radius);
Rysuje jednolity dwudziestocian foremny ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). cianki dwudziestocianu s trjktami
Parametry rwnobocznymi. Uywana gwnie do demonstracji.
radius
Zwracana warto GLdouble: Promie dwudziestocianu.
Przykad Brak.
Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Patrz take wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxWire!cosahedron
auxSolidOctahedron
Przeznaczenie Rysuje jednolity omiocian.
Plik nagwkowy <glaux.h>
Skadnia void auxSolidOctahedron(GLdouble radius);
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 89
auxSolidSphere
Przeznaczenie Rysuje jednolit kul.
Plik <glaux.h>
naglwkowy void auxSolidSphere(GLdouble radius);
Skadnia Opis Rysuje jednolit kul ze rodkiem w centrum ukadu wsprzdnych
(O, O, 0). Uywana gwnie do demonstracji.
Parametry
radius GLdouble: Promie kuli.
Zwracana Brak.
warto Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Przykad wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxWireSphere
auxSolidTeapot
Przeznaczenie Rysuje jednolity imbryk do herbaty.
Plik <glaux.h>
nagwkowy void auxSolidTeapot(GLdouble radius);
Skadnia Opis Rysuje jednolity imbryk do herbaty ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Uywana gwnie demonstracji.
Parametry
radius Gldouble: Promie imbryka (w przyblieniu).
Zwracana Brak.
90 Cz l * Wprowadzenie do OpenGL
auxSolidTetrahedron
Przeznaczenie Plik Rysuje jednolity czworocian foremny.
nagwkowy <glaux.h>
Skadnia Opis void auxSolidTetrahedron(GLdouble radius);
Rysuje jednolity czworocian foremny ze rodkiem w ukadu
wsprzdnych (O, O, 0). cianki czworocianu s trjktami
Parametry rwnobocznymi. Uywana gwnie do demonstracji.
radius
Zwracana warto GLdouble: Promie omiocianu.
Przykad Brak.
Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia wszystkich
Patrz take predefiniowanych jednolitych obiektw z biblioteki AUX.
auxWireTetrahedron
auxSolidTorus
Przeznaczenie Rysuje jednolity torus (dtk).
Plik nagwkowy <glaux.h>
Skadnia Opis void auxSolidTorus(GLdouble innerRadius, GLdouble outerRadius);
Rysuje jednolity torus ze rodkiem w centrum ukadu wsprzdnych (O, O, 0).
Torus ma ksztat dtki. Promie wewntrzny to promie dtki, za promie
zewntrzny to promie koa. Uywana gwnie do demonstracji.
Parametry
GLdouble: Wewntrzny promie torusa.
innerRadius
GLdouble: Zewntrzny promie torusa. Brak.
outerRadius
Uzupeniajcy przykad AUXSOLID na pytce CD-ROM, w folderze tego
Zwracana warto rozdziau. Umieszczony tam program zawiera przykady tworzenia wszystkich
Przykad
predefiniowanych jednolitych obiektw z biblioteki AUX.
auxWireTorus
Patrz take
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 91
auxSwapBuffers
Przeznaczenie Przerzuca rysunek z niewidocznego bufora do okna podczas rysowania z
podwjnym buforowaniem.
Plik <glaux.h>
nagwkowy void auxSwapBuffers(void);
Skadnia Ta funkcja jest uywana przy rysowaniu i animacji z wykorzystaniem
podwjnego buforowania. Wywoanie funkcji powoduje przerzucenie
Opis sceny tworzonej w niewidocznym buforze do okna.
Brak.
Zwracana Przykad BOUNCE2 w tym rozdziale.
warto aux!nitDisplayMode, aux!dleFunc
auxWireBox
Przeznaczenie Rysuje szkieletowy prostopadocian.
Plik <glaux.h>
nagwkowy void auxWireBox(GLdouble width, GLdouble height, GLdouble depth);
Skadnia Opis Rysuje szkieletowy prostopadocian ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Alternatywn form tej funkcji jest auxWireCube.
Uywana gwnie do demonstracji.
Parametry
width GLdouble: Szeroko prostopadocianu.
height GLdouble: Wysoko prostopadocianu.
depth GLdouble: Gboko prostopadocianu.
Zwracana Brak.
warto Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Przykad wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxSolidBox, auxWireCube
auxWireCone
Przeznaczenie Rysuje szkieletowy stoek.
Plik nagwkowy <glaux.h>
Skadnia void auxWireCone(GLdouble radius, GLdouble height);
92 Cz l * Wprowadzenie do OpenGL
auxWireCube
Przeznaczenie Rysuje szkieletowy szecian.
Plik nagwkowy <glaux.h>
Skadnia void auxWireCube(GLdouble width);
Opis Rysuje szkieletowy szecian ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Alternatywna forma funkcji auxWireBox
Parametry
Uywana gwnie do demonstracji.
width
Zwracana warto
GLdouble: Dugo krawdzi szecianu.
Przykad
Brak.
Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Patrz take
wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxSolidCube, auxWireBox
auxWireCylinder
Przeznaczenie Rysuje szkieletowy cylinder.
Plik nagwkowy <glaux.h>
Skadnia Opis void auxWireCylinder(GLdouble radius, GLdouble height);
Rysuje szkieletowy cylinder ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Uywana gwnie do demonstracji.
Rozdzia 3. + Nauka OpenGL z uyciem biblioteki AUX 93
Parametry
radius GLdouble: Promie podstawy cylindra.
height GLdouble: Wysoko cylindra. Brak.
Zwracana warto Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Przykad wszystkich predefmiowanych jednolitych obiektw z biblioteki AUX.
auxSolidCylinder
Patrz take
auxWireDodecahedron
Przeznaczenie Plik Rysuje szkieletowy dwunastocian.
nagwkowy <glaux.h>
Skadnia Opis void auxWireDodecahedron(GLdouble radius);
Rysuje szkieletowy dwunastocian foremny ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). cianki dwunastocianu s picioktami
Parametry foremnymi. Uywana gwnie do demonstracji.
radius
Zwracana warto GLdouble: Promie dwunastocianu.
Przykad Brak.
Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Patrz take wszystkich predefmiowanych jednolitych obiektw z biblioteki AUX.
auxSolidDodecahedron
auxWirelcosahedron
Przeznaczenie Plik Rysuje szkieletowy dwudziestocian.
nagwkowy <glaux.h>
Skadnia Opis void auxWire!cosahedron(GLdouble radius);
Rysuje szkieletowy dwudziestocian foremny ze rodkiem w centrum
ukadu wsprzdnych (O, O, 0). cianki dwudziestocianu s trjktami
Parametry rwnobocznymi. Uywana gwnie do demonstracji.
radius Zwracana
warto GLdouble: Promie dwudziestocianu.
Brak.
94 Cz l * Wprowadzenie do
OpenGL
auxWireOctahedron
Przeznaczenie Rysuje szkieletowy omiocian.
Plik <glaux.h>
nagwkowy void auxWireOctahedron(GLdouble radius);
Skadnia Opis Rysuje szkieletowy omiocian foremny ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). cianki omiocianu s trjktami rwnobocznymi.
Uywana gwnie do demonstracji.
Parametry GLdouble: Promie omiocianu. Brak.
radius Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
Zwracana warto rozdziau. Umieszczony tam program zawiera przykady tworzenia wszystkich
predefiniowanych jednolitych obiektw z biblioteki AUX.
Przykad
auxSolidOctahedron
auxWireTeapot
Przeznaczenie Rysuje szkieletowy imbryk do herbaty.
Plik <glaux.h>
nagwkowy void auxWireTeapot(GLdouble radius);
Skadnia Opis Rysuje szkieletowy imbryk do herbaty ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). Uywana gwnie do demonstracji.
Parametry
radius GLdouble: Promie imbryka (w przyblieniu).
Zwracana Brak.
warto Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Przykad wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxSolidTeapot
auxWireTetrahedron
Przeznaczenie Rysuje szkieletowy czworocian foremny.
Plik <glaux.h>
nagwkowy void auxWireTetrahedron(GLdouble radius);
Skadnia Opis Rysuje szkieletowy czworocian foremny ze rodkiem w centrum ukadu
wsprzdnych (O, O, 0). cianki czworocianu s trjktami
rwnobocznymi. Uywana gwnie do demonstracji.
Parametry
radius GLdouble: Promie omiocianu.
Zwracana Brak.
warto Uzupeniajcy przykad AUXWIRE na pytce CD-ROM, w folderze tego
rozdziau. Umieszczony tam program zawiera przykady tworzenia
Przykad wszystkich predefiniowanych jednolitych obiektw z biblioteki AUX.
auxSolidTetrahedron
auxWireTorus
Przeznaczenie Rysuje szkieletowy torus (dtk).
Plik nagwkowy <glaux.h>
Skadnia void auxWireTorus(GLdouble innerRadius, GLdouble outerRadius);
96 Cz l * Wprowadzenie do OpenGL
glCIearColor
Przeznaczenie Plik Ustala wartoci barw skadowych i kanau alfa dla buforw kolorw.
nagwkowy
Skadnia void glClearColor(GLclampf red, GLclampf green, GLclampf blue,
GLclampf alpha);
Opis Ustala wartoci uywane podczas czyszczenia buforw dla barw czerwonej,
zielonej i niebieskiej oraz dla skadnika alfa. Podane wartoci s obcinane
do przedziau [O.Of, 1.0].
Parametry
red GLclampf: Czerwony skadnik koloru wypenienia.
green GLclampf: Zielony skadnik koloru wypenienia.
blue GLclampf: Niebieski skadnik koloru wypenienia.
alpha GLclampf: Skadnik alfa koloru wypenienia.
Zwracana warto Brak.
Przykad Przykad SHORTEST w tym rozdziale.
glFIush
Przeznaczenie Wykonuje funkcje i polecenia OpenGL oczekujce w kolejce.
Plik nagwkowy
Skadnia void glFlush(void);
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX 97
glOrtho
Przeznaczenie Ustala lub modyfikuje zakres bryy obcinania..
Plik
nagwkowy void glOrtho(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble near, GLdouble far);
Skadnia
Ta funkcja okrela rwnoleg bry obcinania. W rzutowaniu tego typu
obiekty znajdujce si dalej od obserwatora nie wydaj si mniejsze ni
obiekty umieszczone bliej (w przeciwiestwie do rzutowania
perspektywicznego). Wyobra sobie bry obcinania umieszczon w
przestrzeni kartezjaskiej; w takim przypadku lewa i prawa paszczyzna
wyznaczaj minimaln i maksymaln warto osi x, paszczyzny dolna i
grna wyznaczaj minimaln i maksymaln warto osi y, za paszczyzny
blisza i dalsza wyznaczaj minimaln i maksymaln warto osi z.
Parametry
left GLdouble: Wsprzdna lewej paszczyzny obcinania.
right GLdouble: Wsprzdna prawej paszczyzny obcinania.
bottom GLdouble: Wsprzdna dolnej paszczyzny obcinania.
top GLdouble: Wsprzdna grnej paszczyzny obcinania.
near GLdouble: Wsprzdna bliszej paszczyzny obcinania.
far GLdouble: Wsprzdna dalszej paszczyzny obcinania.
Zwracana Brak.
warto Przykad SCAL w tym rozdziale.
Przykad Patrz glYiewport
giyiewport
Przeznaczenie Ustala obszar okna (widok), przeznaczony do wykorzystania przez
OpenGL.
Plik nagwkowy
98 Cz l * Wprowadzenie do OpenGL
gIRect
Przeznaczenie Rysuje paski prostokt.
Plik nagwkowy <gl.h>
Odmiany void gIRectd(GLdouble xl, GLdouble yl, GLdouble x2, GLdouble y2);
void glRectf(GLfloat xl, GLfloat yl, GLfloat x2, GLfloat y2);
void glRecti(GLint xl, GLint yl, GLint x2, GLint y2);
void glRects(GLshort xl, GLshort y l, GLshort x2, GLshort y2);
void glRectdv(const GLdouble *vl, const GLdouble *v2);
void glRectfv(const GLfloat *vl, const GLfloat *v2);
void glRectiv(const GLint *vl, const GLint *v2);
void glRectsv(const GLshort *vl, const GLshort *v2);
Opis Ta funkcja stanowi efektywn metod tworzenia prostokta przez podanie
wsprzdnych dwch przeciwlegych wierzchokw. Prostokt jest
rysowany na paszczynie xy o wsprzdnej z = 0.
Parametry
xl, y l Okrelaj lewy grny wierzchoek prostokta.
x2,y2 Okrelaj prawy dolny wierzchoek prostokta.
*vl Tablica dwch wartoci okrelajcych lewy grny wierzchoek
prostokta. Moe by opisany take jako v l [2].
Rozdzia 3. * Nauka OpenGL z uyciem biblioteki AUX_______________________99
A do teraz, do lektury tej ksiki nie bya wymagana adna wiedza na temat trjwy-
miarowej grafiki, wymagana bya jedynie podstawowa umiejtno programowania w
C. Jednak od tego momentu zakadamy, e znasz przynajmniej podstawy pisania pro-
gramw dla Windows. (W przeciwnym wypadku musielibymy napisa ksik dwa
razy grubsz, ktrej wiksza cz dotyczyaby zagadnie programowania Windows ni
programowania w OpenGL). Jeli jeste nowicjuszem w Windows lub przywyke do
korzystania z ktrego z pakietw Application Framework (na przykad MFC czy
OWL) i nie znasz si na procedurach okienkowych, przekazywaniu komunikatw itd.,
przed zagbieniem si w dalszy tekst powiniene zapozna si z ktr z pozycji wy-
mienionych w dodatku B, dotyczcym dalszej lektury zwizanej z tematem programo-
wania w OpenGL.
Rysunek 4.1.
Odpowiednik programu friendly. c z rozdziau 3.,
napisany bez uycia OpenGL
Same pdzle s tworzone w funkcji WinMain, przy uyciu makra RGB w celu utworzenia
jednolitych pdzli, niebieskiego i czerwonego.
// Utworzenie niebieskiego i czerwonego pdzla do wypeniania //
i rysowania
// Czerwony, zielony, niebieski
hBlueBrush = CreateSolidBrush(RGB( O, O, 255));
hRedBrush = CreateSolidBrush(RGB( 255, O, 0));
// Rozpoczcie rysowania
BeginPaint (hWnd, &ps) ;
// Wybranie czerwonego pdzla
hOldBrush = SelectObject (ps .hdc,hRedBrush) ;
Zanim wycigniesz wniosek, e OpenGL dziaa tak samo, przypomnij sobie, e GDI jest
mechanizmem specyficznym dla Windows. Inne rodowiska nie posiadaj kontekstw
urzdze, uchwytw okien itp. Z drugiej strony, OpenGL zosta zaprojektowany tak, aby
by cakowicie przenony pomidzy rnymi rodowiskami i platformami
sprztowymi. Dodanie kontekstu urzdzenia do funkcji OpenGL sprawioby, e kod
OpenGL staby si bezuyteczny w kadym rodowisku innym ni Windows.
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle 105
Gdy kontekst renderowania jest tworzony dla danego kontekstu urzdzenia, mwi si, e
jest odpowiedni do rysowania w tym kontekcie urzdzenia. Gdy kontekst renderowania
staje si biecy (w wyniku wywoania funkcji wglMakeCurrent()), nie jest konieczne
podawanie kontekstu urzdzenia uytego przy tworzeniu tego kontekstu
renderowania. Jednak wskazany przy tym kontekst urzdzenia musi mie t sam chara-
kterystyk, co kontekst urzdzenia wskazany podczas tworzenia kontekstu renderowania.
Musz zgadza si liczba kolorw, definicje buforw itd., czyli te informacje, ktre okrela
si mianem formatu pikseli.
urzdzenia (przy uyciu stylu okna WS_OWNDC) i pozostawaniu przy nim przez cay
czas ycia okna. Co wicej, poniewa wikszo naszych przykadw bdzie animowana,
moemy unikn cigych (i kosztownych) wywoa funkcji GetDC() za kadym razem,
gdy chcemy kontekst renderowania uczyni biecym. Kolejna oszczdno czasu polega na
jednokrotnym uczynieniu kontekstu renderowania biecym i pozostawieniu go biecym
przez cay czas dziaania programu. Jeli tylko jedno okno w wtku korzysta z OpenGL,
nigdy nie spowoduje to problemw, zaoszczdzi za nam koniecznoci regularnego
wywoywania funkcji wglMakeCurrent.
switch (message) {
case WM_CREATE:
hDC = GetDC(hWnd) ;
PostQuitMessage ( 0 ) ;
break;
Sztuczki programistyczne
W dalszym cigu, po narysowaniu sceny przez OpenGL, moesz
uywa do rysowania polece GDI. Wedug dokumentacji
Microsoftu, takie dziaanie jest w peni obsugiwane, z wyjtkiem
okien o podwjnym buforowaniu. Moesz jednak uywa
wywoa GDI take w oknach z podwjnym buforowaniem - jeli
tylko wywoujesz funkcje GDI ju po przerzuceniu buforw. W
rzeczywistoci nie s obsugiwane wywoania GDI dziaajce na
tylnym buforze podwjnie buforowanych okien. Najlepiej unika
takich wywoa, gdy gwnym przeznaczeniem podwjnego
buforowania jest zapobieganie migotaniu oraz pynna
aktualizacja ekranu.
Style okien
Aby OpenGL mg rysowa w oknie, okno musi zosta utworzone z ustawionymi stylami
WS_CLIPCHILDREN oraz WS_CLIPSIBLINGS, natomiast nie moe zawiera stylu
CS_PARENTDC. Powodem tego jest fakt, e kontekst renderowania nadaje si jedynie do rysowania
w oknach, dla ktrych zosta stworzony (okrelonych przez kontekst urzdzenia w funkcji
wglCreateContext) lub w oknach o dokadnie takim samym formacie pikseli. Style
WS_CLIPCHILDREN oraz WS_CLIPSIBLINGS zabezpieczaj funkcj rysunkow przed prb
aktualizacji wszelkich okien potomnych. Styl CS_PARENTDC (powodujcy, e okno dziedziczy
kontekst urzdzenia swojego okna nadrzdnego) jest niedozwolony, poniewa kontekst
renderowania moe by powizany z tylko jednym kontekstem urzdzenia i oknem. Jeli te style nie
zostan okrelone, nie bdziesz mg ustawi formatu pikseli okna - ostatniego szczegu, jakim
musimy si zaj przed przejciem do naszego pierwszego programu OpenGL w Windows.
Formaty pikseli
Rysowanie w oknie przez OpenGL wymaga take ustawienia formatu pikseli. Podobnie jak kontekst
renderowania, format pikseli nie jest w rzeczywistoci czci OpenGL ja-
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle_________________109
Listing 4.1. Funkcja ustalajca format pikseli dla danego kontekstu urzdzenia_______________
Tabela 4.1.
Pola struktury PKELFORMA TDSCRIPTOR uywane podczas dania formatu pikseli
Pole Opis
nSize Rozmiar struktury, ustawiany na sizeof(PIXELFORMATDESCRIPTOR)
nYersion Wersja tej struktury danych, ustawiana na l.
dwFlags Znaczniki okrelajce waciwoci bufora pikseli, ustawiane na
(PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL
PFD_DOUBLEBUFFER). Wskazuj one, e kontekst urzdzenia nie jest
kontekstem bitmapy (pamiciowym), do rysowania zostanie uyty OpenGL
oraz e okno powinno by podwjnie buforowane.
iPixelType Typ danych pikseli. Informuje OpenGL, aby uyo trybu RGBA lub
indeksowanego trybu kolorw. Aby uy trybu RGBA, uyj staej
PFD_TYPE_RGBA.
cColorBits Ilo bitw na kolor, w tym wypadku 24 bity. Jeli sprzt nie obsuguje 24-
bitowego
koloru, zostanie wybrana maksymalna obsugiwana ilo bitw na kolor.
cDepthBits Ilo bitw bufora gbokoci (z-bufora). Ustawiane na 32 dla maksymalnej
dokadnoci, jednak czsto wystarcza 16 bitw (zajrzy] do sekcji podrcznika).
iLayerType Rodzaj warstwy. W przypadku Microsoft Windows dozwolona jest
jedynie staa PFD MAIN PLANE.
GL Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle_________________111
Rysunek 4.3.
Odbijajcy si kwadrat w wersji dla Windows
wc.lpszMenuName = NULL;
wc.lpszClassName = IpszAppName;
// Wywietlenie okna
ShowWindow(hWnd,SW_SHOW);
UpdateWindow(hWnd);
// Przetwarzanie komunikatw a do momentu zakoczenia
// dziaania aplikacji
while( GetMessage(smsg, NULL, O, 0 ) )
{
TranslateMessage(smsgi;
DispatchMessage(imsg); }
return msg.wParam;
}
// Procedura okna, ktra obsuguje wszystkie komunikaty skierowane do
// tego okna
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message, WPARAM wParam, LPARAM
IParam) {
static HGLRC hRC; // Stay kontekst renderowania static
HDC hDC; // Prywatny kontekst urzdzenia GDI
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle_________________113
switch (message)
{
// Utworzenie okna, przygotowanie dla OpenGL
case WM_CREATE:
// Przechowanie kontekstu urzdzenia
hDC = GetDC(hWnd);
// Wybranie formatu pikseli
SetDCPixelFormat(hDC);
// Utworzenie kontekstu renderowania i uczynienie go
// biecym
hRC = wglCreateContext( h D C ) ;
wglMakeCurrent(hDC, hRC);
LION). Gdy funkcja WndProc otrzyma komunikat WM_TIMER, wykonywany jest poniszy
kod:
case WMJTIMER: {
IdleFunctionO ;
Wystpuje tu nowa funkcja GDI Windows, SwapBuffers. Ta funkcja peni t sam rol, co
auxSwapBuffers - w oknie z podwjnym buforowaniem przerzuca do okna zawarto
niewidocznego (tylnego) bufora. Jednym parametrem funkcji jest kontekst urzdzenia.
Zwr uwag, e ten kontekst urzdzenia musi posiada format pikseli z ustawionym
znacznikiem PFD_DOUBLEBUFFER; w przeciwnym razie dziaanie funkcji si nie
powiedzie.
I ju! W tym momencie posiadasz szkielet kodu, w ktry moesz wstawi wasn, dowoln
procedur renderujc OpenGL. Bdzie ona korzystaa z prawdziwego okna Windows,
z wszystkimi jego cechami (skalowaniem, przenoszeniem, zamykaniem itd.). Co wicej,
moesz oczywicie uy tego kodu do utworzenia okna OpenGL stanowicego cz
rozbudowanej aplikacji, zawierajcej inne okna, menu itd.
116 ____ ____ ____ ___ ____ Cz l Wprowadzenie do OpenGL
Podsumowanie
Po przeczytaniu tego rozdziau powiniene zdawa sobie spraw, o ilu uciliwych
szczegach nie musimy pamita korzystajc z biblioteki AUX. Poznae koncepcj
kontekstw renderowania, wprowadzon do Windows GDI po to, aby OpenGL wie-
dziao, w ktrym oknie ma wykonywa operacje graficzne. Wiesz ju, jak wybr i usta-
wienie formatu pikseli przygotowuje kontekst urzdzenia przed wykorzystaniem go do
stworzenia kontekstu renderowania. Oprcz tego dowiedziae si, na ktre komunikaty
okienkowe i w jaki sposb powinien odpowiada program OpenGL w Windows.
Podrcznik
ChoosePixel Format
Przeznaczenie Wybiera format pikseli najbardziej zbliony do formatu zadanego
w strukturze PIXELFORMATDESCRIPTOR, dostpny dla danego
kontekstu urzdzenia.
Plik nagwkowy <wingdi.h>
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle 117
DescribePixelFormat
Przeznaczenie Plik Zwraca szczegowe informacje o formacie pikseli.
nagwkowy <wingdi.h>
Skadnia int DescribePixelFormat(HDC hDC, int iPixelFormat, UINT nBytes,
LPPIXELFORMATDESCRIPTOR ppfd);
Opis Ta funkcja wypenia struktur PIXELFORMATDESCRIPTOR informacjami
o formacie pikseli okrelonym dla danego kontekstu urzdzenia. Zwraca
take maksymalny indeks formatu pikseli dla danego kontekstu urzdzenia.
Jeli ppfd ma warto NULL, funkcja i tak zwraca maksymalny numer
indeksu formatu pikseli dla danego kontekstu urzdzenia. Niektre pola
struktury PIXELFORMATDESCRIPTOR nie s obsugiwane w oglnej
implementacji OpenGL Microsoftu, mog jednak by obsugiwane przez
poszczeglnych producentw sprztu.
Parametry
hDC HDC: Uchwyt kontekstu urzdzenia zawierajcego formaty pikseli.
tPixelFormat int: Indeks formatu pikseli, o ktrym chcemy otrzyma informacje.
nBytes UINT: Rozmiar struktury wskazywanej przez ppfd. Jeli ten parametr ma
warto zero, dane nie bd kopiowane do bufora. Powinien by ustawiony
na sizeof(PIXELFORMATDESCRIPTOR).
ppfd LPPIXELFORMATDESCRIPTOR: Wskanik do struktury
PIXELFORMATDESCRIPTOR, ktra zostanie wypeniona
szczegowymi informacjami o danym formacie pikseli. Struktura
PIXELFORMATDESCRIPTOR jest zdefiniowana nastpujco:
typedef struct tagPIKELFORMATDESCRIPTOR { // pfd
WORD nSize; WORD nVersion; DWORD dwFlags; BYTE
iPixelType; BYTE cColorBits; BYTE cRedBits; BYTE
cRedShift; BYTE cGreenBits; BYTE cGreenShift;
Rozdzia 4. OpenGL for Windows: OpenGL + Win32 = Wiggle_________________119
// Czy ten format pikseli wymaga palety? Jeli nie, po prostu nie //
twrz palety i zwr warto NULL if(!(pfd.dwFlags i
PFD_NEED_PALETTE)) return NULL;
// Stworzenie palety
Tabela 4.2.
Znaczniki pola dwFlags struktury PIXELFORMATDESCR1PTOR
Znacznik Opis
Tabela 4.3.
Znaczniki pola iPixelType
Znacznik Opis
PFD_TYPE_RGBA Tryb koloru RGBA. Kolor kadego piksela jest okrelany przez
podanie skadowej czerwonej, zielonej, niebieskiej i alfa.
PFD_TYPE_COLORINDEX Indeksowany tryb koloru. Kolor kadego piksela jest okrelany
przez podanie indeksu w palecie (tablicy kolorw).
Tabela 4.4.
Znaczniki pola iLayerType
Znacznik Opis
PFD_MAIN_PLANE Warstwa jest gwnym planem.
PFD_O YERLA Y_PL ANE Warstwa j est nakadk.
PFD_UNDERLAY_PLANE Warstwa jest podkadk.
GetPixel Format______________________
Przeznaczenie Zwraca indeks formatu pikseli aktualnie wybranego w danym kontekcie
urzdzenia.
Plik nagwkowy <wingdi.h>
Skadnia int GetPixelFormat(HDC hDC);
Opis Ta funkcja zwraca format pikseli wybrany w danym kontekcie
urzdzenia. Zwracana warto jest indeksem formatu pikseli,
liczonym od l.
Parametry
hDC HDC: Uchwyt kontekstu urzdzenia.
Zwracana warto Indeks formatu pikseli wybranego w danym kontekcie urzdzenia lub warto
zero w przypadku bdu.
Przykad Spjrz na przykad dla funkcji DescribePixelFormat.
Patrz take DescribePixelFormat, ChoosePixelFormat, SetPixelFormat
Opis Ta ftmkcja ustawia format pikseli dla danego kontekstu urzdzenia. Gdy
format pikseli zostanie ustawiony dla danego kontekstu urzdzenia, nie
mona go ju modyfikowa, Ta funkcja musi by wywoana przed
utworzeniem kontekstu renderowania OpenGL dla tego urzdzenia.
Parametry
hDC HDC: Uchwyt kontekstu urzdzenia, dla ktrego chcemy ustawi format
pikseli.
nPixelFormat int: Indeks formatu pikseli do ustawienia.
PPfd LPPDCELFORMATDESCRIPTOR: Wskanik do struktury
PIXELFORMATDESCRIPTOR, zawierajcej deskryptor logicznego formatu
Zwracana pikseli. Ta struktura jest uywana wewntrznie do zapisu specyfikacji
warto logicznego formatu pikseli. Zawarto przekazywanej struktury nie wpywa
na dziaanie operacji.
Przykad TRUE, jeli podany format pikseli zosta ustawiony dla danego kontekstu
Patrz take urzdzenia, a FALSE w przypadku bdu.
Spjrz na przykad do funkcji ChoosePixelFormat.
DescribePixelFormat, GetPixelFormat, SetPixelFormat
SwapBuffers
Przeznaczenie Szybko kopiuje zawarto tylnego bufora do przedniego bufora
(widocznej powierzchni okna).
Plik <wingdi.h>
nagwkowy BOOL SwapBuffers(HDC hDC);
Skadnia Gdy jest wybrane podwjne buforowanie, okno posiada przedni bufor
(widoczny) oraz tylny bufor (niewidoczny). Polecenia rysunkowe s
wykonywane w tylnym buforze. Ta funkcja suy do skopiowania
zawartoci niewidocznego tylnego bufora do wywietlanego przedniego
bufora, w celu uzyskania pynnego rysowania scenki lub pynnej animacji.
Zwr uwag, e zawartoci bufora nie s wymieniane. Po zakoczeniu tej
operacji zawarto tylnego bufora jest niezdefiniowana.
Parametr
y hDC HDC: Uchwyt kontekstu urzdzenia okna, ktre posiada przedni i tylny
bufor.
Zwracana warto TRUE, jeli bufory zostay przerzucone.
Przykad Poniszy przykad przedstawia typowy kod procedury obsugi komunikatu
WM_PAINT. Wywoujemy w nim kod renderowania i jeli pracujemy z
podwjnym buforowaniem, przerzucamy zawarto tylnego bufora. Ten kod
wystpuje take w przykadzie GLRECT w tym rozdziale.
124 Cz l Wprowadzenie do OpenGL
wglCreateContext
Przeznaczenie Tworzy kontekst renderowania odpowiedni do rysowania w podanym
kontekcie urzdzenia.
Plik <wingdi.h>
nagwkowy HGLRC wglCreateContext(HDC hDC);
Skadnia Tworzy kontekst renderowania OpenGL odpowiedni dla danego kontekstu
urzdzenia Windows. Format pikseli kontekstu urzdzenia powinien zosta
wybrany przed tworzeniem kontekstu renderowania. Gdy aplikacja
zakoczy korzystanie z kontekstu renderowania, powinna wywoa funkcj
wglDeleteContext.
Parametry
hDC HDC: Uchwyt kontekstu urzdzenia okna, w ktrym odbdzie si
rysowanie poprzez nowy kontekst renderowania.
Zwracana Uchwyt nowego kontekstu renderowania lub warto NULL w przypadku
bdu.
warto Poniszy przykad przedstawia pocztek procedury obsugi komunikatu
WM_CREATE. Pobieramy w nim kontekst urzdzenia dla biecego okna,
wybieramy format pikseli, a nastpnie tworzymy kontekst renderowania i
czynimy go biecym.
case WM_CREATE:
// Przechowanie kontekstu urzdzenia
hDC = GetDC(hWnd);
wglDeleteContext
Przeznaczenie Plik Usuwa niepotrzebny ju kontekst renderowania.
nagwkowy <wingdi.h>
Skadnia Opis BOOL wglDeleteContext(HGLRC hglrc);
Usuwa kontekst renderowania OpenGL. Zwalniana jest pami i zasoby
Parametry zajmowane przez ten kontekst.
hglrc Zwracana
warto HGLRC: Uchwyt kontekstu renderowania, ktry ma zosta usunity.
TRUE, jeli kontekst renderowania zosta usunity, lub FALSE, jeli wystpi
bd. Bd wystpuje na przykad wtedy, gdy w jednym wtku prbujemy
Przykad usun biecy kontekst renderowania innego wtku.
Poniszy przykad przedstawia pocztek procedury obsugi komunikatu
WM_DESTROY. Zakadajc, e kontekst renderowania zosta utworzony w
momencie tworzenia okna, moemy w tym miejscu usun ten kontekst.
Zanim usuniesz kontekst, musisz uczyni go niebiecym.
case WM_DESTROY:
// Odoenie biecego kontekstu renderowania // i
usunicie go wglMakeCurrent( h D C , NULL);
wglDeleteContext(hRC);
wglGetCurrentContext
Przeznaczenie Plik Zwraca uchwyt biecego kontekstu renderowania nalecego do wtku.
nagwkowy <wingdi.h>
Skadnia Opis HGLRC wglGetCurrentContext(void);
Kady wtek aplikacji moe mie wasny biecy kontekst renderowania. Ta
funkcja moe zosta uyta do sprawdzenia, ktry kontekst renderowania jest
Zwracana warto kontekstem biecym dla wtku.
Jeli wtek posiada biecy kontekst renderowania, funkcja zwraca uchwyt
tego kontekstu. W przeciwnym wypadku zwraca warto NULL.
126 Cz l Wprowadzenie do OpenGL
wglGetCurrentDC
Przeznaczenie Zwraca uchwyt kontekstu urzdzenia powizanego z biecym
kontekstem renderowania OpenGL.
Plik nagwkowy <wingdi.h>
Skadnia HGLRC wglGetCurrentDC(void);
Opis Ta funkcja jest uywana do pobrania kontekstu uchwytu urzdzenia okna, z
Zwracana warto ktrym powizany jest biecy kontekst renderowania OpenGL. Zwykle
Przykad stosuje si j w celu poczenia rysunku OpenGL z rysunkiem tworzonym
Patrz take przy pomocy GDI.
Jeli wtek posiada biecy kontekst renderowania, funkcja zwraca uchwyt
kontekstu urzdzenia powizanego z tym kontekstem renderowania. W
przeciwnym wypadku zwraca warto NULL.
Zajrzyj do przykadowego programu GLTHREAD na pytce CD-ROM, w
folderze tego rozdziau.
wglGetCurrentContext
wglGetProcAddress
Przeznaczenie Zwraca adres funkcji rozszerzenia OpenGL, ktrej mona uy w danym
kontekcie renderowania.
Plik nagwkowy <wingdi.h>
Skadnia PROC wglGetProcAddress(LPCSTR IpszProc);
Opis Funkcje rozszerze to funkcje, ktre albo nie stanowijeszcze standardu
OpenGL, albo zostay wprowadzone do danej implementacji OpenGL, zwykle
w celu uzupenienia tej biblioteki o elementy specyficzne dla danej platformy.
Wiele rozszerze jest obsugiwanych w wicej ni jednej implementacji. Aby
uy tych funkcji, musisz wywoa funkcj wglGetProcAddress podajc
dokadn nazw funkcji rozszerzenia. W ten sposb moesz take sprawdzi
obecno danego rozszerzenia. Otrzymany adres funkcji moe by rny dla
rnych formatw pikseli, wic nie przechowuj go i nie prbuj uywa z
rnymi kontekstami renderowania, chyba e bdziesz pewien, i ich formaty
pikseli s identyczne. Moesz wywoa funkcj glString(GL_EXTENSION) w
celu otrzymania oddzielonego spacjami acucha zawierajcego wszelkie
dostpne rozszerzenia (szczegy znajdziesz w rozdziale 5).
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle 127
Parametry
IpszProc LPCSTR: Nazwa funkcji rozszerzenia. Wielko liter i nazwa musz
dokadnie odpowiada wielkoci liter i nazwie funkcji rozszerzenia.
Zwracana warto Jeli funkcja rozszerzenia nie istnieje, zwracana jest warto NULL, w
przeciwnym wypadku zwracany jest adres funkcji rozszerzenia.
Przykad Poniszy przykad przedstawia sposb pobrania adresu specyficznej dla
Windows funkcji rozszerzenia glAddSwapHintRectWIN. To rozszerzenie
umoliwia przyspieszenie przerzucania buforw przez poinformowanie
OpenGL, e tylko okrelone regiony okna wymagaj odwieenia.
// Sprawdzenie, czy dane rozszerzenie jest obsugiwane
char *szBuffer;
szBuffer = (char*)glString(GL_EXTENSION);
// Wywoaj t funkcje
pSwapHint(40.O f , 40.O f , 50.Of, 50.2 f ) ; )
else (
// Jeli nie jest obsugiwana, obsu to
// w inny sposb...
wglMakeCurrent
Przeznaczenie Biecy kontekst renderowania OpenGL czyni biecym dla danego
wtku i wie go z podanym kontekstem urzdzenia.
Plik <wingdi.h>
nagwkowy BOOL wglMakeCurrent(HDC hDC, HGLRC hglrc);
Skadnia Ta funkcja czyni podany kontekst renderowania biecym kontekstem
renderowania dla aktualnego wtku. Kontekst renderowania jest wizany ze
wskazanym kontekstem urzdzenia Windows. Kontekst urzdzenia nie musi
by kontekstem uytym w wywoaniu funkcji wglCreateContext przy
tworzeniu kontekstu renderowania, jednak jego format pikseli musi by
identyczny z formatem pikseli tamtego kontekstu urzdzenia, za oba
konteksty urzdze musz odnosi si do tego samego urzdzenia
fizycznego. Przed wybraniem nowego kontekstu renderowania, wszelkie
oczekujce w kolejce polecenia graficzne zostan zrzucone do poprzedniego
kontekstu renderowania. Gdy jako uchwyt kontekstu
128 Cz l * Wprowadzenie do OpenGL
wglShareLists
Przeznaczenie Umoliwia kilku kontekstom korzystanie ze wsplnych list wywietlania.
Plik nagwkowy <wingdi.h>
Skadnia Opis BOOL wglShareLists(HGLRC hRCl, HGLRC hRC2);
Lista wywietlania to lista prekompilowanych" polece i funkcji OpenGL
(patrz rozdzia 10). Dla kadego kontekstu renderowania alokowana jest
pami na jego listy wywietlania. Gdy lista wywietlania zostanie
utworzona w ramach danego kontekstu renderowania, tylko ten kontekst ma
dostp do jej pamici. Ta funkcja umoliwia kilku kontekstom renderowania
dostp do wsplnej pamici list wywietlania. Jest to szczeglnie uyteczne
wtedy, gdy w kilku wtkach lub kontekstach renderowania korzysta si z
duych list wywietlania, gdy daje znaczne oszczdnoci pamici. Ze
wsplnej pamici list wywietlania moe korzysta dowolna liczba
kontekstw renderowania; pami nie zostanie zwolniona a do momentu
usunicia ostatniego kontekstu renderowania z niej korzystajcego. Podczas
uywania wsplnej pamici list wywietlania naley synchronizowa
tworzenie i wykorzystywania list wywietlania.
Parametry
hRCl HGLRC: Okrela kontekst renderowania, z ktrym bdzie dzielona
pami list wywietlania.
hRC2 HGLRC: Okrela kontekst renderowania, ktry bdzie dzieli pami list
wywietlania z kontekstem hRCl. A do momentu wywoania tej funkcji nie
naley tworzy adnych list wywietlania dla kontekstu hRC2.
Zwracana warto TRUE w przypadku powodzenia, a FALSE w przypadku bdu.
do Opendtozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle 129
16
bdzie Przykad Zajrzyj do kartoteki symulacji czogu/robota (\TANK) na pytce CD-ROM,
Patrz take wewntrz foldera rozdziau 10. Ten program korzysta z kilku okien w celu
cym stworzenia jednoczenie kilku widokw tej samej sceny. Aby zaoszczdzi
pami, wszystkie konteksty renderowania tych okien korzystaj ze wsplnej
pamici list wywietlania.
gllsList, glNewList, glCallLists, glListBase, glDeleteLists, glEndList,
glGenLists
wglUseFontBitmaps
Przeznaczenie Tworzy zestaw list wywietlania bitmap dla aktualnie wybranej czcionki GDI.
<wingdi.h>
Plik nagwkowy
BOOL wglUseFontBitmaps(HDC hDC, DWORD dwFirst, DWORD
Skadnia dwCount, DWORD dwListBase);
Ta funkcja pobiera czcionk aktualnie wybran w kontekcie urzdzenia
Opis hDC i tworzy listy wywietlania bitmap dla dwCount znakw, poczynajc od
dwFirst. Listy wywietlania s tworzone w biecym kontekcie
renderowania i s identyfikowane przez numery rozpoczynajce si od
numeru dwListBase. Zwykle uywa si tej funkcji do rysowania tekstu w
podwjnie buforowanych scenach OpenGL, gdy Windows GDI nie dziaa w
trybie podwjnego buforowania. Ta funkcja jest uywana take do
nadawania etykietek obiektom OpenGL na ekranie.
HDC: Kontekst urzdzenia Windows, z ktrego pobierana jest definicja
Parametry czcionki. Uywana czcionka moe zosta zmieniona przez utworzenie
hDC nowej czcionki i wybranie jej w tym kontekcie urzdzenia.
DWORD: Warto ASCII pierwszego znaku czcionki, uywanej do
budowania list wywietlania.
dwFirst DWORD: Liczba tworzonych bitmap znakw, poczwszy od znaku
dwFirst.
dwCount DWORD: Warto bazowa identyfikatorw list wywietlania; zostanie
nadana licie wywietlania dla pierwszego znaku.
dwListBase TRUE jeli listy wywietlania mog zosta utworzone; FALSE w
przeciwnym wypadku.
Zwracana warto Poniszy kod demonstruje tworzenie zestawu list wywietlania dla
zestawu znakw ASCII. Ten zestaw list jest nastpnie uywany do
Przykad wypisania tekstu OpenGL" w biecej pozycji rastra.
//Utworzenie sylwetek znakw na podstawie czcionki //
wybran w kontekcie urzdzenia
130 Cz l * Wprowadzenie do OpenGL
// Wyrysowanie napisu
glListBase(1000); glPushMatrix();
glCallLists ( 3 , GL_UNSIGNED__BYTE,
glPopMatrix(); "OpenGL") ,
WglUseFontOutlines
Przeznaczenie Tworzy zestaw list wywietlania trjwymiarowych znakw dla aktualnie
wybranej czcionki GDI.
Plik nagwkowy <wingdi.h>
Skadnia BOOL wglUseFontOutlines(HDC hDC, DWORD dwFirst, DWORD
dwCount, DWORD dwListBase, FLOAT deviation, FLOAT extrusion, int
format, LPGLYPHMETRICSFLOAT Ipgmf);
Opis Ta funkcja pobiera czcionk TrueType aktualnie wybran w kontekcie
urzdzenia hDC i tworzy listy wywietlania trjwymiarowych sylwetek dla
dwCount znakw, poczynajc od znaku dwFirst. Listy wywietlania s
tworzone w biecym kontekcie renderowania i s identyfikowane przez
numery rozpoczynajce si od numeru dwListBase. Sylwetka moe by
tworzona z segmentw linii lub wieloktw; decyduje o tym parametr format.
Komrka znaku uywana dla czcionki ma szeroko i wysoko jednej
jednostki w poziomie i w pionie. Parametr extrusion wyznacza grubo
czcionki w ujemnym kierunku osi z. Parametr deviation, o wartoci O lub
wikszej, okrela odchylenie ukw od oryginalnych postaci znakw czcionki.
Ta funkcja dziaa wycznie z czcionkami typu TrueType. Dodatkowe dane
dotyczce znakw s przekazywane w tablicy /pgw/struktur
GLYPHMETRICSFLOAT.
Parametry
hDC HDC: Kontekst urzdzenia Windows, z ktrego pobierana jest definicja
czcionki.
dwFirst DWORD: Warto ASCII pierwszego znaku czcionki, uywanej do
budowania list wywietlania.
dwCoun DWORD: Liczba tworzonych znakw, poczwszy od znaku dwFirst.
Rozdzia 4. * OpenGL for Windows: OpenGL + Win32 = Wiggle 131
Skadowe:
gmfBlackBoxX Szeroko najmniejszego prostokta cakowicie opisujcego znak.
gmfBlackBoxY Wysoko najmniejszego prostokta cakowicie opisujcego znak.
gmfptGfyphOrigi Wsprzdne x i y lewego grnego rogu prostokta cakowicie
opisujcego znak. Struktura POINTFLOAT jest zdefiniowana
n
nastpujco:
typedef struct _POINTFLOAT { // ptf
gmfCallIncX FLOAT x; // Wsprzdna pozioma punktu
FLOAT y; // Wsprzdna pionowa punktu }
POINTFLOAT;
gmfCalllncY
Odstp w poziomie od pocztku komrki biecego znaku do pocztku
komrki nastpnego znaku.
Zwracana warto
Odstp w pionie od pocztku komrki biecego znaku do pocztku
komrki nastpnego znaku.
Przykad
TRUE, jeli listy wywietlania mog zosta utworzone; FALSE w
przeciwnym wypadku.
Poniszy kod mona znale albo w przykadowym programie MFCGL w
rozdziale 21, albo w pliku glcode.c, w przykadowym programie OWLGL
w rozdziale 22. Te przykady ilustruj, jak czcionka zdefiniowana,
strukturze LOGFONT jest tworzona i wybierana w kontekcie urzdzenia,
a nastpnie jest uywana do utworzenia list wywietlania reprezentujcych
cay zestaw znakw ASCII tej czcionki.
hDC = (HDC)pData;
hFont = CreateFontlndirect(Slogfont);
132________________________________Cz l * Wprowadzenie do OpenGL
SelectObjectfhDC, hFont);
// Otworzenie list wywietlania dla znakw od O do 255,
// z gruboci 0 , 3 oraz domylnym odchyleniem.
// Numerowanie list wywietlania zaczyna si
// od 1000 (moe by dowolna liczba)
wglUseFontOutlines(hDC, O, 255, 1000, O . O f ,
0 . 3 f, WGL_FONT_POLYGONS, agmf);
DeleteObject(hFont);
Patrz take wglUseFontBitmaps, gllsList, glNewList, glCallLists, glListBase,
glDeleteLists, glEndList, glGenLists
Rozdzia 5.
Bdy i inne komunikaty
OpenGL
W tym rozdziale:
W kadym projekcie chcemy, aby tworzona aplikacja bya niezawodnym i dobrze dzia-
ajcym programem, poprawnie reagujcym na polecenia uytkownika i posiadajcym
pewn elastyczno. Nie s tu wyjtkiem take programy graficzne korzystajce z
OpenGL. Nie mamy zamiaru zmieni tego rozdziau w kurs inynierii oprogramowania i
kontroli jakoci, ale jeli chcesz, aby twoje programy dziaay sprawnie, musisz bra
pod uwag take bdy i nieoczekiwane sytuacje. OpenGL dostarcza dwch rnych
metod zapewnienia poprawnoci kodu.
ktry z twoich klientw kupuje tak kart. Czy twj kod bdzie dalej dziaa? Czy te
zniszczy rysunek i wywietli psychodeliczn tcz? By moe masz powody, aby korzysta
z takich sztuczek optymalizacji; funkcja TextOut dziaa zdecydowanie szybciej ni funkcja
wglUseFontBitmaps. (Oczywicie, jeli masz tak super-hiper kart graficzn, TextOut
moe nie by ju najszybszym sposobem wywietlania napisw). Prostym sposobem
zabezpieczenia si przed tym rodzajem katastrof jest sprawdzenie wersji i producenta
biblioteki OpenGL. Jeli uywana implementacja to oglna implementacja Microsoftu,
moesz oszukiwa do woli; w przeciwnym razie lepiej pozosta przy udokumentowanych
metodach.
Listing 5.1 stanowi fragment kodu z programu GLTELL, zawierajcy wanie tak ptl,
odczytujc kody kolejnych bdw. Zwr uwag, e opis bdu jest przekazywany
kontrolce w oknie dialogowym. Wynik dziaania programu GLTELL widzimy na
rysunku 5.1.
Moesz take uy innej funkcji biblioteki GLU, gluErrorString, zwracajcej opis kodu
bdu:
const GLubyte* gluErrorString(GLenum errorCode);
gram dziaa z implementacj Microsoftu, za jej numer wersji jest taki sam jak numer
wersji biblioteki, z ktr testowae program, niczym niezwykym nie bdzie prba uycia
jakich sztuczek w celu poprawienia wydajnoci programu. Aby by pewnym, e
wykorzystywane moliwoci wystpuj w komputerze, w ktrym dziaa twj program,
musisz pozna sposb odpylania biblioteki OpenGL o nazw producenta i numer wersji
systemu graficznego. Zarwno biblioteka GL, jak i GLU potrafi zwrci swj numer
wersji oraz informacje o producencie.
W przypadku biblioteki GL moesz wywoa funkcj glGetString:
const GLubyte *glGetString(GLenum n a m e ) ;
Ta funkcja zwraca statyczny acuch opisujcy wskazany aspekt biblioteki GL. Dozwolone
parametry s podane przy opisie funkcji glGetString w sekcji podrcznika, cznie z
elementami biblioteki GL, do ktrych si odnosz.
Biblioteka GLU take posiada odpowiedni funkcj, gluGetString:
const GLubyte *gluGetString(GLenum n a m e ) ;
Ta funkcja zwraca statyczny acuch opisujcy wskazany aspekt biblioteki GLU. Do-
zwolone parametry s podane przy opisie funkcji gluGetString w sekcji podrcznika,
cznie z elementami biblioteki GLU, do ktrych si odnosz.
Listing 5.2 przedstawia fragment kodu z przykadowego programu GLTELL, zmodyfi-
kowanej wersji programu odbijajcego si kwadratu. Tym razem uzupenilimy program
o menu i okno dialogowe O programie. Okno O programie, pokazane na rysunku 5.1,
wywietla informacje o dostawcy i wersji obu bibliotek: GL oraz GLU. Dodatkowo
umiecilimy w kodzie bdn instrukcj, w celu utworzenia listy komunikatw bdw.
// glGetString demo
SetDlgItemText(hDlg,IDC_OPENGL_VENDOR,glGetString(GL_VENDOR));
SetDlgItemText(hDlg,IDC_OPENGL_RENDERER,glGetString(GL_RENDERER));
SetDlgItemText(hDlg, IDC_OPENGL_VERSION, glGetString(GL_VERSION));
SetDlgItemText(hDlg, IDC_OPENGL_EXTENSIONS, glGetString(GL_EXTENSIONS));
// gluGetString demo
SetDlgItemText(hDlg,IDC_GLU_VERSION,gluGetString(GLU_VERSION));
SetDlgItemText(hDlg,IDC_GLO_EXTENSIONS,gluGetString(GLU_EXTENSIONS));
Rozszerzenia OpenGL
Zwr szczegln uwag na znaczniki GL_EXTENSIONS oraz GLU_EXTENSIONS.
Niektrzy producenci (cznie z Microsoftem w ostatniej wersji OpenGL) oferuj roz-
szerzenia OpenGL umoliwiajce zastosowanie specyficznych optymalizacji lub pe-
wnych popularnych rozszerze, ktre jeszcze nie stay si czci standardu. Te
rozszerzenia mog znacznie poprawi wydajno twojej aplikacji. Jeli jednak korzystasz
z funkcji rozszerze, musisz sprawdzi, czy w systemie wystpuj rozszerzenia
Rozdzia 5. * Bdy i inne komunikaty OpenGL__________________________137
Udzielanie wskazwek za
pomoc funkcji glHint
Wspomnielimy o wykorzystywaniu znanych anomalii w bibliotekach OpenGL. Moesz
wykorzystywa take inne zachowanie specyficzne dla danego producenta. Moesz na
przykad renderowa obraz tak szybko, jak si da, w przypadku oglnej implementacji,
lecz przecza si do trybu sprztowego, jeli tylko karta na to pozwala. Nawet bez
korzystania z funkcji zalenych od producenta, moesz po prostu poleci bibliotece
OpenGL, aby pooya wikszy nacisk na szybko lub na jako obrazu, czyli na przykad
aby pomijajc pewne szczegy utworzya obraz bardzo szybko lub przeciwnie, aby
uwzgldnia wszystkie detale bez wzgldu na to, jak dugo rysunek miaby by
tworzony.
Funkcja glHint umoliwia wskazanie preferencji dotyczcych jakoci lub szybkoci dla
operacji rnych rodzajw. Funkcja jest zdefiniowana nastpujco:
void glHint(GLenum target, GLenum mod);
Podsumowanie
Nawet w tym niedoskonaym wiecie moemy przynajmniej wyapywa bdy i prbowa
jako im zaradzi. Moemy take odczytywa informacje o producencie i numerze wersji
biblioteki, dziki czemu mamy moliwo korzystania ze specyficznych rozszerze lub
wystrzegania si znanych bdw. W tym rozdziale dowiedziae si, jak zmaga si z
tym problemami. Wiesz ju, jak poinstruowa OpenGL, aby powicio jako obrazu na
rzecz szybkoci jego generowania, jednak efekt tych wskazwek take zaley od producenta i
szczegw implementacji biblioteki.
Podrcznik
gIGetError
Przeznaczenie Zwraca informacje o ostatnim bdzie.
Plik nagwkowy <gl.h>
Skadnia GLenum glGetError(void)
Opis OpenGL przechowuje pi znacznikw bdw, wymienionych w tabeli 5.1. Gdy wystpi
bd, odpowiedni znacznik bdu pozostaje ustawiony a do momentu wywoania funkcji
gIGetError. Jeli ustawionych zostanie kilka znacznikw bdw
jednoczenie, konieczne jest kilkakrotne wywoywanie funkcji gIGetError w
celu wyzerowana kolejnych znacznikw. Dobrym pomysem jest
wywoywanie tej funkcji w ptli, a do momentu otrzymania wartoci
GLJNO_ERROR. Jeli gIGetError bdzie wywoana pomidzy instrukcjami
glBegin i glEnd, zostanie ustawiony znacznik bdu
GL_INVALID_OPERATION.
Zwracana warto Jeden z kodw bdw z tabeli 5.1. We wszystkich przypadkach
z wyjtkiem GL_OUT_OF_MEMORY bdne polecenie jest ignorowane,
za stan zmiennych stanu OpenGL, buforw itd. nie zmienia si.
W przypadku bdu GL_OUT_OF_MEMORY, stan OpenGL jest
niezdefiniowany.
Przykad
Patrz przykad GLTELL z listingu 5.1 glErrorString
Patrz take
glGetlastError
Przeznaczenie Zwraca informacje o ostatnim bdzie.
Plik nagwkowy <gl.h>
Rozdzia 5. * Bdy i inne komunikaty OpenGL 139
Tabela 5.1.
Kody bdw zwracane przez funkcj glGetError
Warto Znaczenie
gIGetString
Przeznaczenie Zwraca acuch opisujcy wskazany aspekt implementacji OpenGL.
Plik nagwkowy <gl.h>
Skadnia const GLubyte *glGetString(GLenum name);
140 Cz l * Wprowadzenie do OpenGL
Parametry
glHint
Przeznaczenie Umoliwia programicie przekazanie wskazwek dotyczcych dziaania
biblioteki OpenGL.
Plik nagwkowy
Skadnia void glHint(GLenum target, GLenum mod);
Opis Pewne aspekty dziaania OpenGL mog si nieco rni w rnych
implementacjach. Ta funkcja umoliwia zasugerowanie bibliotece OpenGL,
aby powicia jako obrazu na rzecz szybkoci lub odwrotnie. Specyfikacja
OpenGL nie wymaga, aby funkcja glHint dawaa jaki efekt, wic moe by
ignorowana w rnych implementacjach.
Parametry
target GLenum: Okrela rodzaj dziaania, jakie ma by zmodyfikowane.
Parametr moe przyjmowa jedn z poniszych wartoci:
GL_FOG_HINT Wpywa na obliczenia zwizane z mg.
GL_LINE_SMOOTH_HINT Wpywa na rysowanie linii z
antyaliasingiem.
GL_PERSPECTIVE_CORRECTION_HINT Wpywa na jako koloru i
interpolacji tekstur.
Rozdzia 5. t Bdy i inne komunikaty OpenGL 141
gluErrorString
Przeznaczenie Zwraca acuch opisujcy dany kod bdu.
Plik <glu.h>
nagwkowy const GLubyte *gluErrorString(GLenum errorCode);
Skadnia Opis Ta funkcja zwraca acuch opisujcy wskazany kod bdu. acuch jest
zdefiniowany statycznie, wic zwracany adres nie moe by
Parametry modyfikowany. Zwracany acuch to acuch ANSI. Aby otrzyma acuch
errorCod ANSI lub UNICODE w zalenoci od rodowiska, uyj makra
glErrorStringWIN.
e
Zwracana GLenum: Kod bdu, ktrego opis chcemy uzyska. Moe by podana
dowolna warto z tabeli 5.1.
warto
acuch znakw opisujcy kod bdu.
Przykad Patrz
Patrz przykad GLTELL z listingu 5.2
take
gIGetError
gluGetString
Przeznaczenie Zwraca acuch zawierajcy dodatkowe informacje o bibliotece GLU.
Plik <glu.h>
nagwkowy const GLubyte *gluGetString(GLenum name);
142 Cz l * Wprowadzenie do OpenGL
ar
114________________________________Cz l 4 Wprowadzenie do OpenGL
return ( O L ) ;
Jeli ledzie nasz wczeniejsz dyskusj, z pewnoci zrozumienie kodu w wersji dla
Windows nie sprawi ci problemu. Spjrzmy jednak na kilka miejsc, na ktre powiniene
zwrci szczegln uwag.
Skalowanie do okna
W naszym przykadzie z rozdziau trzeciego, opartym na bibliotece AUX, biblioteka AUX
wywoywaa zarejestrowan funkcj ChangeSize za kadym razem, gdy zmieniay si
wymiary okna. W naszym nowym przykadzie musimy w tym celu przechwy-tywa
komunikat WM_SIZE, wysyany przez Windows przy kadej zmianie wymiarw okna. W
procedurze obsugi tego komunikatu moemy sami wywoywa funkcj ChangeSize,
przekazujc LOWORD z parametru IParam, ktry zawiera now szeroko okna, oraz
HIWORD z IParam, zawierajc now wysoko okna.
// Zmieniaj si wymiary okna
case WM_SIZE:
// Wywoanie naszej funkcji modyfikujcej bry obcinania
/ / i widok
ChangeSize (LOWORD (IParam) , HIWORD (IParam) ) ;
break;
yknicia timera
Biblioteka AUX regularnie wywoywaa take nasz funkcj czasu wolnego, IdleFun-
ction. Ta funkcja bya wywoywana wtedy, gdy program nie mia nic lepszego do roboty (na
przykad nie musia odrysowywa zawartoci okna). Moemy atw.o zasymulowa to
dziaanie ustawiajc timer Windows dla naszego okna. Poniszy kod:
// Utworzenie timera odpalanego co milisekund
SetTimer(hWnd,101,1,NULL);
wywoywany w momencie tworzenia okna, uaktywnia timer Windows dla okna. W wyniku
tego, teoretycznie co milisekund okno OpenGL otrzyma komunikat WMJTIMER. W
praktyce komunikat bdzie wysyany tak czsto, jak czsto Windows bd w stanie go
wysa - w Windows 95 mniej wicej co 55 milisekund - i tylko wtedy, gdy w kolejce nie
bd oczekiwa inne komunikaty. (Wicej informacji na temat timera znajdziesz w
ksice Programming Windows 98 i NT, wydanej przez Wydawnictwo H-
Rozdzia 6.
Rysowanie
w trzech wymiarach:
linie, punkty i wielokty
W tym rozdziale:
Jeli kiedykolwiek uczye si chemii (a nawet jeli si nie uczye), z pewnoci wiesz, e
wszystko dookoa skada si z atomw, za same atomy skadaj si jedynie z trzech
rzeczy: protonw, neutronw i elektronw. Wszystkie materiay i substancje, z ktrymi
kiedykolwiek miae kontakt - od kropel rosy po piasek na play - stanowi po prostu
rne uoenie tych trzech podstawowych klockw. Cho takie podejcie jest nieco
uproszczone z punktu widzenia kadego, kto skoczy trzeci czy czwart klas, przedstawia
jednak pewn generaln zasad: przy pomocy prostych elementw skadowych mona
tworzy bardzo zoone i pikne struktury.
Analogia jest oczywista. Obiekty i sceny tworzone w OpenGL take skadaj si z maych,
prostych ksztatw, uoonych i poczonych na rne i niepowtarzalne sposoby. W tym
rozdziale poznamy wanie te klocki, zwane prymitywami. Wszystkie prymity-
146_______________________________________Cz II Uywanie OpenGL
Rysowanie punktw
w przestrzeni trjwymiarowej
Uczc si cokolwiek rysowa w systemie komputerowym, zwykle zaczynamy od pi-kseli.
Piksel to najmniejszy element na monitorze komputera, ktry moe przyjmowa rne
kolory. Taka jest wanie grafika komputerowa w maksymalnym uproszczeniu:
narysowanie punktu w pewnym miejscu ekranu, z nadaniem mu okrelonego koloru.
Opierajc si na tej prostej koncepcji, uywajc ulubionego jzyka programowania, moesz
tworzy linie, wielokty, okrgi oraz wszelkie inne ksztaty i grafik. Moe nawet graficzny
interfejs uytkownika...
- 0 / +100 l ]0
,
Kierunek
1 0
/ / inn /
/ +z /
Rysunek 6.2.
Punkt (50, 50, 0)
okrelony funkcj
50 ' (50,50,0)
glVertex3f(50.0f,
SO.Of, O.Oj)
50
Narysujmy co!
Teraz wiemy ju, jak wskaza punkt w trjwymiarowej przestrzeni OpenGL. Co moemy
z nim zrobi i co moe zrobi z nim OpenGL? Czy wierzchoek jest punktem, ktry po
prostu powinien zosta narysowany? Czy jest to koniec odcinka lub wierzchoek szecianu?
Geometryczna definicja wierzchoka to nie tylko punkt w przestrzeni, ale raczej miejsce,
gdzie przecinaj si dwie linie lub krzywe. Na tym polegaj prymitywy.
Rysowanie punktw
Zacznijmy od pierwszego i najprostszego z prymityww: punktu. Spjrz na poniszy kod:
glBegin(GL_POINTS); // wybranie punktw jako
// prymitywu
glVertex3f (0 , 0f, 0,0f, 0 , 0 f ) ; // wskazanie punktu
glVertex3f (5 0 ,Of, 50,Of, 50,O f ) , // wskazanie innego punktu
glEnd() ; // koniec z rysowaniem punktw
W tym momencie dochodzimy do wanej roli pary funkcji glBegin i glEnd: pomidzy tymi
wywoaniami moesz umieci dug list prymityww, jeli tylko nale do tego
L
150_______________________________________Cz II Uywanie OpenGL
Nastpny segment kodu jest bardzo rozrzutny i wykonuje si duo wolniej ni poprzedni
przykad:
glBegin(GL_POINTS); // wybranie punktu jako prymitywu
glVertex3f( 0 , 0 f , 0,0f, 0 , 0 f ) ;
glEnd();
glBegin(GL_POINTS); // wybranie punktu jako prymitywu
glVertex3f(50,O f , 50,O f , 50,O f ) ;
glEnd();
z = -50.Of;
for(angle = O . O f ; angle <= (2.Of*GL_PI)*3.Of; angle += O . l f )
{
x = 50.0f*sin(angle);
y = 50.Of*cos(angle);
// Odtworzenie transformacji
glPopMatrix();
glFlushO ;
W tym \ w innych przykadach w tym rozdziale interesuje nas przede wszystkim kod
zawarty pomidzy wywoaniami glBegin i glEnd. Ten kod oblicza wsprzdne x i y dla
ktw od O do 360 dla trzech obrotw. (W programie wyraamy je w radianach, a nie w
stopniach; jeli nie znasz trygonometrii, musisz uwierzy na sowo. Jeli ci to
interesuje, zajrzyj do ramki Trygonometria radianw i stopni"). Za kadym razem, gdy
rysowany jest punkt, zwikszana jest nieco warto wsprzdnej z. Po uruchomieniu
programu wida jedynie zielony krg punktw, a to dla tego, e pocztkowo patrzymy w
d osi z. Aby lepiej widzie spiral, za pomoc klawiszy kursora obr scen dookoa osi x i
y. Ilustruje to rysunek 6.3.
Rysunek 6.3.
Efekt dziaania programu POINTS
152 Cz II Uywanie OpenGL
x=sin(oc)
y=cos(ce)
Uy)
-> x
Listing 6.3. Kod programu POINTSZ tworzcy spiral coraz wikszych punktw_______________
// Rysowanie punktu
glBegin(GL_POINTS);
glVertex3f( x , y, z ) ;
glEnd();
Ten przykad demonstruje kilka wanych rzeczy. Pocztkujcy powinni zwrci uwag, e
funkcja glPointSize musi by wywoywana na zewntrz pary glBegin/glEnd. Nie
wszystkie funkcje OpenGL mog by wywoywane wewntrz tej pary. Poniewa
glPointSize wpywa na wszystkie rysowane po jej wywoaniu punkty, samo rysowanie
Rozdzia 6. Rysowanie w trzech wymiarach: linie, punkty i wielokty_____________155
Wynika to z tego, e rozmiar podany w funkcji glPointSize nie jest dokadnym rozmiarem
punktu w pikselach, ale raczej przyblion rednic okrgu opisujcego wszystkie piksele
uyte do narysowania punktu. Moesz namwi OpenGL, aby rysowao okrge punkty, tj.
wypenione okrgi, wywoujc funkcj
glEnable(GL_POINT_SMOOTH);
Inne funkcje okrelaj sposb wygadzania punktw i linii, jednak naley to ju do sze-
rokiego tematu zwizanego z antyaliasingiem (rozdzia 16). Antyaliasing to technika
uywana do wygadzania zbkowanych krawdzi i zaokrglania wierzchokw. Wspo-
minamy o tym jedynie, aby mg sam poeksperymentowa i aby nabra apetytu na
dalsze rozdziay!
Listing 6.4. Fragment kodu z programu LINES rysujcy seri odcinkw tworzcych promienie okrgu
z = O.Of;
f o r f a n g l e = O . O f ; angle <= GL PI*3.0f; angle += 0 . 5 f )
156____________________________________Cz II Uywanie OpenGL
Rysunek 6.5.
Wynik dziaania
programu LINES
Rysunek 6.6.
Przykad prymitywu
GL_LINE_STR1P V2(50,100,
rozpitego na trzech
wierzchokach 0) V,
V(0,0,0)
Rysunek 6.7.
amana zamknita
rozpita na tych
samych
wierzchokach, co
amana z rysunku 6.6
-* x
z = -50.O f ;
for(angle = O . O f ; angle <= (2. O f * 3 . 1415f)*3.Of; angle += O . l f )
158 Cz II Uywanie OpenGL
Rysunek 6.8.
Program LSTR1PS, 2
krzyw przyblion
za pomoc amanej
Tablica sizes bdzie zawiera dwa elementy okrelajce najmniejsz i najwiksz do-
zwolon warto parametru funkcji glLine Width. Dodatkowo, zmienna step bdzie za-
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty_____________159
Listing 6.6 przedstawia kod wykorzystujcy funkcj glLineWidth. Fragment kodu pochodzi
z programu LINESW i rysuje dziesi odcinkw o rnych grubociach. Zaczyna od dou
okna, od punktu o wsprzdnej -90 w osi y i przechodzi w gr w krokach po 20
jednostek. Kady nastpny odcinek jest grubszy od poprzedniego o jeden piksel. Wynik
dziaania programu ilustruje rysunek 6.9.
Rysunek 6.9.
Wynik dziaania funkcji glLine Width z
programu LINESW
II Wywoywane w celu
narysowania sceny
void
RenderScene( v o i d )
{
GLfloat y; // Zmienna dla zmieniajcej si wsprzdnej Y
GLfloat
fSizes[2];
// Zakres
szerokoci linii
GLfloat
fCurrSize; // Przechowuje biec szeroko
// Narysowanie linii
glBegin(GL_LINES);
glVertex2f(-80.O f , y);
glVertex2f(80.Of, y ) ;
glEnd();
// Zwikszenie szerokoci linii
fCurrSize += l . O f ; }
Linie przerywane
Oprcz zmieniania szerokoci linii moemy take rysowa linie kropkowane lub prze-
rywane. Aby rysowa takie linie, musisz najpierw wczy przerywanie, wywoujc
funkcj
glEnable(GL_LINE_ST1PPLE);
a nastpnie przy pomocy funkcji glLineStipple okreli dese uywany przy rysowaniu
linii:
void glLineStipple(GLint factor, GLushort pattern);
UWAGA:
Kada opcja wczana funkcj glEnable() moe by wyczona
funkcj glDisable().
Wzr linii = l t l i l l l t l l l l l l l l l
linia =
Rozdzia 6. Rysowanie w trzech wymiarach: linie, punkty i wielokty_____________161
Parametr pattern to 16-bitowa warto okrelajca wzr uywany podczas rysowania linii
przerywanych. Kady bit reprezentuje sekcj odcinka, ktra moe by narysowana lub nie.
Domylnie, kady bit odpowiada pojedynczemu pikselowi, lecz parametr factor suy jako
mnonik zwikszajcy szeroko wzoru. Na przykad ustawienie parametru factor na 5
powoduje, e kady bit we wzorze reprezentuje pi kolejnych pikseli linii, ktre albo
wszystkie s wczone, albo wyczone. Co wicej, bit O (najmniej znaczcy) jest uywany
jako pierwszy. Przykadowy wzr linii ilustruje rysunek 6.10.
Listing 6.7 przedstawia przykad uycia wzorca linii, skadajcego si z serii naprze-
miennych zer i jedynek (0101010101010101). Ten program rysuje dziesi odcinkw, od
dou do gry okna. Kada linia korzysta z tego samego wzorca, 0x5555, jednak w
kadej nastpnej linii warto mnonika wzorca zwiksza si o 1. Efekt poszerzajcych si
wzorw wyranie wida na rysunku 6.11.
Rysunek
6.11.
Wynik dziaania
programu
LSTIPPLE
Listing 6.7. Kod z programu LSTIPPLE demonstrujcy efekt zastosowania rnych mnonikw wzorca linii
// Wczenie przerywania
glEnable(GL_LINE_STIPPLE);
// Rysowanie linii
glBegin(GL_LINES);
glVertex2f(-80.Of, y ) ;
glVertex2f(80.Of, y) ;
glEnd();
factor++;
glVertex2f(-50.0f, O . O f ) ; // V3
glVertex2f(-75.O f , 50.O f ) ; //V4
. glVertex2f(-25.Of, O . O f ) ; // V5
glEnd () ;
12.
tfese
tmitywu ILE
trunek
Wana waciwo kadego wieloktnego prymitywu zostaa zilustrowana na rysunku
6.12. Zwr uwag na kierunek strzaek przy liniach czcych wierzchoki trjkta.
Przy rysowaniu pierwszego trjkta, linie s rysowane od wierzchoka V0 do wie-
rzchoka VI, nastpnie do wierzchoka V2, a na koniec z powrotem do wierzchoka V0. Ta
cieka zostaa wyznaczona przez kolejno podawania wierzchokw i w tym przypadku, z
twojego punktu widzenia, jest zgodna z ruchem wskazwek zegara. Rwnie drugi trjkt
zosta utworzony w tym samym kierunku.
Rysunek 6.13.
Dwa trjkty o
rnych
kierunkach
Jakie to ma znaczenie? Jak si wkrtce przekonasz, czsto zdarza si, e przedniej i tylnej
stronie trjkta chcemy nada rne charakterystyki. Mona na przykad cakowicie ukry
ty wielokta lub te nada mu inny kolor i waciwoci odbijania wiata (rozdzia 9).
Bardzo wane jest wic zachowanie spjnych kierunkw wieloktw w scenie, poprzez
uycie wieloktw skierowanych przodem do tworzenia zewntrznych powierzchni
jednolitych obiektw. W nastpnych sekcjach, powiconych jednolitym obiektom,
zademonstrujemy to zagadnienie uywajc bardziej zoonych modeli.
Parametr GL_CW instruuje OpenGL, aby za odwrcone przodem byy uwaane trjkty o
kierunku zgodnym z ruchem wskazwek zegara. Aby powrci do kierunku przeciwnego do
ruchu wskazwek zegara dla trjktw widzianych z przodu, uyj tej funkcji z parametrem
GL_CCW.
Paski trjktw
W przypadku wielu ksztatw i powierzchni zdarzy ci si rysowa kilka poczonych
trjktw. Uywajc prymitywu GL_TRIANGLE_STRIP, moesz zaoszczdzi mnstwo czasu
przy rysowaniu paskw trjktw. Rysunek 6.14 przedstawia kolejno tworzenia paska
trjktw skadajcego si z trzech trjktw rozpitych na piciu wierzchokach V0 i V4.
Jak wida, wierzchoki nie s przetwarzane w tej samej kolejnoci, w jakiej s podawane.
Powodem takiego dziaania jest konieczno zachowania kierunku (przeciwnego do ruchu
wskazwek zegara) kadego trjkta.
Rozdzia 6. + Rysowanie w trzech wymiarach: linie, punkty i wielokty 165
Rysunek 6.14.
Przebieg tworzenia
paska trjktw
GL TRIANGLE
STRIP
Wachlarze trjktw
Rysunek 6.15.
Etapy tworzenia
trjktw w prymitywie
GL TRIANGLE FAN
Oprcz tworzenia paskw trjktw, moesz tworzy take wachlarze trjktw. Prymityw
GL_TRIANGLE_FAN suy do tworzenia grupy trjktw o jednym wsplnym punkcie.
Rysunek 6.15 przedstawia wachlarz trzech trjktw utworzony przez podanie czterech
dodatkowych wierzchokw. Pierwszy wierzchoek, V0, wyznacza wsplny punkt
wachlarza. Gdy pierwsze trzy wierzchoki zostan uyte do narysowania pierwszego
trjkta, kady nastpny trjkt jest budowany w oparciu o wierzchoek wsplny (V0),
nastpny wierzchoek oraz wierzchoek bezporednio go poprzedzajcy (Vn-l).
166____________________________________Cz II Uywanie OpenGL
Wynik dziaania programu TRIANGLE zosta pokazany na rysunku 6.16. W tym momencie
spogldamy dokadnie w d osi z i widzimy jedynie koo utworzone przez wachlarz
trjktw. Poszczeglne trjkty zrnicowano nadajc im na przemian kolory czerwony i
zielony.
Rysunek 6.16.
Pocztkowy wygld
programu
TRIANGLE
// Czarne to
glClearColor ( O . O f , O.Of, O.Of, l.Of );
// Odtworzenie transformacji
glPopMatrix();
// Zrzucenie polece graficznych
glFlusht); }
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty ______ 169
Moesz usun ten problem dziki technice zwanej buforem gbokoci, a OpenGL posiada
specjalne funkcje, ktre zajm si tym za ciebie. Idea jest prosta: gdy jest rysowa-
170____________________________________Cz II Uywanie OpenGL
Zmienna bDepth jest ustawiana w momencie wybrania w menu Efekty polecenia Bufor
gbokoci. Naley pamita, e bufor gbokoci musi by wyzerowany za kadym razem
gdy przystpujemy do narysowania sceny. Bufor gbokoci jest podobny do bufora
koloru, z tym e zamiast koloru przechowuje informacje o odlegociach pikseli od
obserwatora. Dziki temu mona wyznaczy, czy dany piksel znajduje si bliej lub dalej ni
inny piksel.
// Wyczyszczenie okna i bufora gbokoci
glClar(GL_COLOR_BUFFER_BIT | GL_DEPTH__BUFFER_BIT) ;
Rysunek 6.18 przedstawia menu Efekty z wczonym buforem gbokoci. Oprcz tego
przedstawia stoek z podstaw poprawnie ukryt za ciankami. Jak wida, bufor gbokoci
jest praktycznie nieodzowny jeli chodzi o rysowanie jednolitych trjwymiarowych
obiektw.
Rysunek 6.18.
W tym pooeniu podstawajest poprawnie
zasonita przez cian, stoka
Rozdzia 6. Rysowanie w trzech wymiarach: linie, punkty i wielokty 171
W naszym przykadzie stoek jest bry zamknit i nigdy nie widzimy jego wntrza.
OpenGL w rzeczywistoci (wewntrznie) rysuje tylne ciany z tyu stoka, a nastpnie
przednie strony wieloktw, skierowane w nasz stron. Nastpnie, przez porwnanie
wartoci w buforze gbokoci, eliminuje ciany stoka znajdujce si dalej. Rysunki
6.19a i 6.19b przedstawiaj stoek w pewnym pooeniu z wczonym (a) i wyczonym
(b) buforem gbokoci. Zwr uwag e czerwone i zielone trjkty zamieniaj si
miejscami w momencie wczenia i wyczenia bufora gbokoci. Bez bufora gbokoci,
w dalszym cigu widzimy strony trjktw znajdujcych si dalej.
Rysunek
6.19a.
Z wczonym
buforem gbokoci
Rysunek
6.19b.
Bez wczonego
172____________________________________Cz II Uywanie OpenGL
Rysunek 6.20.
Podstawa stoka zostaa ukryta, gdy
przednia strona jej trjktw jest
skierowana do rodka bryy
jednak przednia strona wachlarza podstawy jest skierowana do wntrza stoka. Wyjania
to rysunek 6.21.
Rysunek 6.21. j. .
' ,, , . . Przednia strono
Sposb zoenia
stoka z dwch wachlarzy trjktw
Przednia strona
trjktw
Tryby wieloktw
Wielokty nie musz by wypenione biecym kolorem. Domylnie, wielokty s rysowane
jednolitym kolorem, moesz jednak zmieni to zachowanie nakazujc, by wielokty byy
rysowane jedynie jako sylwetki lub nawet jako punkty (s wtedy rysowane jedynie
wierzchoki). Funkcja glPolygonMode() umoliwia okrelenie, aby wielokty byy
renderowane jako wypenione, jako kontur lub jako punkty. Oprcz tego, tryb ren-
derowania moe by przypisany obu stronom wielokta lub tylko stronie wybranej. Po-
niszy kod z listingu 6.8 przedstawia ustawianie trybu wielokta na wypeniony lub
siatkowy, w zalenoci od stanu zmiennej logicznej bOutline:
// Rysowanie tylko siatki wielokta, jeli znacznik jest ustawiony
if(bOutline)
glPolygonMode(GL_BACK,6L_LINE); else
glPolygonMode(GL_BACK,GL_FILL);
Rysunek 6.22 pokazuje, e wszystkie wielokty skierowane tyem s rysowane jako siatka.
(Aby stworzy ten obrazek, musielimy wyczy usuwanie tylnych powierzchni, gdy w
przeciwnym razie zostayby usunite i nie byoby wida siatki). Zwr uwag, e teraz
podstawa stanowi siatk i nie jest wypeniona, dziki czemu moesz zajrze do wntrza
stoka, w ktrym wewntrzne ciany take s rysowane jako siatkowe trjkty.
174____________________________ Cz II Uywanie
ppenGL
Rysunek 6.22.
Uycie funkcji gIPolygonMode() w celu
narysowania jednej strony trjktw jako
siatki
Inne prymitywy
Trjkty s najczciej
wybieranymi prymitywami,
gdy wikszo kart
graficznych
zoptymalizowanych dla
OpenGL najszybciej rysuje
wanie trjkty; jednak nie s jedynymi dostpnymi obiektami. Niektre karty potrafi
rysowa sprztowo take inne ksztaty, za w programie czsto atwiej jest uy oglnych
prymityww graficznych. Do pozostaych prymityww OpenGL nale czworokty
oraz paski czworoktw, a take wielokty o dowolnej liczbie krawdzi. Jeli wiesz, e
twj program bdzie dziaa w komputerze z kart, ktra obsuguje takie wielokty
sprztowo, moesz pokusi si o zastosowanie ich w celu osignicia lepszej wydajnoci.
Czworokty
Nastpnym ksztatem po trjkcie jest czworokt. Do rysowania czworoktw suy pry-
mityw GL_QUADS. Na rysunku 6.23 widzimy, e czworokt jest rozpity na czterech
wierzchokach. Zwr uwag, e ten czworokt ma kierunek zgodny z ruchem wskazwek
zegara.
Rysunek 6.23.
Przykad prymitywu
GL_QUAD
Rozdzia 6. Rysowanie w trzech wymiarach: linie, punkty i wielokty 175
Paski czworoktw
Tak jak w przypadku paskw trjktw, moesz utworzy take paski czworoktw;
suy do tego prymityw GL_QUAD_STRIP. Rysunek 6.24 przedstawia przebieg po-
wstawania paska czworoktw skadajcego si z dwch czworoktw rozpitych na
szeciu wierzchokach. Poszczeglne czworokty, podobnie jak czworokt prymitywu
GL_QUADS, maj kierunek zgodny z ruchem wskazwek zegara.
Rysunek 6.24. V, 2 V,
Przebieg
powstawania paska
czworoktw
GL_QUAD_STRIP
V, V
Oglne wielokty
Ostatnim prymitywem OpenGL jest GL_POLYGON, ktry moe zosta uyty do nary-
sowania wielokta o dowolnej liczbie krawdzi. Rysunek 6.25 przedstawia wielokt
skadajcy si z piciu wierzchokw. Wielokty tworzone za pomoc GL_POLYGON maj
kierunek zgodny z ruchem wskazwek zegara.
Rysunek
6.25.
Proces tworzenia
wielokta
GL POLYGON
A co z prostoktami?
Wszystkie dziesi prymityww OpenGL jest uywanych
pomidzy wywoaniami gIBegin/glEnd do rysowania oglnych
ksztatw. Jeden z ksztatw jest tak powszechny, e zamiast
prymitywu posiada wasn funkcj; tym ksztatem jest
prostokt. By to pierwszy ksztat, ktry narysowalimy w
rozdziale 3. Funkcja glRect() zapewnia atwy i wygodny
sposb rysowania prostoktw, bez koniecznoci odwoywania
si do prymitywu GL_QUAD.
Wypenianie wieloktw
Istniej dwie metody wypeniania jednolitych wieloktw. Bardziej uniwersaln metod jest
mapowanie tekstur, w ktrym bitmapa jest nakadana na powierzchni wielokta
(omawiamy to w rozdziale 11). Innym sposobem jest okrelenie desenia, tak jak to czy-
176 Cz II * Uywanie OpenGL
nilimy w przypadku linii. Wzr desenia dla wielokta nie jest niczym innym jak mo-
nochromatyczn bitmap o rozmiarach 32x32, uywan do wypenienia wielokta.
a nastpnie
glPolygonStipple(pBitmap);
Rysunek 6.26. 4 2 l 8 4 Z l B 4 2 l 8 4 2 l8 4 2 l 9 4 2 l 8 4 2 l 8 4 2 l
Budowanie wzoru
desenia wypeniania
wieloktw
1 2864 32 16 8 4 2 1 1 2 8 6 4 3 2 16 8 4 2 1 1 2 8 M 3216 8 4 2 1 1 2 8 6 4 3 2 1 6 8 4 2 l
Y
= 0X1F 0X1F OXCO
0X80
Przechowywanie pikseli
Jak dowiesz si w rozdziale 11, moesz modyfikowa sposb
interpretacji pikseli wzorca wypenienia; suy do tego funkcja
glPixelStofe(). Na razie pozostamy jednak przy zwykym
wypenianiu wieloktw.
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty 177
Kod uyty do przechowania wzorca przedstawia listing 6.9. Kady wiersz tablicy repre-
zentuje wiersz punktw z rysunku 6.26. Pierwszy wiersz w tablicy stanowi ostatni wiersz
rysunku, i tak dalej, a do ostatniego wiersza w tablicy, ktry odpowiada pierwszemu
wierszowi na rysunku.
Sugestia: wr tu pniej
Jeli wci nie rozumiesz, jak ta bitmapa ogniska jest przechowywana i
interpretowana, sugerujemy, aby wrci tu pniej, gdy ju opanujesz
materia z rozdziau 11, Grafika rastrowa".
Abymy mogli skorzysta z tego wzorca, musimy najpierw wczy wypenianie wielo-
ktw, a nastpnie wskaza ten wzr jako wzr wypeniania. Wanie to wykonuje
przykadowy program PSTIPPLE, a nastpnie rysuje omiokt (ksztat znaku Stop),
uywajc wzorca wypenienia. Interesujcy nas kod znajduje si na listingu 6.10, za
wynik dziaania programu zosta przedstawiony na rysunku 6.27.
Rysunek 6.27.
Wynik dziaania
programu
PSTIPPLE
II Ta funkcja
odpowiada za
inicjowanie kontekstu
renderowania
void SetupRCO
{
// Czarne to
glClearColor( O . O f
, O . O f , O . O f , l.Of );
Rysunek 6.28 przedstawia omiokt nieco obrcony. Jak wida, wielokat jest w dalszym
cigu wypeniony, jednak dese nie obraca si wraz z nim. Dzieje si tak, poniewa
wzorzec wypenienia jest uywany wycznie do wypeniania wieloktw na ekranie.
Jeli chcesz naoy na wielokat bitmap imitujc jego powierzchni, bdziesz musia
zastosowa mapowanie tekstur (rozdzia 12).
Rysunek 6.28.
Wygld wielokta po obrceniu go wok
osi pionowej. Jak wida, wzr wypenienia
nie obraca si wraz z wieloktem
Reguy konstruowania
wieloktw
Gdy przy tworzeniu zoonej
powierzchni korzystasz z
wielu wieloktw, musisz
pamita o dwch wanych
zasadach.
Po pierwsze, wszystkie
wielokty musz by paskie. Tzn. wszystkie wierzchoki wielokta musz lee na tej samej
paszczynie, jak przedstawiono na rysunku 6.29. Wielokat nie moe by wykrcony" ani
wygity" w przestrzeni.
180 Cz II Uywanie OpenGL
Rysunek 6.29.
Paski i niepaski
wielokt
Jest to wic jeszcze jeden powd, aby korzysta z trjktw. adnego trjkta nie da si
wykrci" tak, aby ktry z wierzchokw nie spoczywa na innej paszczynie ni
pozostae, poniewa zgodnie z zasadami geometrii, wanie trzy punkty wyznaczaj pa-
szczyzn. (Jeli wic uda ci si narysowa niewaciwy trjkt, oczywicie poza usta-
wieniem go w zym kierunku, by moe czeka ci nagroda Nobla!)
Rysunek 6.30.
Dozwolone i
niedozwolone
wielokty
Podzia wielokta
Cho OpenGL potrafi rysowa jedynie wielokty wypuke, istnieje sposb tworzenia
wieloktw niewypukych czc dwa lub wicej wieloktw wypukych. Na przykad,
wemy czteroramienn gwiazd przedstawion na rysunku 6.31. Ten ksztat z ca
pewnoci nie jest wypuky i w zwizku z tym narusza reguy OpenGL dotyczce kon-
struowania wieloktw. Jednak gwiazda po prawej stronie jest skonstruowana z szeciu
trjktw, ktre s zupenie dozwolone.
Rysunek 6.31.
Niewypuka
czteroramienn
gwiazda zoona z
szeciu trjktw
Gdy wielokty zostan wypenione, nie bdzie wida adnych krawdzi i caa figura bdzie
stanowi pojedynczy ksztat na ekranie. Jeli jednak uyjesz funkcji glPolygonMode w celu
przeczenia si na rysowanie sylwetki, bdzie wida szkielety trjktw skadajcych si na
gwiazd, co w pewnych przypadkach moe by bardzo mylce.
OpenGL posiada w tym celu specjalny znacznik, zwany znacznikiem krawdzi. Usta-
wiajc lub zerujc ten znacznik podczas podawania listy wierzchokw, informujesz
OpenGL, ktre linie maj zosta potraktowane jako zewntrzne krawdzie figury (linie
tworzce sylwetk figury), a ktre jako linie wewntrzne (ktre nie powinny by widoczne).
Suy do tego funkcja glEdgeFlag(), wywoywana z pojedynczym parametrem, bdcym
wartoci logiczn, wczajc lub wyczajc znacznik krawdzi. Gdy znacznik zostanie
ustawiony na warto True, wszystkie nastpne wierzchoki bd definioway krawdzie
nalece do sylwetki figury. Na listingu 6.11 widzimy zastosowanie tego w praktyce, w
programie STAR z pytki CD-ROM.
// Rysowanie trjktw
glBegin(GL_TRIANGLES) ;
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.Of, O . O f ) ;
glEdgeFlag(TRUE); glVertex2f
(20.Of, O . O f ) ;
glVertex2f( O . O f , 40.O f ) ;
glVertex2f(-20.Of,O.Of);
glVertex2f( - 6 0 .Of,-20.Of);
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.Of,-40.Of);
glEdgeFlag(TRUE);
182 Cz II * Uywanie OpenGL
glVertex2f(-20.Of,-40.Of);
glVertex2f( O . O f , -80.O f ) ;
glEdgeFlag(bEdgeFlag);
glVertex2f( 2 0 . O f , -40.O f ) ;
glEdgeFlag(TRUE);
glVertex2f( 2 0 . O f , -40.O f ) ;
glVertex2f( 6 0 . Of, -20.O f ) ;
glEdgeFlag(bEdgeFlag);
glVertex2f(20.Of, O . O f ) ;
glEdgeFlag(TROE);
glVertex2f(-20.Of,-40.Of);
glVertex2f( 2 0 . Of, -40.O f ) ;
glVertex2f( 2 0 . Of, O . O f ) ;
glEdgeFlag(TRUE);
// koniec rysowania
glEnd();
Rysunek 6.32b.
Program STAR
z
wyczonymi
wewntrznymi
Podsumowanie
W tym rozdziale zdobylimy mnstwo informacji. Potrafisz ju tworzy wasn trjwy-
miarow przestrze do renderowania, wiesz take, jak narysowa kady z prymityww, od
punktw i odcinkw a po zoone wielokaty. Dowiedziae si rwnie, jak z dwu-
wymiarowych prymityww mona tworzy powierzchni trjwymiarowych obiektw.
Tat
Podrcznik o
Pry
m
gIBegin_____
Przeznaczenie Poprzedza podawanie listy wierzchokw definiujcych jeden lub wicej
prymityww.
Plik nagwkowy <gl.h>
Skadni void glBegin(GLenum mod);
a Opis Ta funkcja, w poczeniu z funkcj glEnd, jest przeznaczona do tworzenia prymityww
OpenGL. Wewntrz pary wywoa glBegin/glEnd mona poda wiele wierzchokw,
definiujcych seri prymityww tego samego rodzaju. Oprcz definiowania
wierzchokw, wewntrz pary glBegin/glEnd mona zmienia rne opcje i
ustawienia, wpywajce na sposb tworzenia i rysowania prymityww.
Pomidzy wywoaniami gIBegin i glEnd mona wywoywa jedynie
nastpujce funkcje: glVertex, glColor, gllndex, glNormal, glEvaICoord,
glCallLists, glTextCoord, glEdgeFlag oraz glMaterial.
Parametr
y mod GLenum: Ten parametr okrela rodzaj konstruowanych prymityww.
Moe by jedn z wartoci z tabeli 6. l.
Zwracana warto Brak.
Przykad Przykady uycia tej funkcji znajdziesz w kadym programie
Patrz opisywanym w tym rozdziale. Poniszy kod przedstawia
tworzenie pojedynczego punktu, pooonego w rodku ukadu
take wsprzdnych:
gIBegin(GL_POINTS);
glVertex3f{ 0 . 0 , 0 . 0 , 0 . 0 ) ; // punkt w rodku ukadu
glEnd();
glEnd, glVertex
Tabela 6.1.
Prymitywy OpenGL obsugiwane przez funkcj glBegin()
Tabela 6.1.
Prymitywy OpenGL obsugiwane przez funkcj glBeginf) - cig dalszy
Staa Rodzaj prymitywu
glCulIFace
Przeznaczenie Plik Okrela niewidoczn stron wieloktw.
nagwkowy
Skadnia void glCullFace(GLenum mod);
186 Cz II Uywanie
OpenGL
glFrontFace, glLightModel
Patrz take
glEdgeFlag
Przeznaczenie Okrela krawdzie wielokta jako wewntrzne (niewidoczne) lub
zewntrzne (widoczne).
Plik
nagwkowy void glEdgeFlag(GLboolean flag);
void glEdgeFlagv(const GLboolean *flag);
Skadnia
Gdy dwa lub wicej wieloktw jest czonych w wikszy region,
zewntrzne (widoczne) krawdzie definiuj sylwetk nowej figury. Ta
funkcja suy do okrelenia krawdzi wewntrznych, ktre zwykle nie
powinny by widoczne. Funkcja odnosi si jedynie do trybw rysowania GL
LIN i GL POINT.
r Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty_____________187
Parametry
flag GLboolean: Ustawia stan znacznika krawdzi. Warto Tnie oznacza
krawdzie zewntrzne, za warto False - krawdzie wewntrzne.
*flag const GLboolean *: Wskanik do wartoci okrelajcej stan znacznika
krawdzi.
Zwracana warto Brak.
Przykad Poniszy przykad (z programu STAR w tym rozdziale) przedstawia
ustawienie znacznika krawdzi na False w odniesieniu do krawdzi
wystpujcych wewntrz figury. Figura (czteroramienna gwiazda) jest
rysowana jako wypeniona, jako sylwetka lub jako punkty w
wierzchokach.
// Narysowanie jedynie zewntrznych konturw
// wielokta, jeli jest ustawiony taki znacznik
if(iMode == MODE_LINE)
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
if{iMode == MODE_POINT)
glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
if(iMode == MODE_SOLID)
glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
// Rysowanie trjktw
glBegin(GLJTRIANGLES);
glEdgeFlag(bEdgeFlag);
glVertex2f(-20.Of, O . O f ) ;
glEdgeFlag(TRUE);
glVertex2f(20.Of, O . O f ) ;
glVertex2f( O . O f , 40.O f ) ;
glVertex2f(-20.Of,O.Of);
glVertex2f( - 6 0 . Of,-20.0f);
glEdgeFlag(bEdgeFlag);
glVertex2f( - 2 0 . 0 f , -40 . 0 f);
glEdgeFlag(TRUE);
glVertex2f(-20.Of,-40.Of);
glVertex2f( O . O f , -80.O f ) ;
glEdgeFlag(bEdgeFlag);
glVertex2f( 2 0 . Of, -40.O f ) ,
glEdgeFlag(TRUE);
glVertex2f(20.Of, -40.O f ) ,
glVertex2f( 6 0 . Of, -20.O f ) ;
glEdgeFlag(bEdgeFlag);
glVertex2f(20.Of, O . O f ) ;
glEdgeFlag(TRUE);
188 Cz II Uywanie OpenGL
glEnd
Przeznaczenie Plik Koczy list wierzchokw definiujcych prymitywy.
nagwkowy
Skadnia Opis void glEnd();
Ta funkcja jest uywana w poczeniu z funkcj glBegin w celu okrelenia
wierzchokw prymityww OpenGL. Wewntrz pary wywoa glBegin/glEnd
mona poda wiele wierzchokw, definiujcych seri prymityww tego
samego rodzaju. Oprcz definiowania wierzchokw, wewntrz pary
glBegin/glEnd mona zmienia rne opcje i ustawienia, wpywajce na
sposb tworzenia i rysowania prymityww. Pomidzy wywoaniami glBegin i
glEnd mona wywoywa jedynie nastpujce funkcje: glVertex, glColor,
gllndex, glNormal, glEvalCoord, glCallLists, glTextCoord, glEdgeFlag oraz
glMaterial.
Zwracana warto Brak.
Przykad Przykady uycia tej funkcji znajdziesz w kadym programie opisywanym w
tym rozdziale. Poniszy kod przedstawia tworzenie pojedynczego punktu,
pooonego w rodku ukadu wsprzdnych:
glBegin(GL_POINTS);
glVertex3f(0.0, 0.0, 0 . 0 ) ; // punkt w rodku ukadu
glEndO ;
gl Front Face
Przeznaczenie Okrela, ktra strona wielokta ma by traktowana jako przednia.
Plik nagwkowy <gl-h>
Skadnia void glFrontFace(GLenum mod);
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty 189
Opis Gdy scena zawiera obiekty zamknite (nie wida ich wntrza), obliczenia
koloru i owietlenia dla wewntrznych stron obiektu nie s potrzebne.
Funkcja glCullFace wycza te obliczenia dla przedniej lub tylnej strony
wieloktw, za funkcja glFrontFace okrela, ktra strona jest przednia, a
ktra tylna. Kierunek wielokta okrela si na podstawie kolejnoci
podawania jego wierzchokw (z punktu widzenia obserwatora) -w kierunku
zgodnym lub przeciwnym do ruchu wskazwek zegara. Ta funkcja umoliwia
okrelenie, ktra strona wielokta jest przednia: strona zgodna z kierunkiem
ruchu wskazwek zegara, czy te strona przeciwna do ruchu wskazwek.
Parametry
mod GLenum: Okrela orientacj przedniej strony wieloktw: zgodn z
ruchem wskazwek (GL_CW) lub przeciwn do ruchu wskazwek
zegara (GL_CCW).
Zwracana warto Brak.
Przykad Poniszy przykad (z programu TRIANGLE w tym rozdziale) przedstawia
sposb wyczenia rysowania trjktw skierowanych tyem do
obserwatora. Przedtem konieczne jest wskazanie, ktra strona wieloktw
ma by traktowana jako przednia.
// Wielokty o kolejnoci krawdzi zgodnej // z ruchem
wskazwek zegara s widoczne od frontu. // Odwracamy
to, gdy korzystamy // z wachlarza trjktw
glFrontFace(GL_CW);
glCullFace, glLightModel
Patrz take
glGetPolygonStipple
Przeznaczenie Zwraca biecy wzr wypeniania wieloktw.
Plik nagwkowy
Skadnia Opis void glGetPolygonStipple(GLubyte *mask);
Ta funkcja zwraca mask 32x32 bity, reprezentujc wzr wypenienia
wieloktw. Maska jest kopiowana do bufora w pamici, wskazywanego
przez wskanik *mask. Sposb upakowania pikseli jest okrelany przez
ostatnie wywoanie funkcji glPixelStore.
190 Cz II Uywanie OpenGL
Parametry
mod GLubyte: Wskanik do bufora, w ktrym ma zosta umieszczona maska
bitw.
Zwracana warto Brak.
Przykad
Poniszy fragment kodu ilustruje pobieranie biecego wzoru
wypeniania:
Glubyte m a s k [ 3 2 * 4 ] ; // 4 bajty = 32 bity x 32 wiersze
glGetPolyginStipple(mask);
gllineStipple
Przeznaczenie Okrela wzr wypeniania linii przerywanych rysowanych z uyciem
prymityww GLJLINES, GL_LINE_STIPPLE oraz GL_LINE_LOOP.
Plik nagwkowy
Skadnia void glLineStipple(GLint factor, GLushort pattern);
Opis Ta funkcja okrela styl wypenienia linii przerywanych. Wzr przerywania
linii okrela parametr pattern, za wielko segmentw okrela parametr
factor. Domylnie, kady bit wzorca pattern odpowiada jednemu pikselowi
rysowanej linii. Aby uy linii przerywanych, musisz najpierw wywoa
funkcj
glEnable (GL_LINE_STIPPLE) ;
// Wczenie przerywania
glEnable(GL_LINE_STIPPLE);
// Rysowanie linii
glBegin(GL_LINES);
glVertex2f(-80.Of, y ) ;
glVertex2f( 8 0 . Of, y ) ;
glEnd();
factor++;
Patrz take glPolygonStipple
gllineWidth
Przeznaczenie Okrela szeroko linii rysowanych przy uyciu prymityww GL_LINES,
GL_LINE_STIPPLE oraz GLLINELOOP.
Plik
nagwkowy void glLineWidth(GLfloat width);
Skadnia Ta funkcja ustala szeroko (w pikselach) rysowanych linii. Biec
szeroko linii mona pobra za pomoc poniszego kodu:
GLfloat fSize;
glGetFloatv(GL_LINE_WIDTH, fSize) ;
192 Cz II Uywanie OpenGL
glGetFloatv(GL_LINE_WIDTH_RANGE, fSizes) ;
glGetFloatv(GL_LINE_WIDTH_GRANULARITY, SfStepSize);
// Narysowanie linii
glBegin(GL_LINES);
glVertex2f(-80.Of, y);
glVertex2f(80.Of, y ) ;
glEnd();
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty 193
// Poszerzenie linii
fCurrSize += l . O f ;
gIPointSize
Przeznaczenie Okrela rozmiar punktw rysowanych przy uyciu prymitywu
GL_POINTS.
Plik
nagwkowy void glPointSize(GLfloat size);
Skadnia Ta funkcja ustala rozmiar (w pikselach) punktw rysowanych przy uyciu
prymitywu GL_POINTS.
Biecy rozmiar punktw mona pobra za pomoc poniszego kodu:
GLfloat fSize;
glGetFloatv(GL_POINT_SIZE, SfSize) ;
glGetFloatv(GL_POINT_SIZE_RANGE, fSizes) ;
SfStepSize) ;
Parametry
size GLfloat: Okrela przyblion rednic rysowanych punktw. Domyln
wartoci jest 1,0.
194 Cz II Uywanie
OpenGL
// Rysowanie punktu
glBegin(GL_POINTS) ;
glVertex3f ( x , y, z ) ;
glEnd ( ) ;
// Zwikszenie wsprzdnej Z i wielkoci punktu z
+= 0.5f; curSize += step;
glPolygonMode
Przeznaczenie Okrela tryb rysowania wieloktw.
Plik nagwkowy <gl.h>
Skadnia void glPolygonMode(GLenum face, GLenum mod);
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty
glPolygonStipple
Przeznaczenie Okrela wzr wypeniania wieloktw.
Plik nagwkowy
Skadnia Opis void glPolygonStipple(const GLubyte *mask);
Do wypeniania wieloktw mona uy wzorca bitowego o wymiarach 32x32
bity. Przedtem naley wywoa funkcj
glEnable(GL_POLYGON_STIPPLE). Jedynki we wzorcu s rysowane
biecym kolorem wypeniania, zera nie s rysowane.
Parametry
*mask const GLubyte: Wskazuje na bufor o rozmiarze 32x32 bity, zawierajcy wzr
wypeniania wielokta. O sposobie upakowania bitw wzorca decyduje funkcja
glPixelSize. Podczas interpretacji wzorca jako pierwszy odczytywany jest
najbardziej znaczcy bajt.
196 Cz II Uywanie OpenGL
glVertex
Przeznaczenie Plik Okrela wsprzdne wierzchoka w trjwymiarowej przestrzeni.
nagwkowy
Skadnia void glVertex2d(GLdouble x, GLdouble y);
void glVertex2f(GLfloat x, GLfloat y);
void glVertex2i(GLint x, GLint y);
void glVertex2s(GLshort x, GLshort y);
void glVertex3d(GLdouble x, GLdouble y, GLdouble z);
void glVertex3f(GLfloat x, GLfloat y, GLfloat z);
void glVertex3i(GLint x, GLint y, GLint z);
void glVertex3s(GLshort x, GLshort y, GLshort z);
Rozdzia 6. * Rysowanie w trzech wymiarach: linie, punkty i wielokty 197
W rozdziale szstym nauczye si rysowa linie, punkty i inne ksztaty. Aby zamieni
kolekcj prymityww w spjn scen, musisz je odpowiednio uoy wzgldem siebie i
wzgldem obserwatora. W tym rozdziale zaczniemy przemieszcza ksztaty i obiekty w
ukadzie wsprzdnych. (W rzeczywistoci nie przesuwamy obiektw, ale raczej prze-
suwamy ukad wsprzdnych, tak aby uzyska podany widok). Moliwo umie-
szczania i orientowania obiektw w scenie jest podstawow spraw dla kadego progra-
misty trjwymiarowej grafiki. Jak si przekonasz, wygodnie jest opisa ksztat obiektu
umieszczonego w rodku ukadu wsprzdnych, a dopiero potem obrci obiekt i przesun
go we waciwe pooenie.
200____________________________________Cz II Uywanie OpenGL
Zatem, mimo e nie potrafisz przemnoy w myli dwch macierzy, powiniene jednak
wiedzie, czym s macierze i jakie maj zastosowanie w trjwymiarowej magii OpenGL.
Zanim jednak odkurzysz ten stary podrcznik algebry liniowej (czy jest kto, kto go nie
ma?), pozbd si obaw - OpenGL wszystkie obliczenia bierze na siebie. Potraktuj to jak
uycie kalkulatora do podzielenia duej liczby, ktrej nie potrafiby podzieli na
papierze. Mimo e nie musisz robi tego samodzielnie, w dalszym cigu musisz wiedzie,
co i po co dzielisz. Widzisz - moesz mie ciastko i jednoczenie je je!
Przeksztacenia
Przeksztacenia umoliwiaj rzutowanie trjwymiarowych wsprzdnych na dwuwy-
miarowy ekran. Przeksztacenia umoliwiaj take obracanie obiektw, przesuwanie, a
nawet ich rozciganie, kurczenie czy zawijanie. Zamiast bezporednio modyfikowa
obiekt, przeksztacenie modyfikuje ukad wsprzdnych. Gdy przeksztacenie obr
ukad wsprzdnych, wszystkie rysowane obiekty bd obrcone. Po okreleniu wierz-
chokw, a przed narysowaniem obiektw na ekranie, korzystamy z trzech rodzajw
przeksztace: punktu obserwacji, modelu i rzutowania. W tej sekcji opiszemy waci
woci kadego z tych przeksztace, zebranych w tabeli 7.1.
Rozdzia 7. Manipulowanie przestrzeni 3D: transformacje wsprzdnych 201
Tabela 7.1.
Rodzaje przeksztace -w OpenGL
Przeksztacenie Zastosowanie
Wsprzdne obserwatora
Wan koncepcj w tym rozdziale swsprzdne obserwatora. Wsprzdne obserwatora
okrelaj ukad wsprzdnych obserwatora, bez wzgldu na wszelkie przeksztacenia,
ktre mog zosta zastosowane - potraktuj je jako bezwzgldne" wsprzdne
ekranowe. Tak wic wsprzdne obserwatora nie s rzeczywistymi wsprzdnymi, lecz
reprezentuj raczej pewien ustalony ukad wsprzdnych, uywany jako ukad odniesienia.
Wszystkie przeksztacenia omawiane w tym rozdziale s opisywane wanie pod ktem ich
efektw wzgldem ukadu wsprzdnych obserwatora.
l +z
Obserwator/V^
y y
Rysunek 7.2.
Ukad wsprzdnych y Przeksztacony
wsprzdnych obserwatora
s^ ** yi ukad
obrcony wzgldem
ukladu
v
wsprzdnych y' Vl^- Przeksztacony kwadrat delu
obserwatora ' '~
Przeksztacenia modelu
Przeksztacenia modelu s uywane do manipulowania modelem i jego poszczeglnymi
obiektami. W tym przeksztaceniu obiekty s przesuwane, modelowane i skalowane.
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych 203
Rysunek 7.3 ilustruje trzy przeksztacenia modelu, zastosowane na obiektach. Rysunek 7.3a
pokazuje przesunicie (translacj), w ktrym obiekt jest przesuwany o zadany wektor.
Rysunek 7.3b przedstawia obrt (rotacj), w ktrej obiekt jest obracany wok zadanej osi.
Na koniec, rysunek 7.3c pokazuje efekt skalowania, w ktrym rozmiary obiektu s
zwikszane lub zmniejszane o zadan warto. Skalowanie moe by nierwnomierne
(obiekt moe by skalowany o rne wartoci w rnych kierunkach) i moe by uyte do
ciskania" lub rozcigania obiektw.
Rysunek 7.3.
Przeksztacenia
modelu
y---y
Przesunicia
(a)
Kocowy wygld sceny lub obiektu zaley gwnie od kolejnoci zastosowanych prze-
ksztace modelu. Jest to szczeglnie istotne w przypadku przesuni poczonych z
obrotem. Rysunek 7.4a przedstawia przeksztacenie kwadratu, w ktrym kwadrat jest
najpierw obracany wok osi z, a nastpnie przesuwany wzdu nowo przeksztaconej osi
x. Na rysunku 7.4b ten sam kwadrat jest najpierw przesuwany wzdu osi x, a
nastpnie obracany wok osi z. Rnica w kocowym pooeniu kwadratu wynika z tego,
e kade przeksztacenie odbywa si wzgldem poprzednio zastosowanych przeksztace.
Na rysunku 7.4a kwadrat jest najpierw obracany wzgldem rodka ukadu. Na rysunku
7.4b, po przesuniciu kwadratu, wykonywany jest obrt wzgldem nowo przesunitego
rodka ukadu.
204 Cz II Uywanie OpenGL
Rysunek 7.4.
Przeksztacenia
modelu:
obrt/przesunicie
oraz
przesunicie/obrt
Rysunek 7.5.
Dwa sposoby
patrzenia na
przeksztacenie
punktu obserwacji
Tak wic przeksztacenie punktu obserwacji jest wanie przeksztaceniem modelu za-
stosowanym w odniesieniu pozornego obiektu (kamery lub oka) przed narysowaniem
obiektw. Jak ju wkrtce zobaczysz, kady nastpny obiekt sceny podlega kolejnym
przeksztaceniom. Pocztkowe przeksztacenie zapewnia ukad odniesienia, na ktrym
opieraj si wszystkie nastpne przeksztacenia.
Przeksztacenia rzutowania
Przeksztacenia rzutowania s stosowane w kocowej scenie, z ju zastosowanymi
wszystkimi przeksztaceniami widoku modelu. Rzutowanie okrela bry widzenia i de-
finiuje paszczyzny obcinania. Co wicej, przeksztacenie rzutowania okrela, jak uko-
czona scena (po zakoczeniu modelowania) jest rzutowana na kocowy obraz na ekranie. W
tym rozdziale poznasz dwa rodzaje rzutowania: rwnolege {perspektywiczne.
Zalet rzutowania perspektywicznego jest to, e nie musisz sam decydowa, ktre obiekty
maj by mniejsze i jak mae powinny by odlege obiekty. Wszystko, co musisz
zrobi, to zdefiniowa scen za pomoc przeksztace widoku modelu, a nastpnie za-
stosowa przeksztacenie perspektywiczne. OpenGL zajmie si ca magi.
jego odlegoci od obserwatora jest do may (ogldamy due obiekty z duej odle-
goci). Tak wic samochd stojcy na wystawie moe by przedstawiony w rzucie
rwnolegym, ale jeli staniesz dokadnie przed mask i spojrzysz w kierunku samo-
chodu, perspektywa zaczyna nabiera duego znaczenia. Rzutowanie perspektywiczne
jest uywane przy renderowaniu scen skadajcych si z wielu rozrzuconych obiektw, na
przykad widokw architektonicznych czy widokw z lotu ptaka, lub w przypadku
duych obiektw, ktre w zalenoci od punktu obserwacji mog si wydawa znie-
ksztacone. W wikszoci przypadkw rzutowanie perspektywiczne jest najodpo-
wiedniejsze.
Przeksztacenia okna
Gdy wszystko zostanie wymodelowane i przeksztacone, mamy dwuwymiarowy rzut
sceny, ktry powinien zosta umieszczony w jakim oknie na ekranie. To odwzorowanie
obrazu na fizyczne wsprzdne okna jest ostatnim z przeksztace i nosi nazw
przeksztacenia okna. Okna (widoki) zostay omwione pokrtce w rozdziale trzecim, w
ktrym rozcigalimy lub ciskalimy obraz tak, aby kwadratowy rysunek zmieci si w
prostoktnym oknie.
Ach, te macierze...
Uzbrojeni w podstawowy sownik definicji i przeksztace, jestemy gotowi do prze-
prowadzenia prostych operacji na macierzach. Zobaczmy, jak OpenGL przeprowadza te
transformacje oraz jakie funkcje su do osignicia zamierzonego efektu.
Matematyka kryjca si za operacjami na macierzach jest znacznie uproszczona dziki
stosowaniu tzw. zapisu macierzowego. Kade z omawianych przeksztace mona osign
przez przemnoenie macierzy zawierajcych wsprzdne wierzchokw przez macierz
opisujc dane przeksztacenie. Tak wic wszystkie przeksztacenia dostpne w
OpenGL sprowadzaj si do mnoenia przez siebie dwch lub wicej macierzy.
Co to jest macierz?
Macierz nie jest niczym innym jak zestawem liczb uoonych w wierszach i kolumnach -
czyli z punktu widzenia programisty jest po prostu dwuwymiarow tablic. Macierz nie
musi by kwadratowa, jednak we wszystkich wierszach musi by ta sama ilo ele-
mentw; take wszystkie kolumny musz mie jednakow wysoko, tj. zawiera je-
dnakow ilo elementw. Przykady macierzy pokazuje rysunek 7.7. (Te macierze nie
reprezentuj niczego szczeglnego, a jedynie demonstruj wasn struktur). Zwr
uwag, e macierz moe skada si z pojedynczej kolumny elementw.
Rozdzia 7. + Manipulowanie przestrzeni 3D: transformacje wsprzdnych______ ___207
1 4 7 0 42
Rysunek 7.7.
2 5 8 1.5 0.877
Przykady macierzy
_3 6 9_ _2 14
Kolejka przeksztace
W celu zastosowania przeksztace opisywanych w tym rozdziale, bdziemy modyfikowa
gwnie dwie macierze: macierz widoku modelu oraz macierz rzutowania. Nie martw
si, OpenGL zapewnia specjalne funkcje przeznaczone do modyfikowania tych macierzy
jako caoci. Poszczeglne elementy tych macierzy bdziesz modyfikowa tylko wtedy, gdy
zechcesz osign jakie specjalne efekty.
Droga od wsprzdnych wierzchoka do wsprzdnych punktu na ekranie jest duga i
mudna. Proces przeksztace wsprzdnych zosta przedstawiony na rysunku 7.8.
Najpierw wsprzdne wierzchoka s zamieniane na macierz 1x4, w ktrej pierwsze
trzy elementy odpowiadaj wsprzdnym x, y i z. Czwarty element to wspczynnik
skalowania, ktry moesz sam okreli, stosujc funkcje wierzchokw wymagajce
podania czterech argumentw. To jest wanie wsprzdna w, domylnie przyjmujca
warto 1,0. Zwykle rzadko bdziesz modyfikowa t warto bezporednio, zamiast
tego stosujc jedn z funkcji skalowania macierzy widoku modelu.
Rysunek 7.8. O X ne Macierz x Macierz
Kolejka r y. ne widoku y. rzutowania -*
Dzielenie dla x/w
przeksztace
wierzchoka
W z
Sf w
ko modelu
Prze w cone
u perspektywy y /w -
rsp _ pun
wi ygin z/w
e ol lr ol Jcszt kt
a Znormalizowane wsprzdne urzdzenia
otrze
tedn
qi obcinania
e
rzch
Przeksztacenie
okna
(take macierz)
Wsprzdne okna
Nastpnie wierzchoek jest mnoony przez macierz widoku modelu, okrelajc wsp-
rzdne ukadu obserwatora. Wsprzdne ukadu obserwatora s mnoone przez macierz
rzutowania, a nastpnie obcinane przez wsprzdne obcinania. Powoduje to wyelimi-
nowanie wszystkich danych poza bry widzenia. Obcite wsprzdne s nastpnie
208 Cz II Uywanie <
Rysunek 7.9.
Rwnanie macierzowe
opisujce przeksztacenie
widoku modelu dotyczce
pojedynczego wierzchoka
Przesunicie
Spjrzmy na przykad modyfikujcy macierz widoku modelu. Powiedzmy, e chcea
narysowa kostk za pomoc funkcji auxWireCube() z biblioteki AUX. Wywoamy]
prostu
auxWireCube(10.Of);
// Narysowanie kostki
auxWireCube( l O . O f );
Parametry tej funkcji okrelaj przesunicie w osi x, y oraz z. W ten sposb tworzona jest
odpowiednia macierz i wykonywane jest mnoenie. Teraz podany wyej pseudokod moe
wyglda nastpujco, za efekt jego dziaania jest przedstawiony na rysunku 7.10.
// Przesunicie w gr osi Y o 10 jednostek
glTranslatef( O . O f , 10.Of, O . O g ) ;
// Narysowanie kostki
auxWireCube( l O . O f );
Rysunek 7.10.
Kostka przesunita
o 10 jednostek w
gr osi y
Obrt
Aby obrci obiekt wok jednej z trzech osi, musielibymy utworzy macierz obrotu i
przemnoy j przez macierz widoku modelu. Jednak take w tym przypadku mamy do
dyspozycji specjaln funkcj:
glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z ) ;
Ta funkcja obraca obiekt o kt angle wok linii wyznaczonej przez wektor [x, y, z].
Kierunek obrotu jest okrelany w stopniach w kierunku przeciwnym do ruchu wska-
zwek zegara. W najprostszym przypadku obrt nastpuje wok jednej z osi, tak e
musi zosta podana tylko jedna warto.
// Wykonanie przeksztacenia
glRotatef(45.Of, l.Of, l.Of, l . O f ) ;
// Narysowanie kostki
auxWireCube(10.0f);
Rysunek
7.11.
Kostka obrcona
wok zadanej osi
Skalowanie
Macierz tosamociowa
Z pewnoci zastanawiasz si, czemu suya wstpna dyskusja o macierzach. Czy nie
moglibymy po prostu uywa funkcji przesuwajc obiekty we waciwe miejsca? Czy
rzeczywicie powinno obchodzi nas to, e modyfikowana jest macierz widoku modelu?
Odpowied brzmi: i tak, i nie, ale tylko w przypadku rysowania w scenie pojedynczego
obiektu. Powodem jest to, e efekty uycia tych funkcji si kumuluj. Za kadym
razem, gdy wywoujesz jedn z tych funkcji, tworzona jest odpowiednia macierz, ktra jest
mnoona przez macierz widoku modelu. Otrzymana w wyniku macierz staje si now
macierz widoku modelu, modyfikowan przez nastpne przeksztacenie, itd.
Przypumy, e chcemy narysowa dwie kule: jedn o 10 jednostek w kierunku osi y i
jedn o 10 jednostek w kierunku osi x, tak jak pokazano na rysunku 7.13. Mgby pokusi
si o napisanie kodu wygldajcego mniej wicej tak:
// Przejcie o 10 jednostek w kierunku osi y
glTranslatef(O.Of, 10.Of, O . O f ) ;
// Narysowanie pierwszej kuli
auxSolidSphere(1.0f);
Rysunek 7.13.
Dwie kule narysowane na osiach y ix
Rysunek 7.14.
Wynik dwch
kolejnych przesuni
10
Ponisze dwie linie kodu aduj macierz tosamociow do macierzy widoku modelu:
glMatrixMode(GL_MODELVIEW);
glLoadldentity(};
Stosy macierzy
Nie zawsze zerowanie macierzy widoku modelu, przed umieszczeniem w scenie kolejnego
obiektu, jest podane. Czsto wygodnie jest zachowa biecy stan macierzy, a
nastpnie odtworzy go po umieszczeniu innych obiektw. Jest to szczeglnie uyteczne,
gdy na pocztku przygotujesz macierz widoku modelu jako macierz widoku sceny (czyli
punkt obserwacji nie znajduje si ju na pocztku ukadu wsprzdnych).
Aby to umoliwi, OpenGL tworzy stos macierzy dla macierzy widoku modelu oraz
macierzy rzutowania. Stos macierzy dziaa tak, jak kady stos programowy. Moesz
umieci biec macierz na stosie w celu zachowania jej stanu, a potem odpowiednio
przeksztaci grup nastpnych obiektw. Gdy zechcesz odtworzy stan macierzy, po
prostu zdejmiesz j ze stosu. Ilustruje to rysunek 7.16.
Rysunek 7.16.
Dziaanie stosu
macierzy
Stos macierzy
214 Cz II Uywanie OpenGL
Stos moe osign maksymaln wysoko, ktr mona odczyta za pomoc wywoa
glGet(GL_MAX_MODELVIEW_STACK_DEPTH);
lub
glGet(GL_MAX_PROJECTION_STACK_DEPTH) ;
Atomowy przykad
Sprbujmy zastosowa nabyt wiedz w praktyce. W nastpnym przykadzie zbudujemy
prosty, animowany model atomu. W rodku atomu umiecimy pojedyncz kul,
reprezentujc jdro, dookoa ktrego bd porusza si trzy elektrony. Uyjemy rzuto-
wania rwnolegego, tak jak we wszystkich poprzednich przykadach w ksice. (Inne
interesujce rzutowania zostan omwione w nastpnej sekcji, Rzutowania").
Rysunek 7.17.
Dziaanie programu ATOM
Potem nastpuje rysowanie elektronu (w postaci kuli), po czym jest odtwarzany stan
macierzy widoku modelu, przez zdjcie jej ze stosu macierzy:
// Rysowanie elektronu
auxSolidSphere( 6 . 0 f );
Rzutowania
Do tej pory w przykadach uywalimy macierzy widoku modelu do umieszczania punktu
obserwacji oraz do rozmieszczania obiektw w scenie. Macierz rzutowania okrela za
rozmiar i ksztat naszej bryy widzenia.
Jak dotd, cay czas tworzylimy zwyk, prostopadocienn bry widzenia, za pomoc
funkcji glOrtho okrelajc pooenie bliszej, dalszej, lewej, prawej, grnej oraz dolnej
paszczyzny obcinania. Gdy do macierzy rzutowania zostanie zaadowana macierz
tosamociowa, brya widzenia zajmuje przestrze od rodka ukadu do punktu o
wsprzdnych rwnych l dla wszystkich trzech osi - macierz rzutowania nie
realizuje zatem adnego skalowania ani perspektywy. Jak si wkrtce przekonamy, nie jest
to jedyna moliwo, jak mamy do dyspozycji.
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych 217
Rzutowanie rwnolege
W rzutowaniu rwnolegym, ktrego uywalimy do tej pory najczciej, brya
widzenia ma ksztat prostopadocienny, a zatem szeroko logiczna obiektu mierzona
wzdu przeciwlegych paszczyzn (tylnej i przedniej, grnej i dolnej, lewej i prawej)
jest identyczna. Daje to w efekcie rzut rwnolegy, odpowiedni dla zobrazowania
obiektw, dla ktrych chcemy unikn znieksztacenia perspektyw. Rzutowanie takie jest
przydatne w programach CAD i rysunkach architektonicznych (w izometriach), w
ktrych chcemy zachowa waciwe rozmiary i proporcje obiektw.
Rysunek 7.19 przedstawia ten obiekt lekko obrcony, aby mg si zorientowa jak
wyglda z boku.
Rysunek 7.19.
Dopiero po
obrceniu obiektu
moemy zorientowa
si co do jego
dugoci
Na rysunku 7.20 patrzymy dokadnie w kierunku pudeka. Poniewa w tym widoku pu-
deko nie zwa si wraz ze wzrostem odlegoci, nie jest to obraz zbliony do rzeczy-
wistego. Aby uzyska perspektyw, zastosujemy rzutowanie perspektywiczne.
218 Cz II * Uywanie OpenGL
Rysunek 7.20.
Wydrone pudeko
widziane prosto od
frontu
Rzutowanie perspektywiczne
W rzutowaniu perspektywicznym otrzymujemy efekt zmniejszania si obiektw wraz ze
wzrostem ich odlegoci od obserwatora. Szeroko tylnej paszczyzny bryy widzenia jest
rna od szerokoci paszczyzny przedniej. Tak wic obiekt pooony przy przedniej czci
bryy widzenia jest rysowany jako wikszy ni takie same obiekty pooone w dalszych
czciach bryy widzenia.
koci jest obliczany przez podzielenie wysokoci (h) przez szeroko (w) przedniej pa-
szczyzny obcinania.
Rysunek 7.22.
Ostrosup widzenia
definiowany funkcj
gluPerspective
Rysunek 7.23.
Wydrone pudeko
vi rzucie
perspektywicznym
Rysunek 7.24.
Pudeko "widziane
z boku; wyranie
wida efekt
zbiegania si.
krawdzi
220___________________ Cz II Uywanie
OpenGL
Rysunek 7.25.
Spogldanie w gb pudeka przy
zastosowanym rzutowaniu
perspektywicznym
// Zmiana bryy
widzenia i widoku.
// Wywoywane w
momencie zmiany
wymiaru okna
void
ChangeSize(GLsizei
w, GLsizei h)
{
GLfloat fAspect;
fAspect = (GLfloat)w/(GLfloat)h;
glMatrixMode(GL_MODELVIEW);
glLoadldentity();
Przykad daleko-blisko
Aby uzupeni przykady manipulowania przeksztaceniami widoku modelu i rzutowania,
przygotowalimy program stanowicy model dziaania ukadu sonecznego. W celu
uzyskania lepszego efektu wczylimy owietlenie i cieniowanie, dziki czemu lepiej
wida efekt dziaania programu. O cieniowaniu i owietleniu bdziemy mwi w dwch
nastpnych rozdziaach.
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych 221
W naszym modelu Ziemia porusza si dookoa Soca, za Ksiyc obiega Ziemi, rdo
wiata zostao umieszczone za plecami obserwatora, tak aby owietlao Soce.
Nastpnie jest przesuwane na rodek Soca, tak aby owietlao Ziemi i Ksiyc od
strony Soca, dziki czemu otrzymujemy fazy ksiyca. To doskonay przykad, jak
atwo mona uzyska realistyczne efekty w OpenGL.
Listing 7.3 przedstawia kod przygotowujcy rzutowanie oraz kod renderujcy, utrzymujcy
system w ruchu. Timer, zdefiniowany w innym miejscu programu, cztery razy na
sekund uniewania obszar okna, wymuszajc odwieenie jego zawartoci. Spogldajc na
rysunki 7.26 i 7.27, zwr uwag e Ziemia, gdy znajduje si bliej nas, jest wiksza ni
wtedy, gdy znajduje si po drugiej stronie Soca.
Rysunek 7.26.
Ukad soneczny z
Ziemi pooon
dalej
Rysunek 7.27.
Ukad soneczny z
Ziemi po dalszej
stronie
{
GLfloat fAspect;
// Zabezpieczenie przed dzieleniem przez O
i f ( h == 0) h 1;
// Ustawienie widoku na rozmiar okna
glViewport( O , O, w, h ) ;
// Obliczenie stosunku dugoci bokw okna
fAspect = (GLfloat)w/(GLfloat)h;
// Wyzerowanie ukadu wsprzdnych
glMatrixMode(GL_PROJECTION);
glLoadldentity();
// Kt widzenia 45 stopni, blisza i dalsza paszczyzna 1 . 0 i 425
gluPerspective( 4 5 . Of, fAspect, 1 . 0 , 4 2 5 . 0 ) ;
// Zerowanie macierzy widoku modelu
glMatrixMode(GL_MODELVIEW);
glLoadldentity();
adowanie macierzy
Do macierzy rzutowania, widoku modelu lub tekstury moesz zaadowa dowoln ma-
cierz. W tym celu musisz najpierw zadeklarowa tablic szesnastu wartoci, tworzc
macierz o wymiarach 4 x 4 . Uczy dan macierz biec, a nastpnie wywoaj funkcj
glLoadMatrix.
Macierz jest przechowywana w kolejnoci kolumn, co oznacza, e ka2da kolumna jest
kolejno przegldana od gry do dou. Numery kolejnych elementw przedstawia ry-
sunek 7.28. Poniszy kod pokazuje przebieg wypeniania tablicy macierz tosamo-
ciow, a nastpnie adowanie t tablic macierzy widoku modelu. Przedstawiony kod
stanowi odpowiednik funkcji wyszego poziomu, glLoadldentity.
224 Cz II Uywanie OpenGL
Rysunek 7.28. 04 03
Kolejno 5 9
Q
numerowania
2
elementw macierzy ' ^O "14
03 07 On " 1 5
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf( m ) ;
Inne przeksztacenia
Z powielania dziaania funkcji glLoadldentity czy glTranslatef nie pyn adne szcze-
glne korzyci. Rzeczywistym powodem korzystania z moliwoci wypenienia macierzy
dowolnymi wartociami jest tworzenie zoonych przeksztace macierzowych. Jedno
z takich przeksztace jest uywane do rysowania cieni, zajmiemy si tym w rozdziale 9.
Inne przeksztacenia umoliwiaj zawinicie obiektu dookoa innego obiektu lub
uzyskanie pewnych efektw soczewek. Informacje o tych zaawansowanych zastosowaniach
znajdziesz w dodatku B.
Podsumowanie
W tym rozdziale poznae koncepcje majce podstawowe znaczenie dla tworzenia trj-
wymiarowych scen w OpenGL. Nawet jeli nie potrafisz przemnoy macierzy w myli,
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych 225
Podrcznik
glFrustum
Przeznaczenie Mnoy biec macierz przez macierz rzutowania perspektywicznego.
Plik
nagwkowy void glFrustum(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top, GLdouble near, GLdouble far);
Skadnia
Ta funkcja tworzy macierz rzutowania perspektywicznego, tworzc rzut
perspektywiczny. Zakada si w nim, e oko jest pooone w punkcie (O, O,
0), za far okrela odlego do dalszej paszczyzny obcinania, a near -
bliszej. Ta funkcja moe zakci precyzj dziaania bufora gbokoci,
jeli stosunek odlegoci dalszej do bliszej (far/near) jest duy.
Parametry
left, right GLdouble: Wsprzdne lewej i prawej paszczyzny obcinania.
bottom, top GLdouble: Wsprzdne grnej i dolnej paszczyzny obcinania.
near,far GLdouble: Odlego do bliszej i dalszej paszczyzny obcinania. Obie
wartoci musz by dodatnie.
Zwracana Brak
warto Poniszy kod przygotowuje macierz rzutowania perspektywicznego,
definiujc bry widzenia od O do 100 jednostek w osi z. W osiach x i y
brya rozciga si na 100 jednostek w kadym kierunku:
226 Cz II Uywanie
glLoadldentity
Przeznaczenie Plik Zeruje biec macierz do macierzy tosamociowej.
nagwkowy
Skadnia Opis void glLoad!dentity(void);
Pa
Funkcja zastpuje zawarto biecej macierzy przeksztacenia
zawartoci macierzy tosamociowej, czyli innymi sowy, zeruje ukad
Zwracana warto wsprzdnych do ukadu wsprzdnych obserwatora.
Przykad Brak J
P
Poniszy kod ilustruje zerowanie macierzy widoku modelu:
glMatrixMode(GL_MODELVIEW);
Patrz take glLoadldentity();
glLoadMatrix, glMatrixMode, glMultMatrix, glPushMatrix
glLoadMatrix
Przeznaczenie aduje wskazan macierz do biecej macierzy.
Plik nagwkowy <gl.h>
Skadnia void glLoadMatrixd(const GLdouble *m);
void glLoadMatrixf(const GLfloat *m);
Opis Zastpuje zawarto biecej macierzy przeksztacenia zawartoci
wskazanej tablicy. Czasem jednak bardziej efektywne moe by uycie
specjalnych funkcji przeznaczonych do przygotowywania przeksztace,
takich jak glLoadldentity, glRotate, glTranslate czy glScale.
Parametry
K
OT GLdouble lub GLfloat: Ta tablica reprezentuje macierz o rozmiarach
4x4, ktra zostanie zaadowana do biecej macierzy przeksztacenia.
Macierz jest zapisana w formie tablicy szesnastu wartoci,
interpretowanych kolumnami, od lewej do prawej strony.
Zwracana warto Brak
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych__________227
glMatrixMode_______________________
Przeznaczenie Okrela biec macierz (rzutowania, widoku modelu lub tekstury).
Plik nagwkowy <gl.h>
Skadnia void glMatrixMode(GLenum mod);
Opis Ta funkcja jest uywana do wybierania stosu macierzy, ktry bdzie
wykorzystywany w nastpnych operacjach macierzowych.
Parametry
mod GLenum: Identyfikuje stos macierzy, ktry bdzie uywany w nastpnych
operacjach macierzowych. Dozwolone s wartoci zebrane w tabeli 7.2.
Zwracana warto Brak
Przykad Ponisze dwie standardowe linie kodu wybieraj do dziaania macierz
widoku modelu, a nastpnie aduj do niej macierz tosamociow.
glMatrixMode(GL_MODELVIEW);
glLoadldentityO;
Patrz take glLoadMatrix, glPushMatrix
Tabela 7.2.
Dostpne wartoci parametru funkcji glMatrixModeQ
g!MultMatrix
Przeznaczenie Mnoy biec macierz przez wskazan macierz.
Plik nagwkowy <gl.h>
Skadnia void glMultMatrixd(const GLdouble *m);
void glMultMatrixf(const GLfloat *m);
Opis Ta funkcja mnoybiec macierz przeksztacenia przez wskazan
macierz. Otrzymana macierz jest umieszczana, jako macierz bieca, na
szczycie stosu macierzy.
Parametry
*m GLdouble lub GLfloat. Ta tablica reprezentuje macierz o rozmiarach
4 x 4 , ktra zostanie przemnoona przez biec macierz. Macierz jest
zapisana w formie tablicy szesnastu wartoci, interpretowanych
kolumnami, od lewej do prawej strony.
Zwracana warto Brak
Przykad Poniszy kod tworzy macierz przesunicia i mnoyjprzez biec
macierz widoku modelu. Nowo utworzona macierz zastpuje macierz
biec. Przedstawione tu mnoenie macierzy moe zosta zastpione
przez wywoanie funkcji glTranslatef(10.0f, O.Of, O.Of);.
// Definicja macierzy przesunicia
glFloat m [ ] = { l.Of, O.Of, O.Of, 10.Of,
O.Of, l.Of, O.Of, O.Of,
O.Of, O . O f , l.Of, O . O f ,
O.Of, O.Of, O.Of, l.Of };
glPopMatrix
Przeznaczenie Plik Zdejmuje biec macierz ze stosu macierzy.
nagwkowy Skadnia
void glPopMatrix(void);
Opis
Ta funkcja suy do pobierania ze stosu ostatniej umieszczonej na nim
macierzy. Najczciej wykorzystuje si j do przywrcenia poprzedniego
stanu biecej macierzy przeksztacenia, odoonej wczeniej na stos za
pomoc funkcji glPushMatrix.
Zwracana warto Brak
Rozdzia 7. Manipulowanie przestrzeni 3D: transformacje wsprzdnych__________229
glPushMatrix_______________________
Przeznaczenie Umieszcza na stosie macierzy biec macierz przeksztacenia.
Plik nagwkowy <gl.h>
Skadnia void glPushMatrix(void);
Opis Ta funkcja jest uywana do umieszczenia biecej macierzy na szczycie
stosu macierzy. Najczciej celem tej operacji jest ch zachowania
biecego stanu macierzy, tak aby mc go pniej odtworzy
wywoaniem funkcji glPopMatrix.
Zwracana warto Brak
Przykad Zobacz glPopMatrix
Patrz take glPopMatrix
gIRotate
Przeznaczenie Mnoy biec macierz przez macierz obrotu.
Plik nagwkowy <gl.h>
Skadnia void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z);
void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
230 Cz II Uywanie OpenGL
auxSolidSphere(6.0f) ;
glScale, glTranslate
Patrz take
gIScale
Przeznaczenie Mnoy biec macierz przez macierz skalowania.
Plik <gl.h>
nagwkowy void glScaled(GLdouble x, GLdouble y, GLdouble z);
Skadnia void glScalef(GLfloat x, GLfloat y, GLfloat z);
Ta funkcja mnoybiec macierz przez macierz skalowania. Nowa
macierz staje si biec macierz przeksztacenia.
Opis
x,y, z Brak
glMatrixMode(GL_MODELVIEW);
glLoadldentity();
glScaled.Of, 0.5f, l.Of);
Patrz take glRotate, glTranslate
gITranslate
Przeznaczenie Plik Mnoy biec macierz przez macierz przesunicia.
nagwkowy <gl.h>
Skadnia void gITranslated(GLdouble x, GLdouble y, GLdouble z);
void glTranslatef(GLfloat x, GLfloat y, GLfloat z);
Opis Ta funkcja mnoybiec macierz przez macierz przesunicia. Nowa
macierz staje si biec macierz przeksztacenia.
Parametry
x,y,z GLdouble lub GLfloat: Wsprzdne x, y i z wektora przesunicia.
Zwracana warto Brak
Przykad Poniszy kod pochodzi z programu SOLAR w tym rozdziale. Umieszcza
Patrz take niebiesk kul (Ziemi) w odlegoci 105 jednostek w kierunku osi x od
pocztku ukadu wsprzdnych.
// Ziemia
glColor3f( O . O f , O . O f , l . O f ) ;
glTranslate(105.Of, O . O f , O . O f ) ;
auxSolidSphere( 1 5 . Of);
glRotate, glScale
glulookAt
Przeznaczenie Definiuje przeksztacenie punktu obserwacji.
Plik nagwkowy <glu.h>
Skadnia void gluLookAt(GLdouble eyex, GLdouble eyey, GLdouble eyez,
GLdouble centerx, GLdouble centery, GLdouble centerz, GLdouble upx,
GLdouble upy, GLdouble upz);
Opis Ta funkcja definiuje przeksztacenie punktu obserwacji na podstawie
pozycji oka, pooenia rodka sceny oraz wektora, ktry z punktu widzenia
obserwatora jest skierowany pionowo do gry.
Parametry eyex,
eyey, eyez GLdouble: Wsprzdne x, y i z punktu pooenia oka.
232 Cz II Uywanie OpenGL
gluOrtho2D
Przeznaczenie Definiuje dwuwymiarowe rzutowanie rwnolege.
Plik nagwkowy <glu.h>
Skadnia void gluOrtho2D(GLdouble left, GLdouble right, GLdouble bottom,
GLdouble top);
Opis Ta funkcja definiuje macierz dwuwymiarowego rzutowania rwnolegego.
Taka macierz rzutowania stanowi odpowiednik wywoania funkcji glOrtho /
parametrami near \far ustawionymi, odpowiednio, na O i 1.
Parametry
left, right GLdouble: Okrelaj lew i praw paszczyzn obcinania.
bottom, top GLdouble: Okrelaj doln i grn paszczyzn obcinania.
Zwracana warto Brak
Rozdzia 7. * Manipulowanie przestrzeni 3D: transformacje wsprzdnych 233
glOrtho, gluPerspectiye
gluPerspectiye
Przeznaczenie
Definiuje macierz rzutowania perspektywicznego. <glu.h>
Plik nagwkowy
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear,
Skadnia GLdouble zFar);
Ta funkcja tworzy macierz opisujc ostrosup widzenia we wsprzdnych
Opis sceny. Stosunek wysokoci do szerokoci (aspect) powinien odpowiada
stosunkowi dugoci krawdzi okna widoku (okrelonego funkcj glYiewport).
Dzielenie w rzutowaniu perspektywicznym odbywa si na podstawie
wartoci kta obserwacji w pionie (fovy) oraz odlegoci do bliszej
(zNear) i dalszej (zFar) paszczyzny obcinania.
Parametry
fovy aspect GLdouble: Szeroko kta widzenia w pionie, wyraona w stopniach.
GLdouble: Stosunek szerokoci do wysokoci ostrosupa widzenia.
zNear, zFar Uywany do wyznaczania kta widzenia w poziomie.
GLdouble: Odlegoci obserwatora od bliszej i dalszej paszczyzny
obcinania. Te wartoci s zawsze dodatnie.
Zwracana warto Brak
Przykad Poniszy kod pochodzi z przykadowego programu SOLAR. Tworzy
rzutowanie perspektywiczne, ktre powoduje, e planety pooone z
drugiej strony Soca s rysowane jako mniejsze ni planety pooone
bliej patrzcego.
// Zmiana bryy widzenia i widoku.
// Wywoywane w momencie zmiany wymiaru okna
void ChangeSize(GLsizei w, GLsizei h)
{
GLfloat fAspect;
// Zabezpieczenie przed dzieleniem przez O
i f ( h == 0) h = 1;
Rysunek 8.2.
Spektrum wiata
widzialnego
390 nm 720 nm
Rozdzia 8. * Kolory i cieniowanie_________________________________237
Odpowied na to pytanie zaczniemy od stwierdzenia, e ani czer, ani biel nie s kolorami.
W rzeczywistoci czer to brak koloru, za biel to rwnomierne wymieszane
wszystkie kolory naraz. Czyli biae przedmioty w rwnym stopniu odbijaj wszystkie
dugoci fal, za czarne obiekty pochaniaj wszystkie dugoci fal.
Rysunek 8.3.
Obiekt pochania /i^ rdo wiatu
niektre fotony, Twoje
oko
za odbija inne
^ f* .!<%
C
Xl
-^F v \\V'
\\V\
Strumie wiata (fotonw)
Baton czekoladowy
przez nerw wzrokowy przekazywane do mzgu, ktry interpretuje je jako wiato i kolor.
Im wicej fotonw trafia w komrk wiatoczu, tym bardziej zostaje ona podraniona.
Ten poziom podranienia jest interpretowany przez mzg jako natenie wiata, co jest
naturalne - im mocniejsze wiato, tym wicej fotonw trafia w komrki siatkwki.
Oko posiada trzy rodzaje komrek wiatoczuych. Wszystkie reaguj na fotony, jednak
kady rodzaj reaguje na inny zakres dugoci fal. Jeden rodzaj jest pobudzany przez
wiato zblione do czerwonego, drugi przez wiato zblione do zielonego, za trzeci
przez wiato zblione do niebieskiego. Tak wic wiato zawierajce gwnie czerwie
bdzie bardziej pobudza komrki reagujce na czerwie ni inne rodzaje komrek, za
mzg zinterpretuje sygnay jako wiato zawierajce w wikszoci czerwie. Mzg auto-
matycznie dokonuje oblicze - mieszanina rnych rodzajw wiata o rnych inten-
sywnociach zostanie zinterpretowana jako okrelony kolor. Tak wic jednakowe
natenie fal o wszystkich dugociach daje wiato biae, za brak jakiegokolwiek wiata jest
interpretowany jako czer.
Jak wida, kady kolor" postrzegany przez oko jest w rzeczywistoci zoony z fal
wietlnych o rnych dugociach i nateniach, pochodzcych z widzialnego spektrum.
Sprzt" w twoim oku wykrywa strumie fotonw jako wzgldne iloci wiata czerwo-
nego, zielonego i niebieskiego. Rysunek 8.4 przedstawia widzenie koloru brzowego,
skadajcego si z 60 procent fotonw czerwieni, 40 procent fotonw zieleni i 10 procent
fotonw wiata niebieskiego.
G R G
8~<Y~V-r
6 fotonw czerwieni, 4 Fotony zieleni i l foton niebieski
Przed kart Hercules istniaa karta CGA, Color Graphics Adapter. Wprowadzona wraz z
pierwszymi komputerami IBM PC, karta obsugiwaa rozdzielczo 320 x 200 punktw i
na ekranie mona byo wywietli do szesnastu kolorw jednoczenie. Bya dostpna
take wysza rozdzielczo (640 x 200), z dwoma dostpnymi kolorami, ale to rozwizanie
nie byo tak efektywne jak w przypadku karty Hercules (kolorowy monitor = duo ywej
gotwki). W porwnaniu z dzisiejszymi standardami, karta CGA miaa bardzo
niewielkie moliwoci, nie do porwnania z moliwociami graficznymi domo-
240____________________________________Cz II Uywanie OpenGL
Nastpny wikszy przeom w grafice PC nastpi w momencie, gdy IBM opracowa kart
EGA (Enhanced Graphics Adapter). Ta karta moga wywietli wicej ni 25 wierszy
tekstu w nowym trybie tekstowym, a take grafik rastrow o rozdzielczoci 640 x 350
pikseli, i to w szesnastu kolorach! Pewne techniczne poprawki eliminoway problem
migotania, wystpujcy w przypadku kart CGA, dziki czemu umoliwiay tworzenie
pynnych animacji. Od tego czasu nowe gry zrcznociowe, prawdziwe aplikacje graficzne,
a nawet grafika 3D w komputerach PC stay si nie tylko dostpne, ale take uzasadnione.
Stanowio to ogromny postp w porwnaniu z kart CGA, jednak grafika w
komputerach osobistych wci jeszcze bya w powijakach.
Ostatnim gwnym standardem kart graficznych opracowanych przez IBM bya karta
VGA (co w rzeczywistoci oznacza Yector Graphics Array, a nie, jak si powszechnie
uwaa, Video Graphics Adapter). Ta karta bya znacznie szybsza ni karta EGA, moga
wywietla 16 kolorw w wyszej rozdzielczoci 640 x 480 256 kolorw w niszej
rozdzielczoci (320 x 200). Te 256 kolorw byo wybieranych z palety ponad 16 milionw
dostpnych kolorw. W tym momencie otwary si podwoje dla wszelkiego rodzaju grafiki
komputerowej PC. Na ekranach pojawia si prawie fotorealistyczna grafika. Ray tracery,
trjwymiarowe gry, a nawet oprogramowanie do obrbki zdj masowo zaczy
pojawia si na rynku programw do komputerw osobistych.
IBM posiada take jeszcze inn, wysokowydajn kart graficzn- 8514 - do swoich stacji
roboczych". Ta karta moga wywietli 256 kolorw przy rozdzielczoci 1024 x 768.
IBM uzna, e ta karta bdzie wykorzystywana jedynie przez aplikacje CAD i naukowe!
Jednake jedno z pewnoci mona powiedzie o rynku konsumenta: zawsze chce
wicej. Ta krtkowzroczno kosztowaa firm IBM utrat pozycji niedocignionego lidera
na rynku kart graficznych do komputerw osobistych. Inni producenci zaczli tworzy
karty Super-VGA", mogce wywietla coraz wysze rozdzielczoci, w coraz
wikszych ilociach kolorw. Najpierw 800 x 600, potem 1024 x 768 i wicej, najpierw w
256 kolorach, potem w 32 tysicach, a nastpnie w ponad 65 tysicach kolorw. Obecne 24-
bitowe karty graficzne potrafi wywietli 16 milionw kolorw w rozdzielczo-ciach
1024 x 768 i wyszych. Tasze karty graficzne PC obsuguj peny kolor w
rozdzielczociach VGA lub w rozdzielczoci 800 x 600 kart Super-VGA. Wikszo
sprzedawanych obecnie komputerw osobistych moe wywietli przynajmniej 65 tysicy
kolorw w rozdzielczoci 1024 x 768.
Tryby graficzne
w komputerach osobistych
Microsoft Windows zrewolucjonizoway wiat grafiki PC w dwch aspektach. Po
pierwsze, stary si powszechnie uywanym graficznym rodowiskiem operacyjnym,
szybko zaadaptowanym przez rynek aplikacji biurowych i domowych. Po drugie, grafika
PC staa si duo atwiej dostpna dla programistw. W Windows sprzt zosta
uoglniony" przez sterowniki kart graficznych. Zamiast pisa instrukcje przeznaczone
bezporednio dla sprztu graficznego, dzisiejszy programista moe korzysta z jednego,
spjnego API, za samym porozumiewaniem si ze sprztem zajmie si system Win-
dows. Microsoft dostarcza zestawu podstawowych sterownikw (stworzonych z udziaem
producentw) do wikszoci popularnych kart graficznych. Producenci sprztu wraz ze
swoimi kartami dostarczaj specjalizowane sterowniki dla Windows, czsto take
mona pobra nowe wersje sterownikw przez Internet lub BBS.
Rozdzielczoci ekranu
Rozdzielczoci ekranu w przypadku obecnych komputerw PC zmieniaj si od 640 x
480 pikseli do 1280 x 1024 i wikszych. Jednak sama rozdzielczo obrazu nie jest
najwaniejszym czynnikiem podczas tworzenia aplikacji graficznych. Do wikszoci
zada graficznych w zupenoci wystarcza nisza rozdzielczo, 640 x 480 pikseli.
Waniejszy jest rozmiar okna, brany pod uwag przy ustalaniu bryy obcinania i widoku
(patrz rozdzia 3). Skalujc rozmiar rysunku do rozmiaru okna, moesz atwo obsuy
rne rozdzielczoci i rozmiary okien, z jakimi masz do czynienia. Dobrze napisana
aplikacja graficzna wywietli podobny obraz bez wzgldu na rozdzielczo ekranu.
Uytkownik powinien automatycznie dostrzec wicej szczegw w momencie przejcia
do wyszej rozdzielczoci.
Gboko koloru
O ile wraz ze wzrostem rozdzielczoci ekranu wzrasta ostro i ilo widocznych szczegw
obrazu, o tyle wraz ze wzrostem dostpnej iloci kolorw zwiksza si przejrzysto
rysunku. Obraz wywietlony w komputerze potraficym wywietli miliony kolorw
wyglda zdecydowanie lepiej ni wywietlony w szesnastu kolorach. Z punktu widzenia
242____________________________________Cz II Uywanie OpenGL
programisty, powiniene bra pod uwag tylko trzy gbokoci kolorw: 4 bity, 8 bitw i 24
bity.
Kolor 4-bitowy
W najgorszym razie twj program moe zosta uruchomiony w trybie graficznym umo-
liwiajcym wywietlenie jedynie 16 kolorw - nazywanym 4-bitowym, gdy kolor kadego
piksela jest opisany przez 4 bity. Te cztery bity reprezentuj warto od O do 15,
stanowic indeks do zestawu szesnastu predefmiowanych kolorw. Majc do dyspozycji
jedynie 16 kolorw, nie moesz uczyni zbyt wiele w celu poprawienia przejrzystoci i
ostroci rysowanego obrazu. Oglnie akceptuje si, e wikszo powanych aplikacji
graficznych moe ignorowa tryb o 16 kolorach.
Kolor 8-bitowy
Kolor 8-bitowy umoliwia wywietlenie na ekranie do 256 kolorw. Stanowi to znaczny
krok naprzd, za w poczeniu z ditheringiem (roztrzsaniem, ktre omwimy w dalszej
czci rozdziau) umoliwia otrzymanie w wielu przypadkach satysfakcjonujcych
wynikw. Kady piksel jest opisany przez 8 bitw, przechowujcych wartoci od O do 255,
stanowice indeks do tablicy kolorw, zwanej palet. Kolory w palecie mog by
wybierane z ponad 16 milionw dostpnych kolorw. Jeli potrzebujesz 256 odcieni koloru
czerwonego, sprzt jest w stanie ci je zapewni.
Kady kolor w palecie jest okrelany przez podanie omiobitowych wartoci, z osobna
dla kadej barwy skadowej koloru, tak wic intensywno kadej barwy skadowej moe
waha si w przedziale od O do 255. W efekcie kolorowi w palecie mona przypisa
dowolny z 16 milionw dostpnych kolorw. Przez uwane dobranie kolorw palety
mona zapewni prawie fotorealistyczny obraz na ekranie komputera PC.
Kolor 24-bitowy
Obecnie obrazy najwyszej jakoci tworzone s w trybie 24-bitowym. W tym trybie
kady piksel jest opisany przez pene 24 bity, po osiem bitw dla intensywnoci kadej
barwy skadowej (8 + 8 + 8 = 24). Dziki temu kademu pikselowi na ekranie mona
przypisa jeden z ponad 16 milionw dostpnych kolorw. Najwiksz wad tego trybu jest
ilo pamici zajmowanej przez obraz (ponad 2 MB dla ekranu 1024 x 768). Oprcz tego,
przenoszenie obszarw obrazu lub po prostu odwieanie ekranu podczas animacji trwa
znacznie duej. Na szczcie, obecne akcelerowane karty graficzne s zoptymalizowane
dla operacji tego typu.
W celu poprawy wydajnoci, pewne karty obsuguj 32-bitowe tryby koloru, czasem
okrelane jako True Color. W rzeczywistoci, w trybie 32-bitowym na ekranie nie mona
wywietli wicej kolorw ni w trybie 24-bitowym, lecz jedynie poprawia si wydajno
programw, gdy dane kadego piksela zostaj uoone na granicy 32 bitw. Niestety,
powoduje to utrat omiu bitw (jednego bajtu) dla kadego piksela. W obecnych, 32-
bitowych procesorach Intela, dostp do adresw pamici uoonych na granicy 32 bitw
odbywa si znacznie szybciej ni w innych przypadkach.
W celu bardziej efektywnego wykorzystania pamici czsto stosuje si dwa inne popularne
tryby. Pierwszy z nich to tryb 15-bitowy, w ktrym na kad barw skadow
przypada po pi bitw. Kady piksel moe wic zosta wywietlony w jednym z
32768 kolorw. W trybie 16-bitowym, jednej ze skadowych przypada dodatkowy bit;
zwykle jest to skadowa zielona. Dziki temu na ekranie mona wywietli 65 536 do-
stpnych kolorw. Ten ostatni tryb, w przypadku reprodukcji obrazw fotograficznych, jest
praktycznie tak samo efektywny jak tryb 24-bitowy. W przypadku wikszoci obrazw
fotograficznych trudno jest dostrzec rnic pomidzy 16- a 24-bitowym trybem, cho
jeli w obrazie wystpuj wiksze gadko cieniowane paszczyzny, w trybie 16-bitowym
mona zauway na nich pewne paski.
Z punktu widzenia programisty, kolor w trybach 15- i 16-bitowych jest okrelany tak
samo, jak w trybach 24-bitowych - przez podanie intensywnoci trzech barw skado-
wych. Sprzt lub sterownik urzdzenia pobieraj t 24-bitow warto i przed ustawie-
niem koloru piksela konwertuj j do 15 lub 16 bitw.
Wybr koloru
Wiesz ju, e OpenGL okrela konkretny kolor przez oddzielne podanie intensywnoci
skadowych czerwonej, zielonej i niebieskiej. Wiesz take e sprzt obsugiwany przez
Windows moe wywietli prawie wszystkie kombinacje lub tylko bardzo niewiele
kombinacji koloru. Jak wic okrela si podany kolor jako wartoci intensywnoci
skadowych czerwonej, zielonej i niebieskiej? I jak Windows wypenia dania doty-
czce kolorw, ktre nie s dostpne?
Kostka kolorw
Poniewa kolor jest okrelany przez trzy dodatnie wartoci poszczeglnych skado-
wych, moemy zamodelowa dostpne kolory jako bry, ktr nazywa si przestrzeni
koloru RGB. Rysunek 8.6 pokazuje, e ta przestrze wyglda jak pocztek ukadu
wsprzdnych z osiami dla kolorw czerwonego, zielonego i niebieskiego. Wsprzdne
czerwona, zielona i niebieska odpowiadaj osiom x, y oraz z. W pocztku ukadu (0,0,0)
wzgldne intensywnoci wszystkich trzech skadowych wynosz zero, wic w efekcie
otrzymujemy czer. Maksymalna gboko koloru w komputerach PC to 24 bity, z 8
bitami na kad barw skadow, moemy wic zaoy, e warto 255 na kadej z osi
reprezentuje pene nasycenie danego koloru. Otrzymujemy wic kostk o dugoci boku
wynoszcej 255. Wierzchoek pooony dokadnie naprzeciw czerni, w ktrej ko-
244 Cz II Uywanie OpenGL
Niebieski
Ta kostka kolorw" (rysunek 8.7) zawiera wszystkie dostpne kolory, na swojej po-
wierzchni lub we wntrzu. Na przykad, wszystkie dostpne odcienie szaroci pomidzy
czerni i biel wystpuj na przektnej czcej wierzchoki (O, O, 0) i (255, 255, 255).
Rysunek 8.7.
Przestrze kolorw
RGB (255,255,0)
Cyjan
(0,255,255)
Czerwony
Fiolet
(0,0,255 (255,0,255)
Niebieski )
Rysunek 8.8.
Wynikiem dziaania
programu CCUBE
jest kostka kolorw
Rozdzia 8. * Kolory i cieniowanie_________________________________245
Rysunek 8.8 przedstawia gadko cieniowan kostk koloru, narysowan przez przykadowy
program CCUBE z tego rozdziau. Powierzchnia kostki zawiera przejcia kolorw od
czerni w jednym rogu do bieli w przeciwnym. Czerwie, ziele i bkit wystpuj w
swoich rogach, 255 jednostek od czerni. Dodatkowo, kolory ty, cyjan i fiolet zajmuj
rogi odpowiadajce kombinacjom trzech barw podstawowych. Ten program dziaa
poprawnie nawet w trybie 16-kolorowym, za jak to si dzieje, dowiesz si w dalszej
czci rozdziau. W tym programie mona take obraca kostk w celu obejrzenia
wszystkich cian; su do tego klawisze kursora.
W nazwie funkcji <x> reprezentuje ilo argumentw; moe to by 3 dla trzech argu-
mentw - red, green oraz blue lub 4, jeeli wystpuje dodatkowy argument alpha.
(Skadnik alpha okrela przejrzysto koloru i zostanie omwiony szczegowo w roz-
dziale 15). Na razie bdziemy uywa wersji funkcji z trzema argumentami.
<t> w nazwie funkcji okrela typ uywanych argumentw. Moe to by b, d, f, i, s, ub, ui,
us dla, odpowiednio, typw byte, double, float, integer, short, unsigned byte, unsig-ned
integer oraz unsigned short. Inne wersje funkcji zawieraj w nazwie jeszcze liter v; te
wersje jako parametru wymagaj tablicy zawierajcej argumenty (v oznacza vectored w
tablicy). W sekcji podrcznika znajdziesz dokadniejszy opis parametrw funkcji
glColor().
Wikszo programw OpenGL, ktre napotkasz, korzysta z funkcji glColorSf i okrela
intensywno kadej skadowej jako 0,0 dla braku skadowej i 1,0 dla j ej penej intensy-
wnoci. Jeli jednak przyzwyczaie si do programowania w Windows, moe by ci a-
twiej korzysta z wersji glColorSub tej funkcji. Ta wersja wymaga podania trzech bajtw
bez znaku, zawierajcych wartoci od O do 255, okrelajcych intensywnoci skadowej
czerwonej, zielonej i niebieskiej. Uycie tej wersji funkcji przypomina uycie makra RGB
z Windows:
glColor3ub(0, 255, 128) = R G B ( 0 , 255, 1 2 8 ) ;
Cieniowanie
W naszej pierwszej definicji funkcji glColor stwierdzilimy, e ta funkcja ustala biecy
kolor rysowania, za wszystkie obiekty tworzone po tym poleceniu bd rysowane bie-
cym kolorem. Przy omawianiu prymityww OpenGL (rozdzia 6) rozszerzylimy t
definicj nastpujco: funkcja glColor ustawia biecy kolor rysowania, ktry jest uy-
wany do wszystkich wierzchokw rysowanych po wywoaniu tej funkcji. Jak dotd, we
wszystkich przykadach rysowalimy bryy szkieletowe lub bryy jednolite, w ktrych
kada ze cian miaa okrelony, jednolity kolor. Gdybymy jednak okrelili inny kolor dla
kadego wierzchoka prymitywu (punktu, linii lub wielokta), jaki kolor miaoby
wntrze?
W przypadku odcinka mamy dwa wierzchoki, wic kady z nich moe mie inny kolor.
Kolor rysowanej linii zaley od modelu cieniowania. Cieniowanie jest zdefiniowane po
prostu jako pynne przejcie od jednego koloru do innego. Kade dwa punkty w prze-
strzeni kolorw RGB (rysunek 8.7) mog zosta poczone lini prost.
Pynne (ang. smooth) cieniowanie powoduje zmian koloru odcinka w miar przecho-
dzenia przez bry kolorw z jednego punktu do drugiego. Na rysunku 8.9 przedstawiono
kostk kolorw z zaznaczonymi wierzchokami dla czerni i bieli. Poniej przedstawiono
odcinek z dwoma wierzchokami, czarnym i biaym. Kolory uyte do narysowania od-
cinka odpowiadaj kolorom lecym wzdu odcinka czcego wierzchoki kostki ko-
lorw, od czerni do bieli. Otrzymujemy w wyniku odcinek zmieniajcy kolor od
czarnego, poprzez coraz janiejsze odcienie szaroci, a do osignicia na kocu bieli.
Rysunek 8.9.
Sposb cieniowania
odcinka od czerni do
bieli
Rozdzia 8. * Kolory i cieniowanie________________________________247
Rysunek 8.10.
Trjkt w przestrzeni kolorw RGB
// Wczenie
pynnego
cieniowania
glShadeModel(GL
_SMOOTH);
// Rysowanie trjkta
glBegin(GLJTRIANGLES);
// Czerwony grny wierzchoek
glColor3ub((GLubyte)255,(GLubyte)O,(GLubyte)0);
glVertex3f( O . O f ,200.Of,O . O f );
// Zielony wierzchoek w prawym dolnym rogu
glColor3ub((GLubyte)O, (GLubyte)255, (GLubyte)0) ;r
glVertex3f(200.Of,-70.Of,O.Of);
(Innym modelem cieniowania, ktry mona wczy za pomoc funkcji glShadeModel, jest
model GL_FLAT, czyli paskie cieniowanie. Paskie cieniowanie oznacza, e wewntrz
prymityww nie s wykonywane adne obliczenia zwizane z cieniowaniem. Oglnie,
przy paskim cieniowaniu kolor wntrza prymitywu jest kolorem okrelonym przy
definiowaniu jego ostatniego wierzchoka. Jedynym wyjtkiem jest prymityw GL_
POLYGON, w ktrym kolorem caego wielokta jest kolor pierwszego wierzchoka).
Nastpnie kod z listingu 8.1 ustala kolor grnego wierzchoka na czystoczerwony, kolor
prawego dolnego wierzchoka na zielony, za kolor ostatniego, lewego dolnego wierz-
choka na niebieski. Poniewa jest wczone pynne cieniowanie, wntrze trjkta jest
rysowane w taki sposb, aby powstay pynne przejcia pomidzy kolorami.
Wynik dziaania programu TR1ANGLE widzimy na rysunku 8.11. Obraz stanowi repre-
zentacj paszczyzny przedstawionej graficznie na rysunku 8.10.
Rysunek
8.11.
Wynik dziaania
programu
TR1ANGLE
Zwykle nie bdziesz sam stosowa tego typu cieniowania. Jest ono uywane gwnie w
celu stworzenia efektw owietlenia; take w tym przypadku OpenGL przychodzi z
pomoc. Owietleniem zajmiemy si w rozdziale 9.
Rozdzia 8. * Kolory i cieniowanie 249
Palety Windows
Przykadowe programy TRIANGLE i CCUBE dziaaj poprawnie bez wzgldu na ilo
dostpnych kolorw. Jeli moesz zmieni gboko koloru w swoim systemie, sprbuj
uruchomi te programy przy rnych gbokociach koloru, poczynajc od 16 kolorw, a
koczc na 16 milionach kolorw, jeli karta to umoliwia. Zauwaysz, e kolory
uyte do pynnego przejcia zale od gbokoci koloru. Rysunki 8.12a i 8.12b przed-
stawiaj wynik dziaania przykadowego programu TRIANGLE odpowiednio przy 16 i
przy 16 milionach kolorw. Mimo e rysunki nie s wydrukowane w kolorze, widzimy, e
cieniowanie drugiego trjkta jest znacznie pynniejsze.
Rysunek 8.12a.
Wynik dziaania
programu
TRIANGLE przy 16
kolorach
Rysunek 8.12b.
Przy 16 milionach
kolorw cieniowanie
trjkta jest znacznie
pynniejsze
Dopasowywanie kolorw
Co si dzieje, gdy chcesz narysowa piksel w konkretnym kolorze, okrelonym omawia-
nymi przed chwil wartociami RGB? Wewntrznie Windows definiuje kolor uywajc
makra RGB, czyli omiu bitw dla kadej z barw skadowych: czerwonej, zielonej i nie-
bieskiej; w OpenGL moesz odtworzy to dziaanie uywajc funkcji glColorSub.
Jeli karta graficzna pracuje akurat w trybie 24-bitowym, to kady piksel jest rysowany
dokadnie w kolorze okrelonym przez t 24-bitow warto (trzy intensywnoci po 8
bitw). W trybach 15- i 16-bitowych, Windows przekazuje 24-bitow warto do ste-
rownika urzdzenia, ktry przed wywietleniem piksela zamienia j na warto 15- lub 16-
bitow. W 24-bitowym trybie kostka RGB mierzy 255 jednostek (czyli 8 bitw)
250____________________________________Cz II Uywanie OpenGL
w kadym kierunku. W trybach 15- lub 16-bitowym kostka kolorw mierzy 32 jednostki
(5 bitw) lub 64 jednostki (6 bitw) w danym kierunku. Sterownik urzdzenia dopasowuje
24-bitow warto koloru do najbliszej wartoci koloru w 15- lub 16-bitowej kostce
kolorw.
Rysunek 8.13 przedstawia sposb odwzorowania 8-bitowej skadowej czerwieni na 5-bi-
tow warto czerwieni.
Rysunek 8.13.
Odwzorowanie
redniointensywnej
czerwieni z 8-bitowej
wartoci na warto 5-
bitow
Na samym
kocu skali,
w trybie 4-
bitowym
mona
wywietli
tylko 16
kolorw. Te kolory s ustalone i nie mona ich modyfikowa. Wewntrznie Windows w
dalszym cigu reprezentuje kolory jako 24-bitowych wartoci RGB. Gdy okrelasz kolor
rysowania, za pomoc makra RGB lub funkcji glColor3ub, Windows uywa najbardziej
zblionego z 16 dostpnych kolorw. Jeli kolor jest przybliony do wypenienia, zostaje
przybliony przez tzw. dithering kilku dostpnych kolorw.
Dithering
Gdy mamy do dyspozycji jedynie szesnacie kolorw, tworzona grafika raczej nie bdzie
miaa najwyszej jakoci. Jedyn rzecz, jaka moe pomc, jest tzw. dithering
(roztrzsanie), stosowany w tym trybie przez GDI przy wypenianiu wieloktw lub
powierzchni. Roztrzsanie oznacza umieszczanie blisko siebie punktw w rnych ko-
lorach, w celu wywoania iluzji innego koloru zoonego. Na przykad, jeli obok siebie
uoysz w szachownic punkty niebieskie i te, cay dese bdzie sprawia wraenie
zielonego. Bez mieszania kolorw, ziele wydawaaby si ziarnista. Zmieniajc wza-
jemne proporcje tych i niebieskich punktw moesz zmienia intensywno zieleni
caego deseniu.
Windows uywa roztrzsania w celu otrzymania kolorw niedostpnych w biecej palecie.
W trybie 16-kolorowym, w przypadku bardziej zoonych scen, jako obrazu jest zwykle
bardzo kiepska. Rysunek 8.12 jasno ilustrowa roztrzsanie w Windows; prbowalimy na
nim odtworzy trjkt RGB w systemie posiadajcym jedynie 16 kolorw. Oglnie,
Windows nie wykonuje roztrzsania w OpenGL.
OpenGL moe uywa wasnego roztrzsania, ktre wcza si poleceniem
glEnable(GL_DITHER) ;
Rozdzia 8. Kolory i cieniowanie________________________________251
Udostpnianie palety
Wielozadaniowo w Windows umoliwia wystpowanie na ekranie kilku aplikacjom
naraz. Sprzt jednak obsuguje jednoczenie tylko 256 kolorw na ekranie, wic wszystkie
aplikacje musz korzysta z tej samej palety systemowej. Jeli jedna z aplikacji zmieni
palet systemow, obrazy w innych oknach mog zmieni kolory, dajc w efekcie
psychodeliczne tcze. Aby rozdzieli palet pomidzy rne aplikacje, Windows rozsya
zestaw komunikatw. Aplikacje s informowane o tym, e ktra z aplikacji
252____________________________________Cz II Uywanie OpenGL
zmodyfikowaa systemow palet oraz o tym, e ich okno znalazo si w ognisku wej-
ciowym i w zwizku z tym mog same zmodyfikowa palet systemow.
return nRet; }
break;
i
// Wybranie palety w kontekcie urzdzenia
SelectPalette(hDC,hPalette,FALSE);
break;
Tworzenie palety
Niestety, zagadnienia zwizane z palet s zem koniecznym, gdy w dalszym cigu
aplikacje mog zosta uruchomione w systemach dziaajcych w trybie 8-bitowym. C
masz wic zrobi, gdy twj program zostanie uruchomiony w systemie umoliwiajcym
wywietlenie jedynie 256 kolorw?
W przypadku reprodukcji obrazw, zalecamy wybranie palety kolorw cile odzwier-
ciedlajcej oryginalne kolory obrazu. Jednak w przypadku oglnych aplikacji OpenGL,
przydatniejsze bdzie wybranie palety kolorw zapewniajcej najbardziej oglne roz-
mieszczenie kolorw w przestrzeni RGB. Sztuczka polega na takim wybraniu kolorw,
aby byy one rwnomiernie rozmieszczone w kostce kolorw. Wtedy, gdy zostanie
wskazany kolor nie wystpujcy akurat w palecie, Windows wybierze kolor najbardziej
zbliony. Jak ju wspomniano, takie rozwizanie nie jest idealne, ale w przypadku scen
renderowanych za pomoc OpenGL stanowi wszystko, co moemy zrobi. Dopki w scenie
nie wystpuje mapowanie tekstur zawierajcych szeroki zakres kolorw, otrzymane
wyniki mog by cakiem zadowalajce.
254 Cz II Uywanie OpenGL
// Czy ten format pikseli wymaga palety? Jeli nie, po prostu nie //
twrz j e j i zwr warto NULL if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return NULL;
Struktura palety
Aby utworzy palet, musisz najpierw zaalokowa pami dla struktury LOGPALET-
TE. Ta struktura jest wypeniana informacjami opisujcymi palet, a nastpnie prze-
kazywana funkcji Win32, CreatePalette(). Struktura LOGPALETTE jest zdefiniowana
nastpujco:
typedef struct tagLOGPALETTE { // Igpl
WORD palYersion;
WORD palNumEntries;
PALETTEENTRY palPalEntry[1]; }
LOGPALETTE;
Pierwsze dwie skadowe to nagwek palety, okrelajcy jej wersj (zawsze ustawiany na
0x300) oraz ilo pozycji palety (256 dla trybw 8-bitowych). Kada pozycja jest
zdefiniowana jako struktura PALETTEENTRY, zawierajca skadowe RGB dla pozycji
koloru.
Poniszy kod alokuje pami dla palety logicznej:
LOGPALETTE *pPal; // Wskanik do obszaru pamici dla palety logicznej
// i wszystkie j e j pozycje
pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +
nColors*sizeof(PALETTEENTRY));
nColors okrela ilo kolorw w palecie, ktra do naszych celw zawsze wynosi 256.
Kada pozycja palety jest struktur PALETTEENTRY, zdefiniowan nastpujco:
typedef struct tagPALETTEENTRY { // pe
BYTE peRed;
BYTE peGreen;
BYTE peBlue;
BYTE peFlags; }
PALETTEENTRY;
Paleta 3-3-2
A teraz par sztuczek. Nasze 256 pozycji palety musi by nie tylko rwnomiernie roz-
prowadzone w obrbie kostki kolorw, ale musi take by uoone w odpowiedniej ko-
lejnoci. Wanie ta kolejno umoliwi OpenGL wybranie z palety najbliszej wartoci
koloru. Jak pamitamy, w 8-bitowych trybach mamy po trzy bity dla czerwieni i zieleni
oraz dwa bity dla bkitu. Tak palet zwykle okrela si mianem palety 3-3-2. Tak
wic nasza kostka kolorw RGB bdzie mierzya 8x8x4 jednostki, odpowiednio w osiach
czerwonej, zielonej i niebieskiej.
Aby wyszuka w tej palecie dany kolor, warto 8-8-8 (24-bitowa warto koloru)
musi zosta przeskalowana do wartoci 3-3-2. Ta omiobitowa warto staje si inde-
ksem do naszej palety. Intensywnoci czerwieni od O do 7 w palecie 3-3-2 musz odpo-
wiada intensywnociom od O do 255 w palecie 8-8-8. Sposb poczenia skadowych R,
G i B w indeks palety ilustruje rysunek 8.14.
Rysunek 8.14. Intensywno Intensywno Intensywno
Upakowanie bitw bkitu zieleni czerwieni
palety 3-3-2 '***A>
7|t|5|4|3|l|l|Q|
.
Gdy budujemy palet, w ptli przechodzimy przez wartoci od O do 255. Nastpnie de-
komponujemy indeks do wartoci czerwieni, zieleni i bkitu, reprezentowanych przez te
wartoci (w ramach palety 3-3-2). Kada skadowa jest mnoona przez 255, po czym
dzielona przez maksymaln reprezentowaln warto, co daje efekt skokowego przej-
256 Cz II * Uywanie OpenGL
cia od wartoci O do 7 dla czerwieni i zieleni oraz od O do 3 dla bkitu. W celu zade-
monstrowania przebiegu oblicze, tabela 8.1 przedstawia wartoci niektrych pozycji
palety.
Tabela 8.1.
Kilka przykadw wartoci pozycji palety 3-3-2
Budowanie palety
Niestety, w tym momencie OpenGL w Windows obsuguje w trybie RGBA jedynie palet
3-3-2. Jest to okrelone w strukturze PIXELFORMATDESCRIPTOR zwracanej przez
funkcj DescribePixelFormat(). Pola cRedBits, cGreenBits oraz cBlueBits tej struktury
podaj 3, 3 oraz 2 jako liczb bitw reprezentujcych poszczeglne skadowe. Co wicej,
pola CRedShift, cGreenShift oraz cBlueShift okrelaj, o ile bitw naley przesun
kad warto w lewo (w tym przypadku o O, 3 i 6 bitw dla czerwieni, zieleni i bkitu).
Te ustawienia wartoci tworz indeks pozycji palety (rysunek 8.14).
Kod z listingu 8.4 tworzy w miar potrzeby palet i zwraca jej uchwyt. Ta funkcja wy-
korzystuje pola iloci i przesunicia bitw dla kadej skadowej ze struktury PIXEL-
FORMATDESCRIPTOR, tworzc palet 3-3-2.
// Otworzenie palety
hRetPal = CreatePalette(pPal);
Pewne ograniczenia
Nie wszystkie pozycje 256 - kolorowej palety zostan odwzorowane do palety systemowej.
Windows rezerwuje 20 pozycji dla statycznych kolorw systemowych, obejmujcych 16
standardowych kolorw EGA/YGA. Zabezpiecza to przed zmian kolorw
komponentw okien (paskw tytuowych, przyciskw etc.) przez aplikacj zmieniajc
palet systemow. Gdy aplikacja realizuje swoj palet, tych 20 kolorw pozostanie
niezmienionych. Na szczcie, niektre z tych kolorw wystpuj lub cile odzwierciedlaj
kolory z palety 3-3-2. Te, ktre nie odzwierciedlaj danych kolorw, s na tyle
podobne, e, nie raczej zauwaysz rnicy.
Kolejny powd do uywania trybu indeksu koloru maj aplikacje, ktre wykorzystuj
kolor do wskazania trzeciego wymiaru - na przykad stopnia wgbienia pewnych ob-
szarw obiektu. Moesz take uy tego trybu przy tworzeniu obrazw, w ktrych nie jest
wymagana zorganizowana paleta. Na koniec, w przypadku trybw 8-bitowych, tryb
indeksu koloru moe by troch szybszy, gdy podczas zmiany palety czsto konieczne
jest manipulowanie tylko jednym kanaem (a nie trzema czerwonym, zielonym i nie-
bieskim).
Oprcz ogranicze co do wyboru kolorw, w trybie indeksu kolorw nie mona korzysta
z pewnych innych efektw specjalnych OpenGL wcznie z wieloma efektami
owietlenia i cieniowania, antyaliazingu czy alpha blendingu. Oglnie lepiej wic ko-
rzysta z trybu RGBA.
Jak ju wspomniano, najwiksz korzyci pync ze stosowania trybu indeksu koloru jest
wiksza kontrola nad palet w 8-bitowych trybach koloru. Paleta 3-3-2 ogranicza
moliwoci wyboru kolorw, wic gdy w trybie 8-bitowym potrzebujesz dwustu odcieni
czerwieni w celu naprawd gadkiego pocieniowania obiektu, nie masz szczcia.
Jednak w trybie indeksu koloru, pozycjom palety mona przypisa dowolne wartoci
kolorw, od najciemniejszych do najjaniejszych. Moesz przy tym podzieli palet na
dowoln ilo pasm. Przykadowy program INDEX wywietla wanie taki trjkt,
pynnie pocieniowany od czerni do czerwieni (rysunek 8.15). Takie cieniowanie w trybie
8-bitowym, przy uyciu palety 3-3-2, nie byoby moliwe.
Rysunek 8.15.
Wynik dziaania programu IN D EX,
przedstawiajcy dwiecie odcieni czerwieni
// Utworzenie palety
hRetPal = CreatePalette (pPal);
Zwr uwag, e ten kod zawsze zwraca uchwyt palety, gdy w ogle nie sprawdzamy, czy
wybrany format pikseli wymaga palety. Dzieje si tak, poniewa trybu indeksu koloru
moemy uy take w trybach o wikszych ilociach kolorw. Wszystkie pozostae czci
kodu zwizane z realizacj palety pozostaj niezmienione.
Rysowanie trjkta
Przejdmy do fragmentu kodu nadajcego najwyszemu wierzchokowi trjkta kolor o
indeksie O, czyli najciemniejszy kolor palety (czer). Kolor dwch dolnych wierzchokw
trjkta jest ustawiony na indeks palety 255, najjaniejszy odcie czerwieni. Przy
262____________________________________Cz II Uywanie OpenGL
wczonym pynnym cieniowaniu, ten kod (listing 8.7) daje obraz trjkta przedstawionego
na rysunku 8.15.
Podsumowanie
W tym rozdziale zajlimy si jednym z najwaniejszych elementw kadego pakietu
graficznego: kolorem. Wiesz ju, jak okrela kolor przez podanie barw skadowych
RGB, a take jak te skadowe maj si do siebie w przestrzeni (kostce) kolorw RGB.
Poznae zastosowanie funkcji glColor do kolorowania wierzchokw, wiesz wic, jak
wpywa to na efekty cieniowania. Wyjanilimy wybr kolorw OpenGL w trybach ko-
lorw 4-, 8-, 16- i 24-bitowych. Zademonstrowalimy budowanie palety 3-3-2, uywanej
przez OpenGL w trybach 8-bitowych. Na koniec, rzucilimy okiem na tryb indeksu koloru
oraz sposb jego wykorzystania w celu uzyskania wikszej kontroli nad palet w 8-
bitowych trybach kolorw.
Poprawne uycie kolorw i cieniowania jest nieodzownym elementem dobrej trjwy-
miarowej grafiki. W nastpnym rozdziale wyjanimy, jak OpenGL stosuje cieniowanie w
celu uzyskania efektw owietlenia. Dowiesz si, jak okrela kolory materiaw i
warunki owietlenia, a take jak umoliwi OpenGL wybr kolorw przy rysowaniu.
Rozdzia 8. + Kolory i cieniowanie 263
Podrcznik
glClearlndex
Przeznaczenie Ustawia numer koloru ta dla buforw indeksu koloru.
Plik nagwkowy
Skadnia Opis void glClearIndex(GLfloat color);
Ta funkcja okrela numer (indeks) koloru, ktry w trybie indeksu koloru
zostanie uyty do wymazania (wyczyszczenia) buforw koloru. Efektem
ubocznym jest wymazanie zawartoci okna i ustawienie koloru ta na kolor
(indeks) okrelony parametrem color.
Parametry
color GLfloat: Warto uywana przy czyszczeniu buforw koloru funkcj
glClear. Domyln wartoci jest 0.
Zwracana warto Brak
Przykad Patrz Przykadowy program INDEX w tym rozdziale.
take glClear, glGet
glColor
Przeznaczenie Ustawia biecy kolor w trybie koloru RGBA.
Plik nagwkowy <gl.h>
Skadnia void glCo!or3b(GLbyte red, GLbyte green, GLbyte blue);
void glColor3d(GLdouble red, GLdouble green, GLdouble blue);
void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
void g!Co!or3i(GLint red, GLint green, GLint blue);
void glColor3s(GLshort red, GLshort green, GLshort blue);
void glColor3ub(GLubyte red, GLubyte green, GLubyte blue);
void glColor3ui(GLuint red, GLuint green, GLuint blue);
void glColor3us(GLushort red, GLushort green, GLushort blue);
void glColor4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha);
void gICoor4d(GLdouble red, GLdouble green, GLdouble blue,
GLdouble alpha);
void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
void glColor4i(GLint red, GLint green, GLint blue, GLint alpha);
void glColor4s(GLshort red, GLshort green, GLshort blue, GLshort
alpha);
264 Cz II Uywanie OpenGL
gllndex
glColorMask
Przeznaczenie Wcza lub wycza modyfikacje skadowych koloru w buforach koloru.
Plik
nagwkowy void glColorMask(GLboolean bRed, GLboolean bGreen, GLboolean
bBlue, GLboolean bAlpha);
Skadnia
Ta funkcja umoliwia okrelenie, ktre skadowe koloru w buforze koloru
bd mogy by modyfikowane (domylnie wszystkie mog by
modyfikowane). Na przykad, ustawienie parametru bAlpha na GL_FALSE
blokuje wszystkie zmiany w skadowej alfa bufora koloru okna.
Parametry
bRed GLboolean: Okrela, czy skadowa czerwona moe by modyfikowana.
bGreen GLboolean: Okrela, czy skadowa zielona moe by modyfikowana.
bBlue GLboolean: Okrela, czy skadowa niebieska moe by modyfikowana.
bAlpha GLboolean: Okrela, czy skadowa alfa moe by modyfikowana. Brak
Zwracana Przykadowy program MASK na pytce CD-ROM, w folderze tego
rozdziau.
warto
, glColor, gllndex, gl!ndexMask, glDepthMask, glStencilMask
Przykad
gllndex
Przeznaczenie Ustala biecy indeks koloru dla rysowanych wierzchokw.
Plik <gl.h>
nagwkowy void gl!ndexd(GLdouble c);
void glIndexf(GLfloat c); void
gl!ndexi(GLint c);
266 Cz II Uywanie OpenGL
gllndexMask
Przeznaczenie Maskuje bity bufora indeksw kolorw, ktre w trybie indeksu kolorw
mog by modyfikowane.
Plik nagwkowy
Skadnia void gl!ndexMask(GLuint mask);
Opis Ta funkcja umoliwia zamaskowanie poszczeglnych bitw w buforze
indeksw kolorw. Gdy bit maski jest ustawiony, odpowiedni bit indeksu
moe by modyfikowany. Gdy bit maski jest wyzerowany, odpowiedni bit
indeksu nie moe by modyfikowany, czyli jest zabezpieczony przed
zmian w wyniku operacji rysunkowych. Ta funkcja ma zastosowanie
jedynie w trybie indeksu koloru.
Rozdzia 8. + Kolory i cieniowanie 267
Parametry
mask GLuint: Okrela binarn mask bitow, wczajc lub wyczajc zapis
poszczeglnych bitw w buforze indeksw koloru.
Zwracana warto Brak
Przykad
Przykadowy program MASK na pytce CD-ROM, w folderze tego
rozdziau.
gllndex, glDepthMask, glStencilMask
Patrz take
gILogicOp
Przeznaczenie Ustala logiczn operacj na pikselach w trybie indeksu koloru.
Plik nagwkowy
Skadnia Opis void glLogicOp(GLenum opcode);
Logiczna operacja na pikselach okrela sposb czenia wartoci pikseli.
Gdy zamiast piksela jest wpisywana nowa warto indeksu koloru
(rysowany jest nowy punkt), jest on czony logicznie z biecym indeksem
koloru ju istniejcego piksela. Aby wczy operacje logiczne na kolorze
pikseli, wywoaj funkcj glEnable(GL_LOGIC_OP). Aby je wyczy,
wywoaj glDisable(GL_LOGIC_OP). Gdy s wczone logiczne operacje na
indeksach kolorw pikseli, nowe wartoci pikseli s czone logicznie z
wartociami indeksu pikseli ju istniejcych; sam za operacj logiczn
okrela parametr opcode. Gdy operacje logiczne nie s wczone, efekt
rysowania pikseli jest taki, jakby wybrana bya operacja GL_COPY, czyli
zwyke rysowanie. Logiczne operacje na indeksach pikseli nie s
obsugiwane w trybie koloru RGBA.
Parametry
opcode GLenum: Okrela rodzaj operacji logicznej wykonywanej na wartociach
Zwracana warto indeksw koloru pikseli. Dozwolone s wartoci z tabeli 8.2. Ta tabela
zawiera list operacji logicznych oraz wzorw okrelajcych ich dziaanie,
Przykad gdzie s reprezentuje warto indeksu koloru piksela rdowego
(istniejcego), za d reprezentuj e warto indeksu koloru piksela docelowego
(rysowanego).
Patrz take Brak
Przykadowy program FLASHER na pytce CD-ROM. W tym przykadzie
zastosowano operacj logiczn GL_XOR w celu stworzenia pynnej
animacji bez podwjnego buforowania.
glGet, gllsEnabled, glEnable, glDisable
268 Cz II Uywanie OpenGL
Tabela 8.2.
Operacje logiczne na pikselach
Opcode Wynik
GL_CLEAR 0
GL_SET 1
GL_COPY s
GL_COPY_INVERTED !s
GL_NOOP d
GLJNYERT !d
GL_AND s&d
GLJMAND !(s & d)
GL_OR s|d
GL_NOR !(s | d)
GL_XOR sAd
GL_EQUIW !(s A d)
GL_AND_REVERSE s&!d
GL_AND_INVERTED !s&d
GL_OR_REVERSE s|!d
GL_OR_INVERTED !s|d
gIShadeModel
Przeznaczenie Ustala domylny tryb cieniowania paski lub gadki.
Plik nagwkowy
Skadnia Opis void glShadeModel(GLenum mod);
Prymitywy OpenGL s zawsze cieniowane, jednak model cieniowania moe
by paski (GL_FLAT) lub gadki (GL_SMOOTH). W najprostszym
scenariuszu, przed narysowaniem prymitywu jest ustawiany pojedynczy
kolor funkcj glColor(). Taki prymityw ma jednolity, niezmienny kolor, bez
wzgldu na cieniowanie. Jeli dla kadego wierzchoka zostanie okrelony
inny kolor, to w zalenoci od trybu cieniowania zmienia si wygld obiektu.
Przy wczonym gadkim cieniowaniu, kolor wntrza wieloktw jest
interpolowany na podstawie koloru poszczeglnych wierzchokw, czyli
kolor zmienia si pynnie od jednego wierzchoka do innego. Zmiany
kolorw przebiegaj zgodnie ze zmian koloru punktw odcinka czcego
dwa kolory w przestrzeni kolorw. Jeli przy tym jest wczone owietlenie,
OpenGL dokonuje take innych oblicze, majcych na celu wyznaczenie
poprawnego koloru
SL
Rozdzia 8. * Kolory i cieniowanie_________________________________269
piksela (patrz rozdzia 9). Przy paskim cieniowaniu, cay prymityw jest
rysowany w kolorze zdeterminowanym przez kolor przypisany ostatniemu
wierzchokowi prymitywu. Jednym wyjtkiem jest prymityw
GL_POLYGON; w tym przypadku o kolorze wielokta decyduje kolor
okrelony dla pierwszego wierzchoka.
Parametry
mod GLenum: Okrela tryb cieniowania, GL_FLAT (paski) lub
GL_SMOOTH (gadki). Domylnym trybem jest GL_SMOOTH.
Zwracana warto Brak
Przykad Przykadowe programy TRIANGLE i CCUBE na pytce CD-ROM,
w folderach tego rozdziau.
Patrz take glColor, glLight, glLightModel
Rozdzia 9.
Owietlenie i
rda wiata
W tym rozdziale:
Dowiesz si, jak... Uywane funkcje
4 Okreli model owietlenia 4 glLightMaterial
4 Okreli parametry owietlenia 4 glLight
4 Okreli waciwoci refleksyjne materiau * glColorMaterial, glMaterial
4 Uywa normalnych do powierzchni 4 glNormal
obiekt. Owietlony obiekt, ogldany pod rnymi ktami, moe mie zupenie inaczej
pocieniowane ciany. Wikszo z pozostaych zagadnie w czciach II i III zwizanych
jest z technikami umoliwiajcymi nadanie scenie coraz wicej realizmu. Od wic
kalkulator (jeli chcesz), za kapelusz maga i we gboki oddech... Zaczynamy pokaz
magiczny!
Rysunek 9.1.
Prosty samolot zbudowany przez dobraniem
odmiennego koloru dla kadego z trjktw
1
W rzeczywistym wiecie mamy oczywicie tylko jeden rodzaj wiata. Podzia na
rodzaje wiata w OpenGL wynika ze sposobu komputerowego modelowania
owietlenia. (Przy. tum.)
Rozdzia 9. * Owietlenie i rda wiata 273
wiato otaczajce
wiato otaczajce to wiato, ktre nie pochodzi z adnego okrelonego kierunku. Ma
swoje rdo, jednak promienie wiata odbijaj si po caym pomieszczeniu lub scenie i
generalnie s pozbawione kierunku. Obiekty iluminowane wiatem otaczajcym s
rwnomiernie owietlone na wszystkich powierzchniach we wszystkich kierunkach.
Wszystkie poprzednie przykady w tej ksice moesz uzna za owietlone biaym
wiatem otaczajcym, gdy obiekty byy zawsze widoczne i rwnomiernie pokoloro-
wane (lub cieniowane), bez wzgldu na ich obrt i kt patrzenia. Obiekt owietlony
przez wiato otaczajce przedstawia rysunek 9.2.
Rysunek 9.2.
Obiekt owietlony
wycznie wiatem
otaczajcym
wiato rozproszone
wiato rozproszone pochodzi z konkretnego kierunku, lecz jest odbijane od powierzchni
rwnomiernie. Nawet jeli wiato jest odbijane rwnomiernie, powierzchnia jest ja-
niejsza, gdy wiato pada na ni bezporednio, ni wtedy, gdy pada na ni pod wikszym
ktem. Dobrym przykadem rda wiata rozproszonego jest owietlenie jarzeniowe lub
wiato soneczne padajce w boczne okno w poudnie. Na rysunku 9.3 obiekt jest
owietlony rdem wiata rozproszonego.
Rysunek 9.3.
wiato odbyskw
Podobnie jak wiato rozproszone, wiato odbyskw posiada kierunek, ale jest odbijane
ostro i w jedn stron. Bardziej pobyskujce obiekty moemy pozna po jasnych,
lnicych plamach wiata na ich powierzchniach (na ekranie s rysowane z uyciem
274____________________________________Cz II Uywania OpenGL
koloru odbyskw - ang. specular color). Obiekt owietlony wycznie wiatem odby-
skw zosta przedstawiony na rysunku 9.4.
Zmy to razem
adne rdo wiata nie jest zoone wycznie z jednego z tych trzech rodzajw wiata.
Skada si raczej z rnych intensywnoci kadego z rodzajw. Na przykad, czerwone
wiato lasera w laboratorium skada si prawie wycznie z czystego czerwonego wiata
odbysku. Jednak czsteczki dymu lub kurzu wirujce w pomieszczeniu rozpraszaj
promie, przez co wida go, jak biegnie przez pokj. To rozproszenie reprezentuje
skadow wiata rozproszonego. Gdyby promie by jasny, a w pokoju nie byoby adnego
innego rda wiata, zauwayby, e przedmioty w pomieszczeniu przybray czerwony
odcie. Byaby to wanie niewielka skadowa wiata otoczenia.
W zwizku z tym mwimy, e rdo wiata w scenie skada si z trzech skadowych o-
wietlenia: otoczenia, rozpraszania i odbyskw. Podobnie jak inne kolory, kady komponent
wiata jest definiowany przez warto RGBA, okrelajc wzgldne intensywnoci
czerwieni, zieleni i bkitu tworzcych ten komponent. (A do rozdziau 15 bdziemy
ignorowa skadow alfa). Na przykad, nasze czerwone wiato lasera mogoby zosta opisane
za pomoc wartoci z tabeli 9.1.
Tabela 9.1.
Kolor i dystrybucja wiata dla rda czerwonego wiata laserowego
Zauwa, e czerwony promie lasera nie zawiera wiata zielonego ani niebieskiego.
Zwr take uwag, e wiato odbyskw, rozproszone i otoczenia, moe przybiera
wartoci z zakresu od 0,0 do 1,0. Moesz zinterpretowa t tabel jako okrelajc, e
czerwone wiato lasera w pewnych scenach bdzie miao bardzo du skadow odby-
skw, ma skadow wiata rozproszonego i bardzo ma skadow wiata otaczajcego.
Gdziekolwiek skierujesz promie takiego wiata, zobaczysz najprawdopodobniej
czerwony punkt. Oprcz tego, z powodu warunkw panujcych w pomieszczeniu (dym,
Rozdzia 9. Owietlenie i rda wiata___________________________275
Waciwoci materiau
Gdy uywamy owietlenia, nie opisujemy wieloktw jako posiadajcych konkretny
kolor, ale raczej jako zrobione z materiaw o okrelonych waciwociach refleksyjnych.
Zamiast mwi, e wielokt jest czerwony, mwimy, e jest zrobiony z materiau
odbijajcego gwnie wiato czerwone. Wci twierdzimy, e powierzchnia jest czer-
wona, ale tym razem musimy okreli take waciwoci refleksyjne materiau w odnie-
sieniu do rde wiata otaczajcego, rozpraszajcego i odbyskw. Materia moe by
lnicy i doskonale odbija wiato odblaskw, pochaniajc przy tym wikszo wiata
otaczajcego i rozpraszajcego. Odwrotnie, paski pokolorowany obiekt moe absorbowa
cae wiato odbyskw i w adnych warunkach nie wydawa si lnicym. Kolejn
waciwoci, ktr moemy okreli, jest waciwo emisji obiektw emitujcych
wasne wiato, takich jak wietliki czy zegarki wiecce w ciemnoci.
Owietlanie materiaw
Dobranie wiata i waciwoci materiaw tak, aby uzyska podany efekt, wymaga nieco
praktyki. Nie ma tu kostek kolorw ani prostych regu dajcych szybkie i proste odpowiedzi.
Wanie tu analiza ustpuje miejsca sztuce, a nauka magii. Na pytce CD-ROM, w folderze
tego rozdziau, znajduje si program o nazwie MATLIGHT (od Materials and Lighting
Studio). Ten program umoliwia zmian na bieco waciwoci materiau i wiata w
scenie skadajcej si z kilku prostych obiektw. Programu MATLIGHT moesz uy
w celu pobawienia si rnymi kombinacjami waciwoci. Oprcz tego,
276____________________________________Cz II Uywanie OpenGL
poniewa zosta doczony kod rdowy, moesz zastpi obiekty programu wasnymi
obiektami i dopracowa ich waciwoci przed umieszczeniem ich w swoich scenach.
Podczas rysowania obiektu OpenGL decyduje, jakiego koloru uy dla kadego piksela
sceny. Obiekt ma wasne refleksyjne" kolory, a rdo wiata wasne. Jak OpenGL
wyznacza, ktrych kolorw naley uy? Zrozumienie tego nie jest trudne, pod wa-
runkiem, e potrafisz mnoy uamki. (Widzisz, a nauczyciel mwi, e kiedy ci si to
przyda!)
Rysunek 9.5.
Obliczanie koloru U Q
dla skadowej \lntensywnosc 5 \ Intensywno 5 \ Intensywno 5
otaczajcej koloru
obiektu
5 x 5 = 25 5x1=5 5x5 = 25
O
t
a
czajcy "kolor" materiau (.5,1,.5)
Tak wic komponenty koloru materiau okrelaj po prostu procent odbijanego wiata
danego rodzaju. W naszym przykadzie intensywno skadowej czerwonej wiata ota-
czajcego wynosia 1/2, za waciwo materiau .5 dotyczca skadowej czerwonej
wiata otaczajcego okrelia, e tylko poowa poowy intensywnoci zostaa odbita.
Poowa poowy to 1/4, czyli 0,25.
Rozdzia 9. * Owietlenie i rda wiata_____________________________277
Wczanie owietlenia
Aby poinformowa OpenGL, e ma zacz oblicza owietlenie, wywoaj funkcj
glEnable() z parametrem GL_LIGHTING:
glEnable(GL_LIGHTING);
Ta pojedyncza instrukcja nakazuje OpenGL, aby przy obliczaniu koloru kadego wierz-
choka w scenie bra pod uwag waciwoci materiau i parametry owietlenia. Jednak bez
okrelenia waciwoci materiau lub rda wiata twj obiekt pozostanie ciemny i
nieowietlony, tak jak pokazano na rysunku 9.6. Spjrz do kodu kadego z przykadw
opartych na programie JET, a przekonasz si, e w kadym z nich, tu po przygotowaniu
kontekstu renderowania, jest wywoywana funkcja SetupRC(). Wanie tam odbywa si
inicjowanie wszelkich parametrw owietlenia.
278__________________ ___ Cz II Uywanie OpenGL
Rysunek 9.6.
Program 2 wczonym owietleniem, jednak
bez zdefiniowania parametrw owietlenia i
waciwoci materiaw
Przygotowanie modelu
owietlenia
Po wczeniu obliczania owietlenia,
pierwsze, co musisz zrobi, to przygotowa
model owietlenia. Trzy parametry
okrelajce model owietlenia s
ustawiane za pomoc funkcji glLightModel().
Pierwszym parametrem owietlenia,
uywanym w naszym nastpnym przykadzie, jest GL_LIGHT_MODEL_AMBIENT.
Umoliwia okrelenie globalnego wiata otaczajcego, owietlajcego wszystkie obiekty
ze wszystkich stron. Poniszy kod okrela uycie jasnego, biaego wiata:
// Jasne biae wiata = pena intensywno wszystkich skadowych RGB
GLfloat ambientLightU = f l . O f , l . O f , l . O f , 1.0 } ;
// Wczenie wiata
glEnable(GL_LIGHTING);
// Ustawienie modelu owietlenia tak aby korzysta ze wiata
otoczenia
// okrelonego w ambientLight[]
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
glBegin(GL_TRIANGLES);
glVertex3f(-15.Of, O . O f , 30.O f ) ;
glVertex3f( O . O f , 15.Of, 30.O f ) ;
glVertex3f( O . O f , O . O f , -56.O f ) ;
glEnd();
glColor3f(0.75f, 0.75f, 0 . 7 5 f ) ;
glBegin(GL_TRIANGLES) ;
glvertex3f(-15.Of, O . O f , 30.O f ) ;
glVertex3f( O . O f , 15.Of, 30.O f ) ;
glVertex3f( O . O f , O . O f , -56.O f ) ;
glEnd();
Listing 9.1 zawiera kod, ktry dodalimy w funkcji SetupRC do naszego przykadu
JET, ustawiajcy jasne wiato otaczajce oraz dobierajcy waciwoci materiau tak,
aby mg odbija wiato i by widoczny. Oprcz tego zmienilimy kolory samolotu, tak
e teraz kada sekcja, a nie kady wielokt, s rysowane w osobnych kolorach. Zwr
uwag, e kocowy wynik (rysunek 9.7) nie rni si zbytnio od obrazka, dla ktrego
jeszcze nie wczylimy owietlenia. Jeli jednak zredukujemy wiato otaczajce o
poow, otrzymamy obraz pokazany na rysunku 9.8. Osigamy to przez ustawienie
nastpujcych wartoci RGBA wiata otaczajcego:
GLfloat mbientLightn = { 0. 5f, 0.5f, 0.5f, l . O f };
Rysunek 9.7.
Wynik dziaania ukoczonego programu
AMBIENT
// Ta funkcja
odpowiada za
inicjowanie kontekstu
renderowania // Oprcz
tego tworzy i
i n i c j u j e wiata void
SetupRC() {
// Wartoci
owietlenia
// Jasne biae
wiato
GLfloat ambientLightl] = { l . O f , l.Of, l.Of, l.Of };
Rozdzia 9. * Owietlenie i rda wiata 281
// Owietlanie
glEnable(GL_LIGHTING); // Wczenie owietlenia
// Jasnoniebieskie to
glClearColor( O . O f , O . O f , 05.f,l.Of);
Rysunek 9.8.
Wynik dziaania
programu AMBIENT
ze rdem wiata
przygaszonym o
poow
Wiemy wic ju, jak mona zredukowa wiato otaczajce w scenie, w celu stworzenia
ciemniejszego obrazu. Jest to uyteczne w symulacjach, w ktrych stopniowo zapada
mrok lub w ktrych blokowane jest rdo wiata kierunkowego, na przykad gdy
obiekt znajdzie si w cieniu innego, wikszego obiektu.
konkretnych rde wiata. Oprcz intensywnoci i kolorw, te rda posiadaj take po-
oenie i kierunek. Pooenie rde wiata moe radykalnie wpyn na wygld sceny.
OpenGL obsuguje do omiu niezalenych rde wiata umieszczonych w dowolnym
miejscu sceny lub poza bry widzenia. Moesz umieci rdo wiata w nieskoczonej
odlegoci, sprawiajc, e jego promienie bd rwnolege, lub ustawi je blisko,
sprawiajc, e jego promienie bd rozbiegay si dookoa. Moesz take okreli wiato
punktowe, z zadanym stokiem wiata, jak rwnie manipulowa innymi charakte-
rystykami wiata.
Normalne do powierzchni
Linia poprowadzona od wierzchoka w gr zaczyna si na jakiej wyimaginowanej
paszczynie (lub wielokcie) i biegnie do niej pod ktem prostym. Ta linia jest nazywana
wektorem normalnym. Sowo wektor moe raczej kojarzy ci si z rzucanymi od
niechcenia terminami zaogi Star Trek, ale w tym wypadku oznacza po prostu lini pro-
stopad do danej powierzchni. Wektor jest lini wskazujc w pewnym kierunku, za
sowo normalny to kolejne okrelenie, jakie jajogowi wymylili dla sowa prostopady
(oznaczajcego przecinanie si pod ktem 90). Tak jakby sowo prostopady nie byo
okropne samo w sobie!
Tak wic, wektor normalny to linia wskazujca, prostopada do powierzchni wielokta.
Rysunek 9.10 przedstawia przykady wektorw normalnych w dwch i trzech wymiarach.
90
Okrelanie normalnej
Aby zobaczy, jak okrelamy normaln dla wierzchoka, spjrz na rysunek 9.11 - pa-
szczyzn unoszc si ponad paszczyzn \z w przestrzeni 3 D. Zwr uwag na lini
biegnc przez wierzchoek (l, l, 0), prostopad do paszczyzny. Gdybymy wybrali
dowolny punkt na tej linii, powiedzmy, e (1> 10, 0), odcinek od pierwszego punktu (l,
l, 0) do drugiego punktu (l, 10, 0) byby naszym wektorem normalnym. Drugi wybrany
punkt w tym wypadku wskazuje, e kierunek naszego wierzchoka wskazuje
284 Cz II Uywanie OpenGL
Jak widzisz, drugi punkt, okrelajcy koniec wektora normalnego, znajduje si o pewn
liczb jednostek w osiach x, y oraz z od wierzchoka. Zamiast okrela dwa punkty dla
kadego wektora normalnego, moemy odj wierzchoek od drugiego punktu wektora
normalnego, aby otrzyma pojedyncz trjk wsprzdnych opisujc odlegoci x, y i z
od wierzchoka. Dla naszego przykadu bdzie to
( l , 10, 0) -
( l , l, 0) (1-1, 10-1, 0) = (O, 9, 0)
Przesunity wektoi
Ten wektor jest kierunkow wartoci informujc OpenGL, w ktrym kierunku zwrcony
jest wierzchoek (lub wielokt). W nastpnym segmencie kodu widzimy, jak wektory
normalne s okrelane dla jednego z trjktw w przykadowym programie JET:
glBegin(GLJTRIANGLES);
glNormalSf( O . O f , -l.Of, O . O f ) ;
glVertex3f( O . O f , O . O f ,
60.O f ) ;
Rozdzia 9. * Owietlenie i rda wiata_____________________________285
glVertex3f(-15.Of, O . O f , 30.O f ) ;
glVertex3f( 1 5 .Of,O.Of,30.Of); glEnd();
Kierunek wieloktw
Zwr szczegln uwag na kolejno wierzchokw w
trjkcie samolotu. Jeli ogldasz ten trjkt z kierunku, w
ktrym wskazuje wektor normalny, wierzchoki s uoone
dookoa trjkta w kierunku przeciwnym do ruchu wskazwek
zegara. Wanie to nazywa si kierunkiem wielokta.
Domylnie, przednia strona wielokta jest zdefiniowana jako
strona, od ktrej wierzchoki wydaj si uoone w kierunku
przeciwnym do ruchu wskazwek zegara.
Normalne jednostkowe
Aby OpenGL mg realizowa ca swoj magi, wszystkie normalne do powierzchni
musz zosta zamienione na normalne jednostkowe. Normalna jednostkowa to po prostu
wektor normalny o dugoci 1. Normalna na rysunku 9.12 ma dugo 9. Dugo
wektora oblicza si przez zsumowanie jego skadowych podniesionych do kwadratu, a
nastpnie wycignicie z sumy pierwiastka kwadratowego. Po podzieleniu kadej
skadowej przez dugo otrzymujemy wektor wskazujcy dokadnie w tym samym kie-
runku, ale o dugoci jednej jednostki. W naszym przypadku otrzymamy wektor (O, l, 0).
Nazywa si to normalizacj. Tak wic w celu obliczenia owietlenia, wszystkie wektory
normalne trzeba znormalizowa. I jak tu nie mwi w argonie!
Znajdowanie normalnej
Rysunek 9.13 przedstawia kolejny wielokt, ktry ju nie ley po prostu na jednej z g-
wnych paszczyzn. Wektor normalny prostopady do tej powierzchni nie jest ju tak
prosty do odgadnicia, potrzebujemy wic jakiego prostego sposobu obliczania nor-
malnych dla dowolnego wielokta w przestrzeni 3D.
Rysunek 9.13.
Niebanalne
wyznaczanie
normalnej
Normalna
Moesz atwo obliczy wektor normalny dla kadego wielokta skadajcego si z przy-
najmniej trzech wierzchokw lecych w tej samej paszczynie (paskiego wielokta).
Rysunek 9.14 przedstawia trzy punkty: Pl, P2 i P3, uyte do zdefiniowania dwch we-
ktorw: wektora VI z Pl do P2 oraz wektora V2 z P l do P3. Matematycznie rzecz
biorc, dwa wektory w przestrzeni 3 D definiuj paszczyzn (ley w niej nasz wielokt).
Jeli obliczysz iloczyn wektorowy tych dwch wektorw (w zapisie matematycznym VI
x V2), otrzymany w wyniku wektor bdzie prostopady do paszczyzny (czyli bdzie
Rozdzia 9. * Owietlenie i rda wiata____________________________287
normaln). Rysunek 9.15 pokazuje wektor V3 wyprowadzony jako wynik iloczynu we-
ktorowego wektorw VI i V2.
Rysunek 9.14.
Dwa wektory zdefiniowane przez trzy punkty na
paszczynie
Rysunek 9.15.
Wektor normalny jako iloczyn wektorowy dwch
wektorw
Nie martw si, jeli jeszcze nie wiesz, jak obliczy iloczyn
wektorowy dwch wektorw; wszystko, czego
potrzebujesz, to fiinkcja z listingu 9.3. Aby jej uy,
przeka jej tablic zawierajc trzy dowolne wierzchoki
swojego wielokta (podane z zachowaniem kolejnoci
przeciwnej do ruchu wskazwek zegara), a take tablic,
ktra po powrocie z funkcji bdzie zawiera obliczony
wektor normalny. Aby mg zobaczy, jak dziaa ta
funkcja, zostay zapewnione stae wartoci dla
wsprzdnych x, y i z.
Listing 9.3. Funkcja obliczajca wektor normalny dla trzech dowolnych wierzchokw wielokta______
glLightfv(GL_LIGHTO,GL_POSITION,lightPos);
W tym kodzie lightPosf] zawiera pooenie wiata. Ostatni wartoci w tej tablicy jest
1,0, czyli podane wsprzdne oznaczaj koordynaty rda wiata. Gdyby ostatni
wartoci w tablicy byo 0,0, oznaczaoby to e wiato znajduje si w nieskoczonej
odlegoci, w kierunku wektora zawartego w tej tablicy. Zajmiemy si tym nieco
pniej.
w programie LITJET__________
// Wczenie owietlenia
glEnable(GL_LIGHTING);
// Jasne niebieskie to
glClearColor(O.Of, O . O f , l . O f ,
l.Of );
Rysowanie wieloktw
Kod renderowania z pierwszych dwch przykadw JET teraz ulega znacznej zmianie, tak
aby uwzgldni nowy model owietlenia. Listing 9.5 pochodzi z funkcji RenderSce-ne()
programu LITJET.
Listing 9.5. Przykad kodu ustalajcego kolor i obliczajcego normalne dla -wierzchokw wieloktw___
Zauwa, e obliczamy wektor normalny uywajc naszego kodu z listingu 9.3. Oprcz
tego waciwoci materiaw ledz teraz kolory ustawiane funkcj glColor (zastpion
naszym makrem glRGB). Zwr take uwag, e nie kady trjkt jest blokowany par
funkcji glBegin()/glEnd(). Moesz raz okreli, e rysujesz trjkty, za kade trzy no
we wierzchoki bd tworzyy trjkt, chyba e odwoasz to instrukcj glEnd(). W przy
padku bardzo duych iloci wieloktw, moe to znacznie poprawi wydajno, dziki
wyeliminowaniu wielu niepotrzebnych wywoa funkcji. ,
Rysunek 9.16.
Dziaanie programu
LITJET
Efekty owietlenia
wiato otaczajce i rozpraszajce w przykadzie LITJET wystarczy jedynie do zapewnienia
iluzji owietlenia. Powierzchnia samolotu jest cieniowana zgodnie z ktem padania
wiata. Gdy samolot si obraca, te kty si zmieniaj i dostrzegasz efekt owietlenia,
dziki czemu moesz atwo odgadn, skd pada wiato.
Pominlimy jednak wiato odbyskw, a take waciwoci odbyskw materiau sa-
molotu. Cho wystpuj efekty cieniowania, sama powierzchnia samolotu jest raczej
pasko pokolorowana. Waciwoci otaczajca i rozpraszajca materiau s wystarczajce,
jeli modelujesz obiekty udajce plastelin, drewno, karton, szmaty czy inne niepo-
yskliwe materiay. Jednak w przypadku metalicznych powierzchni, takich jak powoka
samolotu, poysk jest najczciej nieodzowny.
Odbyski
wiato i waciwoci materiau dotyczce odbyskw nadaj obiektowi wymagany poysk.
Ten poysk moe rozjani pewne czci obiektu i tworzy plamy odbyskw w momencie,
gdy wiato pada pod ktem ostrym do kta patrzenia na powierzchni. Plama odbysku
wystpuje wtedy, gdy prawie cae wiato padajce na powierzchni jest odbijane w
kierunku obserwatora. Dobrym przykadem plam odbyskw mog by odby-ski soca na
wodzie.
wiato odbyskw
Dodanie skadowej odbyskw do rda wiata jest bardzo atwe. Poniszy program
pokazuje przygotowanie rda wiata z programu LITJET, zmodyfikowane tak, aby
uwzgldni skadow odbyskw.
// Wartoci i wsprzdne rda wiata GLfloat
ambientLigta [ ] = { 0.3f, 0.3f, 0.3f, l.Of }; GLfloat
diffuseLight[] = { 0 . 7 f, 0 . 7 f, 0 . 1 f, l . O f }; GLfloat
specular[] = { l.Of, l.Of, l.Of, l . O f } ; GLfloat
lightPos[] = { O . O f , 150.Of, 150.Of, l . O f };
// Wczenie owietlenia
glEnable(GL LIGHTING);
292____________________________________Cz II Uywanie OpenGL
Tablica specular[] definiuje bardzo jasne, biae wiato dla skadowej odbfyskw wiata.
Naszym celem byo wymodelowanie jasnego wiata sonecznego. Linia
glLightfv(GL_LIGHTO,GL_SPECULAR, specular) ;
Stopie poyskliwoci
Jak ju wspomnielimy, jasne wiato poyskw i wysoka warto waciwoci poysku
materiau powoduj rozjanienie kolorw obiektu. W naszym przykadzie, obecne, eks-
tremalnie jasne wiato poyskw (pena intensywno) i waciwo poysku materiau
(take pena intensywno) powoduj, e samolot staje si prawie cakowicie biay lub
jasnoszary, z wyjtkiem tych powierzchni, ktre s odwrcone od rda wiata (w takim
wypadku staj si czarne i nieowietlone). Aby zmniejszy ten efekt, po okreleniu
skadowej odbyskw stosujemy nastpn lini kodu:
glMateriali(GL_FRONT,GL_SHININESS, 128) ;
Listing 9.6 przedstawia nowy kod funkcji SetupRC, pochodzcy z programu SHINY-
JET. Jest to jedyny fragment kodu, jaki uleg zmianie w stosunku do poprzedniego pro-
gramu LITJET (oczywicie poza nazw programu). W tym programie samolot wydaje si
bardzo poyskliwy. Rysunek 9.17 przedstawia wynik dziaania tego programu, jednak
aby mc w peni doceni efekt, powiniene uruchomi program i przytrzyma jeden z
klawiszy kursora w celu obrcenia samolotu w promieniach soca.
Listing 9.6. Funkcja SetupRC z programu SHINYJET, powodujca powstanie odbyskw na samolocie
// Wczenie owietlenia
glEnable(GL_LIGHTING);
// Jasne niebieskie to
glClearColor(O.Of, O . O f , l . O f , l.Of
);
Rysunek 9.17.
Dziaanie programu
SHINYJET
Urednianie normalnych
Wspomnielimy wczeniej, e przez wykrcanie" normalnych mona tworzy gadkie
krzywe powierzchnie za pomoc prostych linii. Ta technika, zwana urednianiem nor-
malnych, daje interesujc iluzj optyczn. Zamy, e mamy powierzchni tak jak
pokazana na rysunku 9.18, ze zwykymi normalnymi do powierzchni.
Rozdzia 9. + Owietlenie i rda wiata 295
Rysunek 9.18.
Powierzchnia
amana, ze zwykymi
normalnymi
Rysunek 9.19.
Urednianie
normalnych sprawia,
e ostre krawdzie
wydaj si mniej ostre
// Inicjowanie krokw Y
lastY = O . O f ; nextY =
10.O f ;
// Drugi wierzchoek
v [ l ] [ 0 ] = x; // wsp. X dla lewej
v [ l ] [ 1 ] = lastY;
v [ l ] [ 2 ] = -50.O f ; // wsp. Z dla przodu
// Trzeci wierzchoek
v[2][0] = x + 20.Of; // wsp. X dla prawej
v[2][1] = nextY;
v[2] [2] = -50.O f ; // wsp. Z dla przodu
// Czwarty wierzchoek
v [ 3 ] [ 0 ] = x + 20.Of;// wsp. X dla prawej
v [ 3 ] [ 1 ] = nextY;
v [ 3 ] [ 2 ] = 5 0 . O f ; // wsp. Z dla tyu
// Pocztek wielokta
glBegin(GL_POLYGON);
ifUState != AVERAGE)
{
// Obliczenie i ustawienie wektora normalnego,
// chyba e w menu wybrano urednianie
calcNormal( v , normal);
glNormal3fv(normal);
Rozdzia 9. * Owietlenie i rda wiata _____________________________ 297
Program WAYEY posiada opcje menu umoliwiajce rysowanie szkieletu, paskie lub
gadkie cieniowania bd wreszcie urednianie normalnych. Rysunek 9.20 przedstawia
powierzchni aman przy wczonym paskim cieniowaniu, za rysunek 9.2 1 - t sam
powierzchni z urednionymi normalnymi. Mona dostrzec, e na drugim rysunku wzdu
caej powierzchni przebiegaj gadkie fale.
298 Cz II Uywanie OpenGL
Rysunek 9.20.
Powierzchnia
amana, ze zwykymi
normalnymi do
powierzchni
Rysunek
9.21.
Ta sama
powierzchnia po
urednieniu
normalnych
wiata punktowe
Jak dotd, pozycj wiata okrelalimy nastpujco:
// Tablica zawierajca pozycj
GLfloat lightPosU = { O.Of, 150.Of, 150.Of, l.Of },
// Wczenie owietlenia
glEnable(GLJLIGHTING);
// Czarne to
g!ClearColor(O.Of, O.Of, O.Of, l.Of ) ;
Rysunek 9.22.
Kt rozwarcia stoka wiata
punktowego
wiato punktowe
Rozdzia 9. Owietlenie i rda wiata____________________________301
Rysunek 9.23.
Przykad dziaania programu SPOT,
demonstrujcego wiato punktowe
// Wywoywane w celu
narysowania sceny
void RenderScene(void)
{
// Wyczyszczenie
okna biecym
kolorem ta
glClear(GL_COLOR_BUFFER_BIT l
GL_DEPTH_BUFFER_BIT);
Cienie
Rozdzia powicony owietleniu a prosi si o wspomnienie o cieniach. Uzupenienie
sceny o cie moe znacznie poprawi jej realizm i efekt wizualny. Na rysunkach 9.24a i
9.24b widzimy dwa widoki owietlonej kostki, z cieniem i bez cienia (ten przykadowy
program pochodzi z rozdziau 2). Kostka z rysunku 9.24b z cieniem wyglda o wiele
bardziej wiarygodnie.
Rozdzia 9. * Owietlenie i rda wiata 303
Rysunek 9.24a.
Owietlona kostka
bez cienia
Rysunek 9.24b.
Owietlona kostka
z cieniem
Kod zgniatajcy"
Chcemy spaszczy" macierz rzutu widoku modelu, tak aby wszystkie rysowane przy jej
uyciu obiekty stay si dwuwymiarowe. Bez wzgldu na orientacj obiektu, zostanie on
spaszczony do paszczyzny, na ktr pada cie. Drugim elementem jest odlego i
kierunek rda wiata. Kierunek wiata determinuje ksztat cienia oraz wpywa na jego
rozmiar. Jeli kiedykolwiek widziae swj cie wczesnym rankiem lub tu przed
zachodem soca, wiesz, jak dugi moe on by w zalenoci od pooenia soca.
Funkcja z listingu 9.10 pobiera trzy punkty lece na paszczynie, na ktr ma pa
cie, pozycj rda wiata oraz, na koniec, wskanik do macierzy przeksztacenia,
ktra ma zosta wypeniona. Nie zagbiajc si zbytnio w algebr liniow, ta funkcja
oblicza wspczynniki rwnania paszczyzny, na ktr ma pada cie, i cznie z poo-
eniem wiata wykorzystuje je do stworzenia macierzy przeksztacenia. Jeli przemnoysz
t macierz przez biec macierz widoku modelu, wszystkie nastpne obiekty zostan
spaszczone na t paszczyzn.
// Druga kolumna
destMatlO][ 1 ] - O . O f - lightPos[l] * planeCoeff[ 0 ] ,
destMat[ 1 ] [ 1 ] = dot - lightPostl] v planeCoeff[ 1 ] ;
destMat[2][ 1 ] = O . O f - lightPostl] * planeCoeff[ 2 ] ,
destMat[3][ 1 ] = O . O f - lightPos[l] * planeCoeff[ 3 ] ,
// Trzecia kolumna
destMat[0][ 2 ] = O . O f - lightPos[2] * planeCoeff[ 0 ] ,
destMat[ 1 ] [ 2 ] = O . O f - lightPos[2] *
destMat[2][ 2 ] = dot - planeCoeff[ 1 ] ; lightPos[2] *
destMat[3][ 2 ] = O . O f planeCoeff[ 2 ] ;
- lightPos[2] * planeCoeff[ 3 ] ,
// Czwarta kolumna
destMatlO][ 3 ] O.Of
destMat[ 1 ] [ 3 ] O.Of - lightPos[3] * planeCoeff[ 0 ] j
destMat[2][ 3 ] O.Of - lightPos[3] * planeCoeff[ 1 ] ;
destMat[3][ 3 ] dot - - lightPos[3] * planeCoeff[ 2 ] ;
lightPos[3] * planeCoeff[ 3 ] ;
Przykad cienia
Aby zademonstrowa uycie funkcji z listingu 9.10, umiecilimy nasz samolot w po-
wietrzu, wysoko nad ziemi. Umiecimy rdo wiata ponad nim i nieco z lewej strony.
Gdy uyjesz klawiszy kursora w celu obrcenia samolotu, cie samolotu bdzie
odpowiada jego spaszczonej sylwetce na ziemi. Wynik dziaania programu SHADOW
zosta przedstawiony na rysunku 9.26.
Rysunek 9.26.
Wynik dziaania
programu SHADOW
Kod z listingu 9.11 pokazuje sposb przygotowania macierzy cienia na potrzeby tego
przykadu. Zwr uwag, e tworzymy macierz raz i przechowujemy j w zmiennej
globalnej.
306 ____________________________________ Cz II Uywanie OpenGL
II Jasne niebieskie to
glClearColor (O.Of, O.Of, l.Of, l.Of ) ;
Listing 9.12 przedstawia kod renderujcy programu SHADOW. Najpierw rysujemy sa-
molot tak jak zwykle, a nastpnie odtwarzamy macierz widoku modelu i mnoymy j
przez macierz cienia. W ten sposb otrzymujemy spaszczon macierz rzutowania. Na-
stpnie ponownie rysujemy samolot (zmodyfikowalimy kod, tak aby korzysta ze zna-
cznika informujcego funkcj DrawJet e powinna rysowa samolot na czarno lub w
kolorze). Po kolejnym odtworzeniu macierzy widoku modelu rysujemy ma t kul
znajdujc si mniej wicej w miejscu zajmowanym przez rdo wiata, po czym
rysujemy poniej samolotu paszczyzn, imitujc ziemi". Ten prostokt ley na tej
samej paszczynie, na ktrej rysowany jest cie samolotu.
Rozdzia 9. * Owietlenie i rda wiata____________________________307
W przypadku trybu indeksu koloru OpenGL korzysta z pewnych zaoe, jednak w tym
trybie wiata mog zawiera jedynie skadow rozpraszajc i odbyskw. Materiay
mog posiada waciwo lnienia, otaczajc, rozpraszajc i odbyskw cho w pe-
wnych przypadkach to wystarcza, ale czsto uzyskany efekt nie jest wart wysiku.
Aby mona byo zastosowa owietlenie, paleta musi zawiera trzy pasma kolorw dla
kolorw otaczajcych, rozpraszajcych i odbyskw. Aby osign satysfakcjonujce
rezultaty, te pasma zwykle obejmuj odcienie od czarnego, poprzez odcienie pojedyn-
czego koloru, a do biaego. Istnieje moliwo zdefiniowania ich tak, aby stworzy
gadko cieniowany obiekt w jednym kolorze, ale ma to mae zastosowanie w prakty-
cznych aplikacjach.
Oglnie, wikszo publikacji dotyczcych OpenGL zaleca unikanie trybu indeksu koloru
w poczeniu z efektami owietlenia. Jednak jeli musisz go uy, pytka CD-ROM zawiera
dodatkowy przykad o nazwie ILIGHT, ilustrujcy uycie trybu indeksu koloru w celu
owietlenia sceny zawierajcej kilka obiektw. Jednak wszystkie te obiekty maj ten sam
kolor!
Podsumowanie
W tym rozdziale zostae wprowadzony w pewne bardziej zaawansowane i magiczne"
dziedziny OpenGL. Dowiedziae si, jak okrela jedno lub kilka rde wiata oraz jak
definiowa ich charakterystyk w postaci skadowych otaczajcej, rozpraszajcej i
odbyskw. Wyjanilimy take, jak odpowiednie waciwoci materiau wspgraj ze
skadowymi rde wiata, a take zademonstrowalimy pewne efekty specjalne, takie jak
tworzenie plam odbyskw czy wygadzanie ostrych krawdzi.
Oprcz tego zostao omwione pooenie rda wiata, a take tworzenie i manipulo-
wanie wiatami punktowymi. Zaprezentowana w treci wysokopoziomowa funkcja do
operowania macierzami bardzo uatwi tworzenie cieni. Na koniec wyjanilimy, dlacze-
Rozdzia 9. Owietlenie i rda wiata 309
go powiniene unika trybu indeksu koloru przy tworzeniu efektw owietlenia. Pro-
gramy demonstracyjne w tym rozdziale s cakiem proste, ale wicej przykadw znaj-
dziesz na pytce CD-ROM, w folderze tego rozdziau. Programy na pytce demonstruj
wszystkie opisywane efekty, cznie ze scenami zawierajcymi wicej ni jedno rdo
wiata.
Podrcznik
glColorMaterial
Przeznaczenie Sprawia, e kolory materiau ledz biecy kolor ustawiany funkcj
glColor.
Plik nagwkowy
Skadnia void glColorMaterial(Glenum face, GLenum mod);
Opis Ta funkcja umoliwia ustawianie waciwoci materiau bez koniecznoci
bezporedniego wywoywania funkcji glMaterial. Jeli uyjesz tej funkcji,
pewne waciwoci materiau mog by automatycznie ustawianie w
momencie wywoania funkcji glColor. Domylnie ledzenie koloru jest
wyczone; aby je wczy, musisz wywoa funkcj
glEnable(GL_COLOR_MATERIAL). Aby ponownie wyczy ledzenie
koloru, wywoaj funkcj glDisable(GL_COLOR_MATERIAL).
Parametry
face GLenum: Okrela, ktra strona wielokta powinna ledzi biecy kolor.
Dozwolone parametry to GL_FRONT (przednia), GL_BACK (tylna) lub
GL_BACK_AND_FRONT (obie strony).
mod GLenum: Okrela, ktra waciwo materiau ma zalee od biecego
koloru. Dozwolone parametry to GL_EMISSION, GL_AMBIENT,
GL_DIFFUSE, GL_SPECULAR oraz GL_AMBIENT_AND_DIFFUSE.
Zwracana warto Brak
Przykad Poniszy kod z przykadowego programu AMBIENT wcza ledzenie
koloru, a nastpnie ustawia waciwo otaczajc i rozpraszajc
materiau tak, aby ledziy kolor ustawiany funkcj glColor
// Wczenie ledzenia koloru przez materiay
glEnable(GL_COLOR_MATERIAL);
glCulIFace
Przeznaczenie Okrela, ktra strona wielokta, przednia czy tylna, ma by usuwana z
rysunku.
Plik nagwkowy
Skadnia void glCullFace(GLenum mod);
Opis Ta funkcja wycza obliczenia dotyczce owietlenia, cieniowania i koloru
przedniej lub tylnej strony wielokta. Jeli, na przykad, obiekt jest
zamknity i tylne ciany wieloktw nigdy nie bd widoczne, bez wzgldu
na przemieszczenie i obrt, wyczenie rysowania tylnych cian
wyeliminuje niepotrzebne obliczenia w scenie. Usuwanie niewidocznych
cian jest wczane i wyczane przez wywoanie funkcji glEnable i
glDisable z parametrem GL_CULL_FACE. Przednia i tylna strona
wielokta jest definiowana funkcj glFrontFace oraz poprzez kolejno
definiowania wierzchokw wielokta (przeciwnie do ruchu wskazwek
zegara lub zgodnie z nim).
Parametry
mod GLenum: Okrela, ktra strona wielokta powinna by usunita. Dozwolone
parametry to GLJFRONT (przednia) lub GLJ3ACK (tylna).
Zwracana warto Brak
Przykad Poniszy kod z przykadowego programu AMBIENT pokazuje sposb
wyczenia oblicze dotyczcy wntrza samolotu. Oprcz tego konieczne
jest wskazanie, ktra strona wieloktw jest na zewntrz, przez okrelenie
kierunku uoenia ich wierzchokw.
// Wielokty o kierunku przeciwnym do //
ruchu wskazwek s widziane z przodu
glFrontFace(GL_CCW);
// Nie pokazuj wntrza obiektw
glEnable(GL_CULL_FACE);
glFrontFace
Przeznaczenie Okrela, ktra strona wielokta jest traktowana jako przednia, a ktra jako
tylna.
Plik nagwkowy
Skadnia void glFrontFace(GLenum mod);
Opis Gdy scena skada si z obiektw zamknitych (nie mona zobaczy ich
wntrza), nie ma potrzeby obliczania koloru i wiata dla wewntrznych
stron obiektu. Do wyczenia tych oblicze suy funkcja glCulIFace. Z kolei
funkcja glFrontFace okrela, ktra strona wielokta ma by
Rozdzia 9. * Owietlenie i rda wiata 311
gIGetMaterial
Przeznaczenie Zwraca biece waciwoci materiau.
Plik <gl.h>
nagwkowy void glGetMaterialfv(GLenum face, GLenum pname, GLfloat *params);
Skadnia void glGetMaterialiv(GLenum face, GLenum pname, GLint *params);
Ta funkcja jest uywana do odczytywania biecych waciwoci materiau
przednich lub tylnych cian wieloktw. Zwracane wartoci s umieszczane
pod adresem wskazywanym przez params. W wikszoci przypadkw
bdzie to tablica czterech wartoci zawierajca skadowe RGBA
odczytywanej waciwoci.
Paramet
ry face GLenum: Okrela stron wielokta, ktrej waciwoci materiau bd
odczytywane. Dozwolone parametry to GL_FRONT (strona przednia) lub
GL_BACK (strona tylna).
312 Cz II Uywanie OpenGL
gIGetLight
Przeznaczenie Zwraca informacje o biecych parametrach wiata.
Plik nagwkowy <gl.h>
Skadnia void glGetLightfv(GLenum light, GLenum pname, GLfloat *params);
void glGetLightiv(GLenum light, GLenum pname, GLint *params);
Opis Ta funkcja jest uywana do odczytywania biecych waciwoci jednego z
omiu rde wiata. Zwracane wartoci s umieszczane pod adresem
wskazywanym przez params. W wikszoci przypadkw bdzie to tablica
czterech wartoci zawierajca skadowe RGBA odczytywanej waciwoci.
Rozdzia 9. Owietlenie i rda wiata 313
Parametry
ttght GLenum: Okrela rdo wiata, ktrego parametry chcemy odczyta. Ta
pname warto naley do zakresu od O do GL_MAX_LIGHT (8 dla Windows NT i
params Windows 95). Stae dla rde wiata to GL_LIGHTO, GL_LIGHT1 ...
GL_LIGHT7.
Zwracana
GLenum: Okrela waciwo wiata, ktr chcemy odczyta. Dozwolone
warto wartoci to GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR,
Przykad GL_POSITION, GL_SPOT_DIRECTION, GL_SPOT_EXPONENT,
GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION,
GL_LINEAR_ATTENUATION oraz GL_QUADRATIC_ATTENUATION.
GLint* lub GLfloat*: Tablica liczb zmiennopozycyjnych lub cakowitych
reprezentujca zwracane wartoci. Wartoci zwracane s w formie tablicy
czterech, trzech lub jednego elementu. Wartoci zwracane dla kadej z
waciwoci zawiera tabela 9.2.
Brak
Poniszy kod ilustruje sposb odczytania i przechowania biecych
waciwoci rda wiata.
// Miejsce na waciwoci rda wiata
GLfloat ambientComp[4], diffuseComp[4], specularComp[ 4 ] ;
Tabela 9.2.
Dostpne parametry funkcji glGetLight
Tabela 9.2.
Dostpne parametry funkcji glGetLight - cig dalszy
gILight
Przeznaczenie Ustawia parametry jednego z omiu dostpnych rde wiata. <gl.h>
Plik nagwkowy void glLightf(GLenum light, GLenum pname, GLfloat param); void
Skadnia
glLighti(GLenum light, GLenum pname, GLint param); void
Opis glLightfv(GLenum light, GLenum pname, const GLfloat *params); void
glLightiv(GLenum light, GLenum pname, const GLint *params);
Ta funkcja jest uywana do ustawiania parametrw jednego z omiu rde
wiata. Pierwsze dwie odmiany funkcji wymagaj jedynie pojedynczego
parametru sucego do ustawienia jednej z nastpujcych waciwoci:
GL_SPOT_EXPONENT,GL_SPOT_CUTOFF,
GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION oraz
GL_QUADRATIC_ATTENUATION.
Dwie pozostae odmiany wymagaj podania wskanika do tablicy kilku
waciwoci. W ten sposb okrelane s waciwoci:
GL_AMBIENT, GL_DIFFUSE, GL_SPECULAR, GL_POSITION,
GL_SPOT_DIRECTION. Te odmiany funkcji mog by uyte take do
ustawienia parametrw skadajcych si z pojedynczej wartoci, przez
umieszczenie w tablicy *params pojedynczego elementu.
Parametry
light GLenum: Okrela rdo wiata, ktrego parametry chcemy zmodyfikowa.
pname Ta warto naley do zakresu od O do GL_MAX_LIGHT (8 dla Windows
NT i Windows 95). Stae dla rde wiata to GLJJGHTO, GL_LIGHT1 ...
GL_LIGHT7.
GLenum: Okrela waciwo wiata, ktr chcemy zmodyfikowa.
Dozwolone wartoci i znaczenie parametrw zawiera tabela 9.2.
Rozdzia 9. * Owietlenie i rda wiata 315
// Wczenie owietlenia
glEnable(GL_LIGHTING);
gilightModel
Przeznaczenie Ustawia parametry modelu owietlenia uywanego przez OpenGL.
Plik <gl.h>
nagwkowy void glLightModelf(GLenum pname, GLfloat param); void
Skadnia gILightModeli(GLenum pname, GLint param); void
Opis gILightModelfv(GLenum pname, const GLfloat *params); void
glLightModeliv(GLenum pname, const GLint *params);
Ta funkcja jest uywana do ustawiania parametrw modelu owietlenia
uywanego przez OpenGL. Moe by ustawiony dowolny z trzech
parametrw modelu owietlenia. GL_LIGHT_MODEL_AMBIENT jest
uywany do ustawienia domylnego wiata otaczajcego dla sceny.
Domylnie to wiato ma warto RGBA (0,2, 0,2, 0,2, 1,0). Do ustawienia
tego modelu mog zosta uyte jedynie dwie ostatnie odmiany funkcji, gdy
umoliwiaj przekazanie tablicy zawierajcej wartoci RGBA. Parametr
GL_LIGHT_MODEL_TWO_SIDE jest uywany do
316 Cz II Uywanie OpenGL
gIMaterial
Przeznaczenie Ustawia parametry materiau uywane w modelu owietlenia.
Plik nagwkowy <gl.h>
Skadnia void glMaterialf(GLenum face, GLenum pname, GLfloat param); void
Opis glMateriali(GLenum face, GLenum pname, GLint param);
void glMaterialfv(GLenum face, GLenum pname, const GLfloat *params);
void glMaterialiv(GLenum face, GLenum pname, const GLint *params);
Ta funkcja jest uywana do ustawienia waciwoci materiau wieloktw.
Parametry GL_AMBIENT, GL_DIFFUSE oraz GL_SPECULAR
wpywaj na sposb odbijania odpowiednich skadowych wiata.
GL_EMISSION jest uywanew celu nadania materiaom takiego wygldu,
jakby emitoway wasne wiato. GL_SHININESS moe zmienia si w
zakresie od O do 128, gdzie wiksze wartoci powodujjaniejsze i bardziej
skupione plamy odbyskw na powierzchni materiau. Na koniec,
GL_COLOR_INDEXES jest uywany w celu okrelenia waciwoci
materiau w trybie indeksu koloru.
Parametry
face GLenum: Okrela stron
pname wielokta, do ktrej bd si
odnosi ustawiane
waciwoci materiau.
Dozwolone parametry to
GL_FRONT (strona
przednia), GL_BACK (strona
tylna) lub
GL_FRONT_AND_BACK
(przednia i tylna).
GLenum: Dla pierwszych
dwch odmian okrela
warto parametru
param reprezentowanego przez
pojedyncz warto. Obecnie
jedynym takim parametrem
params jest GL_SHININESS.
Pozostae dwie odmiany,
wymagajce przekazania
tablicy wartoci, mog suy
do ustawienia nastpujcych
waciwoci:
GL_AMBIENT,
GL_DIFFUSE,
GL_SPECULAR,
GL_EMISSION,
GL_SHININESS,
GL_AMBIENT_AND_
DIFFUSE oraz
GL_COLOR_INDEXES
.
GLint lub GLfloat:
Warto parametru
okrelanego przez
pname
(GL_SHININESS).
GLint* lub GLfloat*: Tablica
liczb cakowitych lub
zmiennopozycyjnych
zawierajca wartoci dla
ustawianego parametru.
gINormal
Przeznaczenie Definiuje normaln do powierzchni dla nastpnego wierzchoka lub
zestawu wierzchokw.
Plik nagwkowy
Skadnia void glNormal3b(GLbyte nx, GLbyte ny, GLbyte nz);
void glNorma!3d(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);
void glNorma!3bv(const GLbyte *v);
void glNorma!3dv(const GLdouble *v);
void glNormal3fv(const GLfloat *v);
void glNorma!3iv(const GLint *v);
void gINormal3sv(const GLshort *v);
Opis Wektor normalny jest skierowany w gr, prostopady do powierzchni
Parametry nx
wielokta. Normalne s uywane w obliczeniach owietlenia
i cieniowania. Okrelenie wektora o dugoci l poprawia szybko
ny nz renderowania. OpenGL automatycznie konwertuje normalne na normalne
v jednostkowe w momencie wczenia parametru
glEnable(GLJNORMALIZE).
Zwracana warto
Okrela wsprzdn x wektora normalnego.
Przykad
Okrela wsprzdn y wektora normalnego.
Okrela wsprzdn z wektora normalnego.
Wskazuje tablic trzech wartoci odpowiadajcych wsprzdnym x, y i z
wektora normalnego.
Brak
Poniszy kod z programu LITJET demonstruje ustawianie wektora
normalnego przed rysowaniem wielokta.
float normal[ 3 ] ; // Wierzchoki dla tego
panelu float v [ 3 ] [ 3 ] = {{ 15.Of, O . O f ,
30.O f } , ( O.Of, 15.Of, 30.O f } ,
Rozdzia 9. Owietlenie l rda wiata____________________________319
Okrelenie zadania
Aby zademonstrowa budowanie obiektu z prostszych elementw, uyjemy interesujcego,
cho niezbyt skomplikowanego przykadu, tworzcego model metalowej ruby (takiej,
jakie su na przykad do przykrcania dyskw twardych). Cho nasza rubka moe nie
by dostpna w adnym sklepie z elastwem, ma jednak pewne zalety. Po-
322_______________________________________Cz II Uywanie OpenGL
winnimy wic uczyni j tak prost, jak to tylko moliwe, starajc si jednak niczego nie
utraci z sensu naszego zadania.
ruba bdzie miaa szecioktn gwk oraz nagwintowany trzpie, podobnie jak wiele
innych typowych stalowych rubek. Poniewa to tylko wiczenie, uprocimy gwint
owijajc" go na powierzchni trzpienia, a nie wycinajc go w nim.
Szkic modelu, jaki chcemy utworzy, przedstawia rysunek 10.1. Zbudujemy trzy gwne
elementy tej ruby - gwk, trzpie oraz gwint - indywidualnie, a nastpnie zoymy je
razem w kocowy obiekt.
Wybr rzutowania
Zanim zaczniemy konstruowanie, najpierw potrzebujemy rzutowania, czyli paszczyzny
odniesienia dla przedstawianych obiektw. W przypadku tego przykadu najlepsze bdzie
rzutowanie rwnolege. To typowe rzutowanie dla aplikacji typu C AD, w ktrych obiekt
jest dokadnie mierzony i modelowany. Ta ruba ma okrelon wysoko, szeroko i ilo
zwojw gwintu, a przy tym pozostaje stosunkowo maa. Uycie rzutowania
perspektywicznego miaoby sens wtedy, gdybymy modelowali co wikszego, na przykad
krajobraz, w ktrym efekt perspektywy byby bardziej widoczny.
Listing 10.1 stanowi kod tworzcy bry widzenia. Tworzy rzutowanie rwnolege oraz
ukad wsprzdnych rozcigajcy si po 100 jednostek w osiach x i y. Wzdu osi z dodano
dodatkowe 100 jednostek; umiecimy tam obserwatora.
Listing 10.1. Przygotowanie rzutowania rwnolegego dla przykadw w tym rozdziale_______ ____
glMatrixMode(GL_MODELVIEW) ;
glLoadldentity{);
// Wczenie owietlenia
glEnable(GL_LIGHTING);
// Przygotowanie i wczenie wiata O
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLight);
glLightfv(GL_LIGHTO,GL_AMBIENT,ambientLight);
g!Lightfv(GL_LIGHTO,GL_DIFFUSE,diffuseLight);
glLightfv(GL_LIGHTO,GL_SPECULAR,specular); <
324____________________________________Cz II Uywanie OpenGL
// Czarne to
glClearColor(O.Of, O . O f , O . O f , l.Of );
Wywietlanie rezultatu
Gdy okrelilimy widok, owietlenie oraz parametry materiau, jedyne co pozostao, to
wyrenderowanie sceny. Listing 10.3 przedstawia schemat kodu uywanego do wywie-
tlania ruby i jej elementw. Wystpujce tu linie SomeFunc() to po prostu miejsca na
wywoania funkcji indywidualnie renderujcych gwk, trzpie i gwint ruby. Zacho-
wujemy stan macierzy, wykonujemy obroty (za pomoc klawiszy kursora, podobnie jak w
innych przykadach w tej ksice) oraz wywoujemy funkcj renderujc dany element
obiektu.
Zdecydowalimy si podzieli rub na trzy czci: gwk, trzpie i gwint. Takie po-
dejcie zdecydowanie uatwia nam graficzne zaprojektowanie elementw, ale take daje
nam trzy obiekty, ktre moemy wykorzysta w przyszoci. W bardziej skomplikowanych
aplikacjach do modelowania, atwo ponownego wykorzystania ma decydujce
znaczenie. Na przykad w aplikacji typu C AD bdziesz musia modelowa wiele rnych
rodzajw rub - o rnych dugociach, grubociach i gstoci gwintu. Zamiast funkcji
RenderHead(), renderujcej gwk w naszym przykadzie, mgby napisa funkcj
pobierajc parametry okrelajce ilo ktw, grubo i rednic gwki ruby.
Kolejn rzecz jest fakt, e kady element ruby modelujemy w ukadzie wsprz-
dnych najwygodniejszym do opisania obiektu. Najczciej obiekty s modelowane w
pocztku ukadu wsprzdnych, a dopiero pniej przemieszczane w odpowiednie
miejsce. Pniej, gdy bdziemy komponowa ostateczny obiekt, bdziemy przenosi i
obraca poszczeglne elementy, a nawet skalowa je w razie potrzeby.
Gwka
Gwka naszej ruby ma ksztat prostopadocianu o szeciu cianach oraz paskich
podstawach. Moemy skonstruowa ten obiekt z dwch szecioktw reprezentujcych
d i gr gwki oraz serii szeciu czworoktw reprezentujcych boczne cianki. Mo-
glibymy uy prymityww GL_QUAD i GL_POLYGON, aby rysowa przy jak naj-
mniejszej liczbie wierzchokw; jednak, jak ju wczeniej wspomnielimy, jeli to tylko
moliwe, powiniene uywa trjktw. W przypadku kadej karty akceleratora OpenGL (a
take pewnych programowych implementacji) zwykle krcej trwa narysowanie
dwch trjktw ni jednego czworokta.
Rysunek 10.2 pokazuje, w jaki sposb gwka naszej ruby zostanie skonstruowana z
trjktw. Uyjemy wachlarza szeciu trjktw dla grnej i dolnej powierzchni, za
kada z bocznych cianek bdzie skada si z dwch trjktw.
Rysunek 10.2.
Trjkty skadajce
si na gwk ruby
e kod nie zawiera adnych funkcji, ktrych dotd nie omawialimy, lecz jest bardziej
zoony ni jakikolwiek wczeniejszy przykad.
Rysunek 10.3.
Dziaanie programu
HEAD
// Przejcie do gry
corners [1] [0] = x;
corners [ 1 ] [ 1 ] = y;
cornersfl] [ 2 ] = O.Of;
// Obliczenie nastpnego punktu szeciokta x =
diameter* (float) sin (angle+step) ; y = diameter*
(float) cos (angle+step) ;
// Sprawdzenie, czy to koniec
if (angle+step < 3.1415*2.0)
{
// Jeli koniec, po prostu zamknicie wachlarza
// w znanej wsprzdnej
corners [ 2 ] [ 0 ] = x;
corners [ 2 ] [ 1 ] = y;
corners[2] [ 2 ] = O . O f ;
corners [ 3 ] [ 0 ) = x;
corners [ 3 ] [ 1 ] = y;
corners [ 3 ] [ 2 ] = -height;
else
// Jeli nie koniec, punkty na grnej i dolnej //
czci gwki corners [2] [0] = O.Of; corners [ 2 ]
[ 1 ] = diameter; corners[2] [ 2 ] = O . O f ;
corners[3] [0] = O . O f ;
corners [ 3 ] [ 1 ] = diameter;
corners [ 3 ] [2] = -height;
glEnd();
Trzpie
Trzpie ruby nie jest niczym innym jak cylindrem z dnem. Utworzymy cylinder roz-
kadajc punkty na okrgu w paszczynie xy, a nastpnie uyjemy dwch wartoci z
w tych punktach, tworzc wielokty przybliajce cianki cylindra. Jednak take tym
Rozdzia 10. Modelowanie i kompozycja obiektw 3D_____________________329
Rysunek 10.4.
Trjkty skadajce
si na cianki
cylindra
corners[ 3 ] [ 0 ] = x;
corners[ 3 ] [ 1 ] = y;
corners[ 3 ] [ 2 ] = -height;
else
corners[3][0] = O . O f ;
corners[ 3 ] [ 1 ] = diameter;
corners[ 3 ] [ 2 ] = -height;
normal[2] = corners[ 1 ] [ 2 ] ;
ReduceToUnit(normal);
glNorma!3fv(normal);
glVertex3fv(corners[ 1 ] );
Na szczcie, cylinder jest owinity symetrycznie dookoa osi z. Tak wic normalna dla
kadego wierzchoka moe zosta obliczona przez znormalizowanie (zredukowanie do
dugoci jednostkowej) samego wierzchoka. Wynik dziaania programu SHAFT przed-
stawia rysunek 10.5.
Rysunek 10.5.
Wynik dziaania programu SHAFT
Gwint
Gwint jest najbardziej
skomplikowan czci
naszej ruby. Jest zoony z
dwch paszczyzn uoonych
w ksztat V, owinitych
spiralnie wzdu cylindra.
Jest tworzony jako dwa
paskie segmenty uoone w
V. Sposb konstruowania
gwintu przedstawia rysunek 10.6, za kod OpenGL uyty do jego utworzenia zawiera listing
10.6.
Rysunek
10.6.
Sposb
konstruowania
Rozdzia 10. Modelowanie i kompozycja obiektw 3D 333
corners[ 3 ] [ 0 ] = x;
corners[ 3 ] [ 1 ] = y;
corners [ 3 ] [ 2 ] = z+ zstep;
// Uywamy trjktw, wic wybierzemy kierunek
// przeciwny do ruchu wskazwek
glFrontFace(GL_CCW);
glBegin(GL_TRIANGLES); // Pocztek grnej sekcji gwintu
// Przejcie w gr osi Z z
+= zstep;
Rozdzia 10. * Modelowanie i kompozycja obiektw 3D 335
Rysunek 10.7.
Wynik dziaania
programu THREAD
Rysunek 10.8.
Dziaanie programu BOLT
336_______________________________________Cz II Uywanie OpenGL
Test szybkoci
Nasz ostatni program do dobrze prezentuje metalow rub, jak chcielimy wymode-
lowa. Skadajc si z ponad 1700 trjktw, jest to jak dotd najbardziej skompliko-
wany obiekt w tej ksice. Jednak trzeba przyzna, e ta ilo trjktw jest niczym w
porwnaniu z liczbami wieloktw, z jakimi si zetkniesz komponujc wiksze sceny i
bardziej zoone obiekty. W rzeczywistoci, wydajno najnowszych kart akceleratorw
3D jest mierzona w setkach tysicy trjktw na sekund, i to ju w przypadku
taszych modeli! Jednym z celw tego rozdziau byo wprowadzenie list wywietlania w
celu przyspieszenia renderowania. Zanim jednak przejdziemy do porwna, potrze-
bujemy jakiego sposobu mierzenia szybkoci - testu szybkoci.
Gdy przechodzimy do tematu list wywietlania, chcemy wiedzie, czy wystpuje jaka
rnica, zamiast wierzy wszystkiemu na sowo. Zmodyfikujmy wic nasz program
BOLT. Zamiast obraca rub za pomoc klawiszy kursora, obracajmy j cay czas,
Rozdzia 10. Modelowanie i kompozycja obiektw 3D_____________________337
choby wycznie w osi y. Jak si zapewne domylasz, w ten sposb zamienimy program
w generator trjktw, ktrego moemy atwo uy do zmierzenia wydajnoci.
Zmienion funkcj RenderScene() z programu SPINBOLT przedstawia listing 10.8.
Listing 10.8. Nowa funkcja RenderScene() obracajca rub dookoa osi y__________________
Nowa funkcja renderowania nie zachowuje ani nie odtwarza stanu macierzy. Uywamy
funkcji glTranslate, aby rcznie odtworzy stan przesunicia macierzy, jednak efekty
funkcji glRotate si kumuluj. To powoduje, e ruba obraca si dookoa swojej osi y o
5 za kadym razem, gdy jest renderowana.
Prosta technika animacji polega na stworzeniu timera, a gdy zostanie otrzymany komunikat
WM_T1MER, uniewanieniu obszaru okna w celu odmalowania go. W ten sposb moemy
w miar potrzeby spowalnia lub przyspiesza animacj. Naszym celem nie jest jednak
prosta animacja, ale raczej poznanie tempa obrotw. Sensownym kryterium bdzie czas,
wymagany, aby ruba obrcia si o pene 360 stopni.
Uycie komunikatw WM_TIMER nie jest najlepszym rozwizaniem z dwch powodw.
Po pierwsze, nikt nie gwarantuje, e okno otrzyma wszystkie komunikaty WM_TI-MER
(system operacyjny moe by zbyt zajty). Po drugie, gdy okrelisz przedziay czasu,
jak mierzenie odstpw czasu bdzie si miao do rzeczywistej wydajnoci?
renderowanie sceny wiksz ilo razy i mierzc czas, jaki to zabierze, otrzymamy zu-
penie poprawny test czasu.
// Wywietlenie obrazka
SwapBuffers(hDC);
// Zwikszenie licznika. Jeli >= 71 -> koniec mierzenia //
czasu iRenderCount+ + ;
Procedura obsugi odczytuje biecy czas systemowy i zlicza ilo wywoa funkcji
renderujcej. Po 71 razach odczytuje nowy czas, oblicza rnic i wywietla czas, jaki
upyn od ostatniego pomiaru. Pamitaj, e nasza ruba obraca si za kadym razem o
5, wic uywajc tej techniki naliczamy czas trwania obrotu o 360.
Rysunek 10.9.
Dziaanie programu SPINBOLT
340 Cz II Uywanie OpenGL
Poprawianie wydajnoci
By moe dostrzege, gdzie tkwi problem z wydajnoci w programie korzystajcym z
techniki WM_PA1NT. Podczas kadego rysowania ruby naley wykona ogromn
ilo oblicze zwizanych z rysowaniem gwintu, trzpienia i gwki. W tych obliczeniach
mnstwo razy odwoujemy si do kosztownych wywoa funkcji sin() i cos().
To, czego nam potrzeba, to sposb przechowania wszystkich obliczonych wierzchokw
i normalnych, a nastpnie wykorzystanie ich bez koniecznoci kadorazowego
przechodzenia przez ca t trygonometri. Oczywicie, OpenGL moe nam w tym
wzgldzie duo zaoferowa, a mianowicie listy wywietlania. Za pomoc listy wywie-
tlania moesz zarejestrowa wywoania funkcji OpenGL (oraz ich wyniki), a nastpnie je
odtworzy. Listy wywietlania s szybsze ni ponowne odtwarzanie pojedynczych
wywoa OpenGL. Co wicej, wywoania zewntrzne dla OpenGL, takie jak obliczanie
funkcji trygonometrycznych i normalnych, nie s powtarzane, lecz s rejestrowane je-
dynie ich wyniki, przekazywane funkcjom OpenGL. Ju z tego powiniene si zorien-
towa, dlaczego listy wywietlania s tak dobrym pomysem.
Ludzie i komputery
Dobr regu podczas tworzenia dowolnego oprogramowania
jest zajcie si poprawkami, ktre daj
ponaddwudziestoprocentowy wzrost wydajnoci. Zostao
oglnie przyjte, e ludzie w wikszoci przypadkw maj
trudnoci z wykryciem" wzrostu wydajnoci oprogramowania
o mniej ni dwadziecia procent. W przypadku OpenGL te 20%
mona czsto osign wanie przez zastosowanie list
wywietlania tam, gdzie liczba wieloktw staje si znaczna.
Tak wic dobrym pomysem jest przyzwyczajenie si do
uywania list wywietlania.
glNewListd, GL_COMPILE);
glEndList();
Jako drugi parametr funkcji glNewList moesz poda GL_COMPILE lub GL_COM-
PILE_AND_EXECUTE. Informuje on OpenGL o tym, czy polecenia OpenGL maj
zosta skompilowane i przechowane, czy te skompilowane, wykonane i przechowane.
Pniej, gdy chcesz odtworzy list wywietlania, wywoaj po prostu
glCallList(l);
Listing 10.10. Nowy kod wirujcej ruby, tym razem korzystajcy z list wywietlania____________
#define HEAD_LIST l
define SHAFT_LIST 2
#define THREAD_LIST 3
define BOLT_LIST 4
Symulator czogu
Sprbuj uruchomi symulator czogu z poprzedniego rozdziau i porwna
go z symulatorem w tym rozdziale. Ta wersja, w duym stopniu
korzystajca z list wywietlania, zawiera wiele tysicy trjktw i nie
potrzebujesz adnego programu do testowania wydajnoci, aby zauway
rnic w dziaaniu!
Podsumowanie
Wykorzystywalimy ten rozdzia do pokazania, w jaki sposb tworzy si zoone trj-
wymiarowe obiekty, poczynajc od uycia prymityww OpenGL do budowania prostych
trjwymiarowych klockw, a nastpnie skadania ich w wiksze obiekty. Sama nauka
interfejsu programowania jest atwa, ale to wanie dowiadczenie w konstruowaniu
trjwymiarowych scen i obiektw bdzie ci wyrnia spord innych osb zajmujcych
si tym zagadnieniem. Gdy obiekt lub scena zostan rozbite na mniejsze, potencjalnie
ponownie wykorzystywalne czci, moesz oszczdzi czas renderowania sceny tworzc
listy wywietlania. W sekcji podrcznika znajdziesz wicej funkcji przeznaczonych do
wykorzystania, wywietlania i zarzdzania listami. Oprcz tego, na kocu rozdziau
poznae prosty sposb mierzenia wydajnoci swojego programu, umoliwiajcy
porwnanie korzyci pyncych z optymalizacji kodu.
Podrcznik
glCallList
Przeznaczenie Wykonuje list wywietlania
Plik nagwkowy
Skadnia Opis void glCallList(GLuint list);
Wykonuje list wywietlania identyfikowan przez parametr list. Po
wywoaniu tej funkcji maszyna stanu OpenGL nie jest odtwarzana, wic
344 Cz II * Uywanie OpenGL
glCallLists
Przeznaczenie Wywouje list list wywietlania.
Plik nagwkowy
Skadnia Opis void glCallLists(GLsizei n, GLenum type, const GLvoid *lists);
Wywouje kolejno listy wywietlania wskazywane w tablicy *lists. Ta
tablica moe by prawie dowolnego typu. Rezultat jest zamieniany lub
obcinany do najbliszej liczby cakowitej, ktra bdzie stanowi indeks
(identyfikator) konkretnej listy wywietlania. Opcjonalnie, wartoci z listy
mog zosta przesunite o pewn warto bazow, okrelon
wywoaniem funkcji glListBase.
Parametry
n type GLsizei: Ilo elementw tablicy list wywietlania.
GLenum: Rodzaj elementw przechowywanych w licie *lists. Moe by
jedn z nastpujcych wartoci: GL_BYTE, GL_UNSIGNED_BYTE,
GL_SHORT, GL_UNSIGNED_SHORT, GLJNT, GLJJNSIGNEDJNT,
GL_FLOAT, GL_2_BYTES, GL_3_BYTES lub GL_4_BYTES.
GLvoid: Tablica elementw typu okrelanego parametrem type.
Zadeklarowanym typem danych jest void, co umoliwia uycie
dowolnego z wymienionych powyej typw.
jg OpenGl Rozdzia 10. * Modelowanie i kompozycja obiektw 3D 345
// Pierwsza lista
glNewList(lists[0],GL_COMPILE);
glEnd ();
// Druga lista
glNewList(listS[q],GL_COMPILE);
glEnd();
// I tak dalej.. .
glDeleteLists
Przeznaczenie Usuwa cigy zakres list wywietlania.
Plik nagwkowy
Skadnia Opis void glDeleteLists(GLuint list, GLsizei rang);
Ta funkcja usuwa zakres list wywietlania. Usuwanie rozpoczyna si od
pocztkowej listy list i trwa do momentu usunicia rang list. Usuwanie
nieuywanych list wywietlania pozwala odzyska znaczne iloci pamici.
Nieuywane listy wywietlania z podanego zakresu s ignorowane i nie
powoduj bdw.
Parametry
list GLuint: Identyfikator pierwszej usuwanej listy.
rang Zwracana GLsizei: Ilo list wywietlania, jakie maj zosta usunite.
warto Brak
Cz II Uywanie OpenGL
Przykad
Patrz take
346
Ponisza linia kodu ilustruje usuwanie wszystkich list wywietlania o
identyfikatorach pomidzy l a 50:
F
glDeleteLists(l, 5 0 ) ;
glEndList
Przeznaczenie Plik Wyznacza koniec listy wywietlania.
nagwkowy
Skadnia Opis void glEndList(void);
Zwracana warto Listy wywietlania s tworzone przez wywoanie funkcji glNewList.
Wszystkie nastpne polecenia OpenGL s kompilowane i umieszczane na
Przykad licie wywietlania. Funkcja glEndList koczy tworzenie listy wywietlania.
Brak
Poniszy kod stanowi przykad tworzenia listy wywietlania za pomoc
funkcji glNewList i glEndList. Tworzona lista skada si z dwch
zagniedonych w niej list.
// Pocztek listy wywietlania
glNewList (BOLT_LIST, GL_COMPILE) ;
// Lista wywietlania zawiera dwie zdefiniowane //
uprzednio listy wywietlania glCallList (SHftFT_LIST) ;
glCallList (THREAD_LIST) ;
// Koniec listy wywietlania
glEndList O ;
glCallList, glCallLists, glDeleteLists, glGenLists, gllsList
Patrz take
glGenLists
Przeznaczenie Generuje cigy zakres pustych list wywietlania.
Plik nagwkowy
Skadnia Opis GLuint glGenLists(GLsizei rang);
Funkcja tworzy zakres pustych list wywietlania. Ilo tworzonych list
zaley od wartoci argumentu rang. Zwracan wartoci jest
identyfikator pierwszej listy z zakresu. Celem tej funkcji jest
zarezerwowanie zakresu identyfikatorw list do pniejszego uytku.
Parametry
rang GLsizei: Ilo danych pustych list.
Rozdzia 10. * Modelowanie i kompozycja obiektw 3D 347
Zwracana warto Identyfikator pierwszej listy z zakresu. Zostaj utworzone puste listy z
Przykad zakresu od zwracanej wartoci do range-l.
Poniszy kod alokuje tablic 25 liczb cakowitych, ktre zostan uyte do
przechowania identyfikatorw 25 list wywietlania. Kademu elementowi
tablicy musi zosta przypisany poprawny identyfikator listy, ktry moe
zosta uyty pniej.
int l i s t s [ 2 5 ] ; // miejsce na 25 list wywietlania
int first; // indeks pierwszego dostpnego
// identyfikatora listy wywietlania int
x; // Licznik ptli
gllsList
Przeznaczenie Plik Sprawdza, czy istnieje dana lista.
nagwkowy
Skadnia Opis GLboolean gl!sList(GLuint list);
Ta funkcja jest uywana do sprawdzania, czy istnieje lista wywietlania o
danym identyfikatorze. Moesz jej uy do sprawdzenia listy przed jej
Parametry zastosowaniem.
list Zwracana
warto GLuint: Identyfikator potencjalnej listy wywietlania.
GLJTRUE jeli dana lista wywietlania istnieje, lub warto GL_FALSE w
Przykad przeciwnym wypadku.
Poniszy kod przeglda tablic, ktra powinna zawiera poprawne
identyfikatory list. Jeli lista o danym identyfikatorze istnieje, zostaje
wywoana.
int l i s t s [ 2 5 ] ; // miejsce na 25 list wywietlania
int x; // Licznik ptli
gllistBase
Przeznaczenie Okrela warto bazow dodawan do identyfikatorw list
wywoywanych funkcj glCallLists.
Plik nagwkowy
Skadnia void glListBase(GLuint base);
Opis Funkcja glCallLists wywouje seri list wywietlania zawartych w tablicy.
Funkcja glListBase ustawia warto bazow, ktra zostaje dodana do
kadego identyfikatora listy w tablicy. Domyln wartoci bazow jest
zero. Moesz odczyta biec warto wywoujc funkcj
glGet(GL_LIST_BASE).
GLuint: Warto, ktra zostanie dodana do identyfikatora listy w tablicy list,
Parametry wywoywanych funkcj glCallLists. Domylnie ta warto jest rwna zeru.
base Brak.
Poniszy kod tworzy 20 list wywietlania ponumerowanych od O do 19.
Zwracana warto Tworzona jest tablica identyfikatorw list (listA), zawierajca liczby od O do
Przykad 9. Nastpnie jest wywoywana funkcja glCallLists wykonujca wszystkie
listy wystpujce w tablicy listA. Nastpnie, zamiast adowania tablicy
kojejnymi dziesicioma liczbami, za pomoc funkcji glListBase zmieniana
jest warto bazowa. Po ponownym wywoaniu funkcji CallLists dla tablicy
listA, zostan wywoane listy okrelone przez elementy tablicy powikszone
o warto bazow (10).
int listA[10]; int
i;
glEndList();
glEndList();
// I tak dalej...
glNewlist
Przeznaczenie Rozpoczyna tworzenie nowej listy odtwarzania.
Plik nagwkowy
Skadnia Opis void glNewList(GLuint list, GLenum mod);
Lista wywietlania jest grup polece OpenGL zarejestrowanych w celu
pniejszego wywoania i wykonania. Moesz uywa list wywietlania do
przyspieszania zoonych obliczeniowo rysunkw lub wymagajcych danych
odczytywanych z dysku. Funkcja glNewList rozpoczyna tworzenie listy,
ktr jednoznacznie identyfikuje pierwszy parametr. Identyfikatory list s
uywane w funkcjach glCallList i glCallLists w celu okrelenia listy, ktra
ma by wywoana. Jeli identyfikator nie jest unikatowy, poprzednia lista
moe zosta zastpiona. W celu zarezerwowania zakresu identyfikatorw
moesz uy funkcji glGenLists. W celu sprawdzenia, czy istnieje lista o
danym identyfikatorze, moesz uy funkcji gllsList. Listy wywietlania
mog by jedynie kompilowane albo kompilowane i wykonywane. Po
wywoaniu polecenia glNewList, nastpnie polecenia OpenGL s
rejestrowane i przechowywane w licie odtwarzania w kolejnoci ich
wystpienia, a do momentu napotkania polecenia glEndList. Wykonywane,
lecz nigdy nie s rejestrowane w samej lici s poleceniem: glGenLists,
glDeleteLists, glFeedbackBuffer, glSelectBuffer, glRenderMode,
glReadPixels, glPixelStore, glFlush, glFinish, gllsEnabled oraz glGet.
Parametry
list GLuint: Numeryczny identyfikator listy wywietlania. Jeli istnieje ju lista
o takim identyfikatorze, zostanie zastpiona przez now list.
mod GLenum: Listy wywietlania mog by kompilowane w celu pniejszego
wykonania lub kompilowane i wykonywane jednoczenie. Jeli chcesz
jedynie skompilowa list, zastosuj parametr GL_COMPILE. Jeli chcesz
skompilowa i jednoczenie wykona list wywietlania, zastosuj parametr
GL_COMPILE_AND_EXECUTE.
Zwracana warto Brak.
Przykad Poniszy kod stanowi przykad tworzenia listy wywietlania za pomoc
funkcji glNewList i glEndList. Tworzona lista skada si z dwch
zagniedonych w niej list.
350 Cz II Uywanie OpenGL
Rysowanie bitmap
Bitmapy w OpenGL to dwukolorowe obrazy, uywane do szybkiego rysowania na ekranie
znakw lub symboli (na przykad ikon). Rni si to od (bdnej) definicji stosowanej w
Microsoft Windows, ktre do bitmap zaliczaj take obrazki posiadajce wicej kolorw.
W OpenGL do rysowania bitmap suy pojedyncza funkcja, glBitmap. Gdy za
352 Cz II * Uywanie OpenGL
jej pomoc rysujesz bitmap, pierwszy kolor (0) jest przezroczysty. Drugi (1) jest ustalany
na podstawie biecego koloru i waciwoci owietlenia dla materiau.
Rysunek
11.1.
Przyklad bitmapy
w OpenGL
void
RepaintWindow(RECT *rect) /* Obszar roboczy */
int i;
static GLubyte sraileyt] /* buka 16x16 */
0x03, OxcO, O, O, /*
OxOf, OxfO, O, O, /*
Oxle, 0x78, O, O, /* *** ** ***
0x39, Ox9c, O, O, /*
0x77, Oxee, O, O, /* *** ****** ***
Ox6f, O x f 6 , O, O, /* **
******** **
Oxff, Oxff, O, O, /* ****************
Oxff, Oxff, O, O, /* ****************
Oxff, Oxff, O, O, /* ****************
Oxff, Oxff, O, O, /* ****************
0x73, Oxce, O, O, /* *** **** ***
0x73, Oxce, O, O, /* *** **** ***
Ox3f, Oxfc, O, O, /* ************
Oxlf, Oxf8, O, O, /* **********
OxOf, OxfO, O, O, /*
********
0x03, OxcO, O, O /* ****
glMatrixMode(GL_PROJECTION);
glLoadldentity();
g!0rtho(0.0, rect->right - 1 . 0 , 0 . 0 , rect->bottom - 1 . 0 , -1 .0 , 1 . 0 ) ;
/*
* Ta bitmapa jest wyrwnana do granicy 4 bajtw...
*/
glPixelTransferi(GL_UNPACK_ALIGNMENT, 4);
glColorSf ( 1 . 0 , 0 . 0 , 0 . 0 ) ;
for (i = 0 ; i < 100; i ++) {
glRasterPos2i(rand() % rect->right, rand() % rect->bottom);
glBitmap(16, 1 6 , 8 . 0 , 8 . 0 , 0 . 0 , 0 . 0 , smiley); };
glFinish();
W tym przypadku rysujemy bitmap 16 x 16, ktrej rodek ley w punkcie (8,0, 8,0)
bitmapy. Po narysowaniu bitmapy, pozycja rastra jest przesuwana o (0,0, 0,0) pikseli.
Prototyp tej funkcji jest nastpujcy:
glBitmap(GLsizei width, GLsizei height,
GLfloat xorig, GLfloat yorig,
GLfloat xmove, GLfloat ymove,
const GLubyte *bits)
Parametry width i height okrelaj szeroko i wysoko bitmapy. Parametr bits wskazuje
bitmap przeznaczon do narysowania, wyrwnan do granicy 32 bitw. Parametry xorig i
yorig zawieraj pooenie rodka bitmapy. Po narysowaniu bitmapy, bieca pozycja
rastra jest przesuwana o (xmove, ymove) pikseli, za znacznik poprawnej pozycji rastra
pozostaje niezmieniony. Parametry xmove i ymove zwykle s uywane przy rysowaniu
bitmapowych czcionek (opisywanych w nastpnej sekcji) w celu przejcia do komrki"
nastpnego znaku.
Czcionki bitmapowe
Jednym z bardzo wanych zastosowa bitmap jest wywietlanie acuchw znakw. W
zwykych warunkach musiaby zdefiniowa bitmap dla kadego znaku, a nastpnie
rysowaby bitmapy konieczne do narysowania acucha. Na szczcie, biblioteka Win32 w
Windows zawiera funkcj zwan wglUseFontBitmaps, przeznaczon do generowania
bitmap na podstawie czcionek zainstalowanych w systemie.
Aby umoliwi uycie bitmap czcionek, OpenGL dostarcza trzech funkcji: glGenLists,
glListBase oraz glCallList (opisanych w rozdziale 10). Funkcja glGenLists generuje cig
seri identyfikatorw list wywietlania OpenGL, ktre bd odpowiada bitmapom
znakw utworzonych funkcj WglUseFontBitmaps.
GLuint base;
HDC hdc;
base - glGenLists ( 9 6 ) ;
wglUseFontBitmaps(hdc, 32, 9 6 , base);
Ten kod tworzy 96 bitmap znakw z biecej czcionki, poczynajc od znaku 32, kodu
ASCII spacji. Zmienna base zawiera identyfikator listy wywietlania pierwszego znaku -
w tym przypadku znaku 32 (spacji w ASCII). Aby wywietli acuch znakw za pomoc
tej bitmapy, uyj poczenia funkcji glListBase oraz glCallLists:
char *s;
glListBase(font - 3 2 ) ; glCallLists(strlen(s),
GL_UNSIGNED_BYTE, s ) ;
GLuint
FontCreateBitmaps(HDC hdc, /* We - Kontekst urzdzenia */
char *typeface, /* We - Specyfikacja czcionki */ int
height, /* We - Wysoko czcionki w
^pikselach */
356 Cz II Uywanie OpenGL
if ( ( b a s e = glGenLists( 9 6 ) ) == 0)
return ( 0 ) ;
Argument typeface to po prostu nazwa czcionki, taka jak Courier czy Helvetica, okre-
lajca styl znakw. Argumenty height, width oraz italic (wysoko, szeroko, pochylenie)
s przekazywane bezporednio funkcji wglUseFontBitmaps i okrelaj rozmiar i wygld
znakw.
Zanim utworzysz bitmapy znakw, musisz zdecydowa si na wybr zestawu znakw.
Zwykle uywa si zestawu ANSI lub UNICODE. Zestaw znakw ANSI (ANSI_CHA-
RSET) zawiera standardowy zestaw znakw 7-bitowego ASCII. W celu uzyskania znakw
midzynarodowych i znakw diakrytycznych, uyj zamiast niego zestawu znakw
UNICODE (UNICODE_CHARSET). Pewne czcionki zawieraj zestawy znakw spe-
cjalnych. Na przykad czcionka Symbol zawiera litery alfabetu greckiego oraz wiele
symboli naukowych.
W tej prostej implementacji uyjemy zestawu znakw ANSI_CHARSET dla zwykfych
czcionek i zestawu SYMBOL_FONTSET dla czcionki Symbol. Spjrz na listing 11.3.
if (stricmpttypeface, "symbol") == 0)
font = CreateFont(height, O, O, O, weight, italic, FALSE, FALSE,
SYMBOL_CHARSET, OUT_TT_PRECIS, CLIP_DEFAULT_PRECIS,
DRAFT_QUALITY, DEFAULT_PITCH, typeface);
else
font
CreateFont(height, O, O, O, weight, italic, FALSE, FALSE,
ANSI_CHARSET, OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
DEFAOLT_PITCH, typeface);
SelectObject( h d c , f o n t ) ;
wglUseFontBitmaps(hdc, 32, 9 6 , b a s e ) ;
return (base);
else
font = CreateFont(height, O, O, O, weight, italic, FALSE, FALSE,
UNICODE_CHARSET, OUT_TT_PRECIS,
CLIP_DEFAULT_PRECIS, DRAFT_QUALITY,
DEFAULT_PITCH, typeface);
SelectObject(hdc, font);
wglOseFontBitmaps( h d c , 32, 224, base);
void
FontDelete(GLuint font) /* We - Czcionka do usunicia */
{
if (font == 0)
return;
glDeleteLists(font, 9 6 ) ;
Na koniec, aby uatwi sobie rysowanie znakw, moesz stworzy funkcj wypisywania
acuchw i wypisywania sformatowanych acuchw. Funkcja FontPuts (listing 11.5)
uywa funkcji glPushAttrib oraz glPopAttrib w celu zachowania i odtworzenia biecej
wartoci bazowej identyfikatorw list wywietlania. Jeliby o tym zapomnia, mgby
niechccy wpyn na inny kod rysunkowy, korzystajcy z list wywietlania!
void
FontPuts(GLuint font, /* We - Czcionka do uycia */
char *s) /* We - acuch do wypisania */
if (font == 0)
return;
if (s == NULL)
return;
glPushAttrib(GL_LIST_BIT);
glListBase(font - 3 2 ) ;
glCallLists(strlen(s), GL_UNSIGNED_BYTE, s ) ;
glPopAttrib();
358 Cz II * Uywanie OpenGL
Funkcja FontPrintf (listing 11.6) uywa pliku nagwkowego <stdarg.h> w celu zarz-
dzania zmienn liczb argumentw potrzebn do funkcji vsprintf, formatujc acuch,
ktry ma zosta wypisany.
void
FontPrintf(GLuint font, /* We - Czcionka do uycia */
// We - acuch formatowania w stylu funkcji printfO char *
format,
...) /* We - Inne argumenty w miar potrzeby */
{
va_list ap; /* Wskanik argumentw */
char s[MAX_STRING + 1 ] ; /* acuch wyjciowy */
if (format == NULL)
return;
Rysowanie pixmap
Do rysowania pixmap w OpenGL suy pojedyncza funkcja, glDrawPixels. Podobnie jak
glBitmap, glDrawPixels wykorzystuje biec pozycj rastra okrelajc pooenie
lewego dolnego rogu bitmapy. Nie okrela si jednak rodka bitmapy ani przesunicia
pozycji rastra.
BITMAPINFO *BitmapInfo;
GLubyte *BitmapBits;
Parametr format okrela przestrze kolorw pixmapy; dostpne formaty zostay zebrane w
tabeli 11.1. Format GL_COLOR_INDEX okrela, e kada warto koloru w pixma-pie
stanowi indeks do biecej logicznej palety kolorw Windows. Obrazki z indeksowanym
kolorem czsto s uywane do wywietlania ikon. Format GL_LUMINANCE
odwzorowuje kad warto koloru na skal szaroci na ekranie, gdzie warto mini-
malna odpowiada zupenej czerni, za warto maksymalna odpowiada zupenej bieli.
Format GL_RGB okrela, e kady piksel w obrazie posiada wasne intensywnoci
barw skadowych: czerwonej, zielonej i niebieskiej.
Tabela 11.1.
Formaty pikseli OpenGL
Format Opis
GL_COLOR_INDEX Piksele jako indeksy kolorw
GL_LUMINANCE Piksele w skali szaroci
GL_RGB Piksele RGB
Parametr type funkcji glDrawPixels okrela typ oraz zakres wartoci kolorw w obrazie, tak
jak opisano w tabeli 1 1.2.
360 Cz II Uywanie
OpenGL
Tabela 11.2.
Typy pikseli \v OpenGL
TYP Opis
GL_BYTE 8-bitowe wartoci ze znakiem (od -128
GL_UNSIGNEDJB do 127) 8-bitowe wartoci bez znaku (od
YTE GL BITMAP O do 255) Obraz bitmapy (od O do l)
Remapowanie kolorw
Gdy uywasz kolorw w formacie GL_COLOR_INDEX, moesz przemapowa kolory
pixmapy lub bitmapy, uywajc w tym celu funkcji glPixelMap lub glPixelTransfer.
Funkcja glPixelTransfer umoliwia okrelenie przeskalowania i przesunicia indeksw
kolorw i wartoci RGB. Na przykad, poniszy kod rozjania obraz RGB o 10 procent:
glPixelTransfer(GL_RED_SCALE, 1 . 1 ) ;
glPixelTransfer(GL_GREEN_SCALE, 1 . 1 ) ;
glPixelTransfer(GL_BLUE_SCALE, 1 . 1 ) ;
Podobnie, aby przesun indeksy kolorw bitmapy na pozycje palety, ktre dla nich
zdefiniowae, uyj
glPixelTransfer(GL_INDEX_OFFSET, kolor_dla_bitmapy);
Ox3f, Oxfc, O, O, /*
Oxlf, Oxf8, O, O, /*
OxOf, OxfO, O, O, /*
0x03, OxcO, O, O /*
Rozdzia 11. Grafika rastrowa__________________________________361
glMatrixMode(GL_PROJECTION);
glLoadldentity();
glOrtho(0.0, rect->right - 1.0, 0.0, rect->bottom - 1.0, -1.0,
1.0);
/*
* Ta bitmapa jest wyrwnana do granicy 4 bajtw...
*/
glPixelTransferi(GL_UNPACK_ALIGNMENT, 4);
glPixelTransferi(GL_INDEX_OFFSET, 1);
glFinishO;
Rysunek 11.2.
Obraz bez korekcji
gamma (po lewej) oraz
z korekcj gamma l, 7
(po prawej)
362____________________________________Cz II Uywanie OpenGL
glPixelTransfer(GL_MAP_COLOR, GL_TRUE);
glPixelMap(GL_PIXEL_MAP_R_TO_R, 256, l u t ) ;
glPixelMap(GL_PIXEL_MAP_G_TO_G, 256, l u t ) ;
glPixelMap(GL_PIXEL_MAP_B_TO_B, 256, l u t ) ;
Skalowanie pixmapy
Poza dostosowywaniem kolorw pixmapy, moesz dopasowa jej rozmiar, uywajc w
tym celu funkcji glPixelZoom. Ta funkcja przyjmuje dwa parametry zmiennoprzecin-kowe,
okrelajce wspczynniki skalowania obrazu w poziomie i w pionie:
glPixelZoom(l.O, 1 . 0 ) ; // Bez skalowania glPixelZoom(-l.O, 1 . 0 ) ;
// Odbicie lustrzane w poziomie glPixelZoom(l. 0 , - 2 . 0 ) ; // Odbicie
lustrzane w pionie i podwojenie
// wysokoci glPixelZoom(0.33, 0 . 3 3 ) ; //
Zmniejszenie obrazka do 1/3 wielkoci
Wykrawanie obszarw
Funkcja glPixelStore moe zosta uyta do wydzielenia jedynie czci obrazu. Na przykad,
aby wywietli centralny obszar o rozmiarze 300 x 300 pikseli z obrazu o rozmiarze 540 x
480 pikseli, mgby uy poniszego kodu:
glPixelStore(GL_UNPACK_ROW_LENGTH, 640);
glPixelStore(GL_UNPACK_SKIP_PIXELS, ( 6 4 0 - 300) / 2 ) ;
glPixelStore(GL_UNPACK_SKIP_ROWS, (480 - 300) / 2 ) ;
glDrawPixels(300, 300, GL_RGB, GL_ONSIGNED_BYTE, BitmapBits);
UWAGA:
Atrybuty GL_UNPACK_ROW_LENGTH,
GL_UNPACK_SKIP_PIXELS oraz GL_UNPACK_SKIP_ROWS
odnosz si do oryginalnych rozmiarw pixmapy, nie do
rozmiarw po przeskalowaniu!
void *
ReadDIBitmap(BITMAPINFO **info) /* Wy - Nagwek bitmapy */
long i, j,
bitsize, /* Cakowity rozmiar bitmapy */
width; /* Wyrwnana szeroko wiersza */
GLint viewport[ 4 ] ; /* Biecy widok */
void *bits; /* Bity RGB */
GLubyte *rgb, /* Zmienne ptli RGB */
temp; /* Zmienna tymczasowa */
/*
* Odczyt biecego w i d o k u . . .
*/
glGet!ntegerv(GL_VIEWPORT, viewport);
/*
* Zaalokowanie pamici na nagwek
*/
364 Cz II Uywanie OpenGL
if ( ( * i n f o (BITMAPINFO *)malloc(sizeof(BITMAPINFOHEADER)))
NULL)
return (NULL) ;
width = viewport[2] * 3; /* Rzeczywista szeroko
^wiersza */ /* Wyrwnanie do 4 bajtw
width (width + 3) & ~ 3 ;
*/
bitsize = width * viewport [ 3 ] ; /* Rozmiar wyrwnanej bitmapy */
for (i = 0; i < v i e w p o r t [ 3 ] ; i + + )
for (j = O, rgb = ((GLubyte * ) b i t s ) + i * width; j
< viewport[ 2 ] ; j + + , rgb += 3)
temp = rgb[0];
rgb[0] = rgb[ 2 ] ;
rgb[ 2 ] = temp;
Pierwsz rzecz, ktr powiniene zrobi, jest wyznaczenie rozmiarw biecego widoku,
jak pokazano poniej, za pomoc funkcji glGetlntegery. (Ta funkcja zostanie opisana w
rozdziale 14). Powoduje to umieszczenie pocztku X, pocztku Y, rozmiaru X oraz
rozmiaru Y w tablicy widoku, opisanej w tabeli 1 1.3.
/*
* Odczyt biecego widoku. . .
*/
glGet!ntegerv(GL_VIEWPORT, viewport) ;
Tabela 11.3.
Definicje tablicy widoku
Indeks Opis
O Pocztek widoku X (w pikselach)
1 Pocztek widoku Y (w pikselach)
2 Szeroko widoku (w pikselach)
3 Wysoko widoku (w pikselach)
Gdy masz ju rozmiar widoku, moesz zaalokowa pami dla pixmapy. Wane jest,
aby pamita, e bitmapy Windows (i domylnie pixmapy OpenGL) musz zaczyna kad
lini na granicy czterech bajtw. Aby to zapewni, wykonujemy ponisz sztuczk:
width = viewport[2] * 3; /* Rzeczywista szeroko wiersza */ width
= (width + 3 ) & ~ 3 ; /* Wyrwnanie do 4 bajtw */
Kopiowanie pixmap
OpenGL udostpnia take funkcj przeznaczon do kopiowania obszaru na ekranie w
inne miejsce - na przykad w celu przewinicia widoku lub zastosowania efektu szka
powikszajcego:
int mousex, mousey;
glReadBuffer(GL_FRONT) ;
glDrawBuffer(GL_FRONT);
glPixelZoom(2.0, 2 . 0 ) ;
glRasterPos2i( O , 0) ;
glCopyPixels(mousex - 8, mousey - 8, 1 6 , 1 6 , GL_COLOR) ;
fread(bits, l, bitsize, f p ) ;
fclose(fp);
void *
LoadDlBitmap(char *filename, /* We - Plik do wczytania */
BITMAPINFO **info) /* We - Informacje o bitmapie */ {
FILE *fp; /* Wskanik pliku */
void *bits; /* Bity bitmapy */ long
bitsize, /* Rozmiar bitmapy */
infosize; /* Rozmiar nagwka */
BITMAPFILEHEADER header; /* Nagwek pliku */
Rozdzia 11. Grafika rastrowa_________________________________369
/*
* Prba otwarcia pliku w trybie binarnym
*/
if ( ( f p = fopenffilename, " r b " ) ) -- NULL)
return (NULL);
/*
* Odczyt nagwka i informacji o bitmapie
*/
if (fread(Sheader, sizeof(BITMAPFILEHEADER), l, fp) < 1) { /*
* Nie powiodo si odczytanie nagwka
*/
fclose( f p ) ; return
(NULL); };
if ((bitsize = (*info)->bmiHeader.biSizelmage) == 0)
bitsize = ((*info)->bmiHeader.biwidth *
(*info)->bmiHeader.biBitCount + 7 ) / 8 *
abs((*info)->bmiHeader.biHeight);
if ((bits = malloc(bitsize)) == NULL) {
/*
* Brak pamici
*/
free(*info);
fclose(fp);
return (NULL);
int
SaveDIBitmap(char *filename, /* We - Plik do zapisu */
BITMAPINFO *info, /* We - Informacje o bitmapie */
void *bits) /* We - Bity bitmapy */
FILE *fp; /* Wskanik pliku */
long size, /* Rozmiar pliku */
infosize, /* Rozmiar nagwka bitmapy */
bitsize; /* Rozmiar danych bitmapy */
BITMAPFILEHEADER header; /* Nagwek pliku */
l
Rozdzia 11. Grafika rastrowa_________________________________371
/*
* Prba otwarcia pliku do zapisu w trybie binarnym V
if ( ( f p = fopen(filename, "wb")) NULL)
return ( - 1 ) ;
if (info->bmiHeader.bisizelmage == 0) /* Wyznaczenie rozmiaru
<=>bitmapy */
bitsize = (info->bmiHeader.biWidth *
info->bmiHeader.biBitCount + 7 ) / B * abs(info-
>bmiHeader.biHeight); else
bitsize = info->bmiHeader.bisizelmage;
infosize = sizeof(BITMAPINFOHEADER);
switch (info->bmiHeader.biCompression) {
case BI_BITFIELDS :
infosize += 12; /* Dodanie trzech masek RGB doubleword */ if
(info->bmiHeader.biClrUsed == 0) break; case BI_RGB :
if (info->bmiHeader.biBitCount > 8 &&
info->bmiHeader.biClrUsed == 0)
break;
case BI_RLE8 :
case BI_RLE4 :
if (info->bmiHeader.biClrUsed == 0)
infosize += (l info->bmiHeader.biBitCount) * 4;
else
infosize += info->bmiHeader.biClrUsed * 4;
break; };
size = sizeof(BITMAPFILEHEADER) + infosize + bitsize;
/*
* Zapis nagwka pliku, nagwka bitmapy i danych bitmapy
*/
header.bfType = ' M B ' ; /* Nie przenona... ech */
header.bfSize = size;
header.bfReservedl = 0;
header.bfReserved2 = 0;
header.bfOffBits = sizeof(BITMAPFILEHEADER) + infosize;
if (fwrite(Sheader, l, sizeof(BITMAPFILEHEADER), fp) <
sizeof(BITMAPFILEHEADER))
{
/*
* Nie powiodo si zapisanie nagwka pliku V
fclose( f p ) ;
return ( - 1 ) ;
372___________________________________Cz II Uywanie OpenGL
Drukowanie bitmap
Poniewa Windows dostarcza kilku wygodnych funkcji do drukowania, dostpnych z
wntrza aplikacji, nie pozostaje nam nic innego jak wydrukowa nasz obrazek wy-
wietlany w przegldarce. W tym przykadowym programie bdziemy korzysta ze stan-
dardowych usug druku GDI.
Pierwsz rzecz, jak musimy zrobi, jest wywietlenie standardowego okna dialogo-
wego Drukuj w Windows. Suy do tego poniszy fragment kodu:
memsetl&pd, O, sizeof(pd));
pd.lStructSize = sizeof(pd);
pd.hwndOwner = owner; pd.Flags
= PD_RETURNDC; pd.hlnstance =
NULL; if (IPrintDlg(Spd)) return
(0);
Jeli funkcja PrintDlg zwrci warto O, oznacza to, e uytkownik klikn na przycisk
Anuluj. W przeciwnym wypadku struktura PRINTDLG bdzie zawieraa uchwyt kontekstu
urzdzenia (HDC), ktrego bdziemy mogli uy do drukowania.
Teraz musimy rozpocz zadanie drukowania.
di.cbSize - sizeof(DOCINFO);
di.lpszDocName = "OpenGL Image";
di.lpszOutput = NULL;
StartDoc(pd.hDC,
Rozdzia 11. Grafika rastrowa_________________________________373
EndPage( p d . hDC);
EndDoc(pd.hDC);
/*
* Inicjowanie struktury PRINTDLG przed wywietleniem standardowego
* okna dialogowego Drukuj w Windows
*/
memsetl&pd, O, sizeof ( p d ) ) ;
pd.lStructSize sizeof ( p d ) ;
pd.hwndOwner = owner;
pd.Flags = PD_RETURNDC;
pd.hlnstance = NULL; if (
IPrintDlg(spd) )
return ( 0 ) ; /* Uytkownik wybra A n u l u j . . . */
/*
* OK, uytkownik chce drukowa, ustawmy wic kursor zajtoci
* i zacznijmy drukowanie
*/
busy = LoadCursor (NULL, IDC_WAIT) ;
oldcursor = SetCursor (busy) ;
xsize = rect.right;
ysize = xsize * inf o->bmiHeader .biHeight / info->bmiHeader .biwidth;
if (ysize > rect.bottom)
{
ysize = rect.bottom;
xsize = ysize * info->bmiHeader .biwidth / info-
>bmiHeader. biHeight;
x o f f s e t = ( r e c t. r i g h t - x s i z e ) / 2;
Rozdzia 11. Grafika rastrowa 375
/*
* To wszystko. Koniec drukowanie i zwolnienie zaalokowanych zasobw.
*/
EndPage(pd.hDC);
EndDoc(pd.hDC);
DeleteDC(pd.hDC);
DeleteObject(bitmap);
DeleteObject(brush);
DeleteObject(busy);
DeleteDC(hdc);
/*
* Odtworzenie kursora i powrt
*/
SetCursor(oldcursor);
return ( 1 ) ;
Wywietlanie bitmapy
Cz OpenGL naszego przykadowego programu rozpoczyna si od wywietlenia pliku
.BMP. Podobnie jak wikszo programw OpenGL, take ten zaczyna si od ustalenia
biecego widoku i przeksztace widoku.
glViewport ( O , O, rect->right, rect->bottom) ;
glMatrixMode (GL_PROJECTION) ;
glLoadldentity () ;
glOrtho(0.0, rect->right - 1 . 0 , 0 . 0 , rect->bottom - 1 . 0 , -1.0, 1 . 0 ) ;
glMatrixMode (GL_MODELVIEW) ;
ysize = rect->bottom;
xsize = BitmapInfo->bmiHeader .biWidth * ysize /
Bitmaplnf o->bmiHeader . biHeight;
}; (float)xsize / (float)Bitmaplnfo->bmiHeader.biWidth;
xscale
376____________________________________Cz II Uywanie OpenGL R
Pebiy kod funkcji RepaintWindow przedstawia listing 11.12. Listing 11.12. Funkcja
RepaintWindow_____________________________________
void
RepaintWindow(RECT *rect) /* We - Obszar roboczy okna */
{
GLint xoffset, /* Przesunicie obrazu w poziomie */
yoffset; /* Przesunicie obrazu w pionie */ GLint
xsize, /* Szeroko przeskalowanego obrazu */
ysize; /* Wysoko przeskalowanego obrazu */ GLfloat
xscale, /* Skalowanie w poziomie */ yscale; /*
Skalowanie w pionie */
/*
* Wyzerowanie widoku i wyczyszczenie okna biaym tem
*/
glViewport( O , O, rect->right, rect->bottom);
glMatrixMode(GL_PROJECTION);
glLoadldentity();
glOrtho(0.0, rect->right - 1 . 0 , 0 . 0 , rect->bottom - 1 . 0 , - 1 .0 , 1 . 0 ) ;
glMatrixMode(GL_MODELVIEW);
glClearColord.O, 1 . 0 , 1 . 0 , 1 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT);
/*
* Jeli zaadowalimy obraz bitmapy, przeskalowanie go do rozmiarw
* okna
*/
if (BitmapBits != NOLL) {
xsize = rect->right; ysize = BitmapInfo-
>bmiHeader.biHeight * xsize /
Bitmaplnfo->bmiHeader.biWidth; if
(ysize > rect->bottom) {
ysize = rect->bottom;
xsize = Bitmaplnfo->bmiHeader.biWidth * ysize /
Rozdzia 11. Grafika rastrowa_________________________________377
BitmapInfo->bmiHeader.biHeight;
};
xscale = (float)xsize / (float)BitmapInfo->bmiHeader.biwidth;
yscale - (float)ysize / (float)BitmapInfo->bmiHeader.biHeight;
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelZoom(xscale, yscale); glRasterPos2i(xoffset,
yoffset); glDrawPixels(BitmapInfo->bmiHeader.biwidth,
Bitmaplnfo->bmiHeader.biHeight, GL_RGB,
GL_UNSIGNED_BYTE, BitmapBits); };
glFinishO ;
Podsumowanie
W tym rozdziale poznae wikszo zagadnie dotyczcych funkcji OpenGL operujcych
na bitmapach. Poza prostymi zastosowaniami zwizanymi z wywietlaniem bitma-powych
znakw, bitmapy mog by wykorzystywane jako penokolorowe obrazy do tworzenia
ta okna lub tekstur (ktre zostan omwione w nastpnym rozdziale). Funkcje OpenGL,
takie jak glPixelMap, glPixelTransfer czy glPixelZoom pozwalaj take na uzyskanie
wielu specjalnych efektw.
Podrcznik
glCopyPixels
Przeznaczenie Kopiuje prostoktny blok pikseli w buforze ramki.
Plik nagwkowy <gl.h>
Skadnia void glCopyPixels(GLint x, GLint y, GLsizei width, GLsizei height,
GLenum type);
Opis Ta funkcja kopiuje dane pikseli ze wskazanego obszaru w buforze ramki
do obszaru wskazywanego przez biec pozycj rastra. Jeli bieca
pozycja rastra nie jest poprawna, adne dane nie s kopiowane.
Parametry x
width GLint: Wsprzdna pozioma lewego dolnego rogu kopiowanego
obszaru.
height
GLint: Wsprzdna pionowa lewego dolnego rogu kopiowanego
type
obszaru.
Zwracana warto GLsizei: Szeroko kopiowanego obszaru w pikselach.
Przykad Patrz GLsizei: Wysoko kopiowanego obszaru w pikselach.
take GLenum: Typ danych, ktre maj zosta skopiowane. Dostpne s
ponisze wartoci:
GL_COLOR Wartoci bufora kolorw
GL_STENCIL Wartoci bufora szablonu
GL_DEPTH Wartoci bufora gbokoci
Brak.
Przejrzyj kod programu OGLYIEW.C
glPixelMap, glPixelStore, glPixelTransfer, glPixelZoom
glDrawPixels
Przeznaczenie Rysuje prostoktny blok pikseli w buforze ramki.
Plik nagwkowy
Skadnia void glDrawPixels(GLsizei width, GLsizei height, GLenum formay,
GLenum type, const GLvoid *pixels);
Opis Ta funkcja kopiuje dane pikseli z pamici do obszaru wskazywanego przez
biec pozycj rastra w buforze ramki. Do ustawiania pozycji rastra suy
funkcja glRasterPos. Jeli bieca pozycja rastra nie jest poprawna, adne
dane nie s kopiowane.
Poza argumentami/O/Twa/ i type, na kodowanie pikseli i przetwarzanie ich
przed umieszczeniem w buforze ramki wpywa take kilka innych
parametrw. Zajrzyj do opisu funkcji glPixelMap, glPixelStore,
glPixelTransfer oraz glPixelZoom.
Parametry
width GLsizei: Szeroko obrazu w pikselach.
height GLsizei: Wysoko obrazu w pikselach.
Rozdzia 11. Grafika rastrowa 379
glPixelMap
Przeznaczenie Definiuje tablic przegldania dla funkcji operujcych na pikselach.
Plik nagwkowy <gl.h>
380 Cz II Uywanie OpenGL
glPixelStore
Przeznaczenie Okrela sposb zapisu i odczytu pikseli z pamici.
Plik nagwkowy <gl.h>
Rozdzia 11. * Grafika rastrowa 381
void gIPixeIStorei(GLenum pname, GLint param); void glPixelStoref(GLenum
Skadnia pname, GLfloat param);
Ta funkcja okrela sposb zapisu pikseli do pamici funkcj glReadPixels oraz sposb
Opis ich odczytu funkcjami glDrawPixels, glTex!magelD oraz glTex!mage2D. Nie wpywa
na dziaanie funkcji glCopyPixels.
GLenum: Parametr do ustawienia. Dostpne wartoci s nastpujce:
Parametry GL_PACK_SWAP_BYTES* GLJTRUE Jeli True, bajty
wszystkich wielobajtowych wartoci zostaj zamienione w pamici.
pname
GL PACK LSB FIRST GL FALSE Jeli True, lewe bity w
bitmapach znajduj si
w pikselu O, a nie 7.
Ustala szeroko
GL PACK RW LENGTH obrazu w pikselach.
O Jeli O, uywany jest
argument width.
Ustala ilo pikseli
obrazu do pominicia
GL PACK SKIP PDCELS O w poziomie.
Ustala ilo pikseli
obrazu do pominicia
GL PACK SKIP ROWS w pionie.
Ustala wyrwnanie dla
linii obrazu. Patrz
GL PACK ALIGNMENT 4 sekcja Znane bdy
poniej.
Jeli True, bajty
wszystkich
GL_UNPACK_SWAP_BYTES GLJTRUE wielobajtowych
wartoci s zamieniane
(GLJTRUE dla little-endian, miejscami podczas
GL_FALSE dla big-endian) odczytu.
Jeli True, lewy piksel
bitmap odczytywany
GL UNPACK LSB FIRST GL FALSE jest z bitu O, a nie 7.
382 Cz II Uywanie OpenGL
glPixelTransfer
Przeznaczenie Ustala opcje i tryb przenoszenia pikseli dla funkcji glCopyPixels,
glDrawPixels, glReadPixels, glTex!magelD oraz glTexImage2D.
Plik nagwkowy
Skadnia void glPixelTransferi(GLenum pname, GLint param); void
glPixelTransferf(GLenum pname, GLfloat param);
Opis Ta funkcja ustala opcje i tryb przenoszenia pikseli dla funkcji
glCopyPixels, glDrawPixels, glReadPixels, glTexImagelD oraz
glTex!mage2D.
Parametry
pname GLenum: Parametr do ustawienia. Dostpne s ponisze wartoci:
GL_MAP_COLOR Gdy ustawiony na GLJTRUE, wcza pixmapy
zdefiniowane funkcj glPixelMap dla indeksw kolorw i wartoci
RGBA.
GL_MAP_STENCIL Gdy ustawiony na GLJTRUE, wcza pixmapy
zdefiniowane funkcj glPixelMap dla wartoci szablonu.
nGL Rozdzia 11. * Grafika rastrowa 383
glPixelZoom
Przeznaczenie Okrela skal przy rysowaniu obrazka.
Plik nagwkowy
Skadnia Opis void glPixelZoom(GLfloat xfactor, GLfloat yfactor);
Ta funkcja ustala wspczynniki skalowania dla funkcji glCopyPixels,
glDrawPixels, glReadPixels, glTex!magelD oraz glTex!mage2D.
W przypadku odczytu obrazu z pamici lub bufora ramki, piksele s
skalowane przy uyciu algorytmu najbliszy ssiad". W przypadku funkcji
glCopyPixels i glDrawPixels, przeskalowane piksele s rysowane
384 Cz II Uywanie OpenGL
Parametry
xfactor GLfloat: Wspczynnik skalowania w poziomie (1,0 oznacza brak
skalowania).
yfactor GLfloat: Wspczynnik skalowania w pionie (1,0 oznacza brak
skalowania).
Zwracana warto Brak.
Przykad Patrz Przejrzyj kod programu OGLYIEW.C
take glCopyPixels, glDrawPixels, glReadPixels, glTex!magelD,
glTex!mage2D
glReadPixels
Przeznaczenie Odczytuje blok pikseli z bufora ramki.
Plik nagwkowy
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum
format, GLenum type, const GLvoid *pixels);
Skadnia
Ta funkcja kopiuje dane pikseli z bufora ramki do pamici. Poza argumentami
format i type, na kodowanie pikseli i przetwarzanie ich przed umieszczeniem w
Opis pamici wpywa take kilka innych parametrw. Zajrzy] do opisu funkcji
glPixelMap, glPixelStore oraz glPixelTransfer.
Parametry GLint: Pozioma wsprzdna lewego dolnego rogu obszaru obrazu. GLint:
x Pionowa wsprzdna lewego dolnego rogu obszaru obrazu. GLsizei: Szeroko
y obrazu w pikselach. GLsizei: Wysoko obrazu w pikselach.
GLenum: Przestrze kolorw odczytywanych pikseli. Dostpne s ponisze
width
wartoci:
height
GL_COLOR_INDEX Piksele indeksu koloru GL
format LUMINANCE Piksele skali szaroci
Rozdzia 11. Grafika rastrowa 385
Rysunek 12.1.
Tcza stworzona za pomoc
jednowym iarowej tekstury
Tekstura 2D
(dwuwymiarowa)
to obrazek szerszy i
wyszy ni jeden
piksel; zwykle jest
adowana z pliku
.BMP Windows.
Tekstury 2D s
powszechnie
uywane w celu
zastpienia powierzchni o skomplikowanej geometrii (mnstwie wieloktw),
budynkw, drzew itd. Tekstury 2D s uywane take w celu stworzenia realistycznego ta,
na przykad chmur na niebie, pokazanych na rysunku 12.2.
Uyte przez nas jedno- i dwuwymiarowe tekstury skaday si z wartoci koloru RGB.
Tekstury mog by tworzone take z indeksw kolorw lub poziomw szaroci (lumi-
nancji), mog take zawiera wartoci alfa (przezroczystoci). Te ostatnie s uyteczne
przy definiowaniu naturalnych obiektw, takich jak drzewa, gdy warto alfa moe
by uyta do uczynienia drzewa widocznym, a jednoczenie umoliwi przewitywanie ta.
Nauczymy si tego w rozdziale 16.
Niektre karty obsuguj w OpenGL take tekstury trjwymiarowe (wolumetryczne).
Tekstury wolumetryczne s uywane w rnych aplikacjach skanerw" trzeciego wy-
miaru. Niestety, maa tekstura 256 x 256 x 256 pikseli w skali szaroci zajmuje cae 16
MB pamici.
Rozdzia 12. * Mapowanie tekstur 389
Rysunek 12.2.
Dwuwymiarowa
tekstura imitujca
niebo
Definiowanie tekstur ID
W OpenGL do definiowania jednowymiarowych tekstur suy pojedyncza funkcja:
glTex!magelD. Funkcja wymaga przekazania omiu argumentw:
void glTexImagelD(GLenum target, GLint level, GLint components,
GLsizei width, GLint border, GLenum format,
GLenum type, const GLvoid *pixels)
Argument target okrela, ktra tekstura powinna zosta zdefiniowana; musi nim by
GL_TEXTURE_1D. Argument level wskazuje poziom szczegw obrazu tekstury i
zwykle wynosi 0. Inne wartoci s uywane przy tekturach typu mipmap (opisywanych
w dalszej czci rozdziau). Argument components okrela ilo wartoci koloru uytych
dla kadego piksela. W przypadku tekstur z indeksami kolorw, t wartoci musi by l.
Wartoci 3 i 4 s uywane, odpowiednio, dla obrazw tekstur RGB i RGB A.
390 Cz II Uywanie OpenGL
Argumenty width i border okrelaj rozmiar obrazu tekstury. Warto border okrela
ilo pikseli ramki, ktrych OpenGL moe oczekiwa (i uywa) i moe mie warto O, l
lub 2. Parametr width okrela szeroko gwnego obrazu tekstury (bez pikseli ramki) i musi
stanowi potg liczby 2.
void
LoadAllTextures( v o i d )
{
static unsigned char roygbiv_image[ 8 ] [ 3 ] =
{ Ox3f, 0x00, Ox3f t, Ciemny fiolet (dla 8 k o l o r w . . . ) */
{ Ox7f, 0x00, Ox7f ;, Fiolet */
{ Oxbf, 0x00, Oxbf }, Indy go */
{ 0x00, 0x00, Oxff }, Bkit */
{ 0x00, Oxff, 0x00 }, Ziele */
{ Oxff, Oxff, 0x00 },
{ Oxff, Ox7f, 0x00 }, */
{ Oxff, 0x00, 0x00 } * P
/ o
m
aracz
Czerwie
Ten przykadowy kod tworzy list wywietlania zawierajc obraz tekstury oraz dany
filtr powikszania i pomniejszania, GL_LINEAR. Filtr pomniejszania jest uywany,
gdy rysowany wielokt jest mniejszy ni obraz tekstury, w tym przypadku 8 pikseli.
Filtr powikszania jest uywany, gdy wielokt jest wikszy ni obraz tekstury. Stosujc
filtr GL_LINEAR, informujemy OpenGL, e przed narysowaniem czegokolwiek na
ekranie, wartoci kolorw obrazu tekstury powinny zosta liniowo zinterpolowane. Inne
filtry, ktrych moesz uy jako parametru GL_TEXTURE_MIN_FILTER, zostay zebrane
w tabeli 12.1.
Tabela 12.1.
Filtry obrazu tekstury
Filtr______________________Opis___________________________
GL_NEAREST Filtrowanie najbliszy ssiad"
GLJJNEAR Liniowa interpolacja
GL_NEAREST_MIPMAP_NEAREST Filtr mipmapy najbliszy ssiad"
GL_NEAREST_MIPMAP_LINEAR Liniowo interpolowana mipmapa
GL_LINEAR_MIPMAP_NEAREST Liniowa interpolacja mipmap
GL_LINEAR_MIPMAP_LINEAR Liniowa interpolacja interpolowanych mipmap
Definiowanie tekstur 2D
W celu zdefiniowania dwuwymiarowej tekstury naley wywoa funkcj glTex!mage2D. Ta
funkcja, oprcz argumentw przekazywanych funkcji glTex!magelD, wymaga dodatkowo
podania argumentu height (wysoko):
void glTex!mage2D(GLenum target, GLint level, GLint components,
GLsizei width, GLsizei height, GLint border,
GLenum format, GLenum type, const GLvoid *pixels)
Listing 12.2 zawiera przykad adowania obrazu tekstury zachmurzonego nieba Listing
void
LoadAllTextures(void)
{
BITMAPINFO *info; /* Nagwek bitmapy */
void *bits; /* Dane bitmapy */
GLubyte *rgb; /* Piksele RGB bitmapy */
/*
* Prba zaadowania bitmapy i zamiany jej na R G B . . .
*/
/*
* Definiowanie obrazu tekstury 2D
*/
/* Wymuszenie wyrwnania do 4 bajtw */
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0) ;
glTex!mage2D(GL_TEXTURE_2D, O, 3, info->bmiHeader.biwidth,
info->bmiHeader.biHeight, O, GL_RGB, GL_UNSIGNED_BYTE, rgb);
glEndList() ;
Rysowanie wieloktw z
naoon tekstur
Gdy ju zdefiniujesz tekstur, musisz jeszcze wczy teksturowanie. Aby wczy te-
ksturowanie ID, uyj poniszego kodu:
glDisable(GL_TEXTURE_2D);
glEnable(GL_TEXTURE_1D);
glTexEnvi(GL_TEXTURE_ENW, GL_TEXTORE_ENW_MODE, GL_DECAL);
Rozdzia 12. Mapowanie tekstur_________________________________393
Tabela 12.2.
Tryby teksturowania dla parametru GL_TEXTURE_ENV_MODE
Tryb Opis
GL_MODULATE Piksele tekstury filtruj" kolory istniejcych pikseli na ekranie.
GL_DECAL Piksele tekstury zastpuj istniejce piksele na ekranie.
GL_BLEND Piksele tekstury filtruj" kolory istniejcych pikseli na ekranie, bdc
przy tym
czone ze staym kolorem.
glEnable(GL_TEXTURE_1D);
glCallList(RainbowTexture);
glBegin(GL_QUAD_STRIP);
for (th = 0 . 0 ; th <= M_PI; th += (0.03125 * M_PI
{
// Dolna krawd tczy
x = cos( t h ) * 5 0 . 0 ; y
= si n ( th ) * 5 0 . 0 ; z =
-50.0;
glTexCoordlf( 0 . 0 ) ;
glVertx3f( x , y, z);
x = cos( t h ) * 5 5 . 0 ;
y = sin(th) * 5 5 . 0 ;
z = -50.0;
394 Cz II * Uywanie OpenGL
glTexCoordlf ( 1 . 0 ) ;
glVertex3f ( x , y, z ) ;
glEnd ( ) ;
Mipmapy
Dotychczas posugiwalimy si jedynie obrazami z pojedynczymi teksturami. To znaczy,
przy kadym rysowaniu wielokta posugiwalimy si pojedynczym jedno- lub
dwuwymiarowym obrazem. W przypadku wikszoci scen to w zupenoci wystarcza,
jednak w scenach animowanych czsto potrzebny jest zmienny poziom szczegw,
Rozdzia 12. Mapowanie tekstur 395
OpenGL obsuguje tekstury zawierajce wiele obrazw, zwanych mipmapami. Przy sto-
sowaniu mipmapowania wybierany jest obraz tekstury najbliszy rozmiarowi wielokta na
ekranie. adowanie mipmap trwa nieco duej ni zwykych tekstur, ale efekty wizualne
robi wraenie. Dodatkowo, mipmapy mog poprawi wydajno renderowania, gdy
zmniejszaj konieczno stosowania filtru GL_LINEAR.
Poziom obrazu jest okrelany jako drugi parametr funkcji glTexImagelD(). Obraz o po-
ziomie O to obraz podstawowy tekstury, o najwyszej rozdzielczoci. Obraz o poziomie l
ma poow rozmiaru obrazu podstawowego, itd. Rysujc wielokty za pomoc
bitmap, powiniene uy jednego z filtrw zmniejszania (GL_TEXTURE_MIN_FIL-
TER) z tabeli 12.3.
396_______________________________________Cz II Uywanie OpenGL
Tabela 12.3.
Filtry zmniejszania
Filtr___________________Opis______________________________
GL_NEAREST_MIPMAP_NEAREST Uywa obrazu najbliszego pod wzgldem rozmiaru
do
wielokta na ekranie. Przy teksturowaniu tego obrazu
stosuje filtr GL_NEAREST.
GL_NEAREST_MIPMAP_L1NEAR Uywa obrazu najbliszego pod wzgldem
rozmiaru do
wielokta na ekranie. Przy teksturowaniu tego obrazu
stosuje filtr GL_LINEAR.
GL_LINEAR_MIPMAP_NEAREST Liniowo interpoluje pomidzy dwoma obrazami
najbliszymi
pod wzgldem rozmiaru do wielokta na
ekranie. Przy teksturowaniu tego obrazu stosuje
filtr GL_NEAREST.
GL_LINEAR_MIPMAP_LINEAR Liniowo interpoluje pomidzy dwoma obrazami
najbliszymi
pod wzgldem rozmiaru do wielokta na
ekranie. Przy teksturowaniu tego obrazu stosuje
filtr GL_LINEAR.
Aby uatwi ci nieco ycie, biblioteka narzdziowa OpenGL (GLU32.LIB) zawiera dwie
funkcje automatycznie generujce mipmapy na podstawie pojedynczej tekstury o wysokiej
rozdzielczoci. W poniszym kodzie, funkcje gluBuildlDMipmaps oraz gluBuild2-
DMipmaps zajmuj miejsce funkcji glTex!magelD i glTex!mage2D:
// Tekstura ID
// Tekstura 2D
Kod caego programu zosta przedstawiony na kocu rozdziau, tu przed sekcj po-
drcznika. Kopia programu znajduje si na pytce CD-ROM, w folderze tego rozdziau.
Dwukrotnie kliknij na ikon programu TEXSCENE.EXE i sam sprawd, jak dziaa!
Definiowanie terenu
W celu zachowania prostoty, nasz teren zdefiniujemy jako siatk punktw wysoko-
ciowych z dodatkow informacj o teksturze, tak jak to jest woda" czy to jest gra".
Kady punkt siatki bdzie take posiada odpowiedni normaln, w celu zachowania
realistycznego owietlenia.
#define TERRAIN_SIZE 21
int TerrainType[TERRAIN_SIZE][TERRAIN_SIZE];
GLfloat TerrainHeight[TERRAIN_SIZE][TERRAIN_SIZE];
GLfloat TerrainNormal[TERRAIN_SIZE][TERRAIN_SIZE][ 3 ] ;
Tablica TerrainType zawiera rodzaj terenu w kadym punkcie, czyli jeden z poniszych
identyfikatorw kontrolek z pliku definicji zasobw:
IDC_GRASS Trawa
IDC_WATER Woda
IDCJTREES Drzewa
IDC_ROCKS Skay
IDC_MOUNTAINS Gry
Rysowanie terenu
Na kontrolki rysowania terenu skada si okno dialogowe z paskiem narzdzi, zawiera-
jcym pi przyciskw sucych do wybierania rodzaju terenu. Aby narysowa teren, po
prostu kliknij i przecignij przycisk do gwnego okna (rysunek 12.4).
398 Cz II * Uywanie OpenGL
Rysunek 12.4.
Okno edycji terenu
Rysunek 12.5. J.
Wybr komrki
terenu
Gdy znamy pooenie (x, y) terenu, w funkcji draw_cell ustalamy wysoko i typ jego
punktw (listing 12.4).
void
draw_cell (int x, /* We - Pooenie terenu X */
int y) /* We - Pooenie terenu Y */ { /*
* Sprawdzenie zakresu terenu
*/
if (x < O X >= TERRAIN_SIZE |
y < O y >= TERRAIN_SIZE)
return;
Rozdzia 12. * Mapowanie tekstur 399
if (TerrainType[ y ] [ x ] == TerrainCurrent)
return; /* Ju jest poprawnego typu */
TerrainType[ y ] [ x ] = TerrainCurrent;
Wymuszenie odwieenia o k n a . . .
switch (TerrainCurrent) {
case IDC_WATER :
TerrainHeight [ y ] [ x ] = WATER_HEIGHT;
break; case
IDC_GRASS :
TerrainHeight [ y ] [ x ] = GRASS_HEIGHT + O.lf * ( r a n d ( ) % 5 ) ;
break; case
IDC_TREES :
TerrainHeight [y] [ x ] = TREES_HEIGHT + 0.1 * (randf) % 5) ;
break; case
IDC_ROCKS :
TerrainHeight [ y ] [ x ] = ROCKS_HEIGHT + O . l f * ( r a n d ( ) % 5 ) ;
break; case
IDC_MOUNTAINS :
TerrainHeight [ y ] [ x ] = MOUNTAINS_HEIGHT + 0 . 1 5 f * ( r a n d ( ) % 5) ;
break;
Wysoko punktw terenu typu IDC_WATER (wody jest ustawiana po prostu na WA-
TER_HEIGHT (wysoko wody, 0,0). Dla innych typw terenu dodajemy przypadkow
warto odchylenia, dziki czemu teren wyglda bardziej realistycznie. Gdy wybrana
komrka zostanie narysowana, na podstawie nowych wysokoci, za pomoc funkcji
UpdateNormals przeliczamy normalne. Kada normalna jest obliczana przy uyciu punktw
powyej i na prawo od biecego punktu, wedug poniszego wzoru:
N = normalna
H = wysoko biecego punktu
Hu = wysoko punktu powyej Hr
= wysoko punktu na prawo
Nx = ( H r - H) / | N |
Ny = l / |N|
Nz = ( H u - H) / | N |
Rysowanie sceny
Gdy zajlimy si ju obowizkow prac, moemy skoncentrowa si na wywietlaniu
terenu. Pamitajmy, e oprcz wywietlania adnego teksturowanego obrazka, chcemy
take polata nad terenem. Aby to osign, musimy rysowa teren bez teksturowania -
gwnie dlatego, e teksturowanie na zwykym komputerze PC przebiega zbyt wolno jak
na potrzeby animacji. Gdy uytkownik nie lata (i nie rysuje terenu), zastosujemy
teksturowanie. Zadbamy o to za pomoc paru linii warunkowych i kilku parametrw
owietlenia.
Ponadto, poniewa rysowanie teksturowanej sceny przebiega wolniej ni podczas przelotu
nad scen, sprbujemy w jaki sposb wskaza uytkownikowi, e program cokolwiek robi.
Dla uproszczenia, podczas teksturowania bdziemy rysowa po prostu w przednim buforze
(widocznym), za podczas lotu lub rysowania - w tylnym (niewidocznym). W ten sposb,
gdy program bdzie aktualizowa teksturowan scen, uytkownik bdzie widzia postpy
w rysowaniu. Wicej informacji na temat buforw znajdziesz w rozdziale 15.
Funkcja RepaintWindow obsuguje odrysowywanie terenu. Rozpoczyna od wybrania
przedniego lub tylnego bufora (jak wspominalimy powyej). Nastpnie czyci bity koloru
i gbokoci:
glViewport( O , O, rect->right, rect->bottom);
glClearColor( 0 . 5 , 0 . 5 , 1 . 0 , 1 . 0 ) ;
glEnable(GL_DEPTH_TEST);
if (Moving || Drawing) {
glDisable(GL_TEXTURE_2D);
glDrawBuffer(GL_BACK) ;
}
else
{
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glDrawBuffer(GL_FRONT); };
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
Nastpnie jest rysowane niebo. Ze wzgldu na wydajno, niebo jest rysowane tylko
wtedy, gdy uytkownik nie lata i nie rysuje terenu. Poniewa to jest czyszczone ko-
lorem jasnoniebieskim, nie ma z tym wikszego problemu. Niebo ma ksztat piramidy z
naoon tekstur SKY.BMP. przedstawiajc przyjemne, lekko zachmurzone niebo.
Po narysowaniu nieba, funkcja RepaintWindow zaczyna rysowa teren. Uyty algorytm jest
bardzo prosty i polega na generowaniu paskw czworoktw (kwadratw) wzdu
punktw terenu. Kady pasek uywa innej tekstury lub materiau, wic dla kadego z
nich musimy uy pary funkcji glBegin/glEnd. Graficzny opis tego algorytmu przedstawia
rysunek 12.6.
Rozdzia 12. Mapowanie tekstur_________________________________401
Rysunek 12.6.
Algorytm rysowania terenu
dla kadego punktu terenu. Jednak zamiast robi to dla kadego punktu, moemy uy
funkcji glTexGen w celu zdefiniowania wsprzdnych S i T oznaczajcych pooenie X
i Z w scenie (Y jest uywane do okrelania wysokoci). W celu wygenerowania wsp-
rzdnych dla naszego terenu, moemy zastosowa poniszy kod:
static GLint s_vector[4] = { 2, O, O, O }
static GLint t_vector[4] = { O, O, 2, O }
Podsumowanie
W tym rozdziale nauczye si nakada obrazy tekstur na wielokty i inne prymitywy.
Teksturowanie moe w znacznym stopniu podnie realizm tworzonych scen, a wanie to
sprawia, e praca z grafik komputerow jest taka pasjonujca.
Dziki uyciu funkcji glTexParameter moemy w znacznym stopniu wpyn na jako
obrazw tekstur nakadanych na wielokty. Dziki uyciu mipmap moemy zastosowa
wiele poziomw szczegw tekstury, z zachowaniem duej precyzji i szybkoci rende-
rowania. Liniowa interpolacja tekstur moe poprawi pewne rodzaje obrazw, na przykad
takich jak obraz nieba uywany w przykadach w tym rozdziale.
Funkcja glTextGen znacznie uatwia generowanie wsprzdnych tekstur, gdy oszczdza
nam mudnych lub niepotrzebnych oblicze. Poprzez zastpienie duej iloci wa-
runkowych wywoa funkcji glTexCoord, automatyczne generowanie wsprzdnych
upraszcza take programy, ktre musz wywietla zarwno teksturowane, jak i niete-
ksturowane wielokty.
Rozdzia 12. Mapowanie tekstur 403
#ifndef M_PI
define M_PI (double)3.14159265358979323846
ttendif /* !M PI */
Stae. . .
*/
define TERRAIN_SIZE 21
tdefine TERRAIN_EDGE ((TERRAIN_SIZE - 1) / 2)
#define TERRAIN_SCALE (500.0 / TERRAIN_EDGE)
define GRASS_HEIGHT 0.
ttdefine WATER_HEIGHT 0
tdefine TREES_HEIGHT 0.
ttdefine ROCKS_HEIGHT 0
tfdefine MOUNTAINS HEIGHT 0.
0
0.
5
1.
0
Zmienne globalne...
*/ SceneWindow;
ScenePalette;
HWND SceneDC; SceneRC; Okno sceny */
HPALETTE SkyTexture, Paleta kolorw (jeli potrzebna) */
HDC GrassTexture, Kontekst rysowania */
HGLRC RocksTexture, Kontekst renderowania OpenGL */
WaterTexture,
GLuint TreesTexture, /* Obraz tekstury nieba
MountainsTexture; /* Trawa. . */
/* Skaa. . */
/* Woda. . */
/* Drzewa. . . */
/* Gry. . */
HBITMAP GrassDownBitmap, /* Obraz wcinitego przycisku trawy */
GrassUpBitmap, /* Obraz zwolnionego przycisku trawy */
GrassSelectBitmap, /* Obraz zaznaczonego przycisku trawy */
RocksDownBitmap, /* ... V
RocksUpBitmap,
RocksSelectBitmap,
WaterDownBitmap,
404 Cz II Uywanie OpenGL
WaterUpBitmap,
WaterSelectBitmap,
TreesDownBitmap,
TreesOpBitmap,
TreesSelectBitmap,
MountainsDownBitmap,
MountainsUpBitmap,
MountainsSelectBitmap;
HWND TerrainWindow; /* Dialog terenu */ int
TerrainCurrent = IDC_WATER; int
TerrainType[TERRAIN_SIZE][TERRAIN_SIZE]; GLfloat
TerrainHeight[TERRAIN_SIZE][TERRAIN_SIZE]; GLfloat
TerrainNormal[TERRAIN SIZE][TERRAIN SIZE][ 3 ]
CenterMouseKY; /*
Funkcje l o k a l n e . . .
*/ DisplayErrorMessage(char *, .. . ) ;
MakePalette(int);
void SceneProc(HWND, UINT, WPARAM, LPARAM);
void TerrainDlgProclHWND, UINT, WPARAM, LPARAM),
LRESULT CALLBACK InitializeTerrain(void);
UINT CALLBACK LoadAllTextures(void);
void LoadAllBitmaps(HINSTANCE);
void DrawTerrain(int, i n t ) ;
void FlyTerrain(int, i n t ) ;
void RepaintWindow(RECT * ) ;
void SaveBitmapFile(void);
void PrintBitmap(void);
void GetClock(void);
void
double
/*
* 'WinMainO '
*/
int APIENTRY
WinMain (HINSTANCE hlnst,
HINSTANCE hPrev!nstance,
LPSTR IpCmdLine, int
nCmdShow)
MSG msg;
WNDCLASS we;
POINT pos;
Rozdzia 12. Mapowanie tekstur_________________________________405
/*
* Inicjowanie terenu dla trawy V
InitializeTerrain();
we.style = 0;
wc.lpfnWndProc = (WNDPROC)SceneProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hlnstance = hlnst;
wc.hlcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
we.IpszClassName = "Textured S c e n " ;
if (RegisterClass( s w e ) == 0)
{
DisplayErrorMessage( " N i e mog zarejestrowa klasy o k n a ! " ) ;
return (FALSE);
};
Scenewindow = Createwindow("Textured S c e n " , "Teksturowany t e r e n " ,
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
OWS_CLIPSIBLINGS,
32, 32, 400, 300,
NULL, NULL, hlnst, NULL);
if (Scenewindow == NULL)
{
DisplayErrorMessage( " N i e udao si utworzy o k n a ! " ) ;
return (FALSE);
};
ShowWindow(Scenewindow, nCmdShow);
UpdateWindow(Scenewindow);
/*
* adowanie bitmap przyciskw, utworzenie okna dialogowego
* edycji terenu
*/
LoadAllBitmaps(hlnst);
TerrainWindow = CreateDialog(hlnst,
<=>MAKEINTRESOURCE (IDD_TERRAIN_DIALOG) ,
Scenewindow, (DLGPROC)TerrainDlgProc);
{
TranslateMessage(&msg);
DispatchMessage(&msg);
else
return ( 1 ) ;
GetCursorPos(ipos);
FlyTerrain(pos. x , p o s . y ) ;
};
return (msg.wParam);
}
/*
* 'DisplayErrorMessage()' - Wywietla okno komunikatu bdu.
void
DisplayErrorMessage(char *format,// acuch formatowania w stylu
=>printf ()
...) // Pozostae argumenty
if (format == NOLL)
return;
va_start(ap, format);
vsprintf(s, format, ap) ;
va_end(ap) ;
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, s, "Bd", MB_OK | MB_ICONEXCLAMATION); }
/*
* 'MakePalette()' - Jeli trzeba, tworzy palet kolorw.
*/
void
MakePalette(int p f ) /* We - ID formatu pikseli */
PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE *pPal;
int nColors;
int i,
rmax,
gmax,
bmax;
Rozdzia 12. * Mapowanie tekstur _________________________________ 407
/*
* Sprawdzenie, czy paleta jest potrzebna...
*/
DescribePixelFormat (SceneDC, pf, sizeof (PIXELFORMATDESCRIPTOR) ,
/*
* Alokowanie pamici dla palety.
*/
nColors = l pfd.cColorBits;
pPal = (LOGPALETTE *) malloc (sizeof (LOGPALETTE) +
nColors * sizeof (PALETTEENTRY) );
pPal->palVersion = 0x300;
pPal->palNumEntries = nColors;
/*
* Odczyt maksymalnych wartoci barw skadowych i budowanie nColors
^kolorw
*/
rmax = (l pfd. cRedBits) - 1;
gmax = (l pfd.cGreenBits) - 1;
bmax = (l pfd.cBlueBits) - 1;
for (i = 0; i < nColors; i ++)
{
pPal->palPalEntry[i] .peRed = 255 * ( (i pfd.cRedShift) & rmax) /
rmax;
pPal->palPalEntry[i] .peGreen = 255 * ( ( i pfd.cGreenShift) &
t
*gmax) /
gmax;
pPal->palPalEntry[i] .peBlue = 255 * ( (i pfd.cBlueShift) & ^bmaK)
/
bmax ;
pPal->palPalEntry [ i ] .peFlags = 0;
/*
* Uworzenie, wybranie i realizacja palety
*/
ScenePalette = CreatePalette (pPal) ;
SelectPalette (SceneDC, ScenePalette, FALSE) ;
RealizePalette (SceneDC) ;
free(pPal) ;
408____________________________________Cz II Uywanie OpenGL
/*
* 'SceneProc()' - Obsuga komunikatw okna sceny.
*/
LRESULT CALLBACK
SceneProc(HWND hWnd, OINT
uMsg, WPARAM wParam, LPARAM
IParam) (
int pf; /* ID formatu pikseli */
PIKELFORMATDESCRIPTOR pfd; /* informacje o formacie pikseli */
PAINTSTRUCT ps;
RECT rect;
switch (uMsg)
{
case WM_CREATE :
// Pobranie kontekstu urzdzenia i renderowania, //
przygotowanie obszaru klienta dla OpenGL
SceneDC = GetDC(hWnd);
pfd.nSize = sizeof(pfd);
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER;
// Dla OpenGL
pfd.dwLayerMask = PFD_MAIN_PLANE;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 0; pfd.cDepthBits
= 32; pfd.cStencilBits = 0;
pfd.cAccumBits = 0;
pf = ChoosePixelFormat(SceneDC, Spfd); if
( p f == 0)
DisplayErrorMessage("Program nie mg znale
^odpowiedniego formatu p i k s e l i ! " ) ;
else if (!SetPixelFormat(SceneDC, pf, pfd))
DisplayErrorMessage("Program nie mg ustawi
^odpowiedniego formatu p i k s e l i ! " ) ;
MakePalette(pf);
SceneRC = wglCreateContext(SceneDC);
wglMakeCurrent(SceneDC, SceneRC);
// adowanie obrazw tekstur do list wywietlania...
LoadAllTextures();
break;
Rozdzia 12. * Mapowanie tekstur_________________________________409
case WM_SIZE :
case WM_PAINT :
// Odrysowanie obszaru klienta...
BeginPaint (hWnd, sps);
GetClientRect(hWnd, Srect);
RepaintWindow(srect);
EndPaint(hWnd, & p s ) ;
break;
case WM_COMMAND : /*
* Obsuga menu...
*/
switch (LOWORD(wParam)) {
case IDM_FILE_SAVEAS :
SaveBitmapFile();
break; case
IDM_FILE_PRINT :
PrintBitmapt);
break; case
IDM_FILE_EXIT :
DestroyWindow(SceneWindow);
break;
case IDM_WINDOW_TERRAIN : /*
* Wczenie lub wyczenie okna t e r e n u . . .
*/
if (GetMenuState(GetMenu(SceneWindow), IDM_WINDOW_TERRAIN,
MF_BYCOMMAND) S MF_CHECKED)
{
CheckMenuItem(GetMenu(SceneWindow),
OIDM_WINDOW_TERRAIN,
MF_BYCOMMAND | MF_UNCHECKED);
ShowWindow(TerrainWindow, SW_HIDE); } else {
CheckMenuItem(GetMenu(SceneWindo
w), OIDM_WINDOW_TERRAIN,
MF_BYCOMMAND | MF_CHECKED);
ShowWindow(TerrainWindow, SW_SHOW); };
break;
}; break;
case WM_QUIT :
case WM_CLOSE :
/*
* Zniszczenie okna, bitmap i wyjcie...
*/
DestroyWindow(SceneWindow);
DestroyWindow(TerrainWindow);
410____________________________________Cz II Uywanie OpenGL
DeleteObject(GrassDownBitmap);
DeleteObject(GrassSelectBitmap);
DeleteObject(GrassUpBitmap);
DeleteObject(WaterDownBitmap);
DeleteObject(WaterSelectBitmap);
DeleteObject(WaterUpBitmap);
DeleteObject(RocksDownBitmap);
DeleteObject(RocksSelectBitmap);
DeleteObject(RocksUpBitmap);
DeleteObject(TreesDownBitmap);
DeleteObject(TreesSelectBitmap);
DeleteObject(TreesDpBitmap);
DeleteObject(MountainsDownBitmap);
DeleteObject(MountainsSelectBitmap);
DeleteObject(MountainsUpBitmap);
exit( 0 ) ;
break;
case WM_DESTROY : /*
* Zwolnienie kontekstu urzdzenia, kontekstu
* renderowania i palety
*/
if (SceneRC)
wglDeleteContext(SceneRC);
if (SceneDC)
ReleaseDC(SceneWindow, SceneDC);
if (ScenePalette)
DeleteObject(ScenePalette);
PostQuitMessage(0);
break;
case WM_QUERYNEWPALETTE :
/*
* W razie potrzeby realizacja palety...
*/
if (ScenePalette) {
SelectPalette(SceneDC, ScenePalette, FALSE);
RealizePalette(SceneDC);
InvalidateRect(hWnd, NULL, F A L S E ) ;
return (TRUE);
); break;
case WM_PALETTECHANGED: /*
* W razie potrzeby ponowne wybranie palety...
*/
Rozdzia 12. * Mapowanie tekstur_________________________________411
case WM_MOUSEMOVE :
/*
* Poruszy si wskanik myszy. Jeli rysujemy teren,
* zrbmy to.
* Jeli nie, ignorujemy to, bo lecimy w gwnej ptli
*/
if (Drawing)
DrawTerrain(LOWORD(IParam), HIWORD(IParam));
break;
case WM_LBUTTONUP :
/*
* Uytkownik zwolni lewy przycisk myszy. Przestajemy
* rysowa lub lecie.
*/
Moving = GL_FALSE;
Drawing = GL_FALSE;
ReleaseCapture();
default : /*
* Standardowa obsuga wszystkich innych komunikatw
* procedury...
*/
return (DefWindowProc(hWnd, uMsg, wParam, IParam)); };
return ( F A L S E ) ;
UINT CALLBACK
TerrainDlgProc(HWND hWnd,
UINT uMsg, WPARAM wParam,
LPARAM IParam) {
HDC hdc; /* Kontekst rysowania dla przyciskw */
LPDRAWITEMSTRUCT Ipdis; /* Informacja o stanie przyciskw */
UINT idCtl; /* Identyfikator przycisku */
switch ( u M s g )
{
case WM_DRAWITEM :
/*
* Windows chce narysowa przycisk. Sprawd, ktry i narysuj go
*/
idCtl - (UINT)wParam;
Ipdis - (LPDRAWITEMSTROCT)IParam;
hdc = CreateCompatibleDC(lpdis->hDC) ;
switch (idCtl)
{
case IDC_WATER :
if (lpdis->itemState S ODS_SELECTED)
SelectObject(hdc, WaterDownBitmap); else
if (TerrainCurrent == IDC_WATER)
SelectObject(hdc, WaterSelectBitmap);
else
SelectObject(hdc, WaterUpBitmap); break;
case IDC_GRASS :
if (lpdis->itemState & ODS_SELECTED)
SelectObject(hdc, GrassDownBitmap);
else if (TerrainCurrent == IDC_GRASS)
SelectObject(hdc, GrassSelectBitmap);
else
SelectObject(hdc, GrassUpBitmap);
break;
Rozdzia 12. Mapowanie tekstur_________________________________413
case IDCJTREES :
if (lpdis->itemState S, ODS_SELECTED)
SelectObject(hdc, TreesDownBitmap);
else if (TerrainCurrent == IDC_TREES)
SelectObject(hdc, TreesSelectBitmap);
else
SelectObject(hdc, TreesUpBitmap); break;
case IDC_ROCKS :
if (lpdis->itemState i ODS_SELECTED)
SelectObject(hdc, RocksDownBitmap);
else if (TerrainCurrent == IDC_ROCKS)
SelectObject(hdc, RocksSelectBitmap);
else
SelectObject( h d c , RocksUpBitmap); break;
case IDC_MOUNTAINS :
if (lpdis->itemState & ODS__SELECTED)
SelectObject(hdc, MountainsDownBitmap);
else if (TerrainCurrent == IDC_MOUNTAINS)
SelectObject( h d c, MountainsSelectBitmap);
else
SelectObject(hdc, MountainsUpBitmap);
break;
case WM_CLOSE :
/*
* Zamknicie okna (ukrycie g o ) i wyczenie znaczka w menu
*/
ShowWindow(TerrainWindow, SW_HIDE);
CheckMenuItem(GetMenu(SceneWindow), IDM_WINDOW_TERRAIN,
MF_BYCOMMAND | MF_UNCHECKED);
break;
case WM_COMMAND :
/*
* Kliknito na przycisk - wybierz nowy typ terenu.
*/
switch (LOWORD(wParam))
{
case IDC_GRASS :
case IDCJTREES :
case IDC ROCKS :
414 ____ _________________________ Cz II Uywanie OpenGL
/*
* 'LoadAllBitmaps()' - aduje bitmapy przyciskw.
*/
void
LoadAllBitmaps(HINSTANCE hinstance)
{
GrassDownBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_GRASS_DOWN));
GrassSelectBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_GRASS_SELECT))
GrassUpBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_GRASS_UP));
WaterDownBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_WATER_DOWN));
WaterSelectBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOORCE(IDB_WATER_SELECT))
WaterUpBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_WATER_UP));
RocksDownBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOORCE(IDB_ROCKS_DOWN));
RocksSelectBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_ROCKS_SELECT))
RocksDpBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_ROCKS_UP));
TreesDownBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOORCE(IDB_TREES_DOWN));
TreesSelectBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_TREES_SELECT))
TreesDpBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_TREES_UP));
MountainsDownBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_MOUNTAINS_DOWN));
MountainsSelectBitmap = LoadBitmap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_MOONTAINS_SELECT));
MountainsUpBitmap = LoadBitraap((HANDLE)hinstance,
MAKEINTRESOURCE(IDB_MOONTAINS_UP));
Rozdzia 12. Mapowanie tekstur 415
void
LoadAllTextures(void)
{
glNewList(SkyTexture = glGenLists( 1 ) , GL_COMPILE);
glTexParameteri(GL_TEXTORE_2D, GL_TEXTORE_WRAP_S, GL_REPEAT) ;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTORE_WRAP_T, GL_REPEAT);
TextureLoadBitmap("sky.bmp");
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEndList();
/*
* 'UpdateNormals()' - Aktualizuje normalne punktw s c e n y . . .
*/
void
UpdateNormals(void)
{
int x, y; /* Wsprzdne x i y terenu */
GLfloat ( * n ) [ 3 ] , /* Bieca normalna terenu */
nx, ny, nz, /* Skadowe normalnej */ d, /*
Wielko normalnej */ *height; /* Bieca wysoko
terenu */
/*
* Przejcie przez tablice terenu i odtworzenie normalnych
* na podstawie wysokoci terenu
*/
n = TerrainNormal[ 0 ] ;
height = TerrainHeight[ 0 ] ;
for (y = 0; y < (TERRAIN_SIZE - 1) ; y ++, n ++, height ++)
{
for (x = 0; x < (TERRAIN_SIZE - 1 ) ; x ++, n + + , height ++)
{ /*
* Iloczyn wektorowy wektorw w gr i na prawo
* (uproszczone w tym specjalnym przypadku)
*/
nx = height[ 0 ] - height[ 1 ] ;
ny = -1.0;
nz = height[ 0 ] - height[TERRAIN_SIZE];
d = (float)-sqrt(nx * nx + ny * ny + nz * nz) ;
n [ 0 ] [ 0 ] = nx / d; /* Normalizacja wektora */
n [ 0 ] [ 1 ] = ny / d; n [ 0 ] [ 2 ] = nz / d; };
/*
* Iloczyn wektorowy wektorw w gr i na lewo
* (uproszczone w tym specjalnym przypadku) dla ostatniej
* kolumny siatki
*/
nx = height[ 0 ] - height[-l];
ny = -1.0;
nz = height[ 0 ] - height[TERRAIN_SIZE];
/*
* Ustawienie grnego wiersza normalnych tak samo jak
* normalnych drugiego wiersza od gry.
*/
for (x = 0; x < TERRAIN_SIZE; x ++, n + + ) {
n [ 0 ] [ 0 ] = n[-TERRAIN_SIZE][ 0 ] ;
n [ 0 ] [ l ] = n[-TERRAIN_SIZE][1];
n [ 0 ] [ 2 ] = n[-TERRAIN S I Z E ] [ 2 ] ;
/*
* 'InitializeTerrain( ) ' - Inicjuje tablice t e r e n u . . .
*/
void
InitializeTerrain(void)
{
int x, y; /* Pooenie terenu ( x , y) */
/*
* Wypenienie terenu traw.
*/
TerrainCurrent = IDC_WATER;
/*
* Aktualizacja normalnych
*/
UpdateNormals ( ) ;
/*
* 'draw_cell()' - Rysowanie (wypenienie) pojedynczej komrki
^terenu...
*/
void
draw_cell(int x, /* We - Pooenie terenu X */
int y) /* We - Pooenie terenu Y */ { /*
* Sprawdzenie zakresu terenu
*/
418 ___________________________________ Cz II Uywanie OpenGL
if (TerrainType [ y ] [ x ] == TerrainCurrent)
return; /* Ju jest poprawnego typu */
TerrainType [ y ] [ x ] = TerrainCurrent;
/*
* Wymuszenie odwieenia o k n a . . .
*/
InvalidateRect (SceneWindow, MOLL, TRUE) ;
/*
* Ustawienie wysokoci "komrki" terenu. Dla wody wysoko
* jest staa, WATER_HEIGHT. Dla innych typw dodajemy losowe
* odchylenie w celu uzyskania realistycznego obrazu.
*/
switch (TerrainCurrent)
{
case IDCJSATER :
TerrainHeight [ y ] [ x ] = WATER_HEIGHT;
break; case
IDC_GRASS :
TerrainHeight [y] [ x ] = GRASS_HEIGHT + O.lf * (randt) % 5 ) ;
break; case
IDCJTREES :
TerrainHeight [ y ] [ x ] = TREES_HEIGHT + 0.1 * (rand() % 5 ) ;
break; case
IDC_ROCKS :
TerrainHeight [ y ] [ x ] = ROCKS_HEIGHT + O.lf * (rand() % 5 ) ;
break; case
IDC_MOUNTAINS :
TerrainHeight [ y ] [ x ] = MOUNTAINS_HEIGHT + 0.15f * (rand() % 5 ) ;
break;
/*
* ' DrawTerrain ( ) ' - Rysuje komrk terenu na pozycji myszy
*/
void
DrawTerrain (int mousex, /* We - pozioma pozycja myszy */
int mousey) /* We - pionowa pozycja myszy */ {
int i,
count, /* Licznik selekcji */ x, y; /* Pooenie
terenu ( x , y) */ GLfloat *height; /* Bieca
wysoko */ GLuint b u f f e r f l O O ] ; /* Bufor selekcji
*/ GLint viewport[4]; /* Widok OpenGL */
Rozdzia 12. Mapowanie tekstur_________________________________419
/*
* Pobranie biecego widoku OpenGl i rozpoczcia liczenia
* pionowej wsprzdnej myszy od krawdzi widoku.
*/
glGet!ntegerv(GL_VIEWPORT, viewport);
mousey = viewport[3] - l - mousey;
/*
* Umoliwienie wyboru w granicach 4 pikseli od pozycji myszy
*/
glSelectBuffer(100, buffer);
glRenderMode(GL_SELECT);
gllnitNames();
glMatrixMode(GL_PROJECTION);
glLoadldentity();
gluPickMatrix((GLdouble)mousex, (GLdouble)mousey, 4 . 0 , 4 . 0 ,
viewport);
gluPerspective( 4 5 . O, (float)viewport[ 2 ] / (float)viewport[ 3 ] ,
0.1, 1000.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix(); /*
* Obrt/translacja biecego punktu obserwacji
*/
glRotatef(Roli, 0 . 0 , 0 . 0 , 1 . 0 ) ;
glRotatef(Pitch, -1.0, 0 . 0 , 0 . 0 ) ;
glRotatef(Heading, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glTranslatef(-Position[ 0 ] ,
-Positionfl],
-Position[ 2 ] ); glScalef(TERRAIN_SCALE,
TERRAIN_SCALE, TERRAIN_SCALE);
glLoadName( y ) ;
glPushName( 0 ) ;
for (x = 0; x < (TERRAIN_SIZE - 1 ) ; x ++, height ++)
glLoadName( x ) ;
glBegin(GL_POLYGON);
glVertex3f((GLfloat)(x - TERRAIN_EDGE),
height[ 0 ] ,
(GLfloat)(y - TERRAIN_EDGE));
420____________________________________Cz II Uywanie OpenGL
glVertex3f((GLfloat)(x - TERRAIN_EDGE),
height[TERRAIN_SIZE], (GLfloat) (y -
TERRAIN_EDGE + D ) ;
glVertex3f((GLfloat)(x - TERRAIN_EDGE + 1 ) ,
height[ 1 ] ,
(GLfloat)(y - TERRAIN_EDGE));
glVertex3f((GLfloat)(x - TERRAIN_EDGE + 1 ) ,
height[TERRAIN_SIZE + 1 ] ,
(GLfloat)(y - TERRAIN_EDGE + l));
glEnd(); };
glPopName O;
};
glPopName();
glPopMatrix O;
glFinishO ;
/*
* Odczyt trafie w buforze selekcji
*/
count = glRenderMode(GL_RENDER);
for (i = 0; i < count; i += 3) {
if ( b u f f e r [ i ) == 0)
continue;
/*
* Kade trafienie zawiera nastpujce parametry:
*
* O - ilo ( 2 )
* l - Minimalna warto Z
* 2 - Maksymalna warto Z
* 3 - Pooenie X w terenie
* 4 - Pooenie Y w terenie
*/
x = buffer[i + 4];
y = buffer[i + 3];
i += buffer[ i ] ;
/*
* Wypenienie 4 rogw wybranej komrki...
*/
draw_cell( x , y);
draw_cell(x + l, y);
draw_cell(x, y + 1 ) ;
draw_cell(x + 1 , y + 1 ) ;
/*
* Aktualizacja normalnych terenu.
*/
UpdateNormals();
Rozdzia 12. Mapowanie tekstur_________________________________421
/*
* 'FlyTerrain()' - Lot na podstawie biecej pozycji myszy.
*/
void
FlyTerrain(int mousex, /* We - pozioma wsprzdna myszy */ int
mousey) /* We - pionowa wsprzdna myszy */ {
RECT rect;
GLfloat movex, movey; /* Przemieszczenie myszy */
double curtime, /* Biecy czas w sekundach */
distance; /* Dystans do przeniesienia */ GLfloat
cheading, /* Cosinus kierunku */ sheading, /* Sinus
kierunku */ cpitch, /* Cosinus pochylenia */ spitch;
/* Sinus pochylenia */
/*
* Pobranie biecego czasu systemowego
*/
curtime = GetClockO;
distance = 10.0 * (curtime - MoveTime);
MoveTime = curtime;
/*
* Obliczenie odlegoci wskanika myszy od "rodka" (kliknicia)
*/
movex = 0.05 * (mousex - CenterMouseXY.x);
movey = 0.05 * (mousey - CenterMouseKY.y);
/*
* Dostosowanie kierunku pochylenia do biecego pooenia myszy
*/
Roli += movex;
Pitch += movey * cos(Roli * M_PI / 1 8 0 . 0 ) ;
Heading += movey * sin(Roli * M_PI / 180.0);
if (Heading < 0 . 0 )
Heading += 360.0; else if
(Heading >= 360.0)
Heading -= 360.0;
if (Pitch < -180.0)
Pitch += 360.0; else if
(Pitch >= 180.0)
Pitch - 360.0;
if (Roli < -180.0)
Roli += 360.0; else if
(Roli >= 180.0)
Roli -= 360.0;
422 Cz II Uywanie OpenGL
/*
* Przeniesienie w biecym kierunku
*/
GetClientRect(SceneWindow, srect);
Repaintwindow(irect);
int i;
int x, y; /* Pooenie terenu ( x , y) */
int last_type; /* Poprzedni typ terenu */
int *type; /* Biecy typ terenu */
GLfloat *height, /* Bieca wysoko terenu *
(*n)[31; /* Bieca normalna terenu *
static GLfloat
sky_top[4][ 3 ] =
( /* Wsprzdne nieba */ 0.8, -
{ -TERRAIN_EDGE, TERRAIN_SIZE TERRAIN_EDGE
{ TERRAIN_EDGE, TERRAIN_SIZE ),
{ TERRAIN_EDGE, TERRAIN_SIZE 0.8, -
{ -TERRAIN EDGE, TERRAIN SIZE TERRAIN_EDGE
{ -TERRAIN_EDGE, 0 . 0 , -TERRAIN_EDGE },
( TERRAIN_EDGE, 0 . 0 , -TERRAIN_EDGE },
{ TERRAIN_EDGE, 0 . 0 , TERRAIN_EDGE ),
{ -TERRAIN EDGE, 0 . 0 , TERRAIN EDGE }
/*
* Wyzerowanie widoku i wyczyszczenie okna na jasny bkit
*/
glViewport ( O , O, rect->right, rect->bottom) ;
glClearColor(0.5, 0.5, 1.0, 1 . 0 ) ; glEnable
(GL_DEPTH_TEST) ;
if (Moving | | Drawing) {
/*
* Bez tekstur podczas rysowania lub lotu; jest za w o l n e . . .
* Rysowanie tylnego bufora dla pynnej animacji
*/
glDisable (GL_TEXTURE_2D) ;
glDrawBuf fer (GL_BACK) ;
else
glEnable (GL_TEXTURE_2D) ;
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE , GL_DECAL) ;
glDrawBuffer (GL_FRONT) ;
/*
* Przygotowanie przeksztacenia widoku dla biecego
* punktu obserwacji
*/
glMatrixMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(45.0, (float) rect->right / (float) rect->bottom,
0 . 1 , 1000.0);
glMatrixMode (GL_MODELVIEW) ;
glPushMatrix() ;
glRotatef (Roli, 0 . 0 , 0.0, 1 . 0 ) ;
glRotatef (Pitch, -1.0, 0.0, 0 . 0 ) ;
glRotatef (Heading, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glTranslatef |-Position[0] ,
-Position[l] ,
-Position[2] ) ; glScalef (TERRAIN_SCALE,
TERRAIN_SCALE, TERRAIN_SCALE) ;
424____________________________________Cz II Uywanie OpenGL
if (!(Moving l| Drawing)) {
/*
* Rysowanie n i e ba .. .
*/
g!Disable(GL_LIGHTING);
glCallList(SkyTexture);
glBegin(GL_QDAD_STRIP); for
(i = 0; i < 4; i ++) {
glTexCoord2f((float)i, 0 . 0 ) ;
glVertex3fv(sky_bottom[i]);
glTexCoord2f((float)i, 0 . 8 ) ;
glVertex3fv(sky_top[i]); };
glTexCoord2f( 4 . 0 , 0 . 0 ) ;
glVertex3fv(sky_bottom[0]);
glTexCoord2f(4. 0 , 0 . 8 ) ;
glVertex3fv(sky_top[0]);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f( 0 . 5 , 1.0);
glVertex3f( 0 . 0 , TERRAIN_SIZE, 0 . 0 ) ;
glEnable(GL_LIGHTO);
glLightfv(GL_LIGHTO, GL_POSITION, sunpos);
glLightfv(GL_LIGHTO, GL_DIFFUSE, suncolor);
glLightfv(GL_LIGHTO, GL_AMBIENT, sunambient);
if (Moving l l Drawing)
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
Rozdzia 12. Mapowanie tekstur_________________________________425
/*
* Teraz teren...
*/
type = TerrainType[ 0 ] ;
height = TerrainHeight[ 0 ] ;
n = TerrainNormal[ 0 ] ;
for (y = 0; y < (TERRAIN_SIZE - 1 ) ; y ++)
{
last_type = -1;
/*
* Zaczniemy od poprzedniego miejsca, aby nie byo dziur
*/
glTexCoord2i (x * 2 - 2, y * 2 ) ;
glNorma!3fv(n[-l] ) ;
glVertex3f ( (GLfloat) (X - TERRAIN_EDGE - 1 ) ,
heightt-1] , (GLfloat) (y -
TERRAIN_EDGE) ) ;
glTexCoord2i(x * 2 - 2, y * 2 + 2 ) ;
glNorma!3fv(n[TERRAIN_SIZE - 1] ) ;
glVertex3f( (GLfloat) (x - TERRAIN_EDGE - 1 ) ,
height[TERRAIN_SIZE - 1 ] , (GLfloat)
(y - TERRAIN_EDGE + l ) ) ;
};
last_type = *type; >;
glTexCoord2i(x * 2, y * 2 ) ;
glNormal3fv(n[0] ) ;
glvertex3f( (GLfloat) (x - TERRAIN_EDGE) ,
height[0] ,
(GLfloat) (y - TERRAIN_EDGE) ) ;
glTexCoord2i(x * 2, y * 2 + 2) ;
glNormal3fv(n[TERRAIN_SIZE] ) ; glVertex3f(
(GLfloat) (x - TERRAIN_EDGE) ,
height [TERRAIN_SIZE] ,
(GLfloat) (y - TERRAIN_EDGE + D ) ;
};
glEnd ( ) ; };
glPopMatrix () ;
/*
* Gdy lecimy lub rysujemy, uywamy podwjnego buforowania.
* Jeli trzeba, przerzu bufory
*/
glFinish ( ) ;
if (Moving l l Drawing)
SwapBuf fers (SceneDC) ;
/*
* 'SaveBitmapFile () ' - Zapis wywietlanej sceny na dysku.
*/
void
SaveBitmapFile (void)
{
char t i t l e [ 2 5 6 ] , /* Tytu pliku */ filename[256] ,
/* Nazwa pliku */ directory[256] ; /* Bieca kartoteka */
OPENFILENAME ofn; /* Struktura okna dialogowego */ void
*bits; /* Dane bitmapy na ekranie */ BITMAPINFO
*info; /* Nagwek bitmapy na ekranie */
Rozdzia 12. Mapowanie tekstur_________________________________427
/*
* Zrzut ekranu...
*/
bits = ReadDIBitmap(sinfo);
if (bits == NULL)
{
DisplayErrorMessage( " N i e powiodo si odczytanie obrazu z
ekranu!");
return;
>;
/*
* Wywietlenie okna dialogowego...
*/
strcpy(directory, " . " ) ;
strcpy(filename, "bez nazwy.bmp");
strcpyltitle, " " ) ;
memset(sofn, O, sizeof(ofn));
ofn.lstructsize = sizeof( o f n ) ;
ofn.hwndOwner = SceneWindow;
ofn.lpstrFilter = "Bitmapy\0*.BMP\0\0";
ofn.nFilter!ndex = 1;
ofn.lpstrFile = filename;
ofn.nMaxFile = sizeof(filename) - 1;
ofn.lpstrFileTitle = title;
ofn.nMaxFileTitle = sizeof(title) - 1;
ofn.lpstrlnitialDir = directory;
ofn.IpstrTitle = "Zapisz plik bitmapy";
ofn.Flags = OFN_HIDEREADONLY | OFN_PATHMUSTEXIST l
OFN_NONETWORKBUTTON;
if (GetSaveFileName( S o f n ) ) {
/*
* Zapis pliku na dysku...
*/
if (SaveDIBitmap(filename, info, b i t s ) )
DisplayErrorMessage("Could not save to file \ ' % s \ ' -\n%s",
filename, strerror(errno));
};
/*
* Zwolnienie pamici i p o w r t . . .
*/
free(info);
free(bits);
428 Cz II Uywanie OpenGL
void
PrintBitmap(void)
{
void *bits; /* Dane obrazu */
BITMAPINFO *info; /* Nagwek bitmapy */
/*
* Zrzut ekranu. . .
*/
/*
* Wydruk bitmapy. . .
*/
PrintDIBitmap (Scenewindow, info, b i t s ) ;
/*
* Zwolnienie pamici i powrt...
*/
free (info) ;
free(bits) ;
/*
* 'GetClockO 1 - Czas, jaki upyn, w milisekundach...
*/
double
GetClock(void)
{
SYSTEMTIME curtime; /* Biecy czas systemowy */
GetSystemTime(icurtime);
return (curtime.wHour * 3600.0 +
curtime.wMinute * 6 0 . 0 +
curtime.wSecond +
curtime.wMilliseconds * 0 . 0 0 1 ) ;
Rozdzia 12. * Mapowanie tekstur 429
Podrcznik
glTexCoord
Przeznaczenie Okrela wsprzdne tekstury dla wielokta, na ktry nakadamy tekstur.
Plik nagwkowy <gl.h>
Skadnia void glTexCoordl {dfis}(TYPE s);
void glTexCoordl {dfis}v(TYPE *s);
void glTexCoord2{dfis}(TYPE s, TYPE t);
void glTexCoord2{dfis}v(TYPE *st);
void glTexCoord3 {dfis}(TYPE s, TYPE t, TYPE r);
void glTexCoord3{dfis}v(TYPE *str);
void glTexCoord4{dfis}(TYPE s, TYPE t, TYPE r, TYPE q);
void glTexCoord4{dfis}v(TYPE *strq);
Opis Ta funkcja ustala biece wsprzdne obrazu tekstury, dla jednego,
Parametry s t dwch, trzech lub czterech wymiarw. Na przykad, parametry s i t
odpowiadaj poziomej i pionowej wsprzdnej dwuwymiarowego
r obrazu tekstury.
Zwracana warto
Przykad Patrz Pozioma wsprzdna obrazu tekstury.
take Pionowa wsprzdna obrazu tekstury.
Wsprzdna gbokoci obrazu tekstury.
Wsprzdna czasu" obrazu tekstury
Brak.
Przejrzyj kod programu TEXSCENE.C na pytce CD-ROM.
glTextEnv, glTexGen, glTex!magelD, glTex!mage2D. glTexParameter
glTexEnv
Przeznaczenie Okrela parametry teksturowania.
Plik nagwkowy <gl.h>
Skadnia void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
void glTexEnvfv(GLenum target, GLenum pname, GLfloat *param);
void glTexEnvi(GLenum target, GLenum pname, GLint param);
void glTexEnviv(GLenum target, GLenum pname, GLint *param);
430 Cz II * Uywanie OpenGL
glTexGen
Przeznaczenie Definiuje parametry generowania wsprzdnych tekstur.
Plik <gl.h>
nagwkowy void glTexGend(GLenum coord, GLenum pname, GLdouble param);
void glTexGenf(GLenum coord, GLenum pname, GLfloat param);
void glTexGeni(GLenum coord, GLenum pname, GLint param);
void glTexGendv(GLenum coord, GLenum pname, GLdouble *param);
void glTexGenfv(GLenum coord, GLenum pname, GLfloat *param);
void glTexGeniv(GLenum coord, GLenum pname, GLint *param);
Opis Gdy funkcj glEnable zostanie wczona jedna z opcji,
GL_TEXTURE_GEN_S, GL_TEXTURE_GEN_T,
GL_TEXTURE_GEN_R lub GL_TEXTURE_GEN_Q, funkcja
glTexGen ustawia parametry generowania wsprzdnych tekstur.
Rozdzia 12. Mapowanie tekstur 431
glTexlmagelD
Przeznaczenie Definiuje jednowymiarowy obraz tekstury.
Plik nagwkowy
Skadnia void glTexImagelD(GLenum target, GLint Ievel, GLint components,
GLsizei width, GLint border, GLenum format, GLenum type, const
GLvoid *pixels);
432 Cz II Uywanie
OpenGL
glTexlmage2D
Przeznaczenie Definiuje jednowymiarowy obraz tekstury.
Plik nagwkowy
Skadnia void glTexImage2D(GLenum target, GLint level, GLint components,
GLsizei width, GLsizei height, GLint border, GLenum format, GLenum
type, const GLvoid *pixels);
Rozdzia 12. o Mapowanie tekstur 433
Przeznaczenie glTexParameter
Plik Ustala parametry obrazu tekstury.
434 Cz II Uywanie OpenGL
Tworzenie kwadryk
Kada tworzona kwadryka ma pewien stan (kolekcj powizanych ze sob ustawie).
Funkcja gluNewQuadric tworzy zmienn stanu, opisujc aktualny styl rysowania,
orientacj, tryb owietlenia, tryb teksturowania oraz funkcj zwrotn:
GLUuadricObj *obj; obj
gluNewOuadric() ;
Zwr uwag, e stan kwadryki nie okrela ksztatu geometrycznego, jaki zostanie
utworzony. Zamiast tego opisuje, jak rysowa taki ksztat. Dziki temu mona stosowa
kwadryki przy tworzeniu wielu rnych rodzajw ksztatw.
Tabela 13.1.
Style rysowania kwadryk
Styl______________Opis___________________________________
Tabela 13.2.
Tryby obliczania normalnych
Jak zapewne pamitasz, wsprzdne tekstur s uywane przy nakadaniu obrazw te-
kstur na wielokty (rozdzia 12).
Rysowanie cylindrw
Do rysowania cylindrw suy funkcja gluCylinder. Cylinder rysowany za pomoc tej
funkcji to po prostu tuba uoona wzdu osi z (rysunek 13.1). Podstawy cylindra nie s
wypeniane!
^P-^ M ^^^"Tk:
(0,0,0)
topRodius
void gluCylider(GLUuadricObj
*obj,
GLdouble baseRadius,
GLdouble topRadius,
GLdouble height, GLint
slices, GLint stacks)
438____________________________________Cz II Uywanie OpenGL
Parametry baseRadius i topRadius okrelaj promie cylindra przy dolnej i grnej pod-
stawie. Parametr height okrela wysoko (czy te dugo) cylindra.
Parametry slices i stacks okrelaj,, z ilu czci (cian) oraz z ilu segmentw (piter) bdzie
si skada cylinder. Oglnie, aby nada cylindrom gadkie ciany, powiniene uy
okoo 20 cian. Mniejsze wartoci powoduj, e cylinder zaczyna przypomina
graniastosup, za wartoci wiksze mog powodowa powstawianie mieci na rysunku.
Gdy stosujesz wiato punktowe lub wiato odbyskw, powiniene take wybra wiksz
ilo segmentw. W przeciwnym razie wybierz dwa segmenty, odpowiadajce obu
podstawom cylindra.
Cylindry mona wykorzysta take do tworzenia graniastosupw foremnych, takich jak
owek czy szecian.
Rysowanie stokw
Biblioteka GLU nie posiada specjalnej funkcji do rysowania stokw, mona jednak
uy w tym celu funkcji gluCylinder. W tym celu wystarczy poda warto 0,0 jako pa-
rametr topRadius lub bottomRadius.
Teksturowanie cylindrw
Podczas teksturowania cylindra, obraz tekstury jest na nim zawijany poczwszy od przedniej
krawdzi (O, promie, 0). To oznacza, e obraz tekstury powinien by odwrcony do gry
nogami". Nakadanie tekstury na cylinder przeprowadzimy w programie projektu w tym
rozdziale.
Rysowanie dyskw
Dyski to okrge, paskie ksztaty, ktre mog zawiera dziury. Przykadami dyskw
mog by monety lub piercienie.
void gluDisk(GLUquadricObj *obj,
GLdouble innerRadius,
GLdouble outerRadius,
GLint slices, GLint
loops)
rwny l dla okrgw i 2 dla piercieni. Tak jak w przypadku cylindrw, uycie wi-
kszych wartoci poprawia efekt wiata punktowego i odbyskw.
Teksturowanie dysku
Obrazy tekstur s nakadane tak,
aby krawdzie obrazu OuterRodius
pokryway si z krawdziami
dysku. Grna krawd tekstury
pokrywa si z grn krawdzi dysku, lewa krawd tekstury pokrywa si z lew
krawdzi dysku itd.
Rysowanie sfer
Kule to puste piki. Gdy rysujesz sfer, okrelasz jej promie oraz ilo cianek.
void gluSphere(GLUuadricObj *obj,
GLdouble radius,
GLint slices, GLint
stacks)
Jeli potraktujesz sfer jak sfer ziemsk, parametr slices reprezentuje ilo poudnikw,
za parametr stacks - ilo rwnolenikw (rysunek 13.3).
440 Cz II * Uywanie OpenGL
Rysunek 13.3.
Sfera
Rwnoleniki
Poudniki
Teksturowanie sfer
Obrazy tekstur s nakadane zgodnie z poudnikami i rwnolenikami. Tak wic obraz
mapy wiata zostanie poprawnie naoony na sfer.
Rysowanie owka
Aby zamkn ten rozdzia, napiszemy may program, sucy do przedstawienia obraca-
jcego si owka (rysunek 13.4). Owek bdzie si skada z trzech cylindrw i dwch
obrazw tekstur. Pierwszy obraz zawiera typowe symbole dla owka nr 2 oraz napis
OpenGL Country Club". Jako zaostrzony koniec owka zastosujemy drugi obrazek,
przedstawiajcy drewno z wystajcym grafitem.
Rysunek 13.4.
Owek stworzony
przy uyciu kwadryk
Czubek owka to oczywicie stoek. Drugi koniec owka nie jest ju taki oczywisty.
Poniewa jest paski, mgby oczekiwa, e do jego utworzenia uyjemy dysku. Niestety,
w przypadku uytej tekstury (rysunek 13.5) efekt jej naoenia nie wygldaby
najlepiej. Tak wic, zamiast dysku uyjemy cylindra o zerowej wysokoci i zerowym
grnym promieniu.
Rozdzia 13. Kwadryki: sfery, cylindry i dyski
441
Rysunek
13.5.
Obrazy tekstur na
ciany owka i
gluCylinder(PencilObj, 5 . 0 , 5 . 0 , 40.0, 6, 2 ) ;
glPopMatrix();
Nastpnie rysujemy czubek i koniec owka uywajc tekstury grafitu". Take rym
razem stosujemy cylindry skadajce si z szeciu stron.
gluOuadricNormals(PencilObj, GLU_SMOOTH);
glCallList(LeadTexture) ;
442____________________________________Cz II Uywanie OpenGL
glPushMatrix();
glTranslatef (0.0, 0.0, 2 0 . 0 ) ;
gluCylinder(PencilObj, 5 . 0 , 0 . 0 , 7 . 5 , 6, 2);
glPopMatrix();
glPushMatrix();
glTranslatef ( 0 . 0 , 0.0, -20.0);
gluCylinder(PencilObj, 5 . 0 , 0 . 0 , 0 . 0 , 6, 2 ) ;
glPopMatrix();
Podsumowanie
W tym rozdziale poznalimy funkcje suce do rysowania kwadryk. Kwadryki w OpenGL
to geometryczne ksztaty tworzce podstawowe klocki" do budowy wielu innych obiektw,
zarwno sztucznych, jak naturalnych. Uycie kwadryk jest wygodnym sposobem uniknicia
koniecznoci tworzenia dodatkowego kodu budujcego tego typu ksztaty.
Przejdmy teraz do listingu 13.1, programu rysujcego owek. Listing
13.1. Program rysujcy owek______________________________________
/*
* Niezbdne nagwki.
*/
include "texture.h"
include "pencil.h"
tinclude <stdarg.h>
/*
* Zmienne globalne...
*/
HWND PencilWindow; /* Okno sceny */
HPALETTE PencilPalette; /* Paleta kolorw (jeli potrzebna) */
HDC PencilDC; /* Kontekst rysowania */
HGLRC PencilRC; /* Kontekst renderowania OpenGL */
/*
* Funkcje lokalne...
*/
Rozdzia 13. Kwadryki: sfery, cylindry i dyski_________________________443
void DisplayErrorMessage(char *, . . . ) ;
void MakePalette( i n t ) ;
LRESOLT CALLBACK PencilProc(HWND, UINT, WPARAM, LPARAM);
void LoadAllTextures(void);
void RepaintWindow(RECT * ) ;
void PrintBitmap(void);
/*
* 'WinMainO '
*/
int APIENTRY
WinMain(HINSTANCE hlnst,
HINSTANCE hPrevInstance, LPSTR
IpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASS we; RECT
rect;
w e . style = 0;
wc.lpfnWndProc = (WNDPROC)PencilProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hlnstance = hlnst;
wc.hlcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = 0;
wc.lpszMenuName = MAKEINTRESOURCE(IDR_MENU1);
wc.lpszClassName = "Textured Quadric Pencil";
if (RegisterClass( S w e ) == 0) {
DisplayErrorMessage( " N i e udao si zarejestrowanie o k n a ! " } ;
return ( F A L S E ) ;
};
PencilWindow = CreateWindow("Textured Quadric Pencil",
"Owek stworzony z teksturowanych
kwadryk",
WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN |
WS_CLIPSIBLINGS, 32, 32, 400, 300, NOLL,
NULL, hlnst, NULL);
if (PencilWindow == NULL) {
DisplayErrorMessage( " N i e udao si utworzenie o k n a ! " ) ;
return ( F A L S E ) ;
};
ShowWindow(PencilWindow, nCmdShow);
OpdateWindow(PencilWindow);
444 Cz II Uywanie OpenGL
* Obrt owka. . .
*/
PencilRoll += 1 . 0 ;
PencilPitch += 2 . 0 ;
PencilHeading += 3 . 0 ;
if (format == NULL)
return;
va_start(ap, format);
vsprintf(s, format, ap);
va_end(ap);
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, s, " E r r o r " , MB_OK | MB_ICONEXCLAMATION) ,
/*
* 'MakePalette () ' - Jeli trzeba, tworzy palet kolorw.
*/
Rozdzia 13. Kwadryki: sfery, cylindry i dyski__________________________445
void
MakePalette(int p f ) /* We - ID formatu pikseli */
{
PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE *pPal;
int nColors;
int i,
r
max,
gmax,
brn x;
/*
* Sprawdzenie, czy paleta jest potrzebna... V
DescribePixelFormat(PencilDC, pf, sizeof(PIKELFORMATDESCRIPTOR) ,
spfd);
if (!(pfd.dwFlags & PFD_NEED_PALETTE))
{
PencilPalette = NULL;
return;
};
/*
* Alokowanie pamici dla palety.
*/
nColors = l pfd.cColorBits;
/*
* Odczyt maksymalnych wartoci barw skadowych i budowanie nColors
* kolorw
*/
rmax = (l pfd.cRedBits) - 1;
gmax = (l pfd.cGreenBits) - 1;
bmax = (l pfd.cBlueBits) - 1;
for (i = 0 ; i < nColors; i ++) {
pPal->palPalEntry[i].peRed = 255 * ( (i pfd.cRedShift) S rmax) /
rmax ;
pPal->palPalEntry[i].peGreen = 255 * ((i pfd.cGreenShift) 4
^gmaK) /
gmax;
pPal->palPalEntry[i].peBlue = 255 * ((i pfd.cBlueShift) &
c
>bmax) /
bmax ;
pPal->palPalEntry[ i ] .peFlags = 0;
446 ____________________________________ Cz II Uywanie OpenGL
/*
* Utworzenie, wybranie i realizacja palety
*/
PencilPalette = CreatePalette (pPal) ;
SelectPalette(PencilDC, PencilPalette, FALSE) ;
RealizePalette (PencilDC) ;
free (pPal) ;
/*
* ' PencilProc ( ) ' - Obsuga komunikatw okna sceny.
*/
LRESULT CALLBACK
PencilProc (HWND hWnd,
UINT uMsg, WPARAM wParam,
LPARAM IParam) (
int p f ; /* ID formatu pikseli */
PIXELFORMATDESCRIPTOR pfd; /* informacje o formacie pikseli */
PAINTSTRUCT ps;
RECT rect;
switch (uMsg) {
case WM_CREATE :
// Pobranie kontekstu urzdzenia i renderowania,
// przygotowanie obszaru klienta dla OpenGL
PencilDC = GetDC(hWnd) ;
wglMakeCurrent(PencilDC, PencilRC);
// adowanie obrazw tekstur do list wywietlania...
LoadAllTextures(); PencilObj =
gluNewQuadric();
gluQuadricTexture(PencilObj, GL_TRHE);
break;
case WM_SIZE :
case WM_PAINT :
// Odrysowanie obszaru klienta...
BeginPaint(hWnd, ips);
GetClientRect(hWnd, srect);
RepaintWindow(Srect);
EndPaint(hWnd, & p s ) ;
break;
case WM_COMMAND :
/*
* Obsuga menu...
*/
switch (LOWORD(wParam))
{
case IDM_FILE_PRINT :
PrintBitmap();
break; case
IDM_FILE_EXIT :
DestroyWindow(PencilWindow);
break;
}; break;
case WM_QUIT :
case WM_CLOSE :
/*
* Zniszczenie okna,'bitmap i wyjcie...
*/
DestroyWindow(PencilWindow);
exit(0);
break;
case WM_DESTROY :
/*
* Zwolnienie kontekstu urzdzenia, kontekstu
* renderowania i palety
*/
if (PencilRC)
wglDeleteContext(PencilRC);
if (PencilDC)
ReleaseDC(PencilWindow, PencilDC);
448____________________________________Cz II Uywanie OpenGL
if (PencilPalette)
Deleteobject(PencilPalette) ;
PostQuitMessage( 0 ) ;
break;
case WM_QUERYNEWPALETTE :
/*
* w razie potrzeby realizacja palety...
*/
if (PencilPalette)
{
SelectPalette(PencilDC, PencilPalette, FALSE);
RealizePalette(PencilDC);
UpdateColors(PencilDC);
}; break;
default :
/*
* Standardowa obsuga wszystkich innych komunikatw
*/
return (DefWindowProc(hWnd, uMsg, wParam, IParam)); };
return (FALSE);
/*
* 'LoadAllTextures()' - aduje tekstury dla sceny.
*/
void
LoadAllTextures(void)
{
glNewList(PencilTexture = glGenLists( 1 ) , GL_COMPILE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT),
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT),
TextureLoadBitmap("pencil.bmp"); glEndList();
Rozdzia 13. Kwadryki: sfery, cylindry i dyski _________________________ 449
/*
* ' RepaintWindow ( ) ' - Odrysowuje obszar roboczy okna sceny.
*/
void
RepaintWindow (RECT *rect) /* We - Obszar roboczy okna */ {
/*
* Wyzerowanie widoku i wyczyszczenie okna na jasny bkit
*/
glYiewport ( O , O, rect->right, rect->bottom) ;
glClearColor ( 0 . 7 , 0.7, 1 . 0 , 1 . 0 ) ;
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
/*
* Przygotowanie przeksztacenia widoku dla biecego
* punktu obserwacji
*/
glMatrixMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective ( 4 5 . O, (float) rect->right / (float) rect->bottom,
0 . 1 , 1000.0);
glEnable (GL_LIGHTING) ;
glEnable (GL_LIGHTO) ;
glEnable (GL_DEPTH_TEST) ;
glEnable (GL_TEXTURE_2D) ;
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) ;
glMatrixMode(GL_MODELVIEW) ;
glPushMatrix ( ) ;
glTranslatef ( 0 . 0 , 0 . 0 , - 8 0 . 0 ) ;
glRotatef (PencilHeading, 0 . 0 , -1.0, 0 . 0 ) ;
glRotatef (PencilPitch, 1 . 0 , 0 . 0 , 0 . 0 ) ;
glRotatef (PencilRoll, 0 . 0 , 0 . 0 , - 1 . 0 ) ;
/*
* Najpierw cianki owka - cylinder z szecioma ciankami
*/
gluOuadricNormals (PencilObj , GLU_FLAT) ;
glCallList (PencilTexture) ;
glPushMatrix () ;
glTranslatef ( 0 . 0 , 0.0, -20.0);
/*
* Koce owka - stoek na czubku i piaski stoek na kocu
*/
gluCylinder (PencilObj, 5 . 0 , 0 . 0 , 7 . 5 , 6, 2 ) ;
glPopMatrix () ;
glPushMatrix ( ) ;
glTranslatef ( 0 . 0 , 0 . 0 , - 2 0 . 0 ) ;
/*
* Normalnie uylibymy dysku, ale niestety, nie pasuj
* wsprzdne tekstury
*/
gluCylinder (PencilObj, 5 . 0 , 0 . 0 , 0 . 0 , 6, 2 ) ;
glPopMatrix () ; glPopMatrix ( ) ;
/*
* Przerzucenie buforw i powrt
*/
glFinish ( ) ;
SwapBuf fers (PencilDC) ;
/*
* 'PrintBitmapO ' - Wydruk wywietlanej sceny.
*/
void
PrintBitmap (void)
{
void *bits; /* Dane obrazu */
BITMAPINFO *info; /* Nagwek bitmapy */
/*
* Zrzut ekranu. . .
*/
bits = ReadDIBitmap (sinf o) ;
if (bits == NULL)
{
DisplayErrorMessage ( " N i e powiodo si odczytanie bitmapy z
ekranu! ") ;
return;
* Wydruk bitmapy.
*/
Rozdzia 13. Kwadryki: sfery, cylindry i dyski 451
* Zwolnienie pamici i p o w r t . . .
*/
free (info) ;
free(bits) ;
Podrcznik
gluCylinder
Przeznaczenie Rysuje cylinder.
Plik nagwkowy <glu.h>
Skadnia void gluCylinder(GLUquadricObj *obj, GLdouble baseRadius, GLdouble
topRadius, GLdouble height, GLint slices, GLint stacks);
Opis Ta funkcja tworzy pusty cylinder bez podstaw, uoony wzdu osi z. Jeli
parametr topRadius lub bottomRadius wynosi zero, tworzony jest stoek.
Cylinder ma dugo height jednostek wzdu osi z. Parametr slices okrela
ilo cian cylindra, za parametr stacks - ilo segmentw wzdu cylindra.
Parametry obj
GLUuadricObj*: Informacje o stanie kwadryki, uywane podczas
baseRadius rysowania.
topRadius GLdouble: Promie dolnej podstawy cylindra (Z = 0).
height GLdouble: Promie grnej podstawy cylindra (Z = height).
slices GLdouble: Wysoko (dugo) cylindra wzdu osi z.
height GLint: Ilo bocznych cian cylindra.
Zwracana warto GLint: Ilo segmentw cylindra (wzdu osi z).
Przykad Patrz Brak.
take Przejrzyj kod programu PENCIL.C na pytce CD-ROM.
gluDeleteCjuadric, gluNewQuadric, gluQuadricCallback,
gluCjuadricDrawStyle, gIuQuadricNormals, gluQuadricOrientation,
gluQuadricTexture
452 Cz II Uywanie OpenGL
gluDeletepuadric
Przeznaczenie Plik Usuwa obiekt stanu kwadryki.
nagwkowy <glu.h>
Skadnia Opis void gluDeleteQuadric(GLUquadricObj *obj);
Ta funkcja usuwa obiekt stanu kwadryki. Po usuniciu obiektu nie mona
Parametry go ponownie uy do rysowania.
obj
Zwracana warto GLUuadricObj*: Obiekt stanu przeznaczony do usunicia. Brak.
Patrz take gluNewQuadric, gluQuadricCallback, gluQuadricDrawStyle,
gluQuadricNormals, glupuadricOrientation, gluQuadricTexture
gluDisk
Przeznaczenie Plik Rysuje dysk.
nagwkowy <glu.h>
Skadnia void gluDisk(GLUquadricObj *obj, GLdouble innerRadius, GLdouble
outerRadius, GLint slices, GLint loops);
Opis Ta funkcja tworzy dysk prostopady do osi z. Jeli parametr innerRadius
wynosi zero, zamiast dysku tworzony jest piercie. Parametr slices okrela
ilo cian cylindra, za parametr loops ilo piercieni dysku.
Parametry obj
GLUuadricObj*: Informacje o stanie kwadryki, uywane podczas
innerRadius rysowania.
outerRadius GLdouble: Wewntrzny promie dysku.
slices GLdouble: Zewntrzny promie dysku.
height GLint: Ilo bocznych cian dysku. GLint:
Zwracana warto Ilo piercieni dysku. Brak.
Patrz take gluDeleteQuadric, gluNewQuadric, gluQuadricCallback,
gluQuadricDrawStyle, gluQuadricNormals, gluQuadricOrientation,
gluQuadricTexture
Rozdzia 13. Kwadryki: sfery, cylindry i dyski 453
gluNewQuadric
Przeznaczenie Plik Tworzy nowy obiekt stanu kwadryki.
nagwkowy <glu.h>
Skadnia Opis GLUuadricObj *gluNewQuadric(void);
Ta funkcja tworzy nowy obiekt stanu kwadryki. Obiekt stanu kwadryki
Parametry zawiera informacje okrelajce sposb rysowania kwadryk.
Zwracana warto Brak.
GLUuadricObj *: NULL w przypadku braku pamici; w przeciwnym
Przykad razie wskanik do obiektu stanu kwadryki.
Patrz take Kod programu PENCIL.C na pytce CD-ROM.
gluDeleteQuadric, gluQuadricCallback, gluQuadricDrawStyle,
gluQuadricNormals, gluQuadricOrientation, g!uQuadricTexture
gluPartialDisk
Przeznaczenie Rysuje czciowy dysk.
Plik nagwkowy <glu.h>
Skadnia voidgluPartialDisk(GLUquadricObj *obj, GLdouble innerRadius,
GLdouble outerRadius, GLint slices, GLint loops, GLdouble startAngle,
GLdouble sweepAngle);
Opis Ta funkcja tworzy cz dysku prostopadego do osi z. Jeli parametr
innerRadius wynosi zero, zamiast dysku tworzony jest piercie. Parametr
slices okrela ilo cian cylindra, za parametr loops - ilo piercieni
dysku. Parametr startAngle okrela pocztkowy kt dysku (kt 0 to gra
dysku, za 90 to prawa strona dysku). Parametr sweepAngle okrela uk
zajmowany przez dysk, w stopniach.
Parametry obj
GLUuadricObj*: Informacje o stanie kwadryki, uywane podczas
innerRadlus rysowania.
outerRadius slices GLdouble: Wewntrzny promie dysku.
height startAngle GLdouble: Zewntrzny promie dysku.
sweepAngle GLint: Ilo bocznych cian dysku. GLint:
Zwracana warto Ilo piercieni dysku. GLdouble:
Pocztkowy kt czci dysku. GLdouble:
Ktowy rozmiar czci dysku. Brak.
454 Cz II Uywanie OpenGL
gluQuadricCallback
Przeznaczenie Definiuje funkcj zwrotn kwadryki.
Plik nagwkowy <glu.h>
Skadnia void gluQuadricCallback(GLUquadricObj *obj, GLenum which, void
gluQuadricDrawStyle
Przeznaczenie Okrela styl rysowania kwadryki.
Plik nagwkowy <glu.h>
Skadnia Opis void gluQuadricDrawStyle(GLUquadricObj *obj, GLenum drawStyle);
Parametry Ta funkcja suy do wyboru stylu rysowania kwadryki.
obj
drawStyle GLUuadricObj *: Wskanik do obiektu informacji o stanie kwadryki.
GLenum: Styl rysowania. Dostpne style to:
GLU_FILL Kwadryki s tworzone za pomoc wieloktw i paskw
prymityww.
GLU_LINE Kwadryki s rysowane jako siatka odcinkw.
GLU_SILHOUETTE Kwadryki s rysowane jako siatka odcinkw, z tym
e rysowane s jedynie zewntrzne krawdzie.
GLU_POINT Kwadryki s tworzone jako zbir punktw.
Rozdzia 13. * Kwadryki: sfery, cylindry i dyski 455
gluQuadricNormals
Przeznaczenie Okrela sposb generowania normalnych dla punktw kwadryki.
Plik nagwkowy <glu.h>
Skadnia Opis void gluQuadricNormals(GLUquadricObj *obj, GLenum normals);
Ta funkcja okrela sposb generowania normalnych dla kwadryk
Parametry rysowanych z uyciem tego obiektu stanu.
obj
normals GLUuadricObj *: Wskanik do obiektu informacji o stanie kwadryki.
GLenum: Sposb generowania normalnych. Dostpne style to:
GLU_NONE Normalne nie s generowane.
GLU_FLAT Normalne s generowane dla caych wieloktw, co
powoduje, e kwadryka wyglda na zbudowan ze cianek.
GLU_SMOOTH Normalne s generowane dla poszczeglnych
wierzchokw, co powoduje, e powierzchnia kwadryki wydaje si
gadka.
Zwracana warto Brak.
Przykad Patrz Przykadowy program PENCIL.C na pytce CD-ROM.
take gluDeleteQuadric, gluNewQuadric, glQuadricCallback,
gluQuadricDrawStyle, gluQuadricOrientation, gluQuadricTexture
gluQuadricOrientation
Przeznaczenie Okrela kierunek normalnych kwadryki.
Plik nagwkowy <glu.h>
Skadnia Opis void gluQuadricOrientation(GLUquadricObj *obj, GLenum orientation);
Ta funkcja okrela kierunek normalnych dla pustych obiektw. Jeli
normalne maj wskazywa na zewntrz obiektu, parametr orientation
powinien mie warto GLU_OUTSIDE. Jeli normalne maj wskazywa
do wntrza obiektu, parametr orientation powinien mie warto GLU
INSIDE.
Parametry
obj GLUquadricObj *: Wskanik do obiektu informacji o stanie kwadryki.
456 Cz II Uywanie OpenGL
gluQuadricTexture
Przeznaczenie Plik Wcza lub wycza generowanie wsprzdnych tekstury dla kwadryk.
nagwkowy <glu.h>
Skadnia void gluQuadricTexture(GLUquadricObj *obj, GLboolean
textureCoords);
Opis Ta funkcja okrela, czy bd generowane wsprzdne tekstury dla
kwadryki.
Parametry obj
textureCoords GLUuadricObj *: Wskanik do obiektu informacji o stanie kwadryki.
GLboolean: GLU_TRUE, jeli wsprzdne tekstury maj by
Zwracana warto generowane, GLU_FALSE w przeciwnym wypadku.
Patrz take Brak.
gluDeleteQuadric, gluNewQuadric, glQuadricCallback,
gluQuadricDrawStyle, gluQuadricNormals, gluQuadricOrientation
gluSphere
Przeznaczenie Plik Rysuje sfer.
nagwkowy <glu.h>
Skadnia void gluSphere(GLUquadricObj *obj, GLdouble radius, GLint slices,
GLint stacks);
Opis Ta funkcja tworzy sfer, uoon w rodku ukadu wsprzdnych.
Parametr slices okrela ilo poudnikw sfery, za parametr stacks -
ilo jej rwnolenikw sfery.
Parametry obj
GLUuadricObj*: Informacje o stanie kwadryki, uywane podczas
slices height rysowania.
Zwracana warto Glint: Ilo poudnikw sfery. GLint:
Ilo rwnolenikw sfery. Brak.
Rozdzia 13. Kwadryki: sfery, cylindry i dyski_________________________457
Stan renderowania to wanie ten mechanizm, ktry sprawia, e OpenGL jest tak szybki i
efektywny w renderowaniu trjwymiarowej grafiki. Zmienne stanu s podzielone na
rne kategorie, dotyczce koloru, owietlenia, teksturowania itd. Kady tworzony kontekst
renderowania (HRC) posiada wasny stan renderowania, specyficzny dla okna lub bitmapy
w pamici.
W odrnieniu od wikszoci rozdziaw, w tym nie ma ani jednego przykadowego
programu. Sposb uycia opisywanych funkcji znajdziesz we wszystkich innych roz-
dziaach w ksice.
Wikszo zmiennych stanu OpenGL to wartoci logiczne, wczone lub wyczone. Inne,
na przykad biecy widok, to tablice liczb cakowitych lub tablice liczb zmienno-
przecinkowych dla kolorw RGBA. Do odczytu zmiennych tego typu su funkcj
glGetDoublev, glGetFloatv i glGet!ntegerv:
GLint istate[ 4 ] ;
GLfloat fstate[ 4 ] ;
GLdouble dstate[3];
glGet!ntegerv(GL_VIEWPORT, istate);
glGetFloatv(GL_CURRENT_COLOR, fstate);
glGetDoublev(GL_CURRENT_NORMAL, dstate);
Zachowywanie i odtwarzanie
zmiennych stanu
Podobnie jak w przypadku macierzy rzutowania, widoku modelu i tekstury, OpenGL
posiada stos do przechowywania zmiennych stanu. Jednak w odrnieniu od stosu ma-
cierzy, stos stanu umoliwia precyzyjne wybranie zmiennych, ktre zostan odoone na
stos i z niego zdjte (rysunek 14.1).
Rysunek Informocje o sonie Szczyt stosu
14.1. Informacje o sonie
Stos atrybutw w Informacje o stanie
OpenGL
Informacje o sonie
Informacje o sanie
Informacje o sonie
Informacje o stanie
Informacje o sonie
Zwykle jednak bdziesz chcia zachowa jedynie okrelony zestaw informacji, takich
jak biecy kolor, szeroko linii itd. OpenGL definiuje wiele staych dla rnych
rodzajw informacji (zebrano je w tabeli 14.1), na przykad:
glPushAttrib(GL_CURRENT_BIT); // Zachowuje biecy kolor rysowania
// itd.
glPushAttrib(GL_LIGHTING_BIT); // Zachowuje biece ustawienia
// owietlenia
glPushAttrib(GL_TEXTURING_BIT); // Biece ustawienia teksturowania
Gdy wykonasz renderowanie, moesz przywrci bity stanu wywoujc funkcj glPop-
Attrib. Ta funkcja nie posiada argumentu i odtwarza jedynie to, co zostao odoone na
stos ostatnim poleceniem glPushAttrib.
Tabela 14.1.
Bity atrybutw funkcji glPushAttrib
Tabela 14.1.
Bity atrybutw funkcji glPushAttrib - cig dalszy
Stan rysowania
OpenGL posiada wiele zmiennych stanu zwizanych z rysowaniem prymityww we-
wntrz pary wywoa glBegin/glEnd. Wikszo z nich jest zachowywanych w wyniku
wywoania glPushAttrib(GL_CURRENT_BIT | GL_LINE_BIT); opis poszczeglnych
zmiennych tej grupy zawiera tabela 14.2.
Rozdzia 14. Maszyna stanu OpenGL______________________________465
Tabela 14.2.
Zmienne stanu rysowania
Stan owietlenia
Ze wszystkich zmiennych stanu OpenGL, zmienne zwizane z owietleniem s najli-
czniejsze. Informacje o stanie owietlenia obejmuj ustawienia biecego trybu koloru i
wiata dla rodowiska owietlenia (modelu), definicj materiau, kolor, pooenie i
kierunek rde wiata, a take kilka innych parametrw. Co wicej, przy wczonym
466 Cz III Tematy zaawansowane i efekty specjalne
Tabela 14.3.
Zmienne stanu owietlenia
Stan teksturowania
Jeli chodzi o zoono, teksturowanie niewiele ustpuje owietleniu. Dostpne zmienne
stanu teksturowania zawiera tabela 14.4.
Aby zachowa biece parametry teksturowania, wywoaj funkcj glPushAttrib z para-
metrami GL_TEXTUR_BIT oraz GL_EVAL_BIT. Gdy wczasz teksturowanie, pa-
mitaj, aby wczy tylko jeden z dwch trybw - albo GL_TEXTURE_1D, albo
GL_TEXTURE_2D. Specyfikacja OpenGL wymaga, aby teksturowanie 2D zastpowao
teksturowanie ID, ale niektre implementacje nie speniaj tego zaoenia.
Tabela 14.4.
Zmienne stanu teksturowania
Tabela 14.4.
Zmienne stanu teksturowania - cig dalszy
Zmienna stanu Opis
W wyniku wywoa funkcji glEvalPointl,
GL_MAP1_TEXTURE_COORD_3 glEvalMeshl orazglEvalCoordl bd generowane
wsprzdne s, t oraz r tekstury.
W wyniku wywoa funkcji glEvalPointl,
GL_MAP 1_TEXTURE_COORD_4 glEvalMeshl orazglEvalCoordl bd generowane
wsprzdne s, t, r oraz q tekstury.
W wyniku wywoa funkcji glEvalPoint2,
glEvalMesh2 oraz glEvalCoord2 bdzie generowana
GL_MAP2_TEXTURE_COORD_1
wsprzdna s tekstury.
W wyniku wywoa funkcji glEvalPoint2,
g!Eva!Mesh2 oraz glEvalCoord2 bd generowane
GL_MAP2_TEXTURE_COORD_2
wsprzdne s i t tekstury.
W wyniku wywoa funkcji glEvalPoint2,
glEvalMesh2 oraz glEvalCoord2 bd generowane
GL_MAP2_TEXTURE_COORD_3
wsprzdne s, t oraz r tekstury.
W wyniku wywoa funkcji glEvalPoint2,
glEvalMesh2 oraz glEvalCoord2 bd generowane
GL_MAP2_TEXTURE_COORD_4 wsprzdne s, t, r oraz q tekstury.
Wczenie teksturowania ID, chyba e zostanie
wczone teksturowanie 2D.
GL_TEXTURE_1D
Wczenie teksturowania 2D.
GL_TEXTURE_2D Przy wywoaniach funkcji glVertex automatyczne
generowanie wsprzdnej q tekstury.
GL_TEXTURE_GEN_Q
Przy wywoaniach funkcji glVertex automatyczne
generowanie wsprzdnej r tekstury.
GL_TEXTURE_GEN_R
Przy wywoaniach funkcji glVertex automatyczne
generowanie wsprzdnej s tekstury.
GL_TEXTURE_GEN_S
Przy wywoaniach funkcji glVertex automatyczne
generowanie wsprzdnej t tekstury.
GL TEXTURE GEN T
Stan pikseli
Transfer pikseli, przechowywanie oraz tryby odwzorowania s najczciej najmniej
zrozumiaymi i najmniej zoptymalizowanymi elementami OpenGL. Do zachowania ich
stanu suy wywoanie glPusriAttrib(GL_PIXEL_BIT). Dla tych trybw nie ma zmiennych
ustawianych funkcjglEnable.
468 Cz III Tematy zaawansowane i efekty specjalne
Podrcznik
glDisable / glEnable
Przeznaczenie Wcza lub wycza wskazan opcj OpenGL.
Plik nagwkowy <gl.h>
Skadnia void glDisable(GLenum feature);
glEnable
Opis glDisable wycza wskazan opcj OpenGL. glEnable wcza wskazan
opcj OpenGL.
Parametry
feature GLenum: Opcja przeznaczona do wczenia lub wyczenia. Dostpne
opcje zebrano w tabeli 14.5.
Zwracana warto Brak.
Patrz take gllsEnabled, glPopAttrib, glPushArtrib
Tabela 14.5.
Opcje -wczane i wytaczane funkcjami glEnable i glDisable
Opcja Opis
Tabela 14.5.
Opcje wczane i wyczane funkcjami glEnable i glDisable - cig dalszy
Opcja Opis
W wyniku wywoa funkcji glEvalPointl, glEvalMeshl oraz
GL_MAP1_TEXTURE_COORD_4 glEvalCoordl bd generowane wsprzdne s, t, r oraz q tekstury.
W wyniku wywoa funkcji glEvalPoint2, glEvalMesh2 oraz
GL_MAP2_TEXTURE_COORD_1 glEvalCoord2 bdzie generowana wsprzdna s tekstury.
W wyniku wywoa funkcji glEvalPoint2, glEvalMesh2 oraz
GL_MAP2_TEXTURE_COORD_2 glEvalCoord2 bd generowane wsprzdne s i t tekstury.
W wyniku wywoa funkcji glEvalPoint2, glEvalMesh2 oraz
GL_MAP2_TEXTURE_COORD_3 glEvalCoord2 bd generowane wsprzdne s, t oraz r tekstury.
W wyniku wywoa funkcji glEvalPoint2, glEvalMesh2 oraz
GL_MAP2_TEXTURE_COORD_4 glEvalCoord2 bd generowane wsprzdne s, t, r oraz q tekstury.
Wczenie teksturowania l D, chyba e zostanie wczone
GL_TEXTURE_1D teksturowanie 2D.
Wczenie teksturowania 2D.
GL_TEXTURE_2D
Przy wywoaniach funkcji glVertex automatyczne generowanie
GL_TEXTURE_GEN_Q wsprzdnej q tekstury.
Przy wywoaniach funkcji glVertex automatyczne generowanie
GL_TEXTURE_GEN_R wsprzdnej r tekstury.
Przy wywoaniach funkcji glVertex automatyczne generowanie
GL_TEXTURE_GEN_S wsprzdnej s tekstury.
Przy wywoaniach funkcji glVertex automatyczne generowanie
GL_TEXTURE_GEN_T wsprzdnej t tekstury.
Test bufora szablonu.
GL_STENCIL_TEST
Test bufora gbokoci.
GL_DEPTH_TEST
Test wartoci alfa.
GL_ALPHA_TEST
Operacje mieszania kolorw pikseli.
GL_BLEND
Obcinanie prymityww poza okrelon paszczyzn obcinania.
GL_CLIP_PLANEx
Usuwanie wieloktw zwrconych tyem (lub przodem).
GL_CULL_FACE
Roztrzsanie kolorw.
GLJ3ITHER
Antyaliasing linii.
GL_LINE_SMOOTH
Rysowanie linii przerywanych.
GL_LINE_STIPPLE
Operacje logiczne na rysowanych pikselach.
GL_LOGIC_OP
Antyaliasing punktw.
GL_POINT_SMOOTH
Antyaliasing wieloktw.
GL_POLYGON_SMOOTH
Dese na wieloktach.
GL_POLYGON_STIPPLE
Obcinanie rysunku poza regionem glScissor.
GL SCISSOR TEST
470 Cz III Tematy zaawansowane i efekty specjalne
gllsEnabled
Przeznaczenie Plik Sprawdza, czy dana opcja OpenGL jest wczona.
nagwkowy
Skadnia Opis GLboolean gl!sEnabled(GLenum feature);
Ta funkcja zwraca warto GL_TRUE, jeli wskazana opcja jest
Parametry wczona, za warto GL_FALSE w przeciwnym wypadku.
feature
Zwracana warto GLenum: Sprawdzana opcja. Dostpne opcje zebrano w tabeli 14.5.
GLboolean: GLJTRUE, jeli dana opcja jest wczona, a GL_FALSE w
Patrz take przeciwnym wypadku.
glDisable, glEnable, glPopAttrib, glPushAttrib
glPopAttrib
Przeznaczenie Plik Odtwarza zmienne stanu zachowane uprzednio funkcj glPushAttrib.
nagwkowy
Skadnia Opis void glPopAttrib(void);
Parametry glPopAttrib odtwarza warto zmiennych stanu zachowanych uprzednim
wywoaniem funkcji glPushAttrib. Jeli stos atrybutw jest pusty,
Zwracana warto ustawiany jest znacznik bdu OpenGL, za samo wywoanie jest
Patrz take ignorowane.
Brak. Brak. glDisable, glEnable, gllsEnabled,
glPushAttrib
glPushAttrib
Przeznaczenie Odkada na stos zmienne stanu OpenGL.
Plik nagwkowy
Skadnia Opis void glPushAttrib(GLuint bits);
Ta funkcja zachowuje zmienne stanu OpenGL okrelone bitami parametru
bits. Jeli stos atrybutw jest peny, ustawiany jest znacznik bdu OpenGL,
za odkadane zmienne s umieszczane na szczycie stosu, zastpujc
istniejce tam dane.
1
Rozdzia 14. Maszyna stanu OpenGL_____________________________471
Parametry
bits GLuint: Zestaw zmiennych przeznaczonych do odoenia na stos (patrz
tabela 14.1).
! Zwracana warto Brak.
Patrz take glDisable, glEnable, gllsEnabled, glPopAttrib
Rozdzia 15.
Bufory: nie tylko
do animacji
W tym rozdziale:
Czym s bufory?
Bufor w OpenGL to w zasadzie dwuwymiarowa tablica wartoci powizanych z pikse-
lami okna lub bitmapy w pamici. Kady bufor zawiera t sam liczb kolumn i wierszy
474 Cz III Tematy zaawansowane i efekty specjalne
(ma t sam szeroko i wysoko) co obszar roboczy biecego okna, z tym e w buforze
przechowywane s dane innego rodzaju i z innego zakresu. Spjrz na rysunek 15.1.
Rysunek 15.1.
Organizacja
buforw w OpenGL
Konfigurowanie buforw
Zanim uyjesz OpenGL, musisz skonfigurowa kontekst urzdzenia okna (HDC), przy-
gotowujc wymagane bufory i tryb koloru. Te informacje zawiera struktura PIXEL-
FORMATDESCRIPTOR. Oto typowy sposb przygotowywania buforw:
// Ta struktura przechowuje informacje o buforach, warstwach i trybie //
koloru PIXELFORMATDESCRIPTOR pfd;
Pole bitowe dwFlags okrela, czy chcemy rysowa w oknie za pomoc OpenGL. Oprcz
tego informuje Windows o iloci buforw koloru, jakiej wymagamy. Spjrz na tabel 15.1.
Rozdzia 15. Bufory: nie tylko do animacji____________________________475
Tabela 15.1.
Znaczniki opcji w strukturze PKELFORMATDESCRIPTION
Znacznik Opis
PFD_DRAW_TO_W1NDOW Rysowanie w oknie.
PFD_DRAW_TO_BITMAP Rysowanie na bitmapie w pamici.
PFD_SUPPORT_GDI Bufor kolorw obsuguje funkcje GDI.
PFD_SUPPORT_OPENGL Bufor kolorw obsuguje polecenia OpenGL.
PFD_DOUBLEBUFFER Wartoci kolorw s podwjnie buforowane.
PFD_STEREO Dostpne s dwa zestawy buforw (lewy i
prawy).
PFD_DOUBLE_BUFFER_DONT_CARE Nie ma znaczenia, czy wartoci kolorw s
podwjnie buforowane.
PFD_STEREO_DONTCARE Nie ma znaczenia, czy obraz jest
stereoskopowy.
Pola dwLayerMask i iLayerType okrelaj plan rysowania, ktry ma zosta uyty, i zwykle
s ustawiane na PFD_MAIN_PLANE. Niektre karty graficzne OpenGL umoliwiaj
wykorzystywanie pomocniczych buforw pod lub nad normalnym planem kolorw
Windows, pozwalajc na tworzenie menu lub innych obiektw graficznych bez niszczenia
zawartoci gwnego planu. Oglna implementacja OpenGL w Windows nie obsuguje
pomocniczych planw rysunkowych.
Pole iPixelType okrela sposb reprezentowania wartoci kolorw i moe zawiera jedn
z dwch wartoci z tabeli 15.2.
Tabela 15.2.
Typypikseli
Tabela 15.3.
Znaczniki ustawiane przez funkcj ChoosePixelFormat
num_reds = (l p f d . cRedBits) - 1 ;
num_greens = (l pfd.cGreenBits) - 1;
num_blues = (l pfd.cBlueBits) -1;
for(blue = 0 , i = 0; blue <= num_blues; blue++)
for(green = 0; green <= num_greens; green++)
for(red = 0; red <= num_reds; red++) {
pal->palPalEntry[ i ] .peRed = 255 * red / num_reds; pal-
>palPalEntry[ i ] .peGreen = 255 * green / num_greens; pal-
>palPalEntry[ i ] .peBlue = 255 * blue / num_blues; pal-
>palPalEntry[ i ] .peFlags = 0; }
palette = CreatePalette( p a l ) ;
SelectPalettefhdc, palette, FALSE);
RealizePalette(hdc);
Bufor koloru
Bufor koloru przechowuje informacje o kolorze pikseli. Kady piksel moe zawiera indeks
koloru lub skadowe RGBA (red/green/lue/alpha) opisujce kolor danego piksela. Piksele
RGBA s wywietlane bezporednio przy uyciu najbliszego dostpnego koloru na
ekranie. Oglna implementacja OpenGL Microsoftu nie obsuguje obecnie skadowej koloru
alfa.
Wygld pikseli indeksu kolorw jest okrelany przez pobranie koloru RGB z pozycji
palety wyznaczonej przez dany indeks. W Windows palety s zaimplementowane jako
logiczne palety kolorw. Tryb indeksu koloru jest bardzo przydatny przy graficznej
reprezentacji danych tabelarycznych, na przykad miernikw siy lub natenia, co
przedstawimy w drugim przykadzie zastosowania bufora gbokoci, w sekcji Inne
zastosowanie bufora gbokoci".
Podwjne buforowanie
Podwjne buforowanie wykorzystuje dodatkowy bufor koloru w pamici, czsto uywany
w animacji. Przy podwjnym buforowaniu moesz narysowa ca scen w pa-
478______________________Cz III Tematy zaawansowane i efekty specjalne
mici, poza ekranem, a nastpnie szybko przerzuci" j na ekran, eliminujc w ten sposb
nieprzyjemne migotanie obrazu. Podwjne buforowanie wpywa jedynie na bufor
koloru; nie ma drugiego bufora dla gbokoci, szablonu czy akumulacji. Jeli wybie-
rzesz format pikseli z podwjnym buforowaniem, OpenGL wybierze do rysowania
tylny" bufor. Moesz zmieni to domylne zachowanie uywajc funkcji glDrawBuf-fer
z jednym z parametrw z tabeli 15.4.
Tabela 15.4.
Dostpne parametry funkcji glDrawBuffer
Bufor Opis
GL_FRONT OpenGL rysuje w przednim (widocznym) buforze.
GL BACK OpenGL rysuje w tylnym (niewidocznym) buforze.
GL_FRONT_AND_BACK OpenGL rysuje w obu buforach naraz.
Buforowanie stereo
Buforowanie stereo wykorzystuje dodatkowy bufor koloru w trybie pojedynczego bufo-
rowania oraz dwa dodatkowe bufory w trybie podwjnego buforowania, w celu prze-
chowania obrazu osobno dla lewego i prawego oka (tabela 15.5). Poprzez wygenerowanie
osobnych trjwymiarowych obrazw, przesunitych o kilka centymetrw" w stosunku do
siebie dla zasymulowania rozstawu oczu, mona wygenerowa prawdziwe trjwy-
miarowe obrazy. W przypadku wikszoci kart graficznych PC buforowanie stereo nie jest
jednak dostpne.
Oprcz wyboru przedniego lub tylnego bufora, za pomoc funkcji glDrawBuffer mona
wybra take bufor dla lewego lub prawego oka.
Tabela 15.5.
Bufory stereo
Bufor Opis
GL_LEFT_FRONT Rysowanie w lewym przednim buforze.
GL_LEFT_BACK Rysowanie w lewym tylnym buforze.
GL_RIGHT_FRONT Rysowanie w prawym przednim buforze.
GL_R1GHT_BACK Rysowanie w prawym tylnym buforze.
GL_FRONT Rysowanie w obu przednich buforach.
GL_BACK Rysowanie w obu tylnych buforach.
Przerzucanie buforw
OpenGL obsuguje podwjne buforowanie, lecz w samym OpenGL nie ma adnej funkcji
przerzucajcej zawarto przedniego i tylnego bufora! Na szczcie, w kadej im-
Rozdzia 15. Bufory: nie tylko do animacji___________________________479
gdzie hdc to kontekst urzdzenia okna, w ktrym rysujesz. Jeli wybrae format pikseli z
buforowaniem stereo, obrazy dla lewego i prawego oka s przerzucane jednoczenie.
Bufor gbokoci
Bufor gbokoci przechowuje warto gbokoci dla kadego piksela. Kada warto
reprezentuje odlego piksela od obserwatora, przeskalowan do biecej bryy obcinania, a
waciwie jej bliszej i dalszej paszczyzny. Programowa implementacja OpenGL w
Windows obsuguje zarwno 16-, jak i 32-bitowe wartoci bufora gbokoci.
Bufor gbokoci zwykle jest wykorzystywany w celu usuwania niewidocznych po-
wierzchni. Usuwanie niewidocznych powierzchni jest procesem, ktry w rzeczywistym
wiecie odbywa si w sposb naturalny; gdy nieprzezroczysty obiekt zostanie umie-
szczony przed innym obiektem, obiekt bliszy zasania cz lub cao obiektu lecego
dalej.
W OpenGL, bufora gbokoci mona uy w celu uzyskania interesujcych efektw,
takich jak na przykad usunicie przedniej czci obiektu w celu przedstawienia jego
wntrza.
Porwnywanie gbokoci
Gdy rysujesz w oknie posugujc si OpenGL, pozycja Z kadego piksela jest porwnywana
z wartoci w buforze gbokoci. Jeli wynik porwnania wynosi True, piksel, wraz ze
swoj gbokoci, jest umieszczany w buforze kolorw. OpenGL definiuje osiem
funkcji porwna wartoci w buforze gbokoci (tabela 15.6). Domyln funkcj
porwnania jest GL_LESS. Aby j zmieni, wywoaj funkcj glDepthFunction.
glDepthFunction(function);
Jeli jest uywana funkcja GL_LESS, piksele wielokta s rysowane wtedy, gdy warto
gbokoci piksela jest mniejsza ni warto piksela w buforze gbokoci (rysunki
15.2ail5.2b).
Tabela 15.6.
Funkcje porwnywania gbokoci
Nazwa Funkcja
Tabela 15.8.
Funkcje porwnywania gbokoci - cig dalszy
Nazwa Funkcja
Rysunek 15.2a.
Typowe dziaanie
bufora gbokoci
przy porwnaniach
GL LESS
Rysunek 15.2b.
Typowe dziaanie
bufora gbokoci
przy porwnaniach
GL GREATER
Rozdzia 15. Bufory: nie tylko do animacji___________________________481
Wartoci gbokoci
Gdy uywasz porwna gbokoci GL_EQUAL i GL_NOTEQUAL, czasem konieczna
jest zmiana zakresu wykorzystywanych wartoci gbokoci, w celu zredukowania liczby
dostpnych wartoci (zmniejszenia iloci wartoci do minimum). W tym celu moesz uy
funkcji glDepthRange:
glDepthRange(nera, f a r ) ;
/*
* Te definicje zostay wprowadzone w celu zapewnienia zgodnoci
* pomidzy MS Windows a reszt wiata.
*
* CALLBACK i APIENTRY to modyfikatory funkcji w MS Windows.
*/
ifndef WIN32
# define CALLBACK
# define APIENTRY
#endif /* IWIN32 */
/*
* 'reshape_scene () ' - Zmiana rozmiaru s c e n y . . .
*/
void CALLBACK
reshape_scene (GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glYiewport ( O , O, width, height);
glMatrixMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(22.5, (float) width / (float) height, 0.1, 1000.0);
glMatrixMode (GL_MODELVIEW) ;
/*
* 'draw_scene () ' - Rysowanie sceny zawierajcej kostk
* i przesaniajc j kul.
*/
Rozdzia 15. Bufory: nie tylko do animacji____________________________483
void CALLBACK
draw_scene(void)
{
static float red_light[4] = { 1 . 0 , 0 . 0 , 0 . 0 , 1 . 0 };
static float red_pos[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 0 . 0 };
static float blue_light[ 4 ] = { 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 };
static float blue_pos[4] = { - 1 . 0 , - 1 . 0 , - 1 . 0 , 0 . 0 );
/*
* Wczenie buforw i owietlenia
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTO);
glEnable(GL_LIGHT1);
glshadeModel(GL_SMOOTH);
glDepthFunc(depth_function);
/*
* Wyczyszczenie bufora koloru i gbokoci.
*/
if (depth_function == GL_LESS)
glClearDepth(l.O);
else
glClearDepth( 0 . 0 ) ;
glClearColor{ 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT l GL_DEPTH_BUFFER_BIT);
/*
* Rysowanie kostki i kuli w rnych kolorach
*
* W scenie umiecilimy dwa wiata. Pierwsze z nich jest czerwone
* i zostao umieszczone u gry z prawej strony, za obserwatorem.
* Drugie jest niebieskie i znajduje si u dou po lewej stronie,
* przed obserwatorem.
*/
glLightfv(Gt_LIGHTO, GL_DIFFUSE, red_light);
glLightfv(GL_LIGHTO, GL_POSITION, red_pos);
glPushMatrix();
glTranslatef(-1.0, 0 . 0 , -20.0);
auxSolidSphere(1.0) ;
glPopMatrix() ;
glPushMatrix();
glTranslatef( 1 . 0 , 0.0, -20.0);
glRotatef(15.0, 0.0, 1 . 0 , 0 . 0 ) ;
glRotatef(15.0, 0 . 0 , 0 . 0 , 1 . 0 ) ;
auxSolidCube( 2 . 0 ) ;
glPopMatrix();
484 ______________________ Cz III Tematy zaawansowane i efekty specjalne
glFlushO ;
/*
* ' toggle_depth() ' - Przecza porwnywanie gbokoci pomidzy
* funkcjami GL_LESS i GL_GREATER.
*/
V0id CALLBACK
toggle_depth (void)
{
if (depth_function == GL_LESS)
depth_function = GL_GREATER;
else
depth_function = GL_LESS;
/*
* ' m a i n ( ) ' - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza ' E s c ' .
*/
void
main(void)
(
aUKlnitDisplayMode (AOX_RGB | AUX_SINGLE | AUX_DEPTH) ;
auxlnitwindow( "Funkcje gbokoci") ;
auxKeyFunc (AUX_d, toggle_depth) ;
auxReshapeFunc (reshape_scene) ;
auxMainLoop (draw_scene) ;
// Rysowanie sceny...
glEnable(GL_DEPTH_TEST);
glColor3i(0, O, 0);
glBegin(GL_POLYGON);
glVertex3f(-100.0, 100.0, cutting_plane);
glVertex3f( 1 0 0 . 0 , 100.0, cutting_plane);
glVertex3f(100.0, -100.0, cutting_plane);
glVertex3f( - 1 0 0 . 0 , -100.0, cutting_plane);
glEnd();
glDrawBuffer(GL_BACK);
Listing 15.2. Uycie funkcji glDrawBuffer w celu wycicia wy branych fragmentw obiektw__
/*
* Te definicje zostay wprowadzone w celu zapewnienia zgodnoci
* pomidzy MS Windows a reszt wiata.
*
/*
* ' reshape_scene ( ) ' - Zmiana rozmiaru s c e n y . . .
*/
void CALLBACK
reshape_scene (GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glviewport ( O , O, width, height);
glMatrixMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(22.5, (float)width / (float)height, 0 . 1 , 1 0 0 0 . 0 ) ;
glMatrixMode (GL_MODELVIEW) ;
/*
* 'draw_scene ( ) ' - Rysowanie sceny zawierajcej kostk
* i przesaniajc j kul.
*/
void CALLBACK
draw_scene (void)
{
static float red_light[4] = ( 1 . 0 , 0 . 0 , 0 . 0 , 1.0 };
static float red_pos[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 0.0 };
static float blue_light [ 4 ] = { 0.0, 0 . 0 , 1 . 0 , 1.0 };
static float blue_pos[4] = { -1.0, -1.0, -1.0, 0.0 };
Rozdzia 15. * Bufory: nie tylko do animacji___________________________487
/*
* Wczenie buforw i owietlenia
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTO);
glEnable(GL_LIGHTl);
glShadeModel(GL_SMOOTH);
glDepthFunc(depth_function);
/*
* Wyczyszczenie bufora koloru i gbokoci.
*/
if (depth_function == GL_LESS)
glClearDepth(l.O);
else
glClearDepth( 0 . 0 ) ;
glClearColor( 0 . 0 , 0 . 0 , 0.0, 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Rysowanie paszczyzny cicia. Zwr uwag, e na ten czas
* wyczamy zwykle rysowanie w buforze koloru...
*/
glDrawBuffer(GL_NONE);
glColor3i(0, O, 0);
glBegin(GL_POLYGON);
glVertex3f( - 1 0 0 . 0 , 100.0, cutting_plane);
glVertex3f( 1 0 0 . 0 , 100.0, cutting_plane);
glVertex3f( 1 0 0 . 0 , -100.0, cutting_plane);
glVertex3f(-100.0, -100.0, cutting_plane);
glEnd();
g!DrawBuffer(GL_BACK);
/*
* Rysowanie kostki i kuli w rnych kolorach
*
* W scenie umiecilimy dwa wiata. Pierwsze z nich jest czerwone
* i zostao umieszczone u gry z prawej strony, za obserwatorem.
* Drugie jest niebieskie i znajduje si u dou po lewej stronie,
* przed obserwatorem.
*/
glLightfv(GL_LIGHTO, GL_DIFFUSE, red_light);
glLightfv(GL_LIGHTO, GL_POSITION, red_pos);
glPushMatrix();
glTranslatef (-1.0, 0.0, -20.0);
auxSolidSphere( 1 . 0 ) ;
glPopMatrix();
488 _______________________ Cz III Tematy zaawansowane i efekty specjalne
glPushMatrix ( ) ;
glTranslatef ( 1 . 0 , 0 . 0 , -20.0);
glRotatef ( 1 5 . 0 , 0 . 0 , 1 . 0 , 0 . 0 ) ;
glRotatef (15.0, 0 . 0 , 0.0, 1 . 0 ) ;
auxSolidCube ( 2 . 0 ) ;
glPopMatrix() ;
auxSwapBuf f ers ( ) ;
/*
* ' toggle_depth () ' - Przecza porwnywanie gbokoci pomidzy
* funkcjami GL_LESS i GL_GREATER.
*/
V0id CALLBACK
toggle_depth (void) {
if (depth_function == GL_LESS)
depth_function = GLJ3REATER; else
depth_function = GL_LESS;
/*
* 'move_plane ( ) ' - W wolnym czasie przesuwanie paszczyzny cicia.
*/
void CALLBACK
move_plane (void) {
cutting_plane += cutting_dir;
/*
* W miar potrzeby zmiana kierunku...
*/
/*
* ' m a i n ( ) ' - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza ' E s c ' .
*/
void main( ) {
aux!nitDisplayMode(AOX_RGB | AUX_DOUBLE | AOX_DEPTH) ;
auxlnitwindow ( "Depth Function") ;
auxMainLoop(draw_scene) ;
/*
* Koniec pliku "depthcut . c "
*/
Bufor szablonu
Bufor szablonu suy do ograniczenia rysowania na okrelonych obszarach ekranu i ma
wiele zastosowa, do ktrych bufor gbokoci po prostu si nie nadaje. W najpro-
stszym przypadku, bufora szablonu mona uy do zablokowania pewnych obszarw
ekranu. Na przykad, w programie symulatora lotu mona wykorzysta bufor szablonu do
ograniczenia operacji rysunkowych do wntrza okrgych wskanikw w kokpicie, takich
jak sztuczny horyzont czy wskanik wysokoci.
Gdy zadasz utworzenia bufora szablonu, musisz jeszcze wczy uywanie szablonu,
wywoujc w tym celu funkcj glEnable(GL_STENCIL_TEST). Bez tego wywoania,
bufor szablonu nie zostaby w ogle uwzgldniony.
Tabela 15.7.
Funkcje bufora szablonu
Funkcja Opis
GL_NEVER Zawsze False (zablokowanie rysowania).
GL_LESS True, jeli warto odniesienia < warto szablonu.
GL_LEQUAL True, jeli warto odniesienia <= warto szablonu.
GL_GREATER True, jeli warto odniesienia > warto szablonu.
GL_GEQUAL Truejeli warto odniesienia >= warto szablonu.
GL_EQUAL True, jeli warto odniesienia = warto szablonu.
GL_NOTEQUAL True, jeli warto odniesienia != warto szablonu.
GL_ALWAYS Zawsze True (mona rysowa bez ogranicze).
Tabela 15.8.
Operacje szablonu
Operacja Opis
GL_KEEP Pozostawiana jest bieca zawarto bufora szablonu.
GL_ZERO Zawarto bufora szablonu jest zerowana.
GL_REPLACE Zawarto bufora szablonu jest zastpowana wartoci odniesienia.
Rozdzia 15. Bufory: nie tylko do animacji____________________________491
Tabela 15.8.
Operacje szablonu - cig dalszy
Operacja Opis
GL_INCR Zawarto bufora szablonu jest inkrementowana.
GL_DECR Zawarto bufora szablonu jest dekrementowana.
GL_INVERT Zawarto bufora szablonu jest negowana bitowo.
Zwykle obraz maski jest uywany do okrelenia obszaru, w ktrym bdzie dozwolone
rysowanie. Oto przykad przygotowania do rysowania maski w buforze szablonu:
glStencilFunc(GL_ALWAYS, l, 1); glStencilOp(GL_REPLACE,
GL_REPLACE, GL_REPLACE);
glPushMatrix();
glTranslatef( -1 . 0 , 0 . 0 , - 2 0 . 0 ) ;
auxSolidSphere( 1 . 0 ) ;
glPopMatrix();
glPushMatrix();
glTranslatef( 1 . 0 , 0 . 0 , - 2 0 . 0 ) ;
glRotatef(15.0, 0.0, 1.0, 0 . 0 ) ;
glRotatef(15.0, 0.0, 0.0, 1 . 0 ) ;
auxSolidCube( 2 . 0 ) ;
glPopMatrix();
492_______________________Cz III Tematy zaawansowane i efekty specjalne
/*
* "stencilct. c " - Testowy program demonstrujcy uycie funkcji
* glStencilFunc() i glStencilOp() w celu wycicia fragmentw sceny.
*/
ttinclude <GL/glaux.h>
/*
* Te definicje zostay wprowadzone w celu zapewnienia zgodnoci
* pomidzy MS Windows a reszt wiata.
*
* CALLBACK i APIENTRY to modyfikatory funkcji w MS Windows.
*/
ttifndef WIN32
# define CALLBACK
# define APIENTRY
#endif /* 1WIN32 */
/*
* 'reshape_scene()' - Zmiana rozmiaru s c e n y . . .
*/
void CALLBACK
reshape_scene(GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ ( /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glYiewport( O , O, width, h eight);
glMatrixMode(GL_PROJECTION);
glLoadldentity();
gluPerspective(22.5, (float)width / (float)height, 0 . 1 , 1 0 0 0 . 0 ) ;
glMatrixMode(GL_MODELVIEW);
/*
* 'draw_scene()' - Rysowanie sceny zawierajcej kostk i
* przesaniajc j kul.
*/
void CALLBACK
draw_scene(void)
{
static float red_light[4] = { 1 . 0 , 0 . 0 , 0 . 0 , 1 . 0 };
static float red_pos[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 0 . 0 };
static float blue_light[ 4 ] = { 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 };
static float blue_pos[4] = { - 1 . 0 , - 1 . 0 , - 1 . 0 , 0 . 0 };
Rozdzia 15. Bufory: nie tylko do
animacji____________________________493
/*
* Wczenie buforw i owietlenia
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_STENCIL_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTO);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
/*
* Wyczyszczenie bufora koloru, szablonu i gbokoci.
*/
glClearColor( 0 . 0 , 0 . 0 , 0.0, 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT |
GL_STENCIL_BUFFER_BIT);
/*
* Rysowanie kuli, ktra wytnie cz k o s t k i . . .
*/
glstencilFunc(GL_ALWAYS, l, 1 ) ; glStenci!Op(GL_REPLACE,
GL_REPLACE, GL_REPLACE);
glPushMatrix();
glTranslatef (-1.0, 0 . 0 , -20.0);
auxSolidSphere( 1 . 0 ) ;
glPopMatrix();
/*
* Ponowne wyczyszczenie bufora koloru i gbokoci...
*/
glClearColor( 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Rysowanie kostki w rnych kolorach
*k
glPushMatrix();
glTranslatef( 1 . 0 , 0 . 0 , - 2 0 . 0 ) ;
glRotatef(15.0, 0 . 0 , 1 . 0 , 0 . 0 ) ;
494_______________________Cz III Tematy zaawansowane i efekty specjalne
glRotatef( 15 .0 , 0 . 0 , 0 . 0 , 1 . 0 ) ;
auxSolidCube ( 2 . 0 ) ; glPopMatrix();
auxSwapBuffers();
/*
* 'mainO' - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza 'Esc'.
*/
void main() {
aux!nitDisplayMode(AUX_RGB | AUX_DOUBLE | AUX_DEPTH l AUX_STENCIL) ,
auxlnitwindow("Rysowanie od szablonu");
auxReshapeFunc(reshape_scene);
auxMainLoop(draw_scene);
/*
* Koniec pliku "stencilct.c".
*/
Bufor akumulacji
Bufor akumulacji umoliwia uzyskanie wiele efektw specjalnych, takich jak na przykad
rozmycie ruchu. Posugujc si nim, mona przeprowadza penoekranowy anty-aliasing,
cho lepiej nadaj si do tego raczej inne metody, choby multisampling.
Tabela 15.9.
Operacje akumulacji
Operacja Opis
draw_frame (-i) ;
glAccum(GL_ACCUM, 0 . 0 5 ) ; >;
Zwr uwag, e w celu zainicjowania zawartoci bufora akumulacji nie trzeba uywa
funkcji glClear, tak jak to byo konieczne w przypadku buforw koloru, gbokoci i
szablonu. Zamiast niej, zwykle bdziesz stosowa funkcj glAccum(GL_LOAD, s) w
odniesieniu do pierwszej klatki sceny. Rozmycie ruchu dla kuli i kostki demonstruje
program z listingu 15.4.
496 _______________________ Cz III Tematy zaawansowane i efekty specjalne
Listing 15.4. MOTION.C: Rozmycie ruchu przy uyciu bufora akumulacji ___________________
/*
* "motion.c" - Testowy program demonstrujcy uycie funkcji glAccumO
* dla uzyskania efektu rozmycia ruchu.
*/
tinclude <GL/glaux.h>
/*
* Te definicje zostay wprowadzone w celu zapewnienia zgodnoci
* pomidzy MS Windows a reszt wiata.
Tt
ifndef WIN32
# define CALLBACK
# define APIENTRY
#endif /* 1WIN32 */
GLfloat rotation = 0 . 0 ;
/*
* ' reshape_scene ( ) ' - Zmiana rozmiaru s c e n y . . .
*/
void CALLBACK
reshape_scene (GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glViewport ( O , O, width, height);
glMatriKMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(22.5, (float) width / (f loat) height, 0 . 1 , 1000.0);
glMatrixMode (GL_MODELVIEW) ;
/*
* 'draw_scene ( ) ' - Rysowanie sceny zawierajcej kostk
* i przesaniajc j kul.
*/
void CALLBACK
draw_scene (void) {
GLfloat f ram;
static float red_light[4] = { 1.0, 0.0, 0.0, 1.0 };
static float red_pos[4] = { 1.0, 1.0, 1.0, 0.0 };
static float blue_light [4] = { 0.0, 0.0, 1.0, 1.0 };
static float blue_pos[4] = { -1.0, -1.0, -1.0, 0 . 0 };
Rozdzia 15. Bufory: nie tylko do animacji___________________________497
/*
* Wczenie buforw i owietlenia
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTO);
glEnable(GL_LIGHT1);
glShadeModel(GL_SMOOTH);
/*
* Wyczyszczenie bufora koloru i gbokoci.
*/
glClearColor( 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/*
* Rysowanie kostki i kuli w rnych kolorach
*
* W scenie umiecilimy dwa wiata. Pierwsze z nich jest czerwone
* i zostao umieszczone u gry z prawej strony, za obserwatorem.
* Drugie jest niebieskie i znajduje si u dou po lewej stronie,
* przed obserwatorem.
*/
glLightfv(GL_LIGHTO, GL_DIFFOSE, red_light);
glLightfv(GL_LIGHTO, GL_POSITION, red_pos);
/*
* Rysowanie obiektw 11 razy, poczwszy od biecego kta obrotu...
*/
for (fram = 0 . 0 ; fram <= 1 1 . 0 ; fram ++) {
glPushMatrix();
glTranslatef( 0 . 0 , 0 . 0 , - 2 0 . 0);
glRotatef(rotation - frame, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glPushMatrix();
glTranslatef(-1.O, 0 . 0 , 0 . 0 ) ;
auxSolidSphere( 1 . 0 ) ;
glPopMatrix();
glPushMatrix();
glTranslatef( 1 . 0 , 0. 0 , 0 . 0 ) ;
glRotatef(15.0, 0.0, 1.0, 0 . 0 ) ;
glRotatef(15.0, 0.0, 0.0, 1 . 0 ) ;
auxSolidCube( 2 . 0 ) ; glPopMatrix();
glPopMatrix();
/*
* Akumulacja 50% pierwszej klatki i po 5% dla nastpnych
*/
498_______________________Cz III Tematy zaawansowane i efekty specjalne
if (fram == 0 . 0 )
glAccum(GL_LOAD, 0 . 5 ) ;
else
glAccum(GL_ACCUM, 0 . 0 5 ) ;
>;
/*
* Skopiowanie zakumulowanego wyniku do bufora k o l o r u . . . V
g!Accum(GL_RETORN, 1 . 0 ) ;
auxSwapBuffers();
/*
* ' rotate_objects ( ) ' - W wolnych chwilach obrt s c e n y . . .
*/
void CALLBACK
rotate_objects (void)
{
rotation += 2 . 0 ;
if (rotation >= 3 6 0 . 0 )
rotation -= 3 6 0 . 0 ;
draw_scene ( ) ;
/*
* ' m a i n O ' - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza ' E s c 1 .
*/
void main( ) {
aux!nitDisplayMode(AUX_RGB | AUX_DOUBLE | AUX_DEPTH | AUX_ACCOM) ;
auxlnitwindow( "Rozmycie ruchu") ;
auxReshapeFunc (reshape_scene) ;
auxIdleFunc (rotate_objects) ;
auxMainLoop(draw_scene) ;
/*
* Koniec pliku " m o t i o n . c " .
*/
Podrcznik
glAccum
Przeznaczenie Steruje dziaaniem bufora akumulacji.
Plik
nagwkowy void glAccum(GLenum func, GLfloat value);
Skadnia Opis Ta funkcja steruje buforem akumulacji. Z wyjtkiem operacji
GL_RETURN, wartoci koloru s skalowane przez parametr value i
dodawane lub umieszczane w buforze akumulacji. W przypadku
operacji GL_RETURN, wartoci kolorw z bufora akumulacji s
skalowane przez parametr value i umieszczane w biecym buforze
koloru.
Paramet
ry GLenum: Operacja na buforze akumulacji. Dostpne s nastpujce
operacje:
GL_ACCUM Dodaje przeskalowane wartoci z bufora koloru do
wartoci w buforze akumulacji.
GL_LOAD aduje przeskalowane wartoci z bufora koloru do
bufora akumulacji, zastpujc przechowywane w nim
dotd wartoci.
GL_ADD Dodaje sta warto koloru do wartoci w buforze
akumulacji.
GL_MULT Mnoy wartoci w buforze akumulacji przez sta
warto koloru (efekt filtrowania).
GL_RETURN K opiuje zawarto bufora akumulacji do gwnego
bufora koloru.
500 Cz III Tematy zaawansowane i efekty specjalne
glCIearColor
Przeznaczenie Plik Okrela warto uywan do czyszczenia bufora koloru.
nagwkowy
Skadnia void glClearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat
alpha);
Opis Ta funkcja ustawia warto koloru, uywan podczas czyszczenia bufora
koloru funkcj glClear(GL_COLOR_BUFFER_BIT).
Parametry
red GLfloat: Czerwona skadowa koloru czyszczenia bufora.
green GLfloat: Zielona skadowa koloru czyszczenia bufora.
blue GLfloat: Niebieska skadowa koloru czyszczenia bufora.
alpha GLfloat: Skadowa alfa koloru czyszczenia bufora.
Zwracana warto Brak.
Patrz take ChoosePixelFormat, SetPixelFormat
glCIearDepth
Przeznaczenie Plik Okrela warto uywan do czyszczenia bufora gbokoci.
nagwkowy
Skadnia Opis void glClearDepth(GLclampd depth);
Ta funkcja ustawia warto gbokoci, uywan podczas czyszczenia
Parametry bufora gbokoci funkcj glClear(GL_DEPTH_BUFFER_BIT).
depth
Zwracana warto GLclampd: Warto czyszczenia bufora gbokoci.
Patrz take Brak.
ChoosePixelFormat, SetPixelFormat
Rozdzia 15. Bufory: nie tylko do animacji 501
glClearlndex
Przeznaczenie Okrela warto uywan do czyszczenia bufora koloru.
Plik nagwkowy <gl.h>
Skadnia void glClear!ndex(GLfloat index);
Opis Ta funkcja ustawia indeks koloru, uywany podczas czyszczenia bufora
kolorw funkcj glClear(GL_COLOR_BUFFER_BIT).
Paramet
ry GLfloat: Indeks koloru czyszczenia bufora koloru.
Zwracana warto Brak.
Patrz take ChoosePixelFormat, SetPixelFormat
glClearStencil
Przeznaczenie Okrela warto uywan do czyszczenia bufora szablonu.
Plik
nagwkowy void glClearStencil(GLint value);
Skadnia Opis Ta funkcja ustawia warto uywan podczas czyszczenia bufora
szablonu funkcj glClear(GL_STENCIL_BUFFER_BIT).
Parametry
value GLint: Warto czyszczenia bufora szablonu.
Zwracana Brak.
warto Patrz ChoosePixelFormat, SetPixelFormat
gIDrawBuffer
Przeznaczenie Wybiera bufor przeznaczony do rysowania.
Plik
nagwkowy void glDrawBuffer(GLenum mod);
Skadnia Opis Ta funkcja suy do wyboru bufora, do ktrego bd si odnosi nastpne
operacje rysunkowe. Zwykle jest uywana do wyboru przedniego lub
tylnego bufora przy podwjnym buforowaniu.
502 Cz III Tematy zaawansowane i efekty specjalne
Parametry
mod Glenum: Staa (patrz tabela 15.10) okrelajca bufor, ktry ma zosta
wykorzystany. Na przykad, aby wybra do rysowania tylny bufor, uyj
Zwracana warto
wywoania:
Znane bdy glDrawBuffer(GL_BACK);
Brak.
Przykad
Oglna implementacja Microsoftu nie obsuguje buforw stereo ani
Patrz take parametru mod rwnego GL_NONE.
Kod programu DEPTHCUT.C na pytce CD-ROM.
ChoosePixelFormat, SetPixelFormat
Tabela 15.10.
Dostpne tryby w wywoaniu funkcji glDrawBuffer
Bufor Opis
glDepthFunc
Przeznaczenie Wybiera funkcj porwnywania dla bufora gbokoci.
Plik nagwkowy <gl.h>
Skadnia void glDepthFunc(GLenum func);
Rozdzia 15. Bufory: nie tylko do animacji 503
glDepthRange
Przeznaczenie Ustawia zakres wartoci przechowywanych w buforze gbokoci.
Plik
nagwkowy void glDepthRange(GLclampd near, GLclampd far);
Skadnia Opis Ta funkcja ustala zakres wartoci przechowywanych w buforze
gbokoci, uywanych przy porwnaniach gbokoci w celu usuwania
niewidocznych powierzchni. Parametr near moe by wikszy ni/ar.
Parametry
near GLclampd: Blisza warto gbokoci.
far GLclampd: Dalsza warto gbokoci.
Zwracana Brak.
warto Kod programu DEPTH.C na pytce CD-ROM.
Przykad Patrz ChoosePixelFormat, SetPixelFormat
Rozdzia 16.
Efekty
specjalne:
przezrocz
ysto i
mga
W tym rozdziale:
Dowiesz si, jak... Uywane funkcje
* Wywietla przezroczyste linie i wielokty. * glBlendFunc
* Stworzy efekt pyu lub mgy + glFog
Blending
Blending (czenie kolorw) w OpenGL
polega na kontrolowaniu wartoci
RGBA poszczeglnych pikseli w scenie na
podstawie pikseli ju istniejcych. Operacje
czenia kolorw nie s dostpne w trybie
indeksu kolorw.
Tabela 16.1.
Funkcje czenia koloru rdowego
GL_ZERO
GL_DST_ALPHA
GL_ONE
GLJ)ST_COLOR GL_ONE_MINUS _DST_ALPHA GL SRC ALPHA SATURATE
GL_ONE_MINUS_DST_COLOR
GL_SRC_ALPHA
GL_ONE_MINUS_SRC_ALPHA
Kolor rdowy = O, O, O, 0. Kolor rdowy jest mnoony przez rdow skadow alfa.
Uywa <?> koloru rdowego. Kolor rdowy jest mnoony przez (l - rdowa skadowa alfa).
Kolor rdowy jest mnoony przez Kolor rdowy jest mnoony przez docelow skadow alfa.
Nieobsugiwane w Microsoft OpenGL.
kolor piksela docelowego.
Kolor rdowy jest mnoony przez (l - docelowa skadowa alfa).
Kolor rdo wy jest mnoony Nieobsugiwane w Microsoft OpenGL.
przez (l, l, l, l, l - kolor docelowy). Kolor rdowy jest mnoony przez mniejsz z wartoci: rdow
skadow alfa i (l - docelowa skadowa alfa). Nieobsugiwane w
Microsoft OpenGL.
Tabela 16.2.
Funkcje czenia koloru docelowego
Poniewa uywana jest jedynie rdowa skadowa alfa, nie musisz posiada karty prze-
chowujcej w buforze koloru take bity kanau alfa. To jest wane, gdy standardowa
implementacja OpenGL Microsoftu nie obsuguje kanau alfa w buforze koloru.
Rysunek 16.1.
Przezroczysty imbryk do
herbaty narysowany przy
uyciu czenia kolorw
508 ______________________ Cz III Tematy zaawansowane i efekty specjalne
Pierwsz rzecz, jak robimy w funkcji draw_scene, jest wczenie mieszania kolorw w
celu osignicia przezroczystoci na podstawie wartoci alfa koloru rysowania
(rdowego):
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) ;
Listing 16.1. BLENDPOT.C: uycie funkcji glBlendFunc \v celu stworzenia efektu przezroczystoci _____
#ifndef WIN32
define CALLBACK
# define APIENTRY
ttendif /* 1WIN32 */
GLfloat rotation = 0 . 0 ;
/*
* 'reshape_scene () ' - Zmiana rozmiaru s c e n y . . .
*/
Rozdzia 16. * Efekty specjalne: przezroczysto i mga____________________509
void CALLBACK
reshape_scene(GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
giviewport( O , O, width, h e i g h t ) ;
glMatrixMode(GL_PROJECTION);
glLoadldentity();
gluPerspective(22.5, (float)width / (float)height, 0 . 1 , 1000.0);
glMatrixMode(GL_MODELVIEW);
/*
* 'draw_scene()' - Rysowanie sceny zawierajcej dwa imbryki do
* herbaty
*/
void CALLBACK
draw_scene(void)
{
GLfloat frame;
static float red_light[4] = ( 1 . 0 , 0 . 0 , 0 . 0 , 1 . 0 };
static float red_pos[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 0 . 0 };
static float blue_light[ 4 ] = { 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 };
static float blue_pos[4] = { - 1 . 0 , - 1 . 0 , - 1 . 0 , 0 . 0 };
/*
* Wczenie buforw i owietlenia
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHTO);
glEnable(GL_LIGHTl);
glShadeModel(GL_SMOOTH);
/*
* Wyczyszczenie bufora koloru i gbokoci.
*/
glClearColor(0.0, 0.0, 0.0, 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BOFFER_BIT);
/*
* W scenie umiecilimy dwa wiata. Pierwsze z nich jest czerwone
* i zostao umieszczone u gry z prawej strony, za obserwatorem.
* Drugie jest niebieskie i znajduje si u dou po lewej stronie,
* przed obserwatorem.
*/
glLightfv(GL_LIGHTO, GL_DIFFUSE, red_light);
glLightfv(GL_LIGHTO, GL_POSITION, red_pos);
510_______________________Cz III Tematy zaawansowane l efekty specjalne
glEnable(GL_COLOR_MATERIAL);
g!BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glPushMatrix();
glTranslatef( 0 . 0 , 0 . 0 , - 1 5 . 0 ) ;
glRotatef(-rotation, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glDisable(GL_BLEND);
glColor3f( 1 . 0 , 1 . 0 , 0 . 0 ) ;
auxSolidTeapot( 1 . 0 ) ;
glPopMatrix();
glPushMatrix();
glTranslatef( 0 . 0 , 0 . 0 , - 1 0 . 0 ) ;
glRotatef(rotation, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glEnable(GL_BLEND); glColor4f( 1 . 0 ,
1.0, 1.0, 0.25);
auxSolidTeapot( 1 . 0 ) ; glPopMatrix();
auxSwapBuffers();
/*
* ' rotate_objects ( ) ' - w wolnych chwilach obrt s c e n y . . .
*/
void CALLBACK
rotate_objects (void) {
rotation += 2 . 0 ;
if (rotation >= 3 6 0 . 0 )
rotation -= 3 6 0 . 0 ;
draw_scene ( ) ;
/*
* ' m a i n f ) 1 - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza ' E s c ' .
*/
void
main (void)
{
auxInitDisplayMode (AUX_RGB | AUX_DOUBLE | AUX_DEPTH) ;
auxlnitwindow( "Przezroczysty imbryk do h e r b a t y " ) ;
auxReshapeFunc (reshape_scene) ;
aux!dleFunc(rotate_objects) ;
auxMainLoop (draw_scene) ;
Rozdzia 16. Efekty specjalne: przezroczysto i mga_____________________511
/*
* Koniec pliku "blendpot. c " .
*/
Rysunek 16.2.
Rysunek wykonany pdzlem "
wykorzystujcym obraz alfa
To znaczy, wartoci alfa z obrazu pdzla zostan uyte zamiast biecych wartoci alfa
rysowanych pikseli.
Listing 16.2 przedstawia prosty program malarski" uywajcy do rysowania obrazu
pdzla o rozmiarach 7 x 7 pikseli. Gwna ptla komunikatw obsuguje rysowanie w
oknie. Gdy przytrzymasz lewy przycisk myszy, zostanie wywoana funkcja DrawXY,
rysujca obraz pdzla w biecym pooeniu myszy:
glRasterPos2i(mousex, mousey);
glDrawPixels(7, 7, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
*BlendBrush[0] ) ;
Funkcja RepaintWindow czyci obszar roboczy okna za kadym razem, gdy okno zmieni
rozmiar lub wymaga odwieenia:
glViewport( O , O, rect->right, rect->bottom);
glOrtho(0.0, (float)rect->right, (float)rect->bottom, 0 . 0 , -1.0,
1.0);
glClearColor(0.0, 0 . 0 , 0 . 0 , 1 . 0 ) ;
glColorMask(GL_TRUE, GLJTRUE, GLJTRUE, GLJTRUE) ;
glClear(GL_COLOR_BUFFER_BIT);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
"Sld$"
Contents:
WinMainO - Gwne w e j c i e . . .
DisplayErrorMessage () - Wywietla okno komunikatu
bdu.
MakePalette () - Tworzy palet kolorw RGB.
BlendProcO - Obsuguje komunikaty okna widoku.
RepaintWindow () - Odrysowuje obszar roboczy okna.
DrawKY ( ) - Rysuje w obszarze roboczym.
Revision History:
$Log$
Rozdzia 16. Efekty specjalne: przezroczysto i mga_____________________513
/*
* Niezbdne nagwki.
*/
flinclude <windows.h>
tfinclude <GL/gl.h>
#include "blendraw.h"
tfinclude <stdarg.h>
include <math.h> tfifndef
M_PI
# define M_PI (double)3.14159265358979323846
#endif /* !M_PI */
/*
* Zmienne globalne...
*/
HWND BlendWindow; /* Okno rysunku */
HPALETTE BlendPalette; /* Paleta kolorw (jeli potrzebna) */
HDC BlendDC; /* Kontekst rysowania */
HGLRC BlendRC; /* Kontekst renderowania OpenGL */
/*
* Funkcje lokalne...
*/
void DisplayErrorMessage(char *, .. . ) ;
void MakePalette( i n t ) ;
LRESULT CALLBACK BlendProc(HWND, UINT, WPARAM, LPARAM);
void DrawXY(int, int);
void RepaintWindow(RECT * ) ;
/*
* 'WinMainO ' V
514 ______________________ Cz III Tematy zaawansowane l efekty specjalne
int APIENTRY
WinMain(HINSTANCE hlnst,
HINSTANCE hPrev!nstance, LPSTR
IpCmdLine, int nCmdShow) {
MSG msg;
WNDCLASS we;
POINT pos; /* Bieca pozycja myszy */
w e . style = 0;
wc.lpfnWndProc = (WNDPROC) BlendProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hlnstance = hlnst;
wc.hlcon = NULL;
wc.hCursor = LoadCursor (NULL, IDC_ARROW) ;
wc.hbrBackground = 0;
wc.lpszMenuName = MAKEINTRESOURCE (IDR_MENU1) ;
wc.lpszClassName = "Blend Paint";
if (RegisterClass (Swe) == 0) {
DisplayErrorMessage ( " N i e udao si zarejestrowanie o k n a ! " ) ;
return ( F A L S E ) ;
if (Blendwindow == NULL) {
DisplayErrorMessage ( " N i e udao si stworzenie o k n a ! " ) ;
return (FALSE);
return (msg.wParam) ;
/*
* ' DisplayErrorMessage ( ) ' - Wywietla okno komunikatu bdu.
*/
Rozdzia 16. Efekty specjalne: przezroczysto i mga ____________________ 515
i f (format == NULL)
return;
/*
* 'MakePalette () ' - Jeli trzeba, tworzy palet kolorw.
*/
void
MakePalette (int p f ) /* We - ID formatu pikseli */
{
PIXELFORMATDESCRIPTOR pfd;
LOGPALETTE *pPal;
int nColors;
int i,
rmax,
gmax,
bmax
;
/*
* Sprawdzenie, czy paleta jest potrzebna. . .
*/
DescribePixelFormat (BlendDC, pf, sizeof (PIKELFORMATDESCRIPTOR) ,
if ( ! (pfd.dwFlags i PFD_NEED_PALETTE) ) {
BlendPalette = NULL;
return;
/*
* Alokowanie pamici dla palety.
*/
nColors = l pfd.cColorBits;
pPal->palVersion = 0x300;
pPal->palNumEntries = nColors;
Rozdzia 16. Efekty specjalne: przezroczysto i mga____________________517
GetClientRectthWnd, Srect);
RepaintWindow(Srect);
EndPaint(hWnd, sps);
break;
case WM_COMMAND : /*
* Obsuga menu...
*/
switch (LOWORD(wParam))
{
case IDM_FILE_EXIT :
DestroyWindow(BlendWindow);
break;
}; break;
case WM_QUIT :
case WM_CLOSE :
/*
* Zniszczenie okna, bitmap i w y j c i e . . .
*/
DestroyWindow(BlendWindow);
exit( 0 )
; break;
518______________________Cz III Tematy zaawansowane i efekty specjalne
case WM_DESTROY:
/*
* Zwolnienie kontekstu urzdzenia, kontekstu
* renderowania i palety
*/
if (BlendRC)
wglDeleteContext(BlendRC) ;
if (BlendDC)
ReleaseDC(BlendWindow, BlendDC);
if (BlendPalette)
Deleteobject(BlendPalette);
PostOuitMessage( 0 ) ;
break;
case WM_QUERYNEWPALETTE: /*
* W razie potrzeby realizacja palety...
*/
if (BlendPalette) {
SelectPalette(BlendDC, BlendPalette, FALSE);
RealizePalette(BlendDC);
UpdateColors(BlendDC); };
break;
case WM_MOUSEMOVE :
if (Drawing)
DrawXY (LOWORD(lParam) , HIWORD(lParam) ) ;
break;
case WM_LBOTTONUP :
case WM_MBUTTONUP :
case WM_RBUTTONUP :
Drawing = GL_FALSE;
break;
default : /*
* Standardowa obsuga wszystkich innych komunikatw
*/
/*
* 'DrawXYO' - Rysuje w biecej pozycji myszy.
*/
void
DrawXY(int mousex, /* We - pooenie myszy w poziomie */
int mousey) /* We - pooenie myszy w pionie */ {
glRasterPos2i (mousex, mousey);
glDrawPixels ( 7 , 7, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE,
^BlendBrushfO] ) ;
glFinish ( ) ;
/*
* ' RepaintWindow ( ) ' - Odrysowuje obszar roboczy okna.
*/
void
RepaintWindow (RECT *rect) /* We - Obszar roboczy okna */ {
/*
* Wyzerowanie widoku i wyczyszczenie okna na jasny bkit
*/
glviewport ( O , O, rect->right, rect->bottom) ;
g!0rtho(0.0, (float) rect->right, (float) rect->bottom, 0 . 0 , - 1 . 0 ,
520 ______________________ Cz III Tematy zaawansowane i efekty specjalne
glEnable (GL_BLEND) ;
glBlendFunc(GL_SRC_ALPHA, GL__ONE_MINUS__SRC_ALPHA) ;
glFinishf ) ;
/*
* End of "Sld$".
*/
Mga
W OpenGL mona uzyska cieniowanie sceny w zalenoci od gbokoci, w celu uzy-
skania pewnych efektw atmosferycznych, gwnie mgy. Suy do tego funkcja glFog.
Tworzenie mgy polega na dodaniu (wymieszaniu) pewnego okrelonego koloru do
kadego wierzchoka lub obrazu tekstury, w iloci zalenej od odlegoci tego wierz-
choka od obserwatora. Efekt mgy czsto wykorzystuje si w symulatorach lotw i
animacjach w celu uzyskania bardziej realistycznego wygldu scen.
glFogi(GL_FOG_MODE, GL_EXP);
glFogi(GL_FOG_MODE, GL_EXP2);
Gdy ju wybierzesz typ mgy, za pomoc funkcji glFogfy lub glFogiv musisz wybra jej
kolor, ktry bdzie mieszany z kolorami sceny:
GLfloat fog_color[4] = { r, g, b, a } ;
glFogfv(GL_FOG_COLOR, fog_color);
GLint fog_color[4] - { r, g, b, a ) ;
glFogiv(GL_FOG_COLOR, fog_color);
Rysunek 16.3.
Imbryki cieniowane w
zalenoci od gbokoci
Rysowanie
imbrykw
cieniowanych w
zalenoci od
gbokoci
Listing 16.3
rysuje dwa
imbryki przy
wczonym
cieniowaniu w
zalenoci od gbokoci. Wszystkimi operacjami graficznymi zajmuje si funkcja
draw_scene, rozpoczynajc od ustawienia koloru mgy na czer oraz trybu mgy na
GL_LINEAR:
static floatfog_color[4] = { 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 };
glEnable(GL_FOG) ;
glFogf(GL_FOG_DENSITY, 0 . 0 5 ) ;
glFogfv(GL_FOG_COLOR, fog_color);
/*
* Te definicje zostay wprowadzone w celu zapewnienia zgodnoci
* pomidzy MS Windows a reszt wiata.
*
* CALLBACK i APIENTRY to modyfikatory funkcji w MS Windows.
*/
522 _______________________ Cz III Tematy zaawansowane i efekty specjalne
#ifndef WIN32
# define CALLBACK
# define APIENTRY
#endif /* IWIN32 */
GLfloat rotation = 0 . 0 ;
/*
* 'reshape_scene () ' - Zmiana rozmiaru s c e n y . . .
*/
V0id CALLBACK
reshape_scene (GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glViewport ( O , O, width, height);
glMatrixMode(GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(22.5, (float) width / (float) height, 0.1, 1000.0);
glMatrixMode(GL_MODELVIEW) ;
/*
* 'draw_scene () ' - Rysowanie sceny zawierajcej dwa imbryki do
* herbaty
*/
void CALLBACK
draw_scene (void)
{
static float red_light[4] = { 1 . 0 , 0 . 0 , 0 . 0 , 1 . 0 };
static float red_pos[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 0 . 0 };
static float blue_light [ 4 ] = { 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 };
static float blue_pos[4] = ( - 1 . 0 , - 1 . 0 , - 1 . 0 , 0 . 0 } ;
static float fog_color[4] = { 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 };
/*
* Wczenie buforw i owietlenia
*/
glEnable (GL_DEPTH_TEST) ;
glEnable (GL_LIGHTING) ;
glEnable (GL_LIGHTO) ; glEnable
(GL_LIGHT1) ;
glShadeModel (GL_SMOOTH) ;
/*
* Wyczyszczenie bufora koloru i gbokoci. V
Rozdzia 16. * Efekty specjalne: przezroczysto i mga ____________________ 523
glEnable(GL_FOG) ;
glFogf (GL_FOG_DENSITY, 0 . 0 5 ) ;
glFogfv(GL_FOG_COLOR, fog_color) ;
glPushMatrix() ;
glTranslatef (-1.0, 0.0, -15.0);
glRotatef (-rotation, 0 . 0 , 1.0, 0 . 0 ) ;
auxSolidTeapot ( 1 . 0 ) ;
glPopMatrix() ;
glPushMatrix () ;
glTranslatef ( 1 . 0 , 0.0, -10.0);
glRotatef (rotation, 0 . 0 , 1 . 0 , 0 . 0 ) ;
auxSolidTeapot ( 1 . 0 ) ;
glPopMatrix () ;
auxSwapBuf f ers ( ) ;
/*
* 'rotate_objects () ' - W wolnych chwilach obrt sceny.
*/
void CALLBACK
rotate_objects (void)
{
rotation += 2.0;
if (rotation >= 3 6 0 . 0 )
rotation -= 3 6 0 . 0 ;
draw_scene ( ) ;
void
main (void)
{
auxInitDisplayMode (AUX_RGB | AUX_DOUBLE | AUX_DEPTH) ;
auxlnitwindow("lmbryki we m g l e " ) ;
auxReshapeFunc (reshape_scene) ;
aux!dleFunc (rotate_objects) ;
auxMainLoop (draw_scene) ;
/*
* Koniec pliku " f o g p o t . c " .
*/
Parametr density moe by dowoln wartoci wiksz od 0,0, lecz zwykle bdziesz na-
dawa mu warto poniej O, l. Wpyw tego parametru na mieszanie koloru mgy przed-
stawia rysunek 16.4.
Rysunek 16.4.
GL_EXP2 ,,-' //
density=0.25 ,''' tt
gbokoci ^V/ ,''''
Kolor mgy /
, A^. / /
/ *' XGLJXP
* *
Gsto mgy w
zalenoci od
Gboko^
Gboko mgy
Gboko mgy to przetransformowana wsprzdna Z wywoa glVertex. Ta wsprzdna
Z naley do przedziau od 0,0 do 1,0, tak samo jak w przypadku bufora gbokoci.
Gboko mgy oraz jej gsto okrelaj sposb mieszania koloru mgy z kolorami
sceny, przy zastosowaniu nastpujcych wzorw:
r _ -(</L'.v//yr) /exp ~
"
r _ -(demityzy J
exp 2
koniec z
J linear
koniec - pocztek
Rozdzia 16. Efekty specjalne: przezroczysto i mga_____________________525
Rysunek 16.5.
Widok terenu z
zastosowaniem
lekkiej mgieki
W tym przypadku kolor mgy zosta zdefiniowany jako jednolity kolor RGB A (1,0, 1,0,
1,0, 1,0). Aby jeszcze bardziej poprawi jako obrazu (wyduajc czas rysowania),
moemy wywoa take
glHint(GL_FOG_HINT, GL_NICEST);
To wywoanie powoduje, e mga jest obliczana dla kadego wierzchoka, a nie dla kadego
wielokta. Niestety, w przypadku wikszoci scen oznacza to stukrotny wzrost oblicze!
/*
* 'RepaintWindowO ' - Odrysowuje obszar roboczy okna sceny.
*/
void
RepaintWindowfRECT *rect) /* We - Obszar roboczy okna */
{
int i;
int x, y; /* Pooenie terenu
( x , y) */ int last_type; /* Poprzedni
typ terenu */ int *type; /* Biecy
typ terenu */ GLfloat *height, /*
Bieca wysoko terenu */ ( * n ) [ 3 ] ; /*
Bieca normalna terenu */ static GLfloat
sky_top[4][ 3 ] = { /* Wsprzdne nieba
*/
{ -TERRAIN_EDGE, TERRAIN_SIZE * 0 . 8 , -TERRAIN_EDGE }, {
TERRAIN_EDGE, TERRAIN_SIZE * 0 . 8 , -TERRAIN_EDGE }, {
TERRAIN_EDGE, TERRAIN_SIZE * 0 . 8 , TERRAIN_EDGE }, ( -
TERRAIN_EDGE, TERRAIN_SIZE * 0 . 8 , TERRAIN_EDGE }
};
static GLfloat sky_bottom[4][ 3 ] =
{
{ -TERRAIN_EDGE, 0 . 0 , -TERRAIN_EDGE },
{ TERRAIN_EDGE, 0 . 0 , -TERRAIN_EDGE },
{ TERRAIN_EDGE, 0 . 0 , TERRAIN_EDGE },
( -TERRAIN_EDGE, 0 . 0 , TERRAIN_EDGE }
>;
static GLfloat sunpos[4] = { 0 . 0 , 1 . 0 , 0 . 0 , 0.0 };
static GLfloat suncolor[4] = { 6 4 . 0 , 6 4 . 0 , 6 4 . 0 , 1.0 };
static GLfloat sunambient[ 4 ] = { 0.001, 0.001, 0.001,
1.0 };
static GLfloat fogcolor[4] = { 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 };
/*
* Wyzerowanie widoku i wyczyszczenie okna na jasny bkit
*/
glViewport( O , O, rect->right, rect-
>bottom); glClearColor(0.5, 0.5, 1.0,
1.0);
glEnable(GL_DEPTH_TEST);
glEnable(GL_FOG);
glFogf(GL_FOG_DENSITY, 0.0025);
glFogi(GL_FOG_MODE, GL_EXP);
glFogfv(GL_FOG_COLOR, fogcolor);
if (Moving ||
Drawing) { /*
* Bez tekstur podczas rysowania lub lotu; jest za w o l n e . . .
* Rysowanie tylnego bufora dla pynnej animacji
*/
Rozdzia 16. * Efekty specjalne: przezroczysto l mga ____________________ 527
glDisable (GL_TEXTURE_2D) ;
glDrawBuf f er (GL_BACK) ;
else
glEnable (GL_TEXTURE_2D) ;
glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL) ;
glDrawBuf f er (GL_FRONT) ;
/*
* Przygotowanie przeksztacenia widoku dla biecego
* punktu obserwacji
*/
glMatrixMode (GL_PROJECTION) ;
glLoadldentity () ;
gluPerspective(45.0, (float) rect->right / ( float) rect->bottom,
0 . 1 , 1000.0);
glMatrixMode (GL_MODELVIEW) ;
glPushMatrix() ;
glRotatef (Roli, 0.0, 0.0, 1 . 0 ) ;
glRotatef (Pitch, -1.0, 0.0, 0 . 0 ) ;
glRotatef (Heading, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glTranslatef (-PositionfO] ,
-Position [1 ] ,
-Position[2] ) ; glScalef (TERRAIN_SCALE,
TERRAIN_SCALE, TERRAIN_SCALE) ;
if ( ! (Moving l | Drawing) ) {
/*
* Rysowanie nieba. . .
*/
glDisable (GL_LIGHTING) ;
glCallList (SkyTexture) ;
glBegin(GL_QUAD_STRIP) ; for (i
= 0; i < 4; i ++) {
glTexCoord2f ( (float) i, 0 . 0 ) ;
glvertex3fv(sky_bottom[i] ) ;
glTexCoord2f ( (float)i, 0 . 8 ) ;
g!Vertex3fv(sky_top[i] ) ;
528______________________Cz III Tematy zaawansowane i efekty specjalne
glTexCoord2f( 4 . 0 , 0 . 0 ) ;
glVertex3fv(sky_bottom[0]);
glTexCoord2f( 4 . 0 , 0 . 8 ) ;
glVertex3fv(sky_top[0]);
glEnd();
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f( 0 . 5 , 1.0);
glVertex3f( 0 . 0 , TERRAIN_SIZE, 0 . 0 ) ;
for (i = 0; i < 4; i ++)
{
glTexCoord2f((float)i, 0 . 8 ) ;
glVertex3fv(sky_top[i]); };
glTexCoord2f( 4 . 0 , 0 . 8 ) ;
glVertex3fv(sky_top[0]);
glEnd(); };
/*
* Przygotowanie owietlenia...
*/
glEnable(GL_LIGHTING);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
glEnable(GL_LIGHTO);
glLightfv(GL_LIGHTO, GL_POSITION, sunpos);
glLightfv(GL_LIGHTO, GL_DIFFUSE, suncolor);
glLightfv(GL_LIGHTO, GL_AMBIENT, sunambient);
if (Moving || Drawing)
glEnable(GL_COLOR_MATERIAL);
else
glDisable(GL_COLOR_MATERIAL);
/*
* Teraz teren...
*/
type = TerrainType[ 0 ] ;
height = TerrainHeight[ 0 ] ;
n = TerrainNormal[ 0 ] ;
for (y = 0; y < (TERRAIN_SIZE - 1); y ++)
{
last_type = -1;
if (last_type != - 1 )
glEnd() ;
switch (*type)
{
case IDC_WATER :
if (Moving l l Drawing)
glColor3f( 0 . 0 , 0.0, 0 . 5 ) ;
else
glCallList(WaterTexture);
break; case IDC_GRASS :
if (Moving || Drawing)
glColorSf(0.0, 0.5,
0 . 0 ) ; else
glCallList(GrassTexture);
break; case IDC_ROCKS :
if (Moving || Drawing)
glColor3f(0.25, 0.25,
0.25); else
glCallList(RocksTexture);
break; case IDC_TREES :
if (Moving l| Drawing)
glColorSf( 0 . 0 , 0.25, 0 . 0 ) ;
else
glCallList(TreesTexture);
break; case IDC_MOUNTAINS :
if (Moving || Drawing)
glColor3f(0.2, 0.1, 0 . 0 5 ) ;
else
glCallList(MountainsTexture); break;
};
glBegin(GL_QUAD_STRIP);
if (last_type != -1) {
/*
* Zaczniemy od poprEedniego miejsca, aby nie byo dziur V
glTexCoord2i(x * 2 - 2, y * 2 ) ;
glNormal3fv(n[-l]);
glVertex3f((GLfloat)(x - TERRAIN_EDGE - 1 ) ,
height[-l], (GLfloat)(y -
TERRAIN_EDGE));
glTexCoord2i(x * 2 - 2 , y * 2 + 2 ) ;
glNormal3fv(n[TERRAIN_SIZE - 1 ] ) ;
glVertex3f((GLfloat)(x - TERRAIN_EDGE - 1 ) ,
height[TERRAIN_SIZE - 1 ] ,
(GLfloat)(y - TERRAIN_EDGE + 1 ) ) ;
};
last_type = *type;
530_______________________Cz III Tematy zaawansowane i efekty specjalne
glTexCoord2i(x * 2, y * 2 ) ;
glNorma!3fv(n[0]);
glVertex3f((GLfloat)(x - TERRAIN_EDGE),
height[0],
(GLfloat)(y - TERRAIN_EDGE));
glTexCoord2i(x * 2, y * 2 + 2 ) ;
glNormal3fv(n[TERRAIN_SIZE]);
glVertex3f((GLfloat)(x - TERRAIN_EDGE),
height[TERRAIN_SIZE],
(GLfloat)(y - TERRRIN_EDGE + l));
};
glEnd(); };
glPopMatrix();
/*
* Gdy lecimy lub rysujemy, uywamy podwjnego buforowania.
* Jeli trzeba, przerzu bufory
*/
glFinish();
if (Moving || Drawing)
SwapBuffers(SceneDC);
Podsumowanie
czenie kolorw i mga stanowi uzupenienie biblioteki OpenGL bdc kolejnym na-
rzdziem sucym do zwikszania realizmu tworzonych scen. Dziki czeniu kolorw
uzyskujemy efekt przezroczystoci oraz popraw antyaliasingu punktw, linii i wielok-
tw. Stosujc mg moemy cieniowa sceny w zalenoci od gbokoci oraz tworzy
efekty atmosferyczne - gste mgy, chmury lub leciutkie poranne mgieki. Dziki nim
tworzone obrazy wygldaj na mniej precyzyjne, czyli - ironicznie - bardziej przypomi-
najce rzeczywisty wiat.
Podrcznik
gIBIendFunc
Przeznaczenie Ustawia funkcj czenia kolorw.
Plik nagwkowy <gl.h>
Skadnia void glBlendFunc(GLenum sfactor, GLenum dfactor);
Opis Ta funkcja ustala kolor rdowy i docelowy przy czeniu kolorw.
Aby wczy czenie kolorw, musisz wywoa funkcj
glEnable(GL_BLEND). czenie kolorw jest dostpne jedynie
Rozdzia 16. Efekty specjalne: przezroczysto i mga 531
glFog
Przeznaczenie Okrela parametry mgy.
Plik nagwkowy <gl.h>
Skadnia void glFogf(GLenum pname, GLfloat param); void
Opis glFogfv(GLenum pname, GLfloat *params); void
glFogi(GLenum pname, GLint param); void
Parametry glFogiv(GLenum pname, GLint *params);
pname Funkcja glFog ustala parametry mgy. Aby w scenie pojawia si mga,
musisz j wczy wywoaniem glEnable(GL_FOG).
Krzywe i powierzchnie
Krzywa posiada punkt pocztkowy, dugo oraz punkt kocowy. W rzeczywistoci jest
tylko lini wijc si w trjwymiarowej przestrzeni. Z drugiej strony, powierzchnia posiada
zarwno dugo, jak i szeroko, a w zwizku z tym posiada rwnie powierzchni.
Rozdzia ten zaczniemy wic od opisu sposobw rysowania gadkich trjwymiarowych
krzywych, po czym poznane pojcia rozszerzymy na trjwymiarowe powierzchnie. Zanim
jednak do tego przejdziemy, poznajmy przynajmniej podstawowe terminy i kryjc si za
nimi matematyk.
Reprezentacja parametryczna
Gdy mylisz o linii prostej, najczciej masz na uwadze synne rwnanie: Y =
mX + b
W tym rwnaniu m odpowiada pochyleniu linii, za b jest punktem przecicia linii z osi Y.
By moe przypominasz sobie matematyk ze szkoy redniej, gdzie uczye si take o
rwnaniach paraboli, hiperboli, krzywych wykadniczych, itd. We wszystkich tych
rwnaniach zmienna Y (lub X) bya wyraona jako funkcja wartoci na osi X (lub Y).
Innym sposobem reprezentacji rwnania krzywej lub prostej jest rwnanie parametryczne.
Rwnanie parametryczne wyraa zarwno wsprzdne X, jak i Y poprzez inn zmienn,
zmieniajc si w okrelonym zakresie wartoci. Na przykad w fizyce wsprzdne X, Y i
Z mog by niekiedy wyraone w funkcji czasu, gdzie czas moe by po-
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS7J! 535
dawany w sekundach. W poniszych formuach f(), g() i h() to rne funkcje, zmienne w
czasie (t):
X = f(t) Y =
g(t); Z = h(t);
Gdy definiujemy krzyw w OpenGL, definiujemy jej rwnanie parametryczne. Parame-
tryczn zmienn krzywej bdziemy nazywa u, za jej zakres wartoci bdziemy nazywa
dziedzin tej krzywej. Powierzchnie bd opisywane przy uyciu dwch parametrw: u i
v. Reprezentacj krzywej i powierzchni poprzez dziedziny u i v przedstawia rysunek 17.1.
Wane jest, aby pamita, e zmienne parametryczne (u i v) reprezentuj parametry
rwnania, a nie same wartoci wsprzdnych.
Rysunek
17.1. u =1.0
Parametryczna
reprezentacja
krzywych i
powierzchni
u = 0.0
u = 1.0
v=1.0
x = f(u,v)
y=M
Punkty kontrolne
Krzywe s reprezentowane przez pewn ilo punktw kontrolnych, wpywajcych na
ksztat krzywej. W przypadku krzywych Beziera, punkty pierwszy i ostatni s jedno-
czenie pierwszym i ostatnim punktem samej krzywej. Pozostae punkty kontrolne za-
chowuj si jak magnes, przycigajc" krzyw do siebie. Kilka przykadw krzywych, z
rnymi ilociami punktw kontrolnych, przedstawia rysunek 17.2.
Rysunek 17.2. P,
W jaki sposb punkty
kontrolne wpywaj p
na ksztat krzywych l
Klas krzywej okrelamy przez ilo punktw kontrolnych uywanych do opisu tej
krzywej. Stopie krzywej jest liczb o jeden mniejsz od klasy. Matematyczne zna-
536_______________________Cz III Tematy zaawansowane i efekty specjalne
Cigo
Jeli dwie krzywe umieszczone obok siebie maj wsplny punkt, razem tworz krzyw
skadajc si z kawakw. Cigo krzywej w miejscach pocze okrela gadkie jest
przejcie pomidzy poszczeglnymi kawakami. Cztery kategorie cigoci to brak cigoci
(CO), cigo szczepna (Cl), cigo styczna (C2) oraz krzywizna (C3).
Jak wida na rysunku 17.3, brak cigoci wystpuje wtedy, gdy dwa kawaki krzywej
nie stykaj si ze sob. Cigo szczepna jest zachowanie, gdy dwa kawaki krzywej
maj przynajmniej wsplny punkt pocztkowy. Cigo styczna wystpuje wtedy, gdy
krzywe we wsplnym punkcie posiadaj t sam styczn. Na koniec, krzywizna jest za-
chowana wtedy, gdy pochodne obu kawakw krzywej w punkcie zczenia s rwne
(czyli wystpuje gadkie przejcie z kawaka do kawaka krzywej).
C3-Krzywizna
Obliczenia
OpenGL posiada kilka funkcji bardzo uatwiajcych rysowanie krzywych i powierzchni
Beziera, przez okrelenie punktw kontrolnych oraz zakresu zmiennych parametry-
cznych u i v. Nastpnie, przez wywoanie odpowiedniej funkcji wyliczajcej, generowane s
punkty tworzce krzyw lub powierzchni. Zaczniemy od utworzenia dwuwymiarowej
krzywej Beziera, a nastpnie rozszerzymy j o trzeci wymiar w celu zbudowania
powierzchni Beziera.
Dwuwymiarowa krzywa
Najlepszym sposobem bdzie przedstawienie przykadu i opisanie go linia po linii. Listing
17.1 zawiera fragmenty kodu z programu BEZIER na pytce CD-ROM. Program okrela
cztery punkty kontrolne krzywej Beziera, a nastpnie za pomoc funkcji obliczajcej
rysuje kolejne punkty samej krzywej. Wynik dziaania tego programu zosta
przedstawiony na rysunku 17.4.
Rysunek 17.4.
Wynik dziaania
programu BEZIER
Listing 17.1. Fragment programu BEZIER rysujcego krzyw Beziera z czterema punktami kontrolnymi
Dla iloci punktw kontrolnych oraz samej tablicy punktw kontrolnych stworzylimy
zmienne globalne. Aby poeksperymentowa, moesz je zmieni dodajc kolejne punkty
kontrolne lub po prostu modyfikujc pooenie punktw.
Funkcja DrawPoints() jest chyba oczywista. Wywoujemy j z kodu renderujcego w
celu wywietlenia punktw kontrolnych krzywej. Jest take bardzo uyteczna przy
eksperymentach z pooeniem punktw kontrolnych. Nasza standardowa funkcja Chan-
geSize() ustanawia dwuwymiarowy rzut rwnolegy o rozcigoci od -10 do 10 jednostek
w osiach x i y.
Na koniec, przechodzimy do kodu renderujcego. Funkcja RenderScene() wywouje na
pocztku funkcj glMaplf (po wyczyszczeniu ekranu) w celu stworzenia odwzorowania dla
naszej krzywej:
// Wywoywane w celu narysowania sceny
void RenderScene(void)
{
//int i;
Dwa nastpne parametry okrelaj dolny i grny zakres parametru u dla tej krzywej.
Dolna warto okrela pocztkowy punkt krzywej, za grna warto okrela ostatni
punkt krzywej. Wszystkie wartoci pomidzy nimi odnosz si do punktw tworzonej
krzywej. W naszym przykadzie ustalilimy zakres od O do 100.
glEnable(GL_MAP1_VRTEX3);
Obliczanie krzywej
OpenGL moe jeszcze bardziej uproci cae zadanie. Moemy przygotowa siatk punktw
za pomoc funkcji glMapGrid, sucej do utworzenia rwnomiernej siatki punktw w
dziedzinie krzywej. Nastpnie moemy wywoa funkcj glEvalMesh w celu
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS?!!___________________541
Jak wida, jest to bardziej spjne i efektywne, jednak prawdziwe korzyci pynce z
tych wywoa objawiaj si raczej podczas tworzenia powierzchni, nie krzywych.
Powierzchnia trjwymiarowa
Tworzenie trjwymiarowej powierzchni Beziera przebiega podobnie do tworzenia dwu-
wymiarowej krzywej. Oprcz zdefiniowania punktw w dziedzinie u, musimy zdefiniowa
punkty take w dziedzinie v.
Listing 17.2 pochodzi z naszego nastpnego programu, BEZ3D, w ktrym wywietlamy
siatk przedstawiajc powierzchni Beziera. Pierwsz zmian w stosunku do poprze-
dniego przykadu jest zdefiniowanie trzech dodatkowych zestaww punktw kontrol-
nych powierzchni, wzdu dziedziny v. Aby powierzchnia nie bya skomplikowana,
poza wartoci Z pozostae wsprzdne punktw kontrolnych pozostaj takie same. W
ten sposb stworzylimy jednorodn powierzchni, tak jakbymy rozcignli" nasz
dwuwymiarow krzyw Beziera wzdu osi Z.
Nasz kod renderowania take jest nieco inny. Oprcz obrcenia figury w celu uzyskania
lepszego widoku, zamiast funkcji glMap l f wywoujemy funkcj glMap2f. W ten sposb
okrelamy punkty w dziedzinach M i v, a nie tylko w dziedzinie u.
Rozdzia 17. * Krzywe i powierzchnie: co to jest NURBS?!! 543
Rysunek 17.5.
Wynik dziaania
programu BEZ3D
Owietlenie i normalne
Kolejn cenn waciwoci funkcji obliczajcych jest automatyczne generowanie nor-
malnych. Przez prost zmian kodu:
// Utworzenie siatki przy uyciu linii
glEvalMesh2(GL_LINE,O,1 0 , 0 , 10);
na
// Utworzenie siatki przy uyciu linii
glEvalMesh2(GL_FILL,0,10,0,10) ;
a nastpnie wywoanie
glEnable(GL_A0TO_NORMAL);
NURBS
Funkcji obliczajcych powierzchnie Beziera moesz uywa do woli, jednak w przy-
padku bardziej zoonych krzywych bdziesz musia skada je z kawakw. W miar
dodawania kolejnych punktw kontrolnych coraz trudniej jest utworzy krzyw o po-
prawnej cigoci. Na szczcie, peniejsz kontrol mona osign uywajc funkcji
NURBS z biblioteki glu. NURBS to skrt sw non-uniform rational B-spline (nieje-
dnorodne wymierne krzywe B-sklejane). Matematycy ju wiedz, e chodzi po prostu o
bardziej uoglnion form krzywych i powierzchni ni te, ktre mog tworzy krzywe i
powierzchnie Beziera, a take kilka innych rodzajw krzywych. W przypadku funkcji
NURBS mona okrela wpyw punktw kontrolnych podanych funkcjom obliczajcym,
w celu otrzymania gadszych krzywych i powierzchni o wikszej liczbie punktw
kontrolnych.
Wzy
Prawdziwa potga krzywych NURBS polega jednak na tym, e moesz okreli wpyw
czterech punktw kontrolnych na dany segment krzywej w celu osignicia podanej
gadkoci. Odbywa si to poprzez okrelenie sekwencji wartoci zwanych wzlami.
Dla kadego punktu kontrolnego s zdefiniowanie dwie wartoci wzw. Zakres wartoci
wzw odpowiada dziedzinom parametrw u oraz v i musi by niemalejcy, gdy wartoci
wzw okrelaj wpyw punktw kontrolnych przypadajcych na dany zakres w
przestrzeni u/v. Rysunek 17.8 przedstawia krzyw demonstrujc wpyw punktw
kontrolnych na krzyw posiadajc cztery jednostki w dziedzinie parametru M. Punkty w
rodkowej czci krzywej wyginaj j w wikszym stopniu, a na ksztat krzywej maj
wpyw jedynie punkty pomidzy O a 3.
Rysunek 17.8.
Wpyw
Wptyw punktw
kontrolnych wzdu
dziedziny
parametru u
2 3
Kluczowy jest fakt, e jedna z takich krzywych wpywu wystpuje dla kadego punktu w
dziedzinie parametrw u/v. Sekwencja wzw definiuje si wpywu punktw w tej
dziedzinie. Jeli warto wza si powtarza, punkty w pobliu tej parametrycznej
wartoci maj jeszcze wikszy wpyw. Powtarzanie wartoci wzw jest nazywane
multiplikacj wzw. Wysza multiplikacja wzw zmniejsza krzywizn krzywej lub
powierzchni w danym regionie.
Definiowanie powierzchni
Definicja powierzchni jest przekazywana funkcji gluNurbsSurface jako tablice punktw
kontrolnych i sekwencji wzw. Jak wida, ta funkcja jest ujta pomidzy wywoania
gluBeginSurface oraz gluEndSurface:
// Renderuj powierzchni NURBS //
Pocztek definicji powierzchni
gluBeginSurface(pNurb);
// Obliczenia powierzchni
gluNurbsSurface(pNurb, // Wskanik do renderera NURBS
8, Knots, // Ilo wzw i tablica wzw w kierunku u.
8/ Knots, // Ilo wzw i tablica wzw w kierunku v.
4*3, // Odstp pomidzy punktami kontrolnymi
// kierunku u.
3. // Odstp pomidzy punktami kontrolnymi
// kierunku v.
sctrlPoints[ 0 ] [ 0 ] [ 0 ] , // Punkty kontrolne
4. 4, // klasa powierzchni u i v
GL_MAP2_VERTEX_3); // Rodzaj powierzchni
// Koniec definiowania powierzchni
gluEndSurface(pNurb);
548 Cz III Tematy zaawansowane i efekty specjalne
j
Rysunek 17.9.
Dziaanie programu
NURBS
Wycinanie
Wycinanie wie si z usuwaniem sekcji powierzchni NURBS. Zwykle stosuje sieje do
dosownego obcinania ostrych krawdzi tych powierzchni. Rwnie atwo mona take
wycina otwory w powierzchniach. Wynik dziaania programu NURBT zosta przedsta-
wiony na rysunku 17.10.
Rysunek 17.10.
Wynik dziaania
programu NURBT
Listing 17.3. Modyfikacje programu NURBS w celu wycicia fragmentu powierzchni ____________
// Obliczenia powierzchni
gluNurbsSurface(pNurb, // Wskanik do renderera NURBS
8, Knots, // Ilo wzw i tablica wzw w kierunku u.
8, Knots, // Ilo wzw i tablica wzw w kierunku v.
4
* 3, // Odstp pomidzy punktami kontrolnymi
// kierunku u.
3
' , // Odstp pomidzy punktami kontrolnymi
// kierunku v.
sctrlPointst^KU [ 0 ] , // Punkty kontrolne
4
' 4/ >. // Klasa powierzchni u i v
GL_MAP2_VERTEX_3);)<' // Rodzaj powierzchni
f
/ 7 Obszar zewntrzny/ obejmujcy ca powierzchni
gluBeginTrim (pNurb) ;
gluPwlCurve (pNurb, 5, ioutsidePts [ 0 ] [ 0 ] , 2, GLU MAPI TRIM 2)
gluEndTrim (pNurb) ; ~ ~~ ~
Podsumowanie
Ten rozdzia z atwoci mg si sta najbardziej niezrozumiaym rozdziaem w ksice.
Jak jednak widzisz, koncepcje kryjce si za krzywymi i powierzchniami nie s a tak
trudne do zrozumienia. Jeli chcesz dokadniej pozna ich matematyczne podstawy, w
dodatku B znajdziesz wykaz odpowiedniej literatury.
Przykady z tego rozdziau stanowi dobry punkt wyjcia do eksperymentowania z po-
wierzchniami NURBS. Sprbuj dostosowa punkty kontrolne i sekwencje wzw w
celu uzyskania zawinitych lub pofadowanych powierzchni. Sprbuj take stworzy
powierzchnie drugiego, trzeciego i wyszych stopni. Na doczonej do ksiki pytki
CD-ROM znajdziesz dodatkowe przykady.
Uwaaj - jedn z najczstszych puapek jest prba stworzenia zoonych powierzchni
przy uyciu pojedynczych powierzchni NURBS. Przekonasz si, e wiksz elasty-
czno i moliwoci osigniesz wtedy, gdy skomponujesz zoon powierzchni z kilku
mniejszych i atwiejszych do opanowania powierzchni Beziera lub NURBS.
Podrcznik
glEyalCoord
Przeznaczenie Oblicza punkt jedno- lub dwuwymiarowej krzywej, za pomoc uprzednio
wybranej funkcji.
Plik nagwkowy <gl.h>
Skadnia void glEvalCoordld(GLdoub!e u);
void glEvalCoordlf(GLfloat u);
void glEvalCoord2d(GLdouble u, GLdouble v);
void glEvalCoord2f(GLfloat u, GLfloat v);
void glEvalCoordldv(const GLdouble *u);
void glEvaICoordlfv(const GLfloat *u);
void glEvalCoord2dv(const GLdouble *u);
void glEvalCoord2fv(const GLfloat *u);
Opis Ta funkcja uywa poprzednio wybranej (poprzez wywoanie glMap)
funkcji obliczajcej do stworzenia wierzchoka, koloru, normalnej oraz
wsprzdnych tekstury na podstawie wartoci parametrw u i v. Rodzaj
danych oraz wywoywanych funkcji jest okrelany przez wywoanie funkcji
glMap l orazglMap2.
552 Cz III Tematy zaawansowane i efekty specjalne
Parametry
w, v Te parametry okrelaj wartoci parametrw u i v, dla ktrych ma zosta
obliczony punkt krzywej.
Zwracana warto Brak.
Przykad Poniszylwd z przykadowego programu BEZIER odpowiada wywoaniu
funkcji glVertex3f za kadym razem, gdy jest wywoywana funkcja
glEvalCoordLfHF^ooenie wierzchokw jest obliczane z rwnania krzywej
dla Kolejnych wartoci z dziedziny krzywej, przekazywanych poprzez
zmienn i.
// Oycie amanej "czcej punkty"
glBegin(GL_LINE_STRIP);
for(i = 0; i <= 100; i++) {
// Obliczenie krzywej dla danego punktu
glEvalCoordlf((GLfloat) i ) ; } glEnd ();
glEyalMesh
Przeznaczenie Oblicza punkt jedno- lub dwuwymiarowej siatki krzywej.
Plik nagwkowy <gl.h>
Skadnia void glEvalMeshl(GLenum mod, GLint ii, GLint i2);
void gIEvalMesh2(GLenum mod, GLint ii, GLint i2, GLint j l, GLint J2);
Opis Ta funkcja jest uywana razem z glMapGrid w celu utworzenia siatki
punktw powierzchni rwnomiernie rozoonych w dziedzinach u i v.
Funkcja glEvalMesh oblicza pooenie wierzchokw i tworzy punkty,
odcinki lub wypenione wielokty.
Parametry
mod GLenum: Okrela, czy siatka ma by tworzona z punktw (GL_POINT),
odcinkw (GL_LINE) czy wypenionych wieloktw w przypadku
powierzchni (GL_FILL).
11,12 GLint: Okrelaj pierwsz i ostatni warto cakowit w dziedzinie u.
JJJ2 GLint: Okrelaj pierwsz i ostatni warto cakowit w dziedzinie v.
Zwracana warto Brak.
Przykad Poniszy kod z przykadowego programu BEZIER tworzy odwzorowanie
siatki od O do 100 ze stoma podziaami. Wystpujce dalej wywoanie
glEvalMesh oblicza punkty siatki i rysuje odcinki pomidzy wszystkimi
punktami krzywej.
// Oycie funkcji wyszego poziomu do odwzorowania //
siatki, a nastpnie obliczenia caoci
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS?!! 553
glEyalPoint
Przeznaczenie Plik Oblicza i generuje pojedynczy punkt siatki.
nagwkowy <gl.h>
Skadnia void glEvalPointl(GLint i);
void glEvalPoint2(GLint i, GLint j);
Opis Ta funkcja moe zosta uyta zamiast funkcji glEvalMesh w celu
obliczenia pojedynczego punktu krzywej lub powierzchni. W wyniku
Parametry i J oblicze powstaje pojedynczy prymityw, GL_POINTS. Pierwsza
odmiana funkcji (glEvalPointl) jest uywana w przypadku krzywych,
Zwracana warto za druga odmiana (glEvalPoint2) w przypadku powierzchni.
Przykad
GLint: Okrelaj warto parametrw u i v, dla ktrych ma zosta
obliczony punkt krzywej.
Brak.
Poniszy kod tworzy krzyw Beziera zoon z punktw, a nie z
segmentw linii. Jako komentarz pozostawiono niepotrzebne ju
wywoania, pozostae z poprzedniego przykadu, z opisu funkcji
glEvalCoord:
// Oycie amanej "czcej punkty"
glBegin(GL_LINE_STRIP);
for(i = 0; i o 100; i++) {
// Obliczenie krzywej dla danego punktu //
glEvalCoordlf((GLfloat) i ) ; glEvalPointl( i ) ; }
glEnd();
float parametricRange[ 4 ] ;
glGetMapfv(GL_MAP2_VERTEX_3,GL_DOMAIN,parametricRange);
gIMap
Przeznaczenie Definiuje funkcj obliczajc ID lub 2D.
Plik nagwkowy <gl.h>
Skadnia void glMapld(GLenum target, GLdouble ul, GLdouble u2, GLint
ustride, GLint uorder, const GLdouble *points);
void glMaplf(GLenum target, GLfloat ul, GLfloat u2, GLint ustride,
GLint uorder, const GLfloat *points);
void glMap2d(GLenum target, GLdouble ul, GLdouble u2, GLint ustride,
GLint uorder, GLdouble vi, GLdouble v2, GLint vstride, GLint vorder,
const GLdouble *points);
void glMap2f(GLenum target, GLfloat ul, GLfloat u2, GLint ustride,
GLint uorder, GLfloat vi, GLfloat v2, GLint vstride, GLint vorder, const
GLfloat *points);
Opis Ta funkcja definiuje funkcj obliczajc dla krzywych (ID) lub
powierzchni (2D). Funkcje glMaplx s uywane dla krzywych, za funkcje
glMap2x dla powierzchni. Funkcje obliczajce generuj wierzchoki i
zwizane z nimi informacje (patrz opis parametru target) dla parametrw
krzywych i powierzchni z dziedziny u i v.
556_______________________Cz III Tematy zaawansowane i efekty specjalne
Parametry
target GLenum: Okrela rodzaj wartoci generowanych przez funkcj
obliczajc. Dostpne wartoci to:
GL_MAP1_VERTEX_3 (lub GL_MAP2_VERTEX_3): Punktami
kontrolnymi s trjki wartoci reprezentujce wartoci wsprzdnych x, y i z.
Podczas obliczania siatki generowane s wewntrznie polecenia glVertex3.
GLJVIAP1JVERTEX_4 (lub GL_MAP2_VERTEX_4): Punktami
kontrolnymi s czwrki wartoci reprezentujce wartoci wsprzdnych x, y,
z i w. Podczas obliczania siatki generowane s wewntrznie polecenia
glVertex4.
GL_MAP1_INDEX (lub GL_MAP2_INDEX): Generowane punkty kontrolne
to pojedyncze wartoci zmiennoprzecinkowe okrelajce warto indeksu
koloru. Podczas obliczania siatki generowane s wewntrznie polecenia
gllndex. Uwaga: biecy indeks koloru nie jest zmieniany, inaczej ni w
przypadku bezporedniego wywoania polecenia gllndex.
GL_MAP1_COLOR_4 (lub GL_MAP2_COLOR_4): Generowane punkty
kontrolne to czwrki wartoci zmiennoprzecinkowych okrelajcych
skadowe czerwon, zielon, niebiesk oraz alfa koloru. Podczas obliczania
siatki generowane s wewntrznie polecenia glColor4. Uwaga: biecy kolor
nie jest zmieniany, inaczej ni w przypadku bezporedniego wywoania
polecenia glColor4.
GL_MAP1_NORMAL (lub GL_MAP2_NORMAL): Generowane punkty
kontrolne to trjki wartoci zmiennoprzecinkowych okrelajcych
wsprzdne x, y i z wektora normalnego. Podczas obliczania siatki
generowane s wewntrznie polecenia glNormal. Uwaga: bieca normalna
nie jest zmieniana, inaczej ni w przypadku bezporedniego wywoania
polecenia glNormal.
GL_MAP1_TEXTURE_COORD_1 (lub
GL_MAP2_TEXTURE_COORD_1): Generowane punkty kontrolne to
pojedyncze wartoci zmiennoprzecinkowe okrelajce wsprzdn s
tekstury. Podczas obliczania siatki generowane s wewntrznie polecenia
glTexCoordl. Uwaga: biece wsprzdne tekstury nie s zmieniane, inaczej
ni w przypadku bezporedniego wywoania polecenia glTexCoordl.
GL_MAP1_TEXTURE_COORD_2 (lub
GL_MAP2_TEXTURE_COORD_2): Generowane punkty kontrolne to pary
wartoci zmiennoprzecinkowych okrelajce wsprzdne s i t tekstury.
Podczas obliczania siatki generowane s wewntrznie polecenia
glTexCoord2. Uwaga: biece wsprzdne tekstury nie s zmieniane,
inaczej ni w przypadku bezporedniego wywoania polecenia glTexCoord.
GL_MAP1_TEXTURE_COORD_3 (lub
GL_MAP2_TEXTURE_COORD_3): Generowane punkty kontrolne to trjki
wartoci zmiennoprzecinkowych okrelajce wsprzdne s, t i r
Rozdzia 17. * Krzywe i powierzchnie: co to jest NURBS?!! 557
{{ -4.0f, O . O f ,
O . O f } , { -2.0f,
4.0f, O . O f } , {
4.0f, O . O f , O . Of } },
{{ -4.0f, O . O f , -
4 . 0 f ) , { -2.0f, 4 . 0 f,
- 4 . 0 f } , { 4 . 0 f,
O . O f , -4.0f } } } ;
glMapGrid
Przeznaczenie Definiuje siatk odwzorowania krzywej lub powierzchni.
Plik nagwkowy
Skadnia void glMapGrid l d(GLint un, GLdouble ul, GLdouble u2); void
glMapGridlf(GLint un, GLfloat ul, GLfloat u2);
void glMapGrid2d(GLint un, GLdouble ul, GLdouble u2, GLint vn,
GLdouble vi, GLdouble v2);
void glMapGrid2f(GLint un, GLfloat ul, GLfloat u2, GLint vn, GLfloat
vi, GLfloat v2);
Opis Ta funkcja ustanawia siatk odwzorowania ID lub 2D. Odwzorowanie jest
uywane przez funkcje glMap i glEvalMesh do obliczenia siatki
wsprzdnych krzywej lub powierzchni.
Parametry
un, vn GLint: Okrelaj ilo podziaw siatki w kierunku u i v. Okrelaj
ul, u2 dolny i grny zakres wartoci dziedziny w kierunku u. Okrelaj dolny
vl,v2 i grny zakres wartoci dziedziny w kierunku v. Brak.
Zwracana warto Poniszy fragment kodu pochodzi z programu BEZ3D. Ustanawia
odwzorowanie dla powierzchni Beziera drugiego stopnia, a nastpnie
Przykad oblicza punkty tej powierzchni.
// Przygotowanie krzywej Beziera
// Trzeba to zrobi tylko raz, wic powinnimy to
// uczyni w funkcji przygotowujcej kontekst.
glMap2f(GL_MAP2_VERTEX_3, // Rodzaj generowanych danych
O.Of, // Pocztek zakresu u 1 0 . O f ,
// Koniec zakresu u 3, // Odstp pomidzy
danymi wierzchokw 3, // Rozmiar w kierunku
u (klasa) O . O f , // Pocztek zakresu v
10.O f , // Koniec zakresu v 9, // Odstp
pomidzy danymi wierzchokw 3, // Rozmiar w
kierunku v (klasa) // tablica punktw
kontrolnych
Rozdzia 17. Krzywe i powierzchnie; co to jest NURBS711 559
&ctrlPoints[0][ 0 ] [ 0 ] ); //
Wczenie funkcji obliczajcej
glEnable(GL_MAP2_VERTEX_3);
// Uycie funkcji wyszego poziomu do odwzorowania
// siatki, a nastpnie obliczenia caoci
// Odwzorowanie siatki 10 punktw od O do 10
glMapGrid2f(10,O.Of,lO.Of,1 0 , 0 . 0 f , 1 0 . 0 f ) ;
gluBeginCurye
Przeznaczenie Plik
Rozpoczyna definicj krzywej NURBS.
nagwkowy
<glu.h>
Skadnia Opis
void gluBeginCurve(GLUnurbsObj *nObj);
Parametry Ta funkcja, wraz z funkcj gluEndCurve, jest uywana do okrelenia
pocztku i koca definicji krzywej NURBS.
nObj
Zwracana warto
GLUnurbsObj: Okrela obiekt NURBS. Brak.
Przykad
Poniszy fragment kodu pochodzi z programu NURBC na pytce CD-
ROM. Demonstruje zastosowanie tej funkcji w celu okrelenia pocztku
definicji krzywej NURBS.
// Renderuj krzyw NURBS
// Pocztek definicji krzywej
gluBeginCurve(pNurb);
// Obliczanie krzywej
gluNurbsCurve(pNurb,
8, Knots,
3.
SctrlPoints[0][ 0 ] ,
4. GL_MAP1_VERTEX_3)
;
// Obliczenia powierzchni
gluNurbsSurface(pNurb,
8, Knots,
8, Knots,
4*3,
3.
&ctrlPoints[0][ 0 ] [ 0 ] ,
4. 4,
GL_MAP2_VERTEX_3);
gluBeginTrim
Przeznaczenie Rozpoczyna definicj zamknitej krzywej wycinajcej obszar
powierzchni NURBS.
Plik <glu.h>
nagwkowy void gluBeginTrim(GLUnurbsObj *nObj);
Skadnia Ta funkcja, wraz z funkcjgluEndTrim, jest uywana do okrelenia
pocztku i koca definicji krzywej wycinajcej. Krzywa wycinajca jest
krzyw zamknit lub zestawem poczonych krzywych, zdefiniowanych za
pomoc funkcji gluNurbsCurye lub gluPwlCurve. Funkcje gluBeginTrim i
gluEndTrim musz wystpowa wewntrz pary wywoa
gluBeginSurface/gluEndSurface. Gdy stosujesz wycinanie, kierunek
krzywej okrela, ktra cz powierzchni zostanie wycita. Obszar
powierzchni na lewo od krzywej (patrzc w kierunku tej krzywej)
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS?!! 561
gluDeleteNurbsRenderer
Przeznaczenie Niszczy obiekt NURBS.
Plik <glu.h>
562 Cz III Tematy zaawansowane i efekty specjalne
gluEndCurye
Przeznaczenie Plik Koczy definicj krzywej NURBS.
nagwkowy <glu.h>
Skadnia Opis void gluEndCurve(GLUnurbsObj *nObj);
Ta funkcja, wraz z funkcj gluBeginCurve, jest uywana do okrelenia
Parametry pocztku i koca definicji krzywej NURBS.
nObj
Zwracana warto GLUnurbsObj: Okrela obiekt NURBS.
Przykad Patrz Brak.
take Spjrz na przykad w opisie funkcji gluBeginCurve.
gluBeginCurve
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS7H 563
gluEndSurface
Przeznaczenie Koczy definicj powierzchni NURBS.
Plik <glu.h>
nagwkowy void gluEndSurface(GLUnurbsObj *nObj);
Skadni Ta funkcja, wraz z funkcj gluBeginSurface, jest uywana do okrelenia
a Opis pocztku i koca definicji powierzchni NURBS.
gluEndfrim
Przeznaczenie Koczy definicj krzywej wycinajcej NURBS.
Pik <glu.h>
nagwkowy void gluEndTrim(GLUnurbsObj *nObj);
Skadnia Opis Ta funkcja, wraz z funkcj gluBeginTrim, jest uywana do okrelenia
pocztku i koca definicji krzywej wycinajcej NURBS. Wicej informacji
Parametry na temat krzywych wycinajcych znajdziesz w opisie funkcji
nObj gluBeginTrim.
Zwracana
warto GLUnurbsObj: Okrela obiekt NURBS.
Przykad Patrz Brak.
take Spjrz na przykad w opisie funkcji gluBeginTrim.
gluBeginTrim
gluGetNurbsProperty
Przeznaczenie Zwraca waciwo NURBS.
Plik <glu.h>
nagwkowy void gIuGetNurbsProperty(GLUnurbsObj *nObj, GLenum property,
GLloat *value);
Skadnia
Ta funkcja suy do odczytania waciwoci NURBS okrelonej dla
danego obiektu NURBS. Informacje dotyczce poszczeglnych
waciwoci znajdziesz w opisie funkcji gluNurbsProperty.
564 Cz III t Tematy zaawansowane i efekty specjalne
Parametry
nObj GLUnurbsObj: Okrela obiekt NURBS.
property GLenum: Odczytywana waciwo NURBS. Dostpne waciwoci to:
Zwracana warto GLU_SAMPLING_TOLERANCE, GLU_DISPLAY_MODE,
GLU_CULLING, GLU_AUTO_LOAD_MATRIX,
Przykad GLU_PARAMETRIC_TOLLERANCE, GLU_SAMPLING_METHOD,
GLU_U_STEP oraz GLU_V_STEP. Szczegy na temat tych parametrw
znajdziesz w opisie funkcji gluNurbsProperty.
Brak.
Poniszy przykad przedstawia sposb ustawienia waciwoci NURBS
GLU_SAMPLING_TOLERANCE na 25. W dalszej czci programu (by
moe ju w innej funkcji) wywoywana jest funkcja gluGetNurbsProperty w
celu odczytania tolerancji prbkowania.
gluNurbsProperty(pNurb, GLU_SAMPLING_TOLERANCE, 2 5 . Of};
GLfloat fTolerance;
gluGetNurbsProperty(pNurb, GLU_SAMPLING_TOLERANCE,
SfTolerance);
gluLoadSamplingMatrices
Przeznaczenie aduje macierze prbkowania i obcinania NURBS.
Plik nagwkowy <glu.h>
Skadnia void gluLoadSamplingMatrices(GLUnurbsObj *nObj, const GLfloat
modelMatrix[16], const GLfloat projMatrix[16], const GLint viewport[4]);
Ta funkcja jest uywana do ponownego przeliczenia macierzy prbkowania
Opis i obcinania dla powierzchni NURBS. Macierz prbkowania jest uywana
przy wyznaczaniu stopnia podziau powierzchni na wielokty, tak aby bya
zachowana tolerancja prbkowania. Macierz obcinania jest uywana do
wyznaczenia, czy przed renderowaniem powinny zosta wycite
niewidoczne powierzchnie. Zwykle nie trzeba wywoywa tej funkcji,
chyba e zostanie wyczona waciwo GLU_AUTO_LOAD_MATRIX.
Najczciej wycza si j przy pracy w trybach selekcji i informacji
zwrotnej.
Parametry
nObj GLUnurbsObj: Okrela obiekt NURBS.
Rozdzia 17. Krzywe i powierzchnie: co to jest NURBS?!! 565
pNurb = glNewNurbsRenderer(.
gluNewNurbsRenderer
Przeznaczenie Tworzy nowy obiekt NURBS.
Plik nagwkowy <glu.h>
Skadnia GLUnurbsObj * gluNewNurbsRenderer(void);
Ta funkcja tworzy obiekt renderowania NURBS. Ten obiekt jest
Opis
wykorzystywany do sterowania zachowaniem i charakterystykami krzywych
Zwracana warto i powierzchni NURBS. Wszystkie funkcje suce do modyfikacji
Przykad waciwoci NURBS wymagaj podania wskanika do tego obiektu. Po
zakoczeniu renderowania krzywych lub powierzchni musisz usun obiekt
NURBS wywoujc funkcj gluDeleteNurbsRenderer.
Wskanik do nowego obiektu NURBS. Ten obiekt bdzie
wykorzystywany podczas wywoywania funkcji sterujcych i
renderujcych.
Poniszy kod demonstruje tworzenie obiektu NURBS:
// Przygotowanie obiektu NURBS
// Zaczynamy od stworzenia go
pNurb = gluNewNurbsRenderer( ) ;
566 Cz III Tematy zaawansowane l efekty specjalne
.. inne waciwoci
gluNurbsCallback
Przeznaczenie Definiuje funkcj zwrotn dla NURBS.
Plik nagwkowy <glu.h>
Skadnia void gluNurbsCallback(GLUnurbsObj *nObj, GLenum which, void
gluNurbsProperty(pNurb, GLU_SAMPLING_TOLERANCE,
25. O f ) ;
. . . inne waciwoci
Tabela 17.1.
Kody bdw NURBS
Tabela 17.1.
Kody bdw NURBS - cig dalszy
gluNurbsCurye
Przeznaczenie Definiuje ksztat krzywej
Plik nagwkowy NURBS. <glu.h>
Skadnia void gluNurbsCurve(GLUnurbsObj *nObj, GLint nknots,
GLfloat *knots, GLint stride, GLfloat *ctlarray, GLint order,
GLenum type);
Opis
Ta funkcja suy do definiowania ksztatu krzywej NURBS.
Definicja krzywej musi wystpowa pomidzy wywoaniami
gluBeginCurve i gluEndCurve.
Parametry
nObj
GLUnurbsObj*: Wskanik do obiektu NURBS (utworzonego
w wyniku wywoania funkcji gluNewNurbsRenderer).
nknots
GLint: Ilo wzw w tablicy *knots. Odpowiada iloci
punktw kontrolnych plus rzd krzywej.
knots
GLfloat*: Tablica wartoci wzw, uoonych w kolejnoci niemalejcej.
Rozdzia 17. * Krzywe i powierzchnie: co to jest NURBS?!! 569
gluNurbsProperty
Przeznaczenie Ustawia waciwo NURBS.
Plik nagwkowy <glu.h>
Skadnia void gluNurbsProperty(GLUnurbsObj *nObj, GLenum property, GLfloat
value);
Opis Ta funkcja suy do ustawiania waciwoci obiektu NURBS. Dostpne s
nastpujce waciwoci:
GLU_SAMPLING_TOLERANCE: Okrela maksymaln dugo w
pikselach, ktra ma zosta uyta podczas stosowania metody
prbkowania GLU_PATH_LENGTH. Domylna warto to 50,0.
GLU_DISPLAYJMODE: Okrela sposb renderowania powierzchni
NURBS. Parametrem moe by GLU_FILL, powodujcy uycie
cieniowanych wieloktw, GLU_OUTLINE_POLYGON, powodujcy
rysowanie jedynie konturw wieloktw (ju po podziale powierzchni na
wielokty skadowe) oraz GLU_OUTLINE_PATCH, umoliwiajcy
rysowanie wycznie konturw zdefiniowanych przez uytkownika cieek i
krzywych wycinania. Domyln wartoci jest GLU_FILL.
GLU_CULLING: Warto parametru jest interpretowana jako warto
logiczna, okrelajca, czy krzywa NURBS ma by odrzucona, jeli jej
punkty kontrolne le poza widokiem.
GLU_PARAMETRIC_TOLERANCE: Ustawia maksymalny odstp
pikseli uywany, gdy metod prbkowania jest
570______________________Cz III Tematy zaawansowane i efekty specjalne
Parametry
nObj GLUnurbsObj*: Wskanik do obiektu NURBS (utworzonego w wyniku
wywoania funkcji gluNewNurbsRenderer), ktrego waciwoci maj
zosta zmodyfikowane.
property GLenum: Modyfikowana lub ustawiana waciwo NURBS. Moe ni
by jedna z poniszych waciwoci:
value
GLU_SAMPLING_TOLERANCE, GLU_DISPLAY_MODE,
Zwracana GLU_CULLING, GLU_AUTO_LOAD_MATRIX,
warto GLU_PARAMETRIC_TOLERANCE, GLU_SAMPLING_METHOD,
GLU_U_STEP oraz GLU_V_STEP.
Przykad
GLfloat: Warto przypisywana ustawianej waciwoci.
Patrz take
Brak.
Poniszy kod z programu NURBS przygotowuje tryb wywietlania
powierzchni jako siatki krawdzi:
gluNurbsProperty (pNurb, GLU_DISPLAY_MODE,
GLU_OUTLINE_POLYGON) ;
gluNurbsSurface
Przeznaczenie Definiuje ksztat powierzchni NURBS.
Plik <glu.h>
nagwkowy void gluNurbsSurface(GLUnurbsObj *nObj, GLint uknotCount, GLfloat
*uknot, GLint vknotCount, GLfloat *vknot, GLint ustride, GLint vstride,
Skadnia GLfloat *ctlarray, GLint uorder, GLint vorder, GLenum type);
Ta funkcja suy do definiowania ksztatu powierzchni NURBS. Definicja
powierzchni musi wystpowa pomidzy wywoaniami gluBeginSurface i
gluEndSurface. Ksztat powierzchni jest obliczany przed jakimkolwiek
wycinaniem. Powierzchnia NURBS moe zosta wycita przez uycie
funkcji gluBeginTrim/gluEndTrim w poczeniu z funkcjami gluNurbsCurve
i/lub gluPwlCurve.
Parametry
nObj GLUnurbsObj*: Wskanik do obiektu NURBS (utworzonego w wyniku
wywoania funkcji gluNewNurbsRenderer).
uknotCount GLint: Ilo wzw w parametrycznym kierunku u.
u knot GLfloat*: Tablica wartoci wzw, reprezentujcych wzy w kierunku u.
Wartoci w tablicy musz by uoone w kierunku niemalejcym.
Rozmiar tablicy jest okrelony parametrem uknotCount.
572 Cz III * Tematy zaawansowane i efekty specjalne
gluPwICurye
Przeznaczenie Okrela zoon z kawakw krzyw wycinania NURBS.
Plik nagwkowy <glu.h>
Skadnia void gluPwICurye (GLUnurbsObj *nObj, GLint count, GLfloat *array,
GLint stride, GLenum type);
Opis Ta funkcja definiuje zoon z kawakw krzyw wycinania dla
powierzchni NURBS. Punkty w tablicy s okrelone w parametrycznych
Rozdzia 17. * Krzywe i powierzchnie: co to jest NURBS?!! 573
// Obliczenia powierzchni
gluNurbsSurface(pNurb, // Wskanik do renderera NURBS
8, Knots, // Ilo wzw i tablica wzw w kierunku u.
8, Knots, // Ilo wzw i tablica wzw w kierunku v.
4 * 3 , // Odstp pomidzy punktami kontrolnymi
// kierunku u.
3. // Odstp pomidzy punktami kontrolnymi
// kierunku v.
&ctrlPoints[0][ 0 ] [ 0 ] , // Punkty kontrolne
4. 4, // klasa powierzchni u i v
GL_MAP2_VERTEX_3); // Rodzaj powierzchni
// Obszar zewntrzny, obejmujcy ca powierzchni
gluBeginTrim (pNurb);
gluPwlCurve (pNurb, 5, SoutsidePts[ 0 ] [ 0 ] , 2, GLU_MAP1_TRIM_2);
gluEndTrim (pNurb);
Zoone wielokty
Co sprawia, e wielokt staje si zoony? C, w OpenGL zoony wielokt to taki,
ktry albo nie jest wypuky (posiada wcicia), albo posiada otwory. Na rysunku 18.1
przedstawiono kilka prostych oraz kilka zoonych wieloktw, ktre od czasu do czasu
zdarzy ci si renderowa.
Wielokty zoone posiadaj otwory lub zakrzywienia. Prawy dolny wielokt z rysunku
18.1 jest wanie wieloktem zoonym.
Tabela 18.1.
Typy cieek funkcji glhNextContour
Rysunek 18.2.
Litera A jako
\vielokat zoony
578 Cz III Tematy zaawansowane i efekty specjalne
Aby narysowa liter A, funkcj gluNextContour wywoujemy tylko raz, przed okreleniem
wewntrznych punktw. Przykad z listingu 18.1, LETTER.C, do rysowania wirujcej litery
A uywa poniszego kodu:
tess = gluNewTess();
gluTessCallback(tess, GLU_BEGIN, glBegin);
gluTessCallbackttess, GLU_VERTEX, glVertex3dv);
gluTessCallback(tess, GLU_END, glEnd);
gluBeginPolygon(tess),
gluTessVertex(tess, outside[ 0 ] , outside[ 0 ] )
gluTessVertex(tess, outside[ 1 ] , outside[ 1 ]
gluTessVertex(tess, outside[ 2 ] , )
gluTessVertex(tess, outside[ 3 ] , outside[ 2 ] )
gluTessVertex(tess, outside[ 4 ] , outside[ 3 ] )
gluTessVertex(tess, outside[ 5 ] , outside[ 4 ]
gluTessVertex(tess, outside[ 6 ] )
, outside[ 5 ] )
gluNextContour(tess, GLU_INTERIOR) ;
gluTessVertex(tess, inside[0], inside[0]>;
gluTessVertex (tess, inside[l], inside[l]);
gluTessVertex (tess, inside[2], inside[2]);
gluEndPolygon(tess) ; gluDeleteTess (tess) ;
#ifndef WIN32
# define CALLBACK
# define APIENTRY
endif /* IWIN32 */
GLfloat rotation = 0 . 0 ;
void CALLBACK
reshape_scene (GLsizei width, /* We - Szeroko okna w pikselach */
GLsizei height) /* We - Wysoko okna w pikselach */ { /*
* Wyzerowanie biecego widoku i przeksztacenia perspektywicznego.
*/
glviewport ( O , O, width, height);
glMatrixMode (GL_PROJECTION) ;
glLoadldentity ( ) ;
gluPerspective(22.5, (float) width / (float)height, 0 . 1 , 1000.0);
glMatrixMode (GL_MODELVIEW) ;
/*
* ' draw_scene ( ) ' - Rysuje scen zawierajca, liter "A"
*/
V0id CALLBACK
draw_scene (void)
{
GLUtriangulatorObj *tess;
static GLdouble outside [ 7 ] [ 3 ] =
{
{ 0 . 0 , 1 . 0 , 0.0 },
{ -0.5, -1.0, 0.0 },
{ -0.4, -1.0, 0.0 },
{ -0.2, -0.1, 0.0 },
{ 0 . 2 , -0.1, 0.0 },
{ 0 . 4 , -1.0, 0.0 ),
{ 0 . 5 , -1.0,
0.0 } >;
static GLdouble i n s i d e [ 3 ] [ 3 ] -{
{ 0 . 0 , 0 . 6 , 0.0 },
{ -0.1, 0.1, 0.0 },
{ 0 . 1 , 0.1, 0.0
} };
static float red_light[4] = { 1 . 0 , 0 . 0 , 0 . 0 , 1 . 0 };
static float red_pos[4] = { 1 . 0 , 0 . 0 , 0 . 0 , 0 . 0 }; static
float blue_light [ 4 ] = { 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 }; static
float blue_pos[4] - { - 1 . 0 , 0 . 0 , 0 . 0 , 0 . 0 } ;
/*
* Wczenie buforw i owietlenia
*/
glEnable (GL_DEPTH_TEST) ;
glDisable (GL_LIGHTING) ;
glEnable (GL_LIGHTO) ; glEnable
(GL_LIGHT1) ;
glShadeModel (GL SMOOTH) ;
580 Cz III Tematy zaawansowane i efekty
specjalne
glClearColor( 0 . 0 , 0 . 0 , 0 . 0 , 0 . 0 ) ;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_COLOR_MATERIAL) ; .
glPushMatrix();
glTranslatef( 0 . 0 , 0 . 0 , -1 5 . 0);
glRotatef(-rotation, 0 . 0 , 1 . 0 , 0 . 0 ) ;
glColor3f( 0 . 0 , 1 . 0, 0 . 0 ) ;
glNormal3f( 0 . 0 , 0 . 0 , 1 . 0 ) ;
tess = gluNewTess ();
gluTessCallback(tess, GLU_BEGIN, glBegin);
gluTessCallback(tess, GLU_VERTEX, glVertex3dv),
gluTessCallback(tess, GLU_END, glEnd);
gluBeginPolygon(tess)
gluTessVertex(tess, outside[ 0 ] , outside[ 0 ]
gluTessVertex( t e s s, outside[ 1 ] , )
gluTessVertex(tess, outside[ 2 ] , outside[ 1 ]
gluTessVertex(tess, outside[ 3 ] , )
gluTessVertex (tess, outside[ 4 ] , outside[ 2 ]
gluTessVertex(tess, outside[ 5 ] , )
gluTessVertex(tess, outside[ 6 ] outside[ 3 ]
, ) outside
gluNextContour(tess, GLU_INTERIOR);
gluTessVertex( t e s s ,
gluTessVertex(tess inside[0],
gluTessVertex(tess inside[0]);
gluEndPolygon( t e s s ) ; inside[l], i n s i d e f l ] ) ;
gluDeleteTess(tess) ; inside[2], i n s i d e [ 2 ] ) ;
glPopMatrix();
auxSwapBuffers();
1
rotate_objects()' - W wolnych chwilach obrt s c e n y . . .
Rozdzia 18. Podzia wieloktw ________________________________ 581
V0id CALLBACK
rotate_objects (void)
{
rotation +=> 2 . 0 ; if
(rotation >= 3 6 0 . 0 )
rotation -= 3 6 0 . 0 ;
draw scen ( ) ;
/*
* 'mainO' - Inicjowanie okna i wywietlanie sceny do momentu
* wcinicia klawisza 'Esc'.
V
void
main (void)
{
aux!nitDisplayMode(AUX_RGB | AUX_DOUBLE | AUX_DEPTH) ;
auxlnitwindow("wielokt w ksztacie litery - G L U " ) ;
auxReshapeFunc (reshape_scene) ;
auxIdleFunc (rotate_objects) ;
auxMainLoop (draw_scene) ;
/*
* Koniec pliku " l e t t e r . c " .
*/
Funkcje zwrotne
Biblioteka glu definiuje kilka funkcji zwrotnych, ktre mog zosta wykorzystane do
osignicia pewnych efektw specjalnych. Funkcja gluTessCallback umoliwia zmian
tych funkcji na wasne. Wymaga podania trzech argumentw:
void gluTessCallback(GLUtriangulatorObj *tobj, GLenum which, void ( * f n ) ( ) ) ;
Argument which okrela definiowan funkcj zwrotn i musi by jedn z wartoci ze-
branych w tabeli 18.2.
Tabela 18.2.
Funkcje zwrotne triangulatora
Tabela 18.2.
Funkcje zwrotne triangulatora - cig dalszy
void
tess_error_callback(GLenum error)
{
MessageBeep(MB_ICONEXCLAMATION);
MessageBox(NULL, gluErrorString(error), "Bd GLU", MB_OK |
MB_ICONEXCLAMATION);
Podsumowanie
Triangulator wieloktw w OpenGL moe zosta uyty w celu renderowania rnoro-
dnych zoonych wieloktw, ktrych nie da si narysowa przy uyciu prymitywu
OpenGL GL_POLYGON. Podzia wieloktw ma jednak swj cen, dobrze jest wic
umieszcza podzielone wielokty na listach wywietlania, w celu poprawy wydajnoci
rysowania.
Mechanizm zwrotny daje pewn kontrol nad wygenerowanymi wynikami, nie wpywa
jednak na uywany algorytm podziau. Z tego powodu funkcje zwrotne s uywane
do rzadko.
Rozdzia 18. Podzia wieloktw_________________________________583
Podrcznik
gluBeginPolygon_____________________
Przeznaczenie Rozpoczyna podzia zoonego wielokta.
Plik nagwkowy <glu.h>
Skadnia void gluBeginPoIygon(GLUtrianguIatorObj *tObj);
Opis Ta funkcja rozpoczyna podzia zoonego wielokta.
Parametry
tObj GLUtriangulatorObj*: Wskanik do obiektu triangulatora, uywanego
przy podziale wielokta.
Zwracana warto Brak.
Przykad Przykadowy program LETTER.C na pytce CD-ROM.
Patrz take gluEndPolygon, gluNextContour, gluTessVertex
gluDeleteTess_______________________
Przeznaczenie Usuwa obiekt triangulatora.
Plik nagwkowy <glu.h>
Skadnia void gluDeleteTess(GLUtriangulatorObj *tObj);
Opis Funkcja gluDeleteTess zwalnia pami zwizan z obiektem
triangulatora.
Parametry
tObj GLUtriangulatorObj*: Wskanik do obiektu triangulatora
przeznaczonego do usunicia.
Zwracana warto Brak.
Przykad Przykadowy program LETTER.C na pytce CD-ROM.
Patrz take gluNewTess
gluEndPolygon
Przeznaczenie Koczy podzia zoonego wielokta i renderuje go.
Plik nagwkowy <glu.h>
Skadnia void gluEndPolygon(GLUtriangulatorObj *tObj);
584______________________Cz III Tematy zaawansowane i efekty specjalne
gluNewTess________________________
Przeznaczenie Tworzy obiekt triangulatora.
Plik nagwkowy <glu.h>
Skadnia GLUtriangulatorObj *gluNewTess(void);
Opis Funkcja gluDeleteTess tworzy obiekt triangulatora.
Parametry Brak.
Zwracana warto GLUtriangulatorObj *: Nowy obiekt triangulatora.
Przykad Przykadowy program LETTER.C na pytce CD-ROM.
Patrz take gluDeleteTess
gluNextContour______________________
Przeznaczenie Rozpoczyna nowy kontur lub otwr w zoonym wielokcie.
Plik nagwkowy <glu.h>
Skadnia void gluNextContour(GLUtriangulatorObj *tObj, GLenum type);
Opis Ta funkcja rozpoczyna nowy kontur lub otwr w zoonym wielokcie.
Parametry
tObj GLUtriangulatorObj*: Wskanik do obiektu triangulatora, uywanego
przy podziale wielokta.
type GLenum: Typ konturu. Dostpne typy zostay zebrane w tabeli 18.1
w treci rozdziau.
Zwracana wartoBrak.
Przykad Przykadowy program LETTER.C na pytce CD-ROM.
Patrz take gluBeginPolygon, gluEndPolygon, gluTessVertex
Rozdzia 18. * Podzia wieloktw 585
gluTessCallback
Przeznaczenie Okrela funkcj zwrotn podziau wielokta.
Plik nagwkowy <glu.h>
Skadnia void gluTessCallback(GLUtriangulatorObj *tObj, GLenum which, void
(*fn)0);
Opis Ta funkcja okrela funkcje zwrotne podziau wielokta, wywoywane na
rnych etapach podziau. Funkcje zwrotne nie wpywaj na sposb
dziaania triangulatora ani na jego wydajno. Umoliwiaj raczej
uzupenienie generowanych wierzchokw o dodatkowe informacje, takie jak
kolor czy wsprzdne tekstury.
Parametry
tObj GLUtriangulatorObj*: Wskanik do obiektu triangulatora, uywanego
przy podziale wielokta.
which GLenum: Definiowana funkcja zwrotna. Dostpne funkcje zwrotne
zostay zebrane w tabeli 18.2 w treci rozdziau.
gluTessVertex
Przeznaczenie Dodaje wierzchoek do biecej cieki
wielokta.
Skadnia
Plik nagwkowy <glu.h>
void gluTessVertex(GLUtriangulatorObj *tObj, GLdouble v[3], void *data);
Opis
Ta funkcja dodaje wierzchoek do biecej cieki podziau wielokta. Argument
data jest przekazywany w funkcji zwrotnej GL_VERTEX.
Parametry GLUtriangulatorObj*: Wskanik do obiektu triangulatora, uywanego przy podziale
tObj wielokta.
GLdouble[3]: Wierzchoek 3D.
v data void *: Wskanik do danych, ktre maj zosta przekazane w funkcji zwrotnej
GL_VERTEX.
Zwracana warto Brak.
Przykad Przykadowy program LETTER.C na pytce CD-ROM.
Patrz take gluBeginPolygon, gluEndPolygon, gluNextContour
Rozdzia 19.
Grafika interaktywna
W tym rozdziale:
Selekcja
Selekcja jest w rzeczywistoci trybem renderowania, w ktrym adne piksele nie s ko-
piowane do bufora ramki. Zamiast tego prymitywy s rysowane w bryle widzenia (tak jak
normalnie pojawiyby si w buforze ramki) w wyniku czego tworz rekordy trafie" w
buforze selekcji.
Bufor selekcji naley przygotowa wczeniej, a take nazwa prymitywy lub grupy pry-
mityww (twoich obiektw) tak, aby mona je byo zidentyfikowa w buforze selekcji.
Nastpnie przetwarza si bufor selekcji w celu wyznaczenia, ktre obiekty przecinaj
bry widzenia. Ma to marginalne znaczenie dopty, dopki nie zmodyfikujesz bryy
widzenia przed przejciem do rysowania, w celu wyznaczenia, ktre obiekty znajduj si
w okrelonym obszarze sceny. W popularnym rozwizaniu okrela si bry widzenia
odpowiadajc wskanikowi myszy, a nastpnie sprawdza, ktry z nazwanych obiektw
jest wskazywany przez mysz (zawarty w tej bryle widzenia).
Nazywanie prymityww
Moesz nada nazw kademu prymitywowi skadajcemu si na scen, lecz rzadko jest to
uyteczne. O wiele czciej bdziesz nadawa nazwy grupom prymityww, czyli
obiektom lub czciom obiektw w scenie. Nazwy obiektw, podobnie jak nazwy list
wywietlania, nie s niczym innym jak cyfrowymi identyfikatorami w postaci liczb ca-
kowitych bez znaku.
Lista nazw jest przechowywana na stosie nazw. Po zainicjowaniu stosu nazw moesz
odkada nazwy na stos lub zastpowa nazw wystpujc na szczycie stosu. Gdy podczas
selekcji nastpi trafienie, wszystkie nazwy ze stosu nazw s kopiowane do bufora selekcji.
Tak wic pojedyncze trafienie moe zwrci wicej ni jedn nazw.
tdefine SUN l
tfdefine MERCURY 2
#define VENUS 3
#define EARTH 4
Idefine MARS 5
Rozdzia 19. * Grafika interaktywna 589
Kod nadajcy nazwy z listingu 19.1 nie przynosi adnego efektu do momentu prze-
czenia si do trybu selekcji. Najczciej bdziesz uywa tych samych funkcji do ren-
derowania w obu trybach, GL_RENDER i GL_SELECTION, tak jak robimy to w tym
programie.
case WM_LBUTTONDOWN:
{
int xPos = LOWORD(IParam); // Pozioma wsprzdne kursora
int yPos = HIWORD(IParam); // Pionowa wsprzdne kursora
// Renderowanie w trybie selekcji i wywietlenie rezultatu
ProcessSelection(xPos, yPos) ;
Bufor selekcji
Podczas renderowania bufor selekcji jest wypeniany rekordami trafie. Rekord trafienia jest
generowany za kadym razem, gdy renderowany prymityw lub grupa prymityww
przecina bry widzenia. W normalnych warunkach byyby to wszystkie prymitywy, jakie
pojawiyby si na ekranie.
Rozdzia 19. Grafika interaktywna 591
Bufor selekcji to tablica liczb cakowitych bez znaku, za kady rekord selekcji zajmuje
przynajmniej cztery elementy tablicy. Pierwsza pozycja tablicy zawiera ilo nazw na
stosie nazw w momencie wystpienia trafienia. W przypadku programu PLANETS (listing
19.1) bdzie to zawsze 1. Nastpne dwie pozycje zawieraj minimaln i maksymaln
wsprzdn Z wszystkich wierzchokw zawartych w bryle widzenia od ostatniego
rekordu trafienia. Ta warto, z zakresu <0, 1>, jest skalowana do wartoci liczb
cakowitych bez znaku (232 - 1) w celu przechowania w buforze selekcji. Ten wzr,
przedstawiony na rysunku 19.1, powtarza si dla wszystkich rekordw trafie w buforze
selekcji.
Rysunek
19.1. Bufor selekcji [0] w Ilo nazw na stosie nazw w momencie
Format rekordu
trafienia = n,
trafienia w buforze
selekcji [ l ] ^- Minimalna warto z [2] ^-
Maksymalna warto z [n0+2] -^-Dno
stosu nazw
Z formatu bufora selekcji nie wynika adna informacja o iloci rekordw trafie, jakie
trzeba przeanalizowa. Dzieje si tak, poniewa bufor selekcji w rzeczywistoci nie jest
wypeniany a do momentu powrotu do trybu GL_RENDER. Gdy przeczysz si do
tego trybu funkcj glRenderMode, warto zwracana przez t funkcj odpowiada iloci
rekordw trafie skopiowanych do bufora.
// Pobranie widoku
glGetIntegerv(GL_VIEWPORT, viewport);
// Wyrysowanie sceny
RenderScene();
// Zliczenie trafie
hits = glRenderMode(GL_RENDER);
Wybieranie
Wybieranie nastpuje wtedy, gdy podczas selekcji wykorzystujesz pooenie myszy do
utworzenia i uycia zmodyfikowanej bryy obcinania. Po utworzeniu mniejszej bryy
widzenia umieszczonej w scenie na miejscu wskanika myszy, trafienia bd generowane
jedynie przez te obiekty, ktre przecinaj t bry widzenia. Sprawdzajc zawarto
bufora selekcji, moesz wic sprawdzi, na ktrych obiektach nastpio kliknicie
myszk.
Podczas tworzenia macierzy opisujcej now bry widzenia bardzo przydaje si funkcja
gluPickMatrix:
Rozdzia 19. Grafika interaktywna_______________________________593
Wynik dziaania programu PLANETS zosta pokazany na rysunku 19.2, na ktrym wi-
dzimy efekt kliknicia na drug planet od Soca.
Rysunek 19.2.
Dziaanie programu PLANETSpo
klikniciu na panet
Wybr hierarchiczny
W programie PLANETS
nie odkadalimy nazw na
stos, lecz jedynie
zastpowalimy znajdujc
si na nim nazw. Ta
pojedyncza nazwa ze stosu
bya jedyn nazw zwra-
can w buforze selekcji. Po
umieszczeniu wikszej iloci
nazw na stosie nazw moglibymy otrzyma kilka nazw w buforze. Jest to uyteczne w
sytuacjach, gdy potrzebujemy dalszych informacji, na przykad, gdy chcemy by
poinformowani, e zostaa trafiona okrelona ruba, w okrelonym kole, w okrelonym
samochodzie w scenie itd.
Rysunek 19.3.
Dwie planety z ksiycami
Zamiast identyfikowa
jedynie planet lub ksiyc,
na ktrych nastpio
kliknicie, bdziemy
identyfikowa take planet
zwizan z danym
ksiycem. Kod z listingu
19.4 przedstawia nowy kod
renderowania naszej sceny.
Oprcz nazw planet
odkadamy na stos take
nazwy ksiycw, przez co
bdzie on zawiera zarwno
nazw planety, jak i wybranego ksiyca.
define EARTH l
#define MARS 2
define MOON1 3
#define MOON2 4
// Wywoywane w celu narysowania sceny
void RenderScene(void)
{
// Wyczyszczenie okna biecym kolorem ta
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Rysowanie Ziemi
glPushMatrix();
glRGB(0,0,255) ;
glTranslatef(-100.Of,O . O f , O . O f ) ;
glLoadName(EARTH);
auxSolidSphere(30.Of);
596 _______________________ Cz III Tematy zaawansowane i efekty specjalne
// Rysowanie Marsa
glRGB(255,0,0) ;
glPushMatrix () ;
glTranslatef (100. Of, O.Of, O . O f ) ;
glLoadName(MARS) ;
auxSolidSphere (20 . Of ) ;
Listing 19.5 przedstawia funkcj ProcessPlanet, ktra w tym przykadzie jest bardziej
rozbudowana. W tym przypadku dolna nazwa na stosie nazw zawsze bdzie nazw planety,
gdy zostaa odoona na stos jako pierwsza. Jeli nastpi kliknicie na ksiyc, on take
znajdzie si na stosie nazw. Ta funkcja wywietla nazw wybranej planety, a jeli zosta
trafiony ksiyc, ta informacja rwnie jest wywietlana. Przykad dziaania programu
zosta przedstawiony na rysunku 19.4.
Rozdzia 19. Grafika interaktywna 597
Rysunek
19.4.
Przykad dziaania
programu MOONS
Sprzenie zwrotne
Sprzenie zwrotne (ang. feedbacK), podobnie jak selekcja, jest trybem renderowania, w
ktrym nic nie jest rysowane na ekranie. Zamiast tego, do bufora sprzenia zwroten-go
wpisywane s informacje na temat sposobu renderowania sceny. Te informacje obejmuj
wsprzdne okna przetransformowanych wierzchokw, kolory wierzchokw ju po
owietleniu, a take dane tekstury.
Przejcie do trybu sprzenia zwrotnego odbywa si podobnie jak przejcie do trybu se-
lekcji, poprzez wywoanie funkcji glRenderMode z parametrem GLJFEEDBACK. W
celu wypenienia bufora sprzenia zwrotnego i powrotu do normalnego trybu renderowania
musisz wywoa funkcj glRenderMode(GL_RENDER).
Tabela 19.2.
Elementy bufora sprzenia zwrotnego
Element Prymityw
GL_POINT_TOKEN Punkty
GL_LINE_TOKEN Linie
GL_LINE_RESET_TOKEN Segment linii po wyzerowaniu wzorca linii
GL_POLYGON_TOKEN Wielokt
GL_BITMAP_TOKEN Bitmapa
GL_DRAW_PIXEL_TOKEN Narysowany prostokt piksela
GL_COPYJ?IXEL_TOKEN Skopiowany prostokt piksela
GL_PASS_THROUGH_TOKEN Znacznik zdefiniowany przez uytkownika
Rysunek 19.5.
Przykad zawartoci Bufor sprzenia zwrotnego - GL POINTJOKEN
bufora sprzenia [I] - Wsprzdna x
zwrotnego [2] -Wsprzdnay
[3] -Wsprzdna;
[4] - GL_PASS_THROUGH_TOKEN
[5] - Warto zdefiniowana przez uytkownika
[6] GL_POLYGON_TOKEN
[7] Ilo wierzchokw wielokta
[8] - Wsprzdna x pierwszego wierzchoka
[9] Wsprzdna y pierwszego wierzchoka
[10] - Wsprzdna z pierwszego wierzchoka
[II] - Wsprzdna x drugiego wierzchoka
Znaczniki uytkownika
Podczas wykonywania kodu renderowania, bufor sprzenia zwrotnego jest wypeniany
elementami i danymi wierzchokw dla kadego podanego prymitywu. Podobnie jak w
trybie selekcji, moesz zaznacza poszczeglne prymitywy nadajc im nazwy. W trybie
sprzenia zwrotnego moesz take ustawia znaczniki pomidzy prymitywami. Suy
do tego funkcja glPassThrough:
void glPassThrough(GLfloat token);
Przykad
Doskonaym wykorzystaniem sprzenia zwrotnego jest uzyskiwanie informacji o wsp-
rzdnych okna dotyczcych renderowanych obiektw. Otrzymane informacje moesz
wykorzysta w celu umieszczenia kontrolek w pobliu obiektw lub w celu zintegrowania
grafiki GDI z obiektami w oknie.
#define CUBE l
#define SPHERE 2
// Rysowanie kuli
g!RGB(128,0,0) ;
glTranslatef(130.Of, O . O f , O . O f ) ;
glLoadName(SPHERE);
glPassThrough((GLfloat)SPHERE);
auxSolidSphere( 5 0 . O f ) ;
602 Cz III Tematy zaawansowane i efekty specjalne
// Pobranie widoku
glGet!ntegerv(GL_VIEWPORT, viewport);
// Przejcie do macierzy rzutowania i zachowanie jej
glMatrixMode(GL_PROJECTION); glPushMatrix();
Rozdzia 19. Grafika interaktywna_______________________________603
// Wyrysowanie sceny
RenderScene ( ) ;
else
i++; // Przejcie do nastpnego indeksu
break;
Podsumowanie
Selekcja i sprzenie zwrotne to dwa bardzo uyteczne elementy OpenGL, umoliwiajce
interakcj uytkownika ze scen. Selekcja i wybr s uywane przy identyfikacji obiektu
lub regionu sceny we wsprzdnych OpenGL, a nie we wsprzdnych okna. Sprzenie
zwrotne zwraca cenne informacje dotyczce pooenia rysowanych prymityww we
wsprzdnych okna. Moesz uy tych informacji w celu zintegrowania grafiki OpenGL z
grafik GDI w Windows.
Podrcznik
glFeedbackBuffer
Przeznaczenie Przygotowuje bufor sprzenia zwrotnego.
Plik nagwkowy <gl.h>
606 Cz III Tematy zaawansowane i efekty specjalne
gllnitNames_______________________
Przeznaczenie Przygotowuje bufor sprzenia zwrotnego.
Plik nagwkowy <gl.h>
Skadnia void glInitNames(void);
Opis Stos nazw jest uywany w celu umoliwienia rysowania prymityww lub
grup prymityww o nazwach nadanych podczas renderowania w trybie
selekcji. Za kadym razem gdy prymitywowi zostaje nadana nazwa, jest
ona odkadana na stos nazw funkcjglPushName lub zastpuje aktualn
nazw na szczycie stosu, za pomoc funkcji glLoadName. Funkcja
gllnitNames zeruje stos nazw, usuwajc z niego wszystkie wystpujce
nazwy.
Zwracana warto Brak.
Przykad Poniszy kod pochodzi z programu PLANETS. Inicjuje stos nazw
i umieszcza na nim pojedyncz warto.
// Inicjowanie stosu nazw
gllnitNames O;
glPushName( 0 ) ;
Patrz take gllnitNames, glPushName, glRenderMode, glSelectBuffer
glLoadName________________________
Przeznaczenie Umieszcza nazw na szczycie stosu nazw.
Plik nagwkowy <gl.h>
Skadnia void glLoadName(GLuint name);
Opis Ta funkcja umieszcza podan nazw na szczycie stosu nazw. Stos nazw
jest uywany do nazywania prymityww lub grup prymityww podczas
renderowania w trybie selekcji. Podana nazwa zastpuje aktualn nazw
na szczycie stosu.
608 Cz III * Tematy zaawansowane i efekty specjalne
Parametry
name GLuint: Nazwa, ktra ma zosta umieszczona na szczycie stosu nazw.
Nazwy selekcji s liczbami cakowitymi bez znaku.
Zwracana warto Brak.
Przykad Poniszy kod z programu PLANETS przedstawia adowanie nazwy na
Patrz take stos nazw, tu przed przystpieniem do renderowania obiektu.
// Ustawienie koloru materiau na ty //
Soce
glRGB(255, 255, 0);
glLoadName( S U N ) ;
auxSolidSphere( 1 5 . Of);
gllnitNames, glPushName, glRenderMode, glSelectBuffer
gIPassThrough
Przeznaczenie Umieszcza znacznik w buforze sprzenia zwrotnego.
Plik nagwkowy
Skadnia Opis void glPassThrough(GLfloat token);
Gdy OpenGL zostanie przeczony do trybu sprzenia zwrotnego, w
buforze ramki nie s rysowane adne piksele. Zamiast tego w buforze
sprzenia zwrotnego jest umieszczana informacja o rysowanych
prymitywach. Ta funkcja umoliwia umieszczenie w buforze elementu
GL_PASS_THROUGH_TOKEN, a zaraz po nim wskazanej
zmiennoprzecinkowej wartoci. Funkcja jest wywoywana w kodzie
renderujcym i poza trybem sprzenia zwrotnego nie wywouje adnego
efektu.
Parametry
token GLfloat: Warto, ktra ma zosta umieszczona w buforze sprzenia
zwrotnego bezporednio po elemencie GL_PASS_THROUGH_TOKEN.
Zwracana warto Brak.
Przykad Poniszy kod z programu SELECT demonstruje czne uycie funkcji
gIPassThrough i glLoadName w celu zidentyfikowania obiektu. W ten
sposb obiekt jest zaznaczany zarwno w buforze selekcji, jak i w
buforze sprzenia zwrotnego.
// Ustawienie koloru materiau na ty //
Kostka
glRGB(255, 255, 0) ;
glLoadName(CUBE);
gIPassThrough((GLfloat)CUBE);
auxSolidCube(75.0f);
gIPopName
Przeznaczenie Zdejmuje (usuwa) nazw ze szczytu stosu nazw.
Plik
nagwkowy void glPopName(void);
Skadnia Opis Stos nazw jest uywany podczas selekcji w celu identyfikacji rysowanych
obiektw. Ta funkcja powoduje usunicie nazwy ze szczytu stosu nazw.
Zwracana Biec wysoko stosu nazw mona odczyta wywoujc funkcj glGet z
warto parametrem GL_NAME_STACK_DEPTH.
Przykad Brak.
Poniszy kod z programu MOONS umieszcza na stosie nazw nazw planety
oraz nazwy jej ksiycw. Ten kod ilustruje zwaszcza zdejmowanie ze stosu
nazwy pierwszego ksiyca przed umieszczeniem na nim nazwy nastpnego
ksiyca.
// Rysowanie Marsa
glRGB(255,0,0) ;
glPushMatrix ( ) ;
glTranslatef ( l O O . O f , O . O f , O . O f ) ;
glLoadName (MARS) ;
auxSolidSphere (20. Of) ;
// Rysowanie pierwszego ksiyca
glTranslatef (-40. Of, 40. Of, O . O f ) ;
glRGB(220,220,220) ; glPushName (MOON1) ;
auxSolidSphere (5.0f ) ; gIPopName ( ) ;
// Rysowanie drugiego ksiyca
glTranslatef ( O . O f , -80. Of, O . O f ) ;
glPushName (MOON2) ; auxSolidSphere (5 .
Of ) ; gIPopName ( ) ; glPopMatrix ( ) ;
gllnitNames, glLoadName, glRenderMode, glSelectBuffer, glPushName
glPushName
Patrz take
name GLuint: Nazwa, ktra ma zosta odoona na szczyt stosu nazw. Nazwy
selekcji s liczbami cakowitymi bez znaku.
Zwracana warto Brak.
Przykad Poniszy kod z programu MOONS umieszcza na stosie nazw nazw planety
oraz nazwy jej ksiycw. Ten kod ilustruje zwaszcza odkadanie na stos
nazw ksiycw, po odoeniu na niego nazwy planety. Nazwa pierwszego
ksiyca jest zdejmowana ze stosu przed umieszczeniem na nim nazwy
nastpnego ksiyca.
// Rysowanie Marsa
glRGB(255,0,0) ;
glPushMatrix() ;
glTranslatef(lOO.Of, O.Of, O . O f ) ;
glLoadName(MARS);
auxSolidSphere(20. Of) ;
// Rysowanie pierwszego ksiyca
glTranslatef(-40.Of, 40.Of,
O . O f ) ; glRGB(220,220,220) ;
glPushName(MOON1) ;
auxSolidSphere(5.0f) ; glPopName();
// Rysowanie drugiego ksiyca
glTranslatef( O . O f , -80.Of, O . O f ) ;
glPushName(MOON2);
auxSolidSphere(5.0f) ; glPopName();
glPopMatrix();
gllnitNames, glLoadName, glRenderMode, glSelectBuffer, glPopName
Patrz take
glRenderMode
Przeznaczenie Przecza OpenGL w jeden z trzech trybw renderowania.
Plik nagwkowy <gl.h>
Skadnia Opis GLint glRenderMode(GLenum mod);
OpenGL dziaa w jednym z trzech trybw renderowania:
GL_RENDER: Tryb rysowania (domylny). Efekt wywoania funkcji
rysunkowych umieszczany jest w buforze ramki.
GL_SELECT: Tryb selekcji. W tym trybie w buforze ramki nie s
dokonywane adne zmiany. Zamiast tego do bufora selekcji zapisywane
Rozdzia 19. Grafika interaktywna 611
gISelectBuffer
Przeznaczenie Ustawia bufor uywany w trybie selekcji.
Plik nagwkowy <gl.h>
Skadnia void glSelectBuffer(GLsizei size, GLuint *buffer);
Opis Gdy OpenGL dziaa w trybie selekcji (GL_SELECT), polecenia
rysunkowe nie powoduj rysowania pikseli w buforze ramki. Zamiast tego
generuj rekordy trafie, ktre s umieszczane w buforze selekcji,
przygotowanym przez t funkcj. Kady rekord trafienia skada si z
nastpujcych danych:
Iloci nazw na stosie nazw w momencie wystpienia trafienia.
Minimalnej i maksymalnej wartoci Z wszystkich wierzchokw
prymityww przecinajcych bry widzenia. Te wsprzdne s
skalowane do rozmiaru liczby cakowitej bez znaku (232 - 1).
Zawartoci stosu nazw w momencie trafienia, poczynajc od najgbiej
pooonego elementu.
Rozdzia 19. Grafika interaktywna 613
Parametry
size GLsize: Rozmiar bufora wskazywanego przez *buffer.
buffer GLuint*: Wskanik do zaalokowanego obszaru pamici. Brak.
Zwracana warto Poniszy kod przedstawia tworzenie bufora selekcji w programie
PLANETS.
Przykad
// Przetwarzanie selekcji, wywoywane w momencie kliknicia
// myszk w miejscu o wsprzdnych ( x P o s , yPos)
tdefine BUFFER_LENGTH 64
void ProcessSelection(int xPos, int yPos)
{
// Miejsce na bufor selekcji
GLuint selectBuff[BUFFER LENGTH];
gluPickMatrix
Przeznaczenie Definiuje obszar selekcji, ktry moe zosta uyty w celu wyznaczenia
wyboru dokonanego przez uytkownika.
Plik nagwkowy <glu.h>
Skadnia void gluPickMatrix(GLdouble x, GLdouble y, GLdouble width,
GLdouble height, GLint viewport[4]);
Opis Ta funkcja tworzy macierz, ktra na podstawie wsprzdnychekranu
definiuje mniejsz bry widzenia w oparciu o wsprzdne ekranu,
przeznaczon do wyboru obiektw. Uywajc w tej funkcji wsprzdnych
myszy w trybie selekcji, moesz wyznaczy, ktre obiekty s wskazywane
myszk. Tworzona macierz jest mnoona przez biec macierz rzutowania.
Zwykle powiniene wic wywoa funkcj glLoadldentity przed
wywoaniem tej funkcji, nastpnie przemnoy j przez macierz
perspektywy uytej do stworzenia oryginalnej bryy widzenia. Jeli uywasz
funkcji gluPickMatrix w celu wybrania powierzchni NURBS, przed
zastosowaniem tej funkcji musisz wyczy waciwo NURBS GLU
AUTO LOAD MATRIX.
Parametry
// Wyrysowanie sceny
RenderScene ();
// Zliczenie trafie
hits = glRenderMode(GL_RENDER);
Patrz take
Rozdzia 20.
OpenGL w Sieci: VRML
OpenGL ma wiele zastosowa. W tym rozdziale omwimy jedno z nich, ktre stao si
ostatnio bardzo popularne: rzeczywisto wirtualn.
odwiedzajc rne miejsca (strony WWW) i zbierajc rne rodzaje informacji. Byoby
wic sensowne, gdyby mona to byo robi w jakim wizualnym rodowisku, a nie tylko
poprzez seri trudnych do przebrnicia tekstowych opisw.
Graficzna nawigacja w Internecie pierwszy raz pojawia si, gdy Tim Berners-Lee z
CERN (europejskie centrum fizyki nuklearnej) w Genewie opracowa zestaw protokow
umoliwiajcych atwe zakodowanie poczenia pomidzy rnymi plikami zawartymi w
archiwach FTP. Te poczenia wizay ze sob dokumenty z innymi dokumentami o
powizanej treci, umoliwiajc przechodzenie z dokumentu do dokumentu, i to nawet w
innej kartotece, w innym komputerze czy na innym kontynencie. W tych protokoach
zostay wykorzystane nazwy URL (Universal Resource Locator), identyfikujce pooenie
dokumentw i stanowice podstaw sieci WWW.
Wkrtce po tym, Marc Andersen (ktry pniej zaoy Netscape Communications Cor-
poration) stworzy przegldark Sieci, ktra moga czy rne rodzaje plikw, cznie z
tekstem i grafik, w pojedyncz prezentacj. T przegldark by NCSA Mosaic, ktry
mg reprezentowa powizania pomidzy dokumentami, a take wykorzystywa
specjalny jzyk definiujcy format dokumentw z osadzonymi obrazkami i rnymi
rodzajami tekstu. Od tego momentu Internet nie by ju taki jak przedtem. W cigu nie-
caego roku, Internet z wycznej domeny profesjonalistw przeksztaci si w dostpny
dla kadego wirtualny wiat, umoliwiajcy dotarcie do kadego miejsca po kilku kli-
kniciach myszk.
Dwuwymiarowa nawigacja
Rysunek 20.1.
Typowa strona
WWW z czami
hipertekstowymi
VRML
Graficzna, cho wci dwuwymiarowa metoda nawigacji po Sieci w cigu kilku lat staa si
niezwykle popularna. Taka nawigacja" po cyberprzestrzeni jest bardzo efektywna i
wygodna, pod warunkiem, e przeszukiwane informacje mog by przedstawione w
postaci dokumentw. Jednak wiat nie jest bibliotek, za moliwo przedstawienia
wszystkiego jako dwuwymiarowego obrazu jest w znacznym stopniu ograniczona.
W 1994 roku Mark Pesce i Tony Parisi stworzyli nowy typ dokumentu i przegldarki
WWW, ktra umoliwiaa poruszanie si po trjwymiarowych dokumentach. Na dzie
w. Walentego 1994 roku powsta pierwszy trjwymiarowy serwer WWW. Serwer umo-
liwia poruszanie si w przestrzeni 3D i klikanie na obiekty, stanowice cza do innych
scen 3D lub zwykych stron HTML.
Trjwymiarowe sceny byy opisane za pomoc nowego jzyka skryptw, VRML (Vir-tual
Reality Markup Language lub Yirtual Reality Modeling Language). Silicon Graphics
(SGI), wiatowy lider w technologii grafiki komputerowej, zdecydowa si na
publiczne udostpnienie swojego jzyka opisu sceny Open Inventor, ktry sta si pod-
staw dla VRML w wersji l .0.
WebSpace
Oczywicie, to Silicon Graphics bya pierwsz firm, ktra stworzya w peni zgodn,
komercyjnie dostpn przegldark VRML. Przegldarka nosia nazw WebSpace i sta-
nowia standard, z ktrym porwnywane byy wszystkie inne przegldarki VRML.
WebSpace zostaa zaprojektowana do dziaania na wasnych stacjach roboczych SGI,
jednak niezalena firma, Template Graphics Software, otrzymaa pozwolenie na opraco-
wanie wersji programu dla Microsoft Windows i innych platform. Wszystkie wersje tej
przegldarki w peni obsuguj standard VRML 1.0 i do renderowania scen wykorzystuj
OpenGL.
Instalacja
WebSpace moe zosta zainstalowana jako pomocnicza aplikacja wikszoci przegldarek
WWW. Aby uzyska informacje na temat sposobu instalacji, zajrzyj do pliku
README swojej przegldarki. WebSpace aduje plik VRML z rozszerzeniem .wrl, a
take pliki scen Open Inventora z rozszerzeniem .iv. Dodatkowo, najnowsza wersja
WebSpace z Template Graphics automatycznie aduje pliki .wrl skompresowane jako
gzip, w popularnym w Internecie formacie kompresji. Dziki temu mamy do czynienia ze
znacznie mniejszymi plikami, ktre mona o wiele szybciej cign.
Tryb spacerowy
Przegldarka WebSpace moe dziaa w dwch trybach. Pierwszym z nich jest tryb spa-
cerowy (Walk Yiewer), ktry pozwala na poruszanie si po prezentowanym modelu, takim jak
muzeum czy model architektoniczny. Drugim trybem jest tryb ogldania (Examiner
Yiewer), uywany do ogldania obiektw w WebSpace, takich jak samolot, narzdzie czy
element umeblowania. Wkrtce poznasz oba tryby w dziaaniu.
Rysunek 20.2 przedstawia przegldark WebSpace podczas przegldania przykadowej
sceny VRML w trybie spacerowym. Ten tryb jest uywany do poruszania si w trjwy-
miarowej scenie. Moe ni by nieskomplikowany trjwymiarowy teren, architektoniczny
widok budynku, dom towarowy czy nawet obszar maego miasta.
Rozdzia 20. OpenGL w Sieci: VRML 619
Rysunek
20.2.
Przegldarka
WebSpace
dziaajca \v trybie
w gr lub w d, aby przej do przodu lub do tyu albo w lewo lub w prawo, aby obrci
si w wybranym kierunku.
Rysunek 20.3.
Dziki uyciu gaki
najoysticku moemy
spojrze w kierunku
podogi
Tryb ogldania
Tryb ogldania, jak sama nazwa wskazuje, umoliwia blisze przyjrzenie si obiektom.
Rysunek 20.4 przedstawia przegldark WebSpace podczas ogldania modelu komputera.
Wyobra sobie, e wdrujesz po wirtualnym muzeum w trybie spacerowym, a nastpnie
klikasz na may obrazek komputera. Gdy przegldarka przeczy si w tryb ogldania,
moesz przyjrze si komputerowi bliej. Oprcz tego, moesz mie do dyspozycji inne
hipertekstowe cza prowadzce do opisu komputera, gier komputerowych itd.
Rozdzia 20. OpenGL w Sieci: VRML 621
Rysunek 20.4.
Tryb ogldania
Jak wida, deska rozdzielcza w trybie ogldania wyglda podobnie jak w trybie space-
rowym, z tym e joystick zosta zastpiony trackballem i pokrtem. Pokrto umoliwia
zblianie si do obiektu lub oddalanie od niego. Kliknij na pokrto i przecignij je w
gr, aby oddali si od obiektu, lub w d, aby si przybliy. Rysunek 20.5 przedstawia
model komputera z wikszej odlegoci.
Rysunek 20.5.
Model komputera w
trybie ogldania,
widziany z nieco
wikszej odlegoci
622_______________________Cz III Tematy zaawansowane i efekty specjalne
Gdy do tworzenia sceny lub obiektu jest uywany OpenGL, kada funkcja i polecenie
wywiera natychmiastowy wpyw na bufor ramki. Dopki nie uywasz podwjnego
buforowania, wynik kadej instrukcji jest od razu widoczny na ekranie. Nazywa si to
renderowaniem w trybie natychmiastowym.
Z kolei Open Inventor operuje w tzw. trybie wstrzymywanym. W tym trybie, uywane
polecenia i funkcje su do utworzenia bazy danych sceny. Dopiero potem baza danych
obiektw i materiaw jest renderowana w caoci i tworzy scen na ekranie. Du
zalet tego trybu jest to, e bardzo atwo mona programowo manipulowa poszczeglnymi
obiektami sceny. Co wicej, mona ustanowi powizania pomidzy obiektami, co
umoliwia manipulowanie jednym obiektem poprzez manipulowanie innym obiektem
(na przykad elementami przekadni w modelach mechanicznych). Dziki obiektom
biblioteki Open Inventor mona atwo obraca obiekty, animowa je i wykonywa inne
operacje. Informacja o modyfikacji obiektu jest umieszczana w bazie danych, bez
koniecznoci stosowania adnego dodatkowego kodu.
Specyfikacja VRML 1.0 jest oparta wycznie na formacie wymiany dla trjwymiaro-
wych" plikw Open Inventora. Ten format plikw, stanowicy po prostu ustandaryzo-
wany opis ukadu obiektw w scenie, umoliwia projektantom 3D atw modyfikacj
obiektw i scen za pomoc rnych narzdzi opartych na bibliotece Open Inventor.
Dziki nim mona atwo stworzy i zapisa do pojedynczego pliku zarwno indywi-
dualne obiekty, jak i cae sceny wypenione obiektami.
Podsumowanie
WebSpace nie jest jedynym sposobem odwiedzenia cyberprzestrzeni w trzech wymiarach.
Wielu innych producentw (cznie z Microsoftem) przystpio do wspzawodnictwa
tworzc wasne wersje przegldarek VRML. Unikatowa cecha WebSpace to zgodno
prawie z wszystkimi przegldarkami WWW i operowanie na plikach VRML oraz Open-
Inventora, i to skompresowanych lub nie.
Rozdzia 20. OpenGL w Sieci: VRML_______________________________623
Obecnie coraz wiksza liczba programistw przy tworzeniu aplikacji dla Windows ko-
rzysta z C++. Jak dotd w treci ksiki prezentowalimy jedynie kod napisany w C. Na
szczcie, wikszo programistw C++ doskonale daje sobie rad z analiz programw
napisanych w C. Niestety, nie jest to ju tak powszechne w odwrotnej sytuacji (wielu
programistw C ma kopoty ze zrozumieniem kodu C++). Nie twierdzimy, e C++ jest
znacznie trudniejszy w opanowaniu, lecz gdy sigasz po ksik na temat grafiki kom-
puterowej z zamiarem opanowania wanie tego tematu, raczej nie chcesz przy okazji
uczy si nowej skadni jzyka.
aplikacji C++ nie zawiera procedur takich jak przedstawione w tej ksice ani tych in-
strukcji case z pieka rodem", obsugujcych komunikaty przekazywane do okien.
Celem tego rozdziau jest pomoc programicie C++ w wykorzystaniu jednej z popularnych
bibliotek klas C++ jako punktu wyjcia dla wasnych aplikacji C++. Bibliotek klas
opisywan w tym rozdziale jest MFC (Microsoft Foundation Classes). Przykady i zrzuty
okien wystpujce w tym rozdziale zostay przygotowane przy uyciu Microsoft Yisual
C++ 5.0. Inne kompilatory i pakiety wykorzystujce MFC powinny dziaa podobnie.
Uwaga:
Jeli uywasz OWL (Object Windows Library Borlanda), przejd
do rozdziau 22.
extern "C" {
Rozdzia 21. OpenGL i MFC____________________________________629
Zaczynamy od AppWizarda
Wiele aplikacji napisanych w C++ zaczyna istnienie od AppWizarda. Architektur do-
kumentu-widoku mona porwnywa z architektur modelu-widoku w innych obie-
ktowo zorientowanych rodowiskach programistycznych. Nawet w przypadku szybkich,
prbnych aplikacji lub eksperymentalnych projektw, AppWizard moe w nieca minut
utworzy aplikacj SDI (z pojedynczym dokumentem), MDI (z wieloma dokumentami)
lub opart na oknie dialogowym. Tak wic sensownie bdzie uy wanie AppWizarda w
celu stworzenia szkieletu aplikacji SDI MFC, w ktrej pniej wykorzystamy take
OpenGL. Aby stworzy prost scen OpenGL, dodamy funkcje i zmienne do klasy wi-
doku, wyprowadzonej z CYiew. Podobnych metod bdziesz mg uy w celu dodania
elementw OpenGL do kadej klasy wyprowadzonej z CWnd.
Budowanie szkieletu
Zaczniemy od zbudowania szkieletu aplikacji SDI za pomoc AppWizarda, pomijajc
opcje zwizane z dostpem do baz danych i funkcjonalnoci OLE. Rysunek 21.1
przedstawia oryginaln szkieletow aplikacj SDI stworzon przez AppWizarda.
630 Cz IV OpenGL i
Rysunek 21.1.
Oryginalna
szkieletowa
aplikacja SDI
stworzona przez
AppWizarda
By moe zechcesz take wyczy opcj wydruku (Print) i podgldu wydruku (Print
Preview). Sceny OpenGL mog by renderowane w kontekcie urzdzenia drukarki tylko
wtedy, gdy drukarka jest drukark kolorow obsugujc co najmniej cztery lub wicej
bitplanw koloru (16 lub wicej kolorw). Drukowanie na monochromatycznej drukarce
laserowej lub mozaikowej take jest moliwe, lecz do kopotliwe. Przykad kodu
sucego do drukowania scen przy uyciu nowych elementw OpenGL w wersji l. l
znajdziesz w uzupeniajcym przykadzie GLPRTNT, na pytce CD-ROM, w folderze
\OPENGL11 \SAMPLES\GLPRINT.
Dodawanie bibliotek
Zanim zaczniemy dodawa do szkieletu aplikacji jakikolwiek kod OpenGL, musimy
doda do projektu biblioteki OpenGL. W tym celu wybierz w menu polecenie Project/
Settings. Rysunek 21.2 przedstawia miejsce, gdzie powiniene dopisa nazwy bibliotek
OpenGL. By moe dodasz do projektu take inne biblioteki, w zalenoci od potrzeb
swojej aplikacji. Na rysunku zostay przedstawione jedynie pliki wymagane dla aplikacji
OpenGL.
Oprcz tego bdziesz musia doda do projektu pliki nagwkowe OpenGL. Najlepiej
umieci je w pliku stdafx.h (a potem mona ju o nich zapomnie). Dopisz po prostu
dwie ponisze linie wczajce pliki nagwkowe, ktre zostan dopisane take do pre-
kompilowanego pliku nagwkowego:
tinclude <gl\gl.h> // Biblioteka OpenGL
tinclude <gl\glu.h> // Biblioteka GLU OpenGL
Rozdzia 21. OpenGL i MFC 631
Rysunek 21.2.
Dodawanie bibliotek
OpenGL do projektu
VisualC++
return CView::PreCreateWindow( e s ) ;
Zwr uwag, e ustawiamy take styl CS_OWNDC, dziki ktremu okno moe posiada
prywatny kontekst urzdzenia. Cho nie jest to rygorystycznie wymagane, powoduje
szybsze i wydajniejsze dziaanie programu. Niektre wskaniki do kontekstw urzdze
632 Cz IV OpenGL i...
OnDestioy
OnDiao.
PieOeaeWindow
Listing 21.1. Procedura obsugi komunikatu WM CREATE, w ktrej przygotowujemy format pikseli____
return 0;
VERIFY(wglMakeCurrent(m_hDC,m_hRC));
GLResize( e x , cy);
VERIFY(wglMakeCurrent(NULL,NULL));
Renderowanie sceny
Teraz moemy doda kod odpowiedzialny za renderowanie sceny w OpenGL. Metoda
OnDraw klasy widoku jest wywoywana za kadym razem, gdy okno otrzymuje komunikat
WM_PAINT. Wewntrz tej metody wybieramy kontekst renderowania jako biecy i
wywoujemy funkcj GLRenderScene, zawierajc jedynie wywoania funkcji OpenGL.
Poniewa wczeniej zadalimy trybu z podwjnym buforowaniem, zaraz po tym
wywoujemy funkcj SwapBuffers i odkadamy kontekst renderowania.
Rozdzia 21. OpenGL i MFC____________________________________635
Obsuga palety
Ostatnie poprawki dotyczce naszego przykadu MFC zwizane s z obsug palety, co
wie si ze stworzeniem i zrealizowaniem palety RGB dla urzdze korzystajcych z
palety (kart 256-kolorowych). Zamiast przechowywa uchwyt palety, tak jak w rozdziale
8, stworzymy obiekt MFC typu CPalette. Dla listingu 21.2, w pliku mfcglYiew.h
deklarujemy egzemplarz obiektu klasy CPalette:
CPalette m_GLPalette; // Paleta logiczna
a nastpnie rcznie dodajemy do klasy CMfcglYiew metod inicjujc palet. Jej kod
jest niemal identyczny z kodem funkcji GetOpenGLPalette zaprezentowanej w rozdziale 8,
z tym e zamiast zwracania uchwytu palety konstruowany jest obiekt klasy CPalette.
636________________________________________Cz IV OpenGL i...
// Czy ten format pikseli wymaga palety? Jeli nie, po prostu nie //
twrz palety i zwr warto NULL if(!(pfd.dwFlags &
PFD_NEED_PALETTE)) return;
CView::OnPaletteChanged(pFocusWnd) ; }
Kod realizujcy palet bardzo przypomina kod z rozdziau 8. Tutaj jednak Windows nie
przekazuje tych komunikatw bezporednio do klasy widoku, lecz do klasy CMainFrame
aplikacji. Dzieje si tak, poniewa Windows wysya komunikaty o zmianie palety
jedynie do gwnego okna aplikacji; gwne okno odpowiada za rozesanie tych komu-
nikatw do odpowiednich okien potomnych.
Ponownie wic uyjemy ClassWizarda w celu dodania dwch procedur obsugi komu-
nikatw palety do klasy CMainFrame. W tych procedurach po prostu wyznaczamy aktywny
widok i posyamy mu niezmienione komunikaty palety, pozwalajc widokowi na ich
samodzielne obsuenie. Te procedury obsugi zostay przedstawione na listingu 21.4.
Listing 21.4. Kod klasy CMainFrame przesyajcy komunikaty palety do okna widoku ___________
Rysunek 21.4.
Kocowa animowana
scena tworzona przez
program MFCGL
Podsumo
wanie
W tym
rozdziale
omwili
my
zagadnieni
a zwizane
z
uywanie
m OpenGL w aplikacjach opartych na MFC, pokazujc, gdzie naley ustawi style okna
wymagane przez OpenGL, gdzie i kiedy ustawi format pikseli, a take jak stworzy
kontekst renderowa-nia. Przykadowy program ilustruje take, kiedy naley uczyni
kontekst renderowania biecym oraz jak w razie potrzeby zrealizowa palet za pomoc
klasy MFC CPalette.
Obecnie coraz wiksza liczba programistw przy tworzeniu aplikacji dla Windows ko-
rzysta z C++. Dotychczas w treci ksiki prezentowalimy jedynie kod napisany w C. Na
szczcie, wikszo programistw C++ doskonale daje sobie rad z analiz programw
napisanych w C. Niestety, nie jest to ju tak powszechne w odwrotnej sytuacji (wielu
programistw C ma kopoty ze zrozumieniem kodu C++). Nie twierdzimy, e C++ jest
znacznie trudniejszy w opanowaniu, lecz gdy sigasz po ksik na temat grafiki
komputerowej z zamiarem opanowania wanie tego tematu, raczej nie chcesz przy
okazji uczy si nowej skadni jzyka.
Celem tego rozdziau jest pomoc programicie C++ w wykorzystaniu jednej z popu-
larnych bibliotek klas C++ jako punktu wyjcia dla wasnych aplikacji C++. Bibliotek
klas opisywan w tym rozdziale jest OWL (Object Windows Library) Borlanda. Przykady
i zrzuty okien wystpujce w tym rozdziale zostay przygotowane przy uyciu Borland
C++5.0.
Uwaga
Jeli uywasz MFC (Microsoft Foundation Classes), wr do
rozdziau 21
W tym miejscu nie bdziemy prezentowa zawartoci pliku glcode.c, gdy ten plik jest
do dugi, a jeli koniecznie chcesz si z nim zapozna, moesz go skopiowa z pytki
CD-ROM. Ponadto ten sam plik zosta wykorzystany w przykadzie dla MFC w poprzednim
rozdziale.
Zaczynamy od AppExperta
Wiele aplikacji napisanych w C++ zaczyna istnienie od AppExperta. Architektur doku-
mentu-widoku mona porwnywa z architektur modelu-widoku w innych obiektowo
zorientowanych rodowiskach programistycznych. Nawet w przypadku szybkich, pr-
bnych aplikacji lub eksperymentalnych projektw, AppExpert moe w nieca minut
stworzy aplikacj SDI (z pojedynczym dokumentem), MDI (z wieloma dokumentami) lub
opart na oknie dialogowym. Tak wic sensownie bdzie uy wanie AppExperta w celu
stworzenia szkieletu aplikacji SDI OWL, w ktrej pniej wykorzystamy take OpenGL.
Aby stworzy prost scen OpenGL, dodamy funkcje i zmienne do klasy widoku,
wyprowadzonej z TWindowYiew. Podobnych metod bdziesz mg uy w celu dodania
elementw OpenGL do kadej klasy wyprowadzonej z TWindow.
Budowanie szkieletu
Zaczniemy od zbudowania szkieletu aplikacji SDI za pomoc AppExperta, pomijajc
opcje zwizane z funkcjonalnoci OLE, przeciganiem i upuszczaniem itd. Rysunek
22.1 przedstawia pierwszy dialog AppExperta przy tworzeniu szkieletu aplikacji OWL.
By moe zechcesz take wyczy opcj wydruku i podgldu wydruku (Print and Print
Preview). Sceny OpenGL mog by renderowane w kontekcie urzdzenia drukarki
tylko wtedy, gdy drukarka jest drukark kolorow obsugujc co najmniej cztery lub
wicej bitplanw koloru (16 lub wicej kolorw). Drukowanie na monochromatycznej
drukarce laserowej lub mozaikowej take jest moliwe, lecz do kopotliwe. Przykad
kodu sucego do drukowania scen przy uyciu nowych elementw OpenGL w wersji
644 Cz IV OpenGL I...
Rysunek 22.1.
Pocztek tworzenia
nowej aplikacji SDI
za pomoc
AppExperta
Moesz pozostawi opcje aplikacji w ich domylnym stanie lub te wyczy paski na-
rzdzi, pasek stanu itd. Dodatkowo musisz pamita, aby w oknie MainWindow Basic
Options wczy style okna wymagane przez OpenGL (Clip Children i Clip Siblings). Na
koniec, wybierz kategori SDI Client i wska, e gwne okno ma by wyprowadzone z
klasy TWindowWiev, tak jak pokazano na rysunku 22.2.
Rysunek 22.2.
Wskazywanie, e
okno klienta ma by
wyprowadzone z
klasy TWindowYiew
Rysunek 22.3.
Szkieletowa aplikacja
SDI wygenerowana
przez AppExperta
Dodawanie nagwkw
Zanim zaczniemy dodawa do szkieletu aplikacji jakikolwiek kod OpenGL, musimy doda
do projektu nagwki OpenGL. Najlepiej umieci je w pliku owlglapp.h. Dopisz po prostu
dwie ponisze linie wczajce pliki nagwkowe:
tfinclude <gl\gl.h> // Biblioteka OpenGL
include <gl\glu.h> // Biblioteka GLU OpenGL
Tabela 22.1.
Podstawowe komunikaty obsugiwane w aplikacjach OpenGL
Rysunek 22.4.
Dodawanie procedur
obsugi komunikatw
za pomoc
ClassExperta.
Zwr uwag, e ustawiamy take styl CS_OWNDC, dziki ktremu okno moe po-
siada prywatny kontekst urzdzenia. Cho nie jest to rygorystycznie wymagane, powoduje
szybsze i wydajniejsze dziaanie programu. Niektre wskaniki do kontekstw
urzdze zwracane przez OWL s tymczasowe i nie mog by przechowywane do
pniejszego uycia (podobnie jak w MFC). W naszym przypadku lepiej jest pobra
taki wskanik i przechowa go.
W klasie TOwlglWindowYiew (w pliku nagwkowym owlglwnv.h) przygotujemy take
miejsce na kontekst urzdzenia, kontekst renderowania oraz palet
public:
HGLRC m_hRC; // Kontekst renderowania
HDC m_hDC = NULL; // Kontekst urzdzenia
TPalette *m_pPalette; // Paleta 3-3-2
Listing 21.1. Procedura obsugi komunikatu WM_CREATE, \v ktrej przygotowujemy format pikseli____
result - TWindowView::EvCreate(createStruct);
return result;
Rozdzia 22. OpenGL i OWL____________________________________649
Listing 22.3. Procedura obsugi komunikatu WM_PAINT, aktualizujca wymiary okna roboczego___
Renderowanie sceny
Teraz moemy doda kod odpowiedzialny za renderowanie sceny w OpenGL. Metoda
EvPaint klasy widoku jest wywoywana za kadym razem, gdy okno otrzymuje komunikat
WM_PAINT. Wewntrz tej metody wybieramy kontekst renderowania jako biecy i
wywoujemy funkcj GLRenderScene, zawierajc jedynie wywoania funkcji
OpenGL. Kod tej metody zosta przedstawiony na listingu 22.4. Poniewa wczeniej
zadalimy trybu z podwjnym buforowaniem, zaraz po tym wywoujemy funkcj
SwapBuffers. Oprcz tego, w obsudze komunikatu WM_PAINT naley zatwierdzi
obszar roboczy okna informujc Windows o zakoczeniu rysowania. Jeli tego nie uczy-
nimy, Windows bdzie bez przerwy posya do okna kolejne komunikaty WM_PAINT.
void TOwlglWindowView::EvPaint()
{
// Uczynienie kontekstu renderowania biecym
wglMakeCurrent(m_hDC,m_hRC);
// Zatwierdzenie okna
Validate();
Niech si krci
Cho oczywicie nie jest to wymogiem, w przykadzie w tym rozdziale uywamy timera w
celu uniewaniania obszaru roboczego okna co 200 milisekund (czyli wymuszamy
odrysowanie zawartoci okna przez kod OpenGL). Kod w module glcode.c przy kadym
wywoaniu obraca nasze obiekty. Dziki temu powstaje efekt pynnej animacji
obiektw - w tym przypadku trzech trjwymiarowych liter. Zaimplementowanie timera jest
proste: naley ustawi timer w funkcji EvCreate(), doda procedur obsugi komunikatu
WM_TIMER, a na zakoczenie programu usun timer w funkcji EvDestroy. Stanowi
to standardow praktyk programowania w Windows, za odpowiedni kod zosta
przedstawiony na listingu 22.6.
Wynik dziaania programu w obecnej postaci zosta przedstawiony na rysunku 22.5.
Rysunek 22.5.
Animowane litery
w programie
OWLGL
Obsuga palety
Ostatnie poprawki do naszego przykadu OWL dotycz obsugi palety, co wie si z
utworzeniem i zrealizowaniem palety RGB dla urzdze korzystajcych z palety (kart
256-kolorowych). Zamiast przechowywa uchwyt palety, tak jak w rozdziale 8, stwo-
rzymy obiekt OWL typu TPalette. W pliku owlglwnf.h deklarujemy wskanik do obiektu
klasy TPalette:
TPalette *m_pPalette; // Paleta logiczna
nPixelFormat = GetPixelFormat(hDC);
DescribePixelFormat(hDC, nPixelFormat,
sizeof(PIKELFORMATDESCRIPTOR), Spfd);
// Czy ten format pikseli wymaga palety? Jeli nie, po prostu nie //
twrz palety i wr
if(!(pfd.dwFlags & PFD_NEED_PALETTE))
return;
if(RealizePalette(hDC) == NULL)
::MessageBox(NULL,"Nie powiodo si zrealizowanie palety",
"Bd",MB_OK);
// Zwolnienie pamici uytej przez struktur palety logicznej
free(pPal);
Kod realizujcy palet bardzo przypomina kod z rozdziau 8. Tutaj jednak Windows nie
przekazuje tych komunikatw bezporednio do klasy widoku, lecz do klasy TDecora-
tedFrame aplikacji (w naszym przykadzie SDIDecFrame). Dzieje si tak, poniewa
Windows wysya komunikaty o zmianie palety jedynie do gwnego okna aplikacji;
gwne okno odpowiada za rozesanie tych komunikatw do odpowiednich okien po-
tomnych.
Ponownie wic uyjemy ClassExperta w celu dodania dwch procedur obsugi komuni-
katw palety do klasy SDIDecFrame. W tych procedurach po prostu wyznaczamy potomny
widok TWindowYiew i posyamy mu niezmienione komunikaty palety, pozwalajc wi-
dokowi na ich samodzielne obsuenie. Te procedury obsugi zostay przedstawione na
listingu 22.9.
Listing 22.9. Kod klasy SDIDecFrame przesyajcy komunikaty palety do okna widoku___________
return TRUE;
656________________________________________Cz IV OpenGL l
// Wysanie komunikatu
if(pGLWindow)
pGLWindow->SendMessage(WM_PALETTECHANGED, (UINT)hWndPalChg,
( O I N T ) 0);
Podsumowanie
W tym rozdziale omwilimy zagadnienia zwizane z uyciem OpenGL w aplikacjach
opartych na OWL, pokazujc, gdzie naley ustawi style okna wymagane przez OpenGL,
gdzie i kiedy ustawi format pikseli, a take jak utworzy kontekst renderowania.
Przykadowy program ilustruje take, kiedy naley uczyni kontekst renderowania bie-
cym oraz jak w razie potrzeby zrealizowa palet za pomoc klasy OWL TPalette.
Przykadow aplikacj zaprezentowan w tym rozdziale bdziesz mg wykorzysta jako
punkt wyjcia dla wasnych programw OpenGL. Oprcz tego, szkielet aplikacji - wraz z
caym kodem OpenGL w module glcode.c - moe posuy do zamiany innych przy-
kadw C/OpenGL na programy OWL. Inne przykadowe programy OWL korzystajce z
OpenGL znajdziesz na pytce CD-ROM.
658_______________________________________Cz IV OpenGL i...
argumenty, typ zwracanej wartoci oraz plik DLL-a, w ktrym zawarta jest dana
funkcja.
Kolejn niedogodnoci jest wymaganie OpenGL, aby tworzone okna miay ustawione
style WS_CLIPCHILDREN oraz WS_CLIPSIBLINGS. W niektrych ze rodowisk
bardzo trudno jest dobra si do jakichkolwiek niskopoziomowych stylw okna, chyba e
gdzie dostpne jest okno dialogowe z odpowiednimi opcjami. W najgorszym przypadku
trzeba wyeksportowa z Windows funkcj CreateWindow i wywoa j z wntrza
swojego programu.
Jeli nie przeraa ci perspektywa brnicia przez te niedogodnoci w celu uycia OpenGL
powiedzmy, w Yisual Basicu, by moe powiniene po prostu napisa DLL-a w C, ktry
zawieraby cay kod zwizany z renderowaniem OpenGL, a nastpnie wywoywa go z
wntrza procedur Basica. To rozwizanie, mimo e najlepsze pod wzgldem wydajnoci,
nie ma jednak zastosowania dla programistw nie obeznanych z C/C++.
Jeli jednak kupie t ksik, aby nauczy si programowa przy uyciu OpenGL i do tej
pory dawae sobie rad z analiz przykadw i definicji funkcji, wci jeszcze jest dla
ciebie nadzieja!
Magia obiektw
Termin obiektowo zorientowany jest chyba, podobnie jak termin klient/serwer, jednym z
najczciej naduywanych i bdnie uywanych sloganw lat 90-tych. Chcielibymy unikn
powanych rozwaa na ten temat, naley jednak wspomnie o jednej z najwaniejszych
technologii umoliwiajcych wielokrotne wykorzystanie tego samego kodu.
T technologi jest OLE (Object Linking and Embedding) lub - co waniejsze dla tego
rozdziau - OCX (OLE Gustom Control). Gdy Microsoft opracowa Yisual Basic i umoliwi
tworzenie wasnych kontrolek poprzez VBX, w cigu dosownie jednej nocy powstaa
nowa ga przemysu. Powstay nowe firmy, przynoszce fortuny, zajmujce si
dostarczaniem programistom Yisual Basica nowych i interesujcych programowych
gadetw. Wkrtce powstay konkurencyjne rodowiska (PowerBuilder, Delphi i inne),
take umoliwiajce uycie kontrolek VBX w swoich aplikacjach. To jeszcze bardziej
podsycio zapa do tworzenia komponentw nadajcych si do wielokrotnego zasto-
sowania.
Rozdzia 23.
OpenGL w Visual Basic
S4GL
Poza rozdziaami 21 i 22, w caej ksice opisywalimy OpenGL API z punktu widzenia
programisty C. Jednak aden opis zagadnie zwizanych z programowaniem Windows
nie mgby by kompletny bez dyskusji na temat jzykw czwartej generacji (4GL) i
innych popularnych wizualnych rodowisk programowych. W tym rozdziale omwimy
pokrtce wymagania zwizane z uywaniem OpenGL w niektrych z takich rodowisk.
Oprcz tego, zademonstrujemy doczone do tej ksiki kontrolki OCX OpenGL, ktre
mog zosta uyte w dwch najpopularniejszych rodowiskach programowych Win32: w
Yisual Basic 6.0 Microsoftu oraz Delphi 2.0 Borlanda.
Cae API OpenGL mieci si w dwch plikach DLL: opengl32.dll oraz glu32.dll. Tak jak
wikszo API Win32 jest dostpnych bezporednio z bibliotek DLL, take w przypadku
bibliotek opengl32.dll, glu32.dll i innych moesz wywoywa ich funkcje bezporednio z
jzyka programowania wyszego poziomu. W kadym narzdziu i rodowisku jest to
jednak odmiennie zorganizowane. Zwykle musisz poda nazw funkcji, jej
660________________________________________Cz IV OpenGL i...
prostu umie kontrolk w formularzu i zacznij wywoywa jej metody, tak jakby byy
funkcjami i poleceniami OpenGL.
Kade polecenie nosi nazw tak jak w OpenGL API, lecz z odrzuconym przedrostkiem g/.
Gdy kontrolk nazwiesz g/, twj kod bdzie wyglda bardzo podobnie do kodu C uy-
wajcego OpenGL. Aby si o tym przekona, zajrzyj do przykadw dla VB i Delphi w
dalszej czci rozdziau.
Kontrolka odpala dwa zdarzenia, ktre moesz przechwyci w swojej aplikacji. Pierwszym
z nich jest SetupRC, wywoywane za pierwszym razem, gdy kontrolka prbuje odrysowa
swj obszar roboczy. W tym momencie format pikseli i kontekst renderowania zostay ju
utworzone i przygotowane. W swoim kodzie moesz przygotowa owietlenie, kolor ta itd.
Drugim zdarzeniem jest Render, wywoywane za kadym razem, gdy kontrolka ma zosta
odrysowana. Umieszczajc w tym miejscu swj kod renderowania, moesz efektywnie
wypeni obszar roboczy za pomoc OpenGL.
Podczas uywania kontrolki musisz mie na uwadze jeszcze par innych rzeczy:
* Poniewa mgby uy w swojej aplikacji wicej ni jednej kontrolki OpenGL,
kontrolka nie moe zakada, e kontekst renderowania zawsze jest dostpny dla
niej. W zwizku z tym zostay dostarczone dwie metody: MakeCurrent oraz
MakeNotCurrent. Wszystkie wywoania OpenGL musz by ujte pomidzy
wywoania tych dwch funkcji; dotyczy to take funkcji SetupRC i Render.
* Oprcz tego, jeli uczynisz kontekst renderowania biecym dla kontrolki, zawsze
moesz bezporednio wywoywa OpenGL API. Moesz to robi w celu
poprawienia wydajnoci lub w przypadku chci wykorzystania nowych funkcji w
nastpnych wersjach OpenGL, ktre nie zostay zawarte na licie metod kontrolki.
Do dyspozycji masz take kod rdowy kontrolki, wic jeli masz Yisual C++ i
spore zacicie, zawsze moesz sam zmodyfikowa kontrolk.
* Dla kontrolki jest tworzona paleta 3-3-2, realizowana za kadym razem, gdy jest
odpalane zdarzenie Render. Prby samodzielnego manipulowania palet mog
prowadzi do nieprzewidzianych rezultatw.
* Na koniec, okno kontrolki jest podwjnie buforowane, wic aby wywietli obraz,
zawsze musisz wywoa metod SwapBuffers.
Znaczniki OpenGL
Niemoliwe jest korzystanie z funkcji i polece OpenGL bez moliwoci dostpu do
wielu specjalnych znacznikw i zmiennych stanu. Kada z wartoci tych znacznikw jest
dostpna poprzez metod o nazwie odpowiadajcej nazwie danego znacznika. Nazwy tych
metod zawieraj jednak jedynie mae litery, gdy przy zachowaniu oryginalnych nazw
wystpoway problemy z prawdziwymi definicjami w plikach nagwkowych. Cho w
pewnych przypadkach sensowne byoby zaimplementowanie pewnych zmiennych stanu
jako waciwoci kontrolki, jednak nie zawsze byoby to moliwe. Dla zachowania
spjnoci zdecydowalimy si zastosowa metody dopasowane do OpenGL na tyle, na ile
to byo moliwe.
Rozdzia 23. OpenGL w Visual Basic i 4GL___________________________661
Cho wiele funkcji posiada kilka odmian, wszystkie zostay zaimplementowane jako
pojedyncza metoda. Oznacza to, e funkcje takie jak
void glVertex2fv(const GLfloat *v) ;
Dostpny jest plik pomocy (WaiteGL.hlp) zawierajcy spis wszystkich metod zdefinio-
wanych w kontrolce WaiteGL. Zostay one podzielone na trzy biblioteki OpenGL (gl, glu
i glaux) oraz definicje wszystkich staych. Aby skorzysta z pliku pomocy, odszukaj
potrzebn funkcj OpenGL, a nastpnie poszukaj opisu metody kontrolki WaiteGL dla tej
funkcji.
Przejdmy teraz do tworzenia programw korzystajcych z OpenGL w dwch najpopu-
larniejszych rodowiskach 4GL. W nastpnej sekcji omwimy zagadnienia zwizane z
Yisual Basicem. Jeli uywasz Delphi 2.0 (w wersji 32-bitowej), moesz przej od razu
do nastpnej sekcji.
Instalowanie kontrolki
Po zarejestrowaniu kontrolki w systemie, musisz j zainstalowa w palecie narzdzi Yisual
Basica. W tym celu kliknij prawym przyciskiem myszy w obszarze palety
komponentw i z wywietlonego menu lokalnego wybierz opcj Components.... Z listy w
oknie dialogowym z rysunku 23.1 wybierz pozycj WaiteGL OLE Control module, po
czym kliknij na przycisk OK. Teraz bdziesz mg przecign kontrolk z palety na
formularz, a nastpnie dostosowa jej rozmiar.
662 Cz IV OpenGL i.
Rysunek 23.1.
Instalowanie
kontrolki WaiteGL
w Visual Basicu
Zwr uwag, e najpierw kontekst renderowania jest wybierany jako kontekst biecy,
za po wywoaniu kodu rysunkowego jest odkadany. Nie jest to potrzebne, gdy posiadasz
tylko jedn kontrolk i kontekst renderowania, lecz zapewnia, e nie bd wymagane
pniejsze zmiany w kodzie, gdy zechcesz zastosowa dodatkow kontrolk
664 Cz IV OpenGL i...
Troch ruchu
Przedstawiony powyej kod wystarczy do wywietlenia rysunku OpenGL. W tym przy-
kadzie jednak sprbujemy doda nieco animacji. W formularzu z rysunku 23.2 umiecimy
timer, odpalany co 200 milisekund. Za kadym tykniciem timera nasza funkcja uczyni
kontekst renderowania biecym dla kontrolki, obrci macierz widoku o 5, a
nastpnie odoy kontekst renderowania. Na koniec polecimy kontrolce, aby si od-
rysowaa, wywoujc bezporednio metod gl_Render. Spjrz na listing 23.3.
Instalowanie kontrolki
Po zarejestrowaniu kontrolki w systemie, musisz j zainstalowa w palecie narzdzi
Delphi. W gwnym menu wybierz Component, a nastpnie polecenie Install. Kliknij na
przycisk OCX, po czym w oknie dialogowym z rysunku 23.4 pojawi si lista zarejestro-
wanych kontrolek OCX, ktre mog zosta zainstalowane.
Wybierz pozycj WaiteGL OLE Control module, po czym kliknij na przycisk OK. Spo-
woduje to dodanie naszej kontrolki do palety narzdzi. Po prostu przecignij kontrolk na
rodek formularza, a otrzymasz okno przeznaczone do rysowania za pomoc OpenGL.
Rysunek Import OLE Control
23.4.
Instalowanie VBSMSChailWizaid yD
kontrolki WaiteGL First Impression Library VD
Formua One Lfciary VCI
w Delphi WsualSoellet Litu
Przykad w Delphi
W przykadzie w Delphi zaczniemy od utworzenia nowego formularza i umieszczenia na
jego rodku kontrolki WiggleGL, tak aby zajmowaa wikszo powierzchni. Oprcz
666 Cz IV OpenGL i...
Rysunek 23.5.
Formularz Delphi
z kontrolk OCX
Na rysunku 23.6 widzimy zakadk Events inspektora obiektw; jak wida, kontrolk
wywouje dwie unikatowe procedury obsugi: OnRender oraz OnSetupRC
Rysunek 23.6.
Zdarzenia dostpne ijgl: TWaileGLDrl
dla kontrolki
'
WaiteGL
Listing 24.3. Kod Delphi wywoywany w odpowiedzi na zdarzenie SetupRC wywoane przez kontrolk
Troch ruchu
Przedstawiony powyej kod wystarczy do wywietlenia rysunku OpenGL. W tym przy-
kadzie jednak sprbujemy doda nieco animacji. W formularzu z rysunku 23.6 umie-
668 Cz IV OpenGL i...
cilimy timer odpalany co 200 milisekund. Za kadym tykniciem timera, nasza funkcja
uczyni kontekst renderowania biecym dla kontrolki, obrci macierz widoku o 5, a
nastpnie odoy kontekst renderowania. Na koniec polecimy kontrolce, aby si odry-
sowaa, wywoujc porednio funkcj Delphi Invalidate(). Poniewa w Delphi wszystkie
kontrolki OCX s oknami, wszelkie komunikaty lub polecenia wysyane do okien mog
by wysyane bezporednio do kontrolki. Spjrz na listing 23.6.
// Odmaluj kontrolk
gl.Invalidate();
end;
Rysunek 23.7.
Wynik dziaania
programu
stworzonego w
Delphi,
korzystajcego z
OpenGL
Zwr uwag, e kontrolka korzysta z biblioteki MFC w osobnym pliku DLL. Dla twojej
wygody, w podkartotece \REDIST zostay umieszczone redystrybuowalne pliki MFC.
Podsumowanie
W tym rozdziale omwilimy moliwoci i wyzwania kryjce si za uyciem OpenGL w
pewnych popularnych rodowiskach programowych. Cho w wikszoci tych rodowisk
moliwy jest bezporedni dostp do niskopoziomowych funkcji API, duo atwiej jest
jednak posuy si przygotowan przez nas kontrolka OCX. Wikszo przykadowych
programw z tej ksiki moe zosta atwo przerobionych tak, aby mona je byo
zaimplementowa w jzyku czwartej generacji (4GL) przy uyciu tej kontrolki. Oprcz
tego na pytce CD-ROM zostay zamieszczone uzupeniajce przykady.
Rozdzia 24.
Przyszo OpenGL w
Windows
Ta ksika nie jest wycznie o OpenGL - ona jest na temat OpenGL w systemie Mi-
crosoft Windows. Pozwolimy sobie w tym miejscu na omwienie biecej sytuacji
OpenGL oraz sprbujemy wysnu wnioski co do jego rozwoju i zastosowa w najbliszej
przyszoci.
OpenGL to w zaoeniu programowy interfejs dla sprztu 3D. Cho zarwno w Windows
NT, jak w Windows 95 dostpna jest oglna", czysto programowa implementacja tej
biblioteki, wynika to gwnie z faktu, e sprzt 3D dla komputerw osobistych jest jeszcze
w powijakach. Oczywicie, w przypadku OpenGL powinno si korzysta z takiego
sprztu, jeli tylko jest to moliwe.
W momencie powstawania tej ksiki rynek akceleratorw 3D jest jeszcze bardzo mody.
Ceny kart akceleratorw 3D zgodnych z OpenGL zaczynaj ostatnio spada, jednak
prawdziwym motorem wymuszajcym znaczny spadek cen s gry komputerowe prze-
znaczone do uruchamiania na komputerach osobistych. Gry komputerowe wymagaj
najszybszego dostpnego sprztu i najwydajniej napisanych programw. Komputery
osobiste z przynajmniej kilku powodw dobrze nadaj si na maszynki do grania. Przy
odpowiednim osprzcie, moesz gra na ekranie wysokiej jakoci monitora, ktry o par
klas przewysza ekran domowego odbiornika telewizyjnego. To wszystko uzupenia
dwik, nawet z syntez \vave-table, prawie nie rnicy si od brzmienia rzeczywistych
instrumentw. Oprcz joysticka z jednym lub dwoma przyciskami masz do dyspozycji
mysz i ca klawiatur, co otwiera zupenie nowe moliwoci w interakcji z gr. Dodaj
do tego ogromne pojemnoci choby zwykych pytek CD-ROM oraz moliwo
przechowywania (powiedzmy sobie szczerze: kopiowania) programw na dysku. Jeli
zoysz to wszystko razem, otrzymasz bardzo drogi, lecz niezwykle wydajny sprzt do
zabawy.
Oczywicie, niewiele osb przyznaje si, e kupuje komputer wycznie do grania (chyba
e chodzi o tzw. gry edukacyjne). Ale nie oszukujmy si - skoro masz ju w domu
potny komputer przeznaczony do pracy lub cznoci ze wiatem, nie zaszkodzi chyba,
e pozwolisz sobie na nieco rozrywki, prawda? Gdy Micorosft Windows opanoway
672__________________________________________Cz IV OpenGL i...
rynek na tyle, e powane" aplikacje stay si znacznie powszechniejsze dla tego sy-
stemu ni dla DOS-a, wiele osb zainstalowao ten system w swoich komputerach.
Mimo to, do mniej wicej roku temu, twrcy gier unikali Windows jak ognia, tworzc
gry prawie wycznie dla DOS-a.
Wszystkie powody ku temu mona uj w jednym sowie: wydajno. Windows znacznie
uatwiaj ycie twrcom aplikacji, gdy wszystkie polecenia graficzne wywouje si tak
samo bez wzgldu na sprzt zainstalowany w komputerze. Chcesz narysowa prostokt?
Po prostu wywoaj funkcj rysujc ten prostokt! Nie musisz konwertowa
wsprzdnych ekranowych na adres fizyczny w pamici ekranu ani martwi si, e nie
znasz szybkich algorytmw. Wszystko, co potrzebne do obsuenia karty graficznej, to
odpowiedni sterownik Windows, tumaczcy wywoania GDI na instrukcje sprztowe.
Niestety, w takim podejciu pomidzy instrukcjami graficznymi wywoywanymi przez
programist a sam kart graficzn wystpuje wiele porednich warstw kodu zwizanego z
tworzeniem obrazu na ekranie. Powoduje to powstawanie pewnego zjawiska, ktre nosi
nazw P-O-W-O-L-I. aden szanujcy si twrca gier nie mg pozwoli sobie na
tworzenie gier wideo dla Windows, wic przez duszy czas jedynymi przykadami pa-
sjonujcych gier dla Windows byy pasjans i saper.
Dostawcy sprztu starajcy si utrzyma na rynku komputerw wykorzystywanych gwnie
do prac biurowych i przetwarzania tekstw, zaczli tworzy karty graficzne oferujce
sprztow akceleracj wielu powszechnie uywanych polece rysunkowych Windows.
Rynek zalaa powd kart graficznych z akceleratorami 2D, przyspieszajcymi dziaanie
systemw Windows i sprawiajcymi, e gry dla Windows przestay by czym nierealnym.
Programistom ciko byo si oprze pokusie wykorzystania nowego, kolorowego
interfejsu, jake atrakcyjnego w porwnaniu ze zwykym tekstowym interfejsem DOS-a.
Powoli zaczy powstawa gry karciane, gry strategiczne, a nawet powstao kilka gier
wideo.
W tym momencie kady ju zdawa sobie spraw, e standardem jest system Windows,
jednak wikszo najlepszych gier (gwnie gier akcji i symulatorw pojazdw) wci
bya przeznaczona dla DOS-a. Programici po prostu nie mogli osign takiej iloci
klatek na sekund i prdkoci wywietlania, jakie mona byo osign w DOS-ie.
Pierwsz prb, jak Microsoft podj w celu wsparcia twrcw gier, byo WinG API. W
praktyce nowy interfejs nie zawiera wiele wicej ni kilka funkcji umoliwiajcych
bardzo szybkie przerzucanie bitmap. WinG stanowio znaczny postp, jednak byo to
wci za mao, aby znaczca ilo twrcw gier zwrcia si ku Windows.
Kamieniem milowym dla rynku gier okazao si powstanie systemu Windows 95.
Microsoft desperacko stara si ustanowi Windows 95 32-bitowym nastpc DOS-a dla
biurowych i domowych systemw. Tak si zoyo, e Windows NT byy wykorzystywane
gwnie do powaniejszych zada, wic Windows 95 znalazy sobie przytuln (i obszern)
nisz jako system do zastosowa domowych. Jednak nawet zanim stao si to oczywiste,
Microsoft chcia uczyni z Windows 95 podstawowy system do gier. W zwizku z tym
konieczna bya rozbudowa moliwoci multimedialnych tego systemu, i to w bardzo
duym stopniu.
Rozdzia 24. * Przyszo OpenGL w Windows___________________________673
Aby umoliwi twrcom gier bardziej bezporedni dostp do sprztu, Microsoft opracowa
zestaw interfejsw API, znanych teraz pod wspln nazw DirectX.
Nale do nich Direct Draw, przeznaczony do szybkiego przerzucania bitmap na ekran,
Direct Sound do szybkiej obsugi dwiku i MIDI, Direct Play do umoliwienia gry w
sieci oraz Direct Input do obsugi joysticka i innych urzdze wejciowych. Pomidzy
sprztem a aplikacj wystpuje jedynie bardzo cienka" warstwa porednia oprogra-
mowania, dziki czemu programista ma niespotykany dotd dostp do sprztu, zatem
gry mog zyska niespotykan dotd w Windows szybko.
Ostatnim komponentem dodanym do pakietu DirectX by DirectSD. Dzisiejsze gry wideo
nie s ju paskimi, dwuwymiarowymi scenkami. S wysoce zoonymi symulatorami
lotw lub trjwymiarowymi strzelaninami, penymi teksturowanych potworw, cian i
korytarzy. Direct3D jest cile zintegrowany z DirectDraw i kartami akceleratorw 3D.
Jeli jakie funkcje nie s obsugiwane przez sprzt, s emulowane programowo.
Dziki temu twrcy gier mog kodowa i testowa swoje aplikacje, a pniej
bezproblemowo korzysta z dodatkowych moliwoci oferowanych przez nowy sprzt.
Jak to wszystko ma si do OpenGL? Cakiem zwyczajnie: co jest dobre dla gier, jest
rwnie dobre dla OpenGL. Za rok czy dwa od momentu ukazania si tej ksiki, akce-
leratory 3D zapewne stan si standardowym wyposaeniem wikszoci komputerw
osobistych. Istnieje wiele historycznych przesanek, ktre mog utwierdzi nas w tym
przekonaniu. Na przykad, gdy pojawiy si napdy CD-ROM, nie mona w nich byo
odtwarza muzycznych pyt CD. Wkrtce jednak kto spostrzeg, e napd posiadajcy
tak moliwo z pewnoci bdzie si lepiej sprzedawa. Kt nie chciaby sucha
muzyki pracujc przy komputerze? Oczywicie, dzisiaj nie mona kupi nowego napdu
CD-ROM, w ktrym nie daoby si odtwarza muzycznych pytek CD.
To samo dziao si z pocztkowymi akceleratorami 2D dla Windows. Karty z akceleracj
szybko stay si bardzo tanie, oferujc sprztowe przyspieszenie operacji za bardzo
niewielk dodatkow cen. Na koniec, podobnie dzieje si w przypadku faksmodemw. Id
do sklepu i sprbuj kupi nowy modem, ktry rwnoczenie nie mgby dziaa jako faks.
Producenci ukadw scalonych zespolili funkcje obu urzdze w jednej kostce i dziki
masowej produkcji cena faksmodemu spada do ceny zwykego modemu.
Oczywicie, naley zakada e podobnie bdzie si dziao z kartami graficznymi z
akceleratorami 3D, a z czasem bdzie coraz lepiej. W 1995 roku Microsoft kupi firm
RenderMorphics, Ltd., twrc Reality Lab 3D API. Jest to wysokowydajna biblioteka
3D przeznaczona do tworzenia trjwymiarowej grafiki w czasie rzeczywistym na kom-
puterach osobistych. Reality Lab API jest szybsze ni OpenGL, lecz uzyskuje to ko-
sztem pewnej utraty jakoci tworzonej grafiki. Dodatkowo, w tej bibliotece nie s
dostpne wszystkie efekty specjalne i moliwoci dostpne w OpenGL. Jednak dla gier
komputerowych nie ma to wikszego znaczenia, gdy w tym przypadku szybko ma
(na razie!) o wiele wiksze znaczenie ni realizm grafiki.
W nastpnej wersji DirectX, Reality Labs API zostanie doczone do Direct3D. Di-
rect3D bdzie mogo pracowa w jednym z dwch trybw, w trybie wstrzymywanym,
bdcym oryginalnym trybem Reality Labs, oraz w trybie natychmiastowym, stanowicym
niskopoziomowy interfejs dostpu do sprztu akceleratora 3D. Relacje pomidzy
674________________________________________Cz IV OpenGL i...
Dobr wiadomoci dla programistw OpenGL jest to, e OpenGL bdzie mg korzysta
ze sterownikw Direct3D przyspieszajcych dziaanie DirectSD w trybie natych-
miastowym. Tak wic w przypadku kart graficznych z akceleratorem 3D zostanie
przyspieszone rwnie dziaanie aplikacji OpenGL. Gdy komputery stan si szybsze, a
poganiani przez konkurencj producenci kart 3D stworz szybsze modele, nadejdzie czas,
gdy na przecitnym komputerze osobistym bdzie mona oglda skomplikowane animacje
3D tworzone wycznie w OpenGL. Ten czas si zblia i programici (moe nawet Ty)
bd musieli bra pod uwag nie tylko szybko dziaania, ale te wizualn jako swoich
produktw.
Wnioski
Gdy stay si dostpne pierwsze akceleratory 2D, w rzeczywistoci tylko niewielka liczba
uytkownikw potrzebowaa dodatkowej szybkoci. Obecnie karta graficzna z akceleratorem
dla Windows jest standardowym wyposaeniem kadego komputera. W grach w dalszym
cigu rysowanie odbywa si bez pomocy akceleratora 3D, jednak og projektantw jest
gotowy do zaakceptowania akceleracji 3D, jak tylko stanie si ona powszechnie dostpna.
Wkrtce standardowe, przecitne karty graficzne bd zawieray zarwno akceleracj 3D, jak
i akceleracj 2D dla Windows. Tak jak komputery z kolorowym monitorem przestay by
uwaane za maszynki do grania, tak trjwymiarowe technologie wykorzystywane
Rozdzia 24. Przyszo OpenGL w Windows___________________________675
Teraz, gdy wiesz ju, jak programowa przy uyciu OpenGL, chcielibymy podsun ci
kilka rad i uwag uatwiajcych tworzenie jak najbardziej optymalnego kodu OpenGL. Te
rady i uwagi s oglnymi zaleceniami i mog zosta zastosowane w programach bez
wzgldu na platform, ktrej uywasz.
Listy wywietlania
* Uywaj list wywietlania za kadym razem, gdy ten sam obiekt ma by rende-
rowany wicej ni raz. Nawet w wycznie programowych implementacjach.
Listy wywietlania mog znacznie poprawi wydajno.
* Sprbuj osadzi kosztowne przeksztacenia macierzy i zmiany stanu w listach
wywietlania - szczeglnie podczas komponowania tekstur. Do takich prze-
ksztace nale funkcje Rotate, Translate oraz Scal.
* Niektre systemy i karty graficzne mog bezporednio korzysta z list wywie-
tlania OpenGL (na przykad poprzez uycie DMA), wic zastosowanie list
680________________________________________________Dodatki
Operacje na macierzach
Uywaj wbudowanych funkcji (glRotate, glTranslate, glScale) zamiast samemu
komponowa i przemnaa wasne macierze. Wbudowane funkcje s wysoce
zoptymalizowane, szczeglnie jeli w systemie znajduje si odpowiedni sprzt.
Uywaj funkcji glLoadldentity do czyszczenia stosu macierzy zamiast adowa
wasn macierz, a to z powodw wymienionych powyej.
Zmienne stanu odkadaj i zdejmuj ze stosu (glPushAttrib/glPopAttrib) zamiast
odczytywa i ustawia je indywidualnie.
Konstruowanie obiektw
Gdziekolwiek jest to moliwe, uywaj prymitywu GLJTR.IANGLES. Czsto
krcej trwa narysowanie dwch lub wicej trjktw ni jednego czworokta
lub wielokta. Z kolei GL_QUADS jest szybszy od GL_POLYGON, bdc
przy tym rwnie szybkim lub szybszym ni GL_TRIANGLES w czysto pro-
gramowych implementacjach OpenGL.
Grupy podobnych prymityww umieszczaj wewntrz pojedynczej pary instrukcji
glBegin/glEnd.
Uywaj danych wierzchokw i innych polece w formie tablicowej, w celu
przekazania jak najwikszej iloci danych w jak najmniejszej iloci instrukcji.
Dodatek A. Poprawianie wydajnoci OpenGL w Windows ___________________ 681
Inne rady
Nie dodawaj programowi niepotrzebnej pracy, na przykad wci ustawiajc
ten sam kolor lub ustawiajc ten sam znacznik stanu.
Manualnie usuwaj niewidoczne czci sceny. Postaraj si nie rysowa obie-
ktw, o ktrych wiesz, e nie pojawi si w scenie (takich jak obiekty za tob).
Nie prbuj sprawdza widocznoci kadego obiektu, ale raczej tak dostosuj
struktur swojego programu, aby wyeliminowa oczywistych kandydatw (zajrzyj
do symulatora czogu w rozdziale 7).
W Windows jednym z waniejszych wskich garde jest przerzucanie buforw.
Gdy zmianie ulega jedynie niewielka cz sceny, uyj funkcji rozszerzenia
glAddSwapHintRectWIN.
W celu przyspieszenia renderowania zredukuj ilo szczegw sceny. Jeli po-
siadasz akcelerator sprztowy, w celu uzyskania lepszych efektw graficznych
moesz zwikszy ilo szczegw. Obecno akceleratora sprztowego moesz
sprawdzi za pomoc funkcji DescribePixelFormat. W wersji 1.1 i pniejszych
sprawd obecno znacznika PFD_GENERIC_ACCELERATED w polu
dwFlags struktury PIXELFORMATDESCRIPTOR.
Uywaj 16-bitowego bufora gbokoci, chyba e twoja aplikacja wymaga doda-
tkowej precyzji. W ten sposb nie tylko oszczdzisz pami, ale take bdziesz
mg skorzysta z wikszoci taszych akceleratorw, ktre nie obsuguj
32-bitowego bufora gbokoci.
Dodatek B
Dalsza lektura
W tym dodatku zamiecilimy list rde dalszych informacji dotyczcych programo-
wania OpenGL. Wrd podanych ksiek znajduj si zarwno pozycje zwizane bez-
porednio z OpenGL, jak i z programowaniem Windows w oglnoci, za kilka z nich
dotyczy zaawansowanych technik programowania grafiki 3D. Oprcz tego zamiecilimy
kilka ciekawych adresw stron internetowych wypenionych informacjami na temat
programowania OpenGL, przykadowymi programami oraz czami do innych zwizanych
z tym stron.
Programming Windows 95
Charles Petzold, Paul Yao
Microsoft Press
(polskie wydanie:Programowanie Windows 95 READ ME)
684_______________________________________________Dodatki
Firma URL
Silicon Graphics/OpenGL WWW http://www.sgi.com/Technology/openGL/
Center
Template Graphics http://www.cts.com/~template/
Microsoft http://www.microsoft.com/ntworkstation/opengl.htm
Yiewpoint Datalabs http://www.viewpoint.com/
3D Accelerator Information http://www.cs.columbia.edu/~bm/3dcards/3d-cardsl.html
Mark Kilgard's home page http://reality.sgi.com/employees/mjk_asd/home.html
Silicon Graphics/Mark Kilgard http://www.sgi.com/Technology/openGL/glut3.html
Skadnice VRML
The VRML Repository http://www.sdsc.edu/vrmy
Paragraph International http://vrml.paragraph.com/
Silicon Graphics Vertex http://webspace.sgi.com/Repository/
International The http://www.vrml. com:80/models/vertex/
Geometry Center Ziff- http://www.geom.umn.edu/~daerorL/bin/legitlist.cgi
Davis ORC http://www.zdnet.com/zdi/vrml/
http://www.ocnus/models/models.html
Dodatek C
OpenGL wersja 1.1
W grudniu 1995 roku, podczas powstawania tej ksiki, grupa OpenGL Architecture
Review Board ratyfikowaa i zaaprobowaa now wersj, 1.1, specyfikacji OpenGL.
Wraz z wypuszczeniem Windows NT 4.0, Microsoft stanie si jednym z pierwszych,
jeli nie pierwszym, dostawc penej implementacji nowej specyfikacji OpenGL, prze-
znaczonej do komputerw osobistych. Oprcz zachowania zgodnoci z now specyfi-
kacj, Microsoft poprawi wydajno OpenGL oraz doda kilka nowych elementw i
moliwoci, midzy innymi moliwo umieszczania wywoa OpenGL w rozszerzonych
metaplikach, a take poprawion obsug wydruku.
Do najciekawszych elementw nowej specyfikacji OpenGL nale:
* Tablice wierzchokw, umoliwiajce szybsze przekazywanie pooenia wierz-
chokw, normalnych, kolorw oraz indeksw kolorw, wsprzdnych tekstur
oraz znacznikw krawdzi.
* Operacje logiczne na pikselach w trybie RGBA, a nie tylko w trybie indeksu
kolorw.
4 Wiele nowych i ulepszonych waciwoci zwizanych z teksturami^to jest pra-
wdopodobnie najwaniejszym dodatkiem zawartym w nowej specyfikacji).
Nowa wersja OpenGL dla Windows 95 ma si pojawi w kilka miesicy od ukazania si
Windows NT 4.0, czyli ju po wydaniu tej ksiki. Tak wic aby mc odpowiednio
przedstawi now specyfikacj i rozszerzenia dodane przez Microsoft, na pytce CD-
ROM zamiecilimy specjaln kartotek. Kartoteka \OpenGLll zawiera bardziej kom-
pletn dokumentacj na temat nowych elementw wersji 1.1, a take troch dodatko-
wych rzeczy dorzuconych przez Microsoft. Znajdziesz tam take kilka przykadowych
programw.
Dodatek D
Sownik
Alfa
Czwarta warto koloru dodana w celu umoliwienia okrelenia przezroczystoci koloru
obiektu. Warto alfa 0,0 oznacza cakowit przezroczysto, za warto l ,0 oznacza
zupeny brak przezroczystoci.
Antyaliasing
Metoda renderowania uywana do uzyskiwania gadkich linii i krzywych. Ta technika
urednia kolor pikseli przylegych do linii i daje wizualny efekt zagodzenia przejcia z
pikseli linii do pikseli otaczajcych lini, przez co linia wydaje si gadsza.
Aspekt ekranu
Stosunek szerokoci okna do jego wysokoci, szeroko okna w pikselach podzielona
przez wysoko okna w pikselach.
Biblioteka AUX
Niezalena biblioteka narzdziowa. Uyteczna przy popiesznym tworzeniu przenonych
programw OpenGL.
Bitplan
Tablica bitw odwzorowywanych bezporednio na piksele ekranu.
Brya widzenia
Obszar przestrzeni 3D, ktry mona obserwowa przez okna na ekranie. Obiekty i punkty
poza bry widzenia zostan obcite (nie bd widoczne).
Bufor
Obszar pamici uywany do przechowywania informacji o obrazie. Tymi informacjami
mog by kolor, gboko czy informacje o mieszaniu kolorw. Bufory dla czerwieni,
zieleni i bkitu nosz wspln nazw bufora koloru.
690______________________________________________Podatki
Culling
Eliminacja przedniej lub tylnej ciany prymitywu, w wyniku czego nie jest ona
rysowana.
Czworokt
Wielokt o dokadnie czterech bokach.
Dese
Wzorzec binarny uywany przy blokowaniu operacji w buforze ramki podczas rysowania
linii i wieloktw. Przypomina to uycie bitmapy maski, lecz w przypadku linii
uywane s jednowymiarowe desenie, za w przypadku wieloktw - dwuwymiarowe.
Krzywa Beziera
Krzywa, ktrej ksztat jest wyznaczany przez punkty kontrolne w pobliu krzywej, a nie
przez same punkty krzywej.
Krzywa parametryczna
Krzywa, ktrej ksztat jest wyznaczony przez jeden (w przypadku krzywej) lub dwa (w
przypadku powierzchni) parametry. Te parametry wystpuj w osobnych rwnaniach,
wyznaczajcych wsprzdne x, y i z punktw nalecych do krzywej.
Lista wywietlania
Skompilowana lista polece i funkcji OpenGL. Gdy zostanie wywoana, jest wykonywana
szybciej, ni trwaoby wywoywanie poszczeglnych polece i funkcji z listy.
Litera
Warto, a nie nazwa zmiennej. Oznacza acuch lub sta liczbow wpisan bezporednio
w kodzie rdowym.
Macierz
Dwuwymiarowa tablica liczb. Na macierzach mona wykonywa operacje matematy-
czne, za same macierze s wykorzystywane przy przeksztaceniach wierzchokw.
Mapowanie tekstury
Proces nakadania obrazu tekstury na powierzchni. Powierzchnia nie musi by przy
tym planarna (paska). Mapowanie tekstury czsto jest uywane w celu owinicia"
obrazu dookoa zakrzywionego obiektu lub w celu uzyskania powierzchni z deseniem, na
przykad drewna czy marmuru.
Dodatek D. Sownik________________________________________691
Normalizacja
Oznacza redukcj wektora normalnego do wektora jednostkowego, przy zachowaniu
oryginalnego kierunku. Normalna jednostkowa jest wektorem, ktrego dugo wynosi
dokadnie 1,0.
Normalna
Wektor kierunkowy wskazujcy prostopadle do paszczyzny lub powierzchni w danym
punkcie. Jeli uywasz normalnych, musisz okreli je dla kadego wierzchoka
prymitywu.
NURBS
Skrt od Non-Uniform Rational B-Spline (niejednorodna wymierna krzywa B-skleja-na).
Metoda parametrycznej reprezentacji krzywych i powierzchni.
Obcinanie
Eliminacja czci pojedynczego prymitywu lub grupy prymityww. Punkty, ktre miayby
zosta narysowane poza regionem lub bry obcinania, nie s rysowane. Bryla
obcinania to oglnie uywane okrelenie macierzy rzutowania.
Open Irwentor
Biblioteka klas C++ oraz zestaw narzdzi przeznaczone do tworzenia interaktywnych
aplikacji 3D. Open Inventor jest zbudowany na podstawie OpenGL.
Ostrosup widzenia
Brya widzenia w ksztacie ostrosupa uywana w rzucie perspektywicznym (blisze
obiekty s wiksze, dalsze s mniejsze).
Paleta
Zestaw kolorw dostpnych dla operacji rysunkowych. W przypadku 8-bitowych trybw
Windows paleta zawiera 256 kolorw, ktre musz wystarczy do wyrysowania
wszystkich pikseli na ekranie.
Perspektywa
Tryb rzutowania, w ktrym obiekty pooone dalej od obserwatora wydaj si mniejsze od
obiektw pooonych bliej.
Piksel
Nazwa pochodzi od zoenia sw picture element - element obrazu. Najmniejszy element
obrazu na ekranie komputera. Piksele s uoone w wiersze i kolumny ekranu i s im
przypisywane odpowiednie kolory skadajce si na cakowity obraz.
Podwjne buforowanie
Technika rysowania uywana w OpenGL. Obraz, ktry ma zosta wywietlony, tworzony
jest w pamici, a nastpnie przerzucany na ekran w pojedynczej operacji, w przeci-
wiestwie do tworzenia obrazu prymityw po prymitywie, bezporednio na ekranie.
692____________________________________________________Dodatki
Podzia wielokata
Proces podziau zoonego wielokata lub powierzchni analitycznej na siatk paskich
wieloktw wypukych. Moe zosta zastosowany take w celu rozbicia zoonej krzywej
na seri mniej zoonych odcinkw.
Prymityw
Paski wieloktny ksztat zdefiniowany w OpenGL. Wszystkie obiekty i sceny skadaj si
z rnorodnych kombinacji prymityww.
Przeksztacenie
Manipulacja ukadem wsprzdnych. Do przeksztace nale obroty, translacje (prze-
sunicia), skalowanie (w okrelonym kierunku lub rwnomiernie we wszystkich kie-
runkach) oraz podzia perspektywiczny.
Pasteryzacja
Zamiana prymityww we wsprzdnych obiektu na obraz w buforze ramki. Tzw. kana
renderowania to proces, w ktrym polecenia i instrukcje OpenGL zostaj zamienione w
piksele na ekranie.
Roztrzsanie
Metoda uywana do symulacji szerszego zakresu kolorw, ni jest sprztowo dostpny,
przez rozmieszczanie obok siebie odpowiednio pokolorowanych pikseli, tworzcych
wzory dajce wraenie przejcia midzy kolorami.
Rzut rwnolegy
Tryb rzutowania, w ktrym nie wystpuje perspektywa. W tym rzutowaniu rozmiary
wszystkich prymityww pozostaj niezmienne bez wzgldu na ich orientacj i odlego
od obserwatora.
Rzutowanie
Przeksztacenie linii, punktw i wieloktw ze wsprzdnych obserwatora do obcitych
wsprzdnych na ekranie.
Siatka
Reprezentacja jednolitych obiektw przez siatk linii zamiast wypenionych, cienio-
wanych wieloktw. Modele siatkowe zwykle s rysowane szybciej i mog suy do
przedstawienia zarwno przedniej, jak i tylnej ciany modelu rwnoczenie.
Splajn
Oglne okrelenie kadej krzywej utworzonej przez rozmieszczenie dookoa niej punktw
kontrolnych, wpywajcych na ksztat tej krzywej. Uoenie krzywej przypomina reakcj
elastycznego materiau na nacisk przyoony w rnych jego miejscach.
Dodatek D. Sownik________________________________________693
wiato otaczajce
wiato w scenie, ktre nie pochodzi z adnego konkretnego rda ani kierunku. wiato
otaczajce rwnomiernie iluminuje wszystkie obiekty ze wszystkich stron.
Teksel
Podobny do piksela (elementu obrazu), z tym e stanowi element tekstury (texture ele-
ment). Teksel reprezentuje kolor tekstury, jaki zostanie zastosowany w buforze ramki dla
pikseli reprezentujcych dany fragment wielokta z naoon tekstur.
Tekstura
Obraz (bitmapa) nakadany na powierzchni prymitywu.
Transcluencja
Stopie przezroczystoci obiektu. W OpenGL reprezentowany jest przez warto alfa z
zakresu od l ,0 (nieprzezroczysty) co 0,0 (cakowicie przezroczysty).
Tryb natychmiastowy
Tryb renderowania grafiki, w ktrym funkcje i polecenia natychmiast wpywaj na stan
renderowania.
Ukad kartezjaski
Ukad wsprzdnych oparty na trzech skierowanych osiach, uoonych pod ktem pro-
stym do siebie. Wsprzdne w tym ukadzie oznaczane s literami x, y i z.
Widok
Obszar okna uywany do wywietlania obrazw OpenGL. Zwykle obejmuje cay obszar
roboczy okna Windows. Rozcignite lub skurczone widoki mog suy do tworzenia
powikszonego lub pomniejszonego obrazu w fizycznym oknie na ekranie.
Wielokt
Dwuwymiarowy ksztat z dowoln (lecz wiksz ni dwa) liczb wierzchokw.
Wielokty wypuke
Wielokty, ktre nie posiadaj wci" ani wgniece". Precyzyjnie: wielokt wypuky to
taki, w ktrym adna przechodzca przez niego linia nie przecina krawdzi wicej ni dwa
raz (raz wchodzi" i raz wychodzi").
Wierzchoek
Pojedynczy punkt w przestrzeni. Uywany przy definiowaniu wieloktw i linii, definiuje
take punkt, w ktrym cz si dwie krawdzie wielokta.
694________________________________________________Dodatki
Wsprzdne obserwatora
Ukad wsprzdnych oparty na pooeniu obserwatora. Oko obserwatora znajduje si na
osi z, a patrzy w kierunku ujemnych wartoci tej osi.
Wyciganie
Proces dodawania trzeciego wymiaru do paskiego obrazu lub ksztatu, na przykad za-
miana dwuwymiarowych czcionek na trjwymiarowe litery.
Skorowidz
.BMP 367 AUX_RETURN 83
3DDI 36 4GL AUX_RGBA 80
52, 657 8514 AUX_RIGHT 83
240 AUX_RIGHTBUTTON 84
AUX_SINGLE 80
AUX_SPACE 83
alpha blending 260 AUX_STENCIL 81
ambient 272, 273 AUX_UP 83 AUX_Z 83
animacja 74 AUX_z 83 aux!dleFunc()
animacja palety 259 74,79 auxInitDisp!ayMode()
ANSI 356 77, 80 aux!nitPosition() 61, 81
antyaliasing 260,498 aux!nitWindow() 62,81
API 35,51 auxKeyFunc() 82
aplikacja konsoli 59 auxMainLoop() 67, 83
AppExpert 643 auxMouseFunc() 84
AppWizard 629 auxReshapeFunc() 69, 85
ARB 37 auxSetOneColor() 85
Architecture Review Board 37 auxSolidBox() 86
aspect ratio 72 auxSo!idCone() 86, 87
automatyczne generowanie wsprzdnych auxSolidCylinder() 87
tekstury 401 AUX 33, 51, 52 auxSolidDodecahedron() 88
AUX_0 83 AUX_9 83 AUX_A auxSolid!cosahedron() 88
83 AUX_a 83 AUX_ACCUM 81 auxSolidOctahedron() 88
AUX_ALPHA 81 AUX_DEPTH auxSolidSphere() 89
81 AUX_DEPTH16 81 auxSolidTeapot() 89
AUX_DOUBLE 80 auxSolidTetrahedron() 90
AUX_DOWN 83 AUX_ESCAPE auxSolidTorus() 90
83 AUX_FIXED_332_PAL 81 auxSolidxxxx() 78
AUX_INDEX 80 AUX_LEFT 83 auxSwapBuffers() 77,91
AUX_LEFTBUTTON 84 auxWireBox() 91
AUX_MIDDLEBUTTON 84 auxWireCone() 91,92,208
AUX_MOUSEDOWN 84 AUX auxWireCylinder() 92
MOUSEUP 84 auxWireDodecahedron() 93
auxWire!cosahedron() 93
auxWireOctahedron() 94
auxWireSphere() 94
auxWireTeapot() 78
auxWireTeapot() 95
696 Dodatki
auxWireTetrahedron() 95 cprintf() 60 CreatePalette()
auxWireTorus() 95 254 CS_PARENTDC 108
auxWirexxxx() 78 cylindry 435 czcionki
bitmapowe 355 czworokty
B 174 czysto kodu 55
BeginPaint() 104 czyszczenie okna 62
Bezier 535 Bezier
545
biblioteka AUX 33,51,56 dane typu
biblioteka narzdziowa 52 double 54
bitmapa 175 float 54
BITMAPINFOHEADER 365, 367 GLbitfield 54
bitmapy 351 blending 505 bd GLboolean 54
GL_INVALID_ENUM 139 GLbyte 54
GL_INVALID_OPERATION 138, 139 GLclampd 54
GL_INVALID_VALUE 139 GLclampf 54
GL_NO_ERROR 138, 139 GLdouble 54
GL_OUT_OF_MEMORY 138, 139 GLenum 54
GL_STACK_OVERFLOW 139 GLfloat 54
GL_STACK_UNDERFLOW 139 GLint 54
GLU_INVALID_ENUM 139 GLshort 54
GLU_INVALID_VALUE 139 GLsizei 54
GLU_OUT_OF_MEMORY 138, 139 GLubyte 54
bdy 133 brya obcinania 49 brya GLuint 54
widzenia 50,217 bufor GLushort 54
akumulacji 494 long 54
gbokoci 479 short 54
koloru 64, 477 signed char 54
selekcji 590 unsigned char 54
sprzenia zwrotnego 598 unsigned long 54
stereo 478 szablonu 489 unsigned short 54
buforowanie 76, 77 bufory 60, DDI 38 DEC 37
473 definiowanie
bryy obcinania 72
tekstur 389
C 52 widoku 71 Delphi 657,665
C++ 52 DescribePixelFormat() 118, 476
CAD 36, 49 dese 176
CALLBACK 66 Device Driver Interface 38
CGA 239 diffuse 272,273
ChangeSizeO 69,114 DirectDraw 36 DirectX 36
chipset GLINT 40 dithering 242, 250 DLL 53
ChoosePixelFormat() 109,116, 476 domylny kolor rysowania 163
cigo krzywej 536 dopasowywanie kolorw 249
cienie 302 DOS 59 double 54
cieniowanie 43, 235, 246 drukowanie bitmap 372
cie 44 dyski 435
COLORREF 62
Skorowidz 697
ChangeSize() 69,114
ChoosePixelFormat()
efekty specjalne 459 109,116,476 cprintfO 60
EGA 240 CreatePalette() 254
ekran 44 DescribePixelFormat()
EndDoc() 373 118,476 EndDoc() 373
EndPageO 373 EndPage() 373 EndPaint()
EndPaint() 104 104 getch() 60
etykiety sprzenia zwrotnego GetPixelFormat() 122
601 glAccumO 495,499
glBeginO 149, 184,340
fala wietlna 236 glBitmapO 352
false 54 glBlendFunc() 507, 530
FL_FOG_HINT 525 glCallListO 343 glCallLists()
float 54 344 glClear() 64, 170
format pikseli 108 glClearColor() 62, 96, 500
fosfor 238 glClearDepth() 481,500
funkcja renderujca 66 glClear!ndex() 263, 501
funkcja glClearStencilO 489, 501
aux!dleFunc() 74, 79 glColorO 245, 263
aux!nitDisplayMode() glColorMask() 265
77, 80 aux!nitPosition() glColorMaterial() 279, 309
61, 81 aux!nitWindow() glCopyPixels() 366, 377
62, 81 auxKeyFunc() 82 glCullFaceO 185,310
auxMainLoop() 67, 83 glDeleteLists() 345
auxMouseFunc() 84 glDepthFuncO 502
auxReshapeFunc() 69, glDepthRange() 481, 503
85 auxSetOneColor() 85 glDisableO 153,160,461,468
auxSolidBox() 86 glDrawBuffer() 501
auxSolidCone() 86 gIDrawPixels() 359, 362, 378
auxSolidCube() 87 glEdgeFlagO 181, 186
auxSolidCylinder() 87 glEnable() 153, 160,461,468
auxSolidDodecahedron() glEndO 149, 188,340
88 glEndListO 340, 346
auxSolid!cosahedron() glEvalCoord() 540,551
88 auxSolidOctahedron() glEvalMesh() 541,552
88 auxSolidSphere() 89 glEvalPoint() 553
auxSolidTeapot() 89 glFeedbackBuffer() 598, 605
auxSolidTetrahedron() glFlush() 96 glFog() 531
90 auxSolidTorus() 90 glFrontFace()
auxSolidxxxx() 78 164,173,188,310
auxSwapBuffers() 77, 91 glFrustum() 218,225
auxWireBox() 91 glGenList() 346 glGet() 153
auxWireCone() 91 glGetBoolean() 462
auxWireCube() 92, 208 glGetErrorO 134, 138
auxWireCylinder() 92 glGetFloatO 153
auxWireDodecahedron() glGetLastErrorO 138
93 glGetLight() 312 glGetMapO
auxWire!cosahedron() 553 glGetMaterial() 311
93 auxWireOctahedron() glGetPolygonStipple() 189
94 auxWireSphere() 94
auxWireTeapot() 78,95
auxWireTetrahedron()
95 auxWireTorus() 95
auxWirexxxx() 78
BeginPaint() 104
698 Dodatki
funkcja glTexCoord() 394, 429
glGetStringO 136, 139 glTexEnv() 429 glTexGen()
glHintO 137, 140, 525 430 glTex!magelD() 389,431
gllndex() 265 gl!ndexMask() glTexImage2D() 391,432
266 gllnitNamesO 607 glTexParameter() 433
glIsDisabled() 462 glTextEnv() 392 glTranslateO
gllsEnabledO 462, 470 209,216,231 gluBeginCurve()
gllsListO 347 glLight() 559 gluBeginPolygon() 576,
300,314 glLightModelO 315 583 gluBeginSurfaceO 547,
glLineStippleO 160, 190 560 gluBeginTrimO 549,560
glLineWidthO 158, 191 gluCylinder() 437,451
glListBase() 348 gluDeleteNurbsRenderer()
glLoadEntityO 147 547, 561 gluDeleteQuadric()
glLoadldentityO 72, 212, 226 452 gluDeleteTessO 583
glLoadMatrix() 223,226 gluDiskO 438,452
glLoadName() 607 gluEndCurve() 562
glLogicOpO 267 glMap() gluEndPolygon() 576, 583
539, 555 glMapGridO 541, gluEndSurface() 547,563
558 glMaterialO 293,317 gluEndTrim() 549, 563
glMatrixMode() 147, 212, gluErrorStringO 135, 141
224, 227 glMultMatrix() 224, gluGetNurbsPropertyO 563
228 glNewList() 340, 349 gluGetStringO 136, 141
glNormalO 284,318 glOrtho() gluLoadSamplingMatrices()
69, 97, 147 gIPassThroughO 654 gluLookAt() 231
600, 608 glPixelMap() 362, gluNewContour() 584
379 glPixelStore() 362, 380 gluNewNurbsRenderer() 547,
glPixelTransfer() 360, 382 565 gluNewQuadric() 436,
glPixelZoom() 362,383 453 gluNewTess() 576, 584
glPointSize() 152, 193 gluNextContour() 577
glPolygonMode() 173,194 gluNurbsCallback() 566
glPolygonStipple() 195 gluNurbsCurve() 568
glPopAttrib() 301,470 gluNurbsProperty() 547, 569
glPopMatrix() 148,216,228 gluNurbsSurfaceO 547, 571
glPopNameO 609 gluOrtho2D() 232
glPushAttribO 301,462,470 gluPaitialDisk() 439, 453
glPushMatrix() 148, 216, 229 gluPerspective() 218,233
glPushNameO 609 gluPickMatrix() 593,613
glRasterPos() 353 gluPwlCurve() 549, 572
glReadPixels() 363, 384 gluQuadricCallback() 454
glRect() 66,98 gluQuadricDrawStyle() 436,
glRenderMode() 590,610 454 gluQuadricNormals() 436,
glRotate() 79, 148, 209, 216, 455 gluQuadricOrientation()
229 glScale() 210,230 436, 455 gluQuadricTexture()
glSelectBuffer() 612 glSet() 436,456 gluSphere() 439, 456
153 glShadeMode() 169 gluTessCallback() 581,585
glShadeModel() 268 gluTessVertex() 576, 585
glStencilFunc() 489 glVertex() 148, 196
glStencilMask() 489 glViewport() 69, 71, 97
glStencilOpO 489 RenderScene() 66, 115,
148,289 SetPixelFormat()
109, 122 SetTimerO 114
SetupRCO 277
Skorowidz 699
funkcja GL_BLUE_BIAS 383, 464
StretchBltO 373 SwapBuffersO GL_BLUE_SCALE 383,464
115, 123 wgICreateContext() 106, GL_BORDER_COLOR 434
124 wglDeleteContext() 106, 125 GLJ3YTE 344,379 GL_CCW
wglGetCurrentContext() 125 164, 189,310 GL_CLAMP 434
wglGetCurrentDCO 126 GL_CLEAR 268 GL_COEFF
wglGetProcAddress() 126 554 GL_COLOR 378
wglMakeCurrent() 106, 127 GL_COLOR_BUFFER_BIT 170,463
wglShareListsO 128 GL_COLOR_INDEX 359, 379, 432, 433
wglUseFontBitmaps() 129, 355 GL_COLOR_INDEXES 312
wglUseFontOutlinesO 130 GL_COLOR_MATERIAL 279, 309, 463, 464
WinMain() 111 WndProcO 111 GL_COLOR_MATERIAL_FACE 464
funkcje bufora szablonu 489 GL_COMPILE 341, 349
funkcje Wiggle 106 GL_COMPILE_AND_EXECUTE 341,349
funkcje zwrotne 581 GL_CONSTANT_ATTENUATION 313
GL_COPY 268 GL_COPY_INVERTED 268
GL_COPY_PIXEL_TOKEN 599
GDI 35, 102, 245 GL_CULL_FACE 172, 186, 310, 463, 464
getch() 60 GL_CULL_FACE_MODE 464
GetPixelFormat() 122 GL_CURRENTJBIT 463
GL 36 gl 52 gl.h 52 GL_CURRENT_POSITION_VALID 463
GL_2_BYTES 344 GL_2D 599, 606 GL_CW 164, 189 GL_DECAL 393,430
GL_3_BYTES 344 GL_3D 599,606 GL_DECR 491 GL_DEPTH 378
GL_3D_COLOR 599, 606 GL_DEPTH_BIAS 383,464
GL_3D_COLOR_TEXTURE 599, 606 GL_DEPTH_BUFFER 463
GL_4_BYTES 344 GL_DEPTH_BUFFER_BIT 170
GL_4D_COLOR_TEXTURE 599, 606 GL_DEPTH_COMPONENT 379
GL_ACCUM 494, 499 GL_DEPTH_SCALE 383,464
GL_ACCUM_BUFFER_BIT 463 GL_ADD GL_DEPTH_TEST 170, 461, 463
494,499 GL_ALPHA 379, 432, 433 GL_DEPTH_WRITEMASK 463
GL_ALPHA_BIAS 383,464 GLJDIFFUSE 309 GL_DITHER 250, 463
GL_ALPHA_LUMINANCE 432, 433 GL_DOMAIN 554 GL_DONT_CARE 141
GL_ALPHA_SCALE 383, 464 GL_DRAW_PIXEL_TOKEN 599
GL_ALPHA_TEST 463 GL_ALWAYS GL_DST_ALPHA 506 GL_DST_COLOR 506
480,503 GL_AMBIENT 309 GL_EDGE_FLAG 463 GL_EMISSION 309
GL_AMBIENT_AND_DIFFUSE 279, 309 GL_ENABLE_BIT 463 GL_EQUAL 480, 503
GL_AND 268 GL_AND_INVERTED 268 GL_EQUIW 268 GL_EVAL_BIT 463
GL_AND_REVERSE 268 GL_EXP 520 GL_EXP2 520
GL_AUTO_NORMAL 463 GL_BACK 173, GL_EXTENSIONS 136, 140
186, 195, 309, 478, 502 GL_EYE_LINEAR 431 GL_EYE_PLANE 431
GL_BACK_AND_FRONT 309 GL FALT 169
GLJBITMAP 360,379
GL_BITMAP_TOKEN 599 GL_BLEND
393, 430, 463, 505 GL_BLUE 379, 432, 433
700 Dodatki
GL_FASTEST 141 GL_LINE_TOKEN 599
GLJFEEDBACK 598,611 GL_LINE_WIDTH_GRANULARITY 158
GL_FILL 173, 195 GL_LINE_WIDTH_RANGE 158 GLJJNEAR
GL_FLAT 268 390, 520 GL_LINEAR_ATTENUATION 313
GL_FLOAT 344, 379 GL_LINEAR_MIPMAP_LINEAR 391,396
GL_FOG 463 GL_LINEAR_M1PMAP_NEAREST 391,396
GL_FOG_BIT 463 GL_LINES 155, 184 GL_LIST_BASE 464
GL_FOG_COLOR 531 GL_LIST_BIT 464 GL_LOAD 494, 499
GL_FOG_DENSITY 524, 531 GL_LOGIC_OP 267, 463 GL_LUMINANCE
GL_FOG_END 531 359, 379, 432, 433 GL_LUMINANCE_ALPHA
GL_FOG_HINT 140,463 379 GL_MAP_COLOR 380, 382, 464
GL_FOG_INDEX 531 GL_MAP_DEPTH 464 GL_MAP_STENCIL
GL_FOG_MODE 463,520,531 380, 382 GL_MAP1_COLOR_4 554, 556, 569
GL_FOG_START 531 GL_MAP1_INDEX 554, 556, 569
GL_FRONT 186, 195, 309, 478, 502 GL_MAP1_NORMAL 554, 556, 569
GL_FRONT_AND_BACK 195,478,502 GL_MAP1_TEXTURE_COORDJ 554, 556,
GL_FRONT_FACE 464 569 GL_MAP1_TEXTURE_COORD_2
GL_GEQUAL 480, 503 554, 556,
GL_GREATER 480, 503 569 GL_MAP1_TEXTURE_COORD_3
GL_GREEN 379,432,433 554,556,
GL_GREEN_BIAS 383,464 569 GL_MAP1_TEXTURE_COORD_4
GL_GREEN_SCALE 383, 464 554,556,
GL_HINT_BIT 463 569
GLJNCR 491 GL_MAP1_VERTEX_3 539,554,556,569
GL_INDEX_OFFSET 383, 464 GL_MAP1_VERTEX_4 539, 554, 556, 569
GL_INDEX_SHIFT 383,464 GL_MAPl_x 463
GLJNT 344, 379 GL_MAP2_COLOR_4 554, 556, 572
GL_INVALID_ENUM 135, 139 GL_MAP2JNDEX 554, 556, 572
GL_INVALID_OPERATION 138, 139 GL_MAP2_NORMAL 554, 556, 572
GL_INVALID_VALUE 139 GL_MAP2_TEXTURE_COORD_1 554, 556,
GLJNYERT 268, 491 572 GL_MAP2_TEXTURE_COORD_2
GLJCEEP 490 554, 556,
GL_LEFT_BACK 478, 502 572 GL_MAP2_TEXTURE_COORD_3
GL_LEFT_FRONT 478, 502 554, 556,
GL_LEQUAL 480, 503 572 GL_MAP2_TEXTURE_COORD_4
GL_LESS 479, 503 554, 556,
GL_LIGHT 313 572
GL_LIGHT_MODEL_AMBIENT 278,315 GL_MAP2_VERTEX_3 554, 556, 572
GL_LIGHT_MODEL_LOCAL_VIEWER GL_MAP2_VERTEX_4 554, 556, 572
316,464 GL_MAP2_x 463 GL_MATRIX_MODE 464
GL_L1GHT_MODEL_TWO_SIDE 315,464 GL_MAX_MODELVIEW_STACK_DEPTH
GL_LIGHTO 288 GL_LIGHTi 463 214
GL_LIGHTING 277, 463, 464 GL_MAX_NAME_STACK_DEPTH 610
GL_LIGHTING_BIT 301,464 GL_LIGHTx GL_MAX_PROJECTION_STACK_DEPTH
464 GL_LINE 173, 195 GL_LINE_BIT 464 214
GL_LINE_LOOP 156, 185 GL_MODELVIEW 212, 224, 227, 431
GL_L1NE_RESET_TOKEN 599 GL_MODULATE 393,430 GL MULT
GL_LINE_SMOOTH 463, 464 494,499
GL_LINE_SMOOTH_HINT 140, 463
GL_LINE_STIPPLE 160,190,463,464
GL_LINE_STRIP 156, 184
Skorowidz 701
GL_NAME_STACK_DEPTH 609 GL_POLYGON_SMOOTH_HINT 141,463
GL_NAND 268 GL_NEAREST 390 GL_POLYGON_STIPPLE 176, 195,463,464
GL_NEAREST_MIPMAP_LINEAR 391,396 GL_POLYGON_STIPPLE_BIT 464
GL_NEAREST_MIPMAP_NEAREST 391, 396 GL_POLYGON_TOKEN 599 GL_POSITION
GL_NEVER 479, 503 GL_NICEST 141,525 298,313 GL_PROJECTION 227 GL_Q 431
GL_NO_ERROR 135, 138, 139 GL_NOOP 268 GL_QUAD_STRIP 175, 185
GL_NOR 268 GL_QUADRATIC_ATTENUATION 313
GL_NORMALIZE 285,318,463,464 GL_QUADS 174, 185 GL_R 431
GL_NOTEQUAL 480, 503 GL_READ_BUFFER 464 GL_RED
GL_OBJECT_LINEAR 401,430,431 379,432,433 GL_RED_BIAS 383,464
GL_ONE 506,531 GL_RED_SCALE 383, 464
GL_ONE_MINUS_DST_ALPHA 506 GL_RENDER 590,610 GL_RENDERER
GL_ONE_MINUS_DST_COLOR 506 140,611 GL_REPEAT 394, 434
GL_ONE_MINUS_SRC_ALPHA 506 GL_REPLACE 490 GL_RETURN 494,
GL_OR 268 499 GL_RGB 359,379,432,433
GL_OR_INVERTED 268 GL_RGBA 379,432,433
GL_OR_REVERSE 268 GL_RIGHT_BACK 478, 502
GL_ORDER 554 GL_RIGHT_FRONT 478, 502 GL_S
GL_OUT_OF_MEMORY 135, 138, 139 401,431 GL_SCISSOR_BIT_BIT 464
GL_PACK_ALIGNMENT 381 GL_SCISSOR_TEST 463, 464
GL_PACK_LSB_FIRST 381 GL_SELECT 610 GL_SELECTION 590
GL_PACK_ROW_LENGTH 381 GL_SET 268 GL_SHADE_MODE 464
GL_PACK_SKIP_PIXELS 381 GL_SHININESS 292,312 GL_SHORT
GL_PACK_SKIP_ROWS 381 344, 379 GL_SMOOTH 169,268
GL_PACK_SWAP_BYTES 381 GL_SPECULAR 292, 309
GL_PASS_THROUGH_TOKEN 599, 608 GL_SPHERE_MAP 431
GL_PERSPECTIVE_CORRECTION_HINT GL_SPOT_CUTOFF 300,313
140, 463 GL_SPOT_DIRECTION 313
GL_PIXEL_MAP_A_TO_A 380 GL_SPOT_EXPONENT 300,313
GL_PIXEL_MAP_B_TO_B 380 GL_SRC_ALPHA 506
GL_PIXEL_MAP_G_TO_G 380 GL_SRC_ALPHA_SATURATE 506
GL_PIXEL_MAP_I_TO_A 380 GL_STACK_OVERFLOW 139,214
GL_PIXEL_MAP_I_TO_B 380 GLJSTACKJJNDERFLOW 139,214
GL_PIXEL_MAP_I_TO_G 380 GL_STENCIL 378
GL_PIXEL_MAP_I_TO_I 380 GL_STENCIL_BUFFER_BIT 464
GL_PIXEL_MAP_I_TO_R 380 GL_STENCILJNDEX 379
GL_PIXEL_MAP_R_TO_R 380 GL_STENCIL_TEST 463, 464 GL_T
GL_PIXEL_MAP_S_TO_S 380 401,431 GL_TEXTURE 227
GL_PIXEL_MODE_BIT 464 GL_TEXTURE_1D 434,463
GL_POINT 195 GL_POINT_BIT GL_TEXTURE_2D 432, 433, 434, 463
464 GL_TEXTURE_BIT 464
GL_POINT_SIZE_GRANULARITY 153, 193 GL_TEXTURE_ENV 430 GL
GL_POINT_SIZE_RANGE 153, 193 TEXTURE ENV COLOR 430
GL_POINT_SMOOTH 463, 464
GL_POINT_SMOOTH_HINT 141,463
GL_POINT_TOKEN 599 GL_POINTS 149, 184
GL_POLYGON 185,575 GL_POLYGON_B1T
464 GL_POLYGON_MODE 464
GL_POLYGON SMOOTH 463,464
702 Dodatki
GL_TEXTURE_ENV_MODE 430 glDeleteLists() 345
GL_TEXTURE_GEN 463 glDepthFuncO 502
GL_TEXTURE_GEN_MODE 430, glDepthRange() 481,503
464 GL_TEXTURE_GEN_Q 430 glDisableO 153,
GL_TEXTURE_GEN_R 430 160,461,468 GLdouble 54
GL_TEXTURE_GEN_S 430 glDrawBuffer() 501
GL_TEXTURE_GEN_T 430 glDrawPixels() 359, 362,
GL_TEXTURE_GEN_x 464 378 glEdgeFlagO 181, 186
GL_TEXTURE_MAX_FILTER glEnable()
434 GL_TEXTURE_MIN_FILTER 153,160,461,468 glEnd()
390,434 GL_TEXTURE_WRAP_S 149,188,340 glEndListO
394, 434 GL_TEXTURE_WRAP_T 340, 346 GLenum 54
434 GL_TRANSFORM_BIT 464 glEvalCoord() 540,551
GL_TRIANGLE_FAN glEvalMesh() 541,552
165,185,581 glEvalPoint() 553
GL_TRIANGLE_STRIP glFeedbackBuffer() 598,
164,185,581 GLJTRIANGLES 605 GLfloat 54 glFlush()
162,185,581 96 glFogO 520,531
GL_UNPACK_ALIGNEMNT 382, glFrontFaceO 164, 173,
379 GL_UNPACK_LSB_FIRST 188, 310 glFrustumO
381 218,225 glGenList() 346
GL_UNPACK_ROW_LENGTH glGet() 153 glGetBoolean()
362, 382 462 glGetErrorO 134, 138
GL_UNPACK_SKIP_PIXELS 362, glGetFloatO 153
382 GL_UNPACK_SKIP_ROWS glGetLastError() 138
363, 382 glGetLightO 312
GL_UNPACK_SWAP_BYTES 381 glGetMapO 553
GL_UNSIGNED_BYTE 344, 379 glGetMaterial() 311
GLJJNSIGNEDJNT 344, 379 glGetPolygonStippleO 189
GL_UNSIGNED_SHORT 344, 379 glGetStringO 136,139
GL_VENDOR 140 GL_VERSION glGetStringO 139 glHintO
140 GL_VIEWPORT_BIT 464 137, 140, 525 gllndex() 265
GL_XOR 268 GL_ZERO gl!ndexMask() 266
490,506,531 GL_ZOOM_X 464 gllnitNamesO 607 GLINT
GL_ZOOM_Y 464 glAccumO 40 GLint 54 glIsDisabled()
495,499 glaux.h 52 glaux.lib 52 462 glIsEnabled() 462, 470
glBegin() 149,184,430 GLbitfield glIsList() 347 glLight()
54 glBitmapO 352 glBlendFuncO 300,314 glLightModelO
507, 530 GLboolean 54 GLbyte 54 315 glLineStippleO 160,
glCallList() 343, 344 GLclampd 54 190 glLineWidth() 158, 191
GLclampf 54 glClear() 64, 170 glListBase() 348
glClearColorO 62, 96, 500 glLoadEntityO 147
glClearDepthO 481,500 glLoadIdentity()
glCleadndex() 263, 501 212,226,72 glLoadMatrix()
glClearStencilO 489, 501 glColorO 223, 226 glLoadName()
245, 263 glColorMaskO 265 607 glLogicOpO 267
glColorMaterial() 279, 309 glMapO 539, 555
glCopyPixels() 366, 377 glMapGridO 541, 558
glCullFaceO 185,310
Skorowidz 703
glMaterialO 293,317 GLU_ERROR 566, 567, 582
glMatrixMode() 147,212,224,227 GLU_EXTENSIONS 136 GLU_EXTERIOR
glMultMatrix() 224,228 577 GLU_FALSE 437 GLU_FILL 436, 454,
glNewList() 340, 349 569 GLU_FLAT 437, 455 GLU_INSIDE 455
glNormalO 284,318 GLU_INTERIOR 577 GLU_INVALID_ENUM
glOrthoO 69, 97, 147 139 GLU_INVALID_VALUE 139 GLU_LINE
glPassThrough() 600,608 436 GLU_LINE 454 GLU_MAP1_TRIM_2
glPixelMap() 362,379 573 GLU_MAP1_TRIM_3 573 GLU_NONE
glPixelStore() 362, 380 437,455 GLU_NURBS_ERRORx 566,567
glPixelTransfer() 360, 382 GLU_OUT_OF_MEMORY 135,138, 139
glPixelZoom() 362, 383 GLU_OUTLINE_PATCH 569
glPointSize() 152, 193 GLU_OUTLINE_POLYGON 569
glPolygonMode() 173, 194 GLU_OUTSIDE 455
glPolygonStipple() 195 GLU_PARAMETRIC_ERROR 570
glPopAttrib() 301,470 GLU_PARAMETRIC_TOLERANCE 564, 569
glPopMatrix() 148,216,228 GLU_PATH_LENGTH 569, 570 GLU_POINT
glPopName() 609 436, 454 GLU_SAMPLING_METHOD 564,
glPushAttribO 301,462,470 570 GLU_SAMPLING_TOLERANCE 564, 569
glPushMatrix() 148, 216, 229 GLU_SILHOUETTE 436, 454 GLU_SMOOTH
glPushNameO 609 437,455 GLUJTRUE 437 GLU_U_STEP 564,
glRasterPos() 353 570 GLUJJNKNOWN 577 GLU_V_STEP 564,
glReadPixels() 363, 384 570 GLU_VERTEX 582 glu32.dll 52
glRectO 66,98 gluBeginCurve() 559 gluBeginPoygonO 576,
glRenderMode() 590,610 583 gluBeginSurfaceO 547, 560 gluBeginTrimO
glRotate() 79, 148, 209, 216, 229 549,560 GLubyte 54 gIuCylinder() 437,451
glScale() 210,230 gluDeleteNurbsRenderer() 547, 561
g!SelectBuffer() 612 gluDeleteQuadric() 452 gluDeleteTessO 583
glSet() 153 gluDiskO 438, 452 gluEndCurve() 562
glShadeMode() 169 gluEndPolygonO 576, 583 gluEndSurface() 547,
glShadeModelO 268 563 gluEndTrim() 549, 563 gluErrorStringO
GLshort 54 135, 141 gluGetNurbsPropertyO 563
GLsizei 54 gluGetStringO 136, 141 GLuint 54
glStencilFunc() 489 gluLoadSamplingMatricesO 654
glStencilMask() 489 gluLookAt() 231
glStencilOpO 489
g!TexCoord() 394, 429
glTexEnv() 429
glTexGen() 430
glTex!magelD() 389,431
glTexImage2D() 391,432
glTexParameter() 433
glTextEnv() 392
glTranslateO 209,216,231
glu 52
glu.h 52
GLU_AUTO_LOAD_MATRIX 564, 570, 613
GLUJ3EGIN 581
GLU_CCW 577
GLU_CULLING 564, 569
GLU_CW 577
GLU_DISPLAY_MODE 564, 569
GLU_DOMAIN_DISTANCE 570
GLU_EDGE_FLAG 582
GLU END 582
704 Dodatki
gluNewContour() 584
gluNewNurbsRenderer()
547, 565 gluNewQuadric() jednolite obiekty 166
436, 453 gluNewTess() jzyk 4GL 52 jzyk
576,584 gluNextContour() GL 36
577 gluNurbsCallback() 566 K
gluNurbsCurve() 568
GLUnurbsObj 546 karta
gluNurbsPropertyO 547, 569 8514 240
gluNurbsSurfaceO 547, 571 EGA 240
gluOrtho2D() 232 Hercules 239
gluPartialDisk() 439, 453 VGA 240
gluPerspective() 218,233 kartezjaski ukad wsprzdnych
gluPickMatrix() 593,613 45 kierunek trjkta 163 kierunek
gluPwlCurve() 549,572 wieloktw 285 kierunkowe
gluQuadricCallback() 454 rdo wiata 299 klasa krzywej
gluQuadricDrawStyle() 436, 535 klawiatura 83 kolejka polece
454 gluQuadricNormals() 64 kolejka przeksztace 207
436, 455 GLUuadricObj kolor 43, 63, 235
436 gluQuadricOrientation() dopasowywanie 249
436, 455 paleta 249 komunikat
gluQuadricTexture() 436, WM_CLOSE 338
456 GLushort 54 WM_CREATE 107
gluSphereO 439, 456 WM_DESTROY 107
gluTessCallback() 581,585 WM_PAINT 104, 107,338
gluTessVertes() 576, 585 WM_PALETTECHANGED
GLUtriangulatorObj 576 116,253
glVertex() 148, 196 WM_QUERYNEWPALETTE
glViewport() 69,71,97 252
GLYPHMETR1CSFLOAT WM_QUERYPALETTE 116
131 gbia koloru 241 WM_SIZE 114
gboko mgy 524 grafika WMJTIMER 115,337
interaktywna 587 grafika konfigurowanie buforw 474
rastrowa 351 Graphics konstruowanie wieloktw 179
Device Interface 35 GUI 59 kontekst renderowania OpenGL
105 kontekst urzdzenia GDI 102
H kontrolki OCX 659 konwencje
HAL 39 nazw funkcji 55 kopiowanie
Hardware Abstraction Layer pixmap 366 kostka kolorw 243
39 krzywe 533 krzywe
HBRUSH 103 Beziera 535, 545
Hercules 239 cigo 536
HGLRC 106 dwuwymiarowe 537
hierarchia obiektw 594 klasa 535
HPALETTE 251 obliczenia 537
punkty kontrolne 535
l reprezentacja parametryczna
IBM 37 imbryk 534
78 inicjowanie stopie 535
67 Intel 37 wzy 546
Internet 615 kwadryki
IR1S GL 36, 37 435
Skorowidz 705
normalne jednostkowe 285
lampa 44 NURBS 54,533,545
linie 145
linie przerywane 160
listy wywietlania 340 obcinanie wsprzdnych 46
LOGPALETTE 251 obiekt GLUnurbsObj 546
long 54 GLUquadricObj 436
GLUtriangulatorObj 576 obrt 203, 209 obszar
obcinania 46, 49 obszar roboczy okna 46 OCX
adowanie macierzy 223 659 odbyski 291 odczytplikow.BMP 368
amane 156 amane odtwarzanie zmiennych stanu 462 odwzorowanie
zamknite 156 czenie GL_MAP1_COLOR_4 554, 556, 569
kolorw 509 GL_MAP1_INDEX 554,556,569
GL_MAP1_NORMAL 554, 556, 569
M GL_MAP1_TEXTURE_COORD_1 554,556,
macierze 206, 680 569
macierz GL_MAP1_TEXTURE_COORD_2 554,556,
GL_MODELVIEW 227 569
GL_PROJECTION 227 GL_MAP1_TEXTURE_COORD_3 554,556,
GL_TEXTURE 227 569
adowanie 223 rzutowania GL_MAP1_TEXTURE_COORD_4 554, 556,
216 stos macierzy 213 569
tosamociowa 211 widoku GL_MAP1_VERTEX_3 554,556,569
modelu 208 GL_MAP1_VERTEX_4 554,556,569
makro RGB 103,245 GL_MAP2_COLOR_4 554, 556, 572
mapowanie tekstur 387 GL_MAP2_INDEX 554, 556, 572
maszyna stanu OpenGL 461 GL_MAP2_NORMAL 554, 556, 572
materia 275 owietlenie GL_MAP2_TEXTURE_COORD_1 554, 556,
275 waciwoci 275, 572
279 GL_MAP2_TEXTURE_COORD_2 554, 556,
MFC 52, 627 572
mga 505, 520 GL_MAP2_TEXTURE_COORD_3 554, 556,
GL_FOG_COLOR 531 572
GL_FOG_DENSITY 531 GL_MAP2_TEXTURE_COORD_4 554, 556,
GL_FOG_END 531 572
GL_FOG_INDEX 531 GL_MAP2_VERTEX_3 554, 556, 572
GL_FOG_MODE 531 GL_MAP2_VERTEX_4 554, 556, 572
GL_FOG_START 531 okno widoku 46 oko 41
mipmapy 389, 394 Open Inventor 617
model 202 opengl32.dll 52 operacja
model cieniowania 246 GL_AND 268
model owietlenia 278 GL_AND_INVERTED 268
modelowanie obiektw 321 GL_AND_REVERSE 268
mysz 84 GL_CLEAR 268
GL_COPY 268
N GL_COPY_INVERTED 268
nakadanie tekstur 388 nazwy GL_EQUIW 268
funkcji 55 nazywanie
prymityww 588 niezaleno
od platformy 57 normalizacja
285 normalne 544
706 Dodatki
operacja glu.h 52
GLJNYERT 268 glu32.dll 52
GLJMAND 268 opengl32.dll 52
GL_NOOP 268 WINSRV.DLL 38 pliki
GL_NOR 268 nagwkowe 60 Pug and Play 659
GLJDR 268 paskie cieniowanie 248 paszczyzna
GL ORJNYERTED 268 44 paszczyzna xy 45 pynne
GL~OR_REVERSE 268 cieniowanie 246 podwjne
GL_SET 268 buforowanie 76, 77, 477 podzia
GL_XOR 268 wielokta 181,575 PO1NTFLOAT
oprnianie kolejki polece 64 131 pojedyncze buforowanie 60
osie ukadu wsprzdnych 45 poprawianie wydajnoci 340, 679
ostrosup widzenia 218 porwnywanie gbokoci 479
owietlenie 271 owietlenie powierzchnie 533, 541
materiau 275 otwarte API 57 normalne 544
OWL 52,641 owietlenie 544
pozycjonowanie okna 60
pozycyjne rdo wiata 299
PAINTSTRUCT 104 PRINTDLG 372 prostokt 66
paleta systemowa 251 prymityw
paleta 242,249 GL_LINE_LOOP 156, 185
3-3-2 255 GL_LINE_STRIP 156, 184
animacja 259 GLJJNES 155, 184
struktura 254 GL_POINTS 149, 184
tworzenie 253, 258 GL_POLYGON 185,575
usuwanie 258 PALETTEENTRY 254 pasek GL_QUAD_STRIP 175, 185
czworoktw 175 perspektywa 50, 218 pdzle GL_QUADS 174, 185
103 PFD_DOUBLE_BUFFER_DONT_CARE GL_TR1ANGLE_FAN 165,185,581
121, GL_TRIANGLE_STRIP 164, 185, 581
475 GLJRIANGLES 162, 185, 581
PFD_DOUBLEBUFFER 121,475 prymitywy 47, 145 przedrostki nazw
PFD_DRAW_TO_B1TMAP 121,475 funkcji 52 przeksztacenia 200
PFD_DRAW_TO_WINDOW 121,475 przeksztacenie modelu 202 przeksztacenie
PFD_GENERIC_FORMAT 121,476 okna 206 przeksztacenie punktu
PFD_MA1N_PLANE 122 obserwacji 202 przeksztacenie rzutowania
PFD_NEED_PALETTE 121,254,476 205 przerzucanie kolorw 478 przestrze
PFD_NEED_SYSTEM_PALETTE 121,476 trjwymiarowa 146 przesunicie 203,208
PFD_OVERLAY_PLANE 122 PFD_STEREO przezroczysto 505 przygotowanie modelu
121,475 PFD_STEREO_DONT_CARE 121,475 owietlenia 278 przygotowanie okna 108
PFD_SUPPORT_GDI 121, 475 przygotowanie waciwoci materiau 279
PFD_SUPPORT_OPENGL 121,475 przyrostki nazw zmiennych 54 punkt
PFD_TYPE_COLORINDEX 122,260,475 zbiegu 205 punkty 145 punkty kontrolne
PFD_TYPE_RGBA 122,475 535
PFD_UNDERLAY_PLANE 122
PKELFORMATDESCRIPTOR 109, 254, 474
pixmapy 359 plik .BMP 367
gl.h 52
glaux.h 52
glaux.lib 52
Skorowidz 707
SetTimerO 114
SetupRCO 277
ay tracing 35 sfery 435 SGI
Reality Labs 39 35 short 54
remapowanie kolorw 360 sie komputerowa 615 signed
renderowanie 66 char 54 Silicon Graphics 35
RenderSceneO 66, 115, 148,289 skalowanie pixmapy 362
reprezentacja parametryczna krzywych 534 skalowanie 68, 114,203,210
RGB 51, 103,245 specular 272, 273 sprzenie
RGBA 60, 239 zwrotne 587 staa AUX_0 83
rotacja 203 AUX_9 83
rozdzielczo ekranu 241 AUX_A 83
roztrzsanie 242, 250 AUX_a 83
rwnanie parametryczne 534 AUX_ACCUM 81
rysowanie bitmapy 351 AUX_ALPHA 81
cylindrw 437 AUX_DEPTH 81
czworokty 174 AUX_DEPTH16 81
domylny kolor 163 AUX_DOUBLE 80
dyskw 438 AUX_DOWN 83
jednolite obiekty 166 AUX_ESCAPE 83
kierunek trjkta 163 AUX_FIXED_332_PAL 81
konstruowanie wieloktw 179 AUX_1NDEX 80
linie 155 AUX_LEFT 83
linie przerywane 160 AUX_LEFTBUTTON 84
amane 156 AUX_MIDDLEBUTTON 84
amane zamknite 156 AUX_MOUSEDOWN 84
pasek czworoktw 175 AUX_MOUSEUP 84
pixmapy 359 AUX_RETURN 83
podzia wielokta 181 AUX_RGBA 80
prymityww 47 AUX_RIGHT 83
punkty 149 AUX_RIGHTBUTTON 84
sfer 439 AUX_SINGLE 80
stokw 438 AUX_SPACE 83
wiata punktowego 301 AUX_STENCIL 81
trjktw 162,261 AUX_UP 83
tryby wieloktw 173 AUX_Z 83
ustawienie koloru wieloktw 169 AUX_z 83
usuwanie niewidocznych powierzchni 171 COLORREF 62
wachlarz trjktw 165 false 54
wieloktw 289 FL_FOG_HINT 525
wieloktw wklsych 576 GL_2_BYTES 344
wieloktw zoonych 577 GL_2D 599, 606
wycinkw dysku 439 GL_3_BYTES 344
wypenianie wieloktw 175 GL_3D 599,606
znacznik krawdzi 181 rzutowanie GL_3D_COLOR 599, 606
perspektywiczne 205, 218 rzutowanie GL_3D_COLOR_TEXTURE 599, 606
rwnolege 205,217 rzutowanie GL_4_BYTES 344
216,322 rzuty 48 rzuty GL_4D_COLOR_TEXTURE 599, 606
perspektywiczne 50 GL_ACCUM_BUFFER_BIT 463
GL_ALPHA 379, 432, 433
GL_ALPHA_BIAS 383,464
selekcja 588
SetPixelFormat() 109, 122
708 Dodatki
stal GL_DOMAIN 554 GL_DONT_CARE 141
GL_ALPHA_LUMINANCE 432, 433 GL_DRAW_PIXEL_TOKEN 599
GL_ALPHA_SCALE 383,464 GL_DST_ALPHA 506 GL_DST_COLOR
GL_ALPHA_TEST 463 GL_ALWAYS 506 GL_EDGE_FLAG 463 GL_EMISS10N
480, 490, 503 GL_AMBIENT 309 309 GL_ENABLE_BIT 463 GL_EQUAL
GL_AMBIENT_AND_DIFFUSE 279, 309 480, 490, 503 GL_EQUIW 268
GL_AND 268 GL_AND_INVERTED 268 GL_EVAL_BIT 463 GL_EXP 520
GL_AND_REVERSE 268 GL_EXP2 520 GL_EXTENSIONS 136, 140
GL_AUTO_NORMAL 463 GL_BACK 173, GL_EYE_LINEAR 431 GL_EYE_PLANE
186, 195, 309, 478, 502 431 GL_FALT 169 GL_FASTEST 141
GL_BACK_AND_FRONT 309 GL_FEEDBACK 590, 598, 611 GL_FILL
GL_BITMAP 360,379 173, 195 GL_FLAT 268 GL_FLOAT 344,
GL_BITMAP_TOKEN 599 GL_BLEND 379 GL_FOG 463 GL_FOG_BIT 463
430, 463, 505 GL_BLUE 379,432,433 GL_FOG_COLOR 531 GL_FOG_DENSITY
GL_BLUE_BIAS 383,464 524,531 GL_FOG_END 531
GL_BLUE_SCALE 383, 464 GL_FOG_HINT 140,463 GL_FOG_INDEX
GL_BORDER_COLOR 434 GL_BYTE 344, 531 GL_FOG_MODE 463,520,531
379 GL_CCW 164,189,310 GL_CLAMP GL_FOG_START 531 GL_FRONT 186,
434 GL_CLEAR 268 GL_COEFF 554 195, 309, 478, 502
GL_COLOR 378 GL_FRONT_AND_BACK 195, 478, 502
GL_COLOR_BUFFER_BIT 170,463 GL_FRONT_FACE 464 GL_GEQUAL 480,
GL_COLOR_INDEX 359, 579, 432, 433 490, 503 GL_GREATER 480, 490, 503
GL_COLOR_INDEXES 312 GL_GREEN 379,432,433
GL_COLOR_MATER1AL 279 GL_GREEN_BIAS 383,464
GL_COLOR_MATERIAL 309, 463, 464 GL_GREEN_SCALE 383,464
GL_COLOR_MATERIAL_FACE 464 GL_HINT_BIT 463 GL_INDEX_OFFSET
GL_COMPILE 341,349 383, 464 GL_INDEX_SHIFT 383, 464
GL_COMPILE_AND_EXECUTE 341,349 GLJNT 344, 379 GL_INVAL1D_ENUM
GL_CONSTANT_ATTENUATION 313 135, 139 GL_INVALID_OPERATION 138,
GL_COPY 268 GL_COPY_INVERTED 268 139 GL_1NVALID_VALUE 139
GL_COPY_PIXEL_TOKEN 599 GLJNYERT 268 GL_LEFT_BACK 478,
GL_CULL_FACE 172,186,310,463,464 502 GL_LEFT_FRONT 478, 502
GL_CULL_FACE_MODE 464 GL_LEQUAL 480, 490, 503 GL_LESS
GL_CURRENT_BIT 463 479,490,503 GL_LIGHT 313
GL_CURRENT_POSITION_VALID 463 GL_LIGHT_MODEL_AMBIENT 278,315
GL_CW 164, 189 GL_DECAL 392,430 stal
GL_DEPTH 378 GL_DEPTH_BIAS 383,
464 GL_DEPTH_BUFFER 463
GL_DEPTH_BUFFER_BIT 170
GL_DEPTH_COMPONENT 379
GL_DEPTH_SCALE 383,464
GL_DEPTH_TEST 170,461,463
GL_DEPTH_WRITEMASK 463
GLJDIFFUSE 309 GL DITHER 250, 463
Skorowidz 709
GL_LIGHT_MODEL_LOCAL_VIEWER 316, GL_MAP2_TEXTURE_COORD_3 554, 556,
464 572 GL_MAP2_TEXTURE_COORD_4 554,
GL_LIGHT_MODEL_TWO_SIDE 315,464 556,
GL_LIGHTO 288 GL_LIGHTi 463 572
GL_LIGHTING 277, 463, 464 GL_MAP2_VERTEX_3 554, 556, 572
GL_LIGHTING_BIT 301,464 GL_LIGHTx GL_MAP2_VERTEX_4 554, 556, 572
464 GL_LINE 173, 195 GL_LINE_B1T 464 GL_MAP2_x 463 GL_MATRIX_MODE 464
GL_LINE_LOOP 156, 185 GL_MAX_MODELVIEW_STACK_DEPTH
GL_LINE_RESET_TOKEN 599 214
GL_LINE_SMOOTH 463,464 GL_MAX_NAME_STACK_DEPTH 610
GL_LINE_SMOOTH_HINT 140,463 GL_MAX_PROJECTION_STACK_DEPTH
GL_LINE_STIPPLE 160, 190, 463, 464 214
GL_LINE_STRIP 156, 184 GL_LINE_TOKEN GL_MODELVIEW 212,224,227,431
599 GL_LINE_WIDTH_GRANULARITY 158 GL_MODULATE 430
GL_LINE_WIDTH_RANGE 158 GL_LINEAR GL_NAME_STACK_DEPTH 609
390, 520 GL_LINEAR_ATTENUATION 313 GL_NAND 268 GL_NEAREST 390
GL_LINEAR_MIPMAP_LINEAR 391,396 GL_NEAREST_MIPMAP_LINEAR 391,396
GL_LINEAR_MIPMAP_NEAREST 391,396 GL_NEAREST_MIPMAP_NEAREST 391,
GL_LINES 155, 184 GL_LIST_BASE 464 396
GL_LIST_BIT 464 GL_LOGIC_OP 267, 463 GL_NEVER 479, 490, 503
GL_LUMINANCE 359, 379, 432, 433 GLJNICEST 141,525
GL_LUMINANCE_ALPHA 379 GL_NO_ERROR 135, 138, 139
GL_MAP_COLOR 380, 382, 464 GL_NOOP 268 GL_NOR 268
GL_MAP_DEPTH 464 GL_MAP_STENCIL GL_NORMALIZE 285,318,463,464
380, 382 GL_MAP1_COLOR_4 554, 556, 569 GL_NOTEQUAL 480, 490, 503
GL_MAP1_INDEX 554, 556, 569 GL_OBJECT_LINEAR 430
GL_MAP1_NORMAL 554,556,569 GL_OBJECT_PLANE 401,431
GL_MAP1_TEXTURE_COORD_1 554, 556, GL_ONE 506,531
569 GL_MAP1_TEXTURE_COORD_2 GL_ONE_MINUS_DST_ALPHA 506
554,556, GL_ONE_MINUS_DST_COLOR 506
569 GL_MAP1_TEXTURE_COORD_3 554, GL_ONE_MINUS_SRC_ALPHA 506
556, GL_OR 268
569 GL_MAP1_TEXTURE_COORD_4 554, GL_OR_INVERTED 268
556, GL_OR_REVERSE 268
569 GL_ORDER 554
GL_MAP1_VERTEX_3 539,554,556,569 GL_OUT_OF_MEMORY 135, 138, 139
GL_MAP1_VERTEX_4 539, 554, 556, 569 GL_PACK_ALIGNMENT 381
GL_MAPl_x 463 GL_PACK_LSB_FIRST 381
GL_MAP2_COLOR_4 554, 556, 572 GL_PACK_ROW_LENGTH 381
GL_MAP2_INDEX 554, 556, 572 GL_PACK_SKIP_PIXELS 381
GL_MAP2_NORMAL 554, 556, 572 GL_PACK_SKIP_ROWS 381
GL_MAP2_TEXTURE_COORD_1 554, 556, GL_PACK_SWAP_BYTES 381
572 GL_MAP2_TEXTURE_COORD_2 554, GL_PASS_THROUGH_TOKEN 599, 608
556, GL_PERSPECTIVE_CORRECTION_HINT
572 140,463
GL_PIXEL_MAP_A_TO_A 380
GL_PIXEL_MAP_B_TO_B 380
GL_PIXEL_MAP_G_TO_G 380
GL_PIXEL_MAP_I_TO_A 380 GL
PIXEL MAP I TO B 380
710 Dodatki
staa GL_SPOT_DIRECTION 313
GL_PIXEL_MAP_I_TO_G GL_SPOT_EXPONENT 300,313
380 GL_PIXEL_MAP_I_TO_I GL_SRC_ALPHA 506
380 GL_SRC_ALPHA_SATURATE 506
GL_PIXEL_MAP_1_TO_R GL_STACK_OVERFLOW 139,214
380 GL_STACK_UNDERFLOW 139,214
GL_PIXEL_MAP_R_TO_R GL_STENCIL 378
380 GL_STENCIL_BUFFER_BIT 464
GL_PIXEL_MAP_S_TO_S GL_STENC1L_INDEX 379
380 GL_PIXEL_MODE_BIT GL_STENCIL_TEST 463, 464 GL_T
464 GL_POINT 195 401,431 GL_TEXTURE 227
GL_POINT_BIT 464 GL_TEXTURE_1D 392, 434, 463
GL_POINT_SIZE_GRANULARITY GL_TEXTURE_2D 392, 432, 433, 434,
153,193 GL_POINT_SIZE_RANGE 463 GL_TEXTURE_BIT 464
153,193 GL_POINT_SMOOTH 463, GL_TEXTURE_ENV 392,430
464 GL_POINT_SMOOTH HINT GL_TEXTURE_ENV_COLOR 430
141,463 GL_POINT_TOKEN 599 GL_TEXTURE_ENV_MODE 392, 430
GL_POINTS 149, 184 GL_POLYGON GL_TEXTURE_GEN 463
185,575 GL_POLYGON_BIT 464 GL_TEXTURE_GEN_MODE 430, 464
GL_POLYGON_MODE 464 GL GL_TEXTURE_GEN_Q 430
POLYGON_SMOOTH 463, 464 GL_TEXTURE_GEN_R 430
GLJPOLYGON_SMOOTH_HINT GL_TEXTURE_GEN_S 430
141,463 GL_POLYGON_STIPPLE GL_TEXTURE_GEN_T 430
176, 195,463,464 GL_TEXTURE_GEN_x 464
GL_POLYGON_STIPPLE_BIT 464 GL_TEXTURE_MAX_FILTER 434
GL_POLYGON_TOKEN 599 GL_TEXTURE_MIN_FILTER 390,
GL_POSITION 298,313 434 GL_TEXTURE_WRAP_S 394,
GL_PROJECTION 227 GL_Q 431 434 GL_TEXTURE_WRAP_T 434
GL_QUAD_STRIP 175, 185 GL_TRANSFORM_BIT 464
GL_QUADRATIC_ATTENUATION GL_TRIANGLE_FAN 165, 185, 581
313 GL_QUADS 174, 185 GL_R 431 GL_TRIANGLE_STRIP 164,185,581
GL_READ_BUFFER 464 GLJTRIANGLES 162, 185, 581
GL_RED 379,432,433 GL_UNPACK_ALIGNEMNT 382, 379
GL_RED_BIAS 383,464 GL_UNPACK_LSB_FIRST 381
GL_RED SCAL GL_UNPACK_ROW_LENGTH 362,
383,464 GL_RENDER 382 GL_UNPACK_SKIP_PIXELS 362,
590,610 GL RENDERER 382 GL_UNPACK_SKIP_ROWS 363,
140,611 GL~REPEAT 382 GL_UNPACK_SWAP_BYTES 381
394, 434 GL_RGB GL_UNSIGNED_BYTE 344, 379
359,379,432,433 GLJJNSIGNEDJNT 344, 379
GL_RGBA 379, 432, 433 GL_UNSIGNED_SHORT 344, 379
GL RIGHT_BACK 478, GL_VENDOR 140 GL_VERSION 140
502 GL~RIGHT_FRONT GL_VIEWPORT_BIT 464 GL_XOR
478, 502 GL_S 401,431 268 GL_ZERO 506 GL_ZERO 531
GL_SCISSOR_BIT_BIT GL_ZOOM_X 464 GL_ZOOM_Y 464
464 GL_SCISSOR_TEST GLU_AUTO_LOAD_MATRIX
463, 464 GL_SELECT 564,570,613 GLU_BEGIN 581
610 GL_SELECTION 590 GLU_CCW 577 GLU CULLING 564,
GL_SET 268 569
GL_SHADE_MODE 464
GL_SHININESS 292,312
GL_SHORT 344, 379
GL_SMOOTH 169,268
GL_SPECULAR 292, 309
GL_SPHERE_MAP 431 GL
SPOT CUTOFF 300,313
Skorowidz 711
staa PFD_UNDERLAY_PLANE 122
GLU_CW 577 PIXELFORMATDESCRIPTOR 254
GLU_DISPLAY_MODE 564, 569 true 54
GLU_DOMAIN_DISTANCE 570 WGL_FONT_LINES 131
GLU_EDGE_FLAG 582 GLU_END 582 WGL_FONT_POLYGONS 131
GLU_ERROR 566, 567, 582 stan bufora gbokoci 465
GLU_EXTENSIONS 136 GLU_EXTERIOR 577 bufora szablonu 465
GLU_FALSE 437 GLU_FILL 436, 454, 569 owietlenia 465
GLU_FLAT 437, 455 GLUJNSIDE 455 pikseli 467
GLUJNTERIOR 577 GLU_INVALID_ENUM rysowania 464
139 GLU_INVALID_VALUE 139 GLU_LINE teksturowania 466
436,454 GLU_MAP1_TRIM_2 573 stereoskop 42 stopie krzywej
GLU_MAP1_TRIM_3 573 GLU_NONE 437, 535 stopie poryskliwoci
455 GLU_NURBS_ERRORx 566, 567 293 stos macierzy 213
GLU_OUT_OF_MEMORY 135, 138, 139 stosunek wsprzdnych 72
GLU_OUTLINE_PATCH 569 StretchBltO 373 struktura
GLU_OUTLINE_POLYGON 569 palety 254 struktura
GLU_OUTSIDE 455 BITMAPFILEHEADER 367
GLU_PARAMETRIC_ERROR 570 BITMAPINFOHEADER 365
GLU_PARAMETRIC_TOLERANCE 564, 569 GLYPHMETRICSFLOAT 131
GLU_PATH_LENGTH 569, 570 GLU_POINT LOGPALETTE 251
436, 454 GLU_SAMPLING_METHOD 564, 570 PAINTSTRUCT 104
GLU_SAMPLING_TOLERANCE 564, 569 PALETTEENTRY 254
GLU_SILHOUETTE 436,454 GLU_SMOOTH PIXELFORMATDESCRIPTOR 109,474
437,455 GLU_TRUE 437 GLU_U_STEP 564, POINTFLOAT 131
570 GLUJJNKNOWN 577 GLU_V_STEP 564, PRINTDLG 372
570 GLU_VERTEX 582 style okien 108 styl
PFD_DOUBLE_BUFFER_DONT_CARE 121, CS_PARENTDC 108
475 WS_CLIPCHILDREN 108
PFD_DOUBLEBUFFER 121,475 WS_CL1PSIBLINGS 108
PFD_DRAW_TO_BITMAP 121,465 WS_OWNDC 107 Super VGA 61
PFD_DRAW_TO_WINDOW 121,475 SwapBuffers() 115, 123 szybko
PFD_GENERIC_FORMAT 121 dziaania 336
PFD_MAIN_PLANE 122
PFD_NEED_PALETTE 121,254
PFD_NEED_SYSTEM_PALETTE 121 cieka
PFD_OVERLAY_PLANE 122 PFD_STEREO GLU_CCW 577 GLU_CW
121,475 PFD_STEREO_DONT_CARE 121,475 577 GLU_EXTERIOR 577
PFD_SUPPORT_GDI 121,475 GLUJNTERIOR 577
PFD_SUPPORT_OPENGL 121,475 GLUJJNKNOWN 577
PFD_TYPE_COLOR1NDEX 122, 260, 475 PFD wiato 44,236 wiata
TYPE_RGBA 122, 475 punktowe 298 wiato jako
czstka 237 wiato
kierunkowe 299 wiato
ambient 272, 273 diffuse
272, 273 odbysku 272,
273 otaczajce 272, 273
712 Dodatki
wiato HGLRC 106
rozproszone 272, HPALETTE 251
273 specular 272, typy danych 53
273
U
uchwyt palety 251 uchwyt
tablice odwzorowa kolorw 361 pdzla 103 udostpnianie
teksturowanie cylindrw 438 palety 251 ukad
teksturowanie dysku 439 wsprzdnych 44, 45
teksturowanie sfer 440 kartezjaski 45
tekstury 387 osie 45
test szybkoci 336 UNICODE 356 UNIX 56 unsigned
timer 114 char 54 unsigned long 54 unsigned
transformacje wsprzdnych 199 short 54 ustalanie gruboci linii 158
translacja 203 ustalanie koloru rysowania 245
trjkt 162,261 ustalanie rozmiaru punktu 152
trjwymiarowe wsprzdne ustawianie bryy obcinania 68
kartezjaskie 48 ustawianie widoku 68 ustawienie
TrueColor 259 koloru wieloktw 169 usuwanie
true 54 niewidocznych linii 43 usuwanie
tryb cieniowania 248 niewidocznych powierzchni 171
tryb graficzny 241 usuwanie palety 258 urednianie
tryb indeksu koloru 239, 259, 308 normalnych 294 uywanie rda
tryb konsoli 59 wiata 281
tryb renderowania
GL_FEEDBACK 590
GL_RENDER 590 VGA 45,61,240
GL_SELECTION 590 tryb Yisual Basic 52,657
RGBA 239 tryb wywietlania 60 VRML 617
tryb-RGBA 60 tryby wieloktw
173 trzeci wymiar 41, 78 W
tworzenie kontekstu renderowania wachlarz trjktw 165
106 tworzenie kwadryk 436 warto
tworzenie palety 253, 258 AUX_0 83
tworzenie powierzchni NURBS AUX_9 83
546 tworzenie wasnych AUX_A 83
przeksztace 224 typ danych AUX_a 83
GL_2D 599,606 AUX_ACCUM 81
GL_3D 599,606 AUX_ALPHA 81
GL_3D_COLOR 599, 606 AUX_DEPTH 81
GL_3D_COLOR_TEXTURE 599, AUX_DEPTH16 81
606 AUX_DOUBLE 80
GL_4D_COLOR_TEXTURE 599, AUX_DOWN 83
606 AUX_ESCAPE 83
GL_2_BYTES 344 AUX_FIXED_332_PAL 81
GL_3_BYTES 344 AUX_INDEX 80
GL_4_BYTES 344 AUX_LEFT 83
GL_BYTE 344 AUX_LEFTBUTTON 84
GL_FLOAT 344 AUX MIDDLEBUTTON 84
GLJNT 344
GL_SHORT 344
GL_UNSIGNED_BYTE 344
GL_UNSIGNED_INT 344
GL UNSIGNED SHORT 344
Skorowidz 713
warto GL_COLOR_INDEXES 312
AUX_MOUSEDOWN GL_COLOR_MATERIAL 279
84 AUX_MOUSEUP GL_COLOR_MATERIAL 309, 463,
84 AUX_RETURN 83 464
AUX_RGBA 80 GL_COLOR_MATERIAL_FACE
AUX_RIGHT 83 464 GL_COMPILE 341,349
AUX_RIGHTBUTTON GL_COMPILE_AND_EXECUTE
84 AUX_SINGLE 80 341,349
AUX_SPACE 83 GL_CONSTANT_ATTENUATION
AUX_STENCIL 81 313 GL_COPY 268
AUX_UP 83 AUX_Z GL_COPY_INVERTED 268
83 AUX_z 83 GL_COPY_PIXEL_TOKEN 599
COLORREF 62 false GL_CULL_FACE
54 172,186,310,463,464
FL_FOG_HINT 525 GL_2_BYTES GL_CULL_FACE_MODE 464
344 GL_2D 599, 606 GL_CURRENT_BIT 463
GL_3_BYTES 344 GL_3D 599, GL_CURRENT_POSITION_VALID
606 GL_3D_COLOR 599, 606 463 GL_CW 164, 189 GL_DECAL
GL_3D_COLOR_TEXTURE 599, 392, 430 GL_DEPTH 378
606 GL_4_BYTES 344 GL_DEPTH_BIAS 383,464
GL_4D_COLOR_TEXTURE 599, GL_DEPTH_BUFFER 463
606 GL_ACCUM_BUFFER_BIT GL_DEPTH_BUFFER_BIT 170
463 GL_ALPHA 379, 432, 433 GL_DEPTH_COMPONENT 379
GL_ALPHA_BIAS 383,464 GL_DEPTH_SCALE 383,464
GL_ALPHA_LUMINANCE 432, GL_DEPTH_TEST 170, 461, 463
433 GL_ALPHA_SCALE 383,464 GL_DEPTH_WRITEMASK 463
GL_ALPHA_TEST 463 GL_DIFFUSE 309 GL_DITHER
GL_ALWAYS 480, 490, 503 250, 463 GL_DOMAIN 554
GL_AMBIENT 309 GLJDONT_CARE 141
GL_AMBIENT_AND_DIFFUSE GL_DRAW_PIXEL_TOKEN 599
279, 309 GL_AND 268 GL_DST_ALPHA 506
GL_AND_INVERTED 268 GL_DST_COLOR 506
GL_AND_REVERSE 268 GL_EDGE_FLAG 463
GL_AUTO_NORMAL 463 GL_EMISSION 309
GL_BACK 173, 186, 195, 309, 478, GL_ENABLE_BIT 463 GL_EQUAL
502 GL_BACK_AND_FRONT 309 480, 490, 503 GL_EQUIW 268
GL_BITMAP 360,379 GL_EVAL_BIT 463 GL_EXP 520
GL_BITMAP_TOKEN 599 GL_EXP2 520 GL_EXTENSIONS
GL_BLEND 430, 463, 505 136, 140 GL_EYE_LINEAR 431
GL_BLUE 379,432,433 GL_EYE_PLANE 431 GL_FALT
GL_BLUEJ3IAS 383,464 169 GL_FASTEST 141
GL_BLUE_SCALE 383, 464 GL_FEEDBACK 590,598,611
GL_BORDER_COLOR 434 GL_FILL 173, 195 GL_FLAT 268
GL_BYTE 344,379 GL_CCW GL_FLOAT 344, 379 GL_FOG 463
164,189,310 GL_CLAMP 434 GL_FOG_BIT 463
GL_CLEAR 268 GL_COEFF 554 GL_FOG_COLOR 531
GL_COLOR 378 GL_FOG_DENSITY 524,531
GL_COLOR_BUFFER_BIT GL_FOG_END 531
170,463 GL COLOR_INDEX 359, GL_FOG_HINT 140,463
579, 432, 433
714 Dodatki