22. října 2013, Brno Připravil: David Procházka Knihovna GLUT Počítačová grafika 2
Obsah přednášky Strana 2 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Obsah přednášky Strana 3 / 38 Obsah přednášky Dnes se podíváme na základní funkce, které knihovna GLUT poskytuje pro práci se vstupními zařízeními a pro vykreslování objektů. Zastaralý přístup Řada zmiňovaných nástrojů je v OpenGL od verze 3 nedoporučována. Jedná se zejména o nástroje okolo vykreslování objektů. Tyto nástroje je vhodné nahradit např. Vertex Buffer Objects, které jsou vysvětleny dále.
Obsah přednášky Strana 4 / 38 OpenGL Utility Toolkit Původní knihovna GLUT je již řadu let nevyvíjena. Lze ji nahradit knihovnou OpenGLUT. GLUT poskytuje následující funkcionalitu: 1 správu oken (ukázáno na úvodní přednášce), 2 základní podporu pro menu (nebude probráno 1 ), 3 funkce pro událostně řízené programování klávesnice, myši, časovače, atp. (částečně již ukázáno) 4 základní funkce pro generování grafických objektů, 5 funkce pro práci s bitmapami a fonty. 1 viz tutoriály od P. Tišnovského na http://www.root.cz/serialy/ tvorba-prenositelnych-grafickych-aplikaci-vyuzivajicich-knihovnu-glut/ a jinde
Obsah přednášky Strana 5 / 38 Překlad aplikace využívající GLUT Pro používání knihovny GLUT potřebujete udělat pod Windows následující kroky: 1 Soubor glut.h nakopírovat do [cesta]\mingw\include\gl. 2 Soubor libglut32.a nakopírovat do [cesta]\mingw\lib. 3 Soubor glut32.dll do adresáře c:\windows\system32 (pro 32b systémy) nebo c:\windows\syswow64, nouzově stačí do adresáře s projektem. (pro 64b systémy). Nyní nastavíme překlad: 1 V nastavení linkeru nechejte připojit opengl32, glu32 a glut32. 2 Ujistěte se, že překladač zná cestu ke složkám include a lib.
Inicializace aplikace Strana 6 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Inicializace aplikace Strana 7 / 38 Inicializace aplikace Inicializace aplikace void glutinit(int *argcp, char *argv[]) Inicializuje GLUT a zajistí komunikaci s OS. Zpracuje parametry předané z příkazového řádku. Režim aplikace void glutinitdisplaymode(unsigned int m) m je seznam příznaků pro inicializaci okna. 1 int main(int argc, char** argv){ 2 glutinit(&argc, argv); 3 glutinitdisplaymode (GLUT_SINGLE GLUT_RGBA); 4...
Inicializace aplikace Strana 8 / 38 Nastavení okna Nastavení velikosti okna void glutinitwindowsize(int width,int height) kde width a height jsou šířka a výška okna aplikace v pixelech. Nastavení umístění okna void glutinitwindowposition(int x, int y) x a y jsou vzdálenosti od levého horního rohu obrazovky, resp. předchozího okna. 1 int main(int argc, char** argv){ 2 glutinit(&argc, argv); 3 glutinitdisplaymode (GLUT_SINGLE GLUT_RGBA); 4 glutinitwindowsize (640, 480); 5 glutinitwindowposition (100, 100);
Inicializace aplikace Strana 9 / 38 Parametry pro inicializaci GLUT RGBA/GLUT RGB RGBA mód okna (doporučeno), GLUT INDEX režim indexovaných barev (zastaralé), GLUT ALPHA okno s alfa komponentou (definujeme už prvním bodem), GLUT SINGLE používá se jeden framebuffer (pro jednoduché aplikace OK), GLUT DOUBLE prohazování dvou bufferů pro lepší výkon, GLUT ACCUM aktivuje se práce s akumulačním bufferem, GLUT DEPTH práce s bufferem hloubky, GLUT STENCIL práce se stencil bufferem, GLUT STEREO okno se dvěma samostatnými buffery pro stereo zobrazování.
Inicializace aplikace Strana 10 / 38 Pokročilá správa oken Vytvoření okna int glutcreatewindow(char *name) vrátí jedinečný identifikátor pro přepínání. Vytvoření podokna v okně id int glutcreatesubwindow(int id, int x, int y, int w, int h) kde x, y jsou relativní pozice a w h velikosti. Nastavení aktivního okna void glutsetwindow(int id) Získání ID aktivního okna int glutgetwindow(void)
Inicializace aplikace Strana 11 / 38 Změny velikosti a pozice okna Změna pozice aktuálního okna void glutpositionwindow(int x, int y) Změna velikosti aktuálního okna void glutreshapewindow(int w, int h) Zapnutí celoobrazovkového režimu void glutfullscreen(void)
Inicializace aplikace Strana 12 / 38 Double a Quad Buffering V režimu GLUT DOUBLE jsou používány dva buffery. Jeden je zobrazován a do druhého je připravován následující snímek. Při překreslení je voláno glutswapbuffers(), které je prohodí. Při stereo zobrazení režim GLUT STEREO jsou používány obvykle 4 buffery (pro každý výstup 2). Grafická karta musí Quad Buffering podporovat (např. NVIDIA Quadro).
Inicializace aplikace Strana 13 / 38 Stereo zobrazení: změna bufferu Změna vykreslovacího bufferu void gldrawbuffer(glenum mode) mode je GL LEFT, GL RIGHT, GL FRONT LEFT, GL FRONT RIGHT, GL BACK LEFT, GL BACK RIGHT, GL FRONT, GL BACK, GL FRONT AND BACK, GL NONE, GL AUXi Obraz pro levé oko je v levém zadním bufferu. Obraz pro pravé oko je v pravém zadním bufferu. Existuje řada nastavení pěkně popsáno na: http://www.orthostereo.com/geometryopengl.html
Inicializace aplikace Strana 14 / 38 Stereo zobrazení: základní myšlenka
Inicializace aplikace Strana 15 / 38 Stereo zobrazení: levé oko 1 // nastaveni leveho oka 2 gldrawbuffer(gl_back_left); 3 glmatrixmode(gl_modelview); 4 glloadidentity(); 5 6 glulookat( 7 -IOD/2, 0.0, 0.0, 8 0.0, 0.0, screenz, 9 0.0, 1.0, 0.0); 10 11 glpushmatrix(); 12 gltranslatef(0.0, 0.0, depthz); 13 drawscene(); 14 glpopmatrix();
Inicializace aplikace Strana 16 / 38 Stereo zobrazení: pravé oko 1 // nastaveni praveho oka 2 gldrawbuffer(gl_back_right); 3 glmatrixmode(gl_modelview); 4 glloadidentity(); 5 6 glulookat( 7 IOD/2, 0.0, 0.0, 8 0.0, 0.0, screenz, 9 0.0, 1.0, 0.0); 10 11 glpushmatrix(); 12 gltranslatef(0.0, 0.0, depthz); 13 drawscene(); 14 glpopmatrix(); 15 16 glutswapbuffers();
Zpracování událostí Strana 17 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Zpracování událostí Strana 18 / 38 Události zobrazení Překreslení aktuálního okna void glutdisplayfunc(void (*func)(void)) Funkce zaregistrována tímto příkazem je volána při překreslení okna. Změna velikosti aktuálního okna void glutreshapefunc(void (*func)(int w,int h)) Zaregistrovaná funkce je zavolána když je změněna velkost okna. Nová velikost je předána ve w (width) a h (height). 1 void display(void){ 2... 3 } 4 int main(int argc, char** argv){ 5 glutdisplayfunc(display); 6...
Zpracování událostí Strana 19 / 38 Události klávesnice Stisk klávesy void glutkeyboardfunc(void (*funct)(unsigned char key,int x, int y)) kde key je stisknutá klávesa a x, y pozice kurzoru myši Stisk speciální klávesy void glutspecialfunc(void (*foo)(int key, int x, int y)) kde key nabývá hodnot: GLUT KEY F1,...,GLUT KEY F12, GLUT KEY {LEFT RIGHT UP DOWN}, GLUT KEY PAGE {UP DOWN}, GLUT KEY {HOME END INSERT} a a ESC==27
Zpracování událostí Strana 20 / 38 Události klávesnice: příklad 1 void onkeyboard(unsigned char key, int x, int y){ 2 switch(key){ 3 case r : g_red=1.0; break; 4 case g : g_green=1.0; break; 5 case b : blue=1.0; break; 6 case q : exit(0); 7 } 8 glutpostredisplay(); // vyvolej prekresleni okna 9 } 10 11 void onspecialkeyboard(int key, int x, int y){ 12 switch(key){ 13 case GLUT_KEY_UP: mycar.y++; break; 14 case GLUT_KEY_DOWN: mycar.y--; break; 15 case GLUT_KEY_LEFT: mycar.x--; break; 16 case GLUT_KEY_RIGHT: mycar.x--; break; 17...
Zpracování událostí Strana 21 / 38 Události myši Stisk tlačítka myši void glutmousefunc(void (*funct)(int button, int state,int x,int y)) kde button nabývá hodnot GLUT LEFT BUTTON, GLUT MIDDLE BUTTON, GLUT RIGHT BUTTON a state hodnot GLUT UP, GLUT DOWN. Vstup myši do okna void glutentryfunc(void (*foo)(int state)) kde state nabývá hodnot GLUT ENTERED nebo GLUT LEFT podle toho zda kurzor do okna vstoupil nebo jej pustil.
Zpracování událostí Strana 22 / 38 Události myši: příklad 1 void onmouseclick(int button,int state,int x,int y) 2 { // at je zmacknuto kterekoliv tlacitko... 3 if (state==glut_down) { 4 experimentalcube ->enablerotation(); 5 experimentalcube ->setmotionlast(x,y); 6 } else { 7 experimentalcube ->disablerotation(); 8 } 9 glutpostredisplay(); // prekresli okno 10 } 11 12 int main(int argc, char** argv) 13 { 14... 15 glutmousefunc(onmouseclick); 16...
Zpracování událostí Strana 23 / 38 Události myši (pokračování) Pohyb myší při stisknutém tlačítku void glutmotionfunc(void (*funct)(int x, int y)) kde x a y jsou aktuální souřadnice kurzoru. Pohyb myší při nestisknutém tlačítku void glutpassivemotionfunc(void (*funct)(int x, int y)) kde x a y jsou aktuální souřadnice kurzoru.
Zpracování událostí Strana 24 / 38 Události myši (pokračování): příklad 1 void onmouseactivemotion(int x, int y) { 2 g_cursorx = x; 3 g_cursory = y; 4 glutpostredisplay(); 5 } 6 7 int main(int argc, char** argv) 8 { 9... 10 glutmotionfunc(onmouseactivemotion); 11...
Časovač Strana 25 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Časovač Strana 26 / 38 Tvorba animací Časovač Timer void gluttimerfunc(unsigned int msecs, void (*func)(int value), int value) kde msecs je počet milisekund do zavolání funkce v druhém parametru a value je hodnota předávaná do zaregistrované funkce. Funkce je zavolána pouze jednou. Musíme ji pak znovu zaregistrovat. Hodnova value je používána pro vnitřní komunikaci mezi voláními časovače.
Časovač Strana 27 / 38 Tvorba animací: příklad 1 /* ve funkci prekresleni bude provedeno 2 posunuti objektu a jejich vykresleni */ 3 void ontimer(int state) { 4 // provedu prekresleni 5 glutpostredisplay(); 6 // znovu zavolam timer 7 gluttimerfunc(30, ontimer, 0); 8 } 9 10 int main(int argc, char** argv) 11 { 12... 13 gluttimerfunc(0, ontimer, 0); 14 glutmainloop(); 15 return 0; 16 }
Vykreslování grafických objektů Strana 28 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Vykreslování grafických objektů Strana 29 / 38 Vykreslování graf. objektů pomocí GLUT Každý objekt má dvě varianty: těleso s povrchem (solid) a drátěný model (wire): 1 koule (sphere), 2 krychle (cube), 3 kužel (cone), 4 anuloid (torus), 5 osmistěn (octahedron), 6 dvanáctistěn (dodecahedron), 7 dvacetistěn (icosahedron), 8 čajník (teapot). GLUT generuje normálové vektory pro nasvícení objektů. Negenerují se souřadnice pro texturování. Využívá čistě OpenGL funcí, knihovny AUX.
Vykreslování grafických objektů Strana 30 / 38 Koule a krychle Koule void glutwiresphere(gldouble radius, GLint slices, GLint stacks) kde slices představují počet vrcholů v horizontálním řezu a stacks jemnost řezů ve vertikálním směru. Krychle void glutsolidcube(gldouble size) kde sice je velikost strany.
Vykreslování grafických objektů Strana 31 / 38 Vykreslení koule: příklad 1 glpushmatrix(); 2 gltranslatef(2.0, 2.0, 0.0); 3 glutwiresphere(2, 5, 10); 4 glpopmatrix(); 5 glpushmatrix(); 6 gltranslatef(-2.0, 2.0, 0.0); 7 glutwiresphere(2, 10, 10); 8 glpopmatrix(); 9 glpushmatrix(); 10 gltranslatef(2.0, -2.0, 0.0); 11 glutwiresphere(2, 100, 100); 12 glpopmatrix(); 13 glpushmatrix(); 14 gltranslatef(-2.0, -2.0, 0.0); 15 glutsolidsphere(2, 100, 100); 16 glpopmatrix();
Vykreslování grafických objektů Strana 32 / 38 Vykreslení koule: výsledek
Vykreslování grafických objektů Strana 33 / 38 Vykreslení graf. objektů Kužel void glutsolidcone(gldouble base, GLdouble height, GLint slices, GLint stacks) kde slices představují počet vrcholů v horizontálním řezu a stacks jemnost řezů ve vertikálním směru. Základna leží v 0. Vrchol v height. Anuloid void glutsolidtorus(gldouble inrad, GLdouble outrad, GLint sides, GLint rings) kde inrad je vnitřní poloměr, outrad vnější poloměr, sides určuje počet vrcholů při vertikálním řezu a rings počet kružnic po obvodu anuloidu.
Vykreslování grafických objektů Strana 34 / 38 Vykreslení graf. objektů Osmistěn void glutsolidoctahedron(void) Dvanáctistěn void glutsoliddodecahedron(void) Dvacetistěn void glutsolidicosahedron(void) Čajník void glutsolidteapot(gldouble size) používá se evaluátorů, jsou generovány texturové souřadnice.
Vykreslování grafických objektů Strana 35 / 38 Vykreslení drátěných verzí objektů
Shrnutí Strana 36 / 38 Obsah přednášky 1 Obsah přednášky 2 Inicializace aplikace 3 Zpracování událostí 4 Časovač 5 Vykreslování grafických objektů 6 Shrnutí
Shrnutí Strana 37 / 38 Shrnutí Knihovna GLUT nám zajišt uje dobrou funkcionalitu pro správu aplikace. Metody na vykreslování grafických objektů jsou v rozporu s novými verzemi OpenGL. Menu i GUI obecně jsou velmi základní. Pro kvalitní GUI je vhodné použít jinou knihovnu (Qt, GTK+, aj.).
Shrnutí Strana 38 / 38 Kontrolní otázky/úkoly Zkuste pomocí grafických objektů nakreslit jednoduchého robota, jehož paže můžete ovládat pomocí klávesnice.