opengl obiekty buforowe

background image

Janusz Ganczarski

OpenGL

Obiekty buforowe

background image

Spis treści

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

1

1. Obiekty buforowe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

1

1.1.

Generowanie identyfikatorów obiektów . . . . . . . . . . . . . . . . .

1

1.2.

Dowiązanie obiektów buforowych . . . . . . . . . . . . . . . . . . . .

1

1.3.

Usuwanie obiektów . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2

1.4.

Ładowanie danych do obiektu . . . . . . . . . . . . . . . . . . . . . .

2

1.5.

Pobieranie właściwości obiektu . . . . . . . . . . . . . . . . . . . . .

5

1.6.

Pobieranie danych obiektu

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

7

1.7.

Obiekty buforowe tablic wierzchołków . . . . . . . . . . . . . . . . .

7

1.8.

Obiekty buforowe indeksowych tablic wierzchołków . . . . . . . . . .

7

1.9.

Obiekty buforowe odczytu (rozpakowania) danych pikseli . . . . . .

8

1.10. Obiekty buforowe zapisu (spakowania) danych pikseli . . . . . . . .

8

1.11. Programy przykładowe

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

8

1.11.1. Plik vbo.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

1.11.2. Plik pbo.cpp . . . . . . . . . . . . . . . . . . . . . . . . . . .

19

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

26

background image

1. Obiekty buforowe

Obecne karty graficzne posiadają bardzo duże ilości pamięci. Jedynie

stosunkowo niewielka część z tej pamięci przeznaczona jest na bufor ram-
ki. Pozostałą pamięć mogą wykorzystywać tekstury (mechanizm obiektów
tekstur) lub wprowadzone w wersji 1.5 biblioteki OpenGL obiekty buforowe
wierzchołków VBO (ang. vertex buffer object), wcześniej dostępne w rozsze-
rzeniu ARB vertex buffer object. W wersji 2.1 biblioteki dodano obsługę
obiektów buforowych pikseli PBO (ang. pixel buffer object), które wcześniej
obsługiwały rozszerzenia ARB pixel buffer object i EXT pixel buffer -
object. Obiekty buforowe PBO i VBO korzystają z tego samego interfejsu,
funkcjonalnością zbliżonego do mechanizmów obiektów tekstur.

1.1. Generowanie identyfikatorów obiektów

Utworzenie wskazanej w parametrze n ilości unikatowych identyfikatorów

(nazw) obiektów buforowych realizuje funkcja:

void glGenBuffers (GLsizei n,

GLuint *buffers)

Numery identyfikatorów zwracane sa w tablicy wskazywanej w parame-
trze buffers. Oczywiście program musi zapewnić odpowiednią ilość miejsca
w tablicy. Identyfikator o wartości zero nie jest związany z żadnym obiektem
buforowym.

Sprawdzenie czy wskazany identyfikator jest identyfikatorem obiektu bu-

forowego umożliwia funkcja:

GLboolean glIsBuffer (GLuint buffer)

która zwraca stosowne wartości logiczne (GL TRUE lub GL FALSE).

1.2. Dowiązanie obiektów buforowych

Utworzony identyfikator trzeba dowiązać do obiektu buforowego wywo-

łując funkcję:

void glBindBuffer (GLenum target,

GLuint buffer)

której parametr buffer zawiera unikatowy identyfikator obiektu, a para-
metr target określa rodzaj obiektu buforowanego. Dostępne są następujące
rodzaje obiektów buforowych:
— GL ARRAY BUFFER - obiekt buforowy tablic wierzchołków,
— GL ELEMENT ARRAY BUFFER - obiekt buforowy indeksowych tablic wierz-

chołków,

background image

1. Obiekty buforowe

2

— GL PIXEL UNPACK BUFFER - obiekt buforowy odczytu (rozpakowania) da-

nych pikseli,

— GL PIXEL PACK BUFFER - obiekt buforowy zapisu (spakowania) danych

pikseli.
Pierwsze dwa rodzaje obiektów buforowych należą do grupy obiektów

buforowych wierzchołków (VBO), dwa pozostałe to obiekty buforowe pikseli
(PBO).

Pierwsze wywołanie funkcji glBindBuffer tworzy obiekt buforowy, a na-

stępne wywołania służą do przełączania się pomiędzy wybranymi obiektami.
Opisane dalej operacje na obiektach buforowych wykonywane są zawsze na
bieżącym obiekcie, wybranym przy użyciu funkcji glBindBuffer.

1.3. Usuwanie obiektów

Usuwanie wybranej grupy obiektów buforowych realizuje funkcja:

void glDeleteBuffers (GLsizei n,

const GLuint *buffers)

Parametr n określa ilość usuwanych obiektów buforowych, których identyfi-
katowy zawiera tablica buffers.

1.4. Ładowanie danych do obiektu

Ładowanie danych do obiektu buforowego można zrealizować na dwa

sposoby. Pierwszy polega na skorzystaniu z tradycyjnego modelu aplikacji
OpenGL, tj. kopiowaniu danych do obiektu bufora z tablicy (lub innej struk-
tury danych) zawartej w pamięci operacyjnej komputera. Taki model łado-
wania danych wykorzystują obiekty tekstur. Druga metoda korzysta z tzw.
odwzorowania obiektu buforowego (ang. mapping buffer object) i pozwala na
bezpośrednie operowanie na pamięci obiektu.

Zauważmy, że pierwsza z wymienionych metod wymaga zarezerwowania

odpowiedniej ilości pamięci operacyjnej komputera, choć może to być alo-
kacja tymczasowa (dynamiczna). Drugi sposób nie wymaga przydzielania
dodatkowych zasobów systemowych.

Niezależnie od przyjętej metody ładowanie danych do obiektu buforowe-

go wymaga wywołania funkcji:

void glBufferData (GLenum target,

GLsizeiptr size,
const GLvoid *data,
GLenum usage)

background image

1. Obiekty buforowe

3

Parametr target określa rodzaj obiektu buforowego, którego dane two-

rzymy. Możliwe są cztery opisane wcześniej wartości: GL ARRAY BUFFER, GL -
ELEMENT ARRAY BUFFER, GL PIXEL UNPACK BUFFER i GL PIXEL PACK BUFFER.

Drugi parametr size wskazuje rozmiar danych bufora obiektu buforo-

wego. Wielkość ta jest określana w BMU - podstawowe jednostkach maszy-
nowych (ang. basic machine units), czyli w bajtach. Jedynym sposobem na
zmianę wielkości bufora jest usunięcie obiektu i ponowne jego utworzenie
z żądanym rozmiarem.

Kolejny parametr data zawiera wskaźnik na dane ładowane do obiektu

buforowego. Podanie wartości różnej od NULL powoduje skopiowanie danych
z bufora zawartego w pamięci operacyjnego do bufora zawartego w pamię-
ci karty graficznej. Natomiast w przypadku podania wartości NULL pamięć
bufora obiektu buforowego jest jedynie rezerwowana, a jej zawartość jest
nieokreślona. Możliwość tę wykorzystujemy w szczególności w przypadku,
gdy zamierzamy bezpośrednio operować na pamięci obiektu buforowego.

Ostatni parametr usage zawiera wskazówkę dla biblioteki OpenGL do-

tyczącą przewidywanej metody dostępu do danych zawartych w obiekcie
buforowym. Możliwe są następujące wartości:
— GL STREAM DRAW - jednokrotne lub sporadyczne pobieranie danych i przez

większość czasu wykorzystanie ich do zapisu do obiektu OpenGL,

— GL STREAM READ - jednokrotne lub sporadyczne pobieranie danych i przez

większość czasu wykorzystanie ich do odczytu z obiektu OpenGL,

— GL STREAM COPY - jednokrotne lub sporadyczne pobieranie danych i przez

większość czasu wykorzystanie ich zarówno do odczytu z obiektu OpenGL
jak i do zapisu,

— GL STATIC DRAW - jednokrotne lub sporadyczne pobieranie danych i wie-

lokrotne ich wykorzystanie do zapisu do obiektu OpenGL,

— GL STATIC READ - jednokrotne lub sporadyczne pobieranie danych i wie-

lokrotne ich wykorzystanie do odczytu z obiektu OpenGL,

— GL STATIC COPY - jednokrotne lub sporadyczne pobieranie danych i wie-

lokrotne wykorzystanie ich zarówno do odczytu z obiektu OpenGL jak i
do zapisu,

— GL DYNAMIC DRAW - wielokrotne pobieranie danych i wielokrotne ich wy-

korzystanie do zapisu do obiektu OpenGL,

— GL DYNAMIC READ - wielokrotne pobieranie danych i wielokrotne ich wy-

korzystanie do odczytu z obiektu OpenGL,

— GL DYNAMIC COPY - wielokrotne pobieranie danych i wielokrotne wyko-

rzystanie ich zarówno do odczytu z obiektu OpenGL jak i do zapisu.
Parametr usage jest jedynie wskazówką umożliwiającą optymalizację im-

plementacji biblioteki OpenGL. Wybrana metoda dostępu do danych obiek-
tu nie ogranicza wykonywanych na nim operacji.

background image

1. Obiekty buforowe

4

W przypadku braku możliwości przydzielenia wymaganej ilości pamięci

funkcja glBufferData generuje błąd GL OUT OF MEMORY.

Zmianę całości lub części danych zawartych w obiekcie buforowym umoż-

liwia funkcja:

void glBufferSubData (GLenum target,

GLintptr offset,
GLsizeiptr size,
const GLvoid *data)

Parametr target określa oczywiście rodzaj obiektu buforowego i przyj-

muje jedną z czterech znanych już wartości. Zakres modyfikowanych danych
określają parametry offset i size, gdzie offset jest numerem pierwszego
zmienianego elementu danych bufora obiektu (numeracja elementów zaczyna
się od zera i jest prowadzona w bajtach), a size to ilość modyfikowanych ele-
mentów bufora. Nowe dane zawarte są w tablicy wskazywanej w parametrze
data.

Wspomniana wcześniej metoda odwzorowania obiektu buforowego wy-

maga uzyskania wskaźnika do danych obiektu buforowego. Wymaga to wy-
wołania funkcji:

GLvoid *glMapBuffer (GLenum target,

GLenum access)

której parametr target określa rodzaj obiektu buforowego i przyjmuje znane
już wartości: GL ARRAY BUFFER, GL ELEMENT ARRAY BUFFER, GL PIXEL UN-
PACK BUFFER i GL PIXEL PACK BUFFER.

Drugi parametr access wskazuje do jakich operacji będzie wykorzystany

pobierany wskaźnik na dane obiektu buforowego:
— GL READ ONLY - odczyt danych,
— GL WRITE ONLY - zapis danych,
— GL READ WRITE - odczyt i zapis danych.
Wykorzystanie wskaźnika niezgodnie z planowanym przeznaczeniem nie po-
woduje wprawdzie zgłoszenia błędu przez bibliotekę OpenGL, ale efekt dzia-
łania jest nieokreślony.

Jeżeli odwzorowywany obiekt jest już w tym trybie funkcja glMapBuffer

zwraca wartość NULL oraz dodatkowo generowany jest błąd GL INVALID -
OPERATION.

Gdy obiekt buforowy znajduje się w trybie nie można na min wykony-

wać innych operacji niż związanych z pobieraniem (lub ładowaniem) danych.
W szczególności wywołanie funkcji glBufferSubData spowoduje wystąpie-
nie błędu GL INVALID OPERATION. Efekt działania innych operacji związa-
nych z obiektem buforowym jest nieokreślony. Zezwolenie na takie zachowa-

background image

1. Obiekty buforowe

5

nie obiektów buforowych specyfikacji biblioteki OpenGL tłumaczy możliwo-
ścią uzyskania wyższej wydajności.

Po zakończeniu operacji w trybie odwzorowania trzeba zwolnić pobrany

wskaźnik do danych obiektu buforowego wywołując funkcję:

GLboolean glUnmapBuffer (GLenum target)

której parametr target określa oczywiście rodzaj obiektu buforowego.

W przypadku poprawnego wyjścia obiektu buforowego z trybu odwzoro-

wania funkcja glUnmapBuffer zwraca wartość GL TRUE. Wartość GL FALSE
zostanie zwrócona, gdy obiekt nie znajduje się w trybie odwzorowania oraz
w każdym przypadku wystąpienia zdarzenia wpływającego na zmianę sta-
nu pamięci karty graficznej. Takim zdarzeniami mogą być w szczególności:
zmiana rozdzielczości ekranu, przejście karty graficznej w tryb oszczędza-
nia energii. Wystąpienie takich sytuacji wymaga ponownego załadowania
danych do pamięci bufora obiektu.

1.5. Pobieranie właściwości obiektu

Pobranie właściwości bieżącego obiektu buforowego umożliwia funkcja:

void glGetBufferParameteriv (GLenum target,

GLenum pname,
GLint *params)

Parametr target określa rodzaj obiektu buforowego i przyjmuje jedną

z dobrze znanych wartości: GL ARRAY BUFFER, GL ELEMENT ARRAY BUFFER,
GL PIXEL UNPACK BUFFER i GL PIXEL PACK BUFFER.

Drugi parametr pname zawiera rodzaj pobieranej właściwości obiektu

buforowego, który zostaje zwrócony w parametrze params. Możliwe są na-
stępujące wartości:
— GL BUFFER SIZE - rozmiar danych obiektu (w bajtach),
— GL BUFFER USAGE - wskazówka dostępu do danych obiektu,
— GL BUFFER ACCESS - przeznaczenie wskaźnika do danych obiektu,
— GL BUFFER MAPPED- znacznik czy obiekt znajduje się w trybie odwzoro-

wania.
Jeżeli obiekt buforowy znajduje się w trybie odwzorowania możliwe jest

pobranie wskaźnika na dane obiektu. Wymaga to wywołania funkcji:

void glGetBufferPointerv (GLenum target,

GLenum pname,
GLvoid **params)

której parametr target określa rodzaj obiektu buforowego (cztery znane
wartości: GL ARRAY BUFFER, GL ELEMENT ARRAY BUFFER, GL PIXEL UNPACK -
BUFFER i GL PIXEL PACK BUFFER), a drugi parametr pname może przyjąć

background image

1. Obiekty buforowe

6

par

am

etr

w

artość

p

o

c

zątk

o

w

a

dop

usz

czalne

w

artości

GL

BUFFE

R

SIZE

0

ni

e

u

jem

n

a

lic

zba

całk

o

wita

GL

BUFFE

R

USA

GE

GL

ST

A

TIC

DRA

W

GL

STRE

AM

DRA

W,

GL

STRE

AM

READ,

GL

STRE

AM

COPY,

G

L

ST

A

TIC

DRA

W,

GL

ST

A

TIC

READ,

G

L

ST

A

TIC

COPY,

GL

D

YNAMIC

DRA

W,

GL

D

YNAMIC

READ,

GL

D

YNAMIC

COPY

GL

BUFFE

R

A

CC

E

SS

GL

READ

WRITE

GL

READ

ONL

Y,

G

L

WRITE

ONL

Y

,

GL

READ

WRITE

GL

BUFFE

R

MAP

PE

D

GL

F

ALS

E

GL

TR

UE

,

GL

F

ALS

E

GL

BUFFE

R

MAP

PO

INT

E

R

NULL

ws

k

aźnik

T

ab

e

la

1:

Zes

ta

wie

n

ie

właśc

iw

ci

obi

e

któ

w

buf

oro

wyc

h

background image

1. Obiekty buforowe

7

jedynie wartość GL BUFFER MAP POINTER, oznaczającą właśnie pobieranie
wskaźnika na dane obiektu. Wskaźnik jest zwracany w ostatnim parametrze
params.

W przypadku, gdy wybrany obiekt buforowy nie jest w trybie odwzoro-

wania w parametrze params zostanie zwrócona wartość NULL.

Zestawienie wszystkich właściwości obiektów buforowych wraz z dopusz-

czalnymi wartościami oraz wartościami początkowymi przedstawia tabela 1.

1.6. Pobieranie danych obiektu

Biblioteka OpenGL umożliwia pobranie wybranych danych zawartych

w obiekcie buforowym przy użyciu funkcji:

void glGetBufferSubData (GLenum target,

GLintptr offset,
GLsizeiptr size,
GLvoid *data)

której parametr target określa rodzaj obiektu buforowego, a parametry
offset i size wyznaczają odpowiednio pierwszy pobierany element oraz
ilość kopiowanych elementów. Numeracja elementów obiektu buforowego za-
czyna się od zera i jest wyznaczana w bajtach. Bufor, do którego kopiowane
są wybrane elementy, wskazywany jest w parametrze data.

1.7. Obiekty buforowe tablic wierzchołków

Dane przechowywane w obiektach buforowych tablic wierzchołków są

zgodne z formatem używanym w tablicach wierzchołków. Umożliwia to bez-
pośrednie korzystanie z tablic wierzchołków przy użyciu funkcji: glArray-
Element, glDrawArrays, glMultiDrawArrays, glDrawElements, glDraw-
RangeElements i glMultiDrawElements. Jedyna różnica polega na sposo-
bie dostarczenia danych tablic wierzchołków do funkcji: glVertexPointer,
glNormalPointer, glColorPointer, glSecondaryColorPointer, glIndex-
Pointer, glEdgeFlagPointer, glFogCoordPointer i glTexCoordPointer.
Zamiast wskaźnika na dane tablicy (parametr pointer powyższych funkcji)
należy podać położenie początku danych w bieżącym obiekcie buforowym
tablicy wierzchołków. W praktyce jeden obiekt buforowy tablic wierzchołków
może zatem służyć do przechowywania danych wielu tablic wierzchołków.

1.8. Obiekty buforowe indeksowych tablic wierzchołków

Obiekty buforowe indeksowych tablic wierzchołków są bezpośrednio

przystosowane do współpracy z funkcjami: glDrawElements, glDrawRange-
Elements i glMultiDrawElements obsługującymi indeksowe tablice wierz-

background image

1. Obiekty buforowe

8

chołków. Jedyna różnica polega na sposobie dostarczenia danych tablicy in-
deksów. Zamiast wskaźnika na dane tablicy z indeksami (parametr indices
dwóch pierwszych funkcji) podaje się położenie początku danych w bieżącym
obiekcie buforowym indeksowej tablicy wierzchołków. W przypadku funkcji
glMultiDrawElements parametr indices zawiera adresy położenia danych
kolejnych tablic indeksów w bieżącym obiekcie buforowym.

1.9. Obiekty buforowe odczytu (rozpakowania) danych pikseli

Obiekty buforowe odczytu danych pikseli można wykorzystać jako źró-

dło danych pikseli dla następujących funkcji biblioteki OpenGL: glBitmap,
glColorSubTable, glColorTable, glCompressedTexImage1D, glCompres-
sedTexImage2D, glCompressedTexImage3D, glCompressedTexSubImage1D,
glCompressedTexSubImage2D, glCompressedTexSubImage3D, glConvolu-
tionFilter1D, glConvolutionFilter2D, glDrawPixels, glPixelMapfv,
glPixelMapuiv, glPixelMapusv, glPolygonStipple, glSeparableFilter2D,
glTexImage1D, glTexImage2D, glTexImage3D, glTexSubImage1D, glTexSub-
Image2D i glTexSubImage3D.

W parametrach powyższych funkcji wskazujących źródło danych pikseli

zamiast adresu tablicy z danymi wskazujemy położenie danych w obiekcie
buforowym.

1.10. Obiekty buforowe zapisu (spakowania) danych pikseli

Obiekty buforowe zapisu danych pikseli można wykorzystać jako bufor

danych pikseli dla następujących funkcji biblioteki OpenGL: glGetCompres-
sedTexImage, glGetConvolutionFilter, glGetHistogram, glGetMinmax,
glGetPixelMapfv, glGetPixelMapuiv, glGetPixelMapusv, glGetPolygon-
Stipple, glGetSeparableFilter, glGetTexImage i glReadPixels.

W parametrach powyższych funkcji wskazujących tablicę na dane pikseli

zamiast adresu tablicy na dane wskazujemy położenie danych w obiekcie
buforowym.

1.11. Programy przykładowe

Pierwszy program przykładowy (plik vbo.cpp) jest kolejnym rozwinię-

ciem programu służącego wcześniej do testów list wyświetlania oraz ta-
blic wierzchołków. W porównaniu do poprzednika trzykrotnie zwiększono
ilość wyświetlanych prymitywów. Zastosowanie obiektów buforowych wy-
raźnie zwiększyło szybkość wyświetlania prymitywów, przy czym największy
wzrost szybkości dotyczy wyświetlania punktów (23%), nieco mniej zyskują
odcinki (8%) i trójkąty (6%). Pamiętajmy jednak, że program faktycznie
testuje jedynie szybkość renderingu, a VBO pozwala także na optymalizację

background image

1. Obiekty buforowe

9

zarządzania pamięcią, co umożliwia jeszcze większe przyspieszenia działania
programów.

W programie zastosowano obie opisane wyżej metody ładowania danych

do obiektu buforowego, jednak nie został wyeliminowany bufor zawarty
w pamięci operacyjnej z uwagi na konieczność jego obecności do porów-
nawczego testu tablic wierzchołków. Dane tablicy ze składowymi kolorów
wierzchołków prymitywów i tablicy ze współrzędnymi tych wierzchołków
przechowywane są w dwóch odrębnych obiektach buforowych, choć możliwe
jest także wykorzystanie jednego obiektu do przechowywania danych obu
tablic.

Wyniki wszystkich testów dostępnych w programie przedstawiono na

rysunkach 1 - 6.

Rysunek 1. Program VBO - punkty z obiektami buforowymi

background image

1. Obiekty buforowe

10

Rysunek 2. Program VBO - punkty z tablicami wierzchołków

1.11.1. Plik vbo.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 f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
#i n c l u d e <GL/ g l x . h>
#d e f i n e

w g l G e t P r o c A d d r e s s

glXGetProcAddressARB

#e n d i f
#i n c l u d e
< s t d l i b . h>
#i n c l u d e < s t 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 i m e . h>
#i n c l u d e

” c o l o r s . h ”

//

w s k a ź n i k

na

f u n k c j ę

g l G e n B u f f e r s

PFNGLGENBUFFERSPROC g l G e n B u f f e r s = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l B i n d B u f f e r

background image

1. Obiekty buforowe

11

Rysunek 3. Program VBO - odcinki z obiektami buforowymi

PFNGLBINDBUFFERPROC g l B i n d B u f f e r = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l B u f f e r D a t a

PFNGLBUFFERDATAPROC g l B u f f e r D a t a = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l M a p B u f f e r

PFNGLMAPBUFFERPROC g l M a p B u f f e r = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l U n m a p B u f f e r

PFNGLUNMAPBUFFERPROC g l U n m a p B u f f e r = NULL ;

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

//

r o d z a j

t e s t u

POINTS VBO ,

//

p u n k t y

z VBO

POINTS VA ,

//

p u n k t y

z

t a b l i c a m i

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

LINES VBO ,

//

o d c i n k i

z VBO

LINES VA ,

//

o d c i n k i

z

t a b l i c a m i

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

TRIANGLES VBO,

//

t r ó j k ą t y

z VBO

TRIANGLES VA ,

//

t r ó j k ą t y

z

t a b l i c a m i

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

background image

1. Obiekty buforowe

12

Rysunek 4. Program VBO - odcinki z tablicami wierzchołków

//

o b s z a r

r e n d e r i n g u

FULL WINDOW,

//

a s p e k t

o b r a z u c a ł e

o k n o

ASPECT 1 1 ,

//

a s p e k t

o b r a z u

1 : 1

EXIT

//

w y j ś c i e

} ;

//

a s p e k t

o b r a z u

i n t

a s p e c t = FULL WINDOW ;

//

u s u n i ę c i e

d e f i n i c j i

makr

n e a r

i

f a r

#i f d e f

n e a r

#undef

n e a r

#e n d i f
#i f d e f

f a r

#undef

f a r

#e n d i f

//

r o z m i a r y

b r y ł y

o b c i n a n i a

const GLdouble

l e f t = − 2 . 0 ;

const GLdouble

r i g h t = 2 . 0 ;

const GLdouble bottom = − 2 . 0 ;
const GLdouble

t o p = 2 . 0 ;

background image

1. Obiekty buforowe

13

Rysunek 5. Program VBO - trójkąty z obiektami buforowymi

const GLdouble

n e a r = 3 . 0 ;

const GLdouble

f a r = 7 . 0 ;

//

r o d z a j

t e s t u d o m y ś l n i e

p u n k t y

z

t a b l i c a m i

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

i n t

t e s t = POINTS VA ;

//

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

o b i e k t ó w

b u f o r o w y c h

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

GLuint

v b o i d

[ 2 ] ;

//

i l o ś ć

g e n e r o w a n y c h

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

p r y m i t y w ó w

const

i n t

s i z e = 9 0 0 0 0 ;

//

w s p ó ł r z ę d n e

p r y m i t y w ó w

G L f l o a t

v e r t e x x y z

[ 3 ∗ s i z e ] ;

//

k o l o r y

p r y m i t y w ó w

G L f l o a t

c o l o r r g b

[ 3 ∗ s i z e ] ;

//

l i c z n i k

ramek

( FPS )

i n t

f r a m e s = 0 ;

background image

1. Obiekty buforowe

14

Rysunek 6. Program VBO - trójkąty z tablicami wierzchołków

//

l i c z n i k

c z a s u

long

s t a r t t i m e = 0 ;

//

t a b l i c a

z n a k ó w

z e

w a r t o ś c i ą

FPS

char

t i m e s t r i n g

[ 1 0 0 ] = ”FPS : ” ;

//

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 S c e n e

( )

{

background image

1. Obiekty buforowe

15

//

l i c z n i k

c z a s u

i f

( ! f r a m e s ++)

s t a r t t i m e = c l o c k

( ) ;

//

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

//

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 k o n a n i e

w y b r a n e g o

t e s t u

switch

( t e s t )

{

//

p r y m i t y w y w VBO

c a s e POINTS VBO :
c a s e LINES VBO :
c a s e TRIANGLES VBO :

//

d o w i ą z a n i e

p i e r w s z e g o

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL ARRAY BUFFER, v b o i d [ 0 ] ) ;

//

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

d a n y c h

t a b l i c y

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

g l V e r t e x P o i n t e r

( 3 , GL FLOAT , 0 , 0 ) ;

//

d o w i ą z a n i e

d r u g i e g o

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL ARRAY BUFFER, v b o i d [ 1 ] ) ;

//

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

d a n y c h

t a b l i c y

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

g l C o l o r P o i n t e r

( 3 , GL FLOAT , 0 , 0 ) ;

//

w ł ą c z e n i e

t a b l i c

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

g l E n a b l e C l i e n t S t a t e

(GL VERTEX ARRAY ) ;

g l E n a b l e C l i e n t S t a t e

(GL COLOR ARRAY ) ;

//

n a r y s o w a n i e

d a n y c h

z a w a r t y c h w

t a b l i c a c h

i f

( t e s t == POINTS VBO)

g l D r a w A r r a y s

( GL POINTS , 0 , s i z e ) ;

e l s e

i f

( t e s t == LINES VBO )

g l D r a w A r r a y s

( GL LINES , 0 , s i z e ) ;

e l s e

g l D r a w A r r a y s

( GL TRIANGLES , 0 , s i z e ) ;

//

w y ł ą c z e n i e

t a b l i c

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

g l D i s a b l e C l i e n t S t a t e

(GL COLOR ARRAY ) ;

g l D i s a b l e C l i e n t S t a t e

(GL VERTEX ARRAY ) ;

//

w y ł ą c z e n i e

d o w i ą z a n i a

o b i e k t ó w

b u f o r o w y c h

g l B i n d B u f f e r

(GL ARRAY BUFFER , 0 ) ;

break ;

//

p r y m i t y w y

z

t a b l i c a m i

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

c a s e POINTS VA :
c a s e LINES VA :
c a s e TRIANGLES VA :

//

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

d a n y c h

t a b l i c

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

g l V e r t e x P o i n t e r

( 3 , GL FLOAT, 0 , v e r t e x x y z ) ;

g l C o l o r P o i n t e r

( 3 , GL FLOAT, 0 , c o l o r r g b ) ;

//

w ł ą c z e n i e

t a b l i c

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

g l E n a b l e C l i e n t S t a t e

(GL VERTEX ARRAY ) ;

g l E n a b l e C l i e n t S t a t e

(GL COLOR ARRAY ) ;

//

n a r y s o w a n i e

d a n y c h

z a w a r t y c h w

t a b l i c a c h

i f

( t e s t == POINTS VA )

g l D r a w A r r a y s

( GL POINTS , 0 , s i z e ) ;

e l s e

background image

1. Obiekty buforowe

16

i f

( t e s t == LINES VA )

g l D r a w A r r a y s

( GL LINES , 0 , s i z e ) ;

e l s e

g l D r a w A r r a y s

( GL TRIANGLES , 0 , s i z e ) ;

//

w y ł ą c z e n i e

t a b l i c

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

g l D i s a b l e C l i e n t S t a t e

(GL VERTEX ARRAY ) ;

g l D i s a b l e C l i e n t S t a t e

(GL COLOR ARRAY ) ;

break ;

} ;

//

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

//

k o m u n i k a t

o

i l o ś c i

ramek

r y s o w a n y c h

na

s e k u n d ę

( FPS )

g l C o l o r 3 f v

( B l a c k ) ;

i f

( f r a m e s == 1 0 0 )

{

f r a m e s = 0 ;

s p r i n t f

( t i m e s t r i n g , ”FPS : %i ” , ( i n t ) ( 1 0 0 ∗ CLOCKS PER SEC / ( f l o a t ) ( c l o c k

() − s t a r t t i m e ) ) ) ;

}

//

n a r y s o w a n i e

n a p i s u

D r a w S t r i n g

( l e f t , bottom , t i m e s t r i n g ) ;

//

s k i e r o w a n i e

p o l e c e ń

do

w y k o n a n i a

g l F l u s h

( ) ;

//

z a m i a n a

b u f o r ó w

k o l o r u

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

}

//

z m i a n a

w i e l k o ś c i

o k n a

void

R esh ape

( i n t

width ,

i n t

h e i g h t )

{

//

o b s z a r

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

o k n o

g l V i e w p o r t

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

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

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

(GL PROJECTION ) ;

//

m a c i e r z

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

j e d n o s t k o w a

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

( ) ;

//

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

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

w y b ó r

r o d z a j u

t e s t u

c a s e POINTS VBO :
c a s e POINTS VA :
c a s e LINES VBO :
c a s e LINES VA :
c a s e TRIANGLES VBO :
c a s e TRIANGLES VA :

t e s t = v a l u e ;

background image

1. Obiekty buforowe

17

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

o b i e k t ó w

b u f o r o w y c h

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

void GenerateVBO

( )

{

//

o k r e ś l e n i e

z a r o d k a

d l a

c i ą g u

l i c z b

p s e u d o l o s o w y c h

s r a n d

( t i m e

(NULL ) ) ;

//

g e n e r o w a n i e

p o ł o ż e n i a

p u n k t ó w

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

f i g u r

o r a z

i c h

k o l o r ó w

f o r

( i n t

i = 0 ;

i < s i z e ;

i ++)

{

v e r t e x x y z

[ 3 ∗ i +0] = ( r a n d ( )

/

( f l o a t )RAND MAX)

∗ 4 − 2 ;

v e r t e x x y z

[ 3 ∗ i +1] = ( r a n d ( )

/

( f l o a t )RAND MAX)

∗ 4 − 2 ;

v e r t e x x y z

[ 3 ∗ i +2] = ( r a n d ( )

/

( f l o a t )RAND MAX)

∗ 4 − 2 ;

c o l o r r g b

[ 3 ∗ i +0] = ( r a n d ( )

/

( f l o a t )RAND MAX ) ;

c o l o r r g b

[ 3 ∗ i +1] = ( r a n d ( )

/

( f l o a t )RAND MAX ) ;

c o l o r r g b

[ 3 ∗ i +2] = ( r a n d ( )

/

( f l o a t )RAND MAX ) ;

}

//

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

d w ó c h

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

o b i e k t ó w

b u f o r o w y c h

g l G e n B u f f e r s

( 2 , v b o i d ) ;

//

d o w i ą z a n i e

p i e r w s z e g o

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL ARRAY BUFFER, v b o i d [ 0 ] ) ;

//

z a ł a d o w a n i e

d a n y c h

p i e r w s z e g o

o b i e k t u

b u f o r o w e g o

g l B u f f e r D a t a

(GL ARRAY BUFFER, s i z e o f

( G L f l o a t ) ∗ s i z e ∗ 3 , v e r t e x x y z , GL STATIC DRAW ) ;

//

d o w i ą z a n i e

d r u g i e g o

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL ARRAY BUFFER, v b o i d [ 1 ] ) ;

//

u t w o r z e n i e

d a n y c h

d r u g i e g o

o b i e k t u

b u f o r o w e g o

g l B u f f e r D a t a

(GL ARRAY BUFFER, s i z e o f

( G L f l o a t ) ∗ s i z e ∗ 3 ,NULL, GL STATIC DRAW ) ;

//

p o b r a n i e

w s k a ź n i k a

na

d a n e

d r u g i e g o

o b i e k t u

b u f o r o w e g o

GLvoid ∗ b u f = g l M a p B u f f e r

(GL ARRAY BUFFER, GL WRITE ONLY ) ;

//

s k o p i o w a n i e

d a n y c h

do

d r u g i e g o

o b i e k t u

b u f o r o w e g o

memcpy ( b u f , c o l o r r g b , s i z e o f

( G L f l o a t ) ∗ s i z e ∗ 3 ) ;

//

z w o l n i e n i e

w s k a ź n i k a

na

d a n e

d r u g i e g o

o b i e k t u

b u f o r o w e g o

i f

( g l U n m a p B u f f e r

(GL ARRAY BUFFER) == GL FALSE )

{

p r i n t f

( ” N i e p o p r a w n e

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

o b i e k t u

b u f o r o w e g o \n ” ) ;

e x i t

( 0 ) ;

}

//

w y ł ą c z e n i e

d o w i ą z a n i a

o b i e k t ó w

b u f o r o w y c h

g l B i n d B u f f e r

(GL ARRAY BUFFER , 0 ) ;

}

//

s p r a w d z e n i e

i

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

o b s ł u g i

w y b r a n y c h

r o z s z e r z e ń

void

E x t e n s i o n S e t u p

( )

{

//

p o b r a n i e

numeru

w e r s j i

b i b l i o t e k i

OpenGL

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

( GL VERSION ) ;

//

o d c z y t

w e r s j i

OpenGL

i n t

m a j o r = 0 ,

m i n o r = 0 ;

background image

1. Obiekty buforowe

18

i f

( s s c a n f

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

!=

2 )

{

#i f d e f WIN32

p r i n t f

( ” Błędny

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e l s e

p r i n t f

( ” B l e d n y

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e n d i f

e x i t

( 0 ) ;

}

//

s p r a w d z e n i e

c z y

j e s t

c o

n a j m n i e j

w e r s j a

1 . 5

i f

( m a j o r > 1

| |

m i n o r >= 5 )

{

//

p o b r a n i e

w s k a ź n i k a

w y b r a n y c h

f u n k c j i

OpenGL

1 . 5

g l G e n B u f f e r s = (PFNGLGENBUFFERSPROC) w g l G e t P r o c A d d r e s s

( ” g l G e n B u f f e r s ” ) ;

g l B i n d B u f f e r = (PFNGLBINDBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l B i n d B u f f e r ” ) ;

g l B u f f e r D a t a = (PFNGLBUFFERDATAPROC) w g l G e t P r o c A d d r e s s

( ” g l B u f f e r D a t a ” ) ;

g l M a p B u f f e r = (PFNGLMAPBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l M a p B u f f e r ” ) ;

g l U n m a p B u f f e r = (PFNGLUNMAPBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l U n m a p B u f f e r ” ) ;

}

e l s e

//

s p r a w d z e n i e

c z y

j e s t

o b s ł u g i w a n e

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

A R B v e r t e x b u f f e r o b j e c t

i f

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

( ” G L A R B v e r t e x b u f f e r o b j e c t ” ) )

{

//

p o b r a n i e

w s k a ź n i k a

w y b r a n y c h

f u n k c j i

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

A R B v e r t e x b u f f e r o b j e c t

g l G e n B u f f e r s = (PFNGLGENBUFFERSPROC) w g l G e t P r o c A d d r e s s

( ” g l G e n B u f f e r s A R B ” ) ;

g l B i n d B u f f e r = (PFNGLBINDBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l B i n d B u f f e r A R B ” ) ;

g l B u f f e r D a t a = (PFNGLBUFFERDATAPROC) w g l G e t P r o c A d d r e s s

( ” g l B u f f e r D a t a A R B ” ) ;

g l M a p B u f f e r = (PFNGLMAPBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” glMapBufferARB ” ) ;

g l U n m a p B u f f e r = (PFNGLUNMAPBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” glUnmapBufferARB ” ) ;

}

e l s e

{

p r i n t f

( ” Brak

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

A R B v e r t e x b u f f e r o b j e c t ! \ n ” ) ;

e x i t

( 0 ) ;

}

}

i n t

main ( i n t

a r g c ,

char ∗ a r g v [ ] )

{

//

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

b i b l i o t e k i

GLUT

g l u t I n i t

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

//

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

b u f o r a

r a m k i

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

(GLUT DOUBLE | GLUT RGB | GLUT DEPTH ) ;

//

r o z m i a r y

g ł ó w n e g o

o k n a

p r o g r a m u

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

( 5 0 0 , 5 0 0 ) ;

//

u t w o r z e n i e

g ł ó w n e g o

o k n a

p r o g r a m u

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

( ”VBO” ) ;

//

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

//

u t w o r z e n i e

podmenu T e s t

i n t

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

( Menu ) ;

#i f d e f WIN32

glutAddMenuEntry

( ” Punkty

z VBO” ,POINTS VBO ) ;

glutAddMenuEntry

( ” Punkty

z

t a b l i c a m i

w i e r z c h o ł k ó w ” , POINTS VA ) ;

glutAddMenuEntry

( ” O d c i n k i

z VBO” , LINES VBO ) ;

glutAddMenuEntry

( ” O d c i n k i

z

t a b l i c a m i

w i e r z c h o ł k ó w ” , LINES VA ) ;

glutAddMenuEntry

( ” T r ó j k ą t y

z VBO” ,TRIANGLES VBO ) ;

glutAddMenuEntry

( ” T r ó j k ą t y

z

t a b l i c a m i

w i e r z c h o ł k ó w ” ,TRIANGLES VA ) ;

#e l s e

glutAddMenuEntry

( ” Punkty

z VBO” ,POINTS VBO ) ;

glutAddMenuEntry

( ” Punkty

z

t a b l i c a m i

w i e r z c h o l k o w ” , POINTS VA ) ;

glutAddMenuEntry

( ” O d c i n k i

z VBO” , LINES VBO ) ;

glutAddMenuEntry

( ” O d c i n k i

z

t a b l i c a m i

w i e r z c h o l k o w ” , LINES VA ) ;

glutAddMenuEntry

( ” T r o j k a t y

z VBO” ,TRIANGLES VBO ) ;

glutAddMenuEntry

( ” T r o j k a t y

z

t a b l i c a m i

w i e r z c h o l k o w ” ,TRIANGLES VA ) ;

#e n d i f

background image

1. Obiekty buforowe

19

//

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

( ” T e s t ” , MenuTest ) ;

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

//

s p r a w d z e n i e

i

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

o b s ł u g i

w y b r a n y c h

r o z s z e r z e ń

E x t e n s i o n S e t u p

( ) ;

//

u t w o r z e n i e

o b i e k t ó w

b u f o r o w y c h

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

GenerateVBO

( ) ;

//

f u n k c j a

b e z c z y n n o ś c i

g l u t I d l e F u n c

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

//

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 przykładowy program (plik pbo.cpp) testuje obiekty buforowe

pikseli przy renderingu tekstur. Wyniki uzyskane na komputerze Autora nie
wskazują na przewagę szybkości w renderingu tekstur przy pomocy obiektów
buforowych, ale też nie odnotowano spadku tej szybkości. Prawdopodobnie
użycie większej ilości tekstur wykazałoby przewagę obiektów buforowych,
która ma bezpośredni związek z większą przepustowością pamięci karty gra-
ficznej w stosunku do przepustowości pamięci operacyjnej komputera.

Przykładowy efekt działania programu przedstawiono na rysunku 7.

1.11.2. Plik pbo.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 f n d e f WIN32
#d e f i n e GLX GLXEXT LEGACY
#i n c l u d e <GL/ g l x . h>
#d e f i n e

w g l G e t P r o c A d d r e s s

glXGetProcAddressARB

#e n d i f
#i n c l u d e
< s t d l i b . h>
#i n c l u d e < s t 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 i m e . h>
#i n c l u d e

” t a r g a . h ”

#i n c l u d e

” c o l o r s . h ”

background image

1. Obiekty buforowe

20

Rysunek 7. Program PBO - test wyświetlania tekstury „Lena”

//

w s k a ź n i k

na

f u n k c j ę

g l G e n B u f f e r s

PFNGLGENBUFFERSPROC g l G e n B u f f e r s = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l B i n d B u f f e r

PFNGLBINDBUFFERPROC g l B i n d B u f f e r = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l B u f f e r D a t a

PFNGLBUFFERDATAPROC g l B u f f e r D a t a = NULL ;

//

w s k a ź n i k

na

f u n k c j ę

g l G e t B u f f e r P a r a m e t e r i v

PFNGLGETBUFFERPARAMETERIVPROC g l G e t B u f f e r P a r a m e t e r i v = NULL ;

//

s t a ł e

do

o b s ł u g i

menu

p o d r ę c z n e g o

enum

{

TEST PBO ,

//

t e s t

z PBO

TEST WPBO,

//

t e s t

b e z PBO

EXIT

//

w y j ś c i e

} ;

background image

1. Obiekty buforowe

21

//

r o d z a j

t e s t u d o m y ś l n i e

p u n k t y

b e z PBO

i n t

t e s t = TEST WPBO ;

//

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

o b i e k t u

b u f o r o w e g o

p i k s e l i

GLuint

p b o i d ;

//

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

o b i e k t u

t e k s t u r y

GLuint

t e x t u r e i d ;

//

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

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

//

l i c z n i k

ramek

( FPS )

i n t

f r a m e s = 0 ;

//

l i c z n i k

c z a s u

long

s t a r t t i m e = 0 ;

//

t a b l i c a

z n a k ó w

z e

w a r t o ś c i ą

FPS

char

t i m e s t r i n g

[ 1 0 0 ] = ”FPS : ” ;

//

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 S c e n e

( )

{

//

l i c z n i k

c z a s u

i f

( ! f r a m e s ++)

s t a r t t i m e = c l o c k

( ) ;

//

w s p ó ł r z ę d n e

p o ł o ż e n i a

p r o s t o k ą t a

z

t e k s t u r ą

f l o a t

x = g l u t G e t

(GLUT WINDOW WIDTH)

∗ r a n d

( )

/

( f l o a t )RAND MAX;

f l o a t

y = 20 + g l u t G e t

(GLUT WINDOW HEIGHT)

∗ r a n d

( )

/

( f l o a t )RAND MAX;

//

w ł ą c z e n i e

t e k s t u r o w a n i a

2D

g l E n a b l e

(GL TEXTURE 2D ) ;

//

f i l t r

p o m n i e j s z a j ą c y

g l T e x P a r a m e t e r i

(GL TEXTURE 2D , GL TEXTURE MIN FILTER , GL NEAREST ) ;

//

f i l t r

p o w i ę k s z a j ą c y

g l T e x P a r a m e t e r i

(GL TEXTURE 2D , GL TEXTURE MAG FILTER , GL NEAREST ) ;

//

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

t e k s t u r y

z

d a n y c h

z

p a m i ę c i

o p e r a c y j n e j

i f

( t e s t == TEST WPBO)

{

//

t e k s t u r a

2D

glTexImage2D

(GL TEXTURE 2D , 0 , GL RGB, width , h e i g h t , 0 , f o r m a t , t y p e , p i x e l s ) ;

//

c z w o r o k ą t

g l C o l o r 3 f v

( White ) ;

g l B e g i n

(GL QUADS ) ;

g l T e x C o o r d 2 f

( 0 . 0 , 0 . 0 ) ;

g l V e r t e x 2 f

( x , y ) ;

g l T e x C o o r d 2 f

( 1 . 0 , 0 . 0 ) ;

g l V e r t e x 2 f

( x +64 , y ) ;

g l T e x C o o r d 2 f

( 1 . 0 , 1 . 0 ) ;

background image

1. Obiekty buforowe

22

g l V e r t e x 2 f

( x +64 , y + 6 4 ) ;

g l T e x C o o r d 2 f

( 0 . 0 , 1 . 0 ) ;

g l V e r t e x 2 f

( x , y + 6 4 ) ;

g l E n d

( ) ;

}

//

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

t e k s t u r y

z

d a n y c h

o b i e k t u

b u f o r o w e g o

p i k s e l i

i f

( t e s t == TEST PBO)

{

//

d o w i ą z a n i e

o b i e k t u

b u f o r o w e g o

p i k s e l i

g l B i n d B u f f e r

(GL PIXEL UNPACK BUFFER , p b o i d ) ;

//

t e k s t u r a

2D

glTexImage2D

(GL TEXTURE 2D , 0 , GL RGB, width , h e i g h t , 0 , f o r m a t , t y p e , NULL ) ;

//

c z w o r o k ą t

g l C o l o r 3 f v

( White ) ;

g l B e g i n

(GL QUADS ) ;

g l T e x C o o r d 2 f

( 0 . 0 , 0 . 0 ) ;

g l V e r t e x 2 f

( x , y ) ;

g l T e x C o o r d 2 f

( 1 . 0 , 0 . 0 ) ;

g l V e r t e x 2 f

( x +64 , y ) ;

g l T e x C o o r d 2 f

( 1 . 0 , 1 . 0 ) ;

g l V e r t e x 2 f

( x +64 , y + 6 4 ) ;

g l T e x C o o r d 2 f

( 0 . 0 , 1 . 0 ) ;

g l V e r t e x 2 f

( x , y + 6 4 ) ;

g l E n d

( ) ;

//

w y ł ą c z e n i e

o b i e k t u

b u f o r o w a n i a

p i k s e l i

p o p r z e z

//

d o w i ą z a n i e

o b i e k t u

o b i e k t u

o

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

0

g l B i n d B u f f e r

(GL PIXEL UNPACK BUFFER , 0 ) ;

}

//

w y ł ą c z e n i e

t e k s t u r o w a n i a

2D

g l D i s a b l e

(GL TEXTURE 2D ) ;

//

k o m u n i k a t

o

i l o ś c i

ramek

r y s o w a n y c h

na

s e k u n d ę

( FPS )

i f

( f r a m e s == 1 0 0 )

{

f r a m e s = 0 ;

s p r i n t f

( t i m e s t r i n g , ”FPS : %i ” , ( i n t ) ( 1 0 0 ∗ CLOCKS PER SEC / ( f l o a t ) ( c l o c k

() − s t a r t t i m e ) ) ) ;

}

//

z a m a z a n i e

p o p r z e d n i e g o

n a p i s u

g l C o l o r 3 f v

( White ) ;

g l R e c t f

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

//

n a r y s o w a n i e

n a p i s u

g l C o l o r 3 f v

( B l a c k ) ;

D r a w S t r i n g

( 1 , 2 , t i m e s t r i n g ) ;

//

s k i e r o w a n i e

p o l e c e ń

do

w y k o n a n i a

g l F l u s h

( ) ;

//

z a m i a n a

b u f o r ó w

k o l o r u

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

}

//

z m i a n a

w i e l k o ś c i

o k n a

void

R esh ape

( i n t

width ,

i n t

h e i g h t )

{

//

o b s z a r

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

o k n o

g l V i e w p o r t

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

//

w y b ó r

m a c i e r z y

r z u t o w a n i a

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

(GL PROJECTION ) ;

//

m a c i e r z

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

j e d n o s t k o w a

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

( ) ;

//

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

//

k o l o r

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

b u f o r a

k o l o r u

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

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

//

c z y s z c z e n i e

b u f o r a

k o l o r u

g l C l e a r

( GL COLOR BUFFER BIT ) ;

background image

1. Obiekty buforowe

23

//

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

menu

p o d r ę c z n e g o

void Menu ( i n t

v a l u e )

{

switch

( v a l u e )

{

//

w y b ó r

r o d z a j u

t e s t u

c a s e TEST PBO :
c a s e TEST WPBO :

t e s t = v a l u e ;
g l C l e a r

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

}

}

//

u t w o r z e n i e

o b i e k t ó w

b u f o r o w y c h

p i k s e l i

void GeneratePBO

( )

{

//

w y 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

o b i e k t u

b u f o r o w e g o

g l G e n B u f f e r s

( 1 , & p b o i d ) ;

//

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

//

d o w i ą z a n i e

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL PIXEL UNPACK BUFFER , p b o i d ) ;

//

o b l i c z e n i e

r o z m i a r u

b u f o r a

na

d a n e

GLint

s i z e = w i d t h ∗ h e i g h t ;

i f

( f o r m a t == GL BGRA)

s i z e

∗= 4 ;

e l s e

i f

( f o r m a t == GL BGR)

s i z e

∗=3;

//

z a ł a d o w a n i e

d a n y c h

o b i e k t u

b u f o r o w e g o

g l B u f f e r D a t a

(GL PIXEL UNPACK BUFFER , s i z e , p i x e l s , GL STREAM DRAW ) ;

//

p o b r a n i e

r o z m i a r u

d a n y c h

o b i e k t u

b u f o r o w e g o

GLint

b u f s i z e ;

g l G e t B u f f e r P a r a m e t e r i v

(GL PIXEL UNPACK BUFFER , GL BUFFER SIZE,& b u f s i z e ) ;

//

s p r a w d z e n i e

p o p r a w n o ś c i

r o z m i a r u

d a n y c h

o b i e k t u

b u f o r o w e g o

i f

( b u f s i z e

!=

s i z e )

{

p r i n t f

( ” Niepoprawny

z a p i s

danych do

o b i e k t u

b u f o r o w e g o \n ” ) ;

e x i t

( 0 ) ;

}

//

w y ł ą c z e n i e

d o w i ą z a n i a

o b i e k t u

b u f o r o w e g o

g l B i n d B u f f e r

(GL PIXEL UNPACK BUFFER , 0 ) ;

//

o k r e ś l e n i e

z a r o d k a

d l a

c i ą g u

l i c z b

p s e u d o l o s o w y c h

s r a n d

( t i m e

(NULL ) ) ;

}

//

s p r a w d z e n i e

i

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

o b s ł u g i

w y b r a n y c h

r o z s z e r z e ń

void

E x t e n s i o n S e t u p

( )

{

//

p o b r a n i e

numeru

w e r s j i

b i b l i o t e k i

OpenGL

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

( GL VERSION ) ;

//

o d c z y t

w e r s j i

OpenGL

i n t

m a j o r = 0 ,

m i n o r = 0 ;

i f

( s s c a n f

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

!=

2 )

{

#i f d e f WIN32

p r i n t f

( ” Błędny

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e l s e

background image

1. Obiekty buforowe

24

p r i n t f

( ” B l e d n y

f o r m a t

w e r s j i

OpenGL\n ” ) ;

#e n d i f

e x i t

( 0 ) ;

}

//

s p r a w d z e n i e

c z y

j e s t

c o

n a j m n i e j

w e r s j a

2 . 1

i f

( 1 0 ∗ m a j o r + m i n o r >= 2 1 )

{

//

p o b r a n i e

w s k a ź n i k a

w y b r a n y c h

f u n k c j i

OpenGL

2 . 1

( a

w ł a ś c i w i e

1 . 5 )

g l G e n B u f f e r s = (PFNGLGENBUFFERSPROC) w g l G e t P r o c A d d r e s s

( ” g l G e n B u f f e r s ” ) ;

g l B i n d B u f f e r = (PFNGLBINDBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l B i n d B u f f e r ” ) ;

g l B u f f e r D a t a = (PFNGLBUFFERDATAPROC) w g l G e t P r o c A d d r e s s

( ” g l B u f f e r D a t a ” ) ;

g l G e t B u f f e r P a r a m e t e r i v = (PFNGLGETBUFFERPARAMETERIVPROC)

w g l G e t P r o c A d d r e s s

( ” g l G e t B u f f e r P a r a m e t e r i v ” ) ;

}

e l s e

//

s p r a w d z e n i e

c z y

j e s t

o b s ł u g i w a n e

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

A R B p i x e l b u f f e r o b j e c t

i f

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

( ” G L A R B p i x e l b u f f e r o b j e c t ” ) )

{

//

p o b r a n i e

w s k a ź n i k a

w y b r a n y c h

f u n k c j i

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

A R B p i x e l b u f f e r o b j e c t

// a

w ł a c i w i e

A R B v e r t e x b u f f e r o b j e c t

g l G e n B u f f e r s = (PFNGLGENBUFFERSPROC) w g l G e t P r o c A d d r e s s

( ” g l G e n B u f f e r s A R B ” ) ;

g l B i n d B u f f e r = (PFNGLBINDBUFFERPROC) w g l G e t P r o c A d d r e s s

( ” g l B i n d B u f f e r A R B ” ) ;

g l B u f f e r D a t a = (PFNGLBUFFERDATAPROC) w g l G e t P r o c A d d r e s s

( ” g l B u f f e r D a t a A R B ” ) ;

g l G e t B u f f e r P a r a m e t e r i v = (PFNGLGETBUFFERPARAMETERIVPROC)

w g l G e t P r o c A d d r e s s

( ” g l G e t B u f f e r P a r a m e t e r i v A R B ” ) ;

}

e l s e

{

p r i n t f

( ” Brak

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

A R B v e r t e x b u f f e r o b j e c t ! \ n ” ) ;

e x i t

( 0 ) ;

}

}

//

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

}

}

i n t

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

//

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

( ”PBO” ) ;

//

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

background image

1. Obiekty buforowe

25

//

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

// 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

( ” T e s t

z PBO” ,TEST PBO ) ;

glutAddMenuEntry

( ” T e s t

b e z PBO” ,TEST WPBO ) ;

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

//

s p r a w d z e n i e

i

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

o b s ł u g i

w y b r a n y c h

r o z s z e r z e ń

E x t e n s i o n S e t u p

( ) ;

//

u t w o r z e n i e

o b i e k t ó w

b u f o r o w y c h

p i k s e l i

GeneratePBO

( ) ;

//

f u n k c j a

b e z c z y n n o ś c i

g l u t I d l e F u n c

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

//

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

26

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/

,

http://www.opengl.org/registry/


Document Outline


Wyszukiwarka

Podobne podstrony:
opengl elementarne obiekty geometryczne
opengl selekcja obiektow
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
Obiekty Graficzne w PowerPoint
Metodyka Obiektowa pojęcia podstawowe

więcej podobnych podstron