01 opengl 3 2 wprowadzenie

background image

OpenGL 3.2

Wprowadzenie

Janusz Ganczarski

www.januszg.hg.pl

background image

Wstęp

W tym odcinku kursu poznamy niezbędne wiadomości wstępne dotyczące historii oraz

podstaw budowy i działania biblioteki OpenGL. Czytelnik znajdzie tutaj także uzasadnienie do
konwencji przyjętej w dalszej części kursu.

Historia OpenGL

Specyfikacja pierwszej wersji biblioteki OpenGL (ang. Open Graphics Library) została

opublikowana 1 czerwca 1992 roku na bazie języka GL opracowanego przez firmę Silicon Graphics
Inc. (SGI) na potrzeby stacji graficznych IRIS. Początkiem sukcesu OpenGL stała się jednak dopiero
wersja 1.1, opublikowana 4 marca 1997 roku, którą zaimplementowano m.in. w systemach z rodziny
Microsoft Windows. Kolejne wersje biblioteki (1.2, 1.3, 1.4, 1.5, 2.0, 2.1, 3.0 i najnowsza 3.1 z 24
marca 2009 roku) są znakomitą ilustracją rozwoju sprzętu graficznego i tendencji w programowym
generowaniu grafiki.

Przez tych kilkadziesiąt lat jedną z głównych idei twórców OpenGL była zgodnośd wstecz

biblioteki. W praktyce programy przygotowane dla wcześniejszych wersji biblioteki działały
prawidłowo także na jej najnowszych implementacjach. Drugą zasadą OpenGL jest jej
wieloplatformowośd – programy z niej korzystające działają praktycznie na wszystkich współczesnych
systemach operacyjnych. Cechy te są miarą sukcesu OpenGL, która jest obecnie podstawową
niskopoziomową biblioteką graficzną 3D, standardem powszechnie wykorzystywanym przez
producentów oprogramowania użytkowego i gier.

Od początku rozwojem OpenGL zajmowała się ARB (ang. Architecture Review Board), w skład

której wchodzili przedstawiciele najważniejszych firm z branży komputerowej. Taki sposób
wprowadzania zmian w bibliotece zapewnia OpenGL zachowanie niezależności od jednej platformy
sprzętowej lub programowej przy jednoczesnym uwzględnieniu najnowszych osiągnięd w dziedzinie
grafiki komputerowej. Oczywiście współpraca wielu firm, o często sprzecznych interesach, nie zawsze
przebiegała idealnie. Producenci sprzętu graficznego promowali własne rozwiązania,
niekompatybilne z rozwiązaniami konkurencji, a spory wewnątrz ARB powodowały opóźnienia w
przygotowywaniu nowych wersji specyfikacji.

Od 2006 roku rolę opiekuna OpenGL przejął Khronos Group, który rozwija także inne otwarte

standardy programistyczne. Początkowo krytykowany za opóźnienia, Khronos Group w drugiej
połowie 2008 roku wprowadził specyfikację wersji 3.0 i krótko po tym opublikowane zostały kolejne
wersje OpenGL oznaczone numerami 3.1 i 3.2. Ewolucję OpenGL zaproponowaną przez Khronos
Group opiszemy nieco dalej, z kilkuletniej perspektywy wydaje się jednak, że zmiana ta wywarła
pozytywny wpływ na tempo i kierunek rozwoju biblioteki.

Rozszerzenia

Jednym z najczęściej dyskutowanych mechanizmów OpenGL są rozszerzenia. Rozszerzenia

określają dodatkowe możliwości implementacji biblioteki i mogą dotyczyd najróżnorodniejszych jej
elementów. Zaletą tego mechanizmu jest dostępnośd z poziomu OpenGL najnowszych możliwości
sprzętu graficznego, ale jest jednocześnie to także wada. Rozszerzenia proponowane przez niektóre
firmy nie były implementowane przez inne (czasami wynikało to jednak z braku możliwości
technicznych), co czyniło rozszerzenia mechanizmem niepewnym w zastosowaniach komercyjnych.
Mimo tych wad rozszerzenia na trwałe wpisały się w bibliotekę OpenGL i stanowią ważny mechanizm
wspomagający jej rozwój.

OpenGL 3.0 - rewolucja przez ewolucję

Wspomniana wcześniej wersja 3.0 biblioteki OpenGL zapoczątkowała zupełnie nowe

podejście do dotychczas obowiązujących zasad. Twórcy standardu zauważyli bowiem, że dalsze
utrzymywanie tak rozbudowanej i w znacznej części przestarzałej funkcjonalności nie znajduje
praktycznego uzasadnienie. Wyodrębniono liczną grupę tzw. funkcji przestarzałych, która została
wytypowana do usunięcia w przyszłych wersjach specyfikacji. Wskazuje to na generalną tendencję

background image

ewolucji OpenGL – stopniowe usuwanie przestarzałych jej elementów i zastępowanie ich
nowoczesnymi programowalnymi mechanizmami.

Kolejną nowością w bibliotece OpenGL 3.0 jest wymuszenie na twórcach systemów

okienkowych utworzenia funkcji obsługujących nowy kontekst renderingu. Związane jest to z
zupełnie nową w bibliotece OpenGL koncepcją profilowania kontekstów renderingu oraz
planowanym cyklem usuwania z biblioteki przestarzałych mechanizmów. W przyszłości planowane są
profile przeznaczone do rozrywki, tworzenia dokumentów i stron WWW, obsługi aplikacji
desktopowych, czy też dedykowane do urządzeo mobilnych. Warto zauważyd, że ARB zastrzegła
sobie wyłącznośd do tworzenia profili OpenGL. Sposób obsługi nowego kontekstu renderingu musi
umożliwiad aplikacji wskazanie konkretnego profilu niezbędnego do działania programu. Zauważmy,
że brak nowego kontekstu renderingu przy redukcji funkcjonalności OpenGL, mógłby doprowadzid w
przyszłości do błędów przy uruchamianiu starszych programów.

Początkowo wersja 3.0 OpenGL spotkała się z dośd chłodnym przyjęciem ze strony

środowiska programistycznego. Wśród głównych zarzutów pojawiały się tezy o braku pełnej
rezygnacji z przestarzałych funkcji oraz braku modelu obiektowego. Wszystko to było związane z
oczekiwaniami na zupełnie nowe API biblioteki. Całkiem słusznie niezadowolenie wzbudzało także
wielomiesięczne opóźnienie w prezentacji specyfikacji biblioteki.

Analiza decyzji Khronos Group wskazuje jednak, że podjęto bardzo racjonalne decyzje. Na

obecnym etapie rozwoju biblioteki nie była możliwa rezygnacja z całej jej dotychczasowej
funkcjonalności. Zbyt dużo jest bowiem na rynku oprogramowania z tego korzystającego – w grę
wchodzą chodby niezwykle skomplikowane aplikacje inżynierskie i naukowe. Wprowadzenie nowego
kontekstu renderingu, mechanizmu profili oraz redukcji funkcjonalności ułatwi stopniowe
przechodzenie do przyszłych wersji biblioteki.

OpenGL 3.1 – dalszy etap rewolucji przez ewolucję

Kolejna odsłona biblioteki OpenGL pojawiła się bardzo szybko (oczywiście w porównaniu do

poprzednich standardów w tym zakresie) i stanowi kolejny istotny krok w jej rozwoju. Zdecydowano
się na usunięcie wszystkich funkcji określonych w wersji 3.0 jako przestarzałe, chod pozostawiono
jeszcze dodatkową furtkę w postaci rozszerzenia GL_ARB_compatibility, które zawiera wszystkie
usunięte funkcje. Dzięki temu API stał się znacznie mniejsze, co widad chodby po objętości
specyfikacji. Pełna jej wersja obejmująca opis funkcji przestarzałych to blisko 500 stron, a właściwa
zajmuje nieco ponad 350 stron.

Usunięcie przestarzałej funkcjonalności znaczne uprościło bibliotekę i jednocześnie ułatwiło

jej stosowanie. Jednak z ułatwieo tych w pełni skorzystają jedynie twórcy nowych aplikacji, którzy od
początku zdecydują się korzystanie wyłącznie z nowoczesnych rozwiązao oferowanych przez OpenGL
3.0/3.1.

OpenGL 3.2 – szybka ewolucja

OpenGL 3.2 to kolejny etap rewolucji przez ewolucję. Specyfikacja została opublikowana

nieco ponad cztery miesiące po upublicznieniu wersji 3.1 i wnosi szereg nowych możliwości do
biblioteki, w tym . Jedną z bardziej praktycznych zmian jest zdefiniowanie dwóch profili:
podstawowego, obejmującego tylko nieusuniętą funkcjonalnośd i kompatybilnego, zgodnego ze
wszystkim poprzednimi wersjami OpenGL. Nie zmieniono przy tym praktycznie funkcjonalności
określonych jako przestarzałe, co wskazuje na pewną stabilizację w dalszym kierunku rozwoju
biblioteki.

OpenGL w wersji 3.2 bez rozszerzeo można w pełni porównywad z aktualnym jej

odpowiednikiem, tj. biblioteką DirectX 10.0, a wraz z zaaprobowanymi przez ARB rozszerzeniami:
GL_ARB_draw_buffers_blend,

GL_ARB_sample_shading,

GL_ARB_texture_cube_map_array,

GL_ARB_texture_gather i GL_ARB_texture_query_lod z biblioteką DirectX w wersji 10.1.

background image

GLSL

Język programów cieniowania OpenGL GLSL (ang. OpenGL Shading Language), zwanymi

najczęściej shaderami, został wprowadzony w wersji 2.0 biblioteki, a od wersji 3.1 stanowi
podstawowy element potoku renderingu zarówno na etapie przetwarzania wierzchołków jaki
fragmentów. Sam język GLSL sukcesywnie ewoluował wraz z kolejnymi wersjami OpenGL. Aktualnie
jego najnowszą wersją jest 1.50, która odpowiada możliwościom tzw. Shader Model 4.1 języka HLSL z
biblioteki DirectX 10.1. Dodajmy jeszcze, że wersja 3.1 OpenGL obsługuje shadery GLSL w wersji 1.30 i
1.40, a wersja 3.2 shadery w wersji 1.40 i 1.50.

Język GLSL jest opisany w odrębnej specyfikacji, która tworzy spójną całośd ze specyfikacją

podstawowego API biblioteki OpenGL.

Powiązania z systemami okienkowymi

Biblioteka OpenGL wymaga wsparcia API systemu okienkowego do tworzenia i zarządzania

kontekstami graficznymi, renderingu w oknie oraz obsługi innych zasobów. Wszystkie liczące się
współczesne systemy operacyjne posiadają API obsługujące bibliotekę OpenGL. W systemie X
Window, dostępnym głownie pod Unix i Linux, jest to GLX. Warto także wspomnied, że
implementacje GLX istnieją również w systemach Microsoft Windows, MacOS X i kilku innych
platformach, na których jest dostępny X Serwer. OpenGL w systemach Microsoft Windows
obsługiwany jest przez WGL. Quartz, warstwa graficzna systemu MacOS X, zawiera kilka interfejsów
API obsługujących OpenGL. Są to CGL, AGL i NSGLView.

Oczywiście stosowanie rozwiązao specyficznych dla danego systemu operacyjnego powoduje,

że danego programu nie można skompilowad i uruchomid w innym systemie operacyjnym bez
dokonania szeregu zmian w kodzie źródłowym. Rozwiązanie tego problemu stanowią biblioteki
oferujące jeden, niezależny od systemu operacyjnego, interfejs do obsługi okien i komunikatów.
Pierwszą biblioteką tego typu była biblioteka AUX (ang. Auxiliary Library), jednak bodaj największą
popularnośd zdobyła biblioteka GLUT (ang. OpenGL Utility Toolkit), opracowana i rozwijana w latach
1994-1998 przez Marka J. Kilgarda. Pomimo sędziwego wieku jest ona ciągle powszechnie stosowana.

Typy danych

Typy danych w obsługiwane przez bibliotekę OpenGL przedstawia Tabela 1. Specyfikacja nie

określa jakiego rodzaju typy danych są użyte w konkretnej implementacji, zawiera jedynie minimalne
wymagania związane z precyzją i wykonywaniem operacji na całkowitych i zmiennoprzecinkowych
typach danych. W szczególności implementacja może używad typów danych o większej ilości bitów
niż minimalne wskazane we wspomnianej wyżej tabeli. Typy GLintptr, GLsizeiptr i GLsync
mają ilośd bitów opisaną jako prtbits, co oznacza minimalną ilośd bitów niezbędną w danej
implementacji do umieszczenia wskaźnika. Typy te muszą umożliwid zapamiętanie dowolnego
adresu. Trzeba także wyraźnie podkreślid, że typy danych OpenGL nie są typami danych
występującymi w języku C (pomimo częściowej zgodności nazw). Tak więc, na przykład, typ GLint
niekoniecznie jest równoznaczny z typem int w C. Ponadto, poza wymienionymi typami funkcje
OpenGL korzystają z typu pustego GLvoid.

Typ GL

Minimalna ilość
bitów

Opis

GLboolean

1

typ logiczny

GLbyte

8

liczba całkowita ze znakiem w kodzie uzupełnieo do 2

GLubyte

8

liczba całkowita bez znaku

GLchar

8

znaki tworzące ciągi

GLshort

16

liczba całkowita ze znakiem w kodzie uzupełnieo do 2

GLushort

16

liczba całkowita bez znaku

GLint

32

liczba całkowita ze znakiem w kodzie uzupełnieo do 2

background image

GLuint

32

liczba całkowita bez znaku

GLint64

64

liczba całkowita ze znakiem w kodzie uzupełnieo do 2

GLuint64

64

liczba całkowita bez znaku

GLsizei

32

nieujemna liczba całkowita

GLenum

32

typ wyliczeniowy

GLintptr

ptrbits

liczba całkowita ze znakiem w kodzie uzupełnieo do 2

GLsizeiptr

ptrbits

nieujemna liczba całkowita

GLsync

ptrbits

uchwyt obiektu synchronizacji

GLbitfield

32

pole bitowe

GLhalf

16

liczba zmiennoprzecinkowa połówkowej precyzji zakodowana
jako skalar bez znaku

GLfloat

32

liczba zmiennoprzecinkowa

GLclampf

32

liczba zmiennoprzecinkowa ograniczona do przedziału

GLdouble

64

liczba zmiennoprzecinkowa podwójnej precyzji

GLclampd

64

liczba zmiennoprzecinkowa podwójnej precyzji ograniczona
do przedziału

Tabela 1 Typy danych w bibliotece OpenGL

Składnia poleceń

Polecenia OpenGL są funkcjami lub procedurami. Różne grupy poleceo wykonują tę samą

operację, lecz różnią się sposobem w jaki dostarczane są do nich argumenty. Ogólnie rzecz biorąc,
deklaracja polecenia posiada formę:

rtype Name{1|2|3|4}{b|s|i|i64|f|d|ub|us|ui}{v}( [args ,] T arg1, … ,
T argN [, args] );

Polecenia OpenGL są zbudowane z nazwy, po której następuje, w zależności od konkretnego

przypadku, maksymalnie do 4 znaków. rtype jest typem zwracanym przez funkcję. Nawiasy {}
dołączają szereg znaków (lub zestawów znaków), z których tylko jeden jest używany. Pierwszy znak
{1|2|3|4} oznacza liczbę wartości wskazanego typu, które muszą byd przedstawione do
polecenia. Drugi znak lub zestaw znaków {b|s|i|i64|f|d|ub|us|ui} wskazuje konkretne
rodzaje argumentów: 8-bitowe liczby całkowite, 16-bitowe liczby całkowite, 32-bitowe liczby
całkowite, 64-bitowe liczby całkowite, liczby zmiennoprzecinkowe pojedynczej precyzji lub liczby
zmiennoprzecinkowe podwójnej precyzji – patrz Tabela 2. Zauważmy, że wskazując na typ bez znaku
dodajemy literę u na początku tego nazwy typu (na przykład unsigned byte jest skracany do
ubyte). Ostatni znak {v}, jeśli jest obecny, wskazuje, że polecenie zawiera wskaźnik do tablicy
(wektora) wartości, a nie serię poszczególnych argumentów.

Litera Odpowiadający typ GL

b

GLbyte

s

GLshort

i

GLint

i64

GLint64

f

GLfloat

d

GLdouble

ub GLubyte
us GLushort
ui GLuint

Tabela 2 Powiązanie sufiksów poleceo GL z typami argumentów. Patrz Tabela 1 z definicjami typów GL

background image

Argumenty poleceo umieszczone w nawiasach [args ,] i [, args] mogą, ale nie muszą

byd obecne. N argumentów od arg1 do argN ma typ T, który odpowiada jednemu ze znaków lub
parze znaków wskazanych w Tabela 2. Jeśli ostatnim znakiem nie jest v, to N jest podane przez znaki

{1|2|3|4}

(jeśli ich nie ma, to liczba argumentów jest ustalona). Jeśli ostatnim znakiem jest v, to

tylko arg1 jest obecny i jest to tablica N wartości wskazanego typu. Argumenty, których typ jest
stały (tzn. nie wskazany przez sufiks polecenia) są jednym z typów danych OpenGL zawartych w
Tabela 1 lub wskaźnikami do jednego z tych typów.

Przykładowo grupa funkcji glUniform* w specyfikacji OpenGL jest opisywana następująco:


void Uniform{1234}{if}( int location, T value );

co wskazuje osiem deklaracji funkcji, przedstawionych poniżej w notacji ANSI C:

void Uniform1i( int location, int value );
void Uniform1f( int location, float value );
void Uniform2i( int location, int v0, int v1 );
void Uniform2f( int location, float v0, float v1 );
void Uniform3i( int location, int v0, int v1, int v2 );
void Uniform3f( int location, float v0, float v2, float v2 );
void Uniform4i( int location, int v0, int v1, int v2, int v3 );
void Uniform4f( int location, float v0, float v1, float v2,
float v3 );

W dalszej części kursu będziemy używad pełnych deklaracji funkcji w języku ANSI C, jednak

prezentacja zasad budowy poleceo OpenGL ułatwi Czytelnikowi samodzielne zgłębianie specyfikacji
biblioteki.

Zmienne stanu

Zmienne stanu (ang. state) są ważnym wewnętrznym elementem OpenGL opisującym

ustawienia biblioteki. Wiele zmiennych stanu jest dwustanowych, inne mają wartości całkowite lub
zmiennoprzecinkowe. Wszystkie zmienne stanu tworzą tzw. maszynę stanów (ang. state machine),
która steruje zachowaniem OpenGL.

Wyróżniamy dwa rodzaje zmiennych stanu. Pierwszy typ, zwany zmiennymi serwera GL,

znajduje się w serwerze GL. Większośd zmiennych stanu GL wchodzi w skład tej kategorii. Drugi typ,
zwany zmiennymi klienta GL, znajduje się w kliencie GL. W typowym przypadku klientem jest
aplikacja wykorzystująca polecenia OpenGL, a serwerem aktualnie używana implementacja biblioteki
(np. w sterowniku karty graficznej). Każdy egzemplarz kontekstu OpenGL zawiera jeden pełny zestaw
zmiennych stanu serwera GL. Natomiast każde połączenie od klienta do serwera zawiera odrębny
zbiór zmiennych stanu zarówno klienta jak i serwera OpenGL.

Zmienne stanu modyfikowane są, w sposób jawny lub nie, przez polecenia biblioteki OpenGL,

które będziemy poznawad w dalszych odcinkach kursu. Natomiast do odczytu zmiennych stanu służy
bardzo liczna grupa funkcji glGet*, z których najbardziej podstawowe są następujące funkcje:

void glGetBooleanv( GLenum pname, GLboolean *params );
void glGetIntegerv( GLenum pname, GLint *params );
void glGetInteger64v( GLenum pname, GLint64 *params );
void glGetFloatv( GLenum pname, GLfloat *params );
void glGetDoublev( GLenum pname, GLdouble *params );

Parametr pname określa, którą wartośd maszyny stanów OpenGL chcemy pobrad (wszystkie

zmienne stanu przedstawiamy w odrębnym odcinku kursu), a params wskaźnik na zwracaną

background image

wartośd. W zależności od rodzaju pobieranej zmiennej tablica params może zawierad pojedynczą
zmienną lub tablicę zmiennych. Program musi zapewnid odpowiednią ilośd miejsca w pamięci.
Zauważmy, że rodzaj zwracanej lub zwracanych wartości jednoznacznie określa koocowa częśd nazwy
funkcji.

Obsługa błędów

Biblioteka OpenGL zawiera mechanizmy obsługi błędów. Jednak z założenia wykrywanych

jest tylko częśd sytuacji spośród zbioru warunków, które mogłyby byd uważane za błędy. Stanowi to
kompromis na rzecz efektywności, ponieważ w wielu przypadkach kontrola błędów miałby
niekorzystny wpływ na wydajnośd programu wolnego od błędów.

Informację o kodzie bieżącego błędu zwraca funkcja:


GLenum glGetError( void );

Zestawienie zwracanych kodów błędów zawiera Tabela 3. Działanie OpenGL jest

niezdefiniowane tylko w przypadku wystąpienia błędu o kodzie GL_OUT_OF_MEMORY. W
pozostałych przypadkach błąd nie powoduje przerwania wykonywania programu, nie jest
wykonywana jedynie funkcja odpowiedzialna za jego powstanie. Polecenie takie na ma wpływu na
stan OpenGL lub zawartośd bufora ramki. Jeśli polecenie generujące błąd zwraca wartości, zwracana
jest wartośd zero. Jeśli polecenie generujące błąd zmienia wartości poprzez wskaźnik do argumentu,
nie są dokonywane zmiany tych wartości.

Kod błędu

Opis

Czy błędne polecenie
jest ignorowane?

GL_INVALID_ENUM

Argument GLenum
poza zakresem

Tak

GL_INVALID_VALUE

Argument liczbowy
poza zakresem

Tak

GL_INVALID_OPERATION

Nielegalna operacja w
bieżącym stanie

Tak

GL_INVALID_FRAMEBUFFER_OPERATION Niekompletny obiekt

bufora ramki

Tak

GL_OUT_OF_MEMORY

Brak pamięci do
wykonania polecenia

Nieokreślone

GL_NO_ERROR

Brak błędu

-

Tabela 3 Zestawienie kodów błędów OpenGL

Kiedy błąd zostanie wykryty, ustawiana jest flaga błędu i rejestrowany jest jego kod. Jeżeli

występują kolejne błędy nie wpływają one na ten zarejestrowany kod. Dopiero, gdy wywołana jest
funkcja glGetError, zwracany jest kod błędu i czyszczona jest flaga, tak aby kolejny błąd mógł byd
zarejestrowany. Jeżeli glGetError zwraca GL_NO_ERROR oznacza to, że od ostatniego
wywołania glGetError (lub od kiedy GL został zainicjowany) nie był wykryty żaden błąd.
Implementacja może przechowywad więcej niż jedną informację o błędzie. W takim przypadku
wywołanie glGetError zwraca kody kolejnych zarejestrowanych błędów, tak długo aż nie zostanie
zwrócona wartośd GL_NO_ERROR.

Typowy kod odczytujący błędy zgłaszane przez bibliotekę OpenGL ma postad poniższej pętli:


GLenum error;
while( ( error = glGetError() ) != GL_NO_ERROR )
{
// obsługa błędu

background image

}

Ogólne warunki generowania błędów przedstawione są poniżej:

Jeśli polecenie wymagające wartości wyliczeniowej określonej jako stała symboliczna
otrzymuje wartośd, która nie należy do dopuszczalnych dla tego polecenia, generowany jest
błąd GL_INVALID_ENUM.

Jeśli przekazywana jest ujemna liczba, a typ argumentu jest określony jako GLsizei lub
GLsizeiptr, zostanie wygenerowany błąd GL_INVALID_VALUE.

Jeśli ubocznym efektem wykonania polecenia jest wyczerpanie pamięci, może byd
wygenerowany błąd GL_OUT_OF_MEMORY.

W innych wypadkach, błędy generowane są tylko na warunkach, które są wyraźnie opisane w
specyfikacji biblioteki OpenGL.

Operacje OpenGL i potok renderingu

OpenGL koncentruje się jedynie na renderingu do bufora ramki oraz czytaniu wartości

zapisanych w tym buforze. Biblioteka nie ma wsparcia dla innych urządzeo, takich jak myszy i
klawiatury, stąd trzeba używad innych mechanizmów w celu przetworzenia informacji
wprowadzanych przez użytkownika.

Rysunek 1 przedstawia schemat działania OpenGL. Z lewej strony diagramu wprowadzane są

polecenia OpenGL. Niektóre z nich określają obiekty geometryczne, które mają zostad narysowane,
inne kontrolują obsługę obiektów przez różne etapy renderingu. Polecenia zawsze są przetwarzane w
kolejności, w jakiej zostały przekazane do OpenGL, a ewentualne opóźnienie realizacji skutków
danego polecenia nie mogą mied wpływu na wyniki późniejszych poleceo. To samo dotyczy operacji
pobierania zmiennych stanu zapytania i odczytu pikseli, które zwracają stan odpowiadający
kompletnemu wykonaniu wszystkich wcześniej wywoływanych poleceo OpenGL (poza przypadkami
wyraźnie określonymi w specyfikacji). OpenGL wiąże dane w chwili wywoływania polecenia, a
wszelkie późniejsze zmiany danych nie mają wpływu na jego wynik.

Rysunek 1 Diagram blokowy potoku renderingu OpenGL (źródło: specyfikacja OpenGL)

Pierwszy etap potoku renderingu operuje na prymitywach geometrycznych: punktach,

segmentach linii i wielokątach, które są opisane przez wierzchołki. W tym etapie wierzchołki są
przekształcane i oświetlane, a prymitywy są obcinane do bryły widoku w celu przygotowania do
następnego etapu, rasteryzacji. Możliwe jest także programowe generowanie nowych prymitywów
lub usuwanie istniejących. Rasteryzator generuje szereg fragmentów - elementów bufora ramki
używanych do dwuwymiarowego opisu punktów, segmentów linii lub wielokątów. Każdy tak
wyprodukowany fragment jest przekazywany do następnego etapu, gdzie wykonywane są operacje
na poszczególnych fragmentach przed finalnym zapisem w buforze ramki. Operacje na buforze ramki

background image

obejmują m.in. obsługę wartości bufora głębokości, mieszanie kolorów oraz maskowanie i inne
operacje logiczne na wartościach fragmentów. Dane bufora ramki mogą byd również odczytywane
lub kopiowane pomiędzy różnymi częściami bufora ramki.

Poszczególne etapy potoku renderingu OpenGL poznamy bliżej w kolejnych odcinkach kursu.

Podstawowa zasada OpenGL - powtarzalność

Specyfikacja biblioteki OpenGL opisuje poszczególne operacje realizowane przez OpenGL, nie

zakłada jednak i nie zapewnia zgodności na poziomie pikseli pomiędzy różnymi jej implementacjami.
Poniżej krótko przedstawimy podstawową zasadę implementacji OpenGL – powtarzalnośd.

Powtarzalnośd jest rozumiana jako identycznośd zawartości bufora ramki przy takich samych

poleceniach i początkowych wartościach zmiennych stanu. Jest to szczególnie istotne przy typowych
w OpenGL technikach podwójnego buforowania i algorytmach wieloprzebiegowych, bowiem przy
braku powtarzalności każdy z tworzonych obrazów mógłby różnid się tworząc widoczne artefakty.
Powtarzalnośd ma także dalej idące znaczenie, przykładowo dwie sceny różniące się tylko niewielkim
przesunięciem wielokąta oczywiście nie będą identycznie wyrenderowane, ale zakładamy zgodnośd
tych fragmentów sceny, które nie obejmują pierwotnego i przesuniętego wielokąta. Oto podstawowe
zasady powtarzalności:

1. Dla danego kontekstu renderingu i zmiennych stanu bufora ramki dowolne polecenie

OpenGL da taki sam efekt koocowy w buforze ramki i wartościach zmiennych stanu.

2. Zmiany zawartości bufora ramki, buforów koloru do zapisu, parametrów testu nożycowego,

masek zapisu składowych oraz wartości czyszczących bufory nie mogą mied wpływów
ubocznych na inne zmienne stanu.

3. Specyfikacja zaleca także, aby zmiany parametrów bufora szablonowego, testu głębokości,

mieszania kolorów, operacji logicznych na pikselach, zapisu pikseli oraz przesuwania wartości
głębokości wielokątów nie miały wpływu ubocznego na inne zmienne stanu.

4. Generowanie fragmentu jest niezmienne w stosunku do zasad wymienionych w zasadzie 2 i

3.

5. Arytmetyka operacji na fragmentach jest niezmienna za wyjątkiem parametrów

bezpośrednio je kontrolujących.

6. Obrazy generowane w różnych buforach koloru współdzielących ten sam bufor ramki,

używające równocześnie lub oddzielnie tej samej sekwencji poleceo są identyczne na
poziomie pikseli.

7. Identyczny shader wierzchołków lub fragmentów (czyli zgodny na poziomie kodu

źródłowego) wykonywany wielokrotnie dla takich samych danych wejściowych i wartościach
zmiennych stanu generuje ten sam wynik.

8. Wszystkie shadery fragmentów, które warunkowo lub bezwarunkowo przypisują

gl_FragCoord.z do gl_FragDepth są niezmienne w zakresie wartości głębokości w
odniesieniu do każdego innego shadera, dla tych fragmentów, gdzie przypisanie do
gl_FragDepth zostało zrealizowane.

Chod powyższe zasady określone są dla implementatorów OpenGL warto o nich pamiętad i

wykorzystywad także w trakcie opracowywania programów. Częśd zasad odnosi się do szczegółów, z
którymi będziemy się bliżej zapoznawad w kolejnych odcinkach niniejszego kursu.

Przyjęte w kursie konwencje i zasady

Programy w kursie zasadniczo wymagają dostępności biblioteki OpenGL w wersji 3.2, ale w

wielu przypadkach wystarczy dostępnośd wersji 3.1 lub 3.0. Przy ich pisaniu wykorzystano nowe
funkcje zarządzające kontekstem OpenGL, co powoduje, że programy nie mogą byd bezpośrednio
uruchamiane na starszych niż 3.0 wersjach biblioteki. Jednakże częśd z nich, po odpowiednich
modyfikacjach, może działad z OpenGL 2.0/2.1. Programy przykładowe przy tworzeniu okien
korzystają bezpośrednio z Xlib (systemu UNIX i Linux) oraz API WIN32 (systemy Microsoft Windows).

background image

Fragmenty programu specyficzne dla danego systemu operacyjnego są oddzielone od elementów
korzystających z biblioteki OpenGL, co ułatwi Czytelnikowi ewentualną migrację programu na
wybraną platformę systemową lub programową.

Wszystkie programy napisane są przy użyciu języka C++ i kompilowane za pomocą

kompilatorów: Microsoft Visual C++ 2008 EE, Turbo C++ 2006 Explorer oraz kompilatora GCC 4.4 w
systemie Linux Mandriva 2010. Programy testowano na karcie graficznej NVidia GeForce 8600GT.

Do kompilacji programów nie są wymagane żadne dodatkowe zewnętrzne biblioteki. Jednak

najczęściej używane funkcje zostały pogrupowane w odrębne pliki, które mogą stanowią przydatną
podręczną bibliotekę.


Document Outline


Wyszukiwarka

Podobne podstrony:
01 opengl 4 2 wprowadzenie
01 opengl wprowadzenie 2011id 2873 pptx
01 Gramatyka wprowadzenie
01 CalkaNieozn Wprowadzenieid 3058
01 NoZ wprowadzenie
01 html wprowadzenie
01 Algorytmy wprowadzenieid 2595 ppt
01 xml wprowadzenie
01-CalkaNieozn-Wprowadzenie
MEBS 01 Metody wprowadzenie
01 OT wprowadzenie
01 PKON wprowadzenie
01 Gramatyka wprowadzenie
01 CalkaNieozn Wprowadzenieid 3058
01 Algorytmy wprowadzenieid 2595 ppt

więcej podobnych podstron