Wprowadzenie do grafiki
komputerowej
Podstawy OpenGL
Podstawy OpenGL
Najkrótsza charakterystyka OpenGL
Przenośna biblioteka graficzna API
(Application Programming Interface).
Niezależna od sprzętu, ale wykorzystująca
akcelerację sprzętową), pośredniego poziomu.
realizuje grafikę 2D/3D z elementami niższego
poziomu
zasadniczo zapewnia wyjście jedynie na ekran
monitora
stanowi podstawę dla bibliotek i pakietów
narzędziowych wysokiego poziomu (np. Open
Inventor i innych)
W roku 1995 Microsoft wprowadził
bibliotekę Direct3D – głównego konkurenta
OpenGL.
OpenGL jako narzędzie do renderowania
Tworzy elementarne obiekty geometryczne
(primitives)
punkty, linie, wielokąty
Wykonuje operacje na obrazach rastrowych
Renderuje sceny zależnie od stanu
Kolory, materiały, źródła światła, etc.
Najkrótsza historia OpenGL
Utworzona z biblioteki IRIS GL (Graphics Library) –
SGI, z 1982.
Od 1992 rozwijana przez Architecture Review
Board (ARB) już jako OpenGL (wersja 1.0 została
ogłoszona w czerwcu 1992). Kluczowi uczestnicy
ARB: SGI, DEC, IBM, Intel, Microsoft.
W kolejnych latach ogłaszane są oficjalne wersje:
1.1, 1.2, 1.2.1, 1.3, 1.4, 1.5. Wersja 2.0 ogłoszona
w 2004 włączyła oficjalnie język shaderów
(OpenGL Shading Language, GLSL).
Wersja 2.1 kończy serię bibliotek kompatybilnych
wstecz. W dalszym ciągu może być i jest używana.
Najkrótsza historia OpenGL, c.d.
Od września 2006 nadzór na rozwojem OpenGL
sprawuje Khronos Group.
W sierpniu 2008 ogłoszono OpenGL 3.0,
kompatybilny z wcześniejszymi wersjami, ale
zapowiadający usuwanie starszych rozwiązań w
kolejnych wersjach. Realizuje wersję 1.30 GLSL.
W marcu 2009 – OpenGL 3.1 + GLSL 1.40.
W sierpniu 2009 – OpenGL 3.2 + GLSL 1.50.
W marcu 2010 – OpenGL 3.3 i 4.0
W lipcu 2010 – OpenGL 4.1
W tej chwili bieżącymi wersjami są OpenGL 3.3 i
4.1
Na czym polega przełom pomiędzy wersją
2.1, a późniejszymi?
Wersje =< 2.1 pozwalały na ukrycie karty
graficznej przed użytkownikiem
W wersji 2.1 można jawnie programować kartę
graficzną za pomocą GLSL (jawnie korzystać z
shaderów), można jednak korzystać jedynie z
mechanizmów OpenGL.
W wersji 3.3 istnieje tryb tradycyjny
(Compatibility Mode) i tryb nowy (Core Mode)
pozwalający na efektywne wykorzystanie
procesorów graficznych.
W wersji 3.3 (Core Mode) jawne korzystanie z
shaderów jest konieczne.
Podsumowanie
Przygotowując program w OpenGL, w
rzeczywistości przygotowujemy DWA
programy:
pierwszy, opisany przy pomocy funkcji OpenGL
realizowany na CPU (przygotowuje scenę, buduje
obiekty)
drugi opisany przez język shaderów GLSL,
realizowany na GPU (dokonuje przekształceń
obiektów i renderowania)
Potok renderowania; model klient-serwer
Client – kod pracujący na CPU
Server – kod pracujący na GPU
Różne linki do tutoriali
Swiftless Tutorials: www.swiftless.com
Z czego składa się OpenGL?
Z biblioteki właściwej GL;
Nazwy funkcji zaczynają się od gl (np. glClearColor).
W wersji 2.1 mamy 249 funkcji.
W wersji 3.3 - 199 funkcji.
Z pomocniczej biblioteki narzędziowej
W wersji 2.1 – Biblioteka GLU (OpenGL Utilities)
W wersji 3.3 …no właśnie … wszystko jest w trakcie
tworzenia …
My będziemy raczej korzystać z biblioteki GLTools związanej
z podręcznikiem OpenGL SuperBible.
Przykłady, m.in.
http://www.starstonesoftware.com/OpenGL/
Pożyteczne książki
Podstawy OpenGL
•
R.S.Wright, et al.. OpenGL-Superbible, 5th edition,
Addison-Wesley, 2010
•
Randi J. Rost, OpenGL Shading Language, 3rd edition,
2009
•
T. Akenine-Moller, Real-time rendering, 3rd edition, 2009
•
M. Bailey i S. Cunnigham, Graphics shaders, A.K.
Peters, 2009
•
M.Woo, J.Neider, T.Davies, OpenGL – Programming
Guide, Addison-Wesley, 7th edition, 2010 (wersja
elektroniczna, np. fly.srk.fer.hr/~unreal/theredbook/
www.opengl.org/documentation/red_book_1.0)
Pożyteczne linki
• www.nopper.tv
• strona Janusza Ganczarskiego januszg.hg.pl
• znany tutorial nehe.gamedev.net
• strona podstawowa OpenGL, www.opengl.org
Na początek – GLUT (a właściwie
FreeGLUT)
Podstawy OpenGL
Na następnych slajdach przedstawione są krótko
wybrane funkcje GLUT (daleko nie wszystkie).
Pełny opis w dokumentacji Marka Kilgarda (autora
biblioteki).
www.opengl.org/documentation/....
Również jest dostępna na
gd.tuwien.ac.at/graphics/GLUT/glut3.html
freeGLUT - bieżąca wersja: 2.6 z marca 2010
Omówienie niektórych funkcji GLUT
GLUT – inicjowanie biblioteki
Podstawy OpenGL
void glutInit(int *argcp, char **argv)
Zainicjowanie biblioteki GLUT.
Ta funkcja zawsze jest wywoływana na początku.
Może zakończyć się błędem, gdy np. system nie obsługuje OpenGL
W ogólności przekazuje parametry umieszczone w linii
wywołania programu, ale tylko w X Windows została
zaimplementowana interpretacja kilku parametrów.
GLUT – inicjowanie okna
Podstawy OpenGL
void glutInitWindowPosition(int x, int y);
void glutInitWindowSize(int x, int y);
Zgodnie z nazwą, funkcje określają:
• początkowe położenie okna – x, y są
współrzędnymi lewego górnego rogu;
• początkowy rozmiar okna, domyślnie 300x300
pikseli
x, y są współrzędnymi ekranowymi wyrażonymi w
pikselach od lewego górnego rogu ekranu.
GLUT - inicjowanie trybu
wyświetlania w oknie
Podstawy OpenGL
void glutInitDisplayMode(GLbitfield mode);
void glutInitDisplayMode(unsigned long int mode);
mode jest bitową sumą poszczególnych masek bitowych
(zapisanych
symbolicznie):
GLUT_RGBA, GLUT_INDEX
GLUT_SINGLE, GLUT_DOUBLE
pojedynczy lub podwójny bufor
ekranu
GLUT_DEPTH
aktywny bufor głębokości
GLUT_ACCUM
aktywny bufor akumulacji
GLUT_ALPHA
GLUT_STENCIL
GLUT_STEREO
GLUT – obsługa okien
Otwarcie okna graficznego
Podstawy OpenGL
void glutCreateWindow(char *name)
Otwarcie okna na ekranie; name jest łańcuchem
znaków wpisanym w górnej belce okna.
Wybrane funkcje obsługi zdarzeń
Podstawy OpenGL
void glutDisplayFunc(void(*func)(void))
void glutReshapeFunc(void(*func)(int w, int h))
void glutKeyboardFunc(void(*func)
(unsigned char key, int x, int y))
Wybrane funkcje obsługi zdarzeń
Podstawy OpenGL
void glutSpecialFunc(void(*func)
(unsigned char key, int x, int y))
Oznaczenia kluczy:
GLUT_KEY_*
GLUT_KEY_F1,...,GLUT_KEY_F12
GLUT_KEY_LEFT, GLUT_KEY_UP, GLUT_KEY_RIGHT,
GLUT_KEY_DOWN
GLUT_KEY_PAGE_UP, GLUT_KEY_PAGE_DOWN
GLUT_KEY_HOME, GLUT_KEY_END, GLUT_KEY_INSERT
Wybrane funkcje obsługi zdarzeń
Podstawy OpenGL
void glutMouseFunc(void(*func)
(int button, int state,
int x, int y))
button:
GLUT_LEFT_BUTTON, GLUT_MIDDLE_BUTTON,
GLUT_RIGHT_BUTTON
state: GLUT_DOWN, GLUT_UP
void glutMotionFunc(void(*func)(int x, int y))
Wybrane funkcje obsługi zdarzeń
Podstawy OpenGL
void glutIdleFunc(void (*func)(void))
glutIdleFunc wprowadza nieprzerywalną pętlę.
Ew. przerwanie:
glutIdleFunc(NULL)
void glutPostRedisplay(void)
GLUT - Rysowanie gotowych brył; wygodne, ale
nie do wykorzystania w OpenGL 3.3
Podstawy OpenGL
void glutWireSphere(GLdouble radius, Glint slices, GLint stacks);
void glutSolidSphere(GLdouble radius, Glint slices, GLint stacks);
void glutWireCube(GLdouble size);
void glutWireTorus(GLdouble innerRadius, GLdouble outerRadius,
GLint nsides, GLint rings);
void glutWireIcosahedron(void);
void glutWireOctahedron(void);
void glutWireTetrahedron(void);
void glutWireDodecahedron(GLdouble radius);
void glutWireTeapot(GLdouble size);
Typy danych w OpenGL
Podstawy OpenGL
Suffix Data type
C type
OpenGL type
b
8-bit integer
signed char
GLbyte
s
16-bit integer
short
GLshort
i
32-bit integer
int/long
GLint, GLsizei
f
32-bit floating point float
GLfloat, GLclampf
d
64-bit floating point double
GLdouble, GLclampd
ub
8-bit unsigned integer
unsigned char
GLubyte, GLboolean
us
16-bit unsigned integer
unsigned short
GLushort
ui
32-bit unsigned integer
unsigned int/long
GLuint, GLenum, GLbitfield
OpenGL wprowadził własne typy danych w celu zapewnienia
przenośności programów. Używanie standardowych oczywiście
też jest dopuszczalne
Typy danych w OpenGL, cd
Podstawy OpenGL
Gdy spojrzymy na typy danych OpenGL,
odnajdujemy odpowiedniki z C/C++.
Z małymi wyjątkami.
GLclampf, GLclampd – to float i double obcięty do
[0,1]
Konwencje nazw funkcji
OpenGL w zasadzie nie dopuszcza przeładowania
funkcji.
W zamian za to wprowadzony jest system jedno- lub
dwuznakowych sufiksów; Maksymalnie można użyć
trzech:
pierwszy określa liczbę argumentów,
drugi (jeden lub dwa znaki) określa typ parametru
trzeci – jeśli występuje, pokazuje że podany jest adres do
argumentów
Od OpenGL 1.5 możliwe jest przeładowywanie funkcji
odwołujących się do buforów jako obiektów (wspomnimy
o tym później)
Konwencje nazw zmiennych stanu
biblioteki
Podstawy OpenGL
OpenGL zawiera ponad 250 parametrów
(zmiennych stanu) określających „stan maszyny
OpenGL” – środowisko tworzenia grafiki.
Parametry zapisywane symbolicznie dużymi
literami są poprzedzone przedrostkiem GL_,
np. GL_SMOOTH, GL_FLAT.
Analogiczne parametry (choć w mniejszej ilości)
dostarczone są do bibliotek GLT, GLUT.
Ich postać jest analogiczna, np. GLUT_RGBA
GLUT_SINGLE
Jeszcze o zmiennych stanu
Podstawy OpenGL
Zmienne stanu mogą być skalarami lub tablicami
zawierającymi maski bitowe lub wielkości typu
int, float, double.
Do ich ustawienia stosujemy raczej funkcje
OpenGL, niż bezpośrednie podstawienie wartości –
o tym będzie mowa później.
Możemy też pytać o bieżące ustawienia zmiennych
stanu.
Zmienne stanu mają na początku pewne sensowne
wartości domyślne, więc na ogół coś się na
ekranie narysuje (choć nie zawsze tak, jak tego
chcielibyśmy).
Ustawianie zmiennych stanu
O zmienne stanu, które są wartościami logicznymi
możemy zapytać funkcją:
void glEnable(GLenum opis);
void glDisable(GLenum opis);
np.
glEnable(GL_DEPTH_TEST);
Pytanie o binarne zmienne stanu
Podstawy OpenGL
O zmienne stanu, które są wartościami logicznymi
możemy zapytać funkcją:
GLboolean glIsEnabled(GLenum opis);
np. glIsEnabled(GL_DEPTH_TEST);
W odpowiedzi otrzymujemy GL_TRUE lub GL_FALSE
O inne zmienne pytamy przez glGet…()
Ogólne pytanie o zmienne stanu
OpenGL umożliwia również ogólne zapytanie o
zmienne stanu różnych typów:
void glGetBooleanv(GLenum pname, GLboolean* param);
void glGetDoublev(GLenum pname, GLdouble* param);
void glGetFloatv(GLenum pname, GLfloat* param);
void glGetIntegerv(GLenum pname, GLint* param);
pname jest nazwą zmiennej stanu; niestety trzeba znać
te nazwy. Można je znaleźć między innymi na stronie
http://www.opengl.org/sdk/docs/man/xhtml/glGet.xml
param zwraca wskaźnik do zmiennej zawierającej
wartość wybranej zmiennej stanu
Układ współrzędnych
Podstawy OpenGL
y
x
z
W OpenGL przyjęto
układ prawoskrętny.
(Przeciwstawiając się
wcześniejszej tradycji,
zgodnie z którą w grafice
komputerowej stosowano
raczej układ lewoskrętny)
Niektóre operacje wstępne
Podstawy OpenGL
Na następnym slajdzie...
Czyszczenie ekranu (lub ogólniej
buforów)
Podstawy OpenGL
void glClear(GLbitfield mask)
void glClear(unsigned long int mask)
Argument mask wskazuje, które bufory powinny
zostać wyczyszczone.
GL_COLOR_BUFFER_BIT
GL_DEPTH_BUFFER_BIT
GL_STENCIL_BUFFER_BIT
GL_ACCUM_BUFFER_BIT
Obecnie interesuje nas przede wszystkim postać
void glClear(GL_COLOR_BUFFER_BIT)
Czyszczenie ekranu różnymi
kolorami
Podstawy OpenGL
void glClear(GL_COLOR_BUFFER_BIT);
domyślnie czyści ekran kolorem czarnym (zeruje
bufor)
Możemy określić dowolny kolor funkcją:
void glClearColor(GLclampf red,
GLclampf green,
GLclampf blue,
GLclampf alpha);
Np.
void glClearColor(1.0f,1.0f,1.0f,1.0f);
Ustawienie bieżącego koloru do
rysowania
Podstawy OpenGL
Zajmujemy się wyłącznie trybem RGB/RGBA
Tryb pracy zazwyczaj jest taki:
ustaw_bieżący_kolor(red);
rysuj_obiekt(A);
rysuj_obiekt(B);
ustaw_bieżący_kolor(blue);
ustaw_bieżący_kolor(green);
rysuj_obiekt(C);
Samo rysowanie jest oderwane od koloru. Bieżący
kolor jest kontekstem ustawionym przez zmienne
stanu.
Ustawienie bieżącego koloru do
rysowania, glColor
Podstawy OpenGL
Już nieaktualne…
W GLTools stosujemy metody klasy GLshaderManager
np.
Glfloat vRed[]={1.0f, 0.0f, 0.0f, 1.0f};
shaderManager.UsesStockShader
(GLT_SHADER_IDENTITY, vRed);
Niektóre kolory RGB.
Tablice wierzchołków
Podstawą rysowania czegokolwiek jest
przygotowanie tablicy wierzchołków.
Tablica wierzchołków zawiera atrybuty
każdego z nich.
Podstawowe atrybuty to:
współrzędne położenia
barwa
kierunek wektora normalnego
współrzędne tekstury nakładanej
Wierzchołki są przekazywane do bufora jako
obiekt (VBO) i przetwarzane przez vertex
shader (my na początek ukrywamy to
wykorzystując GLTools)
Rysowanie podstawowych elementów
(prymitywów) w GLTools
Przygotowujemy tablicę wierzchołków.
Wykorzystujemy klasę GLBatch, np
GLBatch triangleBatch;
Używamy standardowej sekwencji:
triangleBatch.Begin(GL_TRIANGLES, nvert);
triangleBatch.CopyVertexData3f(tabvert);
triangleBatch.End();
Glfloat vRed[]={1.0f, 0.0f, 0.0f, 1.0f};
shaderManager.UsesStockShader
(GLT_SHADER_IDENTITY, vRed);
trianglebatch.Draw(0);
Do wyboru z listy
na
następnym slajdzie
Tryby rysowania prymitywów
Podstawy OpenGL
Triangle strip
Podstawy OpenGL
–
trójkąt 0 -> v0, v1, v2
–
trójkąt 1 -> v2, v1, v3 (czemu nie v1, v2,
v3?)
–
trójkąt 2 -> v2, v3, v4
–
trójka 3 -> v4, v3, v5 (nie v3, v4, v5)
v
0
v
1
v
5
v
0
v
1
v
5
v
0
v
1
v
5
v
5
v
5
v0
v1
v2
v3
v4
Koniec wstępu
Podstawy OpenGL