opengl bufor szablonowy

background image

Janusz Ganczarski

OpenGL

Bufor szablonowy

background image

Spis treści

Spis treści . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1. Bufor szablonowy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.1.

Włączenie i wyłączenie bufora szablonowego

. . . . . . . . . . . . .

1

1.2.

Czyszczenie bufora szablonowego . . . . . . . . . . . . . . . . . . . .

1

1.3.

Sterowanie buforem szablonowym

. . . . . . . . . . . . . . . . . . .

1

1.4.

Rozłączny bufor szablonowy

. . . . . . . . . . . . . . . . . . . . . .

3

1.5.

Programy przykładowe

. . . . . . . . . . . . . . . . . . . . . . . . .

4

1.5.1.

Plik odbicie.cpp . . . . . . . . . . . . . . . . . . . . . . . . .

7

1.5.2.

Plik csg.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

1.5.3.

Plik krawedzie.cpp . . . . . . . . . . . . . . . . . . . . . . . .

25

1.5.4.

Plik przejscie obrazow.cpp . . . . . . . . . . . . . . . . . . .

31

Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

37

background image

1. Bufor szablonowy

Bufor szablonowy (ang. stencil buffer) w budowie i działaniu przypomi-

na bufor głębokości. Bufor ten umożliwia utworzenie specjalnego szablonu
(matrycy) określającego obszar w buforze koloru, który będzie używany do
renderingu. Stąd właśnie porównanie funkcjonalne do bufora głębokości.

Bufor szablonowy zawiera dane w postaci liczb całkowitych. Ilość bitów

przypadających na jeden element bufora zależy od implementacji, ale nie
może być mniejsza niż 1. Wielkość tę można ustalić korzystając z funkcji
z grupy glGet z parametrem GL STENCIL BITS.

1.1. Włączenie i wyłączenie bufora szablonowego

Włączenie bufora szablonowego wymaga wywołania funkcji glEnable

z parametrem GL STENCIL TEST. Wcześniej trzeba jeszcze dodać bufor sza-
blonowy przy inicjalizacji bufora ramki. W przypadku biblioteki GLUT
sprowadza się to do dodania stałej GLUT STENCIL przy wywołaniu funkcji
glutInitDisplayMode. Wyłącznie bufora szablonowego sprowadza się do
wywołania funkcji glDisable z parametrem GL STENCIL TEST.

1.2. Czyszczenie bufora szablonowego

Zawartość bufora szablonowego, podobnie jak innych buforów wchodzą-

cych w skład bufora ramki, można wypełniać (czyścić) stałą wartością przy
pomocy znanej już funkcji glClear z parametrem GL STENCIL BUFFER BIT.
Domyślnie bufor szablonowy wypełniany jest zerami, ale wartość tę można
zmienić przy użyciu funkcji:

void glClearStencil (GLint s)

1.3. Sterowanie buforem szablonowym

Działanie bufora szablonowego reguluje kilka funkcji. Podstawową z nich

jest funkcja:

void glStencilFunc (GLenum func, GLint ref, GLuint mask)

która ustala tzw. test szablonu. Parametr func wskazuje rodzaj zastosowanej
funkcji testującej i może przyjąć jedną z poniższych wartości:
— GL NEVER - wartość testu zawsze negatywna,
— GL LESS - wartość testu pozytywna jeżeli parametr ref jest mniejszy od

wartości znajdującej się w buforze,

— GL LEQUAL wartość testu pozytywna jeżeli parametr ref jest mniejszy

lub równy wartości znajdującej się w buforze,

background image

1. Bufor szablonowy

2

— GL GREATER - wartość testu pozytywna jeżeli parametr ref jest większy

od wartości znajdującej się w buforze,

— GL GEQUAL - wartość testu pozytywna jeżeli parametr ref jest większy

lub równy wartości znajdującej się w buforze,

— GL EQUAL - wartość testu pozytywna jeżeli parametr ref jest równy war-

tości znajdującej się w buforze,

— GL NOTEQUAL - wartość testu pozytywna jeżeli parametr ref jest różny

od wartości znajdującej się w buforze,

— GL ALWAYS - wartość testu zawsze pozytywna.
Zauważmy, że zestaw funkcji testujących bufora szablonowego jest taki sam
jak testy bufora głębokości.

Parametr ref określa tzw. wartość referencyjną używaną w teście bufora

szablonowego. Wartość ta jest zawsze obcinana do przedziału [0, 2

n

− 1],

gdzie n jest ilością bitów bufora szablonu. Przy wykonywaniu testu bufo-
ra szablonowego wykorzystywana jest maska bitowa zawarta w parametrze
mask określająca, dla których bitów wartości referencyjnej i wartości prze-
chowywanej w buforze wykonywany jest test szablonu. Operacja ta jest re-
alizowana za pomocą iloczynu logicznego testowanych wartości z wartością
maski. Domyślną wartość maski bitowej wynoszącą 1 dla każdego bitu bufora
szablonowego można zmienić przy użyciu funkcji:

void glStencilMask (uint mask)

Trzecią funkcją sterującą działaniem bufora szablonowego jest:

void glStencilOp (GLenum sfail, GLenum dpfail, GLenum dppass)

której parametry określają jaka operacja na buforze szablonowym wykony-
wana jest w przypadku:
— sfail - negatywnego wyniku testu szablonu,
— dpfali - pozytywnego wyniku testu szablonu przy negatywnym wyniku

testu bufora głębokości,

— dppass - pozytywnego wyniku testów bufora szablonowego i bufora głę-

bokości (także, gdy bufor głębokości jest wyłączony).
Każdy z parametrów sfail, dpfail i dppass może niezależnie przyjąć

jedną z poniższych wartości:
— GL KEEP - wartość bufora szablonowego nie jest zmieniana,
— GL ZERO - wartość bufora szablonowego jest zerowana,
— GL REPLACE - wartość bufora szablonowego jest zamieniana wartością

referencyjną określoną w parametrze ref funkcji glStencilFunc,

— GL INCR - wartość bufora szablonowego jest zwiększana o 1; w przypadku

wystąpienia nadmiaru rezultat przyjmuje maksymalną wartość obsługi-
waną przez bufor szablonowy,

background image

1. Bufor szablonowy

3

— GL DECR - wartość bufora szablonowego jest zmniejszana o 1; w przypad-

ku wystąpienia niedomiaru rezultat przyjmuje wartość 0,

— GL INVERT - wartość bufora szablonowego jest negowana,
— GL DECR WRAP - wartość bufora szablonowego jest zmniejszana o 1; w przy-

padku wystąpienia niedomiaru rezultat przyjmuje maksymalną wartość
obsługiwaną przez bufor szablonowy,

— GL INCR WRAP - wartość bufora szablonowego jest zwiększana o 1; w przy-

padku wystąpienia nadmiaru rezultat przyjmuje wartość 0.
Stałe GL DECR WRAP i GL INCR WRAP zostały dodane w wersji 1.4 biblioteki

OpenGL, a wcześniej były dostępne w rozszerzeniu EXT stencil wrap.

Dla celów operacji GL INCR, GL DECR, GL DECR WRAP i GL INCR WRAP war-

tości bufora szablonowego traktowane są jak liczby całkowite bez znaku.

1.4. Rozłączny bufor szablonowy

W wersji 2.0 biblioteki OpenGL zaimplementowano zaproponowany w roz-

szerzeniach ATI separate stencil i EXT stencil two side mechanizm roz-
łącznego bufora szablonowego. Rozłączność sprowadza się do możliwości
określenia odrębnych operacji na buforze szablonowym dla przednich i tyl-
nych stron tych prymitywów graficznych, dla których OpenGL określa stro-
nę, czyli wielokątów. Natomiast przy renderingu prymitywów, dla których
nie określa się stron (m.in. punkty, linie, mapy bitowe i pikselowe) używane
są operacje określone dla przednich stron wielokątów.

Specyfikacja wprowadza trzy nowe funkcje sterujące pracą rozłącznego

bufora szablonowego:

void glStencilFuncSeparate (enum face,

enum func, int ref, uint mask)

void glStencilOpSeparate (enum face,

enum sfail, enum dpfail, enum dppass)

void glStencilMaskSeparate (enum face, uint mask)

Funkcje te różnią się od wcześniej opisanych parametrem face określającym
strony prymitywów, których dotyczą zmieniane ustawienia. Parametr ten
przyjmuje jedną z trzech znanych już wartości: GL FRONT (przedni bufor),
GL BACK (tylni bufor) i GL FRONT AND BACK (przedni i tylni bufor). Działanie
dotychczasowych funkcji glStencilFunc, glStencilOp i glStencilMask
odpowiada definiowaniem operacji dla obu stron prymitywów. Jedynie przy
czyszczeniu bufora używana jest zawsze maska określona dla przednich stron
wielokątów.

background image

1. Bufor szablonowy

4

1.5. Programy przykładowe

Program przykładowy (plik odbicie.cpp) przedstawia sposób wykorzy-

stania mieszania kolorów i bufora szablonowego do uzyskania efektu odbicia
na płaskiej, półprzezroczystej powierzchni. Idea rozwiązania jest stosunkowo
prosta. Obiekty „świata”, które mają zostać odbite na powierzchni rysowane
są dwukrotnie. Pierwszy raz obiekty rysowane są w położeniu „lustrzanym”
w stosunku do powierzchni, w którym mają być odbite. W przypadku, gdy
płaszczyzna ta jest prostopadła do osi X wystarczy do tego odpowiednie
skalowanie macierzy modelowania:

glScalef (1.0,-1.0,1.0)

Takiemu samemu przekształceniu trzeba poddać współrzędne położenia źró-
deł światła, które są wykorzystywane do oświetlenia sceny. Pozostałe prze-
kształcenie macierzy modelowania (obroty, przesunięcia itp.) są identyczne
jak dla obiektów „rzeczywistego” świata. W przypadku, gdy program ry-
suje tylko przednie strony obiektów, przy rysowaniu świata „lustrzanego”
trzeba zmienić orientację stron wielokąta na przeciwną do stosowanej przy
rysowania świata rzeczywistego (funkcja glCullFace).

Po narysowaniu świata lustrzanego rysujemy płaszczyznę, na której re-

alizowany jest efekt odbicia. W tym celu trzeba włączyć mieszanie kolorów
oraz ustawić współczynniki mieszania kolorów na GL SRC ALPHA dla koloru
źródłowego i GL ONE MINUS SRC ALPHA dla koloru przeznaczenia. Jeżeli ko-
rzystamy z oświetlenia, tak jak ma to miejsce w przykładowym programie,
trzeba na czas rysowania płaszczyzny wyłączyć oświetlenie.

Drugi raz obiekty świata rysowane są już po narysowaniu płaszczyzny

odbicia, oczywiście po wyłączeniu mieszania kolorów oraz włączeniu oświe-
tlenia sceny.

Opisany sposób postępowania nie wymaga żadnych dodatkowych zabie-

gów w przypadku, gdy odbicie obiektów świata nigdy wykracza poza granice
płaszczyzny odbicia. W przeciwnym wypadku część sceny lustrzanej zostanie
narysowana także poza płaszczyzną odbicia, co jest oczywiście efektem nie-
pożądanym (patrz rysunek 1). Jednym ze sposobów eliminacji tego zjawiska
jest wykorzystanie opisanego wyżej bufora szablonowego.

Bufor szablonowy jest wykorzystany przy rysowaniu obiektów świata „lu-

strzanego”. Wcześniej trzeba jednak utworzyć szablon i wymaga to niestety
narysowania powierzchni, na której będzie widoczny efekt odbicia. Test bu-
fora szablonowego definiujemy tak, aby był zawsze spełniony, a poprzednie
jego wartości zastępowane (na początku rysowania ramki obrazu bufor jest
czyszczony wartością domyślną):

glStencilFunc (GL_ALWAYS,0x00000001,0xFFFFFFFF);
glStencilOp (GL_REPLACE,GL_REPLACE,GL_REPLACE);

background image

1. Bufor szablonowy

5

Rysunek 1. Program Odbicie - bufor szablonowy wyłączony

Aby dwukrotne rysowanie powierzchni odbicia nie spowodowało niepo-

żądanego efektu w postaci zmiany jej kolorów, na czas tworzenia szablonu
trzeba wyłączyć zapis składowych RGBA w buforze koloru. Realizuje to
opisywana już funkcja glColorMask. Po narysowaniu powierzchni odbicia
i otrzymaniu szablonu test bufora szablonowego definiujemy tak, aby był
spełniony tylko przy wartości równej do znajdującej się w buforze, a sam
bufor pozostawiamy bez modyfikacji:

glStencilFunc (GL_EQUAL,0x00000001,0xFFFFFFFF);
glStencilOp (GL_KEEP,GL_KEEP,GL_KEEP);

Zauważmy, że przy tworzeniu szablonu wykorzystywaliśmy tylko jeden

bit bufora szablonowego (parametr ref funkcji glStencilFunc) co czyni
program niezależny od implementacji biblioteki OpenGL.

background image

1. Bufor szablonowy

6

Przy tak określonym teście bufora szablonowego rysujemy tylko obiekty

świata „lustrzanego”. Następne operacje, czyli rysowanie powierzchni odbi-
cia i obiektów świata rzeczywistego, już z niego nie korzystają. Efekt dzia-
łania program z włączonym buforem szablonowym przedstawia rysunek 2.

Rysunek 2. Program Odbicie - bufor szablonowy włączony

Do uzyskania ciągłego i jednostajnego ruchu obiektu sceny, który prak-

tycznie nie będzie zależny od wydajności komputera i karty graficznej zasto-
sowano licznik czasu (ang. timer). Funkcję licznika czasu wywołuje się przy
użyciu funkcji:

void glutTimerFunc (unsigned int millis,

void (GLUTCALLBACK *func)(int value),
int value)

background image

1. Bufor szablonowy

7

gdzie millis określa czas w milisekundach, jaki ma upłynąć do wywołania
funkcji licznika, do której wskaźnik zawiera parametr func. Ostatni para-
metr value jest przekazywany jako parametr funkcji licznika.

W przykładowym programie funkcja licznika nazywa się po prostu Timer,

która po zwiększeniu kąta obrotu obiektów sceny ponownie ustawia licznik
czasu wywołując funkcję glutTimerFunc.

1.5.1. Plik odbicie.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

” c o l o r s . h ”

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

STENCIL ,

//

b u f o r

s z a b l o n o w y

w ł ą c z / w y ł ą c z

FULL WINDOW,

//

a s p e k t

o b r a z u c a ł e

o k n o

ASPECT 1 1 ,

//

a s p e k t

o b r a z u

1 : 1

EXIT

//

w y j ś c i e

} ;

//

a s p e k t

o b r a z u

i n t

a s p e c t = FULL WINDOW ;

//

r o z m i a r y

b r y ł y

o b c i n a n i a

const GLdouble

l e f t = − 2 . 0 ;

const GLdouble

r i g h t = 2 . 0 ;

const GLdouble bottom = − 2 . 0 ;
const GLdouble

t o p = 2 . 0 ;

const GLdouble

n e a r = 3 . 0 ;

const GLdouble

f a r = 7 . 0 ;

//

k ą t y

o b r o t u

s c e n y

G L f l o a t

r o t a t e x = 3 0 . 0 ;

G L f l o a t

r o t a t e y = 0 . 0 ;

//

k ą t

o b r o t u

o b i e k t u

G L f l o a t

a n g l e = 0 . 0 ;

//

w s k a ź n i k

n a c i ś n i ę c i a

l e w e g o

p r z y c i s k u

m y s z k i

i n t

b u t t o n s t a t e = GLUT UP ;

//

p o ł o ż e n i e

k u r s o r a

m y s z k i

i n t

b u t t o n x , b u t t o n y ;

//

i d e n t y f i k a t o r y

l i s t

w y ś w i e t l a n i a

GLint GROUND LIST ;
GLint WORLD LIST ;

//

p o ł o ż e n i e

ź r ó d ł a

ś w i a t ł a

G L f l o a t

l i g h t p o s i t i o n

[ 4 ] =

{

0 . 0 , 1 0 . 0 , 1 0 . 0 , 1 . 0

} ;

//

u ż y c i e

b u f o r a

s z a b l o n o w e g o

bool

s t e n c i l

t e s t = true ;

background image

1. Bufor szablonowy

8

//

f u n k c j a

g e n e r u j ą c a

s c e n ę

3D

void

D i s p l a y S c e n e

( )

{

//

k o l o r

t ł a z a w a r t o ś ć

b u f o r a

k o l o r u

g l C l e a r C o l o r

( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;

//

c z y s z c z e n i e

b u f o r a

k o l o r u ,

b u f o r a

g ł ę b o k o ś c i

i

o p c j o n a l n i e

b u f o r a

s z a b l o n o w e g o

i f

( s t e n c i l

t e s t == true )

g l C l e a r

( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT |

GL STENCIL BUFFER BIT ) ;

e l s e

g l C l e a r

( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;

//

w y b ó r

m a c i e r z y

m o d e l o w a n i a

g l M a t r i x M o d e

(GL MODELVIEW ) ;

//

m a c i e r z

m o d e l o w a n i a = m a c i e r z

j e d n o s t k o w a

g l L o a d I d e n t i t y

( ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

w ł ą c z e n i e

ś w i a t ł a

GL LIGHT0

g l E n a b l e

( GL LIGHT0 ) ;

//

w ł ą c z e n i e

a u t o m a t y c z n e j

n o r m a l i z a c j i

w e k t o r ó w

n o r m a l n y c h

g l E n a b l e

(GL NORMALIZE ) ;

//

w ł ą c z e n i e

o b s ł u g i

w ł a ś c i w o ś c i

m a t e r i a ł ó w

g l E n a b l e

(GL COLOR MATERIAL ) ;

//

w ł a ś c i w o ś c i

m a t e r i a ł u

o k r e ś l o n e

p r z e z

k o l o r

w i e r z c h o ł k ó w

g l C o l o r M a t e r i a l

(GL FRONT, GL AMBIENT AND DIFFUSE ) ;

//

w ł ą c z e n i e

n i e r y s o w a n i a

t y l n e j

s t r o n y

w i e l o k ą t ó w

g l E n a b l e

( GL CULL FACE ) ;

//

p r z e s u n i ę c i e

u k ł a d u

w s p ó ł r z ę d n y c h

o b i e k t ó w

do

ś r o d k a

b r y ł y

o d c i n a n i a

g l T r a n s l a t e f

( 0 , 0 , − ( n e a r+f a r ) / 2 ) ;

//

o b r o t y

c a ł e j

s c e n y

g l R o t a t e f

( r o t a t e x , 1 . 0 , 0 . 0 , 0 . 0 ) ;

g l R o t a t e f

( r o t a t e y , 0 . 0 , 1 . 0 , 0 . 0 ) ;

//

p r z y

w ł ą c z o n y m

b u f o r z e

s z b l o n o w y m

r y s u j e m y

” p o d ł o g ę ” w

c e l u

u t w o r z e n i a

//

s z a b l o n u ,

k t ó r y

z o s t a n i e

w y k o r z y s t a n y

do

n a r y s o w a n i a

o b i e k t ó w

o d b i t y c h

i f

( s t e n c i l

t e s t == true )

{

//

w y ł ą c z e n i e

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

//

w ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l E n a b l e

( GL STENCIL TEST ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL ALWAYS, 0 x 0 0 0 0 0 0 0 1 , 0 xFFFFFFFF ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL REPLACE, GL REPLACE, GL REPLACE ) ;

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

w y ś w i e t l e n i e

p ł a s z c z y z n y

o d b i c i a

g l C a l l L i s t

(GROUND LIST ) ;

//

w ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

(GL TRUE, GL TRUE, GL TRUE, GL TRUE ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL EQUAL, 0 x 0 0 0 0 0 0 0 1 , 0 xFFFFFFFF ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

background image

1. Bufor szablonowy

9

g l S t e n c i l O p

(GL KEEP , GL KEEP , GL KEEP ) ;

}

//

o d ł o ż e n i e

m a c i e r z y

m o d e l o w a n i a

na

s t o s

g l P u s h M a t r i x ( ) ;

//

s k a l o w a n i e

m a c i e r z y

m o d e l o w a n i a w

c e l u

n a r y s o w n a i a

o b i e k t ó w

ś w i a t a

” l u s t r z a n e g o ”

g l S c a l e f

( 1 . 0 , − 1 . 0 , 1 . 0 ) ;

//

p o ł o ż e n i e

” l u s t r z a n e g o ”

ź r ó d ł a

ś w i a t ł a

g l L i g h t f v

( GL LIGHT0 , GL POSITION , l i g h t p o s i t i o n ) ;

//

p r z e s u n i ę c i e

o b i e k t ó w

ś w i a t a

” l u s t r z a n e g o ”

g l T r a n s l a t e f

( 0 . 0 , 1 . 2 , 0 . 0 ) ;

//

o b r o t y

o b i e k t ó w

ś w i a t a

” l u s t r z a n e g o ”

g l R o t a t e f

( a n g l e , 1 . 0 , 0 . 0 , 0 . 0 ) ;

g l R o t a t e f

( a n g l e , 0 . 0 , 2 . 0 , 0 . 0 ) ;

g l R o t a t e f

( a n g l e , 0 . 0 , 0 . 0 , − 1 . 0 ) ;

// w

ś w i e c i e

l u s t r z a n y m

t r z e b a

z m i e n i ć

o r i e n t a c j ę

w i e r z c h o ł k ó w

p r y m i t y w ó w

g l F r o n t F a c e

(GL CW ) ;

//

w y ś w i e t l e n i e

o b i e k t ó w

ś w i a t a

” l u s t r z a n e g o ”

g l C a l l L i s t

(WORLD LIST ) ;

//

p o w r ó t

do

n o r m a l n e j

o r i e n t a c j i

w i e r z c h o ł k ó w

p r y m i t y w ó w

g l F r o n t F a c e

(GL CCW ) ;

//

z d j ę c i e

m a c i e r z y

m o d e l o w a n i a

z e

s t o s u

g l P o p M a t r i x

( ) ;

//

k o n i e c

r y s o w a n i a

o b i e k t ó w

ś w i a t a

” l u s t r z n a e g o ”

t o

t a k ż e

//

k o n i e c

k o r z y s t a n i a

z

b u f o r a

s z a b l o n o w e g o

i f

( s t e n c i l

t e s t == true )

{

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

}

//

w y ł ą c z e n i e

o ś w i e t l e n i a

g l D i s a b l e

( GL LIGHTING ) ;

//

w ł ą c z e n i e

m i e s z a n i a

k o l o r ó w

g l E n a b l e

(GL BLEND ) ;

//

w s p ó ł c z y n n i k i

r ó w n a n i a

m i e s z a n i a

k o l o r ó w

g l B l e n d F u n c

( GL SRC ALPHA , GL ONE MINUS SRC ALPHA ) ;

//

w y ś w i e t l e n i e

p ł a s z c z y z n y

o d b i c i a

g l C a l l L i s t

(GROUND LIST ) ;

//

w y ł ą c z e n i e

m i e s z a n i a

k o l o r ó w

g l D i s a b l e

(GL BLEND ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

p o ł o ż e n i e

ź r ó d ł a

ś w i a t ł a

g l L i g h t f v ( GL LIGHT0 , GL POSITION , l i g h t p o s i t i o n ) ;

//

p r z e s u n i ę c i e

o b i e k t ó w

ś w i a t a

g l T r a n s l a t e f

( 0 . 0 , 1 . 2 , 0 . 0 ) ;

//

o b r o t y

o b i e k t ó w

ś w i a t a

g l R o t a t e f

( a n g l e , 1 . 0 , 0 . 0 , 0 . 0 ) ;

g l R o t a t e f

( a n g l e , 0 . 0 , 2 . 0 , 0 . 0 ) ;

g l R o t a t e f

( a n g l e , 0 . 0 , 0 . 0 , − 1 . 0 ) ;

//

w y ś w i e t l e n i e

o b i e k t ó w

ś w i a t a

g l C a l l L i s t

(WORLD LIST ) ;

//

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 ( ) ;

}

//

f u n k c j a

t i m e r a

background image

1. Bufor szablonowy

10

void Timer

( i n t

v a l u e )

{

//

z w i ę k s z e n i e

k ą t a

o b r o t u

o b i e k t u

s c e n y

a n g l e ++;

//

w y ś w i e t l e n i e

s c e n y

D i s p l a y S c e n e

( ) ;

//

n a s t ę p n e

w y w o ł a n i e

f u n k c j i

t i m e r a

g l u t T i m e r F u n c

( 2 0 , Timer , 0 ) ;

}

//

z m i a n a

w i e l k o ś c i

o k n a

void

R esh ape

( i n t

width ,

i n t

h e i g h t )

{

//

o b s z a r

r e n d e r i n g u c a ł e

o k n o

g l V i e w p o r t

( 0 , 0 , width , h e i g h t ) ;

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

g l M a t r i x M o d e

(GL PROJECTION ) ;

//

m a c i e r z

r z u t o w a n i a = m a c i e r z

j e d n o s t k o w a

g l L o a d I d e n t i t y

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a

i f

( a s p e c t == ASPECT 1 1 )

{

//

w y s o k o ś ć

o k n a

w i ę k s z a

od

w y s o k o ś c i

o k n a

i f

( w i d t h < h e i g h t && w i d t h > 0 )

g l F r u s t u m

( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;

e l s e

//

s z e r o k o ś ć

o k n a

w i ę k s z a

l u b

równa

w y s o k o ś c i

o k n a

i f

( w i d t h >= h e i g h t && h e i g h t > 0 )

g l F r u s t u m

( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;

}

e l s e

g l F r u s t u m

( l e f t , r i g h t , bottom , top , n e a r , f a r ) ;

//

g e n e r o w a n i e

s c e n y

3D

D i s p l a y S c e n e

( ) ;

}

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

void MouseButton

( i n t

b u t t o n ,

i n t

s t a t e ,

i n t x ,

i n t

y )

{

i f

( b u t t o n == GLUT LEFT BUTTON)

{

//

z a p a m i ę t a n i e

s t a n u

l e w e g o

p r z y c i s k u

m y s z k i

b u t t o n s t a t e = s t a t e ;

//

z a p a m i ę t a n i e

p o ł o ż e n i a

k u r s o r a

m y s z k i

i f

( s t a t e == GLUT DOWN)

{

b u t t o n x = x ;
b u t t o n y = y ;

}

}

}

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

void MouseMotion

( i n t x ,

i n t

y )

{

i f

( b u t t o n s t a t e == GLUT DOWN)

{

r o t a t e y += 30

∗ ( r i g h t − l e f t ) / g l u t G e t

(GLUT WINDOW WIDTH)

∗ ( x − b u t t o n x ) ;

b u t t o n x = x ;
r o t a t e x −= 30

∗ ( t o p − bottom ) / g l u t G e t

(GLUT WINDOW HEIGHT)

∗ ( b u t t o n y − y ) ;

b u t t o n y = y ;
g l u t P o s t R e d i s p l a y

( ) ;

}

}

//

o b s ł u g a

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

background image

1. Bufor szablonowy

11

{

switch

( v a l u e )

{

//

b u f o r

s z a b l o n o w y

w ł ą c z / w y ł ą c z

c a s e STENCIL :

s t e n c i l

t e s t = ! s t e n c i l

t e s t ;

D i s p l a y S c e n e

( ) ;

break ;

//

o b s z a r

r e n d e r i n g u c a ł e

o k n o

c a s e FULL WINDOW :

a s p e c t = FULL WINDOW ;

R esha pe

( g l u t G e t

(GLUT WINDOW WIDTH) , g l u t G e t

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

o b s z a r

r e n d e r i n g u a s p e k t

1 : 1

c a s e ASPECT 1 1 :

a s p e c t = ASPECT 1 1 ;

R esha pe

( g l u t G e t

(GLUT WINDOW WIDTH) , g l u t G e t

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

w y j ś c i e

c a s e EXIT :

e x i t

( 0 ) ;

}

}

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

void

G e n e r a t e D i s p l a y L i s t s

( )

{

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

GROUND LIST = g l G e n L i s t s

( 1 ) ;

//

p i e r w s z a

l i s t a

w y ś w i e t l a n i a p o d ł o g a

g l N e w L i s t

(GROUND LIST , GL COMPILE ) ;

// ” p o d ł o g a ”

r y s o w a n a

j e s t

j a k o

s z a c h o w n i c a

o

r o z m i a r a c h

// 4

x

4

j e d n o s t k i

i

z a w i e r a

s i ę

w

p ł a s z c z y ź n i e

y = 0

g l B e g i n

(GL QUADS ) ;

g l N o r m a l 3 f

( 1 . 0 , 0 . 0 , 0 . 0 ) ;

//

p r z y

k a ż d e j

i t e r a c j i

p ę t l i

r y s o w a n e

s ą

c z t e r y

p r o s t o k ą t y

s z a c h o w n i c y

f o r

( G L f l o a t

z = − 2 . 0 ;

z < 2 . 0 ;

z += 1 )

f o r

( G L f l o a t

x = − 2 . 0 ;

x < 2 . 0 ;

x += 1 )

{

g l C o l o r 4 f

( B l u e [ 0 ] , B l u e [ 1 ] , B l u e [ 2 ] , 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 0 , 0 . 0 , z + 0 . 0 ) ;

g l V e r t e x 3 f

( x + 0 . 0 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 0 ) ;

g l C o l o r 4 f

( S i l v e r [ 0 ] , S i l v e r [ 1 ] , S i l v e r [ 2 ] , 0 . 7 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 0 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 1 . 0 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 1 . 0 , 0 . 0 , z + 0 . 0 ) ;

g l C o l o r 4 f

( B l u e [ 0 ] , B l u e [ 1 ] , B l u e [ 2 ] , 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 1 . 0 ) ;

g l V e r t e x 3 f

( x + 1 . 0 , 0 . 0 , z + 1 . 0 ) ;

g l V e r t e x 3 f

( x + 1 . 0 , 0 . 0 , z + 0 . 5 ) ;

g l C o l o r 4 f

( S i l v e r [ 0 ] , S i l v e r [ 1 ] , S i l v e r [ 2 ] , 0 . 7 ) ;

g l V e r t e x 3 f

( x + 0 . 0 , 0 . 0 , z + 0 . 5 ) ;

g l V e r t e x 3 f

( x + 0 . 0 , 0 . 0 , z + 1 . 0 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 1 . 0 ) ;

g l V e r t e x 3 f

( x + 0 . 5 , 0 . 0 , z + 0 . 5 ) ;

}

g l E n d

( ) ;

//

k o n i e c

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

d r u g i e j

l i s t y

w y ś w i e t l a n i a

WORLD LIST =

g l G e n L i s t s

( 1 ) ;

//

d r u g a

l i s t a

w y ś w i e t l a n i a o b i e k t

” ś w i a t a ”

g l N e w L i s t

(WORLD LIST , GL COMPILE ) ;

//

z i e l o n y

t o r u s

g l C o l o r 4 f v

( Green ) ;

background image

1. Bufor szablonowy

12

g l u t S o l i d T o r u s

( 0 . 3 , 0 . 7 , 5 0 , 4 0 ) ;

//

k o n i e c

d r u g i e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

}

i n t

main

( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

i n i c j a l i z a c j a

b i b l i o t e k i

GLUT

g l u t I n i t

(& a r g c , a r g v ) ;

//

i n i c j a l i z a c j a

b u f o r a

r a m k i

g l u t I n i t D i s p l a y M o d e

(GLUT DOUBLE | GLUT RGB | GLUT DEPTH | GLUT STENCIL ) ;

//

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

( ” O d b i c 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 S c e n e ) ;

//

d o ł ą c z e n i e

f u n k c j i

w y w o ł y w a n e j

p r z y

z m i a n i e

r o z m i a r u

o k n a

g l u t R e s h a p e F u n c ( R es hape ) ;

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

g l u t M o u s e F u n c

( MouseButton ) ;

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

g l u t M o t i o n F u n c

( MouseMotion ) ;

//

u t w o r z e n i e

podmenu A s p e k t

o b r a z u

i n t

MenuAspect = g l u t C r e a t e M e n u

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a ł e

okno ” ,FULL WINDOW ) ;

#e l s e

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a l e

okno ” ,FULL WINDOW ) ;

#e n d i f

glutAddMenuEntry

( ” A s p e k t

o b r a z u

1 : 1 ” , ASPECT 1 1 ) ;

// menu g ł ó w n e
g l u t C r e a t e M e n u

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” B u f o r

s z a b l o n o w y

w ł ą c z / w y ł ą c z ” , STENCIL ) ;

glutAddSubMenu

( ” A s p e k t

o b r a z u ” , MenuAspect ) ;

glutAddMenuEntry

( ” W y j ś c i e ” , EXIT ) ;

#e l s e

glutAddMenuEntry

( ” B u f o r

s z a b l o n o w y

w l a c z / w y l a c z ” , STENCIL ) ;

glutAddSubMenu

( ” A s p e k t

o b r a z u ” , MenuAspect ) ;

glutAddMenuEntry

( ” W y j s c i e ” , EXIT ) ;

#e n d i f

//

o k r e ś l e n i e

p r z y c i s k u

m y s z k i

o b s ł u g u j ą c e 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 ) ;

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

G e n e r a t e D i s p l a y L i s t s

( ) ;

//

w y w o ł a n i e

f u n k c j i

t i m e r a

g l u t T i m e r F u n c

( 2 0 , Timer , 0 ) ;

//

w p r o w a d z e n i e

p r o g r a m u

do

o b s ł u g i

p ę t l i

k o m u n i k a t ó w

g l u t M a i n L o o p ( ) ;
return

0 ;

}

Drugi program przykładowy (plik csg.cpp) przedstawia techniki wy-

korzystania bufora szablonowego do konstruowania obiektów przy użyciu
operacji CSG (ang. Constructive Solid Geometry), czyli konstruktywnej geo-
metrii brył. W przestrzeni trójwymiarowej CSG polega na wykonywaniu na

background image

1. Bufor szablonowy

13

bryłach (lub innych obiektach geometrycznych) tzw. regularyzowanych ope-
racji logicznych, czyli operacji logicznych w wyniku których zawsze powstaje
bryła. Wykonywanie operacji GSG prześledzimy na przykładzie dwóch brył:
sześcianu (rysunek 3) i kuli (rysunek 4).

Rysunek 3. Program CSG - obiekt A

Wykonanie operacji logicznej OR na dwóch obiektach jest bardzo proste i

sprowadza się do ich kolejnego wyświetlenia przy włączonym buforze głębo-
kości. Do tej operacji tej nie jest potrzebny bufor szablonowy. Efekt działania
operatora OR przedstawiono na rysunku 5. Jak już Czytelnik zauważył jest
to domyślny tryb rysowania prymitywów graficznych w bibliotece OpenGL.

Operator AND wymaga już znacznie większego nakładu pracy. Oto kolejno

wykonywane operacje:
1. Przy włączonym buforze głębokości, ale bez zapisu składowych RGBA

do bufora kolorów, rysujemy przednie strony wielokątów składających
się na obiekt A.

background image

1. Bufor szablonowy

14

Rysunek 4. Program CSG - obiekt B

2. Przy włączonym buforze szablonowym i wyłączonym buforze głębokości

(ciągle bez zapisu danych do bufora kolorów) rysujemy przednie strony
wielokątów składających się na obiekt B. Operacje na buforze szablono-
wym są tak ustawione, że jego zawartość jest przy rysowaniu obiektu B
zwiększana o 1.

3. Następnie przy niezmienionych ustawieniach buforów głębokości i koloru

rysujemy wyłącznie tylne strony wielokątów składających się na obiekt
B. Jednocześnie zmieniamy operacje na buforze szablonowym tak, aby
podczas rysowania zmniejszać jego zawartość o 1. W efekcie bufor sza-
blonowy zawiera informacje o tych elementach obiektu A, które znajdują
się we wnętrzu B.

4. W kolejnym kroku rysujemy te elementy obiektu A, które znajdują się

we wnętrzu B. W tym celu należy odblokować zapis do bufora kolorów
oraz zmienić sposób działania bufora szablonowego, tak aby zapis składo-

background image

1. Bufor szablonowy

15

Rysunek 5. Program CSG - A OR B

wych RGBA do bufora kolorów obejmował wyłącznie wcześniej wybrane
elementy obiektu A, które znajdują się we wnętrzu B.

5. Przed przystąpieniem do kolejnego etapu wykonywania operacji AND trze-

ba jeszcze narysować elementy obiektu B zmieniając jednak funkcję te-
stu bufora głębokości z domyślnej GL LESS na GL ALWAYS, przy czym
rysowanie odbywa się przy wyłączonym zapisie składowych RGBA do
bufora kolorów oraz wyłączonym buforze szablonowym. Po zakończeniu
rysowania przywracamy domyślną funkcję testu bufora głębokości.

6. Następnym etapem jest narysowanie tych elementów obiektu B, które

znajdują się we wnętrzu obiektu A. Wykonywane czynności odpowiadają
krokom 1-4 z oczywistą różnicą polegającą na zamianie obiektu A na
obiekt B i odwrotnie.
Końcowy wynik operacji AND przedstawiono na rysunku 6. Jak łatwo

zauważyć jest to część wspólna przenikającego się sześcianu i kuli.

background image

1. Bufor szablonowy

16

Rysunek 6. Program CSG - A AND B

Operacja SUB (odejmowanie) jest w ogólnym przypadku nieprzemienna,

stąd różne jej efekty w zależności od kolejności odejmowania obiektów, co
wyraźnie widać na rysunkach 7 i 8. Pierwszy etap odejmowania pokrywa
się z krokami 1-5 operacji AND. Dalej także rysowane są te elementy obiektu
B, które znajdują się we wnętrzu obiektu A, przy czym w kroku 4 zmienia
się test bufora szablonowego z GL NOTEQUAL na GL EQUAL co daje właściwy
efekt „odejmowania” obiektów. Zasadniczą część programu zajmującą się
wydzielaniem wnętrza obiektów zawiera funkcja Inside.

background image

1. Bufor szablonowy

17

Rysunek 7. Program CSG - A SUB B

1.5.2. Plik csg.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

” c o l o r s . h ”

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

CSG A ,

//

t y l k o

o b i e k t A

CSG B ,

//

t y l k o

o b i e k t A

CSG A OR B ,

// A OR B

CSG A AND B ,

// A AND B

CSG A SUB B ,

// A SUB B

CSG B SUB A ,

// B SUB A

FULL WINDOW,

//

a s p e k t

o b r a z u c a ł e

o k n o

ASPECT 1 1 ,

//

a s p e k t

o b r a z u

1 : 1

EXIT

//

w y j ś c i e

} ;

background image

1. Bufor szablonowy

18

Rysunek 8. Program CSG - B SUB A

//

a s p e k t

o b r a z u

i n t

a s p e c t = FULL WINDOW ;

//

r o z m i a r y

b r y ł y

o b c i n a n i a

const GLdouble

l e f t = − 2 . 0 ;

const GLdouble

r i g h t = 2 . 0 ;

const GLdouble bottom = − 2 . 0 ;
const GLdouble

t o p = 2 . 0 ;

const GLdouble

n e a r = 3 . 0 ;

const GLdouble

f a r = 7 . 0 ;

//

k ą t y

o b r o t u

s c e n y

G L f l o a t

r o t a t e x = 0 . 0 ;

G L f l o a t

r o t a t e y = 0 . 0 ;

//

w s k a ź n i k

n a c i ś n i ę c i a

l e w e g o

p r z y c i s k u

m y s z k i

i n t

b u t t o n s t a t e = GLUT UP ;

//

p o ł o ż e n i e

k u r s o r a

m y s z k i

i n t

b u t t o n x , b u t t o n y ;

background image

1. Bufor szablonowy

19

//

i d e n t y f i k a t o r y

l i s t

w y ś w i e t l a n i a

GLint A, B ;

//

r o d z a j

o p e r a c j i CSG

i n t

c s g o p = CSG A OR B ;

//

u s t a w i e n i e

b u f o r a

s z a b l o n o w e g o

t a k ,

a b y

w y d z i e l i ć

i

w y ś w i e t l i ć

//

t e

e l e m e n t y

o b i e k t u A ,

k t ó r e

z n a j d u j ą

s i ę

we

w n ę t r z u

o b i e k t u B ;

//

s t r o n ę

( p r z e d n i ą

l u b

t y l n ą )

w y s z u k i w a n y c h

e l e m e n t ó w

o b i e k t u A

//

o k r e ś l a

p a r a m e t r

c u l l

f a c e

void

I n s i d e

( GLint A,

GLint B ,

GLenum

c u l l f a c e ,

GLenum

s t e n c i l f u n c )

{

//

p o c z ą t k o w o

r y s u j e m y

o b i e k t A w

b u f o r z e

g ł ę b o k o ś c i

p r z y

//

w y ł ą c z o n y m

z a p i s i e

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

r y s o w a n i e

w y b r a n e j

s t r o n y

w i e l o k ą t ó w

g l C u l l F a c e

( c u l l f a c e ) ;

//

w y ś w i e t l e n i e

o b i e k t u A

g l C a l l L i s t

(A ) ;

//

n a s t ę p n i e

p r z y

u ż y c i u

b u f o r a

s z a b l o n o w e g o

wykrywamy

t e

e l e m e n t y

//

o b i e k t u A ,

k t ó r e

z n a j d u j ą

s i ę

w e w n ą t r z

o b i e k t u B ;

w tym

c e l u

//

z a w a r t o ś ć

b u f o r a

s z a b l o n o w e g o

j e s t

z w i ę k s z a n a

o

1 ,

w s z ę d z i e

g d z i e

//

b ę d ą

p r z e d n i e

s t r o n y

w i e l o k ą t ó w

s k ł a d a j ą c y c h

s i ę

na

o b i e k t

B

//

w y ł ą c z e n i e

z a p i s u

do

b u f o r a

g ł ę b o k o ś c i

glDepthMask

( GL FALSE ) ;

//

w ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l E n a b l e

( GL STENCIL TEST ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL ALWAYS, 0 , 0 ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL KEEP , GL KEEP , GL INCR ) ;

//

r y s o w a n i e

t y l k o

p r z e d n i e j

s t r o n y

w i e l o k ą t ó w

g l C u l l F a c e

(GL BACK ) ;

//

w y ś w i e t l e n i e

o b i e k t u B

g l C a l l L i s t

(B ) ;

// w k o l e j n y m

e t a p i e

z m n i e j s z a m y

z a w a r t o ś ć

b u f o r a

s z a b l o n o w e g o

o 1

//

w s z ę d z i e

tam ,

g d z i e

s ą

t y l n e

s t r o n y

w i e l o k ą t ó w

o b i e k t u B

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL KEEP , GL KEEP , GL DECR ) ;

//

r y s o w a n i e

t y l k o

t y l n e j

s t r o n y

w i e l o k ą t ó w

g l C u l l F a c e

(GL FRONT ) ;

//

w y ś w i e t l e n i e

o b i e k t u B

g l C a l l L i s t

(B ) ;

//

d a l e j

w y ś w i e t l a m y

t e

e l e m e n t y

o b i e k t u A ,

k t ó r e

//

z n a j d u j ą

s i ę

we

w n ę t r z u

o b i e k t u B

//

w ł ą c z e n i e

z a p i s u

do

b u f o r a

g ł ę b o k o ś c i

glDepthMask

(GL TRUE ) ;

//

w ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

(GL TRUE, GL TRUE, GL TRUE, GL TRUE ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

( s t e n c i l f u n c , 0 , 1 ) ;

//

w y ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

background image

1. Bufor szablonowy

20

//

r y s o w a n i e

w y b r a n e j

s t r o n y

w i e l o k ą t ó w

g l C u l l F a c e

( c u l l f a c e ) ;

//

w y ś w i e t l e n i e

o b i e k t u A

g l C a l l L i s t

(A ) ;

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

}

//

f u n k c j a

g e n e r u j ą c a

s c e n ę

3D

void

D i s p l a y S c e n e

( )

{

//

k o l o r

t ł a z a w a r t o ś ć

b u f o r a

k o l o r u

g l C l e a r C o l o r

( 1 . 0 , 1 . 0 , 1 . 0 , 1 . 0 ) ;

//

c z y s z c z e n i e

b u f o r a

k o l o r u ,

b u f o r a

g ł ę b o k o ś c i

i

b u f o r a

s z a b l o n o w e g o

g l C l e a r

( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT |

GL STENCIL BUFFER BIT ) ;

//

w y b ó r

m a c i e r z y

m o d e l o w a n i a

g l M a t r i x M o d e

(GL MODELVIEW ) ;

//

m a c i e r z

m o d e l o w a n i a = m a c i e r z

j e d n o s t k o w a

g l L o a d I d e n t i t y

( ) ;

//

p r z e s u n i ę c i e

u k ł a d u

w s p ó ł r z ę d n y c h

o b i e k t ó w

do

ś r o d k a

b r y ł y

o d c i n a n i a

g l T r a n s l a t e f

( 0 , 0 , − ( n e a r+f a r ) / 2 ) ;

//

o b r o t y

c a ł e j

s c e n y

g l R o t a t e f

( r o t a t e x , 1 . 0 , 0 . 0 , 0 . 0 ) ;

g l R o t a t e f

( r o t a t e y , 0 . 0 , 1 . 0 , 0 . 0 ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

w ł ą c z e n i e

ś w i a t ł a

GL LIGHT0

g l E n a b l e

( GL LIGHT0 ) ;

//

w ł ą c z e n i e

a u t o m a t y c z n e j

n o r m a l i z a c j i

w e k t o r ó w

n o r m a l n y c h

g l E n a b l e

(GL NORMALIZE ) ;

//

w ł ą c z e n i e

o b s ł u g i

w ł a ś c i w o ś c i

m a t e r i a ł ó w

g l E n a b l e

(GL COLOR MATERIAL ) ;

//

w ł a ś c i w o ś c i

m a t e r i a ł u

o k r e ś l o n e

p r z e z

k o l o r

w i e r z c h o ł k ó w

g l C o l o r M a t e r i a l

(GL FRONT, GL AMBIENT AND DIFFUSE ) ;

//

w ł ą c z e n i e

r y s o w a n i a

w y b r a n e j

s t r o n y

w i e l o k ą t ó w

g l E n a b l e

( GL CULL FACE ) ;

//

o p e r a c j a CSG t y l k o

o b i e k t A

i f

( c s g o p == CSG A )

{

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ś w i e t l e n i e

o b i e k t u A

g l C a l l L i s t

(A ) ;

//

w y ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

}

//

o p e r a c j a CSG t y l k o

o b i e k t B

i f

( c s g o p == CSG B )

{

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ś w i e t l e n i e

o b i e k t u B

g l C a l l L i s t

(B ) ;

//

w y ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

}

//

o p e r a c j a CSG A l u b B

i f

( c s g o p == CSG A OR B )

background image

1. Bufor szablonowy

21

{

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ś w i e t l e n i e

o b i e k t u A i B

g l C a l l L i s t

(A ) ;

g l C a l l L i s t

(B ) ;

//

w y ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

}

//

o p e r a c j a CSG A AND B

i f

( c s g o p == CSG A AND B )

{

//

e l e m e n t y

o b i e k t u A z n a j d u j ą c e

s i ę

we

w n ę t r z u B

I n s i d e

(A, B , GL BACK, GL NOTEQUAL ) ;

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

(GL ALWAYS ) ;

//

w y ś w i e t l e n i e

o b i e k t u B

g l C a l l L i s t

(B ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

( GL LESS ) ;

//

e l e m e n t y

o b i e k t u B z n a j d u j ą c e

s i ę

we

w n ę t r z u A

I n s i d e

(B , A, GL BACK, GL NOTEQUAL ) ;

}

//

o p e r a c j a CSG A SUB B

i f

( c s g o p == CSG A SUB B )

{

//

e l e m e n t y

o b i e k t u A z n a j d u j ą c e

s i ę

we

w n ę t r z u B

I n s i d e

(A, B , GL FRONT, GL NOTEQUAL ) ;

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

(GL ALWAYS ) ;

//

w y ś w i e t l e n i e

o b i e k t u B

g l C a l l L i s t

(B ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

( GL LESS ) ;

//

e l e m e n t y

o b i e k t u B z n a j d u j ą c e

s i ę

we

w n ę t r z u A

I n s i d e

(B , A, GL BACK, GL EQUAL ) ;

}

//

o p e r a c j a CSG B SUB A

i f

( c s g o p == CSG B SUB A )

{

//

e l e m e n t y

o b i e k t u B z n a j d u j ą c e

s i ę

we

w n ę t r z u A

I n s i d e

(B , A, GL FRONT, GL NOTEQUAL ) ;

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

background image

1. Bufor szablonowy

22

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

(GL ALWAYS ) ;

//

w y ś w i e t l e n i e

o b i e k t u A

g l C a l l L i s t

(A ) ;

//

w y b ó r

f u n k c j i

do

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D e p t h F u n c

( GL LESS ) ;

//

e l e m e n t y

o b i e k t u A z n a j d u j ą c e

s i ę

we

w n ę t r z u B

I n s i d e

(A, B , GL BACK, GL EQUAL ) ;

}

//

s k i e r o w a n i e

p o l e c e ń

do

w y k o n a n i a

g l F l u s h

( ) ;

//

z a m i a n a

b u f o r ó w

k o l o r u

g l u t S w a p B u f f e r s ( ) ;

}

//

z m i a n a

w i e l k o ś c i

o k n a

void

R esh ape

( i n t

width ,

i n t

h e i g h t )

{

//

o b s z a r

r e n d e r i n g u c a ł e

o k n o

g l V i e w p o r t

( 0 , 0 , width , h e i g h t ) ;

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

g l M a t r i x M o d e

(GL PROJECTION ) ;

//

m a c i e r z

r z u t o w a n i a = m a c i e r z

j e d n o s t k o w a

g l L o a d I d e n t i t y

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a

i f

( a s p e c t == ASPECT 1 1 )

{

//

w y s o k o ś ć

o k n a

w i ę k s z a

od

w y s o k o ś c i

o k n a

i f

( w i d t h < h e i g h t && w i d t h > 0 )

g l F r u s t u m

( l e f t , r i g h t , bottom ∗ h e i g h t / width , t o p ∗ h e i g h t / width , n e a r , f a r ) ;

e l s e

//

s z e r o k o ś ć

o k n a

w i ę k s z a

l u b

równa

w y s o k o ś c i

o k n a

i f

( w i d t h >= h e i g h t && h e i g h t > 0 )

g l F r u s t u m

( l e f t ∗ w i d t h / h e i g h t , r i g h t ∗ w i d t h / h e i g h t , bottom , top , n e a r , f a r ) ;

}

e l s e

g l F r u s t u m

( l e f t , r i g h t , bottom , top , n e a r , f a r ) ;

//

g e n e r o w a n i e

s c e n y

3D

D i s p l a y S c e n e

( ) ;

}

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

void MouseButton

( i n t

b u t t o n ,

i n t

s t a t e ,

i n t x ,

i n t

y )

{

i f

( b u t t o n == GLUT LEFT BUTTON)

{

//

z a p a m i ę t a n i e

s t a n u

l e w e g o

p r z y c i s k u

m y s z k i

b u t t o n s t a t e = s t a t e ;

//

z a p a m i ę t a n i e

p o ł o ż e n i a

k u r s o r a

m y s z k i

i f

( s t a t e == GLUT DOWN)

{

b u t t o n x = x ;
b u t t o n y = y ;

}

}

}

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

void MouseMotion

( i n t x ,

i n t

y )

{

i f

( b u t t o n s t a t e == GLUT DOWN)

{

r o t a t e y += 30

∗ ( r i g h t − l e f t ) / g l u t G e t

(GLUT WINDOW WIDTH)

∗ ( x − b u t t o n x ) ;

background image

1. Bufor szablonowy

23

b u t t o n x = x ;
r o t a t e x −= 30

∗ ( t o p − bottom ) / g l u t G e t

(GLUT WINDOW HEIGHT)

∗ ( b u t t o n y − y ) ;

b u t t o n y = y ;
g l u t P o s t R e d i s p l a y

( ) ;

}

}

//

o b s ł u g a

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

o p e r a c j a CSG

c a s e CSG A :
c a s e CSG B :
c a s e CSG A OR B :
c a s e CSG A AND B :
c a s e CSG A SUB B :
c a s e CSG B SUB A :

c s g o p = v a l u e ;
D i s p l a y S c e n e

( ) ;

break ;

//

o b s z a r

r e n d e r i n g u c a ł e

o k n o

c a s e FULL WINDOW :

a s p e c t = FULL WINDOW ;

R esha pe

( g l u t G e t

(GLUT WINDOW WIDTH) , g l u t G e t

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

o b s z a r

r e n d e r i n g u a s p e k t

1 : 1

c a s e ASPECT 1 1 :

a s p e c t = ASPECT 1 1 ;

R esha pe

( g l u t G e t

(GLUT WINDOW WIDTH) , g l u t G e t

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

w y j ś c i e

c a s e EXIT :

e x i t

( 0 ) ;

}

}

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

void

G e n e r a t e D i s p l a y L i s t s

( )

{

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

A = g l G e n L i s t s

( 1 ) ;

//

p i e r w s z a

l i s t a

w y ś w i e t l a n i a

g l N e w L i s t

(A, GL COMPILE ) ;

//

c z e r w o n y

s z e ś c i a n

g l C o l o r 4 f v

( Red ) ;

g l u t S o l i d C u b e

( 2 . 3 ) ;

//

k o n i e c

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

d r u g i e j

l i s t y

w y ś w i e t l a n i a

B =

g l G e n L i s t s

( 1 ) ;

//

d r u g a

l i s t a

w y ś w i e t l a n i a

g l N e w L i s t

(B , GL COMPILE ) ;

//

z i e l o n a

k u l a

g l C o l o r 4 f v

( Green ) ;

g l u t S o l i d S p h e r e

( 1 . 5 , 3 0 , 3 0 ) ;

//

k o n i e c

d r u g i e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

}

i n t

main

( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

i n i c j a l i z a c j a

b i b l i o t e k i

GLUT

g l u t I n i t

(& a r g c , a r g v ) ;

//

i n i c j a l i z a c j a

b u f o r a

r a m k i

g l u t I n i t D i s p l a y M o d e

(GLUT DOUBLE | GLUT RGB | GLUT DEPTH | GLUT STENCIL ) ;

background image

1. Bufor szablonowy

24

//

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

( ”CSG” ) ;

//

d o ł ą c z e n i e

f u n k c j i

g e n e r u j ą c e j

s c e n ę

3D

g l u t D i s p l a y F u n c

( D i s p l a y S c e n e ) ;

//

d o ł ą c z e n i e

f u n k c j i

w y w o ł y w a n e j

p r z y

z m i a n i e

r o z m i a r u

o k n a

g l u t R e s h a p e F u n c ( R es hape ) ;

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

g l u t M o u s e F u n c

( MouseButton ) ;

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

g l u t M o t i o n F u n c

( MouseMotion ) ;

//

u t w o r z e n i e

podmenu O p e r a c j a CSG

i n t MenuCSGOp = g l u t C r e a t e M e n u

( Menu ) ;

glutAddMenuEntry

( ”A” , CSG A ) ;

glutAddMenuEntry

( ”B” , CSG B ) ;

glutAddMenuEntry

( ”A OR B” , CSG A OR B ) ;

glutAddMenuEntry

( ”A AND B” , CSG A AND B ) ;

glutAddMenuEntry

( ”A SUB B” , CSG A SUB B ) ;

glutAddMenuEntry

( ”B SUB A” , CSG B SUB A ) ;

//

u t w o r z e n i e

podmenu A s p e k t

o b r a z u

i n t

MenuAspect = g l u t C r e a t e M e n u

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a ł e

okno ” ,FULL WINDOW ) ;

#e l s e

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a l e

okno ” ,FULL WINDOW ) ;

#e n d i f

glutAddMenuEntry

( ” A s p e k t

o b r a z u

1 : 1 ” , ASPECT 1 1 ) ;

// menu g ł ó w n e
g l u t C r e a t e M e n u

( Menu ) ;

glutAddSubMenu

( ” O p e r a c j a CSG” ,MenuCSGOp ) ;

#i f d e f WIN32

glutAddSubMenu

( ” A s p e k t

o b r a z u ” , MenuAspect ) ;

glutAddMenuEntry

( ” W y j ś c i e ” , EXIT ) ;

#e l s e

glutAddSubMenu

( ” A s p e k t

o b r a z u ” , MenuAspect ) ;

glutAddMenuEntry

( ” W y j s c i e ” , EXIT ) ;

#e n d i f

//

o k r e ś l e n i e

p r z y c i s k u

m y s z k i

o b s ł u g u j ą c e 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 ) ;

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

G e n e r a t e D i s p l a y L i s t s

( ) ;

//

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 ;

}

Trzeci program przykładowy (plik krawedzie.cpp) przestawia sposób

uzyskania przy użyciu bufora szablonowego krawędzi szkieletowych (ang.
silhouette edge) rysowanych obiektów sceny. Efekt jest bardzo łatwy do
usykania, ale niestety wymaga czterokrotnego narysowania obiektów sceny
przy czym za każdym razem obiekty muszą być przesunięte o jeden piksel
odpowiednio w lewo, w prawo, w górę i w dół. W ten sposób w buforze
szblonowym znajdą się informacje o „zarysach” obiektów. Następne - piąte
- rysowanie obiektów sceny następuje już przy ich normalnym położeniu

background image

1. Bufor szablonowy

25

i służy do usunięcia z bufora szablonowego tej części informacji, która nie
jest związana z krawędziami obiektów. Aby narysowanć tak uzyskaną kra-
wędź wystarczy już zwykły prostokąt obejmujący całe okno renderingu i od-
powiednio ustawiony test bufora szablonowego. Całość opisywanej operacji
znajduje się w funkcji Silhouette.

Efekty działania programu przedstawiają rysunki 9 i 10.

Rysunek 9. Program Krawędzie - obiekt z krawędzią

1.5.3. Plik krawedzie.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 <math . h>
#i n c l u d e

” c o l o r s . h ”

background image

1. Bufor szablonowy

26

Rysunek 10. Program Krawędzie - zarys obiektu

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

TORUS OBJ ,

//

t o r u s

CUBE OBJ ,

//

s z e ś c i a n

OBJECT,

//

r y s o w a n i e

t y l k o

o b i e k t u

SILHOUETTE,

//

r y s o w a n i e

t y l k o

k r a w ę d z i

s z k i e l e t o w y c h

SILHOUETTE OBJECT ,

//

r y s o w a n i e

o b i e k t u

i

k r a w ę d z i

s z k i e l e t o w y c h

EXIT

//

w y j ś c i e

} ;

//

r o z m i a r y

b r y ł y

o b c i n a n i a

const

GLint

l e f t = −5;

const

GLint

r i g h t = 5 ;

const

GLint bottom = −5;

const

GLint

t o p = 5 ;

const

GLint

n e a r = −5;

const

GLint

f a r = 5 ;

//

k ą t y

o b r o t u

s c e n y

G L f l o a t

r o t a t e x = 0 . 0 ;

G L f l o a t

r o t a t e y = 0 . 0 ;

background image

1. Bufor szablonowy

27

//

w s k a ź n i k

n a c i ś n i ę c i a

l e w e g o

p r z y c i s k u

m y s z k i

i n t

b u t t o n s t a t e = GLUT UP ;

//

p o ł o ż e n i e

k u r s o r a

m y s z k i

i n t

b u t t o n x , b u t t o n y ;

//

i d e n t y f i k a t o r y

l i s t

w y ś w i e t l a n i a

GLint TORUS ID , CUBE ID ;

//

i d e n t y f i k a t o r

b i e ż ą c e j

l i s t y

w y ś w i e t l a n i a

GLint CURRENT OBJECT ;

//

t r y b

r y s o w a n i a

i n t

r e n d e r m o d e = SILHOUETTE OBJECT ;

//

r y s o w a n i e

k r a w ę d z i

s z k i e l e t o w y c h

void

S i l h o u e t t e

( )

{

//

w y ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

( GL FALSE , GL FALSE , GL FALSE , GL FALSE ) ;

//

w ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l E n a b l e

( GL STENCIL TEST ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL ALWAYS, 1 , 1 ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL KEEP , GL KEEP , GL REPLACE ) ;

//

w y ł ą c z e n i e

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

//

w y ł ą c z n i e

o ś w i e t l e n i a

g l D i s a b l e

( GL LIGHTING ) ;

//

p o b r a n i e

r o z m i a r ó w

o k n a

r e n d e r i n g u

i n t

w i d t h = g l u t G e t

(GLUT WINDOW WIDTH ) ;

i n t

h e i g h t = g l u t G e t

(GLUT WINDOW HEIGHT ) ;

//

c z t e r o k r o t n e

n a r y s o w a n i e

o b i e k t u

p r z e s u n i ę t e g o

// o

j e d e n

p i k s e l

w l e w o ,

prawo , d ó ł

i

g ó r ę

g l V i e w p o r t

( − 1 , 0 , width −1 , h e i g h t ) ;

g l C a l l L i s t

(CURRENT OBJECT ) ;

g l V i e w p o r t

( 1 , 0 , w i d t h +1 , h e i g h t ) ;

g l C a l l L i s t

(CURRENT OBJECT ) ;

g l V i e w p o r t

( 0 , − 1 , width , h e i g h t − 1 ) ;

g l C a l l L i s t

(CURRENT OBJECT ) ;

g l V i e w p o r t

( 0 , 1 , width , h e i g h t + 1 ) ;

g l C a l l L i s t

(CURRENT OBJECT ) ;

//

p o w r ó t

do

p o d s t a w o w e g o

o b s z a r u

r e n d e r i n g u

g l V i e w p o r t

( 0 , 0 , width , h e i g h t ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL ALWAYS, 0 , 0 ) ;

//

n a r y s o w a n i e

b i e ż ą c e g o

o b i e k t u

g l C a l l L i s t

(CURRENT OBJECT ) ;

//

w ł ą c z e n i e

z a p i s u

s k ł a d o w y c h RGBA do

b u f o r a

k o l o r ó w

g l C o l o r M a s k

(GL TRUE, GL TRUE, GL TRUE, GL TRUE ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL EQUAL , 1 , 1 ) ;

//

o d ł o ż e n i e

m a c i e r z y

m o d e l o w a n i a

na

s t o s

g l P u s h M a t r i x

( ) ;

//

m a c i e r z

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

k r a w ę d z i

s z k i e l e t o w y c h

background image

1. Bufor szablonowy

28

g l C o l o r 3 f v

( Y e l l o w ) ;

//

n a r y s o w a n i e

p r o s t o k ą t a f a k t y c z n i e

k r a w ę d z i

s z k i e l e t o w y c h

g l R e c t i

( l e f t , bottom , r i g h t , t o p ) ;

//

z d j ę c i e

m a c i e r z y

m o d e l o w a n i a

z e

s t o s u

g l P o p M a t r i x

( ) ;

//

w ł ą c z e n i e

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

w y ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l D i s a b l e

( GL STENCIL TEST ) ;

}

//

f u n k c j a

g e n e r u j ą c a

s c e n ę

3D

void

D i s p l a y S c e n e

( )

{

//

k o l o r

t ł a z a w a r t o ś ć

b u f o r a

k o l o r u

g l C l e a r C o l o r

( 0 . 0 , 0 . 0 , 1 . 0 , 1 . 0 ) ;

// w

z a l e ż n o ś c i

od

t r y b u

r y s o w a n i a

c z y s z c z e n i e

b u f o r a

k o l o r u ,

b u f o r a

//

g ł ę b o k o ś c i

i

b u f o r a

s z a b l o n o w e g o

i f

( r e n d e r m o d e == OBJECT)

g l C l e a r

( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT ) ;

e l s e

g l C l e a r

( GL COLOR BUFFER BIT | GL DEPTH BUFFER BIT |

GL STENCIL 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

( ) ;

//

o b r o t y

c a ł e j

s c e n y

g l R o t a t e f

( r o t a t e x , 1 . 0 , 0 . 0 , 0 . 0 ) ;

g l R o t a t e f

( r o t a t e y , 0 . 0 , 1 . 0 , 0 . 0 ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

w ł ą c z e n i e

ś w i a t ł a

GL LIGHT0

g l E n a b l e

( GL LIGHT0 ) ;

//

w ł ą c z e n i e

a u t o m a t y c z n e j

n o r m a l i z a c j i

w e k t o r ó w

n o r m a l n y c h

g l E n a b l e

(GL NORMALIZE ) ;

//

w ł ą c z e n i e

o b s ł u g i

w ł a ś c i w o ś c i

m a t e r i a ł ó w

g l E n a b l e

(GL COLOR MATERIAL ) ;

//

w ł a ś c i w o ś c i

m a t e r i a ł u

o k r e ś l o n e

p r z e z

k o l o r

w i e r z c h o ł k ó w

g l C o l o r M a t e r i a l

(GL FRONT, GL AMBIENT AND DIFFUSE ) ;

//

w ł ą c z e n i e

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

n a r y s o w a n i e

w y b r a n y c h

e l e m e n t ó w

s c e n y

switch

( r e n d e r m o d e )

{

//

r y s o w a n i e

t y l k o

k r a w ę d z i

s z k i e l e t o w y c h

c a s e SILHOUETTE :

S i l h o u e t t e

( ) ;

break ;

//

r y s o w a n i e

o b i e k t u

i

k r a w ę d z i

s z k i e l e t o w y c h

c a s e SILHOUETTE OBJECT :

S i l h o u e t t e

( ) ;

g l C a l l L i s t

(CURRENT OBJECT ) ;

break ;

//

r y s o w a n i e

t y l k o

o b i e k t u

c a s e OBJECT :

g l C a l l L i s t

(CURRENT OBJECT ) ;

break ;

}

background image

1. Bufor szablonowy

29

//

s k i e r o w a n i e

p o l e c e ń

do

w y k o n a n i a

g l F l u s h

( ) ;

//

z a m i a n a

b u f o r ó w

k o l o r u

g l u t S w a p B u f f e r s ( ) ;

}

//

z m i a n a

w i e l k o ś c i

o k n a

void

R esh ape

( i n t

width ,

i n t

h e i g h t )

{

//

o b s z a r

r e n d e r i n g u c a ł e

o k n o

g l V i e w p o r t

( 0 , 0 , width , h e i g h t ) ;

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

g l M a t r i x M o d e

(GL PROJECTION ) ;

//

m a c i e r z

r z u t o w a n i a = m a c i e r z

j e d n o s t k o w a

g l L o a d I d e n t i t y

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a

g l O r t h o

( l e f t , r i g h t , bottom , top , n e a r , f a r ) ;

//

g e n e r o w a n i e

s c e n y

3D

D i s p l a y S c e n e

( ) ;

}

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

void MouseButton

( i n t

b u t t o n ,

i n t

s t a t e ,

i n t x ,

i n t

y )

{

i f

( b u t t o n == GLUT LEFT BUTTON)

{

//

z a p a m i ę t a n i e

s t a n u

l e w e g o

p r z y c i s k u

m y s z k i

b u t t o n s t a t e = s t a t e ;

//

z a p a m i ę t a n i e

p o ł o ż e n i a

k u r s o r a

m y s z k i

i f

( s t a t e == GLUT DOWN)

{

b u t t o n x = x ;
b u t t o n y = y ;

}

}

}

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

void MouseMotion

( i n t x ,

i n t

y )

{

i f

( b u t t o n s t a t e == GLUT DOWN)

{

r o t a t e y += 50

∗ ( r i g h t − l e f t ) / ( f l o a t ) g l u t G e t

(GLUT WINDOW WIDTH)

∗ ( x − b u t t o n x ) ;

b u t t o n x = x ;
r o t a t e x −= 50

∗ ( t o p − bottom ) / ( f l o a t ) g l u t G e t

(GLUT WINDOW HEIGHT)

∗ ( b u t t o n y − y ) ;

b u t t o n y = y ;
g l u t P o s t R e d i s p l a y

( ) ;

}

}

//

o b s ł u g a

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

t o r u s

c a s e TORUS OBJ :

CURRENT OBJECT = TORUS ID ;

D i s p l a y S c e n e

( ) ;

break ;

//

s z e ś c i a n

c a s e CUBE OBJ :

CURRENT OBJECT = CUBE ID ;

D i s p l a y S c e n e

( ) ;

break ;

//

r y s o w a n i e

t y l k o

o b i e k t u

c a s e OBJECT :

background image

1. Bufor szablonowy

30

//

r y s o w a n i e

t y l k o

k r a w ę d z i

s z k i e l e t o w y c h

c a s e SILHOUETTE :

//

r y s o w a n i e

o b i e k t u

i

k r a w ę d z i

s z k i e l e t o w y c h

c a s e SILHOUETTE OBJECT :
r e n d e r m o d e = v a l u e ;

D i s p l a y S c e n e

( ) ;

break ;

//

w y j ś c i e

c a s e EXIT :

e x i t

( 0 ) ;

}

}

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

void

G e n e r a t e D i s p l a y L i s t s

( )

{

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

TORUS ID = g l G e n L i s t s

( 1 ) ;

//

p i e r w s z a

l i s t a

w y ś w i e t l a n i a

g l N e w L i s t

( TORUS ID , GL COMPILE ) ;

//

c z e r w o n y

t o r u s

g l C o l o r 4 f v

( Red ) ;

g l u t S o l i d T o r u s

( 1 . 0 , 2 . 0 , 2 0 , 2 0 ) ;

//

k o n i e c

p i e r w s z e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

//

g e n e r o w a n i e

i d e n t y f i k a t o r a

d r u g i e j

l i s t y

w y ś w i e t l a n i a

CUBE ID = g l G e n L i s t s

( 1 ) ;

//

d r u g a

l i s t a

w y ś w i e t l a n i a

g l N e w L i s t

( CUBE ID , GL COMPILE ) ;

//

z i e l o n y

s z e ś c i a n

g l C o l o r 4 f v

( Green ) ;

g l u t S o l i d C u b e

( 4 . 0 ) ;

//

k o n i e c

d r u g i e j

l i s t y

w y ś w i e t l a n i a

g l E n d L i s t

( ) ;

//

b i e ż ą c y

o b i e k t

CURRENT OBJECT = TORUS ID ;

}

i n t

main

( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

i n i c j a l i z a c j a

b i b l i o t e k i

GLUT

g l u t I n i t

(& a r g c , a r g v ) ;

//

i n i c j a l i z a c j a

b u f o r a

r a m k i

g l u t I n i t D i s p l a y M o d e

(GLUT DOUBLE | GLUT RGB | GLUT DEPTH | GLUT STENCIL ) ;

//

r o z m i a r y

g ł ó w n e g o

o k n a

p r o g r a m u

g l u t I n i t W i n d o w S i z e

( 5 0 0 , 5 0 0 ) ;

//

u t w o r z e n i e

g ł ó w n e g o

o k n a

p r o g r a m u

#i f d e f WIN32

g l u t C r e a t e W i n d o w

( ” K r a w ę d z i e ” ) ;

#e l s e

g l u t C r e a t e W i n d o w

( ” K r a w e d z i e ” ) ;

#e n d i f

//

d o ł ą c z e n i e

f u n k c j i

g e n e r u j ą c e j

s c e n ę

3D

g l u t D i s p l a y F u n c

( D i s p l a y S c e n e ) ;

//

d o ł ą c z e n i e

f u n k c j i

w y w o ł y w a n e j

p r z y

z m i a n i e

r o z m i a r u

o k n a

g l u t R e s h a p e F u n c

( Re sha pe ) ;

//

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 ) ;

background image

1. Bufor szablonowy

31

//

u t w o r z e n i e

podmenu O b i e k t

i n t

MenuObject = g l u t C r e a t e M e n u

( Menu ) ;

glutAddMenuEntry

( ” T o r u s ” ,TORUS OBJ ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” S z e ś c i a n ” ,CUBE OBJ ) ;

#e l s e

glutAddMenuEntry

( ” S z e s c i a n ” ,CUBE OBJ ) ;

#e n d i f

//

u t w o r z e n i e

podmenu T r y b

r y s o w a n i a

i n t

MenuRenderMode = g l u t C r e a t e M e n u

( Menu ) ;

glutAddMenuEntry

( ” T y l k o

o b i e k t ” ,OBJECT ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” T y l k o

k r a w ę d z i e

s z k i e l e t o w e ” ,SILHOUETTE ) ;

glutAddMenuEntry

( ” O b i e k t

i

k r a w ę d z i e

s z k i e l e t o w e ” ,SILHOUETTE OBJECT ) ;

#e l s e

glutAddMenuEntry

( ” T y l k o

k r a w e d z i e

s z k i e l e t o w e ” ,SILHOUETTE ) ;

glutAddMenuEntry

( ” O b i e k t

i

k r a w e d z i e

s z k i e l e t o w e ” ,SILHOUETTE OBJECT ) ;

#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

( ” O b i e k t ” , MenuObject ) ;

glutAddSubMenu

( ” Tryb

r y s o w a n i a ” , MenuRenderMode ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” W y j ś c i e ” , EXIT ) ;

#e l s e

glutAddMenuEntry

( ” W y j s c i e ” , EXIT ) ;

#e n d i f

//

o k r e ś l e n i e

p r z y c i s k u

m y s z k i

o b s ł u g u j ą c e 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 ) ;

//

u t w o r z e n i e

l i s t

w y ś w i e t l a n i a

G e n e r a t e D i s p l a y L i s t s

( ) ;

//

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 ;

}

Ostatni program przykładowy (plik przejscie obrazow.cpp) przedsta-

wia sposób uzyskania przy użyciu bufora szablonowego efektu przejścia po-
między obrazami (ang. dissolving). Efekt jest bardzo prosty do uzyskania,
i daje bardzo ciekawe rezultaty. Przykładowy widok okna programu przed-
stawia rysunek 11.

1.5.4. Plik przejscie obrazow.cpp

/

( c )

J a n u s z

G a n c z a r s k i

h t t p : / / www . j a n u s z g . h g . p l

J a n u s z G @ e n t e r . n e t . p l
/

#i n c l u d e <GL/ g l u t . h>
#i n c l u d e <GL/ g l e x t . h>
#i n c l u d e < s t d l i b . h>
#i n c l u d e < s t r i n g . h>
#i n c l u d e < s t d i o . h>
#i n c l u d e

” t a r g a . h ”

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

background image

1. Bufor szablonowy

32

Rysunek 11. Program Przejście obrazów

CLEAR STENCIL ,

//

c z y s z c z e n i e

b u f o r a

s z a b l o n o w e g o

EXIT

//

w y j ś c i e

} ;

//

w s k a ź n i k

n a c i ś n i ę c i a

l e w e g o

p r z y c i s k u

m y s z k i

i n t

b u t t o n s t a t e = GLUT UP ;

//

p o ł o ż e n i e

k u r s o r a

m y s z k i

i n t

b u t t o n x , b u t t o n y ;

//

r o z m i a r y

g u m k i

const

i n t

e r a s e r w i d t h = 8 0 ;

const

i n t

e r a s e r h e i g h t = 8 0 ;

//

t a b l i c a

na

d a n e mapy

p i k s e l o w e j

z

gumką

GLubyte

e r a s e r p i x m a p

[ 4

e r a s e r w i d t h

e r a s e r h e i g h t ] ;

//

d a n e

o p i s u j ą c e

o b r a z

o d c z y t a n y

z

p l i k u TARGA

G L s i z e i

w i d t h ;

//

s z e r o k o ś ć

o b r a z u

G L s i z e i

h e i g h t ;

//

w y s o k o ś ć

o b r a z u

GLenum f o r m a t ;

//

f o r m a t

d a n y c h

o b r a z u

GLenum t y p e ;

//

f o r m a t

d a n y c h

p i k s e l i

o b r a z u

background image

1. Bufor szablonowy

33

GLvoid ∗ p i x e l s ;

//

w s k a ź n i k

na

t a b l i c ę

z

d a n y m i

o b r a z u

//

w c z y t a n i e

p l i k u

g r a f i c z n e g o

w f o r m a c i e TARGA

void LoadTARGA ( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

s p r a w d z e n i e

c z y

j e s t

p a r a m e t r

i f

( a r g c < 2 )

{

p r i n t f

( ” Brak nazwy

p l i k u TARGA\n ” ) ;

e x i t

( 1 ) ;

}

//

o d c z y t

p l i k u TARGA i

e w e n t u a l n y

k o m u n i k a t

o

b ł ę d z i e

i f

( ! l o a d t a r g a

( a r g v [ 1 ] , width , h e i g h t , f o r m a t , t y p e , p i x e l s ) )

{

#i f d e f WIN32

p r i n t f

( ” Błąd

o d c z y t u

l u b

b ł ę d n y

f o r m a t

p l i k u : %s \n ” , a r g v [ 1 ] ) ;

#e l s e

p r i n t f

( ” B l ad

o d c z y t u

l u b

b l e d n y

f o r m a t

p l i k u : %s \n ” , a r g v [ 1 ] ) ;

#e n d i f

e x i t

( 1 ) ;

}

}

//

s p r a w d z e n i e

c z y

d a n y

f o r m a t

p l i k u TARGA j e s t

o b s ł u g i w a n y

void CheckImageFormat

( )

{

//

o b r a z w f o r m a c i e BGR i BGRA

i f

( f o r m a t == GL BGR

| |

f o r m a t == GL BGRA)

{

//

o d c z y t

w e r s j i

OpenGL

const char ∗ v e r s i o n = ( char ∗ ) g l G e t S t r i n g

( GL VERSION ) ;

i n t

m a j o r = 0 ,

m i n o r = 0 ;

i f

( s s c a n f

( v e r s i o n , ”%d.%d ” ,& major ,& m i n o r )

!=

2 )

{

#i f d e f WIN32

p r i n t f

( ” Błędny

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e l s e

p r i n t f

( ” B l e d n y

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e n d i f

e x i t

( 1 ) ;

}

//

s p r a w d z e n i e

c z y

j e s t

c o

n a j m n i e j

w e r s j a

1 . 2

OpenGL

i f

( m a j o r <= 1 && m i n o r < 2 )

{

//

j e ż e l i

j e s t

s t a r s z a

w e r s j a

OpenGL

s p r a w d z e n i e

//

c z y

j e s t

o b s ł u g a

r o z s z e r z e n i a

GL EXT bgra

i f

( ! g l u t E x t e n s i o n S u p p o r t e d

( ” GL EXT bgra ” ) )

{

//

k o m u n i k a t

o

b ł ę d z i e w tym

m i e j s c u

można

w y k o n a ć

//

k o n w e r s j ę

d a n y c h

z

f o r m a t u BGR/BGRA na RGB/RGBA

p r i n t f

( ” Brak

r o z s z e r z e n i a

GL EXT bgra \n ” ) ;

e x i t

( 1 ) ;

}

}

}

}

//

w y g e n e r o w a n i e

d a n y c h

mapy

p i k s e l o w e j

z

gumką

void

G e n e r a t e E r a s e r

( )

{

//

p o k o l o r o w a n i e

c a ł e j

g u m k i

na

j a s n o

s z a r o

memset

( e r a s e r p i x m a p , 1 9 6 , 4

e r a s e r w i d t h

e r a s e r h e i g h t ) ;

}

//

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 ) ;

background image

1. Bufor szablonowy

34

//

w a r t o ś ć

c z y s z c z ą c a

b u f o r

s z a b l o n o w y

g l C l e a r S t e n c i l

( ˜ 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

( ) ;

//

w ł ą c z e n i e

b u f o r a

s z a b l o n o w e g o

g l E n a b l e

( GL STENCIL TEST ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL KEEP , GL KEEP , GL KEEP ) ;

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL EQUAL, 1 , ˜ 0 ) ;

//

p o z y c j a

mapy

p i k s e l o w e j

g l R a s t e r P o s 2 i

( 0 , 0 ) ;

//

w y r ó w n y w a n i e

w i e r s z a

mapy

p i k s e l o w e j

do

p o j e d y ń c z e g o

b a j t a

g l P i x e l S t o r e i

(GL UNPACK ALIGNMENT, 1 ) ;

//

s k a l o w a n i e

mapy

p i k s e l o w e j

do

r o z m i a r ó w

o k n a

g l P i x e l Z o o m

( ( f l o a t ) g l u t G e t (GLUT WINDOW WIDTH) / ( f l o a t ) width ,

( f l o a t ) g l u t G e t (GLUT WINDOW HEIGHT) / ( f l o a t ) h e i g h t ) ;

//

w y ś w i e t l e n i e

o b r a z u

z a w a r t e g o w m a p i e

p i k s e l o w e j

g l D r a w P i x e l s

( width , h e i g h t , f o r m a t , t y p e , p i x e l s ) ;

//

n e u t r a l n e

s k a l o w a n i e

mapy

p i k s e l o w e j

g l P i x e l Z o o m

( 1 . 0 , 1 . 0 ) ;

//

r y s o w a n i e

g u m k i

i f

( b u t t o n s t a t e == GLUT DOWN)

{

//

t e s t

b u f o r a

s z a b l o n o w e g o

g l S t e n c i l F u n c

(GL ALWAYS, 1 , 0 ) ;

//

o k r e ś l e n i e

o p e r a c j i

na

b u f o r z e

s z a b l o n o w y m

g l S t e n c i l O p

(GL KEEP , GL REPLACE, GL REPLACE ) ;

//

w ł ą c z e n i e

m i e s z a n i a

k o l o r ó w

g l E n a b l e

(GL BLEND ) ;

//

f u n k c j a

m i e s z a n i a

k o l o r ó w

g l B l e n d F u n c

( GL SRC ALPHA , GL ONE MINUS SRC ALPHA ) ;

//

p o z y c j a

g u m k i

g l R a s t e r P o s 2 i

( b u t t o n x , b u t t o n y ) ;

//

p r z e s u n i ę c i e

p o z y c j i

k u r s o r a

do

ś r o d k a

g u m k i

g l B i t m a p

( 0 , 0 , 0 . 0 , 0 . 0 , − e r a s e r w i d t h / 2 . 0 , − e r a s e r h e i g h t / 2 . 0 ,NULL ) ;

//

n a r y s o w a n i e

g u m k i i

g l D r a w P i x e l s

( e r a s e r w i d t h , e r a s e r h e i g h t , GL RGBA, GL UNSIGNED BYTE , e r a s e r p i x m a p ) ;

//

w y ł ą c z e n i e

m i e s z a n i a

k o l o r ó w

g l D i s a b l e

(GL BLEND ) ;

}

//

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

background image

1. Bufor szablonowy

35

g l L o a d I d e n t i t y

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a

g l u O r t h o 2 D

( 0 . 0 , Width , 0 . 0 , H e i g h t ) ;

//

c z y s z c z e n i e

b u f o r a

s z a b l o n o w e g o

g l C l e a r

( GL STENCIL BUFFER BIT ) ;

//

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)

{

//

z a p a m i ę t a n i e

s t a n u

l e w e g o

p r z y c i s k u

m y s z k i

b u t t o n s t a t e = s t a t e ;

//

z a p a m i ę t a n i e

p o ł o ż e n i a

k u r s o r a

m y s z k i

i f

( s t a t e == GLUT DOWN)

{

b u t t o n x = x ;
b u t t o n y = y ;

}

}

}

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

void MouseMotion

( i n t x ,

i n t

y )

{

i f

( b u t t o n s t a t e == GLUT DOWN)

{

b u t t o n x = x ;
b u t t o n y = g l u t G e t

(GLUT WINDOW HEIGHT) − y ;

g l u t P o s t R e d i s p l a y

( ) ;

}

}

//

o b s ł u g a

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

c z y s z c z e n i e

b u f o r a

s z a b l o n o w e g o

c a s e CLEAR STENCIL :

g l C l e a r

( GL STENCIL BUFFER BIT ) ;

g l u t P o s t R e d i s p l a y ( ) ;

break ;

//

w y j ś c i e

c a s e EXIT :

e x i t

( 0 ) ;

break ;

}

}

main

( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

o d c z y t

p l i k u

g r a f i c z n e g o TARGA

LoadTARGA ( a r g c , a r g v ) ;

//

i n i c j a l i z a c j a

b i b l i o t e k i

GLUT

g l u t I n i t

(& a r g c , a r g v ) ;

//

i n i c j a l i z a c j a

b u f o r a

r a m k i

g l u t I n i t D i s p l a y M o d e

(GLUT DOUBLE | GLUT RGB | GLUT STENCIL ) ;

//

r o z m i a r y

g ł ó w n e g o

o k n a

p r o g r a m u

g l u t I n i t W i n d o w S i z e

( 5 0 0 , 5 0 0 ) ;

//

u t w o r z e n i e

g ł ó w n e g o

o k n a

p r o g r a m u

#i f d e f WIN32

g l u t C r e a t e W i n d o w

( ” P r z e j ś c i e

o b r a z ó w ” ) ;

#e l s e

background image

1. Bufor szablonowy

36

g l u t C r e a t e W i n d o w

( ” P r z e j s c i e

o b r a z o w ” ) ;

#e n d i f

//

d o ł ą c z e n i e

f u n k c j i

g e n e r u j ą c e j

s c e n ę

3D

g l u t D i s p l a y F u n c

( D i s p l a y ) ;

//

d o ł ą c z e n i e

f u n k c j i

w y w o ł y w a n e j

p r z y

z m i a n i e

r o z m i a r u

o k n a

g l u t R e s h a p e F u n c

( Re sha pe ) ;

//

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 ) ;

//

s p r a w d z e n i e

c z y

d a n y

f o r m a t

p l i k u TARGA j e s t

o b s ł u g i w a n y

CheckImageFormat

( ) ;

//

u t w o r z e n i e

menu

p o d r ę c z n e g o

g l u t C r e a t e M e n u

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” Wyczyść

b u f o r

s z a b l o n o w y ” , CLEAR STENCIL ) ;

glutAddMenuEntry

( ” W y j ś c i e ” , EXIT ) ;

#e l s e

glutAddMenuEntry

( ” Wyczysc

b u f o r

s z a b l o n o w y ” , CLEAR STENCIL ) ;

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 y g e n e r o w a n i e

d a n y c h

mapy

p i k s e l o w e j

z

gumką

G e n e r a t e E r a s e r

( ) ;

//

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 ;

}

background image

Literatura

37

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,

http://www.opengl.org

[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


Document Outline


Wyszukiwarka

Podobne podstrony:
opengl bufor akumulacyjny
opengl bufor glebokosci
201211 Bufor - potwierdzenie odbioru bufora - szablon, Szablony PL
02 opengl 3 2 szablon aplikacji OpenGL
Grafika komputerowa i OpenGL
CMS Lab 04 Szablony
5 szablon
179 - Kod ramki - szablon
265 - Kod ramki - szablon, ◕ ramki z kodami
504 - Kod ramki - szablon, RAMKI KOLOROWE DO WPISÓW
267 - Kod ramki - szablon, ◕ ramki z kodami
765 - Kod ramki - szablon, RAMKI KOLOROWE DO WPISÓW
218 - Kod ramki - szablon, ◕ ramki z kodami
List Przewodni - Przykł, ► Różne, » Informatyczne, Szablony Offica

więcej podobnych podstron