České vysoké učení technické v Praze Fakulta elektrotechnická
Autorský nástroj pro projektivní zobrazování na fasády budov Bakalářská práce
Autor práce:
Vedoucí práce:
Martin Kolací
Ing. Roman Berka, Ph.D.
Studijní program:
Obor:
Softwarové technologie a management
Web a multimedia
Praha 2011
Čestné prohlášení Prohlašuji, že jsem zadanou diplomovou práci zpracoval sám s přispěním vedoucího práce a konzultanta a používal jsem pouze literaturu v práci uvedenou. Dále prohlašuji, že nemám námitek proti půjčování nebo zveřejňování mé diplomové práce nebo její části se souhlasem katedry.
Datum: 27. 5. 2011 ………………..……………………
podpis autora
Anotace Práce se zaměřuje na problematiku počítačové grafiky a její projekce na nejrůznější druhy podkladu (tzv. „mapping“). Součástí práce je pojednání o vhodnosti a omezeních různých druhů projekčního zařízení v předem určených podmínkách. Čtenář se seznámí s problematikou transformací, transformačních matic a texturování v počítačové grafice a OpenGL. V rámci bakalářské práce jsem navrhl a implementoval aplikaci v jazyce C++, která popisuje základní postupy a techniky při vytváření projekce. Pro implementaci aplikace je využita knihovna OpenGL a její nadstavba GLUT (OpenGL Utility Toolkit), která je v této práci také popsána.
Summary This work focuses on the problems of computer graphics and its projection on various types of surface (the so-called „mapping“). It includes important facts about different projection devices and their usage in specific conditions. A reader will get to know to the problems of transformation, transformation matrixes and texturing in computer graphics and in OpenGL. Within this bachelor thesis I have designed and implemented an application in C++, which describes the basic processes and techniques when projecting. Library OpenGL and its interface GLUT have been used for the implementation of the application.
Obsah 1
2
3
Úvod do mappingu ........................................................................................................... 13 1.1
Co je to mapping ........................................................................................................ 13
1.2
Výrobní postup........................................................................................................... 13
Výrobní postup ................................................................................................................. 15 2.1
Měření, fotodokumentace a příprava ....................................................................... 15
2.2
3D model .................................................................................................................... 15
2.3
Projekce ..................................................................................................................... 16
Projekční zařízení .............................................................................................................. 17 3.1
3.1.1
Filmový projektor .......................................................................................... 17
3.1.2
Diaprojektor................................................................................................... 17
3.1.3
Dataprojektor ................................................................................................ 17
3.2
Zobrazovací technologie dataprojektorů .................................................................. 18
3.2.1
DLP (Digital Light Processing) ........................................................................ 18
3.2.2
LED (Light-Emitting Diode) ............................................................................ 18
3.2.3
LCD (Liquid Crystal Display) ........................................................................... 18
3.2.4
LCoS (Liquid Crystal on Semiconductor)........................................................ 19
3.2.5
CRT (Cathod Ray Tube) .................................................................................. 19
3.2.6
D-ILA (Direct-Drive Image Light Amplification) ............................................. 20
3.3
4
Základní dělení projektorů ......................................................................................... 17
Parametry dataprojektorů ......................................................................................... 20
3.3.1
Světelný výkon ............................................................................................... 20
3.3.2
Ohnisko objektivu .......................................................................................... 20
3.3.3
Rozlišení ......................................................................................................... 21
3.3.4
Kontrast ......................................................................................................... 21
3.3.5
Rozhraní ......................................................................................................... 21
Počítačová grafika a OpenGL ............................................................................................ 23
4.1
OpenGL ...................................................................................................................... 23
4.2
Transformace obecně ................................................................................................ 25
4.2.1
Posunutí......................................................................................................... 25
4.2.2
Otočení .......................................................................................................... 26
4.2.3
Změna měřítka .............................................................................................. 26
4.2.4
Zkosení........................................................................................................... 26
4.2.5
Skládání transformací .................................................................................... 27
4.3
5
Transformace v OpenGL ............................................................................................ 27
4.3.1
Nastavení aktuální transformační matice ..................................................... 28
4.3.2
Změna obsahu aktuálně nastavené transformační matice........................... 28
4.3.3
Získání hodnot prvků jednotlivých transformačních matic........................... 30
4.3.4
Použití transformačních matic ...................................................................... 30
4.3.5
Skládání transformací .................................................................................... 30
4.3.6
Zásobník matic............................................................................................... 31
4.4
Primitiva v OpenGL .................................................................................................... 32
4.5
Texturování v OpenGL ............................................................................................... 33
4.5.1
Výhody a nevýhody rastrových textur .......................................................... 33
4.5.2
Podpora texturování v OpenGL ..................................................................... 34
4.5.3
Omezení texturování v OpenGL .................................................................... 35
Aplikace ............................................................................................................................ 37 5.1
Popis aplikace ............................................................................................................ 37
5.1.1
Zobrazovací okno .......................................................................................... 37
5.1.2
Editační okno ................................................................................................. 37
5.2
Způsob použití ........................................................................................................... 39
5.3
Implementace nejdůležitějších částí ......................................................................... 39
5.3.1
Zobrazování vrstev ........................................................................................ 40
5.3.2
Načítání TGA textury ..................................................................................... 40
5.3.3
Načítání textur z AVI souboru ....................................................................... 41
5.4
5.4.1
Test 1 ............................................................................................................. 42
5.4.2
Test 2 ............................................................................................................. 43
5.5 6
Test aplikace .............................................................................................................. 42
Rozšíření stávající aplikace......................................................................................... 45
Závěr ................................................................................................................................. 47
Zdroje ........................................................................................................................................ 49 Seznam příloh ........................................................................................................................... 51
1 Úvod do mappingu 1.1 Co je to mapping Video mapping je směr vizuálního umění, které využívá projekci ve volném prostoru na libovolné objekty, např. fasády domů nebo interiéry budov. Pro realizaci jsou potřeba silné projektory, odpovídající programové vybavení a tma nebo alespoň šero. Pro přípravu kvalitní projekce je nutná předchozí znalost scény, často jsou vytvářeny 3D modely prostoru budovy nebo fasády domu, aby bylo docíleno dokonalého splynutí světelného divadla se scénou. Výsledek poté připomíná sekvence filmu, ve kterém se reálná kulisa prolíná s virtuálním dějem, např. z fasády domu se vynořují jednotlivé cihly, z oken se vyklánějí lidé a vylétají předměty, ze střechy stéká vodopád apod. Obecně jsou hlavním smyslem video mappingu projekce, které spolupracují s vybraným objektem a usilují o rozbití vnímání perspektivy u diváka. Pomocí projektorů lze zakřivit a zdůraznit jakýkoliv tvar, linii nebo prostor. Všechno se stává iluzí. Nejčastěji se video mapping využívá pro zatraktivnění kulturních událostí a festivalů. V roce 2010 objevil video mapping reklamní průmysl a v současné době se začíná vyskytovat mapování reklam na předměty.[1]
1.2 Výrobní postup Videomapping se připravuje pro každou budovu zvlášť. Základem je pořízení fotografií budovy, na kterou se bude promítat, přesně z míst, kde budou stát jednotlivé projektory. Z pořízených podkladů se pomocí digitální animace připraví vlastní program, který mohou doprovázet i hudba a zvukové efekty.[2] Jelikož není technicky možné umístit projektor na naprosto stejné místo, ze kterého byli pořízeny referenční fotografie, a optická soustava fotoaparátu není nikdy zcela shodná s projekčním zařízením, je třeba připravenou animaci na místě dorovnat s podkladem. Podrobněji si postup výroby popíšeme v následující kapitole.
13
14
2 Výrobní postup 2.1 Měření, fotodokumentace a příprava Základem úspěšné a efektní projekce je příprava. Musíme nashromáždit co nejvíce informací o rozměrech a struktuře podkladu. Je potřeba změřit a vyfotografovat cokoli, co by nám mohlo pomoci při vytváření 3D modelu. Velmi důležité je také pořídit fotografie z míst, kde budou umístěny projektory. Při přípravě musíme brát v úvahu také světelné podmínky při projekci a materiál, na který budeme promítat (např. fasáda budovy). Při venkovní projekci na tmavou fasádu budeme muset použít o mnoho výkonější projektor než při projekci na bílou zeď ve zhaslé místnosti.
2.2 3D model Podle nafocených fotografií sestavíme 3D model objektu, na který budeme promítat. Z 3D modelu vytvoříme animaci, kterou otexturujeme podle toho, jak chceme, aby výsledná projekce vypadala. Výslednou animaci vyexportujeme do několika videosouborů. Scéna rozřezaná na více částí se na povrch objektu, na který budeme promítat, zarovnává lépe než celá scéna. Příklad nařezání výsledné videosekvence je znázorněna na obrázku (Obr 2.1). Scéna je rozřezána na tři části: Střecha a stěny.
Obr 2.1 15
2.3 Projekce Před samotným promítáním musíme vybrat potřebné projekční zařízení. Nejdůlužitějšími parametry při výběru je světelný výkon a ohnisko objektivu. Podle světelných podmínek a struktury objektu, na který budeme promítat, vybíráme světelný výkon. Při nedostatečném světelném výkonu splyne projekce s pozadím a celá projekce nebude působit dobře. Podle umístění projektoru vybíráme ohnisko objektivu. Pokud vybereme nesprávné ohnisko, buď neobsáhneme projektorem celou plochu projekce, nebo budeme mít zbytečně velké okraje a nevyužijeme plně rozlišení projektoru. Po výběru požadovaného projektoru a jeho umístění na místo, ze kterého budeme promítat, zarovnáme rozřezané videosekvence na jejich místo. Nejjednodušším způsob zarovnávání je promítnout obrazec, ve kterém jsou zakresleny nejdůležitější části videosekvence. (Obr 2.2 a Obr 2.3).
Obr 2.2
Obr 2.3
Toto zarovnání je dobré učinit v dostatečném předstihu. Zaprvé budeme mít čas vyřešit případné problému a zadruhé není dobré provádět zarovnání v přítomnosti budoucího publika. Zbytečně tím připravíme budoucího diváka o případné překvapení. Touto částí výrobního postupu se zabývá aplikace, kterou jsem v rámci bakalářské práce navrhl a implementoval.
16
3 Projekční zařízení 3.1 Základní dělení projektorů Projektor je zařízení, které umožňuje zobrazení (projekci) obrazu na dané místo. Podle principu zobrazování a charakteru promítaného obrazu existuje řada typů projektorů. 3.1.1 Filmový projektor Filmový projektor, nebo též promítačka, je zařízení, které umožní sledovat natočené filmy. Využívá vlastností doznívání zrakového vjemu lidského oka a psychologické zkušenosti o průběhu pohybů ve skutečnosti, jedná se fyziologický jev označovaný jako setrvačnost lidského oka. Vjem plynulého jasu vzniká dozníváním na sítnici oka. Je tím dokonalejší, čím vyšší je kmitočet změn světlo/tma. Běžně se promítá 24-25 obrazových polí za sekundu. Kmitočet promítání je zdvojován dalším přerušením světelného toku v době, kdy se film v okeničce promítačky nepohybuje. Tím se dosahuje dvojnásobného počtu obrazových změn, tedy 48 až 50 za sekundu. Každý obrázek na filmu je tak fakticky promítnut dvakrát po sobě.[3] 3.1.2 Diaprojektor Diaprojektor je optický přístroj, který sklouží k promítání diapozitivů na promítací plátno nebo stěnu. Projektory určené pro diapozitivy kinofilmového formátu (36 x 24 mm) byly velmi oblíbené od 50. do 80. let 20. století. V Československu je vyráběla firma Meopta.[3] 3.1.3 Dataprojektor Dataprojektor, nebo také datový projektor, je zařízení, které umožňuje zprostředkovat prezentaci všem přítomným tím, že obraz, jehož zdrojem může být osobní počítač, notebook, přehrávač DVD a jiná videozařízení, projektuje (promítá) na plátno či zeď. Datové projektory se vyrábí v různých provedeních a velikostech: Od ultralehkých projektorů, které jsou vhodné na cesty a jejichž rozměry se pohybují kolem 16 × 7 × 20 centimetrů (Š/V/H) a hmotnost nepřesahuje 1,5 kilogramu, až po konferenční projektory, které jsou součástí konferenčních místností a poskytují maximální kvalitu obrazu.[3]
17
O dataprojektory se v oblasti mappingu budeme zajímat nejvíce.
3.2 Zobrazovací technologie dataprojektorů Dataprojektory se liší hlavně technologií vytváření výsledného obrazu a zdrojem světla. Uvádím výčet nejpoužívanějších technologií a popis jejich funkce. 3.2.1 DLP (Digital Light Processing) Srdcem DLP projektorů je jeden případně více DMD čipů. Je to čip, na kterém jsou malá zrcátka. Nazývá se také DLP čip. Poté, co lampa vyrobí světlo, projde světlo přes optickou čočku a dopadne na rotující barevný kotouč, který změní vlnovou délku světla. Na kotoučku bývají minimálně tři základní RGB barvy a jedna průhledná část pro zvýšení jasu. Na kotouči může být i více barev, namátkově žlutá či azurová. Obarvené světlo z kotouče putuje do další čočky, která nasměruje světlo na DLP čip. Pohyb kotouče a zrcadel na čipu je přesně synchronizován. DLP čip vytvoří obraz pootočením zrcátek. Jedná se o reflektivní, tj. odrazovou technologii. Texas Instruments uvádí až 1024 pohybů zrcátek za sekundu. Právě takto vzniká šedá a všechny barevné odstíny. Čím déle je zrcadlo vystaveno světlu, tím světlejší odstín je.[3] 3.2.2 LED (Light-Emitting Diode) LED projektory jsou vlastně DLP projektory, ve kterých je lampa nahrazena LED diodami. Největšími výhodami této technologie je nízká spotřeba, absence lampy a především malé rozměry. Zásadní nevýhodou je velmi nízká světelnost, které se pohybují v desítkách lumenů. To je mnohonásobně méně než u běžných DLP projektorů, u kterých je světelnost v tisících lumenů.[3] 3.2.3 LCD (Liquid Crystal Display) LCD projektory pracují na odlišném principu než DLP. Srdcem LCD projektorů jsou tzv. dichroická zrcadla a LCD panely. Hlavní výhodou dichroického zrcadla je schopnost odrážet a propouštět světlo v závislosti na vlnové délce. Světlo z lampy dopadne na první zrcadlo, to propustí červenou složku a odrazí zbylé světlo. Následuje zrcadlo pro zelenou složku a nakonec pro modrou. Odražené paprsky světla pokračují samostatně do přiděleného LCD. Pro zobrazení se využívá tekutých krystalů a jedná se o transmisní
18
technologii. LCD projektory mají několik nevýhod. První nevýhodou je stárnutí a vypalování LCD displejů, dále pak pokles kvality zobrazení s přibývajícím počtem vysvícených hodin, a v neposlední řadě také rastr u LCD panelů je z principu znatelně viditelnější než u DLP nebo LCoS projektorů. Náchylnost na prašné prostředí (vniknutí prachu brání pouze prachový filtr). Výhodou LCD projektorů je v průměru nižší hlučnost, dále mají ostrý a jasný obraz a netrpí duhovým efektem.[3] 3.2.4 LCoS (Liquid Crystal on Semiconductor) Jedná se o poměrně novou technologii projektorů. Cenově jsou LCoS projektory zatím pro většinovou populaci nedostupné. Stojí za nimi několik firem, jedná se především o JVC a jejich technologii D-ILA (Direct-Drive Image Light Amplifier), dále Canon a Sony s technologií SXRD (Silicon X-tal Reflective Display). Princip je kombinace LCD a DLP projektoru. Lampa vyrobí světlo, hranol rozdělí světlo z lampy na tři základní barvy, tyto světlené paprsky dopadnou na LCoS displej a od toho se, podobně jako u DLP projektorů, odrazí. Obraz na displeji je v odstínech šedi. V případě černé barvy se světlo neodrazí. Čím světlejší barva, tím více světla se od displeje odrazí. Odražené světlo putuje opět do hranolu, kde se spojí všechny barevné složky a nakonec zamíří přes optiku na plátno. Výhodou LCoS projektoru je vysoké rozlišení, disponuje vynikajícím barevným podáním, vysokým kontrastem a nemá duhový efekt. Nevýhodou je především vysoká cena.[3] 3.2.5 CRT (Cathod Ray Tube) Základem jsou tři projekční obrazovky principiálně podobné těm v běžných televizních přijímačích či počítačových monitorech. Každá z obrazovek promítá v jedné ze základních barev (červené, modré a zelené) a výsledný obraz je potom složen na projekční ploše. Tato technika patří k nejstarším a používá se dnes pouze výjimečně, a to u pevných instalací. Výhody jsou výborná kvalita reprodukce barev, vysoké rozlišení i kontrast, spolehlivost, dlouhodobý provoz. Nevýhody jsou omezená oblast použití, překonaná technologie, větší rozměry a hmotnost.[3]
19
3.2.6 D-ILA (Direct-Drive Image Light Amplification) Technologie vyvinutá společností JVC, která přináší bezkonkurenční výkon s přirozeným podáním barev a obraz tak věrný, že téměř konkuruje filmové projekci. Vynikající je rovněž kontrast, který je jinak velkou slabinou jiných technologií. D-ILA je technologie postavená na tekutých krystalech, ale výrazně se liší od tekutých krystalů používaných v LCD technologii, kterou dnes využívá mnoho současných produktů. D-ILA je to, čemu se říká tekuté krystaly na křemíkové podložce neboli LCOS, ale JVC při vývoji D-ILA provedla několik vylepšení výchozí LCOS technologie. Podstatou je D-ILA čip, navržen a vyroben podle JVC. Každý JVC D-ILA projektor používá tři D-ILA čipy, jeden pro červenou, zelenou a modrou, což jsou základní barvy, které vzájemným mísením tvoří plně barevné palety.[4]
3.3 Parametry dataprojektorů Mezi nejdůležitější parametry datových projektorů patří: 3.3.1 Světelný výkon Udává se v ANSI lumenech. Čím je hodnota vyšší, tím je obraz jasnější a kontrastnější. Tento parametr nás bude při přípravě projekce nejvíce zajímat. Dnes jsou běžné projektory se světelným výkonem 2 500 ANSI Lm. Pro účely mappingu se využívá prokjektorů se světelným výkonem až 18 000 ANSI Lm (Projektor Christie HD18K). Lumen (lm) je hlavní jednotkou světelného toku. Lumen je jednou z vedlejších jednotek soustavy SI. Je definován jako světelný tok vyzařovaný do prostorového úhlu 1 steradiánu bodovým zdrojem, jehož svítivost je ve všech směrech 1 kandela.[6] 3.3.2 Ohnisko objektivu Ohnisko objektivu definuje zorný úhel, který dokáže objektiv obsáhnout. Tento parametr budeme sledovat v souvislosti s velikostí scény a vzdáleností projektoru od objektu, na který budeme promítat. Zorný úhel ve stupních se dá snadno dopočítat z ohniskové vzdálenosti pomocí následujícího vztahu: Úhel [°] = 2 * arctg(21,6 / Ohnisko [mm]).
20
Vztah ohniskové vzdálenosti a zorného úhlu je znázorněn na následujícím obrázku (Obr 3.1).
Obr 3.1 3.3.3 Rozlišení Rozlišení určuje počet pixelů (nebo maximální rozlišení obrazu), které mohou být projektorem zobrazeny. Často se udává jako počet sloupců (horizontálně, „X“), které se uvádí vždy jako první, a počet řádků (vertikálně, „Y“). Čím vyšší rozlišení, tím je obraz kvalitnější. Pro účely mappingu se využívají projektory pracující v rozlišení až 1920x1080 (HD). 3.3.4 Kontrast Hodnota kontrastu určuje poměr mezi nejtmavším a nejsvětlejším bodem, který dokáže projektor zobrazit. Dnes jsou běžné projektory s kontrastem 4000:1 (nejsvětlejší bod je 4000x světlejší než bod nejtmavší). 3.3.5 Rozhraní Výběr projektoru bude zajisté ovlivněno i konektory, pomocí kterých je možné projektor připojit a přenášet videosignál. V dnešní době je již standardem HDMI rozhraní.
21
22
4 Počítačová grafika a OpenGL Počítačová grafika (Computer graphics - CG) je součástí oboru informatiky, která se zabývá analýzou (interpretací) nebo tvorbou (syntézou, generováním) grafické obrazové informace. Tento obor můžeme dělit na několik oblastí: 3D rendering v reálném čase (často využívaný v počítačových hrách), počítačová animace, video, střih speciálních efektů (často využívané ve filmu a televizi), editování obrázků a 3D modelování (například pro inženýrské nebo lékařské účely). Zpočátku se počítačová grafika rozvíjela kvůli akademickým zájmům podporovaným vládou a armádou, později však začala pronikat do filmu a televize, kde se osvědčila jako konkurenceschopná náhrada za tradiční speciální efekty a animační techniky. V důsledku toho i komerční firmy začaly přispívat k vývoji v této oblasti.
4.1 OpenGL Knihovna OpenGL (Open Graphics Library) byla navržena firmou SGI (Silicon Graphics Inc.) jako aplikační programové rozhraní (Application Programming Interface – API) k akcelerovaným
grafickým
kartám,
respektive
celým
grafickým
subsystémům.
Předchůdcem této knihovny byla programová knihovna IRIS GL (Silicon Graphics IRIS Graphics Library). OpenGL byla navržena s důrazem na to, aby byla použitelná na různých typech grafických akcelerátorů a aby ji bylo možno použít i v případě, že na určité platformě žádný grafický akcelerátor není nainstalován. V současné době lze knihovnu OpenGL použít na různých verzích unixových systémů (včetně Linuxu a samozřejmě IRIXu), OS/2 a na platformách Microsoft Windows. Na některých platformách je možné rozdělení aplikace na dvě relativně samostatné části – serverovou a klientskou. Při vykreslování se potom jednotlivé příkazy (většinou parametry funkcí OpenGL) přenášejí přes síťové rozhraní. Knihovna OpenGL (na rozdíl od IRIS GL nebo Direct 3D) byla vytvořena tak, aby byla nezávislá na použitém operačním systému, grafických ovladačích a správcích oken (Window Managers). Proto také neobsahuje žádné funkce pro práci s okny (otevírání, zrušení, změnu velikosti), pro vytváření grafického uživatelského rozhraní (Graphical User Interface – GUI) ani pro zpracování událostí. Tyto funkce lze zajistit buď přímo voláním funkcí příslušného správce 23
oken, nebo lze použít některou z nadstaveb, například knihovnu GLUT (OpenGL Utility Toolkit). Pro dosažení co největší nezávislosti na použité platformě zavádí knihovna OpenGL vlastní primitivní datové typy, například GLbyte, GLint nebo Gldouble. Z programátorského hlediska se OpenGL chová jako stavový automat. To znamená, že během zadávání příkazů pro vykreslování lze průběžně měnit vlastnosti vykreslovaných primitiv (barva, průhlednost) nebo celé scény (volba způsobu vykreslování, transformace) a toto nastavení zůstane zachováno do té doby, než ho explicitně změníme. Výhoda tohoto přístupu spočívá především v tom, že funkce pro vykreslování mají menší počet parametrů a že jedním příkazem lze globálně změnit způsob vykreslení celé scény, například volbu drátového zobrazení modelu nebo zobrazení pomocí vyplněných polygonů. Vykreslování scény se provádí procedurálně – voláním funkcí OpenGL se vykreslí výsledný rastrový obrázek. Výsledkem volání těchto funkcí je rastrový obrázek uložený v tzv. framebufferu, kde je každému pixelu přiřazena barva, hloubka, alfa složka popř. i další atributy. Z framebufferu lze získat pouze barevnou informaci a tu je možné následně zobrazit na obrazovce (Obr 4.1).
Obr 4.1 OpenGL nezaručuje, že při spuštění identického programu používajícího knihovnu OpenGL na různých platformách nebo různých grafických akcelerátorech dostaneme vždy přesně stejný výsledek. Pokud bychom oba výsledné rastrové obrázky porovnali pixel po pixelu, mohli bychom zjistit mírné rozdíly v barvách. Může to být způsobeno například odlišnou
24
přesností reprezentace čísel na grafické kartě, odlišnými algoritmy pro interpolaci barvy, normály a texturovými souřadnicemi nebo jinou bitovou hloubkou Z-bufferu. Celkové geometrické a barevné podání scény by však mělo být zachováno. Pomocí funkcí poskytovaných knihovnou OpenGL lze vykreslovat obrazce a tělesa složená ze základních geometrických prvků, které nazýváme grafická primitiva. Mezi tato primitiva patří bod, úsečka, trojúhelník, čtyřúhelník, plošný konvexní polygon, bitmapa (jednobarevný rastrový obraz) a pixmapa (barevný rastrový obraz). Existují i funkce, které podporují proudové vykreslování některých primitiv – lze například vykreslit polyčáru (line loop), pruh trojúhelníků (triangle strip), pruh čtyřúhelníků (quad strip) nebo trs trojúhelníků (triangle fan). Na vrcholy tvořící jednotlivá grafická primitiva lze aplikovat různé transformace (otočení, změna měřítka, posun, perspektivní projekce), pomocí kterých lze poměrně jednoduše vytvořit animace. Vykreslovaná primitiva mohou být osvětlena nebo pokryta texturou.[5]
4.2 Transformace obecně Popis těles je založen na vertexech neboli uzlových bodech. Při manipulaci s tělesem v prostoru je nutné pracovat právě s těmito body. Tělesa se pak mohou na obrazovce zobrazit v libovolném posunu, natočení či měřítku. Tyto manipulace jsou nazývány transformacemi. K provádění transformací je třeba na každý vrchol tělesa aplikovat určitou obdobu vzorce. K vykreslení transformovaného tvaru se pak použijí nově modifikované vrcholy[7]. Mezi transformace patří posunutí, otáčení, změna měřítka a zkosení. 4.2.1 Posunutí Při posunutí dochází ke změně umístění bodů v souřadném systému. Posunová matice pro 3D objekt vypadá následovně: 1 0 P= 0 o x
0 1
0 0
0 oy
1 oz
0 0 0 1
25
4.2.2 Otočení Při rotaci objektu dochází ke změně natočení zobrazeného objektu. Při natočení objektu ve dvourozměrném prostoru dochází k otočení kolem jedné osy. Ve trojrozmněrném prostoru může docházet k otočení kolem tří os současně. Matice k otočení kolem tří os současně neexistuje. Pro každou osu se používá jiná matice. 0 1 0 cos α Ox = 0 − sin α 0 0 cos α 0 Oy = − sin α 0 cosα − sin α Oz = 0 0
0 sin α cos α 0
sin α 1 cos α 0 sin α cosα 0 0
0 0 0 1
0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 1
4.2.3 Změna měřítka Při změně měřítka násobíme souřadnice vrcholů objektu. Násobením číslem větším než 1 se objekt zvětšuje a menším jak 1 se objekt zmenšuje. Matice změny měřítka vypadá následovně: Vx 0 0 0 Vy 0 M = 0 0 Vz 0 0 0
0 0 0 1
4.2.4 Zkosení Podobně jako u transformace otočení se zkosení provádí ve všech třech směrech zvlášť. Máme tudíž tři matice zkosení Zyz, Zxz, Zxy pro zkosení ve směrech YZ, XZ a XY.
26
1 Zy 0 1 Z yz = 0 0 0 0
Zz 0 1 0
1 Z Z xz = x 0 0
0 0 1 Zz 0 1
1 0 Z xy = Z x 0
0 1 Zy
0
0
0
0 0 0 1 0 0 0 1
0 0 0 0 1 0 0 1
4.2.5 Skládání transformací V praxi je však potřeba aplikovat na jeden objekt více transformací najednou. K tomu účelu lze jednotlivé matice skládat. Výslednou transformační matici získáme vynásobením jednotlivých transformačních matic (Obr 4.2).
Obr 4.2
4.3 Transformace v OpenGL V OpenGL existují tři transformační matice, které se postupně aplikují na body (vrcholy, vertexy), popř. i na normály vrcholů. První transformační matice se jmenuje ModelView matrix. Na tuto matici se můžeme dívat jako na spojení modelové matice a pohledové matice, protože se používá jak pro nastavení pozice kamery, tak i pro manipulaci s objekty (modely) ve scéně. Druhá transformační matice se jmenuje Projection matrix a používá se pro nastavení perspektivní projekce kamery. Třetí transformační matice se jmenuje Viewport matrix a používá se pro provedení perspektivní projekce k mapování objektů z abtraktních souřadnic do souřadnic okna. Tato poslední matice ve skutečnosti pouze
27
provádí transformaci v dvojrozměrné ploše, proto se s ní v OpenGL nepracuje jako s „plnohodnotnou“ maticí. Kromě těchto tří matic můžeme měnit matici, která se používá při mapování textur na povrch objektů. Tato matice se nazývá Texture matrix.[5] 4.3.1 Nastavení aktuální transformační matice Při změně některé z transformačních matic musíme nejprve určit, kterou transformační matici budeme měnit. K tomuto účelu se používá funkce void glMatrixMode(Glenum mode). Tato funkce má jeden parametr mode, jímž určujeme matici, kterou budeme dalšími příkazy změnit. Parametr může nabývat tří hodnot, reprezentovaných symbolickými konstantami: •
GL_MODELVIEW - bude se měnit ModelView matrix, tj. matice, ve které jsou uloženy modelové a pohledové transformace (transformace objektů a nastavení kamery).
•
GL_PROJECTION – bude se měnit Projection matrix, tj. matice, která se používá pro nastavení perspektivní nebo ortogonální projekce kamery.
•
GL_TEXTURE – bude se měnit Texture matrix, tj. matice, která se používá při mapování textur na povrch objektů.
Aktuálně nastavenou matici lze zjistit pomocí příkazu glGetIntegerv(GL_MATRIX_MODE, ¤tMode), po jehož provedení je v proměnné currentMode některá z konstant GL_MODELVIEW, GL_PROJECTION nebo GL_TEXTURE.[5] 4.3.2 Změna obsahu aktuálně nastavené transformační matice S obsahem aktuálně nastavené matice lze manipulovat pomocí funkcí glLoadIdentity(), glLoadMatrix(), glMultMatrix(), glTranslate(), glScale() a glRotate(). Nejjednodušší z těchto funkcí je funkce void glLoadIdentity(void). Tato funkce nahraje do aktuálně nastavené transformační matice koeficienty odpovídající jednotkové matici, tj. matici, ve které jsou všechny prvky vynulovány s výjimkou prvků hlavní diagonály, které jsou nastaveny na jedničku. Tato matice hraje úlohu neutrálního prvku při násobení matic nebo při násobení vektoru maticí. Při nastavování některé transformační matice se v
28
naprosté většině případů začíná touto funkcí, neboť pomocí ní matici „připravíme“ na aplikaci dalších transformací. Funkce glLoadMatrix() se používá pro přímé nastavení prvků matice. Tato funkce existuje ve dvou variantách lišících se pouze typem pole, které funkci předáváme jako parametr. První varianta je nadeklarována jako void glLoadMatrixd(const GLdouble *m), druhá varianta jako void glLoadMatrixf(const GLfloat *m). U první varianty má pole jako své prvky hodnoty typu GLdouble, ve druhé variantě jsou to prvky typuGLfloat. Další funkce glMultMatrix*() slouží k vynásobení aktuálně nastavené transformační matice maticí zadanou jako parametr této funkce. Opět existují dvě varianty, které se liší typem prvků předávaného pole. Tyto varianty jsou nadeklarovány jako void glMultMatrixd(const GLdouble *m) a void glMultMatrixf(const GLfloat *m). U první varianty se používají hodnoty typu GLdouble, u druhé typu GLfloat. Další tři funkce, glTranslate, glScale a glRotate jsou používány mnohem častěji než předchozí dvě funkce. U těchto funkcí se nemanipuluje přímo s jednotlivými prvky matice, ale zadávají se základní lineární transformace – posun, změna měřítka a rotace. Pro zadané transformace se vytvoří dočasná matice a aktuální matice (většinou je to matice ModelView) je touto dočasnou maticí vynásobena. Funkce glTranslate*(), která existuje ve dvou variantách void glTranslated(GLdouble x, GLdouble y, GLdouble z) a void glTranslatef(GLflo-at x, GLfloat y, GLfloat z), specifikuje posun o vektor[x, y, z]. Funkce glScale*() s variantami void glScaled(GLdouble x, GLdouble y, GLdouble z) a void glScalef(GLfloat x, GLfloat y, GLfloat z) slouží k zadání transformace změny měřítka, kdy je těleso nezávisle zvětšeno/zmenšeno ve třech směrech odpovídajících jednotlivým souřadným osám. Funkce glRotate*(), která má opět dvě varianty, void glRotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) a void glRotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z), specifikuje transformaci rotace. Těleso je otočeno o úhel angle okolo osy procházející
29
počátkem a bodem (x, y, z). Úhel angle je v obou variantách zadán ve stupních. Bod, jímž osa rotace prochází, by neměl být nastaven na souřadnice (0, 0, 0). 4.3.3 Získání hodnot prvků jednotlivých transformačních matic Pro získání hodnot, které mají jednotlivé prvky transformačních matic, lze použít funkci void glGetDoublev(GLenum pname, GLdouble * params) nebo void glGetFloatv(GLenum pname, GLfloat * params). Parametr pname musí obsahovat jednu z těchto tří symbolických
konstant:
GL_MODELVIEW_MATRIX,
GL_PROJECTION_MATRIX
nebo
GL_TEXTURE_MATRIX. V poli params jsou potom vráceny prvky příslušné transformační matice. 4.3.4 Použití transformačních matic Některé transformace se při vykreslování scény provádí pouze jednou. Typickou operací je nastavení záběru kamery pomocí projekční matice (Projection matrix) a výřezu pomocí změny Viewportu. Tyto operace se většinou provádí v callback funkci vyvolávané při změně velikosti okna. Další změny projekční matice a výřezu se většinou neprovádí. Výjimkou bývá současné zobrazení trojrozměrné scény a dvojrozměrných textů. V tomto případě se provádí změna projekční matice dvakrát. Poprvé pro nastavení perspektivní projekce pro zobrazení trojrozměrné scény a podruhé pro nastavení ortogonální projekce pro vykreslení textů. V době vykreslování je však velmi často měněna ModelView matice, protože s tělesy ve scéně je většinou nějakým způsobem manipulováno. Manipulace hlavně zahrnuje posun tělesa, změnu měřítka a rotaci. Tyto lineární transformace lze přímo zadat pomocí funkcí glTranslate(), glScale() a glRotate(). Před zadáváním samostatných transformací je však vždy zapotřebí nastavit transformační matici na jednotkovou zavoláním funkce glLoadIdentity(), jinak se transformace budou skládat, což v některých případech může způsobit chybnou funkci programu. 4.3.5 Skládání transformací Pokud mezi zadáváním jednotlivých transformací nevkládáme příkaz glLoadIdentity(), dochází při modifikaci transformační matice k vynásobení původní hodnoty matice s dočasnou maticí, která je pro každou transformaci vytvořena. V důsledku toho se 30
transformační matice chová jako by se transformace skládaly, tj. postupně prováděly. Jedná se praktickou vlastnost, protože sice můžeme zadat libovolné množství transformací, ale při výsledném transformování jednotlivých vrcholů (vertexů) se bude provádět pouze násobení čtyřsložkového vektoru jednou maticí velikosti 4×4. Protože však násobení matic není komutativní, musíme dát pozor na pořadí zadávání transformací. V OpenGL platí, že transformace jsou na vertexy aplikovány v opačném pořadí, než jsou zavolány jejich korespondující příkazy. Jestliže například bude v programovém kódu sekvence příkazů glTranslatef(), glRotatef(), ve skutečnosti bude objekt nejprve otočen a teprve poté posunut. Na tuto vlastnost se můžeme také dívat tak, že se neprovádí transformace se samotným objektem, ale postupně s celým souřadným systémem (nyní už ve správném pořadí) (Obr 4.3).
Obr 4.3 4.3.6 Zásobník matic Transformační matice lze v OpenGL ukládat do takzvaného zásobníku matic. Zásobník matic není nic jiného než datová oblast vyhrazená uvnitř bloku OpenGL, která se používá pro uložení šestnácti koeficientů transformační matice. Pro různé typy transformačních matic jsou vyhrazeny různé zásobníky s obecně odlišnou kapacitou. Aktuálně vybranou matici lze uložit na vrchol zásobníku zavoláním funkce void glPushMatrix(void), odstranění
31
matice z vrcholu zásobníku obstará funkce void glPopMatrix(void). Ta matice, která je uložená na vrcholu zásobníku, je použita při transformacích. Jak již bylo řečeno, pro každý typ transformační matice (zejména ModelView a projekční matice) je vyhrazen vlastní zásobník, který může mít odlišnou kapacitu. Největší kapacitu mívá většinou zásobník pro ModelView matici, protože tato matice se nejčastěji mění. Kapacitu jednotlivých zásobníků lze zjistit pomocí funkce void glGetIntegerv(GLenum pname, GLint *params), kde se za parametr pname dosadí symbolická konstanta GL_MAX_MODELVIEW_STACK_DEPTH,
nebo
GL_MAX_PROJETION_STACK_DEPTH.
Pomocí této funkce je také možné zjistit aktuální obsazenost zásobníku – stačí použít parametr GL_MODELVIEW_STACK_DEPTH, resp. GL_PROJECTION_STACK_DEPTH. Každá implementace OpenGL by měla mít zásobník pro ModelView matice s kapacitou minimálně třiceti dvou matic, pro zásobník projekčních a texturovacích matic je vyžadována pouze kapacita dvou matic.
4.4 Primitiva v OpenGL Pomocí příkazů OpenGL lze vykreslovat pouze základní objekty nazývané primitiva. Z těchto primitiv se skládají všechny složitější objekty. V OpenGL máme deset základních primitiv: bod (GL_POINTS), úsečka (GL_LINES), řetězec úseček (GL_LINE_STRIP), smyčka úseček
(GL_LINE_LOOP),
trojúhelník
(GL_TRIANGLES),
trs
trojúhelníků
(GL_TRIANGLE_FAN), pás trojúhelníků (GL_TRIANGLE_STRIP), čtyřúhelník (GL_QUADS), pás čtyřúhelníků (GL_QUAD_STRIP) a polygon (GL_POLYGON).[5] Před samotným zadáváním vrcholů primitiva se volá příkaz glBegin(typ primitiva). Jediným parametrem této funkce je typ primitiva. Po příkazu glBegin() už následuje výčet bodů zadaných příkazem glVertex2(x, y) pro 2D zadávání bodů (z je automaticky nastaveno na 0 a váha w je nastavena na 1), glVertex3(x, y, z) pro 3D zadávání (váha w je automaticky 1) nebo glVertex4(x, y, z, w) pro zadávání 3D bodů a váhy bodu. Váha vrcholu je použita při perspektivní projekci. Pro běžné použití ji vždy nastavujeme na jedničku, protože se touto souřadnicí dělí zbylé tři souřadnice, tedy x'=x/w, y'=y/w a z'=z/w.
32
Pro účely mé bakalářské práce jsem využil pouze čtyřúhelníku. Zadávání čtyřúhelníku začíná příkazem glBegin(GL_QUADS), po němž následují jednotlivé vrcholy. Při zadávání vrcholů musíme zaručit, že vrcholy čtyřúhelníku budou ležet v jedné rovině a čtyřúhelník bude konvexní. Pokud tyto podmínky nebudou splněny, nemusí být (a pravděpodobně ani nebude) vykreslení korektní, protože interpolátory v grafickém akcelerátoru většinou nedovedou detekovat hranici, kde se má vykreslování přerušit.
4.5 Texturování v OpenGL Jako texturování (přesněji nanášení textur) se označuje princip obarvení povrchu zobrazovacích těles různými obrazci. Důležité přitom je, že se nijak nemění geometrické vlastnosti těles, pouze se jinak zobrazuje jejich povrch. Obrazce, které se na povrch těles nanášejí, se nazývají textury (textures). Tyto textury jsou většinou představovány plošnými obrázky (dvoudimenzionální textury), některé grafické systémy však podporují i vykreslování jednorozměrných, či dokonce trojrozměrných (objemových) textur.[5] Textury lze vytvářet několika způsoby. Lze použít klasickou rastrovou texturu, která vzniká například namalováním, naskenováním nebo vyfocením, nebo můžeme použít takzvanou procedurální texturu, která je tvořena algoritmem, například fraktály. Procedurální texturování lze použít pro vytváření rastrových textur nebo pro přímý výpočet textury při vykreslování. Druhá možnost však není v OpenGL moc podporována. Procedurální textury je tedy třeba tvořit ručně. Texturu lze použít ve všech případech, kdy je nutné vykreslovat tělesa se složitě strukturovanými povrchy, která však nevykazují velké změny v geometrii povrchu. Příkladem může být dřevěné prkno. Prkno lze reprezentovat jednou plochou, na kterou je nanesen rastrový obrázek se strukturou dřeva. Vykreslování bude na dnešních počítačích dostatečně rychlé a při dostatečné velikosti rastrového obrázku i kvalitní. 4.5.1 Výhody a nevýhody rastrových textur Rastrové textury s sebou samozřejmě nesou i jisté výhody a nevýhody.[5]
33
Velkou výhodou rastrových textur je jejich snadná implementace ve vykreslovacím řetězci. Jednoduché grafické akcelerátory řešily texturování tak, že se do jejich vykreslovacího řetězce přidala vyrovnávací paměť pro textury a několik interpolátorů, pomocí kterých se řešil přístup do texturovací paměti. Dnešní grafické akcelerátory jdou mnohem dál. Textury je možné komprimovat, jsou podporovány mipmapy, antialiasing, multitextury a podobně. Texturovací jednotka však stále patří k těm částem vizuálního systému, která má velmi dobrý poměr složitost/vizuálníefekt. Další výhodou je možnost použití průhlednosti, tzv. alfa kanálu, jehož pomocí můžeme vizuálně měnit tvar tělesa, jelikož se na některách částech může jevit jako děravý. Jednou z nevýhod rastrových textur je jejich předem dané rozlišení. Je tudíž třeba zvolit kompromis mezi dvěma extrémy. Jedním extrémem je použití textury s příliš malým rozlišením, ve které bude působit kostrbatě a nepěkně, druhým extrémem je použití zbytečně velkého rozlišení a zbytečné plýtvání pamětí na grafickém akcelerátoru. Další nevýhodou je, že při zobrazování textury dochází k aliasu (jednoduše řečeno tvorbě moaré). Je to jev, který nastává při zvětšování či zmenšování počtu zobrazovaných pixelů. K tomuto jevu dochází těměř vždy, protože se na texturu díváme z různých vzdáleností a úhlů. Tomuto nežádoucímu efektu se nelze nijak jednoduše vyhnout. Lze ho jen potlačit použitím tzv. antialiasingu, který však komplikuje zobrazovací řetězec a obecně vede ke zpomalení vykreslování. Třetí nevýhodou je, že textury zabírají velké množství vykreslovací paměti. Pokud je v paměti grafického akcelerátoru dostatečné místo, lze textury do této paměti nahrát a zobrazování textur významně urychlit. Pokud je však v této paměti místa málo (protože paměť totiž obsahuje i nejrůznější buffery), je potřeba nahrávat textury z hlavní paměti počítače, což vede k významnému zpomalení vykreslování. 4.5.2 Podpora texturování v OpenGL V OpenGL
jsou
podporovány
pouze
rastrové
textury.
Textury
mohou
být
jednodimenzionální (jedná se o proužek pixelů, který umožňuje vykreslování různých přechodů), dvoudimenzionální (nejpoužívanější typ textury, klasický obrázek) a 34
třídimenzionální (pro zobrazování objemových dat například v medicíně). Největší podpora ze strany grafických akcelerátorů je pro dvoudimenzionální textury, které jsou nejpoužívanější. V OpenGL lze také zvolit různé filtrace textur, režimy mapování textur na plošky, multitexturování a další grafické efekty. Musíme si však uvědomit, že pokud použijeme některý grafický efekt, který není grafickým akcelerátorem podporován, dojde k výpočtům pomocí hlavního procesoru počítače, což značně zpomaluje celý systém. 4.5.3 Omezení texturování v OpenGL V OpenGL není mnoho omezení, co se texturování týče. Jedním omezením je, že lze použít textury jen v barevném režimu true-color. Indexované barevné režimy s barevnou paletou podporovány nejsou. Druhým omezením je možnost použití pouze textur o rozměrech mocniny čísla 2. Při použití textur nesplňujících tuto podmínku dochází k přepočtu na nejbližší možnou velikost mocniny čísla 2, což se negativně podepisuje na kvalitě použité textury.
35
36
5 Aplikace Tato kapitola popisuje některé detaily implementace, návrhu a dosažených výsledků aplikace, kterou jsem pro účely bakalářské práce navrhl a implementoval. Aplikace slouží primárně ke zjednodušení konečné fáze práce na mappingu, konkrétně ke zjednodušení nastavování a úpravě projekce.
5.1 Popis aplikace Aplikace se skládá ze dvou základních částí - z editačního a zobrazovacího okna. Zobrazovací okno je určeno pro zobrazování přes projekční zařízení. Zatímco editační okno je určeno k úpravám promítaného obrazu (Obr 5.1).
Obr 5.1 5.1.1 Zobrazovací okno Zobrazovací okno slouží k zobrazení výsledného obrazu přes projektor. Do zobrazení přes celou plochu se přepíná klávesou „f“. Po stisku klávesy „Esc“ se program ukončí. 5.1.2 Editační okno Editační okno slouží k ovládání celého programu. V horní části okna se nacházejí záložky Layers a Player. Záložka layers slouží k nastavení a přemisťování jednotlivých vrstev
37
v zobrazovacím okně. Pod záložkou player najdeme jednoduchý přehrávač, pomocí kterého můžeme jednoduše přehrávat AVI soubory, které jsme použili jako texturu vrstev. 5.1.2.1 Karta Layers V horní části karty layers najdeme combo box, pomocí kterého vybíráme vrstvu, kterou chceme upravovat. Pomocí tlačítka Add přidáme další vrstvu. Pomocí tlačítka Delete můžeme smazat aktuálně vybranou vrstvu (kromě poslední vrstvy). Ve střední části karty layers najdeme nastavení textury a barvy vrstvy. Jako texturu lze nastavit obrázek ve formátu TGA nebo video ve formátu AVI. Pokud není vybraná textura, nebo pokud není zaškrtnut checkbox Enable texture, je vrstva vyplněna barvou, kterou můžeme nastavit tlačítkem Color. Ve spodní části záložky layers najdeme obdelník znázorňující vybranou vrstvu. Tlačítka v rozích znázorňují aktuálně vybraný roh, se kterým manipulujeme. Tlačítko ve středu slouží k manipulaci s celou vrstvou. Pomocí kláves W, A, S, D hýbeme aktuálně vybraným rohem nebo celou vrstvou. S použitím klávesy Shift (Shift + W, A, S, D) je pohyb rychlejší, ale méně přesný. 5.1.2.2 Karta Player Pod kartou Player se nachází jednoduchý přehrávač AVI souborů, které jsme nastavili jako textury vrstev. V horní části karty player se zobrazuje aktuální snímková frekvence. Čím je snímková frekvence vyšší, tím je obraz plynulejší. Pokud je snímková frekvence příliš malá (< 25) bude obraz trhaný. V prostřední části karty player se nachází TrackBar, který znázorňuje postup přehrávání video textur. V pravé části pod TrackBarem se nachází celková délka přehrávané sekvence ve formátu H:M:S.
38
Ve spodní části karty player se nalézají tři tlačítka - play sloužící ke spuštění přehrávání, pause sloužící k zastavení přehrávání a stop sloužící k zastavení přehrávání a přesunutí na začátek.
5.2 Způsob použití Aplikace se užívá k umístění výsledných videosekvencí na správné místo. Při tom je dobré použít obrázek, který zakresluje nejvýznamější body ve videosekvenci, jako například rohy oken, hrany stěn nebo výstupky na stěně (Obr 2.2 a 2.3). Po otevření programu přesuneme zobrazovací okno na plochu projektoru a stiskem klávesy „f“, čímž ho zobrazíme přes celou plochu. Jako texturu vrstvy nastavíme obrázek zakreslující nejvýznamější body videosekvence a zarovnáme vrstvu tak, aby body seděli na místech, kam patří. Poté přidáme další vrstvu a celý postup opakujeme. Po zarovnání všech vrstev zaměníme obrázky skutečnými videosekvencemi a přejdeme na kartu Player. Po stisknutí Play se spustí všechny videosekvence. Pokud je některá ze sekvencí kratší, přehraje se až do posledního snímku, který poté zůstane zobrazen až do konce přehrání všech ostatních videosekvencí. Toho lze využít, pokud se například v polovině prezentace část scény stane statickou a do konce se nezmění.
5.3 Implementace nejdůležitějších částí Následující část popisuje některé detaily z implementace aplikace. Aplikace využívá OpenGL s rozšířením GLUT (OpenGL Utility Toolkit). GLUT je původně připraven pro C a očekává ve svých funkcích ukazatele na statické funkce. S objektovým C++ si moc nerozumí. Proto je potřeba použít techniku, která nám dovolí zacházet s GLUT objektově.[8] Třída GlutMaster v sobě uchovává ukazatele na virtuální metody ve třídě GlutWindow. Instance třídy Projector, která je potomkem třídy GlutWindow, přepisují tyto virtuální metody a nahrazují je svými. Toto nám umožňuje zacházet s jednotlivými okny jako s objekty a dovoluje nám zobrazovat i více OpenGL oken (projekci z více
39
projektorů). Toto však v aplikaci implementováno není. Vztahy mezi třídami jsou znázorněny v následujícím obrázku (Obr 5.1).
Obr 5.1 5.3.1 Zobrazování vrstev Vrsvy jsou instancemi třídy Layer. Tato třída obsahuje veškerá nastavení vrstvy od nastavení pozice, až po texturu a ukazatel na stream s videosekvencí. Každý objekt typu Projector si uchovává ukazatele na své vrstvy v datovém kontejneru typu vector. To nám umožňuje velice snadno přidávat a mazat jednotlivé vrstvy. K zobrazení vrstev slouží funkce CallBackDisplayFunc(void) ve třídě Projector. Tato funkce je volána jako standardní vykreslovací smyčka OpenGL (glutDisplayFunc()). V této funkci se projde celý vector s uloženými ukazateli na vrstvy a postupně se všechny vrstvy vykreslí. 5.3.2 Načítání TGA textury Formát TGA je vhodný pro ukládání a načítání textur, protože umožňuje spolu s barevnou informací ukládat i alfa složku (průhlednost), a to dokonce i v obrázcích s barevnou paletou. Pokud stačí uložit pouze příznak průhlednosti, je možné využít 16bitového
40
formátu pixelů, kdy je pro průhlednost rezervován pouze jeden bit – počet barev dosahuje hodnoty 32 tisíc, což je například pro textury dostatečné množství.[5] Data jsou v souboru TGA rozdělena do čtyř sekcí, ale pouze první sekce je povinná. V první sekci na začátku souboru je hlavička, jejíž velikost je vždy 18 byte. V hlavičce jsou uloženy základní informace o obraze, zejména jeho rozlišení, způsob kódování barvy a orientace obrázku. Z hlavicky zjistíme informace, které budeme potřebovat k načtení samotného obrázku. Po načtení dat z obrázku jej uložíme do paměti příkazem glTexImage2D(). Největší záludností je nutnost prohodit červenou a modrou složku obrázku. V TGA jsou barvy uloženy ve formátu RGB, zatímco specifikaci OpenGL vytvořila firma SGI (Silicon Graphic), jejíž systémy používají big endian. OpenGL totiž standardně vyžadují bitmapy ve formátu big endian, takže ve formátu BGR. V mé aplikaci slouží k načítání TGA textur funkce bitmapLoad() ve třídě Projector. 5.3.3 Načítání textur z AVI souboru Pro načítání videosouborů jsem využil knihovnu Video for Windows z dílny společnosti Microsoft. Tato knihovna ulehčuje otevírání a práci s AVI videosoubory. Pro práci s videosouborem slouží v aplikaci dvě funkce - OpenAviFile() a setFrame(), obě ve třídě Projector. První funkce, openAviFile(vrstva, avi_soubor), otevírá AVI soubor. Po otevření AVI souboru funkce nastaví ve vrstvě ukazatel na buffer, kam vrátí ukazatel na nový datový proud. Poté funkce setFrame(vrstva, číslo_snímku) vybírá jednotlivé snímky z AVI souboru a nastavuje je jako texturu vrstvy. Funkce setFrame() se volá v každém překreslení scény. Před samotným uložením snímku z videosouboru do paměti je potřeba prohodit červenou a modrou barevnou složku obrázku. Ze stejného důvodu, jako tomu bylo u TGA textur.
41
Jedním z problémů bylo zajistit, aby se videosoubor přehrával plynule a rychlost přehrávání nekolísala s aktuálním FPS. První nápad byl uložit FPS videosouboru a porovnávat ho s aktuálním FPS projekce. To se však neosvědčilo. Dalším nápadem bylo vypočítat, kolik milisekund zabere zobrazení jednoho snímku videosouboru. Poté porovnáme, kolik milisekund uběhlo od stisku tlačítka Play a vybereme požadovaný snímek. Tato technika byla nakonec implemantována v aplikaci.[9]
5.4 Test aplikace Výslednou aplikaci jsem otestoval v reálných podmínkách. 5.4.1 Test 1 První test spočíval v obarvení shluku papírových krabic. První obrázek znázorňuje rozmístění krabic před namapování textur (Obr 5.2).
Obr 5.2 Další snímek znázorňuje výsledek po namapování textur na stěny papírových krabic (Obr 5.3).
42
Obr 5.3 Následující obrázek znázorňuje čistý výstup z projektoru.
Obr 5.4 V prvním testu se aplikace osvědčila. Práce byla jednoduchá a po chvíli jsem se dopracoval k efektnímu výsledku. 5.4.2 Test 2 Druhý test spočíval v namapování několika čar na nerovný povrch krabic, které se budou z jednoho úhlu jevit jako rovné (Obr 5.5). Z jiných úhlů se budou jevit křivě (Obr 5.6).
43
Obr 5.5
Obr 5.6 Syrový výstup z projektoru vypadá následovně (Obr 5.7).
44
Obr 5.7 Druhý test dopadl také dobře. Z jednoho pozorovacího úhlu se jevily čáry rovně i na nerovném povrchu krabic. V pravé části obrázku (Obr 5.6) je však vidět drobná nepřesnost způsobená chybou při tvorbě textury. Tuto nepřesnost lze opravit vložením nové vrstvy, nastavením její barvy na černou a překrytím této nepřesnosti.
5.5 Rozšíření stávající aplikace Na aplikaci je stále co zlepšovat a dodávat. V této kapitole bych rád navrhl některá zlepšení, ke kterým jsem se v průběhu studia OpenGL a technik mappingu dopracoval, ale které jsem již nestihl do výsledné aplikace vložit. Jedním z největších zlepšení by dozajista byla podpora projekce na více projektorech současně. Jelikož je aplikace již dnes schopna vytvořit a pracovat s více instancemi třídy Projector, bylo by třeba předělat a přizpůsobit této funkcionalitě logiku a grafické rozhraní aplikace. Dalším významným zlepšením by bylo zavedení bufferu pro načítání snímků z videí. Zrychlilo by se tím načítání jednotlivých snímků a tím by vzrostla snímková frekvence celé projekce. To by vedlo k plynulejší projekci i při velikém počtu videosouborů. Zrychlení snímkové frekvence by dozajista způsobilo i nahrazení jednoduchého cyklu pro prohazování červené a modré barevné složky textur (RGB na BGR) za efektivnější způsob. Například funkcí sepsanou v assambleru.
45
46
6 Závěr Cílem této práce bylo dát čtenáři základní povědomí o tvorbě animovaných obrazů promítaných na fasády budov v praxi známé pod pojmem „mapping“. V bakalářské práci jsou rozebrána zařízení, která lze při projekci použít, jejich výhody, nevýhody a základní parametry, na které je při výběru projekčního zařízení nahlíženo. Čtenáři je popsán jeden ze základních postupů při tvorbě projekce a je mu představena jednoduchá aplikace implementovaná v jazyce C++ s použitím knihovny OpenGL, kterou lze využít při tvorbě projekce. Dále je čtenáři popsána základní problematika transformací, transformačních matic, texturování a práce s externím obsahem v počítačové grafice, která čtenáři ještě více přiblíží problematiku mappingu.
47
48
Zdroje [1] Wikipedie: Otevřená encyklopedie [online], [cit. 12. 5. 2011] URL: http://cs.wikipedia.org/wiki/Videomapping [2] Vítek P. Digitalni kino [online], [cit. 12. 5. 2011] URL: http://www.digitalnikino.cz/node/534 [3] Wikipedie: Otevřená encyklopedie [online], [cit. 12. 5. 2011] URL: http://cs.wikipedia.org/wiki/Dataprojektor [4] DISK Multimedia [online], [cit. 12. 5. 2011] URL: http://www.disk.cz/disk/view.csp?!AV,425 [5] Tišnovský P. Grafická knihovna OpenGL [online], [cit. 12. 5. 2011] URL: http://www.root.cz/clanky/graficka-knihovna-opengl-1 [6] Wikipedie: Otevřená encyklopedie [online], [cit. 12. 5. 2011] URL: http://cs.wikipedia.org/wiki/Lumen [7] Walnum C. Programujeme grafiku v Direct3D. Brno, Computer Press, 2004 [8] Stetten G., Crawford K. GlutMaster - version 0.3 [online], [cit 12. 5. 2011] URL: http://www.stetten.com/george/glutmaster/glutmaster.html [9] Turek M. NeHe OpenGL Tutoriály [online], [cit 12. 5. 2011] URL: http://nehe.ceske-hry.cz/tut_35.php
49
50
Seznam příloh Příloha 1: Ovládání programu Příloha 2: CD s textem bakalářské práce, spustitelným programem a zdrojovými kódy
51
Příloha 1: Ovládání programu
1. Karty Layers a Player slouží k přepínání mezi editací vrstev a přehrávačem 2. ComboBox sloužící k přepínání právě editované vrstvy 3. Tlačítko sloužící k přidání vrstvy 4. Tlačítko sloužící ke smazání právě vybrané vrstvy 5. Cesta k souboru s texturou 6. Tlačítko zobrazující dialog pro vybrání textury (TGA nebo AVI) 7. CheckBox zapínající a vypínající texturu vrstvy 8. Tlačítko zobrazující dialog pro výběr barvy textury 9. Obredlník znázorňující vrstvu a její barvu 10. Tlačítko pro výběr rohu vrstvy, se kterým chceme manipulovat 11. Tlačítko pro manipulaci s umístěním celé vrstvy
Klávesnice [W] – Posun aktuálně vybraným bodem nahoru [A] – Posun aktuálně vybraným bodem vlevo [S] – Posun aktuálně vybraným bodem dolu [D] – Posun aktuálně vybraným bodem vpravo + [Shift] – Při stisknutí klávesy shift dochází k rychlejšímu posunu
1. Aktuální snímková frekvence projekce (FPS) 2. TrackBar znázorňující průběh přehrávání 3. Celkový čas přehrávání (délka nejdelšího videosouboru) 4. Tlačítko sloužící ke spuštění přehrávání 5. Tlačítko sloužící k pozastavení přehrávání 6. Tlačítko sloužící k zastavení přehrávání a návratu na začátek