KAPITOLA 13 Grafika a zvuk Mnoho aspektů profesionálního programování vyžaduje pokročilou podporu grafiky a zvuku. Vše od vytváření matematických modelů až po psaní nejnovějších akčních her vyžaduje schopnost kreslit (a také animovat) složité geometrické objekty. V případě současného šílení po multimédiích je zase vyžadováno zpracování zvukových souborů jak v digitální podobě, tak i přímo z audio CD. Bohužel, většina standardních programových nástrojů, které jsou obsaženy ve většině linuxových systémů, neposkytuje metody potřebné pro vývoj pokročilých grafických a zvukových programů. Tato kapitola popisuje dva nástroje, které lze přidat do vašeho programového vybavení, a jež vám pomohou ve vašem úsilí vytvářet pokročilou grafiku a zvuky pro vaše linuxové aplikace.
Linux a grafika Většina linuxových distribucí je dnes založena na grafice. Když startujete systém, jste přivítáni grafickou přihlašovací obrazovkou, která často obsahuje efektní obrázek na pozadí a grafický seznam uživatelů a příslušných voleb. Jakmile se přihlásíte do linuxového systému, ocitnete se v grafickém desktopovém prostředí, které obsahuje nejenom různé ikony pro programy a zařízení, ale také systémové menu s ikonami pro vybrané aplikace. Spuštění programu pak spočívá v jednoduchém kliknutí na příslušnou ikonu na ploše nebo výběrem odpovídající položky z menu. Aby se tohle mohlo uskutečnit, Linux musí za scénou provádět velkou spoustu věcí. Existuje mnoho programového kódu, který je použit pro zobrazení grafiky na Linuxu. Grafické programování je jedním z nejsložitějších programovacích prostředí v Linuxu. Manipulace grafickými objekty vyžaduje znalost, jak grafická karta komunikuje s monitorem při vytváření obrázků na obrazovce. Naštěstí dnes už existuje několik nástrojů, které dokáží programátorům grafiky v Linuxu hodně usnadnit život. Tato sekce popisuje celkem čtyři nástroje, které jsou používány pro práci s grafikou v prostředí Linuxu: X Windows, OpenGL, GLUT a SDL.
424
Kapitola 13 – Grafika a zvuk
X Windows Nejrozšířenější formou grafiky, která je poskytována současnými operačními systémy, je systém oken. Kromě populárního systému od Microsoftu, který je podle nich nazván, existuje několik dalších operačních systémů, jež poskytují programátorům grafické okenní prostředí. Linux se k této grafické revoluci připojil tím, že rovněž nabídli několik prostředí založených na oknech. Ve všech operačních systémech existují dva základní prvky, které ovládají grafické prostředí: grafická karta instalovaná v počítači a monitor, jenž všechno zobrazuje. Oba tyto prvky musí být správně detekovány a řízeny, aby nějaký program mohl zobrazovat grafiku. Celý vtip spočívá v získání snadného přístupu k těmto prvkům. Linuxové distribuce pro ovládání grafiky používají grafický standard X Windows. Standard X Windows definuje protokoly, které slouží jako rozhraní mezi grafickými aplikacemi a systémovou grafickou kartou + monitorem. Od té doby, co se X Windows stal standardem, poskytuje společné rozhraní pro mnoho různých grafických karet a monitorů. Aplikace, které jsou napsány pro X Windows, mohou běžet na jakémkoliv systému s libovolnou kombinací grafické karty a monitoru, pokud daná kombinace grafické karty a monitoru umí pracovat s rozhraním X Windows. To je znázorněno na obrázku 13.1.
Obrázek 13.1. Standard X Windows sám o sobě představuje pouze specifikaci, nikoliv konkrétní produkt. Jednotlivé operační systémy používají odlišný software X Windows pro implementaci standardu X Windows. V linuxovém světě dnes existují dva softwarové balíčky, které X Windows implementují:
XFree86.
X.org.
Softwarový balíček XFree86 je nejstarší implementací standardu X Windows. Po dlouhou dobu se jednalo o jediný balíček X Windows, který byl dostupný pro Linux. Jak už plyne z jeho jména, jedná se o svobodnou (a open source) implementaci navrženou pro systémy Intel x86.
Linux PROFESIONÁLNĚ – programování aplikací
425
Nedávno ovšem na linuxovou scénu vstoupil nový balíček nazvaný jako X.org. Program X.org je považován za vývojového následníka programu XFree86 a rychle si získal oblibu v různých linuxových distribucích – hlavně díky podpoře pokročilejších vlastností než měl XFree 86. Mnoho distribucí Linuxu tak v současnosti používá X.org místo staršího XFree86. Oba balíčky pracují stejným způsobem – řídí komunikaci Linuxu s grafickou kartou a zobrazují grafický obsah na monitoru uživatele. Aby tohle bylo možné, X Windows vyžaduje specifickou konfiguraci vzhledem k systému, na kterém běží. V dávných dobách Linuxu jste se museli prodírat ohromným konfiguračním souborem a ručně upravovat volby programu XFree86 pro konkrétní typ grafické karty a monitoru. Použití špatné konfigurace mohlo znamenat zničení drahého monitoru. V současnosti ovšem většina linuxových distribucí při své instalaci automaticky detekuje vlastnosti grafické karty a monitoru, takže bez jakéhokoliv zásahu uživatele dojde k vytvoření odpovídajících konfiguračních souborů. V době své instalace Linux detekuje vlastnosti grafické karty a monitoru a následně vytvoří odpovídající konfigurační soubor pro X Windows, který obsahuje nalezené informace. Při instalaci Linuxu si můžete povšimnout okamžiku, kdy je zkoumán monitor kvůli zjištění podporovaných grafických režimů. Někdy to způsobí, že monitor po několik sekund nic nezobrazuje. Protože existuje mnoho rozdílných typů karet a monitorů, dokončení tohoto procesu může trvat nějakou dobu. Pokud váš systém obsahuje nějakou novější a pokročilejší grafickou kartu, instalační proces nemusí zvládnout proces automatické detekce. A aby se věci ještě více zhoršily, některé distribuce Linuxu se nedokáží nainstalovat, pokud nebudou schopny zjistit nastavení grafické karty. Jiné distribuce vám v případě selhání autodetekce mohou položit několik otázek, aby bylo možné alespoň tímto způsobem získat nějaké informace. A ještě jiné distribuce mohou přejít v případě selhání autodetekce na nejnižší společný jmenovatel, čímž se vytvoří obraz, který není přizpůsoben konkrétnímu grafickému prostředí. Mnoho uživatelů PC má k dispozici fantastické grafické karty, aby mohli hrát moderní počítačové hry ve vysokém rozlišení. Tyto grafické akcelerátory obsahují specializovaný hardware, který společně s dodávaným softwarem dokáže zvyšovat rychlost vykreslování trojrozměrných objektů na obrazovce. V minulosti ovšem tento speciální grafický hardware způsoboval spoustu problémů při pokusu o instalaci do linuxového systému. Výrobci těchto grafických karet ovšem pomalu začínají tyto problémy řešit, takže ke svým produktům konečně poskytují ovladače určené pro Linux. A mnoho dnešních linuxových distribucí, které jsou upraveny pro koncové uživatele, dokonce obsahuje i vlastní ovladače pro takové grafické karty. Jakmile je dostupné prostředí X Windows, aplikace ho mohou použít pro interakci s grafickým prostředím na linuxovém systému. Oblíbené desktopy KDE a GNOME běží v prostředí X Windows a využívají volání API X Windows pro vykonání všech vykreslovacích funkcí. Přestože X Windows je výborný pro tvorbu programů v okenním prostředí, existují určité meze toho, co všechno smí systém X Windows dělat. Protože se jedná o trochu starší standard, systém X Windows neobsahuje podporu pro spoustu moderních věcí. Tento nedostatek se projeví zejména v případě, kdy chce programátor vytvářet pokročilé grafické aplikace, které mají pracovat s trojrozměrnými objekty. K tomuto typu programování tak musíte použít jiné balíčky.
426
Kapitola 13 – Grafika a zvuk
OpenGL Knihovna OpenGL (Open Graphic Library) byla vytvořena za účelem poskytnutí společného API pro přístup k pokročilým grafickým vlastnostem, které jsou obsaženy v grafických kartách s 3-D akcelerátorem. Zatímco standard X Windows se zaměřuje na poskytnutí okenního prostředí pro programátory, OpenGL projekt se zaměřuje na poskytnutí API, které jsou specifické pro vykreslování pokročilých dvojrozměrných (2D) a trojrozměrných (3D) objektů. Podobně jako X Windows, ani projekt OpenGL projekt není specifickou softwarovou knihovnou s funkcemi. Naopak – jedná se o obecné specifikace pro funkce, které jsou vyžadovány pro vykreslování grafických objektů na výkonných grafických pracovních stanicích. Jednotliví výrobci grafických karet si pořizují licence ke specifikacím OpenGL, aby mohli vytvořit příslušné API pro své konkrétní grafické karty. Programátoři pak mohou využívat tato stejná API pro interakci s různými grafickými kartami podporujícími OpenGL. Místo použití specifické knihovny OpenGL pro konkrétní grafickou kartu je rovněž možné použít obecnou OpenGL knihovnu, která je implementována plně softwarově. Tato softwarová knihovna převede všechny 2D a 3D objekty do standardních volání funkcí X Windows, které mohou být obslouženy standardními grafickými kartami. Podívejte se na obrázek 13.2.
Obrázek 13.2. Program Mesa je oblíbeným balíčkem, který poskytuje softwarovou implementaci funkcí knihovny OpenGL. Program Mesa je často standardně instalován na linuxovém systému, který sice nemá k dispozici moderní grafickou 3D kartu, nicméně potřebuje implementovat pokročilou 3D grafiku. Program Mesa totiž obsahuje několik knihoven pro vývojáře, takže ho lze použít k vytvoření vlastních 2D a 3D aplikací bez nutnosti kupovat moderní grafickou kartu s 3D akcelerátorem. Libovolný program, který je napsán tak, aby běžel v Mese, bude fungovat i případě použití pokročilé grafické kartě s podporou OpenGL.
Linux PROFESIONÁLNĚ – programování aplikací
427
OpenGL Utilities Toolkit Knihovna OpenGL sice poskytuje funkce pro pokročilou 2D a 3D grafiku, nicméně neposkytuje funkce pro standardní programování oken. Aby se mohl kompenzovat tento nedostatek OpenGL, Mark Kilard vyvinul GLUT (OpenGL Utility Toolkit). GLUT je založen na specifikacích OpenGL, které jsou zkombinovány s obecnými funkcemi pro okna. Tím je vytvořena kompletní knihovna funkcí, která se dá použít pro snadnější vytváření oken, interakci s uživatelem či vykreslování 2D/3D objektů. Knihovna GLUT tak slouží jako zprostředkující vrstva mezi OpenGL a systémem X Windows. Stejně jako v případě OpenGL i v tomto případě mnoho výrobců grafických karet pro své výrobky poskytuje specifickou knihovnu GLUT. I program Mesa poskytuje plně softwarovou implementaci GLUT pro méně pokročilé grafické systémy. Pokud využíváte OpenGL pro vytváření grafických objektů, pravděpodobně budete chtít používat i knihovnu GLUT pro usnadnění vaší práce.
Simple Directmedia Layer OpenGL a GLUT jsou výborné, pokud potřebujete vykreslovat mnohoúhelníky a rotovat je kolem vlastní osy, ale v některých grafických prostředích si s tímto nemusíte vystačit. Mnoho programů (zejména hry) kromě vykreslování objektů rovněž potřebuje rychle zobrazovat na monitoru různé obrázky. Většina her také potřebuje přístup k zvukovému systému pro přehrávání zvukových efektů a hudby, stejně jako přístup ke klávesnici (či joysticku) kvůli interakci s uživatelem. Dělat tyto činnosti prostřednictvím GLUT rozhodně není snadný úkol. V takových situacích se hodí herní knihovny vyšší úrovně. Nejoblíbenější grafickou a zvukovou knihovnou pro Linux je knihovna nazvaná Simple Directmedia Layer (SDL). Knihovna SDL poskytuje mnoho pokročilých funkcí pro manipulaci se soubory obrázků na obrazovce, vytváření animací z obrázků, přístup ke zvuku či k obsluze událostí klávesnice a myši (a dokonce joysticku). Knihovna SDL je určena pro více platforem, takže můžete snadno najít implementace SDL pro většinu operačních systémů. Aplikaci můžete vyvinout pomocí SDL na vašem Linuxu a snadno ji portovat do prostředí Microsoft Windows nebo Apple Macintosh. Tato vlastnost vlastně způsobila, že knihovna SDL je velmi oblíbena mezi profesionálními programátory her. Díky této skutečnosti rovněž spousta profesionálních vývojářů her přechází k SDL, aby si usnadnili portaci her z platformy Windows na Linux.
Vytváření aplikací OpenGL Pro vytvoření aplikace OpenGL potřebujete mít na vašem Linuxu nejenom runtime knihovnu OpenGL, ale také mnoho dalších vývojových knihoven. Splnit tyto požadavek může být obtížné, protože knihovna OpenGL není open source. Specifikace k OpenGL nejsou k dispozici zdarma. Jinak řečeno – od společnosti SGI (Silicon Graphics Incorporated) musíte mít k dispozici licencovanou kopii tohoto softwaru, abyste ho mohli provozovat na vašem linuxovém systému. Mnoho
428
Kapitola 13 – Grafika a zvuk
výrobců grafických karet ovšem pro své konkrétní grafické karty poskytuje licencované knihovny OpenGL. Pokud takovou grafickou kartu se specifickými ovladači OpenGL nemáte k dispozici – a přesto chcete programovat v OpenGL – můžete použít nějakou softwarovou implementaci OpenGL, např. již zmiňovaný program Mesa. Tento open source program, který byl vytvořen Brianem Paulem ve formě jednoduché implementace knihovny OpenGL, lze označit za daleko nejoblíbenější softwarovou implementaci OpenGL. Protože jeho autor netvrdí, že Mesa je kompatibilní náhradou za OpenGL, neposkytuje žádnou licenci OpenGL pro Mesu. Mesa vám místo toho nabízí prostředí, které je podobné syntaxi příkazů OpenGL, a jež bylo společností SGI autorizováno pro distribuci v podobě otevřeného kódu. Použitím Mesy neporušíte žádná licenční omezení. Pomocí programového prostředí Mesa tak můžete vyvíjet OpenGL aplikace, které budou fungovat na každé implementaci OpenGL. Na vašem linuxovém prostředí navíc můžete spouštět runtime knihovny Mesy bez nutnosti vlastnit licenci od SGI. Jak už bylo zmíněno v sekci OpenGL Utilities Toolbox, knihovna OpenGL neposkytuje nezbytnou funkcionalitu pro vytváření oken. Naštěstí projekt Mesa zahrnuje i knihovny GLUT, což vám dovoluje vytvářet plně funkční aplikace s grafickými okny v jediném vývojovém prostředí. Tato kapitola předvádí vývoj OpenGL aplikací prostřednictvím knihoven Mesa. Následující sekce popisuje, jak stáhnout a nainstalovat knihovny Mesy a jak je použít pro vytvoření OpenGL aplikací, které mohou běžet na libovolné implementaci OpenGL.
Stažení a instalace Mnoho distribucí Linuxu již obsahuje instalační balíčky pro Mesu, nehledě na skutečnost, že většina linuxových distribucí instaluje runtime knihovny zcela standardně. To umožňuje spouštět OpenGL aplikace i bez přítomnosti pokročilé 3D grafické karty. Abyste mohli vyvíjet OpenGL aplikace, pravděpodobně budete muset nainstalovat hlavičkové soubory Mesy společně se soubory knihovny. Obojí je obsaženo v instalačních balíčcích se jmény jako mesa-devel. Pokud nemůžete najít vývojový balíček Mesy pro vaši konkrétní distribuci Linuxu, nebo pokud dáváte přednost práci s poslední verzí balíčku, nahlédněte na webovou stránku Mesy. Webová stránka projektu Mesa se nachází na adrese www.mesa3d.org. Na hlavní stránce klikněte na odkaz Downloading/Unpacking (Stáhnout/Rozbalit) a stáhněte si nejnovější knihovny Mesy. Existují tři softwarové balíčky, které lze stáhnout:
MesaLib-x.y.z. Hlavní soubory knihovny Mesa OpenGL.
Mesa-demos-x.y.z. Skupina ukázkových programů OpenGL pro demonstraci programování v OpenGL.
MesaGLUT-x.y.z. Implementace GLUT (OpenGL Utility Toolkit) pro Mesu.
Označení x.y.z specifikuje verzi balíčku Mesy, kde x znamená hlavní číslo verze, y vedlejší číslo verze a z číslo záplaty. Mesa dodržuje systém číslování, kde všechna sudá vedlejší čísla verze (y)
Linux PROFESIONÁLNĚ – programování aplikací
429
znamenají stabilní verze. Lichá čísla pak označují vývojové verze. V době psaní této knihy byla nejnovější stabilní verzí 6.4.2 a vývojovou verzí 6.5.1. Pro tvorbu OpenGL aplikací na vašem linuxovém systému byste si měli stáhnout minimálně balíčky MesaLib a MesaGLUT. Tohle vám poskytne kompletní vývojové prostředí OpenGL a GLUT pro vytváření vašich aplikací. Nicméně i balíček Mesa-demos je užitečný. Soubory můžete stáhnout ve formátech .tar.gz nebo .zip (podle toho, který se více hodí pro vaši konkrétní distribuci Linuxu). Balíčky stáhněte do pracovního adresáře a pro jejich rozbalení použijte příkazy tar nebo unzip. Všechny balíčky rozbalte do stejného adresáře Mesa-x.y.z. Po stažení a rozbalení balíčků můžete zkompilovat knihovny (a ukázkové programy, pokud jste si stáhli i balíček Mesa-demos). Mesa nepoužívá program configure pro zjištění kompilačního prostředí. Místo toho se používají různé cíle programu make (jeden cíl pro každý typ podporovaného prostředí). Pro zobrazení všech dostupných cílů napište do příkazové řádky příkaz make. Následně bude zobrazen seznam všech dostupných cílů příkazů make. Pro linuxové systémy můžete použít obecný cíl Linux nebo cíl, který je specifický pro vaše prostředí (jako například Linux-x86). Odpovídající název cíle jednoduše vložte ihned za příkaz make. $ make linux-x86
Po zkompilování souborů knihovny na vašem systému se můžete rozhodnout, že hlavičkové soubory a soubory knihovny nainstalujete do jejich standardních umístění ve vašem systému. Implicitní cíl příkazu make install nainstaluje hlavičkové soubory do adresáře /usr/local/include/GL. Soubory knihovny pak do adresáře usr/local/lib. Jednou z hezkých věcí na OpenGL je skutečnost, že do různých umístění můžete nainstalovat více verzí souborů knihovny OpenGL (například jednu verzi pro grafickou kartu + softwarové knihovny Mesa). Když spustíte vaši aplikaci, můžete si zvolit, kterou knihovnu použijete pro implementaci funkcí OpenGL. Můžete tak porovnat výkon různých verzí knihoven.
Programovací prostředí Po instalaci všech souborů potřebných pro Mesu OpenGL a GLUT můžete začít vytvářet vaše vlastní programy. Do vaší aplikace ovšem musíte zahrnout umístění hlavičkových souborů (pomocí standardního příkazu #include): #include
#include
Když kompilujete vaše aplikace OpenGL, musíte prostřednictvím parametrů -l pro linker zahrnout nejenom umístění hlavičkových souborů, ale také knihovny Mesa OpenGL a GLUT: $ cc -I/usr/local/include -o test test.c -L/usr/local/lib -lGL -lglut
Povšimněte si, že knihovna pro Mesa OpenGL (GL) je specifikována velkými písmeny, zatímco knihovna GLUT písmeny malými. Do souboru /etc/ld/so.conf byste také měli zahrnout adre-
430
Kapitola 13 – Grafika a zvuk
sář /usr/local/lib, aby Linux mohl vyhledat dynamické soubory knihovny OpenGL a GLUT. Po úpravě tohoto souboru nezapomeňte spustit program ldconfig. A tímto jsme si řekli všechno potřebné, takže se konečně můžeme pustit do vytváření vaší první aplikace OpenGL.
Použití knihovny GLUT Jak lze očekávat, knihovna GLUT obsahuje mnoho funkcí pro vytváření oken, kreslení objektů či obsluhu vstupu od uživatele. Tato sekce ukazuje několik základních principů ohledně používání knihovny GLUT pro tvorbu následujících jednoduchých grafických aplikací.
Vytvoření okna.
Kreslení objektů v okně.
Zpracování vstupu od uživatele.
Animace kreseb.
Předtím, než budete moci kreslit, musíte mít pracovní prostor. Pracovním prostorem v GLUT je okno. Následující první téma ukazuje, jak pomocí knihovny GLUT vytvořit okno standardního prostředí X Windows. Po úspěšném vytvoření okna můžete použít základní příkazy knihovny GLUT pro kreslení různých objektů, jako například čar, trojúhelníků, mnohoúhelníků a dalších komplexních matematických modelů. Při práci v prostředí okna je klíčové zachytit vstup od uživatele. Vaše aplikace musí být schopna detekovat nejenom události klávesnice, ale také pohyb kurzorem myši. A nakonec skoro každý herní program vyžaduje nějakou animaci. Knihovna GLUT naštěstí poskytuje příkazy pro jednoduchou animaci objektů, které mohou oživit vaše objekty.
Vytvoření okna Nejzákladnějším prvkem každého grafického programu je okno, do kterého jsou umístěny samotné grafické objekty. Existuje celkem pět funkcí, které jsou běžně používány pro inicializaci prostředí GLUT a vytvoření okna: void glutInit(int argc, char **argv); void glutInitDisplayMode(unsigned int mode); void glutInitWindowSize(int width, int height); void glutInitWindowPosition(int x, int y); int glutCreateWindow(char *name);
Tato uvedená volání funkcí jsou přítomna prakticky v každém OpenGL programu. Funkce glutInit() inicializuje knihovnu GLUT a používá parametry příkazové řádky k definici toho, jak bude GLUT komunikovat se systémem X Windows. Parametry funkce glutInit() pro příkazový řádek jsou následující:
display. Specifikuje X server, ke kterému se má připojit.
Linux PROFESIONÁLNĚ – programování aplikací
geometry. Specifikuje umístění okna na X serveru.
iconic. Vyžaduje, aby všechna okna nejvyšší úrovně byla vytvořena v ikonickém stavu.
indirect. Vynucené použití nepřímého kontextu renderování OpenGL.
direct. Vynucené použití přímého kontextu renderování OpenGL.
gldebug. Zavolá glGetError po každém volání funkce OpenGL.
sync. Povoluje synchronní transakce protokolu X Windows.
431
Další funkce glutInitDisplayNode() pak specifikuje režim zobrazení, který bude použit pro prostředí OpenGL. Režim zobrazení je možné definovat následující řadou hodnot přepínačů: Přepínač
Hodnota
GLUT_SINGLE
Poskytuje jedno bufferované okno.
GLUT_DOUBLE
Poskytuje dvě bufferovaná okna, mezi kterými se lze přepínat.
GLUT_RGBA
Řídicí okno založené na hodnotách RGB.
GLUT_INDEX
Řídicí okno založené na indexu barev.
GLUT_ACCUM
Poskytuje akumulační buffer pro okno.
GLUT_ALPHA
Poskytuje komponentu průhlednosti pro barvu okna.
GLUT_DEPTH
Poskytuje okno s bufferem barevné hloubky.
GLUT_STENCIL
Poskytuje okno s bufferem šablon.
GLUT_MULTISAMPLE
Poskytuje okno s podporou multisamplingu.
GLUT_STEREO
Poskytuje stereo buffer okna.
GLUT_LUMINANCE
Poskytuje komponentu průhlednosti pro barvu okna.
Funkce glutInitWindowSize() a glutInitWindowPosition() dělají přesně to, co naznačuje jejich název – dovolují vám stanovit počáteční velikost okna (v pixelech) a jeho pozici (založenou na souřadnicovém systému okna). Základní bod souřadnicového systému oken (0,0) je v levém dolním rohu okna displeje. Osa x probíhá podél dolní strany displeje, osa y podél levé strany displeje. Funkce glutCreateWindow() vytváří skutečné okno. Použité parametry specifikují název okna, který je zobrazen v pruhu v horní části okna. Po vytvoření okna může začít skutečná zábava. Protože se jedná o programování řízené událostmi, GLUT se v tomto ohledu podobá všem ostatním programovacím jazykům, které jsou založeny na oknech. Místo lineárního postupu kódem aplikace při provádění příkazů čeká GLUT na události, které se stanou uvnitř vytvořeného okna. Když dojde k takové události, bude vykonána funkce zpětného volání, která je s ní spojena. GLUT pak začne čekat na další událost.
432
Kapitola 13 – Grafika a zvuk
Všechna činnost v programech, které jsou založeny na oknech, probíhá prostřednictvím funkcí zpětného volání. To znamená, že musíte poskytnout kód pro události, které se stanou ve vaší aplikaci (což je například situace, kdy uživatel stiskne tlačítko myši nebo klávesu na klávesnici). GLUT poskytuje několik volání funkcí, která vám umožní registrovat vaše vlastní funkce zpětného volání, jež budou GLUT zavolány při výskytu specifických událostí: Funkce
Popis
GlutDisplayFunc (void (*func) void)
Specifikuje funkci, která bude zavolána, když bude potřeba překreslit obsah okna.
GlutReshapeFunc (void (*func)
Specifikuje funkci, která bude zavolána, když bude potřeba změnit velikost nebo polohu okna.
int width, int height) GltKeyBoardFunc (void (*func ) (unsigned int key, int x, int y) GlutSpecialFunc (void (*func) (int key, int x, int y) GlutMouseFunc (void )*func) intButton, int state, int x, int y) GlutMotionFunc (void (*func) (int x, int y) GlutTimerFunc (int msec, void
Specifikuje funkci, která bude zavolána při stisknutí nějaké ASCII klávesy. Specifikuje funkci, která bude zavolána při stisknutí speciální klávesy, například šipka nebo F1-F12. Specifikuje funkci, která bude zavolána při stisknutí nebo uvolnění tlačítka myši. Specifikuje funkci, která bude zavolána při pohybu kurzoru myši v okně.
(*func) (int value), value)
Specifikuje funkci, která bude zavolána po uplynutí času specifikovaného pomocí argumentu msec.
GlutPostRedisplay (void)
Označuje aktuální okno k překreslení.
Pokud nebudete registrovat nějakou funkci s nějakou událostí, GLUT se nebude snažit předat výskyt této události vašemu programu. Jinak řečeno – taková událost bude ignorována. Po registraci vašich funkcí s událostmi musíte použít funkci glutMainLoop(), aby GLUT mohl začít čekat na výskyt daných událostí. Program testwin.c, který je ukázán v následujícím výpisu, demonstruje vytvoření okna v prostředí GLUT a nakreslení jednoduchého objektu v okně. /* * Professional Linux Progamming - OpenGL window test */ #include #include void display(void) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT);
Linux PROFESIONÁLNĚ – programování aplikací
433
glColor3f(1.0, 1.0, 1.0); glRotatef(30, 1.0, 0.0, 0.0); glRotatef(30, 0.0, 1.0, 0.0);) glutWireTetrahedron(); glFlush(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); glutInitWindowSize(250, 250); glutInitWindowPosition(0, 0); glutCreateWindow("Test Window"); glutDisplayFunc(display); glutMainLoop(); return 0; }
Sekce main() programu testwin.c používá standardní inicializační funkce GLUT pro vytvoření okna, které zobrazí OpenGL kreslení. Je registrována funkce zpětného volání pro obsluhu zobrazení okna. Následně je spuštěna hlavní smyčka událostí GLUT. Funkce zpětného volání display je použita pro kontrolu toho, co je umístěno do okna. To je místo, kde se odehrává veškerá činnost. Předtím, než do okna cokoliv umístíte, bude vhodné okno vyčistit od čehokoliv, co se v něm může nacházet. Pro takové vyčistění okna je použita funkce glClear(). Barvu pozadí použitou pro vyčistění okna lze nastavit pomocí funkce glClearColor(), která používá následující čtyři parametry: glClearColor(float red, float green, float blue, float alpha)
Parametry red, green a blue určují množství červené, zelené a modré přidané do barvy pozadí. Hodnota 0.0 znamená vůbec nic, hodnota 1.0 pak maximální hodnotu dané barvy. Pokud stejně jako já nevíte, jak smícháním červené, zelené a modré barvy vytvořit požadovanou barvu, zde je tabulka, která ukazuje některé základní barevné kombinace: Červená
Zelená
Modrá
Barva
0.0
0.0
0.0
černá
1.0
0.0
0.0
červená
0.0
1.0
0.0
zelená
1.0
1.0
0.0
žlutá
0.0
0.0
1.0
modrá
1.0
0.0
1.0
fialová
434
Kapitola 13 – Grafika a zvuk
Červená
Zelená
Modrá
Barva
0.0
1.0
1.0
modrozelená
1.0
1.0
1.0
bílá
Pamatujte si, že se jedná o hodnoty s plovoucí desetinnou čárkou, takže mezi hodnotami 0.0 a 1.0 existuje velké množství odstínů. Nicméně věříme, že tato tabulka vám poskytla alespoň základní představu o tom, jak namíchat požadovanou barvu. Parametr alpha řídí průhlednost aplikovanou na barvu. Hodnota 0.0 indikuje, že žádná průhlednost není použita, hodnota 1.0 pak znamená, že je použita maximální průhlednost. Po nastavení hodnoty barvy pozadí a vyčistění pozadí můžete začít kreslit. Barva kresleného objektu je stanovena pomocí funkce glColor3f(). Tato funkce definuje barvu pomocí tří RGB hodnot (červená, zelená, modrá). Hodnoty je opět možné zadávat v rozmezí od 0.0 do 1.0. Tabulku s kombinacemi hodnot, které jsme použili u funkce glClearColor(), můžete využít i pro tuto funkci. Po nastavení barev je čas začít kreslit objekt. Pro tento příklad jsme použili vestavěný geometrický objekt z knihovny GLUT. Existuje několik typů vestavěných tvarů, které můžete použít – od jednoduchých objektů, jako například krychle, válce a kužely, až po pokročilejší objekty jako jsou osmistěny, čtyřstěny či dvanáctistěny. Funkce glutWireTetrahedron() slouží k vytvoření obrysu čtyřstěnu. Objekt je standardně vycentrován na počátek osy. Abychom věci trochu pozměnili, použili jsme funkci glRotate() pro rotaci objektu. Funkce glRotate() má čtyři parametry: glRotate( float angle, float x, float y, float z)
První parametr, angle, určuje úhel rotace objektu ve stupních (zvolili jsme otočení o 30 stupňů). Další tři parametry určují směr od počátku, ke kterému rotace směřuje. Dvojí zavolání funkce glRotate() otočí objekt o 30 stupňů na ose x a poté o 30 stupňů na ose y. To umožňuje dosáhnout výraznějšího trojrozměrného dojmu. Funkce glFlush() je použita k tomu, aby kresba mohla být poslána na monitor uživatele (na konci volání funkce zpětného volání). Jakmile máte vytvořený kód programu testwin.c, zkompilujte ho na vašem systému: $ cc –I/usr/local/include –o testwin testwin.c –L/usr/local/lib –lGL –lglut
Aby bylo možné program spustit, musíte mít na vašem systému otevřenou relaci X Windows. Pokud používáte nějakého správce desktopu (jako například KDE nebo GNOME), můžete pro odstartování programu testwin.c otevřít okno příkazové řádky. Okno programu by se následně mělo objevit na vašem desktopu společně s nakresleným objektem, jak je ukázáno na obrázku 13.3.