}w !"#$%&'()+,-./012345
M ASARYKOVA UNIVERZITA FAKULTA INFORMATIKY
Grafický engine na základech OpenGL pro podporu 3D animací ˇ B AKALÁ RSKÁ PRÁCE
Pavel Stupka
Brno, jaro 2006
Prohlášení Prohlašuji, že tato bakaláˇrská práce je mým puvodním ˚ autorským dílem, které jsem vypracoval samostatnˇe. Všechny zdroje, prameny a literaturu, které jsem pˇri vypracování používal nebo z nich cˇ erpal, v práci rˇ ádnˇe cituji s uvedením úplného odkazu na pˇríslušný zdroj.
Vedoucí práce: Mgr. Petr Tobola, Ph.D. ii
Shrnutí Grafické 3D engine jsou obecnˇe pokládány za vývojové knihovny vysoké úrovnˇe definující dané aplikaˇcní programové rozhraní (API – Application Programming Interface) pro vývoj grafických programu. ˚ V dnešní dobˇe se tyto knihovny využívají pˇredevším v komerˇcní sféˇre, zejména v herním prumyslu. ˚
iii
Klíˇcová slova 3D engine, OpenGL, SDL, C++, GLU, API, ARB, 3D model, kamera, detekce kolizí
iv
Obsah 1 Pˇredmluva . . . . . . . . . . . . . . . . . . . 2 O grafických 3D engine . . . . . . . . . . . 2.1 Úvod do oblasti 3D engine . . . . . . . 2.2 Základní funkcionality herních engine 2.2.1 Rozhraní aplikace . . . . . . . . 2.2.2 3D modely . . . . . . . . . . . . 2.2.3 Snímání scény a detekce kolizí ˇ 2.2.4 Cásticové systémy . . . . . . . 3 Použité technologie . . . . . . . . . . . . . 3.1 Technologie OpenGL . . . . . . . . . . 3.1.1 OpenGL standard . . . . . . . 3.1.2 Implementace OpenGL . . . . 3.1.3 Architektura knihovny . . . . . 3.2 Knihovna SDL . . . . . . . . . . . . . . 3.3 Programovací jazyk C++ . . . . . . . . 4 Seznámení s Astral3D . . . . . . . . . . . . 4.1 Základní informace . . . . . . . . . . . 4.2 API . . . . . . . . . . . . . . . . . . . . 5 Architektura knihovny Astral3D . . . . . . ˇ 5.1 Rízení chybových hlášení . . . . . . . 5.2 Práce s okny a zpracování událostí . . 5.3 Snímání scény . . . . . . . . . . . . . . 5.4 Virtuální svˇet a 3D modely . . . . . . . 5.5 Interakce s uživatelem . . . . . . . . . 5.6 2D grafika . . . . . . . . . . . . . . . . 6 Další možná rozšíˇrení . . . . . . . . . . . . 7 Závˇer . . . . . . . . . . . . . . . . . . . . . . A Pˇríklad použití Astral3D . . . . . . . . . . B Obrázková galerie . . . . . . . . . . . . . . C Relevantní internetové odkazy . . . . . . . D Elektronické pˇrílohy . . . . . . . . . . . . . Bibliografie . . . . . . . . . . . . . . . . . . . . . Rejstˇrík . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1 2 2 3 3 3 3 4 5 5 5 5 6 7 8 9 9 9 13 13 14 17 19 22 22 24 26 27 29 32 33 34 35
v
Kapitola 1
Pˇredmluva V dnešní hektické dobˇe se cˇ lovˇek stále více setkává s poˇcítaˇcovými technologiemi. Pokrok nelze zastavit. Stejnˇe tak jako vše ostatní se i poˇcítaˇcové technologie vyvíjí. Pˇred tˇriceti lety jsme jen stˇeží ovládali náš bankovní úˇcet pomocí osobního poˇcítaˇce, kumunikovali s kamarády na druhé stranˇe Zemˇe pomocí chatových programu˚ nebo bˇežnˇe hráli poˇcítaˇcové hry. Jednou z oblastí, která je neoddˇelitelnˇe spjata s tímto fenoménem, je poˇcítaˇcová grafika. Bez ní si dnes již poˇcítaˇce nelze pˇredstavit. Avšak vždy tomu tak nebylo. Poˇcítaˇcová grafika zažívala v posledních deseti letech velký rozmach. Ten byl zpusoben ˚ pˇredevším novým hardwarem v podobˇe grafických akcelerátoru˚ 1 . Díky tomu se zaˇcaly stále více objevovat programy využívající trojdimenzionální grafiku, která byla od roku lepší. Dnes již na tomto poli dosahujeme opravdu realistických simulací. V praxi se cˇ asto setkáváme s ruznými ˚ poˇcítaˇcovými programy. Pro jejich vytváˇrení je zapotˇrebí programovací jazyk. Ten definuje urˇcitou množinu funkcí, kterou programátor používá k vytváˇrení aplikace. Tato množina funkcí je však dle daného programovacího jazyka více cˇ i ménˇe obsáhlá a nemusí tedy vždy zcela vyhovovat. Jinak rˇ eˇceno – vyvíjet složitý poˇcítaˇcový systém pouze pomocí základních funkcí programovacího jazyka je zdlouhavé, nepraktické, nepˇrehledné a v neposlední rˇ adˇe také neekonomické. Proto jsou navrhovány tzv. nadstavbové knihovny. Nejedná se však o knihovny v pravém slova smyslu, ale o další funkcionality, které jsou vystavˇeny pomocí funkcí základních. Takto novˇe vzniklé entity pak výraznˇe ulehˇcují programování. Nadstavbových knihoven pro ruzné ˚ programovací jazyky jsou tisíce. At’ už databázové, hudební, grafické nebo jiné. Téma této bakaláˇrské práce je zamˇerˇ eno na návrh a implementaci jedné takové grafické knihovny urˇcené pro programování trojdimenzionální grafiky. Nˇekdy se také mužeme ˚ setkat s pojmem grafický 3D engine. Jedná se o jiné oznaˇcení téže knihovny. Druhá kapitola této práce rozebere do vˇetší hlouky samotný pojem 3D egine a ukáže celkový pohled na danou problematiku. V další kapitole se potom blíže seznámíme s technologiemi, které byly použity pro implementaci vyvíjené knihovny. Jedná se zejména o programovací jazyk C++ , multimediální knihovnu SDL (Simple DirectMedia Layer) a technologii pro práci se základní 3D grafikou – OpenGL. V následujících dvou kapitolách se již podíváme na vyvíjenou knihovnu nesoucí jméno Astral3D. A to jak z obecného pohledu, tak podrobnˇe na samotnou architekturu této knihovny. Závˇer práce patˇrí ukázkovým pˇríkladum ˚ využití Astral3D a shrnutí postˇrehu˚ a poznatku˚ z období jejího vývoje. 1. Grafický akcelerátor je speciální karta, která provádí složité grafické výpoˇcty.
1
Kapitola 2
O grafických 3D engine 2.1
Úvod do oblasti 3D engine
Grafický engine je vývojová knihovna definující dané aplikaˇcní programové rozhraní (API – Application Programming Interface) pro vývoj grafických programu. ˚ Pokud bychom si položili otázku, jaký rozsah funkcionalit by takové API mˇelo mít, odpovˇed’ je nejasná. V praxi se mužeme ˚ setkat s velice rozsáhlými, ale i prostˇe jednoduchými knihovnami. Tak jako je to i s jiným softwarem, grafické 3D engine mohou být záležitostí komerˇcní, stejnˇe tak jako volnˇe šiˇritelné. Pojd’me se nyní podívat, proˇc se dnes stále více mluví o tˇechto knihovnách a uved’me si nˇejaké pˇríklady. Prumysl ˚ s poˇcítaˇcovými hrami je v souˇcasné dobˇe jedním z faktoru, ˚ které ovlivnují ˇ vývoj herních engine. Se stále se zlepšujícími výkony grafických akcelerátoru˚ vzrustá ˚ kvalita grafických efektu˚ a poˇcítaˇcové hry tak dostávají úplnˇe jinou tváˇr, než jakou mˇely pˇred dvaceti lety. Postupem cˇ asu se ruzné ˚ herní platformy, spíše než osobní pocˇ ítaˇce, dostávají do stále vˇetšího poˇctu domácností. Není tedy divu, že poptávka po zábavˇe spojené s tˇemito médii stoupá. Existuje mnoho firem zabývajících se vývojem 3D engine a jejich distribucí. Ve vˇetšinˇe pˇrípadu˚ je za urˇcitý poplatek k dispozici i technická podpora. Na druhou stranu je tˇreba rˇ íci, že nˇekteré velké spoleˇcnosti vyvíjející poˇcítaˇcové hry si píší knihovny vlastní. 3D engine však nemusí být využíván pouze poˇcítaˇcovými hrami, ale také ruznými ˚ vˇedeckými aplikacemi, které napˇr. provádˇejí urˇcité simulace. To je jeden z duvod ˚ u, ˚ proˇc existují specializované knihovny mající pouze úzce definovanou funkcionalitu. Jedním z pˇredstavitelu˚ volnˇe šiˇritelných engine je Irrlicht 3D. Jedná se o velice vydarˇ ený produkt, který spolu s dalšími pˇrídavnými programy tvoˇrí ucelený systém pro vývoj aplikací – pˇredevším poˇcítaˇcových her. Irrlicht 3D je kompletnˇe napsán v programovacím jazyce C++ a nutno podotknout, že je velice propracovaný a má kolem sebe obsáhlou komunitu vývojáˇru˚ a uživatelu. ˚ Definuje zcela vlastní aplikaˇcní programové rozhraní. To dovoluje jednu velice zajímavou funkcionalitu. Nezáleží na tom, jaká implementace je použita pro vykreslování grafiky na nejnižší úrovni. Jinak rˇ eˇceno – v Linuxu Irrlicht 3D pro vykreslování grafiky využívá OpenGL 1 , ale v Microsoft Windows lze používat jak implementaci OpenGL, tak Direct3D, což je jedna ze souˇcástí multimediální knihovny DirectX navržené firmou Microsoft. Ruzné ˚ grafické karty mohou být ruznˇ ˚ e výkonné pro danou implementaci. Vhodnou kombinací tak lze dosáhnout optimálního výkonu. Dalším zástupcem volnˇe šiˇri1. OpenGL (Open Graphics Library) je standardem pro vykreslování 3D grafiky.
2
2.2. ZÁKLADNÍ FUNKCIONALITY HERNÍCH ENGINE telných produktu˚ je Genesis 3D. Opˇet velice kvalitní systém. Ale pˇri jeho použití je tˇreba si dávat pozor. Program využívající Genesis 3D musí pˇri svém spuštˇení zobrazovat logo tohoto engine. Tuto podmínku lze odstranit zaplacením jednorázového poplatku 10 000 USD. Cena licence komerˇcních produktu˚ pak sahá k ještˇe vyšším cˇ ástkám.
2.2
Základní funkcionality herních engine
Nyní se pojd’me podívat, jaké služby by mˇel herní engine poskytovat. Jak již bylo uvedeno výše, existují mnohé oblasti, na které se muže ˚ engine specializovat. Zustaneme ˚ však u klasické knihovny, kterou je ústˇrední téma této práce – Astral3D. 2.2.1 Rozhraní aplikace První, a velice duležitou, ˚ cˇ inností je vyvtoˇrení okna aplikace. To se sice muže ˚ zdát jako banalita, ale je tˇreba si uvˇedomit, že na každé platformˇe se tato akce muže ˚ provádˇet jinak. Engine by mˇel být co nejvíce pˇrenositelný. Musí tedy obsahovat jednotné vytváˇrení oken a práci s nimy. Duležitou ˚ vlastností je i zmˇena rozlišení a spuštˇení programu v režimu na celou obrazovku (tzv. fullscreen mode). Po vytvoˇrení okna pˇrichází na rˇ adu další velice duležitá ˚ cˇ ást – uživatelské rozhraní a zpracování událostí. Pod uživatelským rozhraním si mužeme ˚ pˇredstavit ruzné ˚ grafické prvky pro interakci uživatele s aplikací. Zpracování událostí je srdcem programu. Na každou událost, která se v programu vyskytne, lze reagovat pˇríslušnou akcí. Touto událostí je napˇr. pohyb myši, stisknutí klávesy, zmˇena polohy okna, ukonˇcení programu apod. 2.2.2 3D modely Další funkcionalitou je naˇcítání 3D modelu˚ a jejich zobrazování ve scénˇe. 3D model jsou v souboru uložená data s geometrickým a grafickým významem, která lze zobrazit v trojdimenzionálním prostoru. Existuje velké množstí formátu˚ 3D modelu. ˚ Mezi ty nejznámˇejší patˇrí 3DS (3D Studio), OBJ (Wavefront object), X (DirectX file) a další. V mnohých poˇcítaˇcových hrách se také mužeme ˚ setkat s tím, že se hráˇci pohybují ve virtuálním svˇetˇe. Ten muže ˚ být reprezentován právˇe nˇekterým z uvedených 3D modelu. ˚ Nejeden 3D engine však definuje vlastní formát pro virtuální svˇet a dodává i ruzné ˚ programy pro editování takových souboru. ˚ Zde je namístˇe uvést BSP (Binary Space Partitioning). Jedná se o metodu reprezentace dat, která využívá tzv. binární dˇelení prostoru, což je technika, kdy se minimalizuje poˇcet vykreslovaných polygonu˚ a tím se dosahuje vyšší rychlosti. Tuto metodu využívají nˇekteré formáty souboru. ˚ Jedním z nich je napˇr. formát Quake 3 BSP. 2.2.3 Snímání scény a detekce kolizí Pro snímání scény slouží kamera. Tu mužeme ˚ najít v jisté podobˇe ve všech existujících engine. Kamera je velice duležitým ˚ prvkem, bez nˇehož by byla orientace v prostoru velmi 3
2.2. ZÁKLADNÍ FUNKCIONALITY HERNÍCH ENGINE složitá. Detekce kolizí je neménˇe duležitou ˚ funkcí. Jedná se o techniku interakce objektu˚ v prostoru. Pˇredstavme si napˇr. hráˇce, který muže ˚ procházet zdí, protože systém nepodporuje žádnou interakci tohoto hráˇce a modelu simulujícího zed’. Potom taková animace neodráží fyzickou realitu. Systém musí zajistit, aby hráˇc nemohl zdí projít. Musí tedy detekovat pˇrípadnou kolizi a pˇríslušnˇe na ni zareagovat. Je více zpusob ˚ u˚ jak na kolizi reagovat. Jedním z nich je nedˇelat nic. Velice jednoduché, ale ne pˇríliš realistické. Dalším možným rˇ ešením je „svézt“ se po zdi (tzv. sliding). Této techniky se cˇ asto využívá. Pokud se detekce kolizí provádí vuˇ ˚ ci kameˇre, muže ˚ uživatel docílit simulace, která zobrazuje scénu vidˇenou z pohledu jeho oˇcí. ˇ 2.2.4 Cásticové systémy Dalším velice duležitým ˚ prvkem 3D engine jsou tzv. cˇ ásticové systémy (particle systems). Jedná se o techniku simulace efektu, ˚ které se velice složitˇe vykreslují bˇežnými zbusoby. ˚ Mezi tyto efekty patˇrí ohen, ˇ exploze, kouˇr, tekoucí voda, jiskry, mraky, sníh a prach. Základem cˇ ásticového systému je emitor – prvek, který je charakterizován svou polohou v prostoru ˇ a který generuje nové cˇ ástice. Cástice je reprezentována velice malým polygonem, jenž je specificky nasvícen a je mu nastavena urˇcitá barva. Velké množství takových polygonu˚ pak tvoˇrí napˇr. plamen ohnˇe. V každém cyklu výpoˇctu cˇ ásticového systému se pˇrepoˇcítá nová poloha pro všechny cˇ ástice, jsou generovány cˇ ástice nové a staré jsou rušeny. Na obrázku 2.1 je znázornˇen efekt ohnivé koule vytvoˇrený cˇ ásticovým systémem.
Obrázek 2.1: Ukázka efektu ohnivé koule v Irrlich 3D engine (pˇrevzato z oficiálního webu projektu:
).
4
Kapitola 3
Použité technologie V této kapitole se blíže seznámíme s technologiemi použitými pro vývoj Astral3D. Jedná se o knihovnu pro práci s 3D grafikou – OpenGL, multimediální knihovnu SDL a programovací jazyk C++.
3.1
Technologie OpenGL
3.1.1 OpenGL standard OpenGL (Open Graphics Library) v dnešní dobˇe pˇredstavuje standard pro vývoj 2D a hlavnˇe pak 3D grafických aplikací. Jedná se o specifikaci API k akcelerovaným grafickým kartám, které bylo navrženo firmou SGI (Silicon Graphics Inc). Jinak rˇ eˇceno – specifikace OpenGL je dokument popisující sadu funkcí a jejich pˇresné chování, které musí být splnˇeno. Na vytváˇrení a udržování této specifikace dohlíží organizace zvaná OpenGL Architecture Review Board (dále jen ARB), která byla založena v roce 1992. Jejími cˇ leny jsou velké svˇetové spoleˇcnosti zabývající se pˇredevším poˇcítaˇcovými technologiemi. K dnešnímu dni (4.3.2006) k nim patˇrí 3DLabs, Apple, ATI, Dell, IBM, Intel, NVIDIA, SGI a Sun Microsystems. Microsoft, jeden ze zakládajících cˇ lenu, ˚ vystoupil v bˇreznu 2003. Ostatní spoleˇcnosti jsou zvány stát se cˇ leny OpenGL ARB vždy po dobu jednoho roku.
3.1.2 Implementace OpenGL Výrobci grafických karet vytváˇrí vlastní implementaci knihovny zamˇerˇ enou pˇrímo na jejich hardware a spnující ˇ požadavky uvedené ve specifikaci. Pokud jejich akcelerátor nepodporuje urˇcitou požadovanou funkcionalitu, musí být taková záležitost emulována softwarovˇe. Obvykle se potom jedná o nezanedbatelné zpomalování celkového výkonu. Hotová implementace musí následnˇe projít speciálním testem, aby mohla být oficiálnˇe oznaˇcena jako implementace OpenGL. Pokud tato podmínka není splnˇena, nesmí být oznaˇcení OpenGL použito. Tento test (tzv. Conformance test) se skládá z nˇekolika programu, ˚ které zkouší jednotlivé cˇ ásti knihovny. Je tˇreba se zmínit o tom, že poplatek za tento test není pˇríliš nízký. To je také duvodem, ˚ proˇc nˇekteré knihovny implementující OpenGL mají jiné jméno. Dobrým pˇríkladem je tˇreba knihovna Mesa3D. 5
3.1. TECHNOLOGIE OPENGL 3.1.3 Architektura knihovny OpenGL ja navržena tak, aby zaruˇcovala maximální pˇrenositelnost na ruzné ˚ operaˇcní systémy a platformy, jako jsou napˇr. MS Windows, Linux, Mac OS X, UNIX, ale tˇreba i herní konzole od firmy Sony – Playstation 3. Taková pˇrenositelnost však pˇrináší jistá omezení. OpenGL je striktnˇe zamˇerˇ ena na vykreslování grafiky, a proto také neobsahuje žádné funkce pro práci s okny (vytváˇrení, zmˇena velikosti, rušení), práci s grafickým uživatelským rozhraním ani pro zpracování událostí. Tyto funkcionality musí být zajištˇeny bud’ pomocí volání funkcí pˇríslušného správce oken, nebo pomocí nˇekteré z nadstavbových knihoven, kterou je napˇr. GLUT (OpenGL Utility Toolkit). Tato knihovna poskytuje ruzné ˚ funkce pro vytváˇrení uživatelského rozhraní a pro správu událostí – ovládání myši, klávesnice, vysunovacích nabídek apod. Pro OpenGL však existuje více rozšiˇrujících knihoven. Mužeme ˚ zmínit GLU (OpenGL Utilities) obsahující funkce pro zobrazování složitˇejších geometrických obrazcu˚ a nastavování snímání scény. GLU je zpravidla vždy šíˇrena spolu s OpenGL, takže není problém ji bez jakékoliv instalace používat. AUX je další použitelná knihovna, která je v dnešní dobˇe již zastaralá a vˇetšina její funkcionality byla nahrazena novˇejšími knihovnami. Pojd’me se nyní podívat na seznam funkcí, které poskytuje základní implementace OpenGL. •
vykreslování základních geometrických tvaru˚ (body, úseˇcky, polygony)
•
texturování
•
svˇetla
•
stínování
•
míchání barev (tzv. alpha blending)
•
efekty s mlhou
•
podpora pro 2D obrázky
•
výpoˇcet viditelnosti scény
•
transformace (posuny, rotace, škálování)
•
speciální pamˇeti pro grafické efekty (accumulation a stencil buffer)
Bližší pohled na zpracování dat v OpenGL je znázornˇen na obrázku 3.1 – blokovém diagramu OpenGL. Zde je jasnˇe vidˇet, že vstupem pro zobrazení scény jsou vrcholy tvoˇrící polygony (vertex data) a obrázky reprezentující textury (pixel data). Výstupem je výsledný obraz ve speciální pamˇeti (frame buffer), ze které je následnˇe zobrazen na obrazovku. Popis jednotlivých operací zpracování scény sahá nad rámec této práce. 6
3.2. KNIHOVNA SDL
Obrázek 3.1: Blokový diagram OpenGL (zdroj: ).
3.2
Knihovna SDL
SDL (Simple DirectMedia Layer) je multimediální knihovna poskytující pˇrístup k audio a video systému, klávesnici, myši, joysticku a v neposlední rˇ adˇe také 3D hardwaru prostˇrednictvím OpenGL. Jedná se o velice rozšíˇrenou a oblíbenou knihovnu pro vývoj aplikací. SDL je multiplatformní a v souˇcasné dobˇe podporuje Linux, Windows, BeOS, MacOS Classic, MacOS X, FreeBSD, OpenBSD, BSD/OS, Solaris, IRIX a QNX. Navíc existuje neoficiální podpora pro Windows CE, AmigaOS, Dreamcast, Atari, NetBSD, AIX, OSF/Tru64, RISC OS a SymbianOS. SDL je napsána v programovacím jazyce C. Je tedy nativnˇe použitelná i v C++. Ovšem existují porty i pro jiné jazyky, kterými jsou Ada, Java, ML, Perl, PHP, Python a další. Vidíme tak, že knihovna SDL má široké využití. Jak je také patrné z jejího názvu, jedná se o relativnˇe malou (simple) knihovnu. Její API není pˇríliš velké a jádro obsahuje pouze základní funkcionalitu. Složitˇejší funkce jsou definovány v nadstavbových knihovnách, kterými jsou SDL_image pro naˇcítáni obrázku˚ (samotná SDL umí naˇcítat pouze formát BMP), SDL_sound a SDL_mixer pro zvuky, SDL_ttf pro truetype fonty, SDL_net pro sít’ové aplikace a další. Souˇcástí SDL API jsou také funkce pro vytvoˇrení okna OpenGL aplikace. To je hlavním duvodem, ˚ proˇc je kombinace SDL a OpenGL oblíbeným základem velkého množstí multimediálních programu. ˚ Jak již bylo v textu uvedeno, také GLUT je jednou z rozšiˇrujících knihoven OpenGL sloužící k vytváˇrení oken a správˇe událostí. Ovšem její licence nedovoluje distribuci pozmˇenˇeného zdrojového kódu. To by nebyl takový problém, kdyby GLUT pomalu nestárla. Alternativou je ještˇe knihovna Freeglut, která se snaží simulovat všechny funkce knihovny GLUT a jejíž kód lze mˇenit. Ovšem silná SDL se svou GNU LGPL 1 licencí je pro OpenGL stále ideálním partnerem.
1. GNU Library General Public License (více na ).
7
3.3. PROGRAMOVACÍ JAZYK C++
3.3
Programovací jazyk C++
Programovací jazyk C++ je moderním víceúˇcelovým programovacím jazykem, který byl vytvoˇren v AT&T Bell Laboratories. Jeho autorem je Bjarne Stroustrup, jenž zapoˇcal vývoj v roce 1980. C++ je postaven na efektivitˇe programovacího jazyka C a tˇrídách pˇrinášejících objektovˇe orientovaný pˇrístup. Podpora pro programování se šablonami 2 byla pˇridána pozdˇeji. V roce 1983 dostal C++ svuj ˚ název. Od té doby se jazyk ještˇe vyvíjel, než dostal dnešní tváˇr. V roce 1990 zaˇcala komise ANSI (American National Standart Institute) pˇripravovat jeho standardizaci. V období do její publikace, v roce 1998, zažil jazyk ohromnou expanzi a dnes je jedním z nejpoužívanˇejších programovacích jazyku˚ vubec. ˚ Nedávno se však zacˇ aly objevovat jazyky, které se nyní stávají velice silnými konkurenty pro C++. Ovšem stále zustávají ˚ oblasti, pro které je tento jazyk nenahraditelným.
2. Šablona je mechanismus datové abstrakce, kdy lze navrhovat algoritmy, aniž bychom pˇredem znali datové typy, které budou použity.
8
Kapitola 4
Seznámení s Astral3D 4.1
Základní informace
Astral3D je multiplatformní knihovna podporující Linux a MS Windows. Je kompletnˇe napsána v programovacím jazyce C++. Tento jazyk byl zvolen pro svou rychlost, nebot’ ta je pro oblast realtimových 3D animací kritická. Dalším duvodem ˚ pro výbˇer tohoto jazyka byl fakt, že základní implementace jak SDL, tak OpenGL, tedy knihoven použitých pro vývoj Astral3D, jsou napsány v jazyce C. Lze je tedy nativnˇe použít i v C++. Objektovˇe orientovaný pˇrístup je další pozitivní vlastností návrhu knihovny. K rˇ ízení verzí je použit systém Subversion. Repozitáˇr obsahující poslední verzi zdrojových kódu˚ je hostován na serverech BerliOS 1 . Veškeré potˇrebné informace lze také nalézt na oficiálním webu projektu 2 . Jak již bylo uvedeno výše, Astral3D je založena na knihovnách SDL a OpenGL. Ovšem to neznamená, že program využívající Astral3D nemuže ˚ zárovenˇ využívat služeb, které SDL spolu s OpenGL nabízejí. Právˇe naopak. Astral3D je koncipována tak, aby bylo možno obˇe tyto knihovny pˇrímo používat. Pro lepší znázornˇení tohoto vztahu se mužeme ˚ podívat na obrázek 4.1. Zde je jasnˇe vidˇet, že aplikace má pˇrístup nejen k aplikaˇcnímu programovému rozhraní Astral3D, ale také k obˇema knihovnám SDL a OpenGL. Výhody, které tato vlastnost pˇrináší, jsou zˇrejmé. Lze plnˇe využívat API všech tˇrí knihoven dohromady. Ještˇe je nutné se zmínit o dvou dalších knihovnách, které jsou použity – SDL_image a GLU. SDL_image slouží k naˇcítání obrázku˚ ze souboru˚ JPG, PNG a TGA. Tyto formáty samotná SDL naˇcítat neumí. GLU pak poskytuje sofistikovanˇejší funkce pro nastavení zobrazování scény, které cˇ asto využívá pˇredevším kamera.
4.2
API
Aplikaˇcní programové rozhraní má jasnˇe daná pravidla, která v nˇem výraznˇe ulehˇcují orientaci. Veškeré funkce a tˇrídy tvoˇrící knihovnu jsou uzavˇreny ve jmenném prostoru astral3d. Název každé tˇrídy zaˇcíná velkým písmenem „A“ symbolizujícím jméno knihovny. Toto neplatí pro tˇrídy abstraktní. Názvy metod a funkcí vždy zaˇcínají malým písmenem. Pokud je však název víceslovný, každé další slovo, které jej tvoˇrí, zaˇcíná písmenem velkým. 1. je bezplatná služba poskytující potˇrebné zázemí pro vývoj open source aplikací. Jedná se o konkurenta známé Sourceforge. 2. .
9
4.2. API
Obrázek 4.1: Závislosti mezi knihovnami. Šipky naznaˇcují vztah „využívá funkce z“. Pro lepší porozumˇení si mužeme ˚ uvést pˇríklad. Tˇrída ALevel sloužící k zobrazování virtuálního svˇeta obsahuje metodu pro import dat ze 3D modelu. Tato metoda se podle výše popsaných pravidel bude jmenovat buildFromModel. Dalším pˇríkladem je tˇreba metoda mouseButtonDown tˇrídy AWindow sloužící jako reakce na událost stisknutí tlaˇcítka myši. Jednou z nejduležitˇ ˚ ejších potˇreb programátora je dokumentace. Dokumentace k Astral3D API je generována pˇrímo ze zdrojových souboru˚ knihovny pomocí dokumentaˇcního systému Doxygen 3 . Hlaviˇckové soubory obsahují tzv. dokumentaˇcní komentáˇre. Jedná se o speciální komentáˇre, které pˇredcházejí definici tˇrídy, metody nebo funkce a které obsahují popis funcionality pro následující položku ve zdrojovém kódu. Programem Doxygen se potom vygeneruje hypertextová dokumentace ve formátu HTML stránek. To pˇrináší velké usnadnˇení, nebot’ pˇri psaní knihovny se zárovenˇ vytváˇrí i dokumentace. Jakákoliv zmˇena API se v ní pak muže ˚ okamžitˇe projevit. Následuje seznam tˇríd a struktur, které tvoˇrí aplikaˇcní programové rozhraní Astral3D. •
Model3D – abstraktní tˇrída pro naˇcítání a zobrazování 3D modelu˚
•
CollisionEllipsoid – abstraktní tˇrída pro kolize s virtuálním svˇetem
•
Level – abstraktní tˇrída pro zobrazování virtuálního svˇeta
•
A3DSModel – tˇrída pro naˇcítání a zobrazování 3D modelu˚ ve formátu 3DS
•
ACamera – tˇrída pro pohyb v prostoru a snímání scény
•
ACollisionPacket – struktura pro provádˇení detekce kolizí
3. Program pro vytváˇrení dokumentace pˇrímo ze zdrojových souboru˚ podporující velké množství programovacích jazyku˚ (více na ).
10
4.2. API •
AConsole – tˇrída pro textovou interakci s uživatelem
•
AError – struktura pro rˇ ízení chybových hlášení
•
ALevel – tˇrída pro zobrazování virtuálního svˇeta
•
ALight – tˇrída pro práci s dynamickým svˇetlem
•
APlane – struktura pro popis geometrické plochy ve 3D prostoru
•
AQuad – struktura pˇredstavující cˇ tuˇrúhelník s texturou
•
ARectangle – struktura reprezentující obdélníkovou oblast
•
ASurface – tˇrída pro vykreslování 2D grafiky
•
AText2D – tˇrída pro textový výstup na obrazovku
•
ATriangle – struktura pˇredstavující trojúhelník s texturou
•
AVector – tˇrída pro práci s trojrozmˇerným vektorem
•
AWindow – tˇrída pro zobrazování a manipulaci s okny
Jednotlivé tˇrídy mohou mezi sebou ruznˇ ˚ e komunikovat a využívat jedna druhou. Tato vlastnost je zobrazena na obrázku 4.2. Zde mužeme ˚ vidˇet nˇekteré základní tˇrídy Astral3D a jejich vzájemné vztahy. Na obrázku jsou tˇri abstraktní tˇrídy, které jsou znázornˇeny cˇ árkovanˇe. Jsou jimi Model3D pro naˇcítání a zobrazování 3D modelu, ˚ CollisionEllipsoid pˇredstavující objekt, vuˇ ˚ ci kterému se provádí kolize s virtuálním svˇetem, který je reprezentován abstraktní tˇrídou Level. Potomci tˇechto tˇríd jsou potom jejich jednotlivé implementace. Na obrázku je také naznaˇcen vztah komunikace. Zde napˇr. abstraktní tˇrída CollisionEllipsoid komunikuje s abstraktní tˇrídou Level. Tato komunikace je duležitá ˚ pro výpoˇcet detekce kolizí. V praxi potom kamera reprezentována tˇrídou ACamera muže ˚ provádˇet detekce kolizí vuˇ ˚ ci virtuálnímu svˇetu – tˇrídˇe ALevel. Další komunikace jen ve struˇcnosti. Konzole potˇrebuje od okna aplikace získávat informace o stisknutých klávesách a zárovenˇ musí mít asociován font (tˇrídu AText2D), pomocí kterého bude vypisovat textové zprávy. Poslední komunikací je vytvoˇrení virtuálního svˇeta pˇrímo ze 3D modelu.
11
4.2. API
Obrázek 4.2: Vztahy mezi základními tˇrídami tvoˇrícími aplikaˇcní programové rozhraní Astral3D.
12
Kapitola 5
Architektura knihovny Astral3D Tato kapitola popisuje architekturu Astral3D. Knihovna je napsána v programovacím jazyce C++, proto se pˇredpokládá jeho základní znalost.
5.1
ˇ Rízení chybových hlášení
Žádný program není dokonalý. Pˇri každém spuštˇení vždy existuje šance, že dojde k chybˇe. Ta muže ˚ být ruzného ˚ puvodu. ˚ Špatný návrh programu na stranˇe jedné, chyba v systému pak na stranˇe druhé. Vˇetšina knihoven definuje urˇcitou sadu funkcí, které se starají o správu chyb. Pod tímto pojmem si mužeme ˚ pˇredstavit detekci chyb, které nastaly a jejich oznámení uživateli, aby bylo jasné, proˇc k nim vubec ˚ došlo. To je velice duležité, ˚ protože uživatel muže ˚ na chybu pˇríslušnˇe reagovat napˇr. tím, že bezpeˇcnˇe ukonˇcí program. Astral3D využívá výjimek. Výjimky jsou mocným nástrojem pro zpracování chyb a neoˇcekávaných událostí. Následuje seznam výjimek implementovaných v knihovnˇe. •
AException – je pro všechny ostatní výjimky pˇredkem a tvoˇrí vrchol celé hierarchie. Zpravidla není generována žádnou metodou. Pokud však dojde k blíže nespecifikované chybˇe, muže ˚ být v takovém pˇrípadˇe AException použita.
•
AIllegalArgumentException – je generována jako reakce na neplatný argument metody nebo funkce. Tím je zaruˇceno, že budou zpracovány pouze platná data.
•
AIOException – tato výjimka signalizuje chybu cˇ tení nebo zápisu. V souˇcasné dobˇe je použita pouze pro vstupní a výstupní operace provádˇené se soubory.
•
AReadFileException – je potomkem AIOException a blíže specifikuje, že se jedná o chybu cˇ tení ze souboru.
•
AWriteFileException – je potomkem AIOException a blíže specifikuje, že se jedná o chybu zápisu do souboru.
•
AMemoryAllocException – urˇcuje chybu dynamické alokace pamˇeti pˇri bˇehu programu. Astral3D totiž provádí výpoˇcty, které vyžadují cˇ astou práci právˇe s dynamickou pamˇetí.
•
ANullPointerException – výjimka signalizující neplatný ukazatel na pamˇet’. 13
5.2. PRÁCE S OKNY A ZPRACOVÁNÍ UDÁLOSTÍ •
ASDLException – tato výjimka urˇcuje, že došlo k chybˇe pˇri volání funkcí z knihovny SDL. Mechanismus, který zjistí podrobné informace o pˇrípadné chybˇe, je popsán níže v této kapitole.
•
ATextureException – vytváˇrení textury ze souboru muže ˚ selhat hned v nˇekolika bodech. Je to zpusobeno ˚ podporou pro více formátu˚ grafických souboru. ˚ Tato výjimka pˇrípadnou chybu oznámí.
Dále je v Astral3D k dispozici tˇrída AError. Ta obsahuje informace o poslední chybˇe v programu. Každá funkce, která v Astral3D muže ˚ selhat, tedy i funkce generující výjimku, tyto informace nastavuje. Instanci tˇrídy AError získáme voláním getAstral3DError. Podívejme se na následující kód: try { window->create(800, 600, 16); } catch(AException &e) { cerr << getAstral3DError(); exit(1); }
Zde mužeme ˚ vidˇet pokus o vytvoˇrení okna o rozmˇerech 800x600 pixelu˚ s barevnou hloubkou 16 bitu. ˚ Pokud takový program spustíme v textovém režimu, je celkem jasné, že grafické okno se vytvoˇrit nepodaˇrí, metoda create vygeneruje výjimku a program bude ukonˇcen s návratovou hodnotou 1. Na standardním chybovém výstupu pak uvídíme tento text: Error Description: No available video device Sender Function: AWindow::create(800, 600, 16, 0, 0) Failed Function: SDL_Init(SDL_INIT_VIDEO)
Jak již bylo rˇ eˇceno, getAstral3DError vrací instanci tˇrídy AError, která definuje pˇretížený operátor << pro textový výstup. My jsme jej použili pro výpis chyby obsahující tˇri položky. První je popis hlášení a rˇ íká nám, co se stalo. V tomto pˇrípadˇe nebylo nalezeno vhodné grafické zaˇrízení (jsme v textovém režimu). Druhým hlášením je funkce, která chybu vygenerovala. V našem pˇrípadˇe se jedná o metodu create tˇrídy AWindow, pomocí které jsme se pokoušeli vytvoˇrit okno. Poslední položka pˇresnˇe urˇcuje funkci, která selhala. SDL_Init je pˇríkazem knihovny SDL, pomocí kterého se inicializují jednotlivé cˇ ásti knihovny. Grafický subsystém je jednou z tˇechto cˇ ástí.
5.2
Práce s okny a zpracování událostí
Vytvoˇrení a manipulace s oknem aplikace je spolu se zpracováním událostí jednou z nejduležitˇ ˚ ejších oblastí, o kterou se Astral3D stará. Pro tyto úˇcely slouží tˇrída AWindow. Ta 14
5.2. PRÁCE S OKNY A ZPRACOVÁNÍ UDÁLOSTÍ obsahuje metody, pomocí kterých se okno vytváˇrí a pracuje se s ním. Navíc definuje množinu metod virtuálních, které mohou být v potomkovi okna pˇrekryty. Tyto metody slouží pˇredevším jako handlery 1 pro zpracování událostí. Typickým použitím tˇrídy AWindow je tedy vytvoˇrení tˇrídy nové, která je jejím potomkem a pˇrekrývá všechny potˇrebné metody. Následující kód ukazuje, jak by mohla taková nová tˇrída vypadat. class MyWindow : public AWindow { public: bool init(); void loop(); void exit(); void render(); void keyDown(SDL_keysym *keysym); void keyUp(SDL_keysym *keysym); };
Zde jsme vytvoˇrili tˇrídu MyWindow a definovali ji metody. Všechny jsou virtuální ve tˇrídˇe AWindow a v programu budou spuštˇeny podle pˇredem daných pravidel. •
init – je volána pouze jednou (pˇri vytvoˇrení okna). Patˇrí sem kód, který provádí potˇrebnou inicializaci celého programu. Pokud tato metoda vrátí hodnotu false, spuštˇení programu se nezdaˇrí.
•
loop – je volána cyklicky po celou dobu bˇehu programu. Patˇrí do ní výpoˇcty, které je nutno neustále opakovat.
•
render – je volána okamžitˇe po loop a patˇrí do ní kód, který provádí vykreslení scény.
•
exit – je opakem init. Je tedy volána pˇri ukonˇcení programu resp. rušení okna.
•
keyDown – je handler pro událost stisknutí klávesy.
•
keyUp – je handler pro událost uvolnˇení klávesy.
Veškerý zdrojový kód vztahující se k danému oknu muže ˚ být tedy umístˇen v tˇechto metodách. Posledním krokem k dokonˇcení programu je vytvoˇrení a spuštˇení okna. To provádíme metodami create a run ve vstupním bodˇe programu – funkci main. int main(int argc, char *argv[]) { MyWindow *window; try { window = new MyWindow(); window->create(800, 600, 16); 1. Handler pro zpracování události je funkce, která je spuštˇena v okamžiku, kdy daná událost nastane. Tedy napˇr. pˇri stisknutí tlaˇcítka myši se spustí funkce reagující právˇe na tuto událost.
15
5.2. PRÁCE S OKNY A ZPRACOVÁNÍ UDÁLOSTÍ window->setCaption("Test"); window->setIcon("test.bmp"); window->run(); } catch(AException &e) { cerr << "Exception: " << e << endl; delete window; return 1; } return 0; }
Na tomto pˇríkladu mužemem ˚ vidˇet, že okno je nejprve vytvoˇreno pomocí, již zminované, ˇ metody create. Dále jsou mu nastaveny parametry (popisek a ikona) a poté je teprve spuštˇeno. Nyní si popíšeme cˇ tyˇri základní vstupní události, na které je okno schopno reagovat. Jsou jimi stisknutí a uvolnˇení klávesy a stisknutí a uvolnˇení tlaˇcítka myši. Pro první dvˇe slouží metody keyDown a keyUp a pro druhé pak mouseButtonDown a mouseButtonUp. Podívejme se na následující cˇ ást kódu: void MyWindow::keyDown(SDL_keysym *keysym) { switch(keysym->sym) { case SDLK_ESCAPE: this->destroy(0); break; } }
Zde vidíme, že parametrem keyDown resp. keyUp je ukazatel na strukturu SDL_keysym obsahující informace o stisknuté klávese. Struktura SDL_keysym je pˇrevzata z knihovny SDL. V její dokumentaci lze tedy nalézt všechny potˇrebné informace. Ve výše uvedeném pˇríkladu reagujeme na stisknutí klávesy Escape zrušením okna a ukonˇcením programu s návratovou hodnotou 0. Na posledním ukázkovém pˇríkladu zpracování událostí je metoda mouseButtonDown, která má tˇri parametry. Pozici kurzoru myši v oknˇe (x a y) a identifikátor stisknutého tlacˇ ítka. Ten muže ˚ nabývat hodnot: SDL_BUTTON_LEFT SDL_BUTTON_MIDDLE SDL_BUTTON_RIGHT
Opˇet se jedná o definice pˇrevzaté z knihovny SDL. void MyWindow::mouseButtonDown(int x, int y, int button) {
16
5.3. SNÍMÁNÍ SCÉNY switch(button) { case SDL_BUTTON_LEFT: // stisknuto levé tlaˇ cítko myši break; } }
5.3
Snímání scény
Ke snímání scény a pohybu v trojrozmˇerném prostoru slouží kamera. Ta je reprezentována tˇrídou ACamera. Jedná se o jednu z nejduležitˇ ˚ ejších souˇcástí Astral3D. V OpenGL se pro orientaci ve 3D prostoru používá kartézský systém souˇradnic. Pˇresná poloha kamery je potom urˇcena cˇ tyˇrmi body (viz obrázek 5.1).
Obrázek 5.1: Kamera je charakterizována cˇ tyˇrmi body. Eye je pozice kamery, front je bod, na který je kamera nasmˇerována, top urˇcuje bod umístˇený nad kamerou a right pak napravo od kamery. Vektory, které jsou tvoˇreny tˇemito body spolu vždy svírají pravý úhel. Pˇresnou polohu kamery lze popsat pouze tˇremi body v prostoru. Eye je zde redundantním bodem, který slouží pouze k jednodušší orientaci. Tˇrída ACamera definuje nˇekolik metod pro pohyb. Tˇemi hlavními jsou move a step. Obˇe mají jeden parametr, který urˇcuje smˇer pohybu. Tento parametr muže ˚ nabývat hodnot: •
FORWARD – pohyb vpˇred
•
BACKWARD – pohyb vzad 17
5.3. SNÍMÁNÍ SCÉNY •
LEFT – pohyb vlevo
•
RIGHT – pohyb vpravo
•
UP – pohyb nahoru
•
DOWN – pobyh dolu˚
Metody se od sebe nepatrnˇe liší, step pˇri pohybu vpˇred nebere v úvahu natoˇcení kamery. Toho využijeme, chceme-li se s kamerou ruznˇ ˚ e natáˇcet, ale pˇri pohybnu stále zustávat ˚ na jedné ploše (v jedné rovinˇe). Pro jednodušší práci s kamerou jsou definovány ještˇe další metody pro pohyb, jsou jimi: •
moveForward
•
moveBackward
•
moveLeft
•
moveRight
•
moveUp
•
moveDown
Tyto metody nemají žádný parametr a pouze volají move s požadovaným smˇerem pohybu. Pro step jsou definovány taktéž. Na obrázcích 5.2, 5.3 a 5.4 jsou znázornˇeny výpoˇcty pohybu˚ pro požadovaný smˇer.
Obrázek 5.2: Pohyb vpˇred a vzad se rˇ ídí podle vektoru urˇceného body eye a front. Dalším duležitým ˚ pohybem kamery je rotace. Ta natáˇcí kameru do cˇ tyˇr stran – napravo, nalevo, nahoru a dolu. ˚ Rotaci vynutíme voláním metody turn. Jejími parametry jsou smˇer a úhel natoˇcení. Ovšem k dispozici je i funkce natáˇcení kamery pomocí myši. Celý mechanismus funguje na principu odchylek od stˇredové pozice. Kurzor je nastaven na stˇred okna a pˇri každém pohybu myši je mírnˇe vychýlen. Jeho nová pozice je pak použita pro 18
ˇ A 3D MODELY 5.4. VIRTUÁLNÍ SV ET
Obrázek 5.3: Pohyb vpravo a vlevo se rˇ ídí podle vektoru urˇceného body eye a right.
Obrázek 5.4: Pohyb nahoru a dolu˚ se rˇ ídí podle vektoru urˇceného body eye a top. výpoˇcet požadované rotace. Abychom však mohli využívat tuto funkcionalitu, musíme kameˇre nejprve asociovat okno, ze kterého budou získávány informace o pohybu kurzoru. To provedeme pomocí metody setWindow. Poslední velice duležitou ˚ vˇecí je volání metody mouseProcedure pˇri každém výpoˇctu scény, tedy napˇr. v metodˇe loop tˇrídy AWindow. Takto jsme propojili kameru s oknem a mužeme ˚ naplno využívat rotaci pomocí myši.
5.4
Virtuální svˇet a 3D modely
Naˇcítání a zobrazování trojrozmˇerných modelu˚ je jedním z hlavních úkolu˚ grafických 3D engine. Astral3D pro tyto úˇcely definuje abstraktní tˇrídy Level a Model3D. První zminovaná ˇ slouží ke zpracování vlastního formátu souboru, ˚ druhá potom pro naˇcítání a zobrazování 3D modelu˚ formátu˚ existujících. Implementací Model3D je tˇrída A3DSModel, která naˇcítá a zobrazuje 3D Studio (3DS) modely. ALevel je potomkem Level a umí zpracovat vlastní formát souboru, ˚ který Astral3D definuje. ALevel je pomˇernˇe složitá tˇrída, která slouží pˇredevším pro vykreslování virtuálního svˇeta. Jejím prostˇrednictvím lze naˇcítat, zobrazovat, modifikovat a ukládat vlastní formát modelu, který je uložen v textovém souboru majícím následující formát. Na první rˇ ádce je 19
ˇ A 3D MODELY 5.4. VIRTUÁLNÍ SV ET uveden poˇcet textur. Následuje jejich seznam. Na každém rˇ ádku je uvedeno cˇ íslo (identifikátor textury) a jméno souboru s texturou. Podporované formáty souboru˚ jsou TGA, JPEG, BMP a PNG. Další cˇ íslo udává poˇcet trojúhelníku˚ tvoˇrících model. Nakonec je uveden jejich seznam, který má následující tvar. Na první rˇ ádce je identifikátor textury, který urˇcuje, jaká textura bude pro trojúhelník použita. Na dalších tˇrech rˇ ádkách jsou specifikovány tˇri vrcholy. Každý je urˇcen pˇeti hodnotami – pozice v prostoru (x, y a z) a koordináty pro mapování textury (u a v). Poslední rˇ ádka popisující trojúhelník obsahuje tˇri hodnoty pro definici normály. Jedná se tedy o normálový vektor plochy tvoˇrené tímto trojúhelníkem. Uvedmˇe si nyní malý pˇríklad modelu, který je tvoˇren dvˇema trojúhelníky a jednou texturou. 1 0 textura.bmp 2 0 -5 0 5 5 0 5 5 0 -5 0 1 0 0 5 0 -5 -5 0 -5 -5 0 5 0 1 0
0 5 5
5 5 0
5 0 0
0 0 5
Další velmi užiteˇcnou funkcí, o kterou se tˇrída ALevel stará, je detekce kolozí s kamerou. Resp. abstraktní tˇrída Level provádí detekce kolizí s abstraktní tˇrídou CollisionEllipsoid, jíž je kamera potomkem. Detekce kolizí ve 3D prostoru je pomˇernˇe složitá záležitost. Na obrázku 5.5 je znázornˇena ve dourozmˇerném prostoru a pomˇernˇe zjednodušena, ovšem princip zustává. ˚ Objekt, který je reprezentován kružnicí, se snaží udˇelat pohyb z bodu A do bodu B. Ovšem ve smˇeru pohybu nastává kolize s pˇrekážkou. Objekt se posouvá na dotek k pˇrekážce (do pozice C), ale dále již nemuže. ˚ Nyní pˇrichází na rˇ adu reakce na kolizi. Astral3D využívá tzv. sliding – posun po pˇrekážce. Z puvodní ˚ cílové pozice B je spuštˇena kolmice na pˇrekážku. V místˇe, kde dojde k pruniku ˚ této kolmice a rovnobˇežky s pˇrekážkou vycházející z dotekového místa C, je koneˇcná pozice D. V praxi tento systém dosahuje pocitu velice realistického pohybu. Ale je duležité ˚ si uvˇedomit hned nˇekolik problému. ˚ Posunování objektu podél pˇrekážky do koneˇcné pozice není nic jiného, než další pohyb, pˇri kterém muže ˚ opˇet nastat kolize. Celá procedura tak musí být volána rekurzivnˇe. Složitost výpoˇctu pak závisí na poˇctu provedených kolizí a hloubce rekurze. Dalším problémem je množství polygonu, ˚ vuˇ ˚ ci kterým se kolize provádí. Je nutné si uvˇedomit, že scéna muže ˚ být tvoˇrena až statisíci polygony. Proto se zavádí ruzné ˚ techniky, které minimalizují poˇcet polygonu˚ pro výpoˇcet. Jednou takovou technikou je dˇelení prostoru do podprostoru. ˚ Kolize je potom provádˇena pouze v dané cˇ ásti. Astral3D zavádí „sphere test“. Detekce kolizí je provádˇena pouze uvnitˇr sféry urˇcené pozicí a polomˇerem. Podle velikosti této sféry se testuje více cˇ i ménˇe polygonu˚ a urychluje se tak výpoˇcet. 20
ˇ A 3D MODELY 5.4. VIRTUÁLNÍ SV ET
Obrázek 5.5: Princip detekce kolize a reakce na ni. Pˇri pohybu z místa A do B nastává kolize v místˇe C. Reakcí na kolizi je tzv. sliding – posun objektu po pˇrekážce do nového cílového místa D. Následující kód ukazuje potˇrebé nastavení, které je nutné provést, aby byla detekce kolizí funkˇcní. ALevel *level; ACamera *camera; ... camera->enableCollision(); camera->setLevel(level); camera->setEllipsoid(AVector(1.0, 1.0, 1.0)); level->setSphereRadius(5.0); level->setSpherePosition(camera.getEye()); level->enableSphere();
Kameˇre je povolena detekce kolizí a asociován model, ve kterém se budou kolize provádˇet. Dále je kameˇre nastaven elipsoid – tˇeleso, vuˇ ˚ ci kterému se kolize provádí (na obrázku 5.5 je tento objekt znázornˇen kružnicí). Sféra, ve které dochází k testování kolizí, je nastavena pomocí metod setSphereRadius a setSpherePosition. Druhá zminovaná ˇ urcˇ uje její stˇred. Ten musí být upraven pokaždé pˇri pohybu kamery. Vhodné umístˇení pro volání setSpherePosition je tedy metoda loop tˇrídy AWindow. 21
5.5. INTERAKCE S UŽIVATELEM
5.5
Interakce s uživatelem
Interakce s uživatelem probíhá prostˇrednictvím textové konzole. Do ní je systém schopen vypisovat informace a uživatel muže ˚ zadávat pˇríkazy pomocí klávesnice. Jedná se o jednoduché, ale zato velice efektivní rozhraní. S konzolí je asociována funkce pro zpˇetnou vazbu. Pokud uživatel stiskne klávesu Enter, je tato funkce spuštˇena a jako parametr je jí pˇredán zadaný pˇríkaz. Záleží pak na implementaci, na jaké pˇríkazy bude program reagovat. Textovou konzoli pˇredstavuje tˇrída AConsole. Další neménˇe duležitou ˚ tˇrídou je také AText2D. Ta slouží pro naˇcítání a zobrazování fontu, tedy pro výpis textu na obrazovku. Konzole ji používá pro zobrazování zpráv. Tˇrída AText2D využívá bitmapu – obrázek tvorˇ ený cˇ ernou a bílou barvou, ve kterém jsou vyobrazeny všechny znaky, které chceme vypisovat. Tento obrázek je naˇcten ze souboru. Dále musí být nastaven popis znaku. ˚ Popis znaku˚ je textový rˇ etˇezec, v nˇemž jsou uvedeny všechny znaky na obrázku cˇ teny zleva shora. Mu˚ žeme se podívat na pobrázek 5.6, kde je uveden ukázkový font pro naˇctení tˇrídou AText2D. Jeho popis znaku˚ je následující: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789:
Obrázek 5.6: Bitmapa s fontem, pomocí kterého lze vypisovat zprávy za použití tˇrídy AText2D.
5.6
2D grafika
Astral3D je knihovna zamˇerˇ ená pˇredevším na 3D grafiku. Ovšem existuje i podpora pro vykreslování grafiky dvoudimenzionální. Toho lze využít napˇr. pro vytvoˇrení grafického rozhraní, tedy zobrazování prvku, ˚ kterými lze ovládat program. Princip je jednoduchý. Pˇred každým renderováním 2D obrázku se zmˇení OpenGL nastavení ze 3D na 2D kartézské sourˇ adnice, které odpovídají velikosti rozlišení obrazovky. Potom již není problém definovat souˇradnice, na které se má daná cˇ ást obrázku vykreslit. Pro tyto úˇcely slouží tˇrída ASurface. Pomocí ní lze nejen pracovat s 2D grafikou, ale také nastavovat ruzné ˚ efekty jako napˇr. pruhlednost, ˚ zmenšení a zvˇetšení obrázku apod. Následující kód ukazuje možné použití: 22
5.6. 2D GRAFIKA ASurface *image image = new ASurface("obrazek.png", window); ... image->begin(); image->draw(10, 20, ARectangle(10, 10, 20, 20)); image->draw(ARectangle(50, 50, 30, 30), ARectangle(10, 10, 20, 20)); image->end()
Zde mužeme ˚ vidˇet, že vykreslování obrázku provádí metoda draw. Jedná se o pˇretíženou metodu. Její první varianta má tˇri parametry, kterými jsou cílové souˇradnice na obrazovce (x a y) a struktura ARectangle definující oblast zdrojového obrázku, která má být vykreslena. Druhá varianta metody draw má parametry pouze dva. Jsou jimi cílová a zdrojá oblast. Obˇe jsou rovnˇež definované pomocí ARectangle. Na pˇríkladu jsou také vidˇet další dvˇe metody – begin a end. Na nˇe nesmíme zapomínat, protože právˇe ony provádˇejí výše zminovanou ˇ zmˇenu OpenGL nastavení, aby bylo možné vykreslovat 2D grafiku. Poslední vˇecí je použitý systém souˇradnic. Jeho poˇcátek je pro cílové okno i zdrojový obrázek stejný – levý dolní roh poˇcítáno v obrazových bodech (pixelech).
23
Kapitola 6
Další možná rozšíˇrení Astral3D je knihovna, která implementuje základní principy grafických 3D engine. Ovšem od profesionálního nasazení má ještˇe daleko. Je to zpusobeno ˚ hned nˇekolika faktory. Mezi ty hlavní patˇrí poˇcet vývojáˇru˚ a cˇ as. Použitelné produkty na poli 3D engine vznikají po dobu nˇekolika let a na jejich vývoji se podílí až desítky vývojáˇru. ˚ To umožnuje ˇ použití ruzných ˚ technik a funkcionalit, o které je Astral3D ochuzena. Tato kapitola chce ukázat, jakým smˇerem by se knihovna mohla dále vyvíjet a jaká další rozšíˇrení by pro ni byla vhodná. První oblastí rozšíˇrení je urychlení snímání scény. Jak již víme, ke snímání scény slouží kamera. Ta je nasmˇerována jedním smˇerem, ve kterém zachytí všechny viditelné objekty. Vše ostatní, co není z pohledu kamery vidˇet, pouze zatˇežuje výpoˇcet. Vhodná implementace tˇrídy, která by byla schopna otestovat, zda-li se daný objekt nachází pˇred kamerou, by velice urychlila celý program. V takovém pˇrípadˇe by se totiž OpenGL nemusela o tyto „neviditelné“ objekty vubec ˚ starat. Nemusela by je sama zpracovávat a nakonec zjistit, že jsou stejnˇe nepoužitelné. Tˇeleso, které svým tvarem pˇripomíná oblast snímanou kamerou, je komolý jehlan (angl. frustum). A právˇe tˇrídu, která provádí tuto funkcionalitu, mužeme ˚ najít v mnoha grafických 3D engine. Je tedy vidˇet, že tato technika je cˇ asto využívána a urˇcitˇe má své uplatnˇení. Dalším nezbytným rozšíˇrením je podpora pro naˇcítání a zobrazování více formátu˚ 3D modelu. ˚ V souˇcasné dobˇe je implementována pouze tˇrída A3DSModel pro zpracování 3DS souboru. ˚ Dále je k dispozici abstraktní tˇrída Model3D, která by mˇela být pro všechny ostatní tˇrídy pracující se 3D modely pˇredkem. Mezi další podporované formáty by mˇel urˇcitˇe patˇrit Wavefront object. Ten pˇrichází ve dvou variantách – textové a binární. Textový Wavefront object soubor má koncovku „.obj“, binární pak „.mod“. Výhodou textového formátu je snadná ruˇcní editace jakýmkoliv textovým editorem. Formát Wavefront object obsahuje veškerá potˇrebná data pro zobrazování 3D modelu˚ vˇcetnˇe textur. Samotnou kapitolu 3D modelu˚ by potom mohl tvoˇrit formát BSP (Binary Space Partitioning). Tento formát je použit pro ukládání informací o 3D svˇetˇe v mnoha poˇcítaˇcových hrách. BSP formátu˚ je hned nˇekolik. Tím nejznámˇejším je Quake 3 BSP. Tyto soubory obsahují nejen grafická data, ale i ostatní uživatelem definované entity, které mohou být pro danou aplikaci užiteˇcné. Samotná grafická data pak obsahují navíc napˇr. svˇetelné textury. Jedná se o techniku míchání více textur dohromady, pˇri které se docílí efektu osvˇetlení objektu bez použití dynamických svˇetel. Jak již také název napovídá, data jsou v BSP souboru reprezentována binárním stromem. To pˇrináší mnoho výhod, jako je tˇreba jednodušší provádˇení detekce kolizí. Ovšem na druhou stranu je tˇreba rˇ íci, že implementace podpory pro 24
ˇ 6. D ALŠÍ MOŽNÁ ROZŠÍ RENÍ
BSP formáty do knihovny Astral3D by svou obtížností byla další samostatná práce. ˇ Cásticové systémy by mohly být dalším rozšíˇrením. Nejprve by bylo vhodné navrhnou abstraktní tˇrídu, která by byla pro všechny cˇ ásticové systémy urˇcitým rozhraním. Potom by se již mohlo pˇristoupit k implementaci jednotlivých systému, ˚ mezi které by jistˇe patˇrily efekty ohnˇe, jisker, snˇehu, deštˇe, tekoucí vody apod. Více informací o cˇ ásticových systémech lze nalézt v kapitole, která se zabývá obecnými technikami grafických 3D engine.
25
Kapitola 7
Závˇer Cílem této práce bylo navrhnout a implementovat grafickou knihovnu na základech OpenGL pro podporu 3D animací. Výsledkem je knihovna nesoucí jméno Astral3D, která je založena na knihovnách SDL a již zminované ˇ OpenGL. Celý systém je objektovˇe orientovaný díky použití programovacího jazyka C++. Pod pojmem 3D animace si mužeme ˚ pˇredstavit trojdimenzionální scénu, ve které se mužeme ˚ pohybovat nebo kterou mužeme ˚ alesponˇ sledovat. Pro tyto úˇcely Astral3D zavádí tˇrídy pro naˇcítání a zobrazování ruzných ˚ modelu˚ a samozˇrejmˇe kameru, pomocí které tyto modely sledujeme. Knihovna však pˇrináší mhohem více. Detekce kolizí a interakce objektu˚ ve scénˇe pˇredstavuje realistickou simulaci pohybu ve 3D svˇetˇe, který muže ˚ být navíc osvˇetlen dynamickými svˇetly. Celý program lze ovládat prostˇrednictvím textové konzole a využívat i podporu pro vykreslování 2D grafiky. Práce s okny a zpracování událostí je samozˇrejmostí a tvoˇrí základ aplikací využívajících Astral3D. Nedílnou souˇcástí knihovny ja také dokumentace. Bez kvalitní dokumentace by programátor jen stˇeží využíval plnou funkcionalitu, kterou knihovna nabízí. Jak již víme, Astral3D využívá systém Doxygen pro generování dokumentace k aplikaˇcnímu programovému rozhraní pˇrímo ze zdrojových souboru. ˚ Dokumentace je navíc psána v anglickém jazyce. Výhodou anglického jazyka je použitelnost pro širší spektrum uživatelu˚ a zárovenˇ odpadají problémy s diakritikou ve zdrojových souborech v pˇrípadˇe použití cˇ eštiny. Tato práce také podává odpovˇed’ na otázku srovnání Astral3D s jinými knihovnami zabývajícími se 3D grafikou. V úvodu práce je zmínˇena kapitola o obecných technikách použitých ve 3D engine. Následující kapitoly pak ukazují vlastnosti a funkcionality knihovny Astral3D. Mužeme ˚ tak jednoduše porovnat jaké funkcionality jsou a jaké naopak nejsou implementovány. Je tedy jasné, že Astral3D v souˇcasné dobˇe nelze použít k vytvoˇrení nˇejakého velkého projektu, na který bychom použili napˇr. knihovnu Irrlich 3D. Lze ji však použít jako základ pro rychle napsanou aplikaci, ve které potˇrebujeme pracovat se 3D grafikou na nejnižší úrovni – tedy využívat pˇrímo OpenGL API. Po pˇridání rozšíˇrení uvedených v pˇredchozí kapitole bude knihovna Astral3D zcela plnˇe použitelná i pro rozsáhlejší aplikace. Astral3D je projektem, na kterém se daly prakticky ovˇerˇ it techniky použité v grafických 3D engine. Autor se díky tomu mohl seznámit s ruznými ˚ aspekty návrhu knihovny a využitím grafického rozhraní OpenGL. Také si ovˇerˇ il nároˇcnost celého procesu vývoje. Programování 3D grafiky totiž vyžaduje znalosti nejen z oblasti informatiky, ale také matematiky, zejména pak lineární a vektorové algebry.
26
Dodatek A
Pˇríklad použití Astral3D Na pˇríkladu A.1 mužeme ˚ vidˇet zdrojový kód programu, který naˇcte 3D model ze souboru „model.3ds“ umístˇený i s texturami ve stejném adresáˇri jako spustitelný program. Nastaví pozici kamery na bod v prostoru o souˇradnicích [0,5,5] a natoˇcí ji o tˇricet stupnˇ u˚ dolu. ˚ Z tohoto místa kamera snímá model. Celá scéna se odehrává v oknˇe o rozmˇerech 640x480 pixelu, ˚ pˇriˇcemž hloubka barev je 16 bitu. ˚ //---------------------------------------------------------------------// pˇ ríklad A.1 //---------------------------------------------------------------------#include #include using namespace std; using namespace astral3d; class Window : public AWindow { private: ACamera *camera; Model3D *model; public: bool init(); void render(); void exit(); }; //---------------------------------------------------------------------int main() { AWindow *window; try { window = new Window(); window->create(640, 480, 16); window->run(); } catch (AException &e)
27
ˇ A. P RÍKLAD POUŽITÍ A STRAL 3D
{ cerr << "Exception: " << e << endl; delete window; return 1; } return 0; } //---------------------------------------------------------------------bool Window::init() { camera = new ACamera(); model = new A3DSModel("model.3ds", "./"); camera->setPosition(AVector(0.0, 5.0, 5.0)); camera->lookDown(30.0); glEnable(GL_TEXTURE_2D); return true; } //---------------------------------------------------------------------void Window::render() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); camera->set(); model->render(); } //---------------------------------------------------------------------void Window::exit() { delete camera; delete model; } //---------------------------------------------------------------------// konec pˇ ríkladu A.1 //----------------------------------------------------------------------
28
Dodatek B
Obrázková galerie Tato pˇríloha obsahuje obrázky z programu, ˚ které byly napsány pomocí knihovny Astral3D. Zdrojové soubory ke všem níže uvedeným programum ˚ jsou souˇcástí linuxové distribuce knihovny.
Obrázek B.1: Tento program ukazuje použití kamery pro snímání scény. Na obrázku je vidˇet poˇcátek souˇradnic, pomocích kterých se definuje poloha ve 3D prostoru.
29
B. O BRÁZKOVÁ GALERIE
Obrázek B.2: Tento program ukazuje použití textové konzole pro interakci s uživatelem.
Obrázek B.3: Tento program využívá tˇrídu AText2D pro ruzné ˚ textové výstupy na obrazovku.
30
B. O BRÁZKOVÁ GALERIE
Obrázek B.4: Toto je již ponˇekud složitˇejší program, který zobrazuje scénu naˇctenou ze souboru, provádí detekce kolizí za využití gravitace a vše osvˇetluje dynamickými svˇetly.
31
Dodatek C
Relevantní internetové odkazy •
•
•
•
•
•
•
•
•
•
•
•
•
•
32
Dodatek D
Elektronické pˇrílohy Souˇcástí práce je CD-ROM, který obsahuje veškeré elektronické pˇrílohy. Jsou jimi knihovna Astral3D ve verzi pro MS Windows a Linux, dokumentace k aplikaˇcnímu programovému rozhraní a ukázkový program.
33
Literatura [1] Hearn, D. a Baker, M.: , Computer graphics using OpenGL 3rd ed., Upper Saddle River, Pearson Education, 2004, 0130153907. [2] Fauerby, K.: , Improved Collison Detection and Response, (bˇrezen 2006). [3] Prata, S.: , Mistrovství v C++, Computer Press, Hornocholupická 22, 143 000 Praha 4, 80-7226-339-0. [4] Woo, M.: , OpenGL programming guide, Addison-Wesley, 1999. xl, 730 s., 0201604582. [5] Tišnovský, P.: , Grafická knihovna OpenGL, (bˇrezen 2006). [6] Hawkins, K. a Astle, D.: , OpenGL game programming, Roseville, Prima publishing, 2001, 0761533303.
34
Index cˇ ásticový systém, 4 3D model, 19 ACamera, 17 AConsole, 22 AError, 14 ANSI, 8 API, iii, 9 ASurface, 22 AText2D, 22 AUX, 6 AWindow, 14 BSP, 3 Conformance test, 5 detekce kolizí, 20 DirectX, 2 Doxygen, 10 emitor, 4 frustum, 24 Genesis 3D, 3 GLU, 6 GLUT, 6 grafický engine, 2 GUI, 3 Irrlicht 3D, 2 jazyk C++, 1 kamera, 3 konzole, 22 Mesa3D, 5 OpenGL, 1, 5 SDL, 1, 7 Subversion, 9 výjimka, 13 35