Za´padoˇceska´ univerzita v Plzni Fakulta aplikovany´ch vˇed Katedra informatiky a vy´poˇcetn´ı techniky
Bakal´ aˇ rsk´ a pr´ ace Tenk´ y grafick´ y klient pro mobiln´ı zaˇ r´ızen´ı
Plzeˇ n 2013
ˇ ak Michal Z´
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem bakal´aˇrskou pr´aci vypracoval samostatnˇe a v´yhradnˇe s pouˇzit´ım citovan´ ych pramen˚ u. V Plzni dne 2. kvˇetna 2013 ˇ ak Michal Z´
Abstract Visualization of data is a common need in the industrial automation software. These data come from multiple sources and by visualizing we display them together with semantic information. Using cross-platform technologies, our goal is to provide simple and thin graphical client which can work on mobile devices and be controlled through its interface or defined protocol. The rendering paradigm that we use is scene graph representation.
Podˇ ekov´ an´ı Chtˇel bych podˇekovat pˇredevˇs´ım panu Ing. Petru Vanˇeˇckovi, Ph.D. za cenn´e rady a pˇripom´ınky pˇri veden´ı pr´ace a firmˇe ICONICS Europe B. V. – o. z. za zap˚ ujˇcen´ı hardwaru nezbytn´eho k v´ yvoji pro platformu iOS.
3
Obsah ´ 1 Uvod
1
2 Software GENESIS 2.1 GraphWorX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Komponenta 3D View . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Sada operac´ı komponenty 3D View . . . . . . . . . . . . . . .
2 2 4 5
3 Vizualizace sc´ eny 3.1 Objekty a jejich transformace . . . 3.2 Graf sc´eny . . . . . . . . . . . . . . 3.3 Kamery . . . . . . . . . . . . . . . 3.4 V´ ybˇer objekt˚ u. . . . . . . . . . . . 3.4.1 Softwarov´e ˇreˇsen´ı . . . . . . 3.4.2 K´odov´an´ı objekt˚ u barvou . 3.4.3 Picking vyuˇz´ıvaj´ıc´ı geometry 3.5 Existuj´ıc´ı frameworky grafu sc´eny . 3.5.1 OpenSG . . . . . . . . . . . 3.5.2 Open Scene Graph . . . . . 3.5.3 Dalˇs´ı implementace . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . shader . . . . . . . . . . . . . . . .
4 OpenGL ES a prostˇ red´ı iOS 4.1 Struˇcn´ y pˇrehled verz´ı OpenGL ES . . . . 4.2 Pipeline OpenGL ES . . . . . . . . . . . 4.3 Pˇrehled API OpenGL ES . . . . . . . . . 4.3.1 Z´akladn´ı funkce a stavy OpenGL 4.3.2 Pr´ace s shadery . . . . . . . . . . 4.3.3 Vytv´aˇren´ı a plnˇen´ı zdroj˚ u . . . . 4.3.4 Kreslen´ı . . . . . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
. . . . . . .
. . . . . . . . . . .
6 6 7 7 8 8 8 9 9 9 10 10
. . . . . . .
11 11 11 13 13 13 14 15
4.4 4.5 4.6
V´ yvoj pro iOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Xcode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 GLKit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5 Architektura grafick´ eho klienta 5.1 Platformn´ı nez´avislost . . . . 5.2 Spoleˇcn´ y pˇredek Generic . . . 5.3 Syst´emov´e a ˇr´ıdic´ı tˇr´ıdy . . . 5.4 Grafick´e zdroje . . . . . . . . 5.4.1 Technika kreslen´ı . . . 5.4.2 Troj´ uheln´ıkov´e meshe . 5.4.3 Textury . . . . . . . . 5.5 Tˇr´ıdy obsluhuj´ıc´ı sc´enu . . . .
. . . . . . . .
18 18 19 20 21 21 22 23 24
6 Rozhran´ı grafick´ eho klienta 6.1 Meshe a textury . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.2 Uzly sc´eny a kamery . . . . . . . . . . . . . . . . . . . . . . . . . . . 6.3 Ostatn´ı operace rozhran´ı . . . . . . . . . . . . . . . . . . . . . . . . .
26 26 26 27
7 Uk´ azkov´ y protokol pro ovl´ ad´ an´ı klienta 7.1 Pˇr´ıkazy protokolu . . . . . . . . . . . . . . 7.1.1 Spr´ava mesh˚ u . . . . . . . . . . . . 7.1.2 Spr´ava uzl˚ u sc´eny . . . . . . . . . . 7.1.3 Spr´ava kamery . . . . . . . . . . . 7.1.4 D´avka pˇr´ıkaz˚ u. . . . . . . . . . . . 7.2 Interpretuj´ıc´ı tˇr´ıda . . . . . . . . . . . . . 7.3 Interaktivn´ı zad´av´an´ı pˇr´ıkaz˚ u ve Windows
29 29 29 30 31 32 32 33
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . . .
. . . . . . .
. . . . . . .
8 Uk´ azkov´ e sc´ eny 35 8.1 Pouˇzit´e meshe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 8.2 Benchmark . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36 9 Z´ avˇ er
37
A Pˇ r´ıloha: Uk´ azky sc´ en
39
B Pˇ r´ıloha: Pouˇ zit´ e verze shader˚ u
44
C Pˇ r´ıloha: Obsah CD
45
´ 1 Uvod V pr˚ umyslov´e sf´eˇre se setk´av´ame s potˇrebou zpracov´avat a n´aslednˇe vizualizovat r˚ uzn´a data. Tato data z´ısk´av´ame z mnoha zdroj˚ u, napˇr´ıklad ze stavu v´ yrobn´ı linky nebo aktu´aln´ıho nastaven´ı klimatizace objektu. Sjednocen´e zobrazen´e u ´daje pak umoˇzn ˇuj´ı oper´atorovi snazˇs´ı kontrolu situace. ˇ Casto je nutn´e data vizualizovat jako trojrozmˇernou sc´enu. Za prv´e mohou b´ yt p˚ uvodn´ı data spjata s konkr´etn´ımi souˇradnicemi, za druh´e tak m˚ uˇzeme usnadnit orientaci ve vizualizaci a za tˇret´ı se trojrozmˇern´e zobrazen´ı ˇcasto jev´ı jako atraktivnˇejˇs´ı. Chceme-li zobrazovat prostorovˇe, je vhodn´e sestavit grafick´eho klienta, kter´y n´am naˇse z´amˇery usnadn´ı, nebot’ knihovn´ı funkce OpenGL, OpenGL ES a DirectX poskytuj´ı aˇz pˇr´ıliˇs n´ızko´ urovˇ nov´a vol´an´ı a je potˇreba je vhodnˇe obalit. Dalˇs´ım c´ılem je snadn´a pˇrenositelnost klienta, tedy jeho nez´avislost na konkr´etn´ı platformˇe. V dneˇsn´ı dobˇe totiˇz existuj´ı r˚ uzn´a mobiln´ı zaˇr´ızen´ı (chytr´e telefony a tablety), kter´a na rozd´ıl od klasick´ ych poˇc´ıtaˇc˚ u disponuj´ı ˇcasto jedin´ ym moˇzn´ ym operaˇcn´ım syst´emem, kter´emu se mus´ıme pˇrizp˚ usobit. V´ ymˇenou za to vˇsak provozujeme aplikaci na stroji, kter´ y nen´ı um´ıstˇen´ y napevno na jednom m´ıstˇe, dod´avku elektˇriny potˇrebuje pouze k dob´ıjen´ı sv´e vlastn´ı baterie a ˇcasto m´a i niˇzˇs´ı poˇrizovac´ı cenu. Tato pr´ace popisuje implementaci klienta pro dvˇe platformy, Windows a iOS. Pro ovˇeˇren´ı spr´avn´e funkˇcnosti potˇrebujeme uk´azkov´e sc´eny. S jejich pomoc´ı lze ovˇeˇrit i v´ ykon klienta, a tak nal´ezt pˇr´ıpadn´e nedostatky.
1
2 Software GENESIS GENESIS je sadou aplikac´ı firmy Iconics pro sledov´an´ı a n´aslednou vizualizaci pr˚ umyslov´ ych dat. Software stav´ı na v´ıce vrstv´ach, jednotliv´e produkty mezi sebou mohou komunikovat a pˇred´avat si mˇeˇren´a ˇci syntetizovan´a data. Uˇzivatel si m˚ uˇze vybrat mezi 32 a 64 bitovou verz´ı softwaru. Sada GENESIS souvis´ı s odvˇetv´ımi HMI a SCADA. Zkratka HMI vyjadˇruje human-machine interface, tedy zaˇr´ızen´ı, kde uˇzivatel monitoruje cel´ y proces a m˚ uˇze do nˇej zas´ahnout. Do t´eto oblasti patˇr´ı pr´avˇe napˇr´ıklad 3D vizualizace, kter´ ymi se tato pr´ace zab´ yv´a. SCADA (supervisory control and data acquisition) pak znaˇc´ı centralizovan´e syst´emy ˇr´ızen´ı rozs´ahl´ ych pr˚ umyslov´ ych komplex˚ u. Oproti jednoduch´emu ˇr´ızen´ı se nav´ıc do syst´emu vn´aˇs´ı moˇznost z´asahu, slouˇz´ı jako nadstavba v´ıce pr˚ umyslov´ ym poˇc´ıtaˇc˚ um. Popiˇsme nyn´ı aplikaci GraphWorX ze sady GENESIS, kter´a souvis´ı se samotnou vizualizac´ı dat, t´ım p´adem i s HMI. Informace o ostatn´ıch aplikac´ıch nalezne laskav´y ˇcten´aˇr na ofici´aln´ıch str´ank´ach produktu GENESIS [2].
2.1
GraphWorX
GraphWorX slouˇz´ı k n´avrhu vizualizace. Uˇzivatel postupnˇe skl´ad´a grafick´e prvky a pˇripojuje k nim ˇza´dan´e akce. V´ ysledek je pot´e moˇzn´e si prohl´ednout v runtime m´odu tak, jak ho spatˇr´ı oper´ator. Pˇri produkci zobrazuje software vytvoˇren´y displej s vyuˇzit´ım technologie WPF (Windows Presentation Foundation), pˇr´ıpadnˇe Microsoft Silverlight. Kreslic´ı pl´atno uprostˇred obrazu je obklopeno ovl´adac´ımi a pˇrehledov´ymi panely. Horn´ı ovl´adac´ı panel nab´ız´ı v nˇekolika z´aloˇzk´ach objekty, kter´e m˚ uˇzeme um´ıstit na pl´atno. Uˇzivatel m´a k dispozici rovnˇeˇz hierarchick´ y pˇrehled pouˇz´ıvan´ ych objekt˚ u a jejich vlastnost´ı (viz obr´azek 2.1). Um´ıstˇen´ı panel˚ u nen´ı pevn´e, software umoˇzn ˇuje uspoˇra´dat pracovn´ı prostˇred´ı jinak.
2
Software GENESIS
GraphWorX
Obr´azek 2.1: Prostˇred´ı aplikace GraphWorX. Umist’ovan´ymi objekty mohou b´yt jednoduch´e vektorov´e tvary (obd´eln´ık, elipsa, mnoho´ uheln´ık), bitmapy (u kter´ych lze zvolit, zda maj´ı b´yt vloˇzeny pˇr´ımo do displeje, nebo se m´a uchovat pouze odkaz na nˇe) i r˚ uzn´e pˇreddefinovan´e panely. Vloˇzit m˚ uˇzeme tak´e objekt zvan´ y 3D View, kter´ y poskytuje zobrazov´an´ı trojrozmˇern´e sc´eny. Pro u ´pravu vzhledu objekt˚ u poskytuje GraphWorX klasick´e moˇznosti jako zmˇenu v´yplnˇe, obrysu a um´ıstˇen´ı v ose Z (z d˚ uvodu spr´avn´eho pˇrekr´yv´an´ı 2D objekt˚ u se takto vol´ı poˇrad´ı, v jak´em se kresl´ı), ale i ponˇekud netradiˇcn´ı efekty zn´am´e z Microsoft Office: st´ın, rozmaz´an´ı, z´aˇri. Komponenty, kter´e poskytuj´ı displeji urˇcitou dynamiˇcnost, jsou zastoupeny klasick´ymi prvky GUI typu radio button, check box, edit box, ale i akcemi, kter´e ovlivˇ nuj´ı objekty um´ıstˇen´e na displeji. Akce a prvky GUI propoj´ıme se zvolen´ ym zdrojem dat (data source), kter´ y m˚ uˇze odkazovat do datab´aze, z´ısk´avat data z pˇridruˇzen´ ych aplikac´ı GENESIS atd. Pr˚ ubˇeh dat lze rovnˇeˇz simulovat, lok´aln´ı simul´ator pak poskytne napˇr´ıklad sinusoidov´y sign´al. V prvc´ıch GUI se z´ıskan´e hodnoty mapuj´ı celkem pˇr´ımoˇcaˇre na zobrazovan´ y text nebo zaˇskrtnut´ı, akce se z´ıskanou hodnotou m˚ uˇze zach´azet uˇz ponˇekud sloˇzitˇejˇs´ım zp˚ usobem – aplikuje ji napˇr´ıklad na transformaci nebo barvu objektu, s n´ımˇz je akce spojena.
3
Software GENESIS
Komponenta 3D View
GraphWorX nab´ız´ı d´ale tak´e komponenty souvisej´ıc´ı s ostatn´ımi aplikacemi sady GENESIS. T´ımto zp˚ usobem m˚ uˇzeme slouˇcit v´ıce pohled˚ u do jednoho displeje. Za zm´ınku stoj´ı rovnˇeˇz volba vzhledu displeje, coˇz pˇredstavuje velikost, barvu pozad´ı, pˇr´ıpadnˇe ˇsablonu vzhledu. Uˇzivatel m˚ uˇze upravit tak´e pohled na sc´enu, aktivovat mˇr´ıˇzku a zobrazit souhrnn´e statistiky.
2.2
Komponenta 3D View
Jelikoˇz se tato pr´ace zab´ yv´a trojrozmˇernou vizualizac´ı na mobiln´ıch zaˇr´ızen´ıch, pod´ıv´ame se nyn´ı podrobnˇeji na komponentu 3D View (obr´azek 2.2). Vznikl´y grafick´y klient by mˇel b´ yt z velk´e ˇca´sti schopn´ y operac´ı, kter´e tato komponenta poskytuje.
Obr´azek 2.2: Komponenta 3D View obsahuj´ıc´ı nˇekolik objekt˚ u. V design m´odu umoˇznuje 3D View (podobnˇe jako pl´atno cel´eho displeje v GraphWorX) um´ıstˇen´ı jednotliv´ ych primitiv ˇci mesh˚ u (napˇr´ıklad krychli, kouli, kuˇzel a v´alec), kaˇzd´emu lze pˇridˇelit identifikaˇcn´ı n´azev, podle nˇehoˇz m˚ uˇze b´ yt vyhled´an. Objekty lze seskupit i rozdˇelit, pˇresouvat, rotovat a mˇenit jejich velikost. 3D View proto zobrazuje pomocnou mˇr´ıˇzku zn´amou z 3D softwaru pro modelovan´ı a animace. Vzhled objektu ovlivˇ nuje pˇriˇrazen´ y materi´al, kter´ y je pops´an ˇctyˇrmi sloˇzkami osvˇetlovac´ıho modelu (ambient, diffuse, specular a emissive) seˇcten´ ymi po osvˇetlen´ı ve v´ yslednou barvu. Nam´ısto jednolit´e barvy m˚ uˇzeme pouˇz´ıt texturu, kter´a se na model namapuje podle jeho texturovac´ıch souˇradnic. Tato moˇznost umoˇzn ˇuje v´ıce realistick´e vn´ım´an´ı sc´eny.
4
Software GENESIS
Komponenta 3D View
Komponenta 3D View nab´ız´ı i nastavovan´ı kamer (pohled˚ u na sc´enu), mezi nimiˇz pak lze pˇrep´ınat. Tohoto chov´an´ı se d´a dobˇre vyuˇz´ıt u rozs´ahlejˇs´ıch sc´en. Sc´eny je vˇzdy osvˇetlena jedn´ım svˇetlem, kter´e se nach´az´ı na souˇradnic´ıch pozorovatele (aktivn´ı kamery). Akc´ı, kter´e m˚ uˇzeme na objekty ve sc´enˇe pˇripojit, nalezneme v GraphWorX v´ıce. Prvn´ı moˇznost´ı je aplikov´an´ı transformace (zmˇena pozice, rotace, velikosti podle hodnoty z data source), druhou zmˇena vlastnost´ı materi´alu, coˇz odpov´ıd´a akci Color ve 2D prostˇred´ı. V nab´ıdce se vyskytuje rovnˇeˇz akce Pick, kter´a nast´av´a po v´ ybˇeru objektu uˇzivatelem (konkr´etnˇe po kliknut´ı definovan´ ym tlaˇc´ıtkem).
2.2.1
Sada operac´ı komponenty 3D View
Sadu operac´ı komponenty 3D View, kter´e si tato pr´ace klade za c´ıl naimplementovat do mobiln´ıho grafick´eho klienta a poskytnout odpov´ıdaj´ıc´ı pˇr´ıstupov´e aplikaˇcn´ı rozhran´ı, tvoˇr´ı:
• rendering troj´ uheln´ıkov´ ych mesh˚ u; • konfigurace materi´al˚ u a jeho pˇriˇrazen´ı mesh˚ um; • aplikov´an´ı transformac´ı (translace, rotace, aj.); • vytv´aˇren´ı a spr´ava kamer; • osvˇetlen´ı sc´eny z pozice aktivn´ı kamery; • picking.
5
3 Vizualizace sc´eny Pod pojmem vizualizace rozum´ıme vytv´aˇren´ı obrazu ˇci animace za u ´ˇcelem pˇred´an´ı informace. V naˇsem pˇr´ıpadˇe dos´ahneme v´ ysledku za pomoci renderingu. Vektorov´a data jsou zasl´ana ke zpracov´an´ı grafick´e kartˇe (avˇsak mohou b´ yt zpracov´ana i softwarovˇe na procesoru), kde jsou postupn´ym sledem algoritm˚ u pˇremˇenˇena na rastrov´y obraz. Grafick´a rozhran´ı poskytuj´ı operace na u ´rovni element´arn´ıch prvk˚ u, at’ se jedn´a o manipulaci s buffery, texturami nebo shadery. Nad tyto operace potˇrebujeme postavit logiku, kter´a bude spolehlivˇe spravovat sc´enu a element´arn´ı prvky ponese skryt´e uvnitˇr.
3.1
Objekty a jejich transformace
V z´akladn´ı podobˇe m˚ uˇzeme sc´enu ch´apat jako mnoˇzinu rozm´ıstˇen´ ych, pˇr´ıpadnˇe jinak transformovan´ ych objekt˚ u, coˇz mohou b´ yt napˇr. troj´ uheln´ıkov´e meshe, kˇrivky a plochy, ale i objekty se speci´aln´ım v´ yznamem – kamery a svˇetla. Tyto pomocn´e objekty nelze pˇr´ımo zobrazit, ale lze je vyuˇz´ıt pro glob´aln´ı ovlivnˇen´ı renderingu. Kaˇzd´e um´ıstˇen´ı definuje jeho transformaˇcn´ı matice, u kamery definujeme nav´ıc i matici projekˇcn´ı. Pro naˇse u ´ˇcely uvaˇzujme, ˇze kaˇzd´y zobraziteln´y objekt tvoˇr´ı mnoˇzina troj´ uheln´ık˚ u a jeho um´ıstˇen´ı je definov´ano transformaˇcn´ı matic´ı QW . Zvol´ıme jednu kameru sc´eny jako aktivn´ı, jej´ı projekˇcn´ı matici oznaˇc´ıme QP , transformaˇcn´ı matici definuj´ıc´ı jej´ı um´ıstˇen´ı pak QV . Vˇsechny vrcholy (troj´ uheln´ık˚ u) jsou pot´e transformov´any podle vztahu 3.1.
x0
x
0 y = QP QV QW y z0 z 0 w w
6
(3.1)
Vizualizace sc´eny
Graf sc´eny
Tento pˇr´ıstup vˇsak neumoˇzn ˇuje nastavit implicitnˇe z´avislost na jin´em objektu. Pokud bychom chtˇeli vizualizovat sc´enu obsahuj´ıc´ı napˇr´ıklad proj´ıˇzdˇej´ıc´ı vlak, mus´ıme v kaˇzd´em sn´ımku nastavit transformaci lokomotivy i vˇsech vagon˚ u zvl´aˇst’.
3.2
Graf sc´ eny
Popisovan´ y zp˚ usob pˇr´ıd´av´a do sc´eny moˇznost relativn´ıch transformac´ı v˚ uˇci nadˇrazen´emu objektu v hierarchii. Sc´enu reprezentujeme acyklick´ym, stromov´ym grafem s pr´avˇe jedn´ım koˇrenov´ym uzlem. Kaˇzd´a hrana grafu znaˇc´ı z´avislost, pˇriˇcemˇz kaˇzd´ y uzel sm´ı z´aviset pr´avˇe na jednom jin´em, jedin´ ym nez´avisl´ ym uzlem je koˇren. Jak jiˇz bylo zm´ınˇeno, v grafu nesm´ı vznikat cykly, tedy ˇz´adn´ y objekt nesm´ı rekurzivnˇe z´aviset s´am na sobˇe. Hlavn´ı v´yhodou tohoto uspoˇr´ad´an´ı je skl´ad´an´ı transformac´ı – matice QW je nyn´ı definov´ana jako souˇcin transformaˇcn´ıch matic uzl˚ u cesty od koˇrenu k dan´emu objektu. M˚ uˇzeme tak vytv´aˇret skupiny objekt˚ u ovlivniteln´e transformac´ı jednoho uzlu. Nad grafem sc´eny m˚ uˇze b´ yt postavena dalˇs´ı pomocn´a datov´a struktura pro urychlen´ı vykreslov´an´ı, napˇr´ıklad strom octree.
3.3
Kamery
Kamery pˇredstavuj´ı pohled na sc´enu pomoc´ı sv´e projekˇcn´ı matice, kter´a definuje parametry prom´ıt´an´ı, dokonce i jeho zp˚ usob (ortogon´aln´ı nebo perspektivn´ı). Abychom pˇrem´ıstili pozorovatele do jin´e pozice, m˚ uˇzeme rozˇs´ıˇrit definici kamery o matici pohledu, avˇsak to se zd´a b´yt nevhodn´e ve chv´ıli, kdy lze vyuˇz´ıt grafu sc´eny. Pˇriˇrad´ıme-li kameˇre nadˇrazen´y uzel sc´eny, m˚ uˇzeme pouˇz´ıt jeho transformaci pro v´ypoˇcet matice pohledu podle vztahu 3.2, kde QV znaˇc´ı v´yslednou matici pohledu a QWi matici transformace i-t´eho uzlu ve smˇeru od koˇrenu. Jedn´a se o afinn´ı transformace, coˇz umoˇzn ˇuje urychlen´ı vypoˇctu inverzn´ı matice oproti obecn´emu algoritmu.
QV = QWN QWN −1 . . . QW1 QW0
7
−1
(3.2)
Vizualizace sc´eny
3.4
V´ybˇer objekt˚ u
V´ ybˇ er objekt˚ u
Ve vizualizaci m˚ uˇzeme od uˇzivatele vyˇzadovat zpˇetnou vazbu, konkr´etnˇe v´ ybˇer nˇekter´eho z objekt˚ u ve sc´enˇe pomoc´ı myˇsi ˇci dotykov´eho displeje (operace oznaˇcovan´a jako picking). Uved’me nˇekolik pˇr´ıstup˚ u, jak toho doc´ılit.
3.4.1
Softwarov´ eˇ reˇ sen´ı
Nejprve hled´ame matice QP
−1
(inverzn´ı k projektivn´ı) a QV
−1
(inverzn´ı k matici
pohledu). N´aslednˇe jimi transformujeme souˇradnice kurzoru (x, y) a z´ısk´av´ame jeho pozici X v prostoru sc´eny. Vektor s vznikl´ y jako rozd´ıl bodu X a pozice kamery C urˇcuje smˇer polopˇr´ımky, kter´a vyb´ır´a s n´ı koliduj´ıc´ı objekty. Cel´y v´ypoˇcet je pops´an ve vztahu 3.3. Promˇenn´e width a height pˇredstavuj´ı rozmˇery pl´atna, do kter´eho rendering prob´ıh´a.
−1
2y 1 − height 0 1
X = QV
−1
QP
−1
2x width
(3.3)
s=X −C Nyn´ı staˇc´ı nal´ezt objekty koliduj´ıc´ı se vzniklou polopˇr´ımkou, z nichˇz vybereme nejm´enˇe vzd´alen´ y od bodu C. Algoritmus lze urychlit hierarchick´ ym uspoˇra´d´an´ım geometrie ve sc´enˇe nebo napˇr. pouˇzit´ım bounding box˚ u. V´ yhodou jsou nulov´e poˇzadavky na grafick´e rozhran´ı a v pˇr´ıpadˇe mal´eho poˇctu objekt˚ u i rychl´a odezva. Se stoupaj´ıc´ım poˇctem objekt˚ u nebo troj´ uheln´ık˚ u poc´ıt´ıme znaˇcn´e zpomalen´ı aplikace pˇri v´ ybˇeru objekt˚ u.
3.4.2
K´ odov´ an´ı objekt˚ u barvou
Implementaˇcnˇe jednoduˇsˇs´ı a hardwarovˇe akcelerovan´ y v´ ybˇer lze prov´est tak, ˇze kaˇzd´emu objektu (pˇr´ıpadnˇe i troj´ uheln´ıku) pˇridˇel´ıme ˇc´ıseln´ y identifik´ator, kter´ y 8
Vizualizace sc´eny
Existuj´ıc´ı frameworky grafu sc´eny
pˇrevedeme na odpov´ıdaj´ıc´ı unik´atn´ı barvu. N´aslednˇe provedeme rendering, kresl´ıme vˇsechny objekty jednolitˇe jejich barvou. Po dokonˇcen´ı pˇreˇcteme barvu pixelu na souˇradnic´ıch kurzoru, pˇrevedeme ji zpˇet na identifik´ator (pokud se nejednalo o barvu pozad´ı) a vyhled´ame objekt v pˇr´ısluˇsn´e datov´e struktuˇre. Pro vysok´e poˇcty objekt˚ u (troj´ uheln´ık˚ u) na sc´enˇe se tato metoda obecnˇe jev´ı jako rychlejˇs´ı. Nav´ıc nen´ı potˇreba udrˇzovat geometrii v pamˇeti pˇr´ıstupn´e procesoru, m˚ uˇze b´yt nad´ale uchov´ana v grafick´e pamˇeti. Zpomaluj´ıc´ımi prvky mohou vˇsak b´yt vysok´e rozliˇsen´ı (lze ˇreˇsit podvzorkov´an´ım) a z´avereˇcn´e ˇcten´ı barvy z color bufferu.
3.4.3
Picking vyuˇ z´ıvaj´ıc´ı geometry shader
Detekci kolize paprsku s geometri´ı lze pˇresunout i na GPU, kde ji ˇreˇs´ı geometry shader [9]. Oproti pickingu zaloˇzen´emu na k´odov´an´ı barvou potˇrebujeme v´ystup z pixel shaderu o velikosti pouh´eho jednoho pixelu, kter´ y uchov´av´a identifik´ator objektu. Tento jedin´y pixel n´am pak poslouˇz´ı k vyhled´an´ı vybran´eho objektu. OpenGL ES 2.0 bohuˇzel nedok´aˇze pracovat s geometry shadery, a tak zde nejsme schopni toto ˇreˇsen´ı implementovat.
3.5
Existuj´ıc´ı frameworky grafu sc´ eny
Uspoˇr´ad´an´ı sc´eny do grafu je ˇcasto pouˇz´ıvan´e ˇreˇsen´ı a existuje mnoho framework˚ u, napˇr´ıklad OpenSG a Open Scene Graph, kter´e poskytuj´ı ˇcasto mnohem robustnˇejˇs´ı implementaci, jeˇz je pro naˇse u ´ˇcely v podstatˇe nadbyteˇcn´a. I tak pˇri sv´e velikosti a uˇzit´ı mohou slouˇzit jako dobr´ y vzor pro v´ yvoj vlastn´ıho ˇreˇsen´ı.
3.5.1
OpenSG
OpenSG implementuje graf sc´eny pro mnoho platforem (Windows, Mac OS X, Linux a Solaris) a stav´ı na OpenGL. O framework se star´a seskupen´ı OpenSG Forum a je ˇs´ıˇren pod licenc´ı LGPL (jedn´a se tedy o open source produkt). V grafu sc´eny jsou geometrick´a data um´ıst’ov´ana pouze do list˚ u (nazvan´e interior node), pr˚ uchoz´ı uzly interpretuj´ı r˚ uzn´e akce (seskupen´ı objekt˚ u, transformace a dalˇs´ı) [8]. 9
Vizualizace sc´eny
3.5.2
Existuj´ıc´ı frameworky grafu sc´eny
Open Scene Graph
Aˇckoliv n´azev m˚ uˇze ˇcten´aˇre zm´ast, ˇze se jedn´a o jiˇz v´ yˇse popisovan´ y produkt OpenSG, opak je pravdou. Poˇca´tky v´ yvoje Open Scene Graph a OpenGL se datuj´ı do pˇribliˇznˇe stejn´e doby, coˇz vedlo ke zvolen´ı podobn´ych n´azv˚ u. Jedn´a se o framework ˇs´ıˇren´y pod vlastn´ı licenc´ı OpenSceneGraph Public License, kter´a je zaloˇzena na LPGL. V´ yvoj´aˇr m´a tedy k dispozici zdrojov´e k´ody, pˇriˇcemˇz se vyuˇz´ıv´a jazyka C++.
3.5.3
Dalˇ s´ı implementace
Firma VSG vyv´ıj´ı komerˇcn´ı objektov´e API Open Inventor. Kromˇe p˚ uvodn´ı multiplatformn´ı implementace v C++ jsou dnes k dispozici varianty tak´e pro platformy .NET a Java. VSG rovnˇeˇz poskytuje nˇekolik rozˇs´ıˇren´ı, napˇr´ıklad vizualizaci objemov´ ych dat nebo rendering pomoc´ı raytracingu. Pro platformu Java existuj´ı napˇr´ıklad knihovny Java3D, Jreality a Aviatrix3D, nicm´enˇe jiˇz nˇekolik let nevych´azej´ı jejich nov´e verze. Z oblasti webov´ych technologi´ı (HTML5 a WebGL) jmenujme OSG.JS, aktivnˇe vyv´ıjenou javascriptovou implementaci scene graphu, a X3D/X3DOM, kter´e reprezentuj´ı sc´enu pomoc´ı jazyka XML.
10
4 OpenGL ES a prostˇred´ı iOS Pro akcelerovan´e vykreslov´an´ı potˇrebujeme vyuˇz´ıvat takov´e rozhran´ı, kter´e zajist´ı komunikaci s grafickou kartou nebo ˇcipem. Zat´ımco u klasick´ ych desktopov´ ych poˇc´ıtaˇc˚ u se setk´av´ame s OpenGL (a v operaˇcn´ım syst´emu Windows i s Direct3D, coˇz je souˇca´st frameworku DirectX), mobiln´ı platforma implementuje OpenGL ES, kter´e bylo navrˇzeno s ohledem na niˇzˇs´ı v´ykon zm´ınˇen´eho hardwaru jako podmnoˇzina klasick´eho OpenGL.
4.1
Struˇ cn´ y pˇ rehled verz´ı OpenGL ES
OpenGL ES 1.0 a 1.1 vych´az´ı ze specifikace OpenGL verze 1.3, resp. verze 1.5 [4]. Rendering prob´ıh´a pouze za pomoci fixed function pipeline, tedy pevnˇe nadefinovanou cestou, programovatelnost nen´ı souˇca´st´ı normy. Ne vˇsechna zaˇr´ızen´ı pracuj´ıc´ı s OpenGL ES podporuj´ı operace s ˇc´ısly v pohybliv´e ˇra´dov´e ˇca´rce, a tak jsou aplikaci zpˇr´ıstupnˇena i vol´an´ı pˇred´avaj´ıc´ı hodnoty ve form´atu pevn´e ˇr´adov´e ˇca´rky. V roce 2010 vyˇsla specifikace OpenGL ES ve verzi 2.0 [5]. S pˇredchoz´ı verz´ı nen´ı kompatibiln´ı, kreslen´ı cestou fixed function pipeline jiˇz nen´ı d´ale podporov´ano. Tu nahradila programovateln´a pipeline a je explicitnˇe nutn´e naimplementovat operace na u ´rovni vrchol˚ u (vertex shader) a fragment˚ u (fragment shader). Tento rok (2013) byla zveˇrejnˇena ofici´aln´ı specifikace OpenGL ES verze 3.0. Vzhledem k moment´alnˇe n´ızk´emu rozˇs´ıˇren´ı zaˇr´ızen´ı podporuj´ıc´ıch nejnovˇejˇs´ı verzi se OpenGL ES 3.0 tato pr´ace nezab´ yv´a.
4.2
Pipeline OpenGL ES
Pˇrejdeme k hardwarov´e implementaci zpracov´an´ı geometrie. Kaˇzd´y poˇzadavek na rendering je zpracov´an vnitˇrn´ı pipeline, kter´a obsahuje nemˇenn´e a programovateln´e prvky. Fixn´ı ˇca´sti mohou b´yt d´ıky sv´e jednoduchosti (nevykon´avaj´ı jin´y typ operace) optimalizov´any jiˇz na u ´rovni hardwaru.
11
OpenGL ES a prostˇred´ı iOS
Pipeline OpenGL ES
Na poˇc´atku zpracov´av´ame pˇredanou mnoˇzinu primitiv dan´eho typu: body, ˇc´ary, troj´ uheln´ıky. Typ je pro celou mnoˇzinu nemˇenn´ y, pokud bychom chtˇeli vykreslit napˇr. troj´ uheln´ıky i body, nezbyde n´am jin´a moˇznost, neˇz rozdˇelit operaci na dvˇe. Jednotliv´e vrcholy primitiv n´aslednˇe proch´az´ı programovateln´ ym vertex shaderem. Ten je psan´y v jazyce GLSL (OpenGL Shading Language), pˇriˇcemˇz standardnˇe slouˇz´ı k transformaci vrchol˚ u a k v´ypoˇctu dalˇs´ıch hodnot k nim se vztahuj´ıc´ıch. Vzhledem k tomu, ˇze tato ˇc´ast je programovateln´a, m˚ uˇze poslouˇzit i k m´enˇe obvykl´ym v´ypoˇct˚ um. V´ ypoˇcet je prov´adˇen nez´avisle na ostatn´ıch vrcholech, coˇz umoˇzn ˇuje cel´ y proces paralelizovat.
Triangles/Lines/Points
Primitive Processing
Vertices
Vertex Shader
Primitive Assembly
Rasterizer
API
Vertex Buffer Objects
Fragment Shader
Depth Stencil
Colour Buffer Blend
Dither
Frame Buffer
Obr´azek 4.1: OpenGL ES 2.0 Pipeline. Zdroj: khronos.org/opengles/2_X Po pr˚ uchodu vertex shaderem se provede rasterizace primitiv a vznikl´e fragmenty putuj´ı do fragment shaderu, opˇet programovateln´e souˇc´asti pipeline. Fragment odpov´ıd´a v podstatˇe jednomu pixelu, opˇet plat´ı, ˇze prov´adˇen´e operace nez´avis´ı na ostatn´ıch (nelze k nim ani pˇristupovat). Fragment shader je moˇzn´e vyuˇz´ıt napˇr´ıklad pro v´ypoˇcet per-pixel osvˇetlen´ı. Jeho v´ystup se oˇrez´av´a podle hodnot depth a stencil bufferu a nastaven´ı depth a stencil test˚ u, pot´e doch´az´ı k m´ıch´an´ı (blendingu) s jiˇz existuj´ıc´ımi pixely frame bufferu, ditheringu a z´apisu do frame bufferu. Na obr´azku 4.1 je pˇribl´ıˇzena cel´a pipeline OpenGL ES 2.0.
12
OpenGL ES a prostˇred´ı iOS
4.3
Pˇrehled API OpenGL ES
Pˇ rehled API OpenGL ES
Popisovat kompletnˇe cel´e API dle specifikace je samozˇrejmˇe nad r´amec t´eto pr´ace, zmiˇ nme vˇsak alespoˇ n nˇekter´e funkce, kter´e vyuˇzijeme pro vizualizaci sc´eny. Tyto funkce jsou prostˇredkem k univerz´aln´ı komunikaci s grafick´ ym hardwarem, jednotn´ ym rozhran´ım ovladaˇc˚ u mnoha grafick´ ych karet a ˇcip˚ u. Stav renderingu a spr´avu jednotliv´ ych zdroj˚ u m´a na starosti kontext OpenGL. Pˇr´ıkazy OpenGL dodrˇzuj´ı pˇresn´ y form´at pojmenov´an´ı. Kaˇzd´ y je uvozen nejprve sekvenc´ı gl, n´asleduje n´azev funkce a pak poˇcet promˇenn´ ych a zkratka datov´eho typu. Datov´ym typem m˚ uˇze b´yt cel´e ˇc´ıslo (integer, i), ˇc´ıslo v pohybliv´e ˇr´adov´e ˇc´arce (float, f), pˇr´ıpadnˇe pole (v). Jako pˇr´ıklad uved’me pˇr´ıkaz glUniform1fv: vol´ame funkci s n´azvem Uniform, a to ve variantˇe, kdy vyˇzaduje jako argument jedno pole ˇc´ısel v pohybliv´e ˇra´dov´e ˇca´rce.
4.3.1
Z´ akladn´ı funkce a stavy OpenGL
Rendering se neprov´ad´ı pˇr´ımo na obrazovku, ale do pomocn´eho bufferu (back bufferu), kter´y je po dokonˇcen´ı kreslen´ı propagov´an (stane se front bufferem). T´ımto chov´an´ım pˇredch´az´ıme problik´av´an´ı sc´eny pˇri renderingu. K vyplnˇen´ı back bufferu jednotnou hodnotou barvy a hloubky slouˇz´ı pˇr´ıkaz glClear. Barvu nastav´ıme pomoc´ı funkce glClearColor, kter´a si za sv´e ˇctyˇri parametry bere barevn´e sloˇzky (r, g, b, a), hloubku funkc´ı glClearDepth vyˇzaduj´ıc´ı parametr v rozsahu od nuly do jedn´e. V OpenGL existuj´ı booleovsk´e stavy jako napˇr´ıklad GL_DEPTH_TEST (urˇcuje, jestli m´a doch´azet ke kontrole hloubky a jej´ımu z´apisu do depth bufferu), kter´e lze zap´ınat a vyp´ınat funkcemi glEnable a glDisable.
4.3.2
Pr´ ace s shadery
Pro pr´aci s shadery mus´ıme nejprve pˇristoupit k jejich kompilaci a linkingu. OpenGL nepracuje se soubory, ale s ˇretˇezci, tud´ıˇz je nutn´e nejprve shader naˇc´ıst napˇr. pomoc´ı standardn´ı knihovny jazyka C ˇci C++. Nov´y shader vytvoˇr´ıme vol´an´ım glCreateShader, pˇriˇcemˇz jako parametr uvedeme typ shaderu (hlaviˇcky OpenGL 13
OpenGL ES a prostˇred´ı iOS
Pˇrehled API OpenGL ES
definuj´ı konstanty GL_VERTEX_SHADER a GL_FRAGMENT_SHADER). K´od psan´y v GLSL a uchov´avan´ y v naˇcten´em ˇretˇezci pˇred´ame funkc´ı glShaderSource, naˇceˇz spust´ıme kompilaci pˇr´ıkazem glCompileShader. Vertex a fragment shader spoj´ıme dohromady v jeden program, kter´ y nejprve vytvoˇr´ıme vol´an´ım glCreateProgram, pot´e pˇripoj´ıme oba shadery pouˇzit´ım funkce glAttachShader a provedeme linking funkc´ı glLinkProgram. Pro kontrolu pˇrekladu shaderu i jejich linkingu m˚ uˇzeme z´ıskat logy cel´eho procesu pomoc´ı glGetShaderInfoLog, respektive glGetProgramInfoLog. Shadery uvoln´ıme z pamˇeti vol´an´ım glDeleteShader, program vol´an´ım glDeleteProgram. Dost´av´ame se k samotn´emu pouˇzit´ı (vykon´an´ı) programu sloˇzen´eho z pˇreloˇzen´ych shader˚ u. Aktivace programu je jednoduch´a, staˇc´ı zavolat funkci glUseProgram, kter´e pˇred´ame patˇriˇcn´ y identifik´ator. Pˇred´ame-li nulu, pouˇz´ıvan´ y program je odpojen a v klasick´e verzi OpenGL (nikoliv OpenGL ES) pˇreb´ır´a rendering fixn´ı pipeline. V GLSL pouˇz´ıv´ame glob´aln´ı konstanty uniforms napˇr´ıklad k pˇred´av´an´ı transformaˇcn´ı matice renderingu. Ty pˇred´ame shader˚ um jednou z variant funkce glUniform (z´aleˇz´ı na typu pˇred´avan´e promˇenn´e a jejich poˇctu).
4.3.3
Vytv´ aˇ ren´ı a plnˇ en´ı zdroj˚ u
Zdroji (resources) m´ame v naˇsem pˇr´ıpadˇe na mysli vertex buffery, element array buffery, vertex arrays a textury. Vertex buffer, jak jiˇz n´azev napov´ıd´a, slouˇz´ı k uchov´av´an´ı vrchol˚ u, element array buffer slouˇz´ı k uchov´an´ı index˚ u pro nepˇr´ım´e adresov´an´ı vrchol˚ u. T´ımto zp˚ usobem jsme schopni bˇehem renderingu vyuˇz´ıt jeden vrchol v´ıcekr´at (odkazuje na nˇej v´ıce index˚ u). Vertex array object zapouzdˇruje veˇsker´ y stav potˇrebn´ y k rederingu, tj. form´at vrchol˚ u a pˇripojen´e buffery. Textura uchov´av´a bitmapu urˇcenou k namapov´an´ı na renderovan´a primitiva. Pouˇzit´ı buffer˚ u je v postatˇe jednoduch´e, vytvoˇren´ı provedeme funkc´ı glGenBuffers vracej´ıc´ı identifik´ator vytvoˇren´eho objektu, pˇripojen´ı funkc´ı glBindBuffer, kter´e naopak identifik´ator pˇred´av´ame. Data do bufferu um´ıst’ujeme vol´an´ım glBufferData, kdy specifikujeme velikost, ukazatel na data a zp˚ usob uˇzit´ı bufferu. Uvolnˇen´ı provedeme funkc´ı glDeleteBuffers. Popsan´e funkce jsou shodn´e pro vertex i element array buffer.
14
OpenGL ES a prostˇred´ı iOS
V´yvoj pro iOS
Texturu vytvoˇr´ıme vol´an´ım glGenTextures, pot´e ji mus´ıme pˇripojit pomoc´ı glBindTexture, abychom s n´ı mohli nad´ale manipulovat. Jako parametry pˇred´ame c´ıl pˇripojen´ı a identifik´ator vytvoˇren´e textury. C´ılem je v naˇsem pˇr´ıpadˇe vˇzdy dvojrozmˇern´a textura definovan´a konstantou GL_TEXTURE_2D. Bitmapu do textury nakop´ırujeme funkc´ı glTexImage2D, kter´a vyˇzaduje parametr˚ u jiˇz v´ıce: c´ıl (opˇet GL_TEXTURE_2D), u ´roveˇ n (pouˇz´ıv´a se pro mipmaping), form´at dat, rozmˇery, ukazatel na data bitmapy atd. Zat´ımco v klasick´em OpenGL je moˇzn´e pˇred´avat texturu v jin´em form´atu, neˇz je pak uloˇzena v grafick´e pamˇeti, OpenGL ES konverzi uvnitˇr funkce nepodporuje. Uvolnˇen´ı textury prov´ad´ı operace glDeleteTextures.
4.3.4
Kreslen´ı
Pˇri kreslen´ı aktivujeme program obsahuj´ıc´ı shadery funkc´ı glUseProgram a napln´ıme konstanty shader˚ u (uniforms) aktu´aln´ımi hodnotami. Konstanty nelze nastavit pˇred pˇripojen´ım programu. Pokud pouˇz´ıv´ame textury, pˇripoj´ıme je jiˇz zm´ınˇen´ ym vol´an´ım glBindTexture, mezi jednotliv´ ymi jednotkami pˇri jejich vˇetˇs´ım pouˇz´ıvan´em mnoˇzstv´ı pˇrep´ın´ame funkc´ı glActiveTexture. Vertex array object pˇripoj´ıme analogicky funkc´ı glBindVertexArray, jako parametr uvedeme jeho identifik´ator. Nakonec zavol´ame funkci glDrawElements, kter´a sestav´ı primitiva z vrchol˚ u vertex bufferu podle index˚ u uloˇzen´ych v element array bufferu. Prvn´ı parametr uv´ad´ı typ kreslen´ych primitiv (napˇr. body, u ´seˇcky, troj´ uheln´ıky), dalˇs´ımi jsou poˇcet index˚ u a jejich datov´y typ. Jako posledn´ı parametr uvedeme offset prvn´ıho indexu v element array bufferu.
4.4
V´ yvoj pro iOS
S operaˇcn´ım syst´emem iOS se setk´ame v produktech spoleˇcnosti Apple Inc., jmenovitˇe iPhone, iPad, iPod Touch a Apple TV. Vych´az´ı z desktopov´eho operaˇcn´ıho syst´emu Mac OS X. Takˇrka nezbytn´ ym jazykem pouˇz´ıvan´ ym pro v´ yvoj je Objective C, nadstavba jazyka C, v nˇemˇz jsou implementov´ana napˇr´ıklad rozhran´ı pro programov´an´ı aplikac´ı Cocoa a Cocoa Touch. Ohraniˇc´ıme-li bloky k´odu psan´e v Objective C podmiˇ nuj´ıc´ımi 15
OpenGL ES a prostˇred´ı iOS
Xcode
makry, m˚ uˇzeme zdrojov´e soubory kompilovat pro jinou platformu jiˇz jako standardn´ı k´od v jazyce C. Existuje rovnˇeˇz jazyk Objective C++, kter´ y rozˇsiˇruje C++. Cocoa Touch API je objektov´ym rozhran´ım nab´ızej´ıc´ı ˇsirokou ˇsk´alu sluˇzeb (napˇr. spr´avu 3D grafiky, audia, s´ıt’ovou komunikaci) [1]. Architektura model-view-controller, kter´e se tento celek drˇz´ı, pˇrisp´ıv´a k ˇcitelnˇejˇs´ımu k´odu.
4.5
Xcode
Standardn´ım v´ yvojov´ ym prostˇred´ım pro iOS je Xcode. Tento komplexn´ı n´astroj umoˇzn ˇuje prov´adˇet prakticky vˇsechny ˇcinnosti spjat´e s v´ yvojem aplikac´ı – samozˇrejmost´ı je pˇreklad, debugging (monitorov´an´ı aplikace pro snazˇs´ı hled´an´ı chyb), ale i profilov´an´ı (mˇeˇren´ı v´ ykonu a efektivnosti) k´odu. Xcode se star´a i o sestaven´ı a nainstalov´an´ı aplikace do c´ılov´eho zaˇr´ızen´ı, kter´ym m˚ uˇze b´yt i simul´ator hardwaru, na kter´em bˇeˇz´ı iOS. Podobnˇe jako v dalˇs´ıch v´yvojov´ych prostˇred´ıch se zdrojov´e k´ody a jejich nastaven´ı sluˇcuj´ı do projekt˚ u, pˇriˇcemˇz program´ator pˇri vytv´aˇren´ı vyb´ır´a z pˇredem pˇripraven´ ych variant, kter´e pomohou odstranit nadbyteˇcn´a a st´ale se opakuj´ıc´ı nastavov´an´ı parametr˚ u pˇrekladu. Poloˇzky projektu mohou b´yt zpracov´any r˚ uznˇe. Podle nastaven´ı se s nimi zach´az´ı jako se zdrojov´ym k´odem, pak Xcode prov´ad´ı jejich pˇreklad, ale lze je nastavit tak´e jako datov´e soubory, kter´e se maj´ı po kompilaci zkop´ırovat do c´ılov´eho zaˇr´ızen´ı. Toho vyuˇzijeme pro jednoduch´e nasazen´ı projektu vˇcetnˇe soubor˚ u, na kter´ ych je z´avisl´ y (v pˇr´ıpadˇe grafick´eho programu se jedn´a napˇr´ıklad o shadery). Nasazovan´y bal´ıˇcek se v terminologii v´ yvoje pro iOS naz´ yv´a bundle.
4.6
GLKit
Pro usnadnˇen´ı programov´an´ı v OpenGL ES poskytuje Apple vlastn´ı rozˇsiˇruj´ıc´ı framework GLKit. Abychom jej mohli vyuˇz´ıt, c´ılov´e zaˇr´ızen´ı s iOS mus´ı podporovat OpenGL ES alespoˇ n ve verzi 2.0. Funkcionalita, kterou poskytuje, se d´a rozdˇelit do n´asleduj´ıc´ıch kategori´ı [3]:
16
OpenGL ES a prostˇred´ı iOS
GLKit
• Naˇ c´ıt´ an´ı textur z r˚ uzn´ ych zdroj˚ u. Kromˇe obvykl´eho synchronn´ıho chov´an´ı je k dispozici i asynchronn´ı naˇcten´ı. • Matematick´ a knihovna poskytuje bˇeˇzn´e optimalizovan´e operace s maticemi, vektory a quaterniony. • Efekty implementuj´ı z´akladn´ı sadu shader˚ u aplikovateln´ ych na renderovan´e vrcholy. • Komponenty Views a ViewControllers redukuj´ı potˇrebn´e mnoˇzstv´ı k´odu k naps´an´ı OpenGL ES aplikace, pˇriˇcemˇz View slouˇz´ı jako panel, do kter´eho prob´ıh´a rendering, ViewController pak ˇr´ıd´ı i jeho pr˚ ubˇeh.
Pro multiplatformn´ı vyuˇzit´ı vˇetˇsina uveden´ ych moˇznost´ı nem´a v´ yznam, nebot’ jsou pevnˇe sv´az´any s iOS, pˇr´ıpadnˇe Mac OS X. Komponenty GLKView nebo GLKViewController vˇsak mohou pˇri v´ yvoji pomoci pr´avˇe v platformnˇe z´avisl´ ych ˇc´astech k´odu, kdy kreslic´ı smyˇcku, velikost pohledu a dalˇs´ı ponech´ame k ˇreˇsen´ı frameworku m´ısto vlastn´ı implementace.
17
5 Architektura grafick´eho klienta V tuto chv´ıli se dost´av´ame k samotn´e realizaci grafick´eho klienta. Postupnˇe vystav´ıme aplikaci tak, aby byla snadno pˇrenositeln´a na v´ıce platforem a z´aroveˇ n rozˇsiˇriteln´a o dalˇs´ı funkˇcnost. Vyuˇzijeme podm´ınˇen´e kompilace jazyka C++, d´ıky kter´e snadno vol´ıme aktivn´ı ˇc´asti k´odu pomoc´ı maker prekompileru, pˇriˇcemˇz pr´avˇe tyto ˇca´sti mohou obsahovat (a pˇr´ıpadnˇe skr´ yt) platformnˇe z´avislou funkcionalitu. Jednou z cest pro udrˇzitelnost k´odu je vyuˇzit´ı vlastnost´ı objektovˇe orientovan´eho programov´an´ı (objekt˚ u, jejich dˇediˇcnosti a zapouzdˇren´ı) a pˇr´ısluˇsn´ ych n´avrhov´ ych vzor˚ u. J´adro enginu ˇr´ıd´ı pr˚ ubˇeh vykreslov´an´ı a star´a se o syst´emov´e u ´lohy s n´ım souvisej´ıc´ı. V naˇs´ı implementaci spravuje i grafick´e zdroje (buffery, textury apod.) a je d´ale rozˇsiˇriteln´e pomoc´ı virtu´aln´ıch ud´alostn´ıch metod. Pod´ıvejme se nyn´ı na techniky a tˇr´ıdy, kter´e dohromady engine tvoˇr´ı.
5.1
Platformn´ı nez´ avislost
Engine vyuˇz´ıv´a jednak knihovn´ı funkce jazyka (u kter´ ych mus´ıme zkontrolovat jejich pˇrenositelnost), ale i syst´emov´a vol´an´ı dan´eho operaˇcn´ıho syst´emu. Ta b´ yvaj´ı znaˇcnˇe odliˇsn´a, a proto bychom je mˇeli oddˇelit jiˇz v nejspodnˇejˇs´ı vrstvˇe enginu, abychom nad´ale pracovali v jednotn´em prostˇred´ı. V dobˇe psan´ı t´eto pr´ace jsme c´ılili na dvˇe platformy: Windows a iOS. Zp˚ usob˚ u, jak zajistit zprovoznˇen´ı libovoln´e aplikace na r˚ uzn´ ych zaˇr´ızen´ıch, se nab´ız´ı samozˇrejmˇe v´ıce. Prvn´ım, naivn´ım ˇreˇsen´ım, je v´yvoj pro prvn´ı platformu a n´asledn´y pˇrepis z´avisl´ych ˇca´st´ı pˇri portov´an´ı. Tento postup bychom mohli oˇcek´avat u jiˇz vyvinut´e aplikace, kter´a se definitivnˇe stˇehuje na nov´e zaˇr´ızen´ı. Jako nev´ yhoda se ukazuje rozdvojen´ı v´ yvoje, chceme-li st´ale podporovat p˚ uvodn´ı platformu. Druhou moˇznost´ı je vloˇzen´ı jiˇz zm´ınˇen´e pomocn´e vrstvy, kter´a sjednocuje v´ıce rozhran´ı operaˇcn´ıch syst´em˚ u. Tato vrstva m˚ uˇze b´ yt bud’to staticky linkovanou knihovnou rozd´ılnou pro kaˇzdou platformu, nebo se vyskytuje pˇr´ımo v k´odu. V jazyce C++ jsou pak tyto ˇc´asti realizov´any pomoc´ı maker (viz uk´azka 5.1 – implementace metody mutexu). 18
Architektura grafick´eho klienta
Spoleˇcn´y pˇredek Generic
Jedn´a-li se o rozs´ahl´e tˇr´ıdy nebo jejich skupinu, pˇrich´az´ı v u ´vahu i vyˇclenˇen´ı cel´eho zdrojov´eho souboru z kompilace. To zrealizujeme snadno zmˇenou makefile nebo nastaven´ım projektu v pouˇz´ıvan´em IDE. Pˇri objektov´em pˇr´ıstupu m˚ uˇzeme rovnˇeˇz vytvoˇrit spoleˇcn´eho abstraktn´ıho pˇredka, kter´ y slouˇz´ı jako ˇsablona pro konkr´etn´ı implementace. 1
#i f d e f i n e d (
2
IPHONE 5 0 )
p t h r e a d m u t e x u n l o c k (&mutex POSIX ) ;
3
# e l i f d e f i n e d ( WINxx )
4
ReleaseMutex ( mutex WIN ) ;
5
#e n d i f
Listing 5.1: Uk´azka multiplatformn´ıho k´odu
5.2
Spoleˇ cn´ y pˇ redek Generic
Pro tˇr´ıdy enginu navrhneme spoleˇcn´eho pˇredka, abychom mohli pˇr´ıpadnˇe rozˇs´ıˇrit vˇsechny najednou pouze trivi´aln´ı u ´pravou v nˇem samotn´em. To ale nen´ı zdaleka jedin´y u ´ˇcel tˇr´ıdy Generic. S jej´ı pomoc´ı m˚ uˇzeme program´atora donutit, aby se drˇzel n´ami definovan´eho n´avrhov´eho vzoru. Generic stav´ı na koncepci vlastnictv´ı – kaˇzd´y objekt (kromˇe koˇrenov´eho) m´a povinnˇe sv´eho vlastn´ıka, kter´y je povinn´ym parametrem konstruktoru. Vznik´a hierarchie (strom), ve kter´e ˇz´adn´y prvek nesm´ı zaniknout pˇred objektem, kter´y vlastn´ı (objekty jsou tedy maz´any od list˚ u smˇerem zpˇet ke koˇrenu). Objekty si ve vˇetˇsinˇe pˇr´ıpad˚ u ukl´adaj´ı pouze ukazatel na sv´eho vlastn´ıka, ukazatele na vlastnˇen´e uchov´av´ame jen pro specifick´e u ´ˇcely (bude rozebr´ano pozdˇeji u objekt˚ u, kter´ ych se tato vlastnost t´ yk´a). Ve vznikl´e hierarchii je moˇzn´e celkem jednoduˇse zas´ılat zpr´avy pˇres vlastn´ıky aˇz ke koˇrenu. Generic obsahuje dvˇe metody, kter´e tuto funkcionalitu zajiˇst’uj´ı: ProcessMessage a virtu´aln´ı ProcessMessageEx. ProcessMessage m´a jeden povinn´y parametr (identifikaˇcn´ı ˇc´ıslo zpr´avy) a tˇri nepovinn´e (pˇr´ıdavn´e informace). Pokud v dan´em objektu nen´ı zpr´ava rozpozn´ana, je pˇred´ana sv´emu vlastn´ıkovi. Rozpozn´an´ı a zpracov´an´ı zpr´av implementujeme v potomc´ıch pr´avˇe uvnitˇr virtu´aln´ı metody ProcessMessageEx. Zas´ıl´an´ı zpr´av je jedn´ım z ˇcasto vyuˇz´ıvan´ ych prvk˚ u enginu – 19
Architektura grafick´eho klienta
Syst´emov´e a ˇr´ıdic´ı tˇr´ıdy
v´ yhodou (navzdory m´ırn´e reˇzii, kter´a ho prov´az´ı) z˚ ust´av´a, ˇze nam´ısto pˇred´av´an´ı mnoha promˇenn´ ych vznikaj´ıc´ımu objektu si o nˇe zaˇza´d´a s´am. Spoleˇcn´y pˇredek Generic nen´ı vyuˇz´ıv´an u trivi´aln´ıch objekt˚ u, kter´e by pomocnou funkcionalitu nevyuˇzily a mˇely by znaˇcn´ y vliv na v´ ykon enginu (napˇr. u matic a mutex˚ u).
5.3
Syst´ emov´ eaˇ r´ıdic´ı tˇ r´ıdy
Tˇr´ıdy Context, Frame zajiˇst’uj´ı spr´avu syst´emov´ ych zdroj˚ u – kontextu OpenGL a oblasti vykreslov´an´ı, coˇz v pˇr´ıpadˇe Windows znamen´a okno, pro iOS pak komponentu GUI roztaˇzenou na celou plochu displeje. Zastˇreˇsuj´ı tedy platformnˇe specifick´a nastaven´ı objektem spoleˇcn´ ym navenek. Context je pevnˇe vlastnˇen objektem typu Frame. Implementace vytvoˇren´ı kontextu OpenGL je rozdˇelena pro kaˇzdou platformu zvl´aˇst’ (CreateContextWindows a CreateContextIOS), kompiluje se opˇet jen blok k´odu pˇr´ısluˇs´ıc´ı c´ılov´e platformˇe. To sam´e plat´ı i pro metody staraj´ıc´ı se o uvolnˇen´ı. Zat´ımco na platformˇe iOS ˇreˇs´ı tˇr´ıda Context sp´ıˇse propojen´ı enginu s frameworkem GLKit, ve Windows odpov´ıd´a pˇr´ımo za spr´avu zdroj˚ u t´ ykaj´ıc´ıch se kontektu. Program´atorovi je tak k dispozici i vol´an´ı SwapBuffers, kter´a na platformˇe Windows zajiˇst’uje manu´aln´ı z´amˇenu back a front bufferu. O spr´avu okna (v podobˇe pˇr´ısluˇs´ıc´ı zvolen´e platformˇe) se star´a abstraktn´ı tˇr´ıda Frame. Zde byl platformnˇe z´avisl´ y k´od pro lepˇs´ı ˇcitelnost pˇresunut do potomk˚ u WindowsFrame a IOSFrame, nebot’ kromˇe funkc´ı ˇci metod, kter´e jsou vol´any, se liˇs´ı i celkov´e pojet´ı. Opˇet plat´ı, ˇze ve Windows ˇr´ıd´ı a spravuje objekt vˇsechny zdroje v k´odu s´am, ale v iOS figuruje jako prostˇredn´ık mezi enginem a Cocoa Touch API. Pro ovl´ad´an´ı pr˚ ubˇehu vykreslov´an´ı vznikla tˇr´ıda FrameControl, pˇriˇcemˇz jej´ım vlastn´ıkem je pˇr´ımo objekt typu Frame. Ten pak vol´a ud´alostn´ı metody FrameControl, mezi nˇeˇz patˇr´ı: • OnInit – metoda, kter´a je vol´ana pˇred prvn´ım vykreslen´ım, • OnRelease – metoda volan´a pˇri uvolˇ nov´an´ı instance Frame, 20
Architektura grafick´eho klienta
Grafick´e zdroje
Context
FrameControl + OnInit() + OnRelease() + OnDraw()
Frame
Obr´azek 5.2: Diagram vlastnictv´ı tˇr´ıd. • OnDraw – metoda volan´a na zaˇca´tku kaˇzd´eho sn´ımku. Instance Frame z´ısk´a ukazatel na zvolen´y FrameControl pomoc´ı zpr´avy s identifikac´ı MESSAGE_SET_FRAME_CONTROL, kter´a je zasl´ana v jeho konstruktoru (uspoˇra´d´an´ı tˇr´ıd viz obr´azek 5.2). Dˇedˇen´ım tˇr´ıdy m˚ uˇzeme pˇrekr´ yt nebo rozˇs´ıˇrit ud´alostn´ı metody a vytvoˇrit tak nov´ y pr˚ ubˇeh kreslen´ı sn´ımku.
5.4
Grafick´ e zdroje
Pˇresuˇ nme se k tˇr´ıd´am vyˇsˇs´ı u ´rovnˇe, kter´e obal´ı API OpenGL a OpenGL ES a skryj´ı tak drobn´e implementaˇcn´ı rozd´ıly. Pro rendering mus´ıme spravovat techniku kreslen´ı (vyuˇz´ıv´ame vertex a fragment shader), troj´ uheln´ıkov´e meshe (vertex array, element array) a materi´al na nˇe aplikovan´ y (textura).
5.4.1
Technika kreslen´ı
OpenGL ES 2.0 vyˇzaduje definici vertex a fragment programu pouˇzit´ ych pˇr´ımo uvnitˇr renderovac´ı pipeline. Programovateln´e prvky jsou sdruˇzeny uvnitˇr tˇr´ıdy Technique (vztah mezi pipeline a tˇr´ıdou zn´azornˇen na obr´azku 5.3), kter´a poskytuje i nˇekolik pomocn´ ych metod, z nichˇz n´as nejv´ıce zaj´ımaj´ı tˇri veˇrejn´e. Metoda Load naˇcte z dan´ ych um´ıstˇen´ı textov´e soubory obsahuj´ıc´ı zdrojov´ y k´od v jazyce GLSL, 21
Architektura grafick´eho klienta
Grafick´e zdroje
provede kompilaci, linking a v pˇr´ıpadˇe chyby (lad´ıme-li program) vyp´ıˇse log pˇrekladu do konzole. Apply aktivuje program uloˇzen´y uvnitˇr dan´e instance. Pokud z nˇejak´ych d˚ uvod˚ u potˇrebujeme pˇristoupit ke grafick´emu programu pˇr´ımo, k dispozici je i getter GetProgramId vracej´ıc´ı jeho identifik´ator. Technique
OpenGL ES 2.0 Pipeline vertex processing
vertex program
rasterization fragment processing pixel processing
fragment program
output
Obr´azek 5.3: Vztah mezi tˇr´ıdou Technique a pipeline OpenGL ES. Pro pˇreklad techniky slouˇz´ı priv´atn´ı metody CompileShader a LinkProgram. CompileShader je univerz´aln´ı pro vertex i fragment shader, coˇz odpov´ıd´a rozhran´ı OpenGL, kde se mezi nimi rozliˇsuje pouze pomoc´ı pˇr´ıznaku, kter´ y pˇred´ame funkci glCreateShader. LinkProgram se pak star´a o jejich propojen´ı ve v´ ysledn´ y grafick´ y program.
5.4.2
Troj´ uheln´ıkov´ e meshe
Po implementaci zp˚ usobu kreslen´ı se zamˇeˇr´ıme na obsah – troj´ uheln´ıkov´e meshe, tedy objekty sloˇzen´e z troj´ uheln´ık˚ u. Za t´ımto u ´ˇcelem existuje v enginu tˇr´ıda Mesh, kter´a spravuje potˇrebn´e objekty OpenGL API: vertex buffer a element array buffer. Zat´ımco ve vertex bufferu jsou uloˇzeny vˇsechny vrcholy objektu, element array buffer obsahuje informace o jejich pouˇzit´ı v troj´ uheln´ıc´ıch – jeden vrchol m˚ uˇze b´ yt vyuˇzit pro v´ıce ploch. O naplnˇen´ı buffer˚ u se star´a veˇrejnˇe pˇr´ıstupn´a metoda Load, kter´a si za parametry bere poˇcet vrchol˚ u a odkazuj´ıc´ıch index˚ u tvoˇr´ıc´ıch troj´ uheln´ıky a d´ale pole samotn´ych vrchol˚ u a index˚ u. Vrchol definujeme pozic´ı, norm´alov´ ym vektorem a texturovac´ımi souˇradnicemi. Pro testovac´ı u ´ˇcely je vhodn´e m´ıt moˇznost snadno vytvoˇrit r˚ uzn´e generovan´e objekty, a proto byly naimplementov´any i statick´e metody CreateCube (vytvoˇren´ı meshe krychle) a CreateCylinder (vytvoˇren´ı meshe v´alce). Zp˚ usob jejich 22
Architektura grafick´eho klienta
Grafick´e zdroje
fungov´an´ı je jednoduch´y: uvnitˇr vytvoˇr´ıme novou instanci tˇr´ıdy Mesh, vygenerujeme pro ni pole vrchol˚ u a index˚ u, kter´a pˇred´ame metodˇe Load, a vzniklou instanci vr´at´ıme jako v´ ysledek. Na troj´ uheln´ıkov´e meshe m´ame moˇznost i aplikovat materi´al. Ten definuje chov´an´ı pro jednotliv´e sloˇzky osvˇetlen´ı (ambient, diffuse, specular). Kaˇzd´a sloˇzka je reprezentov´ana hodnotami (r, g, b, a) v rozsahu od nuly do jedn´e. To umoˇzn ˇuje mˇenit barvu objektu pouze v glob´aln´ım mˇeˇr´ıtku, proto byla pˇrid´ana i moˇznost mapov´an´ı textury. Vykreslen´ı meshe provedeme vol´an´ım Draw. Tato metoda nikterak nezasahuje do techniky kreslen´ı, pouze pˇripoj´ı texturu materi´alu, je-li pˇr´ıtomna, a zavol´a funkci OpenGL API glDrawElements. V pˇr´ıpadˇe, ˇze mesh nen´ı inicializov´an, neprov´ad´ı metoda nic.
5.4.3
Textury
Textura pˇredstavuje bitmapu mapovanou na povrch objektu. Ten pak p˚ usob´ı detailnˇeji bez potˇreby zvyˇsov´an´ı poˇctu vrchol˚ u nebo jeho dˇelen´ı na v´ıce objekt˚ u s r˚ uzn´ ymi materi´alov´ ymi vlastnostmi. Tˇr´ıda Texture obaluje funkce OpenGL a OpenGL ES potˇrebn´e pr´avˇe pro manipulaci s texturami. Tˇr´ıda je pojata skuteˇcnˇe minimalisticky, poskytuje pouze metodu pro naˇcten´ı (Load), uvolnˇen´ı (Release), pˇripojen´ı (Bind) a odpojen´ı (statick´a metoda Unbind) textury. Pˇri vol´an´ı Load zad´av´ame rozmˇery, form´at, typ filtrov´an´ı a samotn´a data textury. OpenGL ES nepodporuje konverzi mezi datov´ ymi form´aty, proto ani tato tˇr´ıda neumoˇzn ˇuje zadat c´ılov´ y form´at textury na grafick´e kartˇe, pouˇzije se zkr´atka form´at zdrojov´ ych dat. Metoda Release uvolˇ nuje pouze objekty rozhran´ı OpenGL, samotn´a instance uvolnˇena nen´ı. Pro testov´an´ı vznikla statick´a metoda CreateCheckerboard, kter´a vytvoˇr´ı novou instanci tˇr´ıdy a vygeneruje ˇcernob´ıl´y ˇsachovnicov´y vzor do ˇctvercov´e textury zadan´eho rozmˇeru. Tuto instanci pak z´ısk´ame jako n´avratovou hodnotu.
23
Architektura grafick´eho klienta
5.5
Tˇr´ıdy obsluhuj´ıc´ı sc´enu
Tˇ r´ıdy obsluhuj´ıc´ı sc´ enu
Shrneme-li pˇredchoz´ı u ´sil´ı, m´ame pˇripravenou komunikaci se syst´emem, kontrolu kreslen´ı sn´ımku a r˚ uzn´e grafick´e zdroje. Tyto objekty enginu jsou (z velk´e ˇca´sti) na sobˇe nez´avisl´e, a proto pˇrich´az´ı chv´ıle, kdy je logicky propoj´ıme tˇr´ıdou, kter´a prov´ad´ı rendering cel´e sc´eny a uchov´av´a k tomu u ´ˇcelu potˇrebn´a data. ´loh SceneControl je potomkem tˇr´ıdy FrameControl, pˇriˇcemˇz m´a na starost v´ıce u – slouˇz´ı jako datab´aze grafick´ych objekt˚ u i jako v´ykonn´y prvek pro jejich rendering. Z toho d˚ uvodu byly rozˇs´ıˇreny ud´alostn´ı metody OnInit, OnRelease a OnDraw, kter´e v pˇredkovi neobsahuj´ı ˇz´adn´ y v´ ykonn´ y k´od. Kromˇe primitivn´ıch objekt˚ u, jako jsou techniky kreslen´ı ˇci nastaven´a barva pozad´ı, obsahuje tˇr´ıda mnoˇzinu grafick´ych zdroj˚ u, kdy kaˇzd´y z nich je identifikov´an unik´atn´ım ˇretˇezcem. K naˇsemu u ´ˇcelu jsme zvolili samovyvaˇzovac´ı bin´arn´ı strom, konkr´etnˇe jeho implementaci ve standardn´ı knihovnˇe jazyka C++: tˇr´ıdu std::map. V tˇechto struktur´ach ukl´ad´ame meshe, textury, ale i uzly sc´eny. Instance tˇr´ıdy SceneNode odpov´ıd´a jednomu uzlu grafu sc´eny. Tento uzel, jak jiˇz bylo pops´ano na str. 7, obsahuje svoji transformaˇcn´ı matici a je ovlivnˇen transformacemi nadˇrazen´ ych uzl˚ u. Hierarchie je zrealizov´ana opˇet pomoc´ı vlastnictv´ı, objekt nicm´enˇe po sv´em vytvoˇren´ı zas´ıl´a jeˇstˇe zpr´avu pro sv´e zaregistrov´an´ı ve vlastn´ıkovi, jinak bychom vznikl´ y graf nebyli schopni proch´azet (existovaly by pouze hrany ve smˇeru ke koˇrenu). Kaˇzd´a instance si tedy ukl´ad´a opˇet mnoˇzinu podˇr´ızen´ ych uzl˚ u, kter´e vlastn´ı. Vykreslen´ı cel´eho podstromu od zvolen´eho uzlu pak provedeme pomoc´ı metody Draw, pˇriˇcemˇz koˇren je uloˇzen v instanci SceneControl. Kaˇzd´emu uzlu m˚ uˇzeme pˇriˇradit mesh, kter´ y se pak bude kreslit ovlivnˇen´ y pˇr´ısluˇsn´ ymi transformacemi. Jeden mesh m˚ uˇze b´ yt pˇriˇrazen v´ıce uzl˚ um sc´eny (opaˇcnˇe nikoliv) vol´an´ım metody SetMesh, kter´a jako parametr vyˇzaduje ˇretˇezec, pod n´ımˇz je uloˇzen uvnitˇr instance tˇr´ıdy SceneControl. Zad´ame-li pr´azdn´y ˇretˇezec ˇci neexistuj´ıc´ı n´azev, pouze odstran´ıme odkaz. Vyhled´an´ı meshe je zaloˇzeno na vysl´an´ı zpr´avy, kterou vyhodnot´ı SceneControl, nalezne odpov´ıdaj´ıc´ı z´aznam a vr´at´ı ukazatel zpˇet odes´ılateli zpr´avy. Obecn´e vztahy mezi tˇr´ıdami viz obr´azek 5.4. Pˇri pr˚ uchodu grafem sc´eny mus´ıme udrˇzovat stav aktu´aln´ıch transformac´ı a dalˇs´ı u ´daje pro rendering. Zat´ımco v OpenGL ES 1.0 jsme mohli tuto ˇcinnost pˇrenechat 24
Architektura grafick´eho klienta
Tˇr´ıdy obsluhuj´ıc´ı sc´enu
0..N
SceneNode
Mesh 0..N
1
SceneControl
Obr´azek 5.4: Tˇr´ıdy SceneControl, SceneNode a Mesh. funkc´ım rozhran´ı (glTranslate, glPushMatrix atd.), verze 2.0 ˇz´adn´e obdobn´e nenab´ız´ı, a tak vznikla tˇr´ıda InstanceParams, kter´a je urˇcit´ym zp˚ usobem napodobuje. Tˇr´ıda obsahuje zaprv´e st´al´e hodnoty, kter´e se t´ykaj´ı cel´eho renderingu (napˇr. adresy promˇenn´ych shader˚ u) – tedy v pˇr´ıpadˇe, ˇze pouˇz´ıv´ame st´ale stejnou techniku kreslen´ı. Zadruh´e zde nach´az´ıme z´asobn´ık transformaˇcn´ıch matic pouˇz´ıvan´y metodami Push a Pop a aktu´aln´ı (akumuluj´ıc´ı se) transformace. Aˇckoliv jsme nyn´ı jiˇz schopni renderovat celou sc´enu, rozˇs´ıˇr´ıme engine jeˇstˇe o jednu tˇr´ıdu, kter´a pˇredstavuje kameru. Tˇr´ıda Camera uchov´av´a svoji projekˇcn´ı matici, pˇriˇcemˇz jej´ım vlastn´ıkem je vybran´ y uzel sc´eny, kter´ y tak urˇcuje jej´ı pozici a orientaci. Vztah pro nalezen´ı matice pohledu jiˇz byl rozebr´an na str. 7, nyn´ı potˇrebujeme jen z´ıskat vˇsechny transformaˇcn´ı matice uzl˚ u leˇz´ıc´ıch na cestˇe od koˇrenu sc´eny k dan´e kameˇre. Opˇet vyuˇzijeme mechanismu zas´ıl´an´ı zpr´av, kdy kaˇzd´ y uzel zap´ıˇse do bufferu svoji transformaci a pˇred´a tut´eˇz zpr´avu sv´emu vlastn´ıkovi. Teprve tˇr´ıda SceneNode oznaˇc´ı zpr´avu jako vyˇreˇsenou a odes´ılatel (kamera) pˇrevezme buffer s transformacemi.
25
6 Rozhran´ı grafick´eho klienta Tˇr´ıda SceneControl se v tuto chv´ıli stala autonomnˇe funkˇcn´ım celkem, kter´ y sice ˇr´ıd´ı pr˚ ubˇeh vykreslov´an´ı sc´eny a star´a se o pˇr´ısluˇsn´e uloˇzen´e zdroje, nicm´enˇe neexistuje prozat´ım ˇza´dn´ y komunikaˇcn´ı kan´al, kter´ y by proces mohl zvenˇc´ı ovlivnit. Dopln´ıme tedy tˇr´ıdu o metody, kter´e poskytnou dohromady rozhran´ı ovl´adaj´ıc´ı sc´enu. Pˇredpokl´ad´ame, ˇze jsou bud’ vol´any z vl´akna, ve kter´em byl vytvoˇren kontext OpenGL, nebo z vl´akna, jemuˇz je kontext nasd´ılen. V takov´em pˇr´ıpadˇe oˇsetˇrujeme pˇr´ıstup ke sd´ılen´ ym promˇenn´ ym pomoc´ı mutex˚ u.
6.1
Meshe a textury
Grafick´ ymi zdroji, kter´e spravujeme skrze rozhran´ı sc´eny, jsou meshe a textury, pˇriˇcemˇz plat´ı, ˇze textury lze pˇriˇradit materi´al˚ um v´ıce mesh˚ u. Techniky kreslen´ı (jako zdroj) zpˇr´ıstupnˇeny nebyly, engine je pouˇz´ıv´a pouze vnitˇrnˇe. Uloˇzen´ı meshe ˇci textury prov´ad´ıme pomoc´ı operace SetMesh a SetTexture. Prvn´ım parametrem je jedineˇcn´ y ˇretˇezcov´ y identifik´ator objektu (jmenn´ y prostor textur a mesh˚ u nen´ı sd´ılen), druh´ ym pak ukazatel na jiˇz vytvoˇrenou instanci grafick´eho zdroje. Pˇri operaci je pˇrevzato vlastnictv´ı objektu a tˇr´ıda SceneControl tak zodpov´ıd´a za jeho uvolnˇen´ı. Nulov´y ukazatel (NULL) je ch´ap´an jako ˇza´dost o manu´aln´ı uvolnˇen´ı pˇr´ısluˇsn´eho uloˇzen´eho objektu. ˇ ı prov´ad´ıme analogicky k z´apisu metodami GetMesh a GetTexture. Opˇet jako Cten´ parametr pˇred´av´ame identifikuj´ıc´ı ˇretˇezec a instanci hledan´eho objektu z´ısk´ame jako n´avratovou hodnotu. Nen´ı-li pod zadan´ ym jm´enem uloˇzen ˇza´dn´ y zdroj, je vr´acena hodnota NULL.
6.2
Uzly sc´ eny a kamery
Manipulace s uzly sc´eny je ponˇekud odliˇsn´a. Jelikoˇz uzel jiˇz ve sv´em konstruktoru zas´ıl´a sv´emu vlastn´ıkovi zpr´avu se ˇz´adost´ı o registraci, nen´ı potˇrebn´e posky-
26
Rozhran´ı grafick´eho klienta
Ostatn´ı operace rozhran´ı
tovat operaci set, ale pr´avˇe vyhled´an´ı onoho vlastn´ıka. K tomu slouˇz´ı metody FindRootSceneNode a FindSceneNode. Prvn´ı zm´ınˇen´a vr´at´ı ukazatel na koˇrenov´ y uzel sc´eny, kter´ y doporuˇcujeme nemodifikovat – mˇel by slouˇzit pouze jako nemˇenn´ y vlastn´ık podˇr´ızen´ ych uzl˚ u. FindSceneNode poskytne ukazatel na uzel sc´eny odpov´ıdaj´ıc´ı pˇredan´emu identifikuj´ıc´ımu n´azvu, a pokud nen´ı nalezen, n´avratovou hodnotou je NULL. Vytvoˇren´ı uzlu sc´eny pak spoˇc´ıv´a ve vol´an´ı konstruktoru tˇr´ıdy SceneNode, kdy jako vlastn´ıka objektu pˇred´av´ame vybran´y nadˇrazen´y uzel sc´eny. Konstruktor m´a vˇsak jeˇstˇe druh´y povinn´y parametr, a to jm´eno vytvoˇren´eho uzlu. Odstranˇen´ı provedeme vol´an´ım delete, pˇriˇcemˇz mechanismus zpr´av zajist´ı zruˇsen´ı registrace v nadˇrazen´em uzlu a spr´avci sc´eny. Kamery vytv´aˇr´ıme opˇet pomoc´ı jejich konstruktoru, jako vlastn´ıka vol´ıme vybran´y uzel sc´eny, jehoˇz transformace ovlivˇ nuje matici pohledu. Kamery jako takov´e nenesou informaci o sv´em jm´enˇe, a proto tˇr´ıda SceneControl poskytuje metody SetCamera a GetCamera, kdy pˇr´ısluˇsn´emu ˇretˇezci pˇr´ıˇrad´ıme ukazatel na danou kameru (odpov´ıd´a jiˇz zm´ınˇen´e logice uchov´av´an´ı mesh˚ u a textur). Mezi kamerami pˇrep´ın´ame operac´ı SetActiveCamera, i tentokr´at pˇred´av´ame identifikaˇcn´ı ˇretˇezec. Chceme-li zjistit, kter´a kamera je moment´alnˇe pouˇz´ıv´ana pro rendering, pouˇzijeme metodu GetActiveCamera.
6.3
Ostatn´ı operace rozhran´ı
S pomoc´ı rozhran´ı lze nastavit barvu pozad´ı. To provedeme vol´an´ım metody SetBackground, jej´ıˇz paremetry jsou sloˇzky RGBA v rozsahu od nuly do jedn´e. M˚ uˇzeme rovnˇeˇz vyhledat nepouˇzit´e meshe metodou FindUnusedMeshes, pˇr´ıpadnˇe je rovnou odstranit pomoc´ı DeleteAllUnusedMeshes. Poskytov´an je rovnˇeˇz picking objekt˚ u ve sc´enˇe. Zavol´ame metodu Pick, jako parametry pˇred´ame souˇradnice kurzoru v rozsahu odpov´ıdaj´ıc´ımu rozliˇsen´ı displeje a referenci na ˇretˇezec, do kter´eho chceme uloˇzit jm´eno vybran´eho uzlu sc´eny. Pokud probˇehl picking u ´spˇeˇsnˇe (naˇsli jsme objekt pod kurzorem), metoda vrac´ı booleovskou hodnotu true a dod´a n´azev vybran´eho uzlu. Picking byl implementov´an metodou
27
Rozhran´ı grafick´eho klienta
Ostatn´ı operace rozhran´ı
k´odov´an´ı objekt˚ u sc´eny r˚ uznou barvou a n´asledn´ ym ˇcten´ım pixelu z framebufferu (popis techniky viz kapitola 3.4.2). Pokud bychom vyv´ıjeli klienta nad OpenGL ES 3.0, kter´y podporuje rendering do v´ıce framebuffer˚ u z´aroveˇ n, mohli bychom picking d´ale optimalizovat. Spolu s vykreslen´ım sc´eny na obrazovku by se z´aroveˇ n do druh´eho pˇripojen´eho framebufferu zaznamenaly identifikaˇcn´ı barvy objekt˚ u, a tak by metoda Pick prov´adˇela uˇz jen zpˇetn´e ˇcten´ı a identifikaci. V pˇr´ıpadˇe OpenGL ES 2.0 nezb´yv´a neˇz sc´enu renderovat ve dvou pr˚ uchodech.
28
7 Uk´azkov´y protokol pro ovl´ad´an´ı klienta Samotn´e rozhran´ı pro manipulaci s objekty vyskytuj´ımi se ve sc´enˇe pokryje pouze pˇr´ım´a vol´an´ı z aplikace, kter´a engine pˇr´ımo vyuˇz´ıv´a (ten je k n´ı staticky ˇci dynamicky pˇripojen jako knihovna). Zavedeme-li textov´y protokol, kter´y je n´aslednˇe pˇreloˇzen aplikac´ı na odpov´ıdaj´ıc´ı vol´an´ı metody enginu, z´ısk´ame moˇznost ovl´adat sc´enu napˇr´ıklad vstupem ze souboru, interaktivnˇe psan´ım pˇr´ıkaz˚ u do konzole nebo pˇrij´ım´an´ım zpr´av pˇres s´ıt’.
7.1
Pˇ r´ıkazy protokolu
V dobˇe psan´ı t´eto pr´ace nebyla d´ana pˇresn´a forma protokolu, kter´ y by mˇel b´ yt klientem vyuˇzit. Z tohoto d˚ uvodu jsem pˇrikroˇcil k navrˇzen´ı vlastn´ıho jednoduch´eho protokolu, kter´y dostateˇcnˇe demonstruje ovl´ad´an´ı prvk˚ u sc´eny. Zvolil jsem imperativn´ı paradigma (protokol se skl´ad´a z pˇr´ıkaz˚ u). Vˇsechny objekty jsou identifikov´any na z´akladˇe sv´eho jednoznaˇcn´eho jm´ena (ˇretˇezce znak˚ u). N´asleduje vysvˇetlen´ı jednotliv´ych pˇr´ıkaz˚ u protokolu, hranat´e z´avorky znaˇc´ı promˇennou, kulat´e z´avorky nepovinnou ˇca´st pˇr´ıkazu, svisl´a ˇc´ara v´ybˇer z nˇekolika moˇznost´ı. Pˇr´ıkazy jsou ukonˇceny stˇredn´ıkem a mohou pokraˇcovat pˇres v´ıce ˇra´dek, na jednom se jich vˇsak nesm´ı nach´azet v´ıce neˇz jeden.
7.1.1
Spr´ ava mesh˚ u
N´ıˇze popsan´e pˇr´ıkazy zach´azej´ı s troj´ uheln´ıkov´ymi modely (meshes), kter´e slouˇz´ı jako zdroje pro kreslen´ı v uzlech sc´eny. mesh [name] generate cube [a]; Vygenerov´an´ı krychle o d´elce hrany a a jej´ı uloˇzen´ı pod n´azvem name. mesh [name] generate cylinder [r] [h]; Vygenerov´an´ı v´alce o polomˇeru r, v´ yˇsce h a jeho uloˇzen´ı pod n´azvem name. 29
Uk´azkov´y protokol pro ovl´ad´an´ı klienta
Pˇr´ıkazy protokolu
mesh [name] load [data]; Naˇcten´ı troj´ uheln´ıkov´eho meshe a jeho uloˇzen´ı pod n´azvem name, promˇenn´a data pˇredstavuje pole vrchol˚ u zapsan´ ych postupnˇe jako souˇradnice vrchol˚ u a norm´al. mesh [name] material ambient|diffuse|specular [r] [g] [b] [a]; Nastaven´ı vybran´e sloˇzky materi´alu meshe name na barvu (r, g, b, a). mesh [name] delete; Odstranˇen´ı meshe name.
7.1.2
Spr´ ava uzl˚ u sc´ eny
Pˇr´ıkazy spravuj´ıc´ı uzly sc´eny zaˇrizuj´ı um´ıstˇen´ı instanc´ı mesh˚ u ve sc´enˇe, zmˇenu jejich transformace nebo jejich odstranˇen´ı. node [name] create ([parent]); Vytvoˇren´ı uzlu sc´eny a jeho uloˇzen´ı pod n´azvem name. Nepovinn´ y ˇretˇezec parent urˇcuje n´azev nadˇrazen´eho uzlu, nen´ı-li pˇr´ıtomen, nadˇrazen´ym se st´av´a koˇren hierarchie sc´eny. node [name] mesh [meshname]; Pˇriˇrazen´ı meshe uloˇzen´eho pod n´azvem meshname uzlu sc´eny name. node [name] identity; Nastaven´ı implicitn´ı (jednotkov´e) transformaˇcn´ı matice uzlu name. node [name] multmatrix [a11] [a12] [a13] [a14] [a21] [a22] [a23] [a24] [a31] [a32] [a33] [a24] [a41] [a42] [a43] [a44]; N´asoben´ı transformaˇcn´ı matice uzlu name zadanou matic´ı ˇc´ısel a11 . . . a44 .
30
Uk´azkov´y protokol pro ovl´ad´an´ı klienta
Pˇr´ıkazy protokolu
node [name] translate [x] [y] [z]; N´asoben´ı transformaˇcn´ı matice uzlu name matic´ı translace definovanou vektorem (x, y, z). node [name] rotate x|y|z [angle]; N´asoben´ı transformaˇcn´ı matice uzlu name matic´ı rotace definovanou osou a u ´hlem otoˇcen´ı angle zadan´em ve stupn´ıch. node [name] scale [x] [y] [z]; N´asoben´ı transformaˇcn´ı matice uzlu name matic´ı ˇsk´alov´an´ı definovanou vektorem (x, y, z). node [name] delete; Odstranˇen´ı uzlu sc´eny uloˇzen´eho pod n´azvem name.
7.1.3
Spr´ ava kamery
Popiˇsme nyn´ı pˇr´ıkazy zach´azej´ıc´ı s kamerami. Na rozd´ıl od implementovan´eho rozhran´ı pro manipulaci se sc´enou nebyly do protokolu zaˇrazeny vˇsechny operace (napˇr. nastaven´ı projekˇcn´ı matice kamery), nebot’ slouˇz´ı pouze pro z´akladn´ı demonstraˇcn´ı u ´ˇcely. camera [name] create [nodename]; Vytvoˇren´ı kamery a jej´ı um´ıstˇen´ı do uzlu nazvan´eho nodename, n´aslednˇe je uloˇzena pod jm´enem name. camera [name] activate; Aktivov´an´ı kamery nazvan´e name a jej´ı n´asledovn´e pouˇz´ıv´an´ı pro rendering sc´eny. camera [name] delete; Smaz´an´ı kamery nazvan´e name, byla-li aktivn´ı, engine pˇrep´ın´a na defaultn´ı kameru.
31
Uk´azkov´y protokol pro ovl´ad´an´ı klienta
7.1.4
Interpretuj´ıc´ı tˇr´ıda
D´ avka pˇ r´ıkaz˚ u
D´avka pˇr´ıkaz˚ u slouˇz´ı k jejich naˇcten´ı ze souboru a n´asledn´emu proveden´ı. Uˇzivatel si je tak m˚ uˇze opˇetovnˇe vyvolat pˇri libovoln´em bˇehu programu bez nutnosti ps´at cel´y skript znovu, coˇz lze vyuˇz´ıt napˇr´ıklad pro naˇc´ıt´an´ı mesh˚ u z rozs´ahl´ych soubor˚ u (samozˇrejmˇe obsahem dodrˇzuj´ıc´ı definovan´ y protokol). batch [filename]; Spuˇstˇen´ı skriptu ze souboru nazvan´eho filename, jm´eno nesm´ı obsahovat b´ıl´e znaky. Vnoˇren´e vol´an´ı skript˚ u je povoleno, avˇsak nekoneˇcn´a rekurze nen´ı oˇsetˇrena.
7.2
Interpretuj´ıc´ı tˇ r´ıda
V klientsk´e aplikaci pˇreklad protokolu na vol´an´ı metod rozhran´ı sc´eny prov´ad´ı tˇr´ıda DemoProtocolHandler. Poskytuje navenek pouze konstruktor a veˇrejnou metodu Command. V konstruktoru se instance propoj´ı s rozhran´ım sc´eny (SceneControl) a inicializuje promˇenn´e instance. Metodu Command vol´ame s parametrem cmd, coˇz je klasick´ y ˇretˇezec terminovan´ y nulov´ ym znakem. Nazpˇet z´ısk´ame ukazatel na ˇretˇezec obsahuj´ıc´ı chybovou hl´aˇsku, kter´ y je nulov´ y v pˇr´ıpadˇe, ˇze pˇr´ıkaz probˇehl v poˇra´dku. Pˇr´ıkaz je parsov´an uvnitˇr objektu za pomoci standardn´ı knihovny jazyka C, na z´akladˇe prvn´ıho pˇreˇcten´eho slova se k´od vˇetv´ı do priv´atn´ıch metod obsluhuj´ıc´ıch jiˇz konkr´etn´ı kategorie pˇr´ıkaz˚ u (meshe, uzly sc´eny atd.). Pˇri prvn´ı nalezen´e chybˇe prov´adˇen´ı konˇc´ı a do priv´atn´ı promˇenn´e lastError, na kterou je volaj´ıc´ımu n´aslednˇe vr´acen ukazatel, je zaps´ano chybov´e hl´aˇsen´ı. Ponˇekud speci´aln´ı u ´lohu pln´ı pˇr´ıkaz batch, pˇri nˇemˇz ˇcteme zdrojov´ y soubor obsahuj´ıc´ı mnoˇzinu pˇr´ıkaz˚ u. Naˇc´ıt´ame postupnˇe ˇr´adek po ˇra´dce a pln´ıme textov´ y buffer, neˇz nenalezneme ukonˇcuj´ıc´ı znak (stˇredn´ık). Protoˇze potˇrebujeme zachovat stav interpretuj´ıc´ı instance, vytvoˇr´ıme doˇcasnˇe novou, kter´a pˇr´ıkaz zpracuje (vol´an´ım jej´ı metody Command). Situace je zn´azornˇena na obr´azku 7.1. Pokud se v d´avkov´em souboru vyskytne opˇet batch, proces bude totoˇzn´ y s v´ yˇse uveden´ ym.
32
Uk´azkov´y protokol pro ovl´ad´an´ı klienta
Interaktivn´ı zad´av´an´ı pˇr´ıkaz˚ u ve Windows
Temporary handler
Protocol handler
načtení příkazu ze souboru
inicializace Command() parsování příkazu a jeho vykonání return
Obr´azek 7.1: Diagram zpracov´an´ı pˇr´ıkazu batch.
7.3
Interaktivn´ı zad´ av´ an´ı pˇ r´ıkaz˚ u ve Windows
Pro demonstraˇcn´ı u ´ˇcely bylo rovnˇeˇz vhodn´e doprogramovat konzoli, do kter´e zad´av´ame jednotliv´e pˇr´ıkazy protokolu a jejich vliv okamˇzitˇe pozorujeme v renderovac´ım oknˇe. Toto rozˇs´ıˇren´ı bylo realizov´ano pouze na platformˇe Windows, kde m´a uˇzivatel k dispozici kl´avesnici a moˇznost uspoˇra´d´an´ı oken aplikac´ı – na rozd´ıl od iOS. Konzoli vytvoˇr´ıme v samostatn´em vl´aknˇe za pomoci vol´an´ı funkce rozhran´ı WinAPI AllocConsole a provedeme pˇresmˇerov´an´ı standardn´ıho vstupu a v´ystupu. Naˇc´ıt´ame vstup do bufferu do chv´ıle, neˇz pˇrijde ukonˇcovac´ı znak (stˇredn´ık). V tuto chv´ıli vl´akno vyˇsle poˇzadavek na vykon´an´ı pˇr´ıkazu vl´aknu, ve kter´em bˇeˇz´ı engine. Uvˇedomme si, ˇze metody rozhran´ı sc´eny nesm´ıme volat z jin´eho, protoˇze kontext OpenGL nesd´ıl´ıme napˇr´ıˇc vl´akny. Hlavn´ı vl´akno mus´ıme proto uzp˚ usobit tak, aby dok´azalo pˇr´ıkazy pˇrij´ımat. Zdˇed´ıme tedy SceneControl do nov´e tˇr´ıdy SceneControlRuntimeCommands, pˇriˇcemˇz rozˇsiˇrujeme metodu OnDraw a nab´ız´ıme novou: Command. Command je blokuj´ıc´ı metoda volan´a z vl´akna konzole – jej´ı u ´lohou je uloˇzit pˇr´ıkaz uvnitˇr instance SceneControlRuntimeCommands, ˇcekat na jeho dokonˇcen´ı a vr´atit v´ ysledek (pˇr´ıpadn´e chybov´e hl´aˇsen´ı). Virtu´aln´ı metoda OnDraw, kter´a je
33
Uk´azkov´y protokol pro ovl´ad´an´ı klienta
Interaktivn´ı zad´av´an´ı pˇr´ıkaz˚ u ve Windows
vol´ana pˇredkem z vl´akna enginu, kontroluje, jestli v instanci nen´ı pˇripraven pˇr´ıkaz k vykon´an´ı. Pokud ano, je proveden a v´ysledek opˇet uloˇz´ıme uvnitˇr instance, odkud si ho pˇreˇcte konzolov´e vl´akno. K sd´ılen´ ym promˇenn´ ym je pˇr´ıstup oˇsetˇren pomoc´ı mutex˚ u, metoda Command ˇcek´a aktivnˇe ve smyˇcce na nastaven´ı promˇenn´e done na hodnotu true. Komunikace mezi vl´akny je pˇribl´ıˇzena na obr´azku 7.2.
SceneControlRuntimeCommands (vlákno konzole)
SceneControlRuntimeCommands (vlákno renderingu)
nastavení done = false uložení příkazu do sdílené paměti
Protocol handler
if (!done) Command()
nastavení done = true uložení odpovědi do sdílené paměti
návrat ke čtení vstupu z konzole
návrat do jádra enginu
Obr´azek 7.2: Komunikace mezi vl´akny (konzol´ı a spr´avcem sc´eny).
34
8 Uk´azkov´e sc´eny Pro otestov´an´ı spr´avn´e funkˇcnosti grafick´eho klienta jsme pˇripravili nˇekolik testovac´ıch sc´en, na kter´ ych byly doladˇeny pˇr´ıpadn´e nedostatky. Vyuˇzili jsme pˇr´ıkazu batch, abychom mohli naˇc´ıtat sc´enu v nativnˇe podporovan´em uk´azkov´em protokolu. Sc´eny postupnˇe testuj´ı r˚ uznˇe obt´ıˇzn´e situace pro zpracov´an´ı, od velmi jednoduch´e sc´eny aˇz po naˇc´ıt´an´ı relativnˇe sloˇzit´ ych mesh˚ u.
8.1
Pouˇ zit´ e meshe
Jako testovac´ı meshe byly zvoleny dva modely. Prvn´ım je zn´am´ y model Utah Teapot (viz obr. 8.1), druh´ ym Stanford Bunny (viz obr. 8.2), kter´ y se skl´ad´a jiˇz ze znaˇcnˇe vyˇsˇs´ıho poˇctu troj´ uheln´ık˚ u.
Obr´azek 8.1: Model Utah Teapot.
Obr´azek 8.2: Model Stanford Bunny z v´ıce u ´hl˚ u pohledu. Tyto modely jsou standardnˇe k dispozici ve form´atu Wavefront OBJ [6] s koncovkou souboru OBJ ˇci Polygon File Format[7] s koncovkou PLY. Ani s jedn´ım form´atem 35
Uk´azkov´e sc´eny
Benchmark
neum´ı n´aˇs grafick´ y klient pracovat, a proto musela b´ yt provedena jednoduch´a konverze do form´atu odpov´ıdaj´ıc´ımu protokolu. Zkonvertovan´y mesh je pak moˇzn´e naˇc´ıst pomoc´ı pˇr´ıkazu batch.
8.2
Benchmark
Zamˇeˇrme se nyn´ı na v´ykon aplikace. Na ˇctyˇrech uk´azkov´ych sc´en´ach (screenshoty v pˇr´ıloze) byly mˇeˇreny ˇcasy naˇcten´ı a renderu jednoho sn´ımku. Do naˇcten´ı je zahrnuta interpretace protokolu vˇcetnˇe I/O operac´ı a vytv´aˇren´ı objekt˚ u OpenGL. Je tˇreba br´at v potaz, ˇze uveden´a mˇeˇren´ı se vztahuj´ı k jedn´e hardwarov´e konfiguraci (Intel Core i5-3350P 3.10Ghz, 8GB RAM, Radeon HD 7750) a byla v´ıcekr´at opakov´ana pro poskytnut´ı pr˚ umˇern´ ych v´ ysledk˚ u. Vzhledem k tomu, ˇze pro iOS nebyl protokol jiˇz testov´an, hodnoty jsme z´ıskali pouze na platformˇe Windows. Pˇri testov´an´ı byla samozˇrejmˇe vypnuta vertik´aln´ı synchronizace. Obsah sc´en se r˚ uzn´ı nejen poˇctem kreslen´ ych primitiv. Prvn´ı sc´ena se skl´ad´a pouze z krychle, na kterou je aplikov´an materi´al. Druh´a obsahuje dvˇe instance komplexnˇejˇs´ıho modelu Stanford Bunny, tˇret´ı jednu instanci modelu Utah Teapot s nˇekolika v´alci. Posledn´ı sc´ena sp´ıˇse demonstruje s´ılu vz´ajemn´ ych z´avislost´ı uzl˚ u (renderuj´ı se pouze krychle), pˇriˇcemˇz ˇz´adn´a v´yrazn´a reˇzie se do v´ysledku neprom´ıtla. V´ysledky mˇeˇren´ı jsou zaznamen´any v tabulce 8.1. Rendering pˇri vypnut´e vertik´aln´ı synchronizaci plnˇe vyt´ıˇzil grafickou kartu i procesor (respektive jedno j´adro).
Sc´ena Poˇcet instanc´ı Poˇcet troj´ uheln´ık˚ u Doba kreslen´ı jednoho sn´ımku [ms] Doba naˇcten´ı [ms]
pr´ azdn´ a 0
Demo 01 1
Demo 02 2
Demo 03 3
Demo 04 11
Demo 05 10000
0
12
138902
15960
132
120000
0,115
0,131
0,647
0,237
0,131
16,5
—
0,65
920
217
0,92
179
Tabulka 8.1: V´ ysledky mˇeˇren´ı v´ ykonu aplikace.
36
9 Z´avˇer Pr´ace si kladla za c´ıl vytvoˇrit tenk´eho grafick´eho klienta, kter´y je schopn´y pracovat na mobiln´ıch zaˇr´ızen´ıch a dok´aˇze pˇrij´ımat poˇzadavky na rendering skrze sv´e rozhran´ı nebo definovan´ y protokol. Vzhledem k vrstven´e architektuˇre s jasnˇe definovan´ ym rozhran´ım neˇcin´ı probl´em doprogramovat jin´ y vstup, napˇr´ıklad nov´ y, robustnˇejˇs´ı komunikaˇcn´ı protokol zaloˇzen´ y na X3DOM ˇci JSON syntaxi. Grafick´y klient splˇ nuje v z´akladn´ı podobˇe kompatibilitu s prostˇred´ım n´avrhu sc´eny v programu GraphWorX softwarov´e sady GENESIS. Pˇredpokl´ad´ame, ˇze vytvoˇren´e sc´eny lze snadno pomoc´ı naˇs´ı aplikace zobrazit. Testov´an´ı v´ ykonu aplikace poskytlo uspokojiv´e v´ ysledky, nebot’ i na mnohon´asobnˇe pomalejˇs´ım neˇz mˇeˇren´em hardwaru by obraz p˚ usobil plynule (v´ıce neˇz tˇricet sn´ımk˚ u za vteˇrinu). Pˇri mˇeˇren´ı nebyly zpozorov´any ˇz´adn´e vˇetˇs´ı odchylky v´ ykonu, kter´e by uˇzivatel mohl vn´ımat jako nepˇr´ıjemn´a zaseknut´ı obrazu. Na vytvoˇren´ y engine a aplikaci je moˇzn´e plynule nav´azat tvorbou dalˇs´ı vrstvy ˇr´ıd´ıc´ı animace a komunikaci se serverem, pˇr´ıpadnˇe rozˇs´ıˇrit funkcionalitu j´adra enginu nejenom v grafick´e oblasti. V u ´vahu pˇripad´a rozˇs´ıˇren´ı logov´an´ı, podpora sloˇzitˇejˇs´ıch (napˇr´ıklad pr˚ uhledn´ ych) materi´al˚ u a implementace multiplatformn´ıch socket˚ u pro s´ıt’ovou komunikaci. Dalˇs´ı platformou, na n´ıˇz by se klient mohl vyskytovat po dops´an´ı platformnˇe z´avisl´ ych ˇc´ast´ı zdrojov´eho k´odu, je napˇr´ıklad OS Android. Klient ve sv´e souˇcasn´e podobˇe nemus´ı slouˇzit pouze pro pr˚ umyslov´e vizualizace, ale drobn´ ymi u ´pravami bychom mohli doc´ılit jednoduch´eho j´adra napˇr´ıklad pro vykreslov´an´ı her. Vzhledem ke zvolen´ ym technonologi´ım a jazyku nen´ı dalˇs´ı v´ yvoj enginu v´ yznamnˇe omezen.
37
Literatura [1] iOS Developer Library [online]. [cit. 17.4.2013]. Dostupn´e z: http://developer.apple.com/library/ios.
[2] GENESIS64TM [online]. [cit. 15.4.2013]. Dostupn´e z: http://www.iconics.com/Home/Products/HMI-SCADA-SoftwareSolutions/GENESIS64.aspx.
[3] Introduction to GLKit [online]. [cit. 17.4.2013]. Dostupn´e z: http://developer.apple.com/library/ios/#documentation/GLkit/ Reference/GLKit_Collection/Introduction/Introduction.html. R [4] OpenGL ES Common Common-Lite Profile Specification [online]. 2004.
[cit. 7.3.2013]. Dostupn´e z: http://www.khronos.org/registry/gles/specs/1.0/opengles_spec_1_0.pdf. R [5] OpenGL ES Common Profile Specification (Version 2.0.25) [online]. 2010.
[cit. 7.3.2013]. Dostupn´e z: http://www.khronos.org/registry/gles/specs/2.0/es_full_spec_2.0.25.pdf.
[6] Wavefront OBJ File Format Summary [online]. 2013. [cit. 3.4.2013]. Dostupn´e z: http://www.fileformat.info/format/wavefrontobj/egff.htm.
[7] BOURKE, P. PLY - Polygon File Format [online]. 2013. [cit. 3.4.2013]. Dostupn´e z: http://paulbourke.net/dataformats/ply/. [8] REINERS, D. Scene Graph Rendering. Proceedings of IEEE Virtual Environments. 2002. [9] ZHAO, H. et al. Fast and Reliable Mouse Picking Using Graphics Hardware. International Journal of Computer Games Technology. 2009.
38
A Pˇr´ıloha: Uk´azky sc´en Sc´ ena Demo 01
mesh greencube generate cube 5; mesh greencube material diffuse 0.2 0.9 0.1; node node_greencube create; node node_greencube mesh greencube; node node_greencube rotate x 30; node node_greencube rotate y 30;
Sc´ ena Demo 02
39
Pˇr´ıloha: Uk´azky sc´en batch bunny.model; node node_bunny create; node node_bunny mesh bunny; node node_bunny translate 4 -2 0; node node_bunny2 create node_bunny; node node_bunny2 translate -10 0 0; node node_bunny2 rotate y 130; node node_bunny2 scale 0.8 0.8 0.8; node node_bunny2 mesh bunny;
Sc´ ena Demo 03
batch teapot.model; mesh teapot material diffuse 0.9 0.6 0.3; mesh cylinder generate cylinder 5.5 0.5; mesh cylinder material diffuse 0.4 0.05 0.05; mesh cylinder material specular 0.4 0.05 0.05; mesh cylinder2 generate cylinder 4 0.5; mesh cylinder2 material diffuse 0.1 0.2 0.6; mesh cylinder material specular 0.4 0.4 0.05; node node_cyl create; 40
Pˇr´ıloha: Uk´azky sc´en node node_cyl mesh cylinder; node node_cyl translate 0 -2 0; node node_cyl rotate x 20; node node_cyl rotate y 165; node node_cyl scale 2 2 2; node node_cyl2 create node_cyl; node node_cyl2 mesh cylinder2; node node_cyl2 translate 0 0.5 0; node node_tea create node_cyl; node node_tea mesh teapot; node node_tea translate 0 0.3 0; node node_tea scale 1.7 1.7 1.7;
Sc´ ena Demo 04
mesh rootcube generate cube 1; mesh rootcube material diffuse 1 0 0; mesh cube generate cube 0.7; mesh cube material diffuse 1 1 1; node n1 create; 41
Pˇr´ıloha: Uk´azky sc´en node n1 mesh rootcube; node n1 translate -2 -2 0; node n1 rotate x -30; node n1 scale 2 2 2; node n2 create n1; node n2 mesh cube; node n2 translate 1.2 0 0; node n2 rotate z 30; node n3 create n2; node n3 mesh cube; node n3 translate 1.2 0 0; node n3 rotate z 30; node n4 create n3; node n4 mesh cube; node n4 translate 1.2 0 0; node n4 rotate z 30; node n5 create n4; node n5 mesh cube; node n5 translate 1.2 0 0; node n5 rotate z 30; node n6 create n5; node n6 mesh cube; node n6 translate 1.2 0 0; node n6 rotate z 30; node n7 create n6; node n7 mesh cube; node n7 translate 1.2 0 0; node n7 rotate z 30;
42
Pˇr´ıloha: Uk´azky sc´en node p1 create n3; node p1 mesh cube; node p1 translate 2 0 0; node p1 rotate z -30; node p1 scale 0.5 0.5 0.5; node p2 create p1; node p2 mesh cube; node p2 translate 1.2 0 0; node p2 rotate z -30; node p3 create p2; node p3 mesh cube; node p3 translate 1.2 0 0; node p3 rotate z -30; node p4 create p3; node p4 mesh cube; node p4 translate 1.2 0 0; node p4 rotate z -30;
Sc´ ena Demo 05
V´ypis pˇr´ıkaz˚ u protokolu je pro tuto sc´enu velmi rozs´ahl´y, proto je pˇriloˇzen pouze na CD. 43
B Pˇr´ıloha: Pouˇzit´e verze shader˚ u Jazyky GLSL a GLSL ES se v drobn´ ych ohledech r˚ uzn´ı, avˇsak pˇri dodrˇzen´ı konkr´etn´ıch verz´ı jim lze dodat t´emˇeˇr totoˇznou podobu. Pro variantu ES byla vybr´ana verze 1.0, pro desktop 1.5. Vertex shader z´ısk´av´a vstup z vertex bufferu pˇres promˇenn´e oznaˇcen´e kl´ıˇcov´ym slovem attribute. V´ysledek pˇred´av´a pˇres promˇenn´e tentokr´at oznaˇcen´e jako varying. Propojen´ı shader˚ u zajiˇst’uje linking, kter´ y z obou shader˚ u k sobˇe pˇriˇrad´ı varying promˇenn´e se stejn´ ym n´azvem. V´ ystup fragment shaderu zajiˇst’uje pˇredpˇripraven´a glob´aln´ı promˇenn´a gl_FragColor. V novˇejˇs´ıch verz´ıch (napˇr. GLSL ES 3.0) je moˇzn´e nam´ısto kl´ıˇcov´eho slova varying pouˇz´ıvat oznaˇcen´ı in pro vstup a out pro v´ ystup. Nutnost pouˇz´ıv´an´ı glob´aln´ı promˇenn´e gl_FragColor ve fragment shaderu potom odpad´a.
44
C Pˇr´ıloha: Obsah CD Tato pˇr´ıloha popisuje adres´aˇrovou strukturu pˇriloˇzen´eho CD.
doc
bakal´aˇrsk´a pr´ace ve form´atu PDF
images
obr´azky uveden´e v pˇr´ıloze A
program
grafick´ y klient
binary
pˇreloˇzen´e bin´arn´ı soubory
documentation
automaticky generovan´a dokumentace
libraries
staticky linkovan´e knihovny
source
zdrojov´e soubory
visual studio
soubory projektu Microsoft Visual C++
protocol
sc´eny uk´azkov´eho protokolu
tex
zdrojov´e soubory bakal´aˇrsk´e pr´ace
45