opengl selekcja obiektow

background image

Janusz Ganczarski

OpenGL

Selekcja obiektów

background image

Spis treści

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

1

1. Selekcja obiektów . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.1.

Zmiana trybu renderowania . . . . . . . . . . . . . . . . . . . . . . .

1

1.2.

Stos nazw obiektów . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.3.

Przetwarzanie rekordu trafień . . . . . . . . . . . . . . . . . . . . . .

2

1.4.

Program przykładowy . . . . . . . . . . . . . . . . . . . . . . . . . .

3

1.4.1.

Plik selekcja obiektow.cpp . . . . . . . . . . . . . . . . . . .

5

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

13

background image

1. Selekcja obiektów

Tryb selekcji jest jednym z trzech trybów renderingu dostępnym w bi-

bliotece OpenGL. W trybie tym piksele nie są kopiowane do bufora ramki
obrazu. W zamian za to w buforze selekcji tworzona jest lista prymitywów,
których wierzchołki przecinają bryłę widzenia. Swoją budową bufor selekcji
nie przypomina żadnego innego opisywanego bufora OpenGL - jest to po
prostu jednowymiarowa tablica liczb całkowitych.

1.1. Zmiana trybu renderowania

Aby korzystać z selekcji obiektów w bibliotece OpenGL trzeba zmienić

tryb renderingu. Służy do tego funkcja:

GLint glRenderMode (GLenum mode)

której parametr mode przyjmuje następujące wartości:
— GL RENDER - tryb renderowania; jest to domyślny tryb renderingu,
— GL SELECT - tryb selekcji,
— GL FEEDBACK - tryb sprzężenia zwrotnego.

Wartość zwracana przez funkcję glRenderMode zależy od trybu renderin-

gu. W przypadku trybu renderowania funkcja zwraca wartość 0. W trybie
selekcji funkcja zwraca ilość rekordów trafień znajdujących się w buforze
selekcji. Jeżeli zabraknie miejsca w buforze selekcji funkcja zwróci wartość
-1. W ostatnim trybie sprzężenia zwrotnego funkcja zwraca ilość wartości
zapisanych w buforze sprzężenia zwrotnego.

Tryb sprzężenia zwrotnego zostanie omówiony oddzielnie. W tym miejscu

wspomnijmy jedynie, że w tym trybie piksele także nie są kopiowane do
bufora ramki obrazu.

1.2. Stos nazw obiektów

Nazwy obiektów, które mogą zostać wybrane w trakcie selekcji, biblio-

teka OpenGL przechowuje na stosie. Jedną nazwą można opisać zarówno
pojedynczy prymityw graficzny jak i dowolnie wybrana grupa obiektów.

Inicjalizację pustego stosu nazw obiektów wykonuje funkcja:

void glInitNames ()

Nazwy poszczególnym obiektom nadaje się wywołując funkcję:

void glLoadName (GLuint name)

gdzie parametr name jest unikatowym identyfikatorem obiektu. Funkcja ta
jednocześnie zastępuje nazwę znajdującą się aktualnie na szczycie stosu
nazw.

background image

1. Selekcja obiektów

2

Jeżeli chcemy wykrywać selekcję obiektów o hierarchicznej strukturze

(np. elementy składowe złożonego obiektu) trzeba umieszczać kolejne nazwy
obiektów na bieżącym stosie. Realizuje to funkcja:

void glPushName (GLuint name)

której parametr name jest unikatowym identyfikatorem obiektu. Po zdefinio-
waniu obiektu podrzędnego trzeba zdjąć nazwę obiektu ze stosu, co wymaga
wywołania funkcji:

void glPopName ()

Wielkość stosu nazw jest określana przez implementację biblioteki, ale

nie może być mniejsza niż 64. Niedomiar i przepełnienie stosu powodu-
je zgłoszenie błędów: GL STACK UNDERFLOW i GL STACK OVERFLOW. Aktual-
ną głębokość stosu zwraca wywołanie funkcji z grupy glGet z parametrem
GL NAME STACK DEPTH, a ustalenie maksymalnej głębokości stosu wymaga
użycie funkcji z tej samej grupy z parametrm GL MAX NAME STACK DEPTH.

Wszystkie powyższe operacje na stosie nazw są ignorowane, gdy biblio-

teka OpenGL znajduje się w innym trybie renderingu niż tryb selekcji.

1.3. Przetwarzanie rekordu trafień

Ostatnią operacją, którą trzeba wykonać przy korzystaniu z selekcji obiek-

tów jest ustawienie bufora selekcji przechowującego dane obiektów wybra-
nych w trakcie selekcji. Wymaga to wywołania funkcji:

void glSelectBuffer (GLsizei size, GLuint *buffer)

gdzie parametr size określa wielkość bufora, do którego wskaźnik zawiera
parametr buffer. Bufor powinien być na tyle duży, aby zmieścić informa-
cje o wszystkich obiektach wybranych w wyniku selekcji, przy czym samo
ustawienie bufora selekcji musi zostać wykonane przed przełączeniem biblio-
teki OpenGL w tryb selekcji. Przypomnijmy, że ilość wybranych obiektów
zwraca funkcja glRenderMode w momencie powrotu do domyślnego trybu
renderowania, czyli już po zakończeniu pracy w trybie selekcji.

Informacje o obiektach wybranych w trakcie selekcji zawarte są w tzw.

rekordach trafień. Każdy rekord zawiera co najmniej cztery elementy (liczby
całkowite ułożone kolejno w buforze selekcji) i ma następującą budowę:
— [0] - ilość nazw na stosie nazw w momencie trafienia,
— [1] - minimalna wartość współrzędnych z prymitywów graficznych wcho-

dzących w skład wybranego obiektu; wartość ta jest pomnożona przez
2

32

− 1 i zaokrąglone do najbliższej liczby całkowitej,

— [2] - maksymalna wartość współrzędnych z prymitywów graficznych wcho-

dzących w skład wybranego obiektu; wartość ta jest pomnożona przez
2

32

− 1 i zaokrąglone do najbliższej liczby całkowitej,

background image

1. Selekcja obiektów

3

— [3] - najniższy element stosu nazw obiektów (pierwszy odłożony na stos),

..

.

— [n] - najwyższy element stosu nazw obiektów (ostatni odłożony na stos),

Bezpośrednio po ostatnim elemencie pierwszego rekordu trafień znajduje

się drugi, a po nim kolejne rekordy.

1.4. Program przykładowy

W programie przykładowym (plikselekcja obiektow.cpp) tworzymy

cztery obiekty. Trzy z nich to sześciany, które należą do grupy CUBE. Każdy
z sześcianów posiada swój własny identyfikator o nazwie odpowiadającej ko-
lorowi (RED CUBE, GREEN CUBE i BLUE CUBE). Czwartym obiektem jest kula
identyfikowana stałą o nazwie SPHERE.

Typowym przypadku, który został także zaimplementowany w prezen-

towanym programie, selekcję obiektów wykonuje się na podstawie położenia
wskaźnika myszki, w chwili, gdy przycisk myszki został przyciśnięty. Aby
uzyskać pożądany efekt trzeba ograniczyć bryłę odcinania tak aby obej-
mowała „najbliższą okolicę” punktu, w którym został przyciśnięty przycisk
myszki. Najłatwiej jest to uzyskać korzystając z funkcji biblioteki GLU:

void gluPickMatrix (GLdouble x, GLdouble y,

GLdouble deltax, GLdouble deltay,
const GLint viewport[4])

Parametry x i y określają współrzędne środka nowej bryły odcinania

(oczywiście we współrzędnych okienkowych). Kolejne parametry deltax
i deltay określają szerokość i wysokość bryły odcinania w pikselach. Ostat-
ni parametr viewport zawiera dane o rozmiarach bieżącego obszaru ren-
deringu. Dane te najłatwiej jest pobrać wywołując funkcję glGetIntegerv
z parametrem GL VIEWPORT.

Jak ciekawostkę można podać w jaki sposób zaimplementowana została

funkcja gluPickMatrix w bibliotece GLU autorstwa firmy SGI:

glTranslatef ((viewport[2]-2*(x-viewport[0]))/deltax,

(viewport[3]-2*(y-viewport[1]))/deltay,0);

glScalef (viewport[2]/deltax,viewport[3]/deltay,1.0);

Zanim jednak, korzystając z funkcji gluPickMatrix, zmodyfikujemy bry-

łę odcinania trzeba odłożyć oryginalną macierz modelowania na stos. Po
zmodyfikowaniu bryły odcinania wykonujemy wszystkie etapy normalnego
renderingu sceny, włączając w to przekształcenia macierzy modelowania,
przy czym samo renderowanie sceny wykonywane jest już po włączeniu try-
bu selekcji. Po zakończeniu renderingu w trybie selekcji i ustaleniu ilości
rekordów trafień trzeba dokonać analizy zawartości bufora selekcji.

background image

1. Selekcja obiektów

4

Analiza bufora selekcji jest ściśle związana z ilością i układem hierarchii

obiektów rysowanych na scenie. W przykładowym programie obiekty są tak
zdefiniowane i ułożone, że w buforze selekcji mogą znaleźć się maksymalnie
dwa rekordy trafień, stąd ich analiza jest stosunkowo prosta. Przyśpieszenie
analizy ułatwia hierarchia obiektów sceny. Przykładowo wiedząc, że w pierw-
szym rekordzie trafień znajduje się kula, mamy pewność, że drugi rekord
może zawierać wyłącznie sześcian.

Efekt działania przykładowego programu przedstawiają rysunki 1 i 2.

W obu przypadkach komunikaty na dole okna pokazują ilość rekordów tra-
fień oraz obiekt, który w miejscu trafienia znajdował się najbliżej położenia
obserwatora.

Rysunek 1. Program Selekcja obiektów - wybrane dwa trafienia

background image

1. Selekcja obiektów

5

Rysunek 2. Program Selekcja obiektów - wybrane jedno trafienie

1.4.1. Plik selekcja obiektow.cpp

/

( c )

J a n u s z

G a n c z a r s k i

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

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

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

” c o l o r s . h ”

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

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 ;

background image

1. Selekcja obiektów

6

//

r o z m i a r y

b r y ł y

o b c i n a n i a

const GLdouble

l e f t = − 2 . 0 ;

const GLdouble

r i g h t = 2 . 0 ;

const GLdouble bottom = − 2 . 0 ;
const GLdouble

t o p = 2 . 0 ;

const GLdouble

n e a r = 3 . 0 ;

const GLdouble

f a r = 7 . 0 ;

//

k ą t y

o b r o t u

G L f l o a t

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

G L f l o a t

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

//

w s k a ź n i k

n a c i ś n i ę c i a

l e w e g o

p r z y c i s k u

m y s z k i

i n t

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

//

p o ł o ż e n i e

k u r s o r a

m y s z k i

i n t

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

//

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

s k a l o w a n i a

G L f l o a t

s c a l e = 1 . 0 ;

//

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

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

o b i e k t ó w

enum

{

NONE,
CUBE,
RED CUBE,
GREEN CUBE,

BLUE CUBE,
SPHERE

} ;

//

n a zw a

w y b r a n e g o

o b i e k t u

char

s e l e c t o b j e c t

[ 3 0 ] = ” T r a f i e n i a :

0 ” ;

//

f u n k c j a

r y s u j ą c a

n a p i s w wybranym

m i e j s c u

void

D r a w S t r i n g

( G L f l o a t

x ,

G L f l o a t

y ,

char ∗ s t r i n g )

{

//

p o ł o ż e n i e

n a p i s u

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

( x , y ) ;

//

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

n a p i s u

i n t

l e n = s t r l e n

( s t r i n g ) ;

f o r

( i n t

i = 0 ;

i < l e n ;

i ++)

g l u t B i t m a p C h a r a c t e r

( GLUT BITMAP 9 BY 15 , s t r i n g

[ i ] ) ;

}

//

f u n k c j a

g e n e r u j ą c a

s c e n ę

3D

void

D i s p l a y

( )

{

//

k o l o r

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

b u f o r a

k o l o r u

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

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

//

c z y s z c z e n i e

b u f o r a

k o l o r u

i

b u f o r a

g ł ę b o k o ś c i

g l C l e a r

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

//

w y b ó r

m a c i e r z y

m o d e l o w a n i a

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

(GL MODELVIEW ) ;

//

m a c i e r z

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

j e d n o s t k o w a

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

( ) ;

//

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

u k ł a d u

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

o b i e k t u

do

ś r o d k a

b r y ł y

o d c i n a n i a

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

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

//

o b r o t y

o b i e k t u

g l R o t a t e f

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

g l R o t a t e f

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

//

s k a l o w a n i e

o b i e k t u k l a w i s z e

”+”

i

background image

1. Selekcja obiektów

7

g l S c a l e f

( s c a l e , s c a l e , s c a l e ) ;

//

w ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l E n a b l e

(GL DEPTH TEST ) ;

//

w ł ą c z e n i e

o ś w i e t l e n i a

g l E n a b l e

( GL LIGHTING ) ;

//

w ł ą c z e n i e

ś w i a t ł a

GL LIGHT0 z

p a r a m e t r a m i

d o m y ś l n y m i

g l E n a b l e

( GL LIGHT0 ) ;

//

w ł ą 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 ) ;

//

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

s t o s u

nazw

o b i e k t ó w

g l I n i t N a m e s

( ) ;

//

u m i e s z c z e n i e

n a z w y

na

s t o s i e

nazw ,

a b y

n i e

b y ł

on

p u s t y

glPushName

(NONE ) ;

//

o b i e k t RED CUBE z

g r u p y CUBE

glLoadName

(CUBE ) ;

glPushName

(RED CUBE ) ;

g l C o l o r 4 f v

( Red ) ;

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

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

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

( 0 . 5 ) ;

glPopName

( ) ;

//

o b i e k t GREEN CUBE z

g r u p y CUBE

glPushName

(GREEN CUBE ) ;

g l C o l o r 4 f v

( Green ) ;

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

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

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

( 0 . 5 ) ;

glPopName

( ) ;

//

o b i e k t

BLUE CUBE z

g r u p y CUBE

glPushName

(BLUE CUBE ) ;

g l C o l o r 4 f v

( B l u e ) ;

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

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

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

( 0 . 5 ) ;

glPopName

( ) ;

//

o b i e k t SPHERE ,

n i e

n a l e ż ą c y

do

g r u p y CUBE

glLoadName

(SPHERE ) ;

g l C o l o r 4 f v

( Orange ) ;

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

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

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

( 0 . 4 , 2 0 , 2 0 ) ;

//

w y ł ą c z e n i e

o ś w i e t l e n i a

g l D i s a b l e

( GL LIGHTING ) ;

//

w y ł ą c z e n i e

t e s t u

b u f o r a

g ł ę b o k o ś c i

g l D i s a b l e

(GL DEPTH TEST ) ;

//

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

//

t r z e b a

o d p o w i e d n i o

p r z e k s z t a ł c i ć

u k ł a d

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

//

a b y

n a p i s

z n a j d o w a ł

s i ę

na

s a m e j

” g ó r z e ”

b r y ł y

o b c i n a n i a

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

( ) ;

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

( 0 , 0 , − n e a r ) ;

//

n a r y s o w a n i e

n a p i s u

o wybranym

o b i e k c i e

g l C o l o r 4 f v

( B l a c k ) ;

D r a w S t r i n g

( l e f t + 0 . 0 2 , bottom + 0 . 0 3 , s e l e c t o b j e c t ) ;

//

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 )

{

background image

1. Selekcja obiektów

8

//

o b s z a r

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

o k n o

g l V i e w p o r t

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

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

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

(GL PROJECTION ) ;

//

m a c i e r z

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

j e d n o s t k o w a

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

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a

i f

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

{

//

w y s o k o ś ć

o k n a

w i ę k s z a

od

w y s o k o ś c i

o k n a

i f

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

g l F r u s t u m

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

e l s e

//

s z e r o k o ś ć

o k n a

w i ę k s z a

l u b

równa

w y s o k o ś c i

o k n a

i f

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

g l F r u s t u m

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

}

e l s e

g l F r u s t u m

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

//

g e n e r o w a n i e

s c e n y

3D

D i s p l a y

( ) ;

}

//

o b s ł u g a

s e l e k c j i

o b i e t k ó w

void

S e l e c t i o n

( i n t x ,

i n t

y )

{

//

w i e l k o ś ć

b u f o r a

s e l e k c j i

const

i n t BUFFER LENGTH = 6 4 ;

//

b u f o r

s e l e k c j i

GLuint

s e l e c t b u f f e r

[ BUFFER LENGTH ] ;

//

p r z y g o t o w a n i e

b u f o r a

s e l e k c j i

g l S e l e c t B u f f e r

(BUFFER LENGTH, s e l e c t b u f f e r ) ;

//

p o b r a n i e

o b s z a r u

r o z m i a r u

r e n d e r i n g u

i n t

v i e w p o r t [ 4 ] ;

g l G e t I n t e g e r v

(GL VIEWPORT, v i e w p o r t ) ;

//

s z e r o k o ś ć

i

w y s o k o ś ć

o b s z a r u

r e n d e r i n g u

i n t

w i d t h = v i e w p o r t

[ 2 ] ;

i n t

h e i g h t = v i e w p o r t

[ 3 ] ;

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

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

(GL PROJECTION ) ;

//

o d ł o ż e n i e

m a c i e r z y

r z u t o w a n i a

na

s t o s

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

( ) ;

//

m a c i e r z

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

j e d n o s t k o w a

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

( ) ;

//

p a r a m e t r y

b r y ł y

o b c i n a n i a j e d n o s t k o w a

k o s t k a

d o o k o ł a

p u n k t u

w s k a ź n i k a

//

m y s z y

( x , y )

r o z c i ą g a j ą c e j

s i ę

na dwa

p i k s e l e

w p o z i o m i e

i

w

p i o n i e

g l u P i c k M a t r i x

( x , h e i g h t −y , 2 , 2 , v i e w p o r t ) ;

//

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

//

w ł ą c z e n i e

t r y b u

s e l e k c j i

glRenderMode

( GL SELECT ) ;

background image

1. Selekcja obiektów

9

//

g e n e r o w a n i e

s c e n y

3D

D i s p l a y

( ) ;

//

z l i c z e n i e

i l o ś c i

r e k o r d ó w

t r a f i e ń ,

p o w r ó t

do

d o m y ś l n e g o

t r y b u

r e n d e r i n g u

GLint

h i t s = glRenderMode

(GL RENDER ) ;

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

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

(GL PROJECTION ) ;

//

z d j ę c i e

m a c i e r z y

r z u t o w a n i a

z e

s t o s u

g l P o p M a t r i x

( ) ;

// w w y n i k u

s l e k c j i

n i e

w y b r a n o

ż a d n e g o

o b i e k t u

i f

( h i t s == 0 )

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

0 ” ) ;

// w w y n i k u

s e l e k c j i

w y b r a n o

j e d e n

o b i e k t

i f

( h i t s == 1 )

{

//

p o j e d y n c z a

n a zw a

na

s t o s i e k u l a

//

s p r a w d z e n i e

d r u g i e g o

w a r u n k u

n i e

j e s t

k o n i e c z n e

i f

( s e l e c t b u f f e r

[ 0 ] == 1 && s e l e c t b u f f e r

[ 3 ] == SPHERE)

{

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

1 ,

o b i e k t : SPHERE” ) ;

}

e l s e

//

d w i e

n a z w y

na

s t o s i e j e d e n

z

t r z e c h

s z e ś c i a n ó w

//

s p r a w d z e n i e

d r u g i e g o

w a r u n k u

n i e

j e s t

k o n i e c z n e

i f

( s e l e c t b u f f e r

[ 0 ] == 2 && s e l e c t b u f f e r

[ 3 ] == CUBE)

//

s p r a w d z e n i e

w i e r z c h o ł k a

s t o s u

nazw

switch

( s e l e c t b u f f e r

[ 4 ] )

{

//

c z e r w o n y

s z e ś c a n

c a s e RED CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

1 ,

o b i e k t : RED CUBE” ) ;

break ;

//

z i e l o n y

s z e ś c a n

c a s e GREEN CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

1 ,

o b i e k t : GREEN CUBE” ) ;

break ;

//

n i e b i e s k i

s z e ś c a n

c a s e BLUE CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

1 ,

o b i e k t : BLUE CUBE” ) ;

break ;

}

}

// w w y n i k u

s e l e k c j i

w y b r a n o

dwa

o b i e k t y

i f

( h i t s == 2 )

{

//

p i e r w s z y

o b i e k t s z e ś c i a n ,

d r u g i

o b i e k t

k u l a

i f

( s e l e c t b u f f e r

[ 0 ] == 2 && s e l e c t b u f f e r

[ 8 ] == SPHERE)

{

//

s p r a w d z e n i e ,

k t ó r y

z

o b i e k t ó w

j e s t

b l i ż e j

o b s e r w a t o r a

i f

( s e l e c t b u f f e r

[ 2 ] > s e l e c t b u f f e r

[ 7 ] )

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : SPHERE” ) ;

e l s e

//

s p r a w d z e n i e ,

k t ó r y

s z e ś c i a n

j e s t

b l i ż e j

o b s e r w a t o r a

switch

( s e l e c t b u f f e r

[ 4 ] )

{

//

c z e r w o n y

s z e ś c a n

c a s e RED CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : RED CUBE” ) ;

break ;

//

z i e l o n y

s z e ś c a n

c a s e GREEN CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : GREEN CUBE” ) ;

break ;

//

n i e b i e s k i

s z e ś c a n

c a s e BLUE CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : BLUE CUBE” ) ;

break ;

}

}

e l s e

background image

1. Selekcja obiektów

10

//

p i e r w s z y

o b i e k t s z e ś c i a n ,

d r u g i

o b i e k t

t a k ż e

s z e ś c i a n

//

z

u w a g i

na

k o l e j n o ś ć

d e f i n i o w a n i a

o b i e k t ó w

p r z y p a d e k ,

//

g d y

p i e r w s z y m

o b i e k t e m

j e s t

k u l a

a

d r u g i m

s z e ś c i a n

n i e

w y s t ą p i

i f

( s e l e c t b u f f e r

[ 0 ] == 2 && s e l e c t b u f f e r

[ 8 ] == CUBE)

{

//

s p r a w d z e n i e ,

k t ó r y

z

s z e ś c i a n ó w

j e s t

b l i ż e j

o b s e r w a t o r a

i f

( s e l e c t b u f f e r

[ 2 ] > s e l e c t b u f f e r

[ 7 ] )

//

d r u g i

s z e ś c i a n

j e s t

b l i ż e j

switch

( s e l e c t b u f f e r

[ 9 ] )

{

//

c z e r w o n y

s z e ś c a n

c a s e RED CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : RED CUBE” ) ;

break ;

//

z i e l o n y

s z e ś c a n

c a s e GREEN CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : GREEN CUBE” ) ;

break ;

//

n i e b i e s k i

s z e ś c a n

c a s e BLUE CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : BLUE CUBE” ) ;

break ;

}

e l s e

//

p i e r w s z y

s z e ś c i a n

j e s t

b l i ż e j

switch

( s e l e c t b u f f e r

[ 4 ] )

{

//

c z e r w o n y

s z e ś c a n

c a s e RED CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : RED CUBE” ) ;

break ;

//

z i e l o n y

s z e ś c a n

c a s e GREEN CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : GREEN CUBE” ) ;

break ;

//

n i e b i e s k i

s z e ś c a n

c a s e BLUE CUBE :

s t r c p y

( s e l e c t o b j e c t , ” T r a f i e n i a :

2 ,

p i e r w s z y

o b i e k t : BLUE CUBE” ) ;

break ;

}

}

}

}

//

o b s ł u g a

k l a w i a t u r y

void Keyboard

( unsigned char key ,

i n t x ,

i n t

y )

{

//

k l a w i s z +

i f

( k e y == ’+ ’ )

s c a l e += 0 . 0 5 ;

e l s e

//

k l a w i s z

i f

( k e y == ’− ’ && s c a l e > 0 . 0 5 )

s c a l e −= 0 . 0 5 ;

//

n a r y s o w a n i e

s c e n y

D i s p l a y

( ) ;

}

//

o b s ł u g a

k l a w i s z y

f u n k c y j n y c h

i

k l a w i s z y

k u r s o r a

void

S p e c i a l K e y s

( i n t

key ,

i n t x ,

i n t

y )

{

switch

( k e y )

{

//

k u r s o r w l e w o

c a s e GLUT KEY LEFT :

r o t a t e y −= 1 ;

break ;

//

k u r s o r w g ó r ę

c a s e GLUT KEY UP :

background image

1. Selekcja obiektów

11

r o t a t e x −= 1 ;

break ;

//

k u r s o r w p r a w o

c a s e GLUT KEY RIGHT :

r o t a t e y += 1 ;

break ;

//

k u r s o r w d ó ł

c a s e GLUT KEY DOWN :

r o t a t e x += 1 ;

break ;

}

//

o d r y s o w a n i e

o k n a

R esh ape

( g l u t G e t

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

(GLUT WINDOW HEIGHT ) ) ;

}

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

void MouseButton

( i n t

b u t t o n ,

i n t

s t a t e ,

i n t x ,

i n t

y )

{

i f

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

{

//

o b s ł u g a

s e l e k c j i

o b i e k t ó w

S e l e c t i o n

( x , y ) ;

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

( ) ;

//

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

s t a n u

l e w e g o

p r z y c i s k u

m y s z k i

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

//

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

p o ł o ż e n i a

k u r s o r a

m y s z k i

i f

( s t a t e == GLUT DOWN)

{

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

}

}

}

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

void MouseMotion

( i n t x ,

i n t

y )

{

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

s e l e k c j i

o b i e k t ó w

S e l e c t i o n

( x , y ) ;

}

}

//

o b s ł u g a

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

o b s z a r

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

o k n o

c a s e FULL WINDOW :

a s p e c t = FULL WINDOW ;

R esha pe

( g l u t G e t

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

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

o b s z a r

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

1 : 1

c a s e ASPECT 1 1 :

a s p e c t = ASPECT 1 1 ;

R esha pe

( g l u t G e t

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

(GLUT WINDOW HEIGHT ) ) ;

break ;

//

w y j ś c i e

c a s e EXIT :

e x i t

( 0 ) ;

}

}

background image

1. Selekcja obiektów

12

i n t

main

( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

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

b i b l i o t e k i

GLUT

g l u t I n i t

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

//

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

b u f o r a

r a m k i

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

(GLUT DOUBLE | GLUT RGB | GLUT DEPTH ) ;

//

r o z m i a r y

g ł ó w n e g o

o k n a

p r o g r a m u

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

( 5 0 0 , 5 0 0 ) ;

//

u t w o r z e n i e

g ł ó w n e g o

o k n a

p r o g r a m u

#i f d e f WIN32

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

( ” S e l e k c j a

o b i e k t ó w ” ) ;

#e l s e

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

( ” S e l e k c j a

o b i e k t 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 ) ;

//

d o ł ą c z e n i e

f u n k c j i

o b s ł u g i

k l a w i a t u r y

g l u t K e y b o a r d F u n c

( Keyboard ) ;

//

d o ł ą c z e n i e

f u n k c j i

o b s ł u g i

k l a w i s z y

f u n k c y j n y c h

i

k l a w i s z y

k u r s o r a

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

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

//

o b s ł u g a

p r z y c i s k ó w

m y s z k i

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

( MouseButton ) ;

//

o b s ł u g a

r u c h u

k u r s o r a

m y s z k i

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

( MouseMotion ) ;

//

u t w o r z e n i e

menu

p o d r ę c z n e g o

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

( Menu ) ;

//

u t w o r z e n i e

podmenu a s p e k t

o b r a z u

i n t

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

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a ł e

okno ” ,FULL WINDOW ) ;

#e l s e

glutAddMenuEntry

( ” A s p e k t

o b r a z u − c a l e

okno ” ,FULL WINDOW ) ;

#e n d i f

glutAddMenuEntry

( ” A s p e k t

o b r a z u

1 : 1 ” , ASPECT 1 1 ) ;

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

( Menu ) ;

glutAddSubMenu

( ” A s p e k t

o b r a z u ” , MenuAspect ) ;

#i f d e f WIN32

glutAddMenuEntry

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

#e l s e

glutAddMenuEntry

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

#e n d i f

//

o k r e ś l e n i e

p r z y c i s k u

m y s z k i

o b s ł u g u j ą c e j

menu

p o d r ę c z n e

g l u t A t t a c h M e n u

(GLUT RIGHT BUTTON ) ;

//

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

p r o g r a m u

do

o b s ł u g i

p ę t l i

k o m u n i k a t ó w

g l u t M a i n L o o p

( ) ;

return

0 ;

}

background image

Literatura

13

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

[9] Mark J. Kilgard: All About OpenGL Extensions,

http://www.opengl.org/

resources/features/OGLextensions/

[10] Jon Leech: How to Create OpenGL Extensions,

http://oss.sgi.com/

projects/ogl-sample/registry/doc/rules.html

[11] Silicon Graphics, Inc: OpenGL

R

Extension Registry,

http://oss.sgi.com/

projects/ogl-sample/registry/


Document Outline


Wyszukiwarka

Podobne podstrony:
Projekt Selekcja obiektów
opengl elementarne obiekty geometryczne
Projekt Selekcja obiektów
opengl obiekty buforowe
Obiekty martyrologii polskiej
R 6 1 Obiektowy model zapytan
Wykład 6 2009 Użytkowanie obiektu
05 Odwzorowanie podstawowych obiektów rysunkowych
Automatyzacja w KiC (w 2) Obiekty reg
na niebie są widoczne różne obiekty astronomiczne
obiektywne metody oceny postawy ciała (win 1997 2003)
30 Obciążenia obiektów budowlanych, mostów drogowych i kolejowych
Zasady zasilania energią obiektu szpitalnego

więcej podobnych podstron