Janusz Ganczarski
OpenGL
Elementarne obiekty geometryczne
Spis treści
Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
1. Elementarne obiekty geometryczne . . . . . . . . . . . . . . . . . . .
1
Wybór rodzaju prymitywu . . . . . . . . . . . . . . . . . . . . . . .
1
Definiowanie współrzędnych wierzchołków figur . . . . . . . . . . . .
4
Funkcje z grupy glVertex2 . . . . . . . . . . . . . . . . . . .
4
Funkcje z grupy glVertex3 . . . . . . . . . . . . . . . . . . .
4
Funkcje z grupy glVertex4 . . . . . . . . . . . . . . . . . . .
5
Prostokąty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
5
Punkty . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
6
Linie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
7
. . . . . . . . . . . . . . . . . . . . . . . . .
8
Plik prymitywy graficzne.cpp . . . . . . . . . . . . . . . . . .
9
Plik punkty.cpp . . . . . . . . . . . . . . . . . . . . . . . . .
16
Plik linie.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . .
18
Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
23
1. Elementarne obiekty geometryczne
Biblioteka OpenGL oferuje kilka podstawowych prymitywów graficznych,
które służą do modelowania dowolnych obiektów. Projektanci biblioteki ce-
lowo nie umieścili w niej bardziej skomplikowanych obiektów (wybrane po-
wierzchnie 3D zawiera biblioteka GLU). Decyzja o stopniu złożoności stoso-
wanych obiektów została pozostawiona użytkownikom i możliwościom kon-
kretnych implementacji OpenGL.
1.1. Wybór rodzaju prymitywu
Definiowanie współrzędnych wierzchołków figur podstawowych musi za-
wierać się pomiędzy wywołaniami funkcji:
void glBegin (GLenum mode)
void glEnd (void)
Parametr mode określa rodzaj prymitywu, którego wierzchołki będą definio-
wane. Parametr przyjmuje jedną z poniższych wartości:
— GL POINTS - punkty: p
1
, p
2
, p
3
, p
4
, ...,
— GL LINES - odcinki: p
1
p
2
, p
3
p
4
, p
5
p
6
, ...,
— GL LINE STRIP - łamana: p
1
, p
2
, p
3
, p
4
, ...,
— GL LINE LOOP - łamana zamknięta: p
1
, p
2
, p
3
, p
4
, ..., p
1
,
— GL TRIANGLES - trójkąty: 4 (p
1
, p
2
, p
3
), 4 (p
4
, p
5
, p
6
), ...,
— GL TRIANGLE STRIP - wstęga trójkątów: 4 (p
1
, p
2
, p
3
), 4 (p
3
, p
2
, p
4
),
4 (p
3
, p
4
, p
5
), 4 (p
5
, p
4
, p
6
), ...,
— GL TRIANGLE FAN - wachlarz trójkątów: 4 (p
1
, p
2
, p
3
), 4 (p
1
, p
3
, p
4
),
4 (p
1
, p
4
, p
5
), ...,
— GL QUADS - czworokąty,
— GL QUAD STRIP - wstęga czworokątów,
— GL POLYGON - wielokąt.
Szczególne znaczenie w grafice 3D ma trójkąt. Zasadniczą zaletą trójką-
ta jest jego ... płaskość, co w geometrycznym ujęciu oznacza, że trzy nie-
współliniowe punkty wyznaczają dokładnie jedną płaszczyznę w przestrzeni
trójwymiarowej.
Przy budowie skomplikowanych obiektów 3D składających się z trójką-
tów proporcjonalnie rośnie ilość wierzchołków, czyli ilość danych przetwa-
rzanych przez procesor komputera i karty graficznej. Stąd duże znaczenie
ma możliwość definiowania wstęg (patrz rysunek 1) i wachlarzy trójkątów
(rysunek 2). Prymitywy te bowiem umożliwiają definiowanie kolejnych trój-
kątów tylko przy pomocy jednego wierzchołka. Oczywiście nie w każdym
przypadku będzie możliwe wykorzystanie wstęgi lub wachlarza trójkątów,
ale wykorzystywać te prymitywy zawsze, gdy jest to możliwe.
1. Elementarne obiekty geometryczne
2
Rysunek 1. Program Prymitywy graficzne - wstęga trójkątów
Rysunek 2. Program Prymitywy graficzne - wachlarz trójkątów
Nieco bardziej skomplikowaną grupą prymitywów graficznych obsługiwa-
nych przez bibliotekę OpenGL są czworokąty i wstęgi czworokątów (patrz
rysunki 3 i 4). Zastosowanie tych prymitywów może być wygodne w wielu
sytuacjach, ale trzeba liczyć się z następującymi ograniczeniami:
— wierzchołki czworokąta muszą znajdować się w jednej płaszczyźnie,
1. Elementarne obiekty geometryczne
3
— rysowanie czworokąta zawierającego samoprzecięcie krawędzi (czwarty
czworokąt na rysunku 3) może być nieprawidłowe w niektórych sytu-
acjach.
Ponadto należy dodać, że wiele implementacji biblioteki OpenGL w procesie
przetwarzania wierzchołków dzieli czworokąty na trójkąty, co także może
powodować nieoczekiwane efekty.
Rysunek 3. Program Prymitywy graficzne - czworokąty
Rysunek 4. Program Prymitywy graficzne - wstęga czworokątów
Ostatnim prymitywem graficznym jest wielokąt. Wielokąty podlegają ta-
kim samym ograniczeniom jak czworokąty. Ich wierzchołki muszą znajdować
się w jednej płaszczyźnie, a krawędzie nie powinny się przecinać. Podobnie
jak w przypadku czworokątów, wiele implementacji OpenGL dzieli wielokąty
na trójkąty, co może być źródłem niepożądanych efektów.
1. Elementarne obiekty geometryczne
4
Specyfikacja wskazuje ograniczoną grupę funkcji biblioteki OpenGL, któ-
re mogą być wywoływane pomiędzy glBegin a glEnd. Należą do nich nastę-
pujące funkcje (lub grupy funkcji): glVertex, glColor, glSecondaryColor,
glIndex, glNormal, glTexCoord, glMultiTexCoord, glVertexAttrib,
glFogCoord, glArrayElement, glEvalCoord, glEvalPoint, glMaterial,
glEdgeFlag, glCallList i glCallLists. Wywołanie funkcji spoza powyż-
szej grupy spowoduje zgłoszenie błędu. Nie ma natomiast ograniczeń co do
wywoływania funkcji pochodzących z innych bibliotek wykorzystywanych
w programie.
1.2. Definiowanie współrzędnych wierzchołków figur
Współrzędne wierzchołków figur podstawowych standardowo definiuje
się przy pomocy funkcji z grupy glVertex. Co do zasady wierzchołki pry-
mitywów graficznych opisywane są w bibliotece OpenGL przy pomocy czte-
rech współrzędnych: (x, y, z, w). Ponieważ nie we wszystkich przypadkach
konieczne jest stosowanie wszystkich współrzędnych, OpenGL zawiera funk-
cje definiujące tylko trzy pierwsze współrzędne (wtedy wartość współrzędnej
w wynosi domyślnie 1) oraz funkcje definiujące dwie pierwsze współrzędne
(wtedy wartość współrzędnej z wynosi domyślnie 0, a wartość współrzędnej
w wynosi 1).
Grupa glVertex obejmuje 24 funkcje, które można podzielić na 3 rów-
noliczne podgrupy, każda wymagająca innej ilości współrzędnych. Parame-
trami funkcji z każdej podgrup są albo kolejne współrzędne wierzchołków,
albo wskaźniki na tablice zawierające te współrzędne.
Jak zapewne Czytelnik zauważył, większość prymitywów wymaga ściśle
określonej ilości wierzchołków. OpenGL w trakcie procesu rysowania prymi-
tywu pomija te ostatnie wierzchołki, których ilość nie pozwala na zbudowa-
nie prymitywu.
1.2.1. Funkcje z grupy glVertex2
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 glVertex2dv (const GLdouble *v)
void glVertex2fv (const GLfloat *v)
void glVertex2iv (const GLint *v)
void glVertex2sv (const GLshort *v)
1.2.2. Funkcje z grupy glVertex3
void glVertex3d (GLdouble x, GLdouble y, GLdouble z)
1. Elementarne obiekty geometryczne
5
void glVertex3f (GLfloat x, GLfloat y, GLfloat z)
void glVertex3i (GLint x, GLint y, GLint z)
void glVertex3s (GLshort x, GLshort y, GLshort z)
void glVertex3dv (const GLdouble *v)
void glVertex3fv (const GLfloat *v)
void glVertex3iv (const GLint *v)
void glVertex3sv (const GLshort *v)
1.2.3. Funkcje z grupy glVertex4
void glVertex4d (GLdouble x, GLdouble y, GLdouble z, GLdouble w)
void glVertex4f (GLfloat x, GLfloat y, GLfloat z, GLfloat w)
void glVertex4i (GLint x, GLint y, GLint z, GLint w)
void glVertex4s (GLshort x, GLshort y, GLshort z, GLshort w)
void glVertex4dv (const GLdouble *v)
void glVertex4fv (const GLfloat *v)
void glVertex4iv (const GLint *v)
void glVertex4sv (const GLshort *v)
1.3. Prostokąty
W specjalny sposób potraktowano w bibliotece OpenGL prostokąty. Opra-
cowana została bowiem oddzielna grupa funkcji glRect rysujących prostokąt
na podstawie współrzędnych dwóch wierzchołków: lewego górnego i prawego
dolnego. Prostokąt rysowany jest na płaszczyźnie o równaniu Z = 0, a jego
boki są równoległe do osi układu współrzędnych. Stanowi to duże oczywiście
ograniczenie, ale umożliwia jednocześnie opracowanie szczególnie szybkiej
implementacji rysowania prostokątów.
Podobnie jak funkcje z grupy glVertex, funkcje glRect dostępne są
w wersjach wymagających dwóch par współrzędnych wierzchołków oraz po-
bierających wskaźnik na tablice ze współrzędnymi wierzchołków:
void glRectd (GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
void glRectf (GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2)
void glRecti (GLint x1, GLint y1, GLint x2, GLint y2)
void glRects (GLshort x1, GLshort y1, GLshort x2, GLshort y2)
void glRectdv (const GLdouble *v1, const GLdouble *v2)
void glRectfv (const GLfloat *v1, const GLfloat *v2 )
void glRectiv (const GLint *v1, const GLint *v2)
void glRectsv (const GLshort *v1, const GLshort *v2)
1. Elementarne obiekty geometryczne
6
1.4. Punkty
Punkt w bibliotece OpenGL nie podlega efektom perspektywy i ma stan-
dardowo kształt kwadratu (piksela lub jego wielokrotności). Wielkość ryso-
wanych punktów określa funkcja:
void glPointSize (GLfloat size)
Parametr size określa średnicę punktu i jego wartość musi być większa od
0. Domyślnie wielkość punktów wynosi 1 i jest to jedyna wielkość, której ob-
sługę wymaga specyfikacja OpenGL. Dopuszczalny zakres wielkości punktu
oraz krok z jakim wielkość ta może być zmieniana zależy od implementacji
biblioteki OpenGL.
Punkty o różnych rozmiarach przedstawia rysunek 5.
Rysunek 5. Program Punkty - punkty o różnych rozmiarach
1. Elementarne obiekty geometryczne
7
1.5. Linie
Podobnie jak w przypadku punktów biblioteka OpenGL umożliwia zmia-
nę grubości (szerokości) rysowanych linii. Służy do tego funkcja:
void glLineWidth (GLfloat width)
Parametr określa grubość linii i musi być większy od 0. Domyślnie grubość
linii wynosi 1. Dopuszczalny zakres grubości linii oraz krok z jakim wielkość
ta może być zmieniana zależy od implementacji biblioteki OpenGL.
Rysunek 6. Program Linie - linie o różnych grubościach i wzorach
Poza grubością biblioteka OpenGL pozwala na określenie wzoru jakim
będzie rysowana linia (patrz rysunek 6). Umożliwia to funkcja:
void glLineStipple (GLint factor, GLushort pattern)
której parametr pattern to 16-bitowa liczba całkowita zawierająca wzór
rysowanej linii, a factor określa zwielokrotnienie bitów wzoru. Wartość pa-
1. Elementarne obiekty geometryczne
8
rametru factor jest ograniczona i w razie potrzeby obcinana do przedziału
[1, 256], a wartość początkowa wynosi 1. Początkowy wzór linii określa stała
FFFFh, która oznacza linię ciągłą.
Standardowo rysowanie linii ze wzorami jest wyłączone. Włączenie tego
mechanizmu wymaga wywołania funkcji glEnable z parametrem GL LINE -
STIPPLE.
1.6. Programy przykładowe
Pierwszy przykładowy program (plik prymitywy graficzne.cpp) po-
zwala na przetestowanie wszystkich prymitywów graficznych dostępnych
w bibliotece OpenGL. Szczególnie ważna jest możliwość bezpośredniej oceny
sposobu konstruowania takich prymitywów jak wstęgi trójkątów i czworo-
kątów. Program umożliwia zmianę rodzaju prymitywu bez usuwania współ-
rzędnych wierzchołków poprzedniego prymitywu. Może dać to czasami bar-
dzo zaskakujące efekty. Do przechowywania współrzędnych wierzchołków
prymitywów zastosowano klasę vector z biblioteki standardowej C++.
Nowym elementem biblioteki GLUT, który pojawił się w pierwszym
przykładowym programie jest wyświetlanie ciągów znaków w postaci nu-
merów wierzchołków prymitywów. Realizuje to funkcja:
void glutBitmapCharacter (void *font, int character)
której parametr font określa rodzaj wyświetlanej czcionki bitmapowej,
a character znak jaki ma zostać wyświetlony. Czcionki bitmapowe są na
stałe zapisane w bibliotece GLUT jako mapy bitowe. GLUT nie zawiera
funkcji umożliwiających skorzystanie z czcionek bitmapowych zawartych
w zewnętrznych plikach.
Biblioteka GLUT w wersji 3.x zawiera następujące czcionki bitmapowe:
— GLUT BITMAP 8 BY 13 - typowa czcionka o wymiarach znaków 8 × 13 pik-
seli; znaki ASCII z przedziału [0, 255]; odpowiednik standardowej czcion-
ki X Window o nazwie:
-misc-fixed-medium-r-normal–13-120-75-75-C-80-iso8859-1,
— GLUT BITMAP 9 BY 15 - typowa czcionka o wymiarach znaków 9 × 15 pik-
seli; znaki ASCII z przedziału [0, 255]; odpowiednik standardowej czcion-
ki X Window o nazwie:
-misc-fixed-medium-r-normal–15-140-75-75-C-90-iso8859-1
— GLUT BITMAP TIMES ROMAN 10 - 10-punktowa czcionka proporcjonalna Ti-
mes Roman; znaki ASCII z przedziałów: [32, 126] i [160, 255]; odpowied-
nik czcionki X Window o nazwie:
-adobe-times-medium-r-normal–10-100-75-75-p-54-iso8859-1,
— GLUT BITMAP TIMES ROMAN 24 - 24-punktowa czcionka proporcjonalna Ti-
mes Roman; znaki ASCII z przedziałów: [32, 126] i [160, 255]; odpowied-
1. Elementarne obiekty geometryczne
9
nik czcionki X Window o nazwie:
-adobe-times-medium-r-normal–24-240-75-75-p-124-iso8859-1,
— GLUT BITMAP HELVETICA 10 - 10-punktowa czcionka proporcjonalna He-
lvetica; znaki ASCII z przedziałów: [32, 126] i [160, 255]; odpowiednik
czcionki X Window o nazwie:
-adobe-helvetica-medium-r-normal–10-100-75-75-p-56-iso8859-1,
— GLUT BITMAP HELVETICA 12 - 12-punktowa czcionka proporcjonalna He-
lvetica; znaki ASCII z przedziałów: [32, 126] i [160, 255]; odpowiednik
czcionki X Window o nazwie:
-adobe-helvetica-medium-r-normal–12-120-75-75-p-67-iso8859-1,
— GLUT BITMAP HELVETICA 18 - 18-punktowa czcionka proporcjonalna He-
lvetica; znaki ASCII z przedziałów: [32, 126] i [160, 255]; odpowiednik
czcionki X Window o nazwie:
-adobe-helvetica-medium-r-normal–18-180-75-75-p-98-iso8859-1.
Jak Czytelnik już zapewne zauważył wszystkie czcionki zawierają znaki
ASCII kodowane w standardzie ISO 8859-1, czyli bez polskich liter. Niestety
nie istnieje prosta metoda wyświetlenia czcionek zawierających polskie litery.
W tym miejscu jedynie sygnalizujemy użycie w programie nowej funkcji:
void glRasterPos2i (GLint x, GLint y)
Funkcja ta, należąca do licznej grupy funkcji glRasterPos, określa poło-
żenie wyświetlanej grafiki rastrowej - w tym przypadku liczby określającej
numer wierzchołka prymitywu. Dokładny opis operacji na rastrach znajdzie
się w jednym z następnych odcinków kursu.
Drugi przykładowy program (plik punkty.cpp) prezentuje podstawowe
możliwości rysowania punktów w bibliotece OpenGL. Rozmiar punktów re-
gulują przyciski „+” (zwiększenie) i „-” (zmniejszenie). Rozmiar punktów
oraz ich współrzędne przechowywane są w obiektach klasy vector z biblio-
teki standardowej C++.
Trzeci przykładowy program (plik linie.cpp) prezentuje podstawowe
możliwości rysowania linii w bibliotece OpenGL. Szerokość rysowanej linii
regulują przyciski „+” (zwiększenie) i „-” (zmniejszenie). Menu podręczne
udostępnia kilka wzorów linii. Szerokość i wzór linii oraz współrzędne ich
początku i końca przechowywane są w obiektach klasy vector z biblioteki
standardowej C++.
1.6.1. Plik prymitywy graficzne.cpp
/∗
( c )
J a n u s z
G a n c z a r s k i
h t t p : / / www . j a n u s z g . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e < s t d l i b . h>
1. Elementarne obiekty geometryczne
10
#i n c l u d e < s t d i o . h>
#i n c l u d e <v e c t o r >
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
RECTANGLES = GL POLYGON + 1 0 0 ,
//
p r o s t o k ą t y
CLEAR VERTEX,
//
u s u w a n i e
w i e r z c h o ł k ó w
EXIT
//
w y j ś c i e
} ;
//
r o d z a j
r y s o w a n e g o
p r y m i t y w u
g r a f i c z n e g o
i n t
p r i m i t i v e = GL POINTS ;
//
w s p ó ł r z ę d n e
w i e r z c h o ł k ó w
p r y m i t y w u
s t d : : v e c t o r <GLint> v e r t e x x ;
s t d : : v e c t o r <GLint> v e r t e x y ;
//
f u n k c j a
g e n e r u j ą c a
s c e n ę
3D
void
D i s p l a y
( )
{
//
k o l o r
t ł a − z a w a r t o ś ć
b u f o r a
k o l o r u
g l C l e a r C o l o r
( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
//
c z y s z c z e n i e
b u f o r a
k o l o r u
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(GL MODELVIEW ) ;
//
m a c i e r z
m o d e l o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
k o l o r
p r y m i t y w u
g l C o l o r 3 f
( 0 . 0 , 1 . 0 , 0 . 0 ) ;
//
r y s o w a n i e
p r y m i t y w u
i f
( p r i m i t i v e == RECTANGLES)
f o r
( unsigned
i n t
i = 0 ;
i + 1 < v e r t e x x . s i z e
( ) ;
i +=2)
g l R e c t i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] , v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
e l s e
g l B e g i n
( p r i m i t i v e ) ;
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l E n d
( ) ;
//
k o l o r
k r a w ę d z i
o r a z
w i e r z c h o ł k ó w
p r y m i t y w ó w
g l C o l o r 3 f
( 0 . 0 , 0 . 0 , 0 . 0 ) ;
//
k r a w ę d z i e
t r ó j k ą t ó w
i f
( p r i m i t i v e == GL TRIANGLES)
{
g l B e g i n
( GL LINES ) ;
unsigned
i n t
p o s = 0 ;
while
( v e r t e x x . s i z e
( ) − p o s >= 3 )
{
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 0 ] , v e r t e x y
[ p o s + 0 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 1 ] , v e r t e x y
[ p o s + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 1 ] , v e r t e x y
[ p o s + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 2 ] , v e r t e x y
[ p o s + 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 2 ] , v e r t e x y
[ p o s + 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 0 ] , v e r t e x y
[ p o s + 0 ] ) ;
p o s += 3 ;
}
g l E n d
( ) ;
}
e l s e
//
k r a w ę d z i e
w s t ę g i
t r ó j k ą t ó w
i f
( p r i m i t i v e == GL TRIANGLE STRIP )
{
g l B e g i n
( GL LINES ) ;
//
k r a w ę d z i e
p i e r w s z e g o
t r ó j k ą t a
w s t ę g i
i f
( v e r t e x x . s i z e
( ) > 2 )
{
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
1. Elementarne obiekty geometryczne
11
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
}
//
k r a w ę d z i e
k o l e j n y c h
t r ó j k ą t ó w
w s t ę g i
f o r
( unsigned
i n t
i = 3 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
{
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i − 1 ] , v e r t e x y
[ i − 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i − 2 ] , v e r t e x y
[ i − 2 ] ) ;
}
g l E n d
( ) ;
}
e l s e
//
k r a w ę d z i e
w a c h l a r z a
t r ó j k ą t ó w
i f
( p r i m i t i v e == GL TRIANGLE FAN)
{
g l B e g i n
( GL LINES ) ;
//
k r a w ę d z i e
p i e r w s z e g o
t r ó j k ą t a
w a c h l a r z a
i f
( v e r t e x x . s i z e
( ) > 2 )
{
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
}
//
k r a w ę d z i e
k o l e j n y c h
t r ó j k ą t ó w
w a c h l a r z a
f o r
( unsigned
i n t
i = 3 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
{
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i − 1 ] , v e r t e x y
[ i − 1 ] ) ;
}
g l E n d
( ) ;
}
e l s e
//
k r a w ę d z i e
c z w o r o k ą t ó w
i f
( p r i m i t i v e == GL QUADS)
{
g l B e g i n
( GL LINES ) ;
unsigned
i n t
p o s = 0 ;
while
( v e r t e x x . s i z e
( ) − p o s >= 4 )
{
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 0 ] , v e r t e x y
[ p o s + 0 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 1 ] , v e r t e x y
[ p o s + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 1 ] , v e r t e x y
[ p o s + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 2 ] , v e r t e x y
[ p o s + 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 2 ] , v e r t e x y
[ p o s + 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 3 ] , v e r t e x y
[ p o s + 3 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 3 ] , v e r t e x y
[ p o s + 3 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ p o s + 0 ] , v e r t e x y
[ p o s + 0 ] ) ;
p o s += 4 ;
}
g l E n d
( ) ;
}
e l s e
//
w s t ę g a
c z w o r o k ą t ó w
i f
( p r i m i t i v e == GL QUAD STRIP )
{
g l B e g i n
( GL LINES ) ;
//
k r a w ę d z i e
p i e r w s z e g o
c z w o r o k ą t a
w s t ę g i
i f
( v e r t e x x . s i z e
( ) > 3 )
{
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 1 ] , v e r t e x y
[ 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 3 ] , v e r t e x y
[ 3 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 3 ] , v e r t e x y
[ 3 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
1. Elementarne obiekty geometryczne
12
g l V e r t e x 2 i
( v e r t e x x
[ 2 ] , v e r t e x y
[ 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ 0 ] , v e r t e x y
[ 0 ] ) ;
}
//
k r a w ę d z i e
k o l e j n y c h
c z w o r o k ą t ó w
w s t ę g i
f o r
( unsigned
i n t
i = 4 ;
i + 1 < v e r t e x x . s i z e
( ) ;
i += 2 )
{
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i − 2 ] , v e r t e x y
[ i − 2 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i − 1 ] , v e r t e x y
[ i − 1 ] ) ;
}
g l E n d
( ) ;
}
e l s e
//
k r a w ę d z i e
w i e l o k ą t a
i f
( p r i m i t i v e == GL POLYGON)
{
g l B e g i n
( GL LINE LOOP ) ;
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l E n d
( ) ;
}
e l s e
//
k r a w ę d z i e
p r o s t o k ą t ó w
i f
( p r i m i t i v e == RECTANGLES)
{
g l B e g i n
( GL LINES ) ;
f o r
( unsigned
i n t
i = 0 ;
i + 1 < v e r t e x x . s i z e
( ) ;
i +=2)
{
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i + 1 ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
}
g l E n d
( ) ;
}
//
w i e l k o ś ć
w i e r z c h o ł k ó w
p r y m i t y w ó w
g l P o i n t S i z e
( 3 . 0 ) ;
//
r y s o w a n i e
w i e r z c h o ł k ó w
p r y m i t y w ó w
g l B e g i n
( GL POINTS ) ;
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l E n d
( ) ;
//
r y s o w a n i e
numerów
w i e r z c h o ł k ó w
p r y m i t y w ó w
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
{
//
p o ł o ż e n i e
n a p i s u
g l R a s t e r P o s 2 i
( v e r t e x x
[ i ] + 2 , v e r t e x y
[ i ] + 2 ) ;
//
k o n w e r s j a
l i c z b a −> c i ą g
z n a k ó w
char
s t r
[ 1 0 ] ;
s p r i n t f
( s t r , ”%i ” , i + 1 ) ;
//
d ł u g o ś ć
n a p i s u
i n t
l e n = s t r l e n
( s t r ) ;
//
w y ś w i e t l e n i e
k o l e j n y c h
z n a k ó w
( c y f r )
n a p i s u
f o r
( i n t
i = 0 ;
i < l e n ;
i ++)
g l u t B i t m a p C h a r a c t e r
( GLUT BITMAP 9 BY 15 , s t r
[ i ] ) ;
}
//
s k i e r o w a n i e
p o l e c e ń
do
w y k o n a n i a
g l F l u s h
( ) ;
//
z a m i a n a
b u f o r ó w
k o l o r u
1. Elementarne obiekty geometryczne
13
g l u t S w a p B u f f e r s
( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( i n t
width ,
i n t
h e i g h t )
{
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
r z u t o w a n i e
p r o s t o k ą t n e
g l u O r t h o 2 D
( 0 , width , 0 , h e i g h t ) ;
//
g e n e r o w a n i e
s c e n y
3D
D i s p l a y
( ) ;
}
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
void MouseButton
( i n t
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o n == GLUT LEFT BUTTON && s t a t e == GLUT DOWN)
{
//
z a p a m i ę t a n i e
w s p ó ł r z ę d n y c h
w i e r z c h o ł k a
p r y m i t y w u
v e r t e x x . i n s e r t
( v e r t e x x . end
( ) , x ) ;
v e r t e x y . i n s e r t
( v e r t e x y . end
( ) , g l u t G e t
(GLUT WINDOW HEIGHT)−y ) ;
D i s p l a y
( ) ;
}
}
//
o b s ł u g a
menu
p o d r ę c z n e g o
void Menu ( i n t
v a l u e )
{
switch
( v a l u e )
{
//
p u n k t y
c a s e GL POINTS :
p r i m i t i v e = GL POINTS ;
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − punkty
( GL POINTS ) ” ) ;
D i s p l a y
( ) ;
break ;
//
l i n i e
c a s e GL LINES :
p r i m i t i v e = GL LINES ;
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − o d c i n k i
( GL LINES ) ” ) ;
D i s p l a y
( ) ;
break ;
//
o d c i n k i
c a s e GL LINE STRIP :
p r i m i t i v e = GL LINE STRIP ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − łamana
( GL LINE STRIP ) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − lamana
( GL LINE STRIP ) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
łamana
z a m k n i ę t a
c a s e GL LINE LOOP :
p r i m i t i v e = GL LINE LOOP ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − łamana
z a m k n i ę t a
( GL LINE LOOP ) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − lamana
z a m k n i e t a
( GL LINE LOOP ) ” ) ;
#e n d i f
1. Elementarne obiekty geometryczne
14
D i s p l a y
( ) ;
break ;
//
t r ó j k ą t y
c a s e GL TRIANGLES :
p r i m i t i v e = GL TRIANGLES ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − t r ó j k ą t y
(GL TRIANGLES) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − t r o j k a t y
(GL TRIANGLES) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
w s t ę g a
t r ó j k ą t ó w
c a s e GL TRIANGLE STRIP :
p r i m i t i v e = GL TRIANGLE STRIP ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w s t ę g a
t r ó j k ą t ó w
( GL TRIANGLE STRIP ) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w s t e g a
t r o j k a t o w
( GL TRIANGLE STRIP ) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
w a c h l a r z
t r ó j k ą t ó w
c a s e GL TRIANGLE FAN :
p r i m i t i v e = GL TRIANGLE FAN ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w a c h l a r z
t r ó j k ą t ó w
(GL TRIANGLE FAN) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w a c h l a r z
t r o j k a t o w
(GL TRIANGLE FAN) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
c z w o r o k ą t y
c a s e GL QUADS :
p r i m i t i v e = GL QUADS ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − c z w o r o k ą t y
(GL QUADS) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − c z w o r o k a t y
(GL QUADS) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
w s t ę g a
c z w o r o k ą t ó w
c a s e GL QUAD STRIP :
p r i m i t i v e = GL QUAD STRIP ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w s t ę g a
c z w o r o k ą t ó w
( GL QUAD STRIP ) ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w s t e g a
c z w o r o k a t o w
( GL QUAD STRIP ) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
w i e l o k ą t
c a s e GL POLYGON :
p r i m i t i v e = GL POLYGON ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w i e l o k ą t
(GL POLYGON) ” ) ;
1. Elementarne obiekty geometryczne
15
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − w i e l o k a t
(GL POLYGON) ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
p r o s t o k ą t y
c a s e RECTANGLES :
p r i m i t i v e = RECTANGLES ;
#i f d e f WIN32
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − p r o s t o k ą t y ” ) ;
#e l s e
g l u t S e t W i n d o w T i t l e
( ” Prymitywy
g r a f i c z n e − p r o s t o k a t y ” ) ;
#e n d i f
D i s p l a y
( ) ;
break ;
//
u s u w a n i e
w i e r z c h o ł k ó w
c a s e CLEAR VERTEX :
v e r t e x x . e r a s e
( v e r t e x x . b e g i n
( ) , v e r t e x x . end
( ) ) ;
v e r t e x y . e r a s e
( v e r t e x y . b e g i n
( ) , v e r t e x y . end
( ) ) ;
D i s p l a y
( ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
char ∗ a r g v [ ] )
{
//
i n i c j a l i z a c j a
b i b l i o t e k i
GLUT
g l u t I n i t
(& a r g c , a r g v ) ;
//
i n i c j a l i z a c j a
b u f o r a
r a m k i
g l u t I n i t D i s p l a y M o d e
(GLUT DOUBLE | GLUT RGB ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 5 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t C r e a t e W i n d o w
( ” Prymitywy
g r a f i c z n e − punkty
( GL POINTS ) ” ) ;
//
d o ł ą c z e n i e
f u n k c j i
g e n e r u j ą c e j
s c e n ę
3D
g l u t D i s p l a y F u n c
( D i s p l a y ) ;
//
d o ł ą c z e n i e
f u n k c j i
w y w o ł y w a n e j
p r z y
z m i a n i e
r o z m i a r u
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
g l u t M o u s e F u n c
( MouseButton ) ;
//
u t w o r z e n i e
podmenu − P r y m i t y w y
i n t
M e n u P r i m i t i v e = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ” Punkty
( GL POINTS ) ” , GL POINTS ) ;
glutAddMenuEntry
( ” O d c i n k i
( GL LINES ) ” , GL LINES ) ;
#i f d e f WIN32
glutAddMenuEntry
( ”Łamana ( GL LINE STRIP ) ” , GL LINE STRIP ) ;
glutAddMenuEntry
( ”Łamana z a m k n i ę t a
( GL LINE LOOP ) ” , GL LINE LOOP ) ;
glutAddMenuEntry
( ” T r ó j k ą t y
(GL TRIANGLES) ” ,GL TRIANGLES ) ;
glutAddMenuEntry
( ” Wstęga
t r ó j k ą t ó w
( GL TRIANGLE STRIP ) ” , GL TRIANGLE STRIP ) ;
glutAddMenuEntry
( ” W a c h l a r z
t r ó j k ą t ó w
(GL TRIANGLE FAN) ” ,GL TRIANGLE FAN ) ;
glutAddMenuEntry
( ” Czworokąty
(GL QUADS) ” ,GL QUADS ) ;
glutAddMenuEntry
( ” Wstęga
c z w o r o k ą t ó w
( GL QUAD STRIP ) ” , GL QUAD STRIP ) ;
glutAddMenuEntry
( ” W i e l o k ą t
(GL POLYGON) ” ,GL POLYGON ) ;
glutAddMenuEntry
( ” P r o s t o k ą t y ” ,RECTANGLES ) ;
#e l s e
glutAddMenuEntry
( ”Lamana ( GL LINE STRIP ) ” , GL LINE STRIP ) ;
glutAddMenuEntry
( ”Lamana z a m k n i e t a
( GL LINE LOOP ) ” , GL LINE LOOP ) ;
glutAddMenuEntry
( ” T r o j k a t y
(GL TRIANGLES) ” ,GL TRIANGLES ) ;
glutAddMenuEntry
( ” Wstega
t r ó j k a t ó w
( GL TRIANGLE STRIP ) ” , GL TRIANGLE STRIP ) ;
glutAddMenuEntry
( ” W a c h l a r z
t r ó j k a t o w
(GL TRIANGLE FAN) ” ,GL TRIANGLE FAN ) ;
1. Elementarne obiekty geometryczne
16
glutAddMenuEntry
( ” Czworokaty
(GL QUADS) ” ,GL QUADS ) ;
glutAddMenuEntry
( ” Wstega
c z w o r o k a t ó w
( GL QUAD STRIP ) ” , GL QUAD STRIP ) ;
glutAddMenuEntry
( ” W i e l o k a t
(GL POLYGON) ” ,GL POLYGON ) ;
glutAddMenuEntry
( ” P r o s t o k a t y ” ,RECTANGLES ) ;
#e n d i f
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
glutAddSubMenu
( ” Prymitywy ” , M e n u P r i m i t i v e ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” Usuń
w i e r z c h o ł k i ” ,CLEAR VERTEX ) ;
glutAddMenuEntry
( ” W y j ś c i e ” , EXIT ) ;
#e l s e
glutAddMenuEntry
( ” Usun
w i e r z c h o l k i ” ,CLEAR VERTEX ) ;
glutAddMenuEntry
( ” W y j s c i e ” , EXIT ) ;
#e n d i f
//
o k r e ś l e n i e
p r z y c i s k u
m y s z k i
o b s ł u g u j ą c e g o
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
1.6.2. Plik punkty.cpp
/∗
( c )
J a n u s z
G a n c z a r s k i
h t t p : / / www . j a n u s z g . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <v e c t o r >
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
CLEAR POINTS ,
//
u s u w a n i e
p u n k t ó w
EXIT
//
w y j ś c i e
} ;
//
w s p ó ł r z ę d n e
p u n k t ó w
s t d : : v e c t o r <GLint> v e r t e x x ;
s t d : : v e c t o r <GLint> v e r t e x y ;
//
r o z m i a r y
p u n k t ó w
s t d : : v e c t o r <G L f l o a t > p o i n t s s i z e ;
//
p o c z ą t k o w y
r o z m i a r
p u n k t ó w
G L f l o a t
p o i n t s i z e = 1 0 . 0 ;
//
f u n k c j a
g e n e r u j ą c a
s c e n ę
3D
void
D i s p l a y
( )
{
//
k o l o r
t ł a − z a w a r t o ś ć
b u f o r a
k o l o r u
g l C l e a r C o l o r
( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
//
c z y s z c z e n i e
b u f o r a
k o l o r u
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(GL MODELVIEW ) ;
//
m a c i e r z
m o d e l o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
k o l o r
p u n k t ó w
1. Elementarne obiekty geometryczne
17
g l C o l o r 3 f
( 1 . 0 , 0 . 0 , 0 . 0 ) ;
//
r y s o w a n i e
p u n k t ó w
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i ++)
{
//
w i e l k o ś ć
p u n k t ó w
g l P o i n t S i z e
( p o i n t s s i z e
[ i ] ) ;
g l B e g i n
( GL POINTS ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l E n d
( ) ;
}
//
s k i e r o w a n i e
p o l e c e ń
do
w y k o n a n i a
g l F l u s h
( ) ;
//
z a m i a n a
b u f o r ó w
k o l o r u
g l u t S w a p B u f f e r s
( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( i n t
width ,
i n t
h e i g h t )
{
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
r z u t o w a n i e
p r o s t o k ą t n e
g l u O r t h o 2 D
( 0 , width , 0 , h e i g h t ) ;
//
g e n e r o w a n i e
s c e n y
3D
D i s p l a y
( ) ;
}
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
void MouseButton
( i n t
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o n == GLUT LEFT BUTTON && s t a t e == GLUT DOWN)
{
//
z a p a m i ę t a n i e
w s p ó ł r z ę d n y c h
p u n k t u
v e r t e x x . i n s e r t
( v e r t e x x . end
( ) , x ) ;
v e r t e x y . i n s e r t
( v e r t e x y . end
( ) , g l u t G e t
(GLUT WINDOW HEIGHT)−y ) ;
//
z a p a m i ę t a n i e
b i e ż ą c e g o
r o z m i a r u
p u n k t u
p o i n t s s i z e . i n s e r t
( p o i n t s s i z e . end
( ) , p o i n t s i z e ) ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
}
//
o b s ł u g a
k l a w i a t u r y
void Keyboard
( unsigned char key ,
i n t x ,
i n t
y )
{
//
z w i ę k s z e n i e
r o z m i a r u
p u n k t u
i f
( k e y == ’+ ’ )
p o i n t s i z e += 0 . 2 5 ;
e l s e
//
z m n i e j s z e n i e
r o z m i a r u
p u n k t u
i f
( k e y == ’− ’ && p o i n t s i z e > 0 )
p o i n t s i z e −= 0 . 2 5 ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
//
o b s ł u g a
menu
p o d r ę c z n e g o
void Menu ( i n t
v a l u e )
{
switch
( v a l u e )
{
1. Elementarne obiekty geometryczne
18
//
u s u w a n i e
w s p ó ł r z ę d n y c h
i
r o z m i a r ó w
p u n k t ó w
c a s e CLEAR POINTS :
v e r t e x x . e r a s e
( v e r t e x x . b e g i n
( ) , v e r t e x x . end
( ) ) ;
v e r t e x y . e r a s e
( v e r t e x y . b e g i n
( ) , v e r t e x y . end
( ) ) ;
p o i n t s s i z e . e r a s e ( p o i n t s s i z e . b e g i n
( ) , p o i n t s s i z e . end
( ) ) ;
D i s p l a y
( ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
}
}
i n t
main
( i n t
a r g c ,
char ∗ a r g v [ ] )
{
//
i n i c j a l i z a c j a
b i b l i o t e k i
GLUT
g l u t I n i t
(& a r g c , a r g v ) ;
//
i n i c j a l i z a c j a
b u f o r a
r a m k i
g l u t I n i t D i s p l a y M o d e
(GLUT DOUBLE | GLUT RGB ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t C r e a t e W i n d o w
( ” Punkty ” ) ;
//
d o ł ą c z e n i e
f u n k c j i
g e n e r u j ą c e j
s c e n ę
3D
g l u t D i s p l a y F u n c
( D i s p l a y ) ;
//
d o ł ą c z e n i e
f u n k c j i
w y w o ł y w a n e j
p r z y
z m i a n i e
r o z m i a r u
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
g l u t M o u s e F u n c
( MouseButton ) ;
//
d o ł ą c z e n i e
f u n k c j i
o b s ł u g i
k l a w i a t u r y
g l u t K e y b o a r d F u n c
( Keyboard ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddMenuEntry
( ” Usuń punkty ” , CLEAR POINTS ) ;
glutAddMenuEntry
( ” W y j ś c i e ” , EXIT ) ;
#e l s e
glutAddMenuEntry
( ” Usun punkty ” , CLEAR POINTS ) ;
glutAddMenuEntry
( ” W y j s c i e ” , EXIT ) ;
#e n d i f
//
o k r e ś l e n i e
p r z y c i s k u
m y s z k i
o b s ł u g u j ą c e g o
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
1.6.3. Plik linie.cpp
/∗
( c )
J a n u s z
G a n c z a r s k i
h t t p : / / www . j a n u s z g . h g . p l
J a n u s z G @ e n t e r . n e t . p l
∗/
#i n c l u d e <GL/ g l u t . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e <v e c t o r >
//
s t a ł e
do
o b s ł u g i
menu
p o d r ę c z n e g o
enum
{
STIPPLE 1111111111111111 ,
//
w z ó r
l i n i i
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1. Elementarne obiekty geometryczne
19
STIPPLE 0000000011111111 ,
//
w z ó r
l i n i i
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
STIPPLE 1111111100000000 ,
//
w z ó r
l i n i i
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
STIPPLE 0000111100001111 ,
//
w z ó r
l i n i i
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
STIPPLE 1111000011110000 ,
//
w z ó r
l i n i i
1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
STIPPLE 0011001100110011 ,
//
w z ó r
l i n i i
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
STIPPLE 1100110011001100 ,
//
w z ó r
l i n i i
1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
CLEAR LINES ,
//
u s u w a n i e
l i n i i
EXIT
//
w y j ś c i e
} ;
//
w s p ó ł r z ę d n e
k o ń c ó w
l i n i i
s t d : : v e c t o r <GLint> v e r t e x x ;
s t d : : v e c t o r <GLint> v e r t e x y ;
//
s z e r o k o ś c i
l i n i i
s t d : : v e c t o r <G L f l o a t > l i n e s w i d t h ;
//
p o c z ą t k o w a
s z e r o k o ś ć
l i n i i
G L f l o a t
l i n e w i d t h = 1 0 . 0 ;
//
w z o r y
l i n i i
s t d : : v e c t o r <G L f l o a t > l i n e s s t i p p l e ;
//
p o c z ą t k o w y
w z ó r
r y s o w a n e j
l i n i i
GLushort
l i n e s t i p p l e = 0xFFFF ;
//
w s k a ź n i k
n a c i ś n i ę c i a
l e w e g o
p r z y c i s k u
m y s z k i
i n t
b u t t o n s t a t e = GLUT UP ;
//
f u n k c j a
g e n e r u j ą c a
s c e n ę
3D
void
D i s p l a y
( )
{
//
k o l o r
t ł a − z a w a r t o ś ć
b u f o r a
k o l o r u
g l C l e a r C o l o r
( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;
//
c z y s z c z e n i e
b u f o r a
k o l o r u
g l C l e a r
( GL COLOR BUFFER BIT ) ;
//
w y b ó r
m a c i e r z y
m o d e l o w a n i a
g l M a t r i x M o d e
(GL MODELVIEW ) ;
//
m a c i e r z
m o d e l o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
k o l o r
l i n i i
g l C o l o r 3 f
( 1 . 0 , 0 . 0 , 0 . 0 ) ;
//
w ł ą c z e n i e
r y s o w a n i a
w z o r ó w
l i n i i
g l E n a b l e
( GL LINE STIPPLE ) ;
//
r y s o w a n i e
l i n i i
f o r
( unsigned
i n t
i = 0 ;
i < v e r t e x x . s i z e
( ) ;
i += 2 )
{
//
s z e r o k o ś ć
l i n i i
g l L i n e W i d t h
( l i n e s w i d t h
[ i / 2 ] ) ;
//
w z ó r
r y s o w a n e j
l i n i i
g l L i n e S t i p p l e
( 1 , l i n e s s t i p p l e [ i / 2 ] ) ;
//
r y s o w a n i e
p o j e d y n c z e j
l i n i i
g l B e g i n
( GL LINES ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i ] , v e r t e x y
[ i ] ) ;
g l V e r t e x 2 i
( v e r t e x x
[ i + 1 ] , v e r t e x y
[ i + 1 ] ) ;
g l E n d
( ) ;
}
//
w y ł ą c z e n i e
r y s o w a n i a
w z o r ó w
l i n i i
g l D i s a b l e
( GL LINE STIPPLE ) ;
//
s k i e r o w a n i e
p o l e c e ń
do
w y k o n a n i a
g l F l u s h
( ) ;
//
z a m i a n a
b u f o r ó w
k o l o r u
1. Elementarne obiekty geometryczne
20
g l u t S w a p B u f f e r s
( ) ;
}
//
z m i a n a
w i e l k o ś c i
o k n a
void
R esh ape
( i n t
width ,
i n t
h e i g h t )
{
//
o b s z a r
r e n d e r i n g u − c a ł e
o k n o
g l V i e w p o r t
( 0 , 0 , width , h e i g h t ) ;
//
w y b ó r
m a c i e r z y
r z u t o w a n i a
g l M a t r i x M o d e
(GL PROJECTION ) ;
//
m a c i e r z
r z u t o w a n i a = m a c i e r z
j e d n o s t k o w a
g l L o a d I d e n t i t y
( ) ;
//
r z u t o w a n i e
p r o s t o k ą t n e
g l u O r t h o 2 D
( 0 , width , 0 , h e i g h t ) ;
//
g e n e r o w a n i e
s c e n y
3D
D i s p l a y
( ) ;
}
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
void MouseButton
( i n t
b u t t o n ,
i n t
s t a t e ,
i n t x ,
i n t
y )
{
i f
( b u t t o n == GLUT LEFT BUTTON)
{
//
p o c z ą t e k
r y s o w a n i a
l i n i i
i f
( s t a t e == GLUT DOWN && b u t t o n s t a t e == GLUT UP)
{
//
z a p a m i ę t a n i e
w s p ó ł r z ę d n y c h
p o c z ą t k u
i
k o ń c a
l i n i i
v e r t e x x . i n s e r t
( v e r t e x x . end
( ) , x ) ;
v e r t e x y . i n s e r t
( v e r t e x y . end
( ) , g l u t G e t
(GLUT WINDOW HEIGHT)−y ) ;
v e r t e x x . i n s e r t
( v e r t e x x . end
( ) , x ) ;
v e r t e x y . i n s e r t
( v e r t e x y . end
( ) , g l u t G e t
(GLUT WINDOW HEIGHT)−y ) ;
//
z a p a m i ę t a n i e
b i e ż ą c e j
s z e r o k o ś c i
l i n i i
l i n e s w i d t h . i n s e r t
( l i n e s w i d t h . end
( ) , l i n e w i d t h ) ;
//
z a p a m i ę t a n i e
b i e ż ą c e g o
w z o r u
l i n i i
l i n e s s t i p p l e . i n s e r t
( l i n e s s t i p p l e . end
( ) , l i n e s t i p p l e ) ;
//
z m i a n a
w a r t o ś c i
w s k a ź n i k a
b u t t o n s t a t e = GLUT DOWN;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
e l s e
//
z a k o ń c z e n i e
r y s o w a n i a
l i n i i
i f
( s t a t e == GLUT UP && b u t t o n s t a t e == GLUT DOWN)
{
v e r t e x x
[ v e r t e x x . s i z e
( ) − 1 ] = x ;
v e r t e x y
[ v e r t e x y . s i z e
( ) − 1 ] = g l u t G e t
(GLUT WINDOW HEIGHT)−y ;
//
z m i a n a
w a r t o ś c i
w s k a ź n i k a
b u t t o n s t a t e = GLUT UP ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
}
}
//
o b s ł u g a
r u c h u
k u r s o r a
m y s z k i
void MouseMotion
( i n t x ,
i n t
y )
{
//
z m i a n a
k o ń c a
p o ł o ż e n i a
l i n i i
i f
( b u t t o n s t a t e == GLUT DOWN)
{
//
z m i a n a
w s p ó ł r z ę d n y c h
k o ń c a
l i n i i
v e r t e x x
[ v e r t e x x . s i z e
( ) − 1 ] = x ;
v e r t e x y
[ v e r t e x y . s i z e
( ) − 1 ] = g l u t G e t
(GLUT WINDOW HEIGHT)−y ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
1. Elementarne obiekty geometryczne
21
}
}
//
o b s ł u g a
k l a w i a t u r y
void Keyboard
( unsigned char key ,
i n t x ,
i n t
y )
{
//
z w i ę k s z e n i e
s z e r o k o ś c i
l i n i i
i f
( k e y == ’+ ’ )
l i n e w i d t h += 0 . 2 5 ;
e l s e
//
z m n i e j s z e n i e
s z e r o k o ś c i
l i n i i
i f
( k e y == ’− ’ && l i n e w i d t h > 0 )
l i n e w i d t h −= 0 . 2 5 ;
//
n a r y s o w a n i e
s c e n y
D i s p l a y
( ) ;
}
//
o b s ł u g a
menu
p o d r ę c z n e g o
void Menu ( i n t
v a l u e )
{
switch
( v a l u e )
{
//
w z ó r
l i n i i
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
c a s e
STIPPLE 1111111111111111 :
l i n e s t i p p l e = 0xFFFF ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1
c a s e
STIPPLE 0000000011111111 :
l i n e s t i p p l e = 0 x00FF ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
c a s e
STIPPLE 1111111100000000 :
l i n e s t i p p l e = 0 xFF00 ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1
c a s e
STIPPLE 0000111100001111 :
l i n e s t i p p l e = 0 x0F0F ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0
c a s e
STIPPLE 1111000011110000 :
l i n e s t i p p l e = 0 xF0F0 ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1
c a s e
STIPPLE 0011001100110011 :
l i n e s t i p p l e = 0 x 3 3 3 3 ;
D i s p l a y
( ) ;
break ;
//
w z ó r
l i n i i
1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0
c a s e
STIPPLE 1100110011001100 :
l i n e s t i p p l e = 0xCCCC ;
D i s p l a y
( ) ;
break ;
//
u s u w a n i e
l i n i i
c a s e CLEAR LINES :
v e r t e x x . e r a s e
( v e r t e x x . b e g i n
( ) , v e r t e x x . end
( ) ) ;
v e r t e x y . e r a s e
( v e r t e x y . b e g i n
( ) , v e r t e x y . end
( ) ) ;
l i n e s w i d t h . e r a s e
( l i n e s w i d t h . b e g i n
( ) , l i n e s w i d t h . end
( ) ) ;
l i n e s s t i p p l e . e r a s e
( l i n e s s t i p p l e . b e g i n
( ) , l i n e s s t i p p l e . end
( ) ) ;
D i s p l a y
( ) ;
break ;
//
w y j ś c i e
c a s e EXIT :
e x i t
( 0 ) ;
1. Elementarne obiekty geometryczne
22
}
}
i n t
main
( i n t
a r g c ,
char ∗ a r g v [ ] )
{
//
i n i c j a l i z a c j a
b i b l i o t e k i
GLUT
g l u t I n i t
(& a r g c , a r g v ) ;
//
i n i c j a l i z a c j a
b u f o r a
r a m k i
g l u t I n i t D i s p l a y M o d e
(GLUT DOUBLE | GLUT RGB ) ;
//
r o z m i a r y
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t I n i t W i n d o w S i z e
( 5 0 0 , 5 0 0 ) ;
//
u t w o r z e n i e
g ł ó w n e g o
o k n a
p r o g r a m u
g l u t C r e a t e W i n d o w
( ” L i n i e ” ) ;
//
d o ł ą c z e n i e
f u n k c j i
g e n e r u j ą c e j
s c e n ę
3D
g l u t D i s p l a y F u n c
( D i s p l a y ) ;
//
d o ł ą c z e n i e
f u n k c j i
w y w o ł y w a n e j
p r z y
z m i a n i e
r o z m i a r u
o k n a
g l u t R e s h a p e F u n c
( Re sha pe ) ;
//
o b s ł u g a
p r z y c i s k ó w
m y s z k i
g l u t M o u s e F u n c
( MouseButton ) ;
//
o b s ł u g a
r u c h u
k u r s o r a
m y s z k i
g l u t M o t i o n F u n c
( MouseMotion ) ;
//
d o ł ą c z e n i e
f u n k c j i
o b s ł u g i
k l a w i a t u r y
g l u t K e y b o a r d F u n c
( Keyboard ) ;
//
u t w o r z e n i e
podmenu − P r y m i t y w y
i n t
M e n u S t i p p l e = g l u t C r e a t e M e n u
( Menu ) ;
glutAddMenuEntry
( ” 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 ” , STIPPLE 1111111111111111 ) ;
glutAddMenuEntry
( ” 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 ” , STIPPLE 0000000011111111 ) ;
glutAddMenuEntry
( ” 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ” , STIPPLE 1111111100000000 ) ;
glutAddMenuEntry
( ” 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 ” , STIPPLE 0000111100001111 ) ;
glutAddMenuEntry
( ” 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 ” , STIPPLE 1111000011110000 ) ;
glutAddMenuEntry
( ” 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 ” , STIPPLE 0011001100110011 ) ;
glutAddMenuEntry
( ” 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 ” , STIPPLE 1100110011001100 ) ;
// menu g ł ó w n e
g l u t C r e a t e M e n u
( Menu ) ;
#i f d e f WIN32
glutAddSubMenu
( ”Wzór
l i n i i ” , M e n u S t i p p l e ) ;
glutAddMenuEntry
( ” Usuń
l i n i e ” , CLEAR LINES ) ;
glutAddMenuEntry
( ” W y j ś c i e ” , EXIT ) ;
#e l s e
glutAddSubMenu
( ”Wzor
l i n i i ” , M e n u S t i p p l e ) ;
glutAddMenuEntry
( ” Usun
l i n i e ” , CLEAR LINES ) ;
glutAddMenuEntry
( ” W y j s c i e ” , EXIT ) ;
#e n d i f
//
o k r e ś l e n i e
p r z y c i s k u
m y s z k i
o b s ł u g u j ą c e g o
menu
p o d r ę c z n e
g l u t A t t a c h M e n u
(GLUT RIGHT BUTTON ) ;
//
w p r o w a d z e n i e
p r o g r a m u
do
o b s ł u g i
p ę t l i
k o m u n i k a t ó w
g l u t M a i n L o o p
( ) ;
return
0 ;
}
Literatura
23
Literatura
[1] Mark Segal, Kurt Akeley: The OpenGL Graphics System. A Specification
Version 2.0
[2] Jackie Neider, Tom Davis, Mason Woo: OpenGL Programming Guide „The
Red Book”
[3] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta, Helion 1999
[4] Richard S. Wright jr, Michael Sweet: OpenGL Księga eksperta Wydanie III,
Helion 2005
[5] The official OpenGL web page,
[6] Piotr Andrzejewski, Jakub Kurzak: Wprowadzenie do OpenGL. Programowa-
nie zastosowań graficznych, Kwantum 2000
[7] Kevin Hawkins, Dave Astle: OpenGL. Programowanie gier, Helion 2003
[8] Mark J. Kilgard: The OpenGL Utility Toolkit (GLUT) Programming Interface
API Version 3. Silicon Graphics, Inc. 1996