ČESKÉ VÝSOKÉ ÚČENÍ TECHNICKÉ Fakulta Elektrotechnická Katedra počítačové grafiky a interakce
Bakalařská práce
Grafické knihovny pro Windows Mobile Rymzhan Bayekeyeva
Vedoucí práce: Mgr. Jiří Danihelka Studijní program: Softwarové technologie a management Obor: Web a multimedia 2011 1
Poděkování Chtěla bych tímto poděkovat Mgr.Jiřímu Danihelkovi za pomoc při vypracování bakalařské práce. 2
Prohlášení Prohlašuji, že jsem svou bakalářskou práci napsala samostatně s použitím citovaných pramenů. Souhlasím se zapůjčováním práce a jejím zveřejňováním.
V Praze dne 27. 5. 2011…............................................. 3
4
Abstract This thesis deals with the research of graphics library for rendering 3D graphics on mobile devices running Windows Mobile. The first part contains a quick introduction to Windows Mobile, the second part describes the common basics of 3D libraries and OpenGLES, WebGL, XNA, M3G, O3D, X3D, VRML, Java3D and GapiDraw. The last part contains a brief step-by-step instructions for programming with OpenGL ES and M3G.
Abstrakt Bakalářská práce se zabývá výzkumem grafických knihoven pro vykreslování 3D grafiky na mobilních zařízeních s operačním systémem Windows Mobile. První část práce obsahuje rychlé seznámení s operačním systémem Windows Mobile, druhá část popisuje společné základy 3D knihoven a technologie OpenGL ES, WebGL, XNA, M3G, O3D, X3D, VRML, Java3D a GapiDraw. Poslední část práce obsahuje stručný návod krok za krokem pro programování s technologiemi OpenGL ES a M3G. 5
6
Obsah 1. Úvod .........................................................................................................................................3 2. OS Windows Mobile..............................................................................................................4 2.1. Zakladní vlastnosti Windows Mobile .....................................................................4 2.2. Verze Windows Mobile ............................................................................................5 2.2.1. Pocket PC 2000 a Pocket PC 2002 ................................................5 2.2.2. Windows Mobile 2003 a Windows Mobile 2003 SE ..................6 2.2.3. Windows Mobile 5 ............................................................................6 2.2.4. Windows Mobile 6 .............................................................................7 2.2.4.1 Windows Mobile 6.1 ................................................8 2.2.4.2 Windows Mobile 6.5 ................................................8 2.2.4.3 Windows Mobile 6.5.1 .............................................9 2.2.4.4 Windows Mobile 6.5.3 .............................................9 2.2.4.5 Windows Mobile 6.5.5 ...........................................9 2.2.5. Windows Mobile 7 ............................................................................ 9 3. Grafické knihovny ............................................................................................................. 11 3.1. X3D ......................................................................................................................... 11 3.1.1 Profily X3D ...................................................................................... 11 3.1.2 Mobile X3D ..................................................................................... 12 3.2. Java3D ..................................................................................................................... 13 3.3. O3D .......................................................................................................................... 13 3.4. GapiDraw ................................................................................................................ 14 3.5. WebGL .................................................................................................................... 15 3.6. OpenGL ES ............................................................................................................. 16 3.6.1 Verzi 1.0 - 1.1............................................................................ 16 3.6.2 Verzi 2.0 .................................................................................... 17 3.7. M3G ........................................................................................................................ 19 3.8. XNA ......................................................................................................................... 20 4. Praktické využítí knihoven 1 ............................................................................................. 22 4.1 Začínáme v M3G ................................................................................................ 22 4.2 Nastavení prostředí ............................................................................................. 22 4.3 New Project ......................................................................................................... 23 4.4 Java a Windows Mobile .................................................................................... 26 4.5 MIDlet Managers................................................................................................ 26 4.6 Instalace a spuštění MIDletu ............................................................................. 26 4.7 Immediate Mode vs Retained Mode ................................................................ 27 4.7.1 Retained Mode ................................................................................. 28 4.7.2 Píšeme aplikaci v Retained Mode ................................................. 28 5. Praktické využítí knihoven 2 ............................................................................................. 32 5.1. Začínáme s OpenGL ES ........................................................................................ 32 5.2. OpenGL ES a Windows Mobile ........................................................................... 33 5.3. Nastavení prostředí................................................................................................. 33 7
5.3.1. Výběr správné verze........................................................................ 34 5.3.2. Instalace Vincent 3D Rendering Library...................................... 34 5.4. New project a nastavení emulátoru ...................................................................... 35 5.5. Programování v OpenGL ES 1.1 ........................................................................... 39 6. Závěr ...................................................................................................................................... 44 7. Použítá literatura ................................................................................................................... 45 8. Seznam příloh ....................................................................................................................... 47
8
1. Úvod Svět mobilních technologií se neustále vyvíjí a mění. Tyto změny možná nejsou tak rychlé jako ve světě počítačů, ale jsou nezbytné. Lidé si rychle zvykli na malé zařízení s velkou funkčností, chtějí být stále k zastižení a mít po ruce vše co mohou potřebovat - při práci, na dovolené, ve škole. Dnešní technologie jsou zaměřeny na zvýšení funkčnosti těchto kompaktních zařízení. Výrobci zpočátku vybavovali svá mobilní zařízení funkcemi, jako je adresář, organizér, budík. Dnes už není vyjímkou mít v telefonu fotoaparát, přehrávač, rádio a dokonce počítadlo kalorií. Vývojáři proto neváhali přidat do mobilních zařízení také hry. První hry byly pouze ve 2D, ale kdo by dnes měl zájem o 2D hru v telefonu, když si může zahrát ve 3D na počítači? Tímto tedy vstoupil mobilní svět do éry 3D. Dnes se setkáváme nejen s 3D hrami, ale také s rozhraním mobilních telefonů vyvíjených pomocí 3D grafiky. To vše je umožněno díky vývoji softwaru a hardwaru na mobilních zařízeních. Jedněmi z prvních operačních systémů pro mobilní zařízení byli Symbian a Windows CE. Dnes operačních systémů více, např. Apple iOS od Apple, Blackberry od RIM1, a dokonce i Android od společnosti Google. Ve své práci se zaměřím na OS od gigantu Microsoft - Windows Mobile. Cílem této práce je prozkoumat dostupné knihovny pro rychlé vykreslování grafiky pro mobilní zařízení s operačním systémem Windows Mobile. Nabídnu srovnání jejich možností, rychlosti, přenositelnosti a jednoduchosti použití. Práce je rozdělena do dvou větších částí, první částí je výzkum a druhá část je praktická. Ve druhé kapitole popíši historii vývoje a verzi OS Windows Mobile. Třetí kapitola popisuje společné základy 3D knihoven. Ve čtvrté kapitole se budu věnovat všem technologiím, které jsou v dnešní době k dispozici. Popíšu technologie OpenGL ES, WebGL a M3G, O3D, X3D, VRML, Java3D a GapiDraw. V dalších kapitolách se zastavím u jednotlivých technologií OpenGL ES, M3G a popíšu jak s nimi lze naprogramovat 3D grafiku. Tyto kapitoly také obsahují stručný návod programování s uvedenými technologiemi.
1
RIM - Research In Motion Limited je kanadská firma zabívající se telekomunikačními a bezdrátovými zařízeními.
9
2. OS Windows Mobile Windows Mobile je operační systém firmy Microsoft, který je založen na Windows CE 5.2 kernel. Je určen pro mobilní zařízení (PDA, smartphony a zařízení portable media center). Jeho vzhled je odvozen od klasických Microsoft Windows, používá malou podmnožinu jejich Win32 API, avšak obsahuje zcela jiné hybridní jádro.[9]
2.1. Základní vlastnosti Windows Mobile Windows Mobile má ve většině verzí tyto rysy:
Obrazovka Dnes ukazuje datum, informace o vlastníkovi, nadcházející události, emailové zprávy a úkoly. Uživatelé si mohou zvolit, které informace se budou na obrazovce zobrazovat. Na obrazovce se nachází rovněž stavové ikony Bluetooth, stavové ikony Bluetooth, Wi-Fi atd. Programy nainstalované v zařízení mohou přidat na obrazovku další položky. Obrázek na pozadí lze změnit přímo v zařízení nebo lze změnit celé téma. Horní pruh ukazuje čas, hlasitost a stav připojení. Hlavní součástí horního pruhu je tlačítko Start, které je podobné tomu z desktopové verze Windows. Start menu zahrnuje seznam nedávno spuštěných programů, devět upravitelných položek menu a odkazy na seznam programů, nastavení, vyhledávání a nápovědu. Office Mobile je sada mobilních verzí aplikace Microsoft Office zahrnutých ve Windows Mobile. Obsahuje Word Mobile, Excel Mobile a PowerPoint Mobile (z verze Windows Mobile 5.0). Mobilní verze mají mnoho rysů desktopových verzí, ale některé funkce byly značně redukovány. Outlook Mobile zahrnuje úkoly, kalendář, kontakty a poštu, které lze synchronizovat s aplikací Outlook, nebo přímo s Exchange Serverem Windows Media Player pro Windows Mobile podporuje formáty .WMA, .WMV, .MP3 a .AVI Klient pro PPTP VPN Internet Connection Sharing(ICS), které v oblasti mobilních telefonů umožňuje připojené počítače pro sdílení připojení k internetu přes USB a Bluetooth.
10
2.2. Verze Windows Mobile Existují tři verze Windows Mobile pro různá hardwarová zařízení:
Windows Mobile Professional běží na telefonech s dotykovými obrazovkami (smartphony) Windows Mobile Standard pracuje na telefonech s pravidelnými obrazovkami Windows Mobile Classic běží na zařízeních se systémem „Windows Mobile Classic devices― (Pocket PC).
a)
b)
c)
Obrázek 2.1: a)- Windows Mobile Professional(LG KU990); b)- Windows Mobile Standard(T-Mobile Dash); c)- Windows Mobile Classic(O2 Pocket PC);
2.2.1. Pocket PC 2000 a Pocket PC 2002
Pocket PC 2000, pod původním kódovým označením "Rapier", byl uveden na trh 19. dubna 2000 a byl založen na systému Windows CE 3.0. Jednalo se o debut, který byl později přejmenován na operační systém Windows Mobile, a který měl být nástupcem operačního systému na zařízení Palm-Size PC2. Jediné podporováné rozlišení bylo v této verzi 240 x 320 (QVGA). Existovala podpora pro vyjímatelné paměťové karty formátů CompactFlash a MultiMediaCard. Esteticky byl původní operační systém Pocket PC podobný operačním systémům Windows 98, Windows ME a Windows 2000. Pocket PC 2002, známý také pod původním kódovým označením "Merlin", byl představen v říjnu 2001. Stejně jako Pocket PC 2000 byl poháněn systémem Windows CE 3.0. Přestože byl zaměřen především na 240 × 320 (QVGA) Pocket PC zařízení, byl Pocket PC 2002 používán také pro telefony Pocket PC, a poprvé též pro Smartphone. Tyto Pocket 2
Palm-Size PC byl prvním pokusem Microsoftu o vytvoření PDA.
11
PC 2002 Smartphony byly hlavně GSM zařízeními. Esteticky se Pocket PC 2002 podobal nově vydanému Windows XP.
2.2.2. Windows Mobile 2003 a Windows Mobile 2003 SE
Třetí verze s názvem Windows Mobile 2003 byla uvedena 23. června 2003. Dělila se na čtyři edice: „Windows Mobile 2003 for Pocket PC Premium Edition―, „Windows Mobile 2003 for Pocket PC Professional Edition―, „Windows Mobile 2003 for Smartphone― a „Windows Mobile 2003 for Pocket PC Phone Edition―. Windows Mobile 2003 for Pocket PC Phone Edition je verze pro Pocket PC s telefonním modulem (například HTC Himalaya, distribuovaným v mnoha zemích jako Qtek, XDA, MDA nebo VPA). Windows Mobile 2003 je založen na Windows CE 4.20. Verze Windows Mobile 2003 Second Edition, známá také jako Windows Mobile 2003 SE, byla vydána 24. března 2004 a jako první byla použita na Dell Axim x30. Zahrnuje tato vylepšení:
Možnost přepnutí rozložení displeje našířku a zpět navýšku (pouze pro Pocket PC). Pocket Internet Explorer (jinak známý jako PIE) obsahoval možnost rozložení stránky do jednoho sloupce, nebylo již tedy nutné rolovat vodorovně. Podpora pro rozlišení displeje VGA (640 x 480). Dřívější verze podporovaly pouze QVGA ( 320 x 240 ). Dále zde byla podpora čtvercového rozlišení ( 240 × 240 a 480 x 480), zejména pro výrobce, kteří chtěli přidat na zařízení hardwarovou klávesnici Podpora Wi-Fi Protected Access (WPA).
2.2.3. Windows Mobile 5
Windows Mobile 5.0, dříve známý pod kódovým označením Magneto, byl představen 9. května 2005 na Mobile and Embedded Developers Conference 2005 (MEDC) v Las Vegas. Systém pohání Windows CE 5.0 a používá .NET Compact Framework 1.0 SP2. První zařízení s Windows Mobile 5.0 byl Dell Axim x51. Nové vlastnosti:
Nová verze Office s názvem "Office Mobile" Nová aplikace PowerPoint Mobile (prohlížeč formátu PPT) 12
Podpora grafů v aplikaci Excel Mobile Podpora vložení tabulek, seznamů a obrázků v aplikaci Word Mobile Změna práce s pamětí (Data se ukládají do FlashROM. RAM je určena pouze pro běh aplikací.) Windows Media Player 10 Mobile Zobrazení fotografie v kontaktu a její synchronizace Vylepšený správce fotografií a videí Centrální správa GPS pro navigační programy Podpora USB 2.0 Podpora technologií Direct3D, DirectDraw a DirectShow pro vývojáře
Obrázek 2.2: Windows Mobile 5.0 pro Pocket PC, obrazovka Dnes
2.2.4. Windows Mobile 6 Windows Mobile 6, dříve známý pod kódovým označením Crossbow, je poslední verzí tohoto mobilního operačního systému, která byla představena 12. února 2007 na 3GSM World Congress 2007. Existují celkem tři verze systému: Windows Mobile 6 Standard pro smartphony, Windows Mobile 6 Professional pro PDA s integrovaným telefonem (Pocket PC Phone Edition) a Windows Mobile 6 Classic pro PDA bez telefonního modulu. Windows Mobile 6 je úzce propojen s Windows Live and Exchange 2007. Windows Mobile 6 Standard poprvé nabídl Orange SPV E650, zatímco Windows Mobile 6 Professional se nejdříve stal součástí O2 Xda Terra. Přehled nových vlastností Windows Mobile 6: Podpora rozlišení 320x320 a 800x480 (WVGA). Schopnost upravovat dokumenty Office na smartphonech Schopnost automatických aktualizací systému 13
Zlepšení přístupu přes vzdálenou plochu Podpora VoIP Integrace Windows Live Šifrování dat na výměnné paměťové kartě. Smartfilter pro rychlejší vyhledávání Podpora prohlížení HTML e-mailů v Outlook Mobile Schopnost hledat v Exchange Server Address Book. Podpora AJAX, JavaScript a XMLDOM v Windows Internet Explorer Mobile
Obrázek 2.3: Windows Mobile 6.0 Standard, obrazovka Dnes
2.2.4.1. Windows Mobile 6.1 Windows Mobile 6.1 byl představen 1. dubna 2008. Je určen pro zařízení, která jsou vybavena dotykovým displejem (typicky smartphony). Jeho hlavní předností by mělo být upravené rozhraní, které usnadní celkové ovládání telefonu.
2.2.4.2. Windows Mobile 6.5 6. října 2009 představil Microsoft Windows Mobile 6.5, nový název Windows Phone pro telefony s Windows Mobile. Nové služby jsou My Phone a obchod s aplikacemi Marketplace. Systém přináší upravený vzhled, který je lépe přizpůsobený pro ovládání prsty.
Obrázek 2.3: Windows Mobile 6.5 Standard, obrazovka Dnes, „Titanium―
14
2.2.4.3. Windows Mobile 6.5.1 Windows Phone 6.5.1 byl neoficiálně portován na několik zařízení Windows Phone a přináší přátelštější rozhraní pro prsty.
2.2.4.4. Windows Mobile 6.5.3 Windows Mobile 6.5.3 byl představen v únoru 2010 jako první Windows Mobile smartphone. Tento operační systém znovu přináší přátelštější rozhraní pro prsty s několika novými funkcemi, jako jsou podpora pro multitouch nebo kompletní dotykové ovládání, a také novou sadu Office Mobile 2010.
2.2.4.5. Windows Mobile 6.5.5 Poslední build Windows Mobile a také verze 6, která se na mobilních telefonech používala zhruba 3 a půl roku přinesla již jen nepatrné změny.[1]
2.2.5. Windows Mobile 7 Windows Phone 7 byl v Evropě, Singapuru a Austrálii představen 21. října 2010, ve Spojených Státech a v Kanadě pak 8. listopadu 2010, zatímco zbytek světa následoval až v roce 2011. Microsoft měl původně v úmyslu pokračovat ze systému Windows Mobile do Windows Mobile 7, který byl založený na modernizaci platformy operačního systému Windows Mobile s kódovým označením Photon. Původní Photon a Windows Mobile 7 byli od té doby zrevidováni, nicméně Microsoft se rozhodl vytvořit novou mobilní platformu OS a představit Windows Phone 7 Series. Microsoft proto nazval operační systém z Windows Phone 7 Series Windows Phone 7. Během Mobile World Congress 2010 v Barceloně odhalil Microsoft podrobnosti o Windows Phone 7, který je vybaven novým operačním systémem a integrací se službami Xbox Live a Zune. Telefony s operačním systémem Windows Mobile 6.* nelze upgradovat na Windows Phone 7. [2] Windows Phone 7 má specifické minimální požadavky na zařízení s daným OS. Všechná zařízení musí mít:
multi-dotykový displej (uznání čtyř doteků současně). Rozlišení displeje – výběr ze dvou možností: 800 x 480 a 320 x 480; CPU s alespoň 1 GHz; 256RAM a 8Gb flash pamětí; podpora DirectX 9; GPS přijímač; 15
akcelerometry; FM – radio; fotoaparát s bleskem a rozlišením minimálně 5 Mpx; elektronický kompas.
Všechna zařízení by také měla mít 6 hardwarových tlačítek: 1. zapnutí/vypnutí: může mít více funkci vedle těch zakladních, např. blokaci zařízení, zapnutí a vypnutí displeje; 2. ovladání hlasitosti: slouží k nastavení hlasitosti; 3. kamera: toto tlačítko musí podporovat Half-way press a Full-way press. Stlačení do poloviny upraví zaostření, stlačení nadoraz pořídí fotografii. Mimo to se stisknutím tlačítka fotoaparátu zobrazí přislušná aplikace; 4. zpět: provádí krok zpět mezi aplikacemi a stránkami; 5. start: všechny aktivní aplikace se pozastaví a otevře se domovská stránka; 6. hledání: pomocí vyhledávače Bing.
Obrázek 2.4: Windows Phone, obrazovka Start
16
3. Grafické knihovny 3.1. X3D X3D (Extensible 3D) – je rozšiřitelný jazyk pro popis tří-dimenzionální scény, určený k vytvoření 3D grafiky na internetu. Pracovní návrh X3D byl poprvé představen na 7. mezinárodní konferenci "3D Web Technology" v USA v únoru 2002. Jedná se o ratifikovaný ISO standard, který poskytuje systém pro ukládání, získávání a přehrávání grafiky v reálném čase, to vše v rámci otevřené architektury pro podporu širokého spektra domén a uživatelských scénářů. Grafický formát X3D z velké části vychází z VRML (proto je také někdy nazýván „VRML 3.0―), ovšem opravuje některé jeho nedostatky a především umožňuje – kromě původní syntaxe odvozené od Open Inventoru – použít i syntaxi zápisu založenou na XML. V důsledku toho je X3D znamý jako nástupce VRML, je ovšem kompaktnější. Využítí XML přináší celou řadu předností, především jednoduché zpracování celého dokumentu pomocí velkého množství knihoven a programových API pro práci s XML (SAX a DOM existující snad pro všechny významné programovací jazyky), možnost poloautomatické serializace a deserializace prostorové scény do X3D, relativně snadné převody mezi X3D a dalšími formáty apod. Řada funkcí X3D může být použita ve vědecké vizualizaci, architektuře, lékařské vizualizaci, školení a simulaci, multimédiích, zábavě, vzdělávání apod.
3.1.1. Profily X3D
Modulární architektura X3D má několik základních „profilů―. Jsou to Interchange (vzájemný), Interactive (interaktivní), Immersive (immersivní), MPEG-4 Interactive, CDF a Full (úplný). Interchange je základní profil pro komunikaci mezi aplikacemi. Tento profil podporuje geometrii, textury, základní osvětlení, a animace. Neexistuje žádný model pro spuštění renderování, takže použití a integrace do libovolné aplikace jsou velmi snadné. Interaktivní profil umožňuje základní interakce s 3D prostředím přidáním různých senzorů - uzly pro navigaci uživatele a interakce (např. PlanseSensor, TouchSensor, atd.), lepší načasování a další osvětlení (Spotlight, PointLight).
17
Immersivní profil umožňuje plnou 3D grafiku a interakci, včetně audio podpory, kolize, mlhy, a skriptování. MPEG-4 Interactive je menší verze Interaktivního profilu navržená pro vysílání (broadcast), kapesní zařízení a mobilní telefony. CDF (CAD Destilační Format) profil je stále ve vývoji. CDF by měl umožňovat překlad dat CAD do otevřeného formátu pro publikování a interaktivní média. Úplný profil zahrnuje všechny definované uzly, včetně NURBS, H-Anim a GeoSpatial komponentů.
3.1.2. Mobile X3D
Jak již bylo řeceno výše, MPEG-4 Interaktivní Profil X3D je navržen pro menší aplikace, včetně mobilních. Tento profil je pečlivě vybranou podmnožinou obsahující sedmdesát X3D uzlů, které poskytují podporu pro základní geometrii, textury obrazu, animace, snímání a interakci s uživatelem. Malé rozměry X3D prohlížeče ukuzují, že mobilní X3D aplikace jsou možné, za použití X3D modelů, které fungují obdobně na stolních počítačích. V létě 2010 prezentovala studijní skupina Mobile X3D na schůzce Web3D Korea Chapter Meeting první příklad X3D na mobilním zařízení:
Obrázek 3.1: ukázka MX3D na Windows Mobile 6.03
Hlavním cílem této skupiny je vytvořit pevný základ pro X3D tak, aby řádně podporoval 3D grafiku na mobilních platformách. Jedinou možností přehravání X3D na platformách Windows Mobile je BS Contact Mobile, který lze stahnout (testovací verzi) na oficialních stránkách BitManagementu.
3
X3D GPS Interface. Web3D Korea Chapter Meeting. July 29, 2010. The University of Suwon. Myeong Won Lee
18
3.2. Java3D Jáva 3D představuje cross platformní knihovnu k zobrazování trojrozměrné grafiky, která je samozřejmě popsána v jazyce Java. Tato knihovna byla poprve představena v prosinci 1998. Programy napsané v Java 3D mohou běžet na mnoha odlišných typech počítačů, menších zařízeních a přes internet. Knihovna tříd Java 3D poskytuje rozhraní, které je jednodušší než rozhraní mnoha jiných grafických knihoven, ale zároveň je dostačující k tvorbě dobrých her a animací. Java 3D staví na existujících technologiích jako je DirectX a OpenGL (v závislosti na platformě), takže programy neběží tak pomalu jak by se dalo očekávat. Java 3D také umožňuje začlenit objekty vytvořené 3D modelovacími nástroji ve formátech 3DS, OBJ, VRML a X3D. OS Windows Mobile v základu Java aplikace nepodporuje, ale Java běží za pomoci aplikace třetích stran, čímž se dá podpora Javy doinstalovat. Mezi nejpoužívanější emulátory patří IBM DELTA MIDP 2.0, který zvládá podporu Java verze 1.0 a 2.0, dále pak emulátory JavaMAN a Java Virtual Machine.[4]
Obrázek 3.2: ukázka Java 3D na Windows Mobile4, emulator Delta MIDP2.0
3.3. O3D 20. dubna 2009 představil Google ve spolupráci s Khronos Group open-source technologii O3D. O3D představuje JavaScript API, který umožňuje vytvořit interaktivní grafické 3D aplikace (hry, simulace, ukazkové modely, virtualní reality) pro jejich následné spuštění ve webovém prohlížeči. Jedná se nejen o návrh 3D API, ale i o jeho implementaci, kterou si můžete stáhnout do vašeho prohlížeče. Podporovány jsou prohlížeče 4
Tento obrázek byl převzat z http://smartmania.mobilmania.cz/ autor: Jiří Hrma
19
Firefox, Safari, Google Chrome a Internet Explorer. Pro zobrazení vysoce kvalitní 3D grafiky používá plugin O3D různé metody renderingu, a to výkon centrálního mikroprocesoru a grafické karty. Hlavní specialitou O3D je ale skutečnost, že se jeho skriptové aplikace píší pomocí speciálního API v běžném Javascriptu a v libovolném textovém editoru. Nic se nepřekládá, nic se nekompiluje.
Obrázek 3.3: ukázka O3D Riad Haddad's walk-in movie store5
O3D zatím nepodporuje žadné mobilní platformy. Koncem května 2010 Google oznámil, že O3D přešel z pluginu do knihovny JavaScript běžící nad WebGL.
3.4. GapiDraw Od roku 2002 se švědská společnost Develant Technologies AB zabyvá vývojem nové komplexní robustní grafické platformy GapiDraw. Tato platforma je cílena zejména na vývoj aplikací s vysokými nároky na rychlou grafiku pro zařízení s OS Windows Mobile. GapiDraw umožňuje využít hardwarovou akceleraci, pokud je dostupná. GapiDraw poskytuje vývojářům dvě základní rozhraní: knihovnu tříd GapiDraw a GapiApplication framework, které společně zprostředkovávají rozsáhlou funkcionalitu. Jedná se o placené řešení, základní licence se dá
5
Obchod s filmy, který získává data o DVD a Blue-ray z Amazonu. Je hezkou ukázkou toho, co umí O3D. Více na: www.3dmoviehaven.com/3ddvdstore.php
20
pořídit za $995, ale existuje testovací verze pro nekomerční použití, která má stejnou funkcionalitu jako verze základní.
Obrázek 3.4: Ancient Evil. Od Pocket PC Studios.
3.5. WebGL WebGL, podobně jako O3D, představuje cross-platformní JavaScript API, který umožňuje vytvářet 3D grafiku v prohlížeči. Tento webový standard od Khronos Group byl odvozen z knihovny OpenGL ES 2.0 s cílem maximalizovat přenositelnost na mobilní zařízení. Toto nízkoúrovňové API poskytuje přístup k výkonu hardwaru přímo ze scriptů na webových strankách. Tato vlastnost umožňuje vytvářet 3D grafiku, která se bude aktualizovat v reálném čase přímo v prohlížeči. WebGL je webový standard, proto nepotřebuje žadné pluginy. V současné době je WebGL podporován v HTML 5 prohlížečích Mozilla Firefox, Google Chrome a Safari. Zatím bohužel není k dipozici podpora WebGL na platformách Windows Mobile. Důvodem je to, že nejsou mobilní HTML 5 prohlížeče, přestože Windows Mobile plně podporuje OpenGL ES. Mozilla před rokem vydala alfa verzi prohlížeče pro Windows Mobile, letos byl ale vývoj přerušen kvuli verzi Windows Phone. Hezkým přikladem WebGL na mobilním zařízení je Nokia 900 s OS Maemo:
21
Obrázek 3.5: ukázka WebGL běžící na Nokia 900. Hra Match3D6.
3.6. OpenGL ES OpenGL ES je multiplatformní API pro programování 3D grafiky na různých vestavěných zařízeních (herní konzole, telefony, komunikátory, PDA, atd.). Jedná se o dobře definovanou podmnožinu OpenGL, která poskytuje flexibilní a výkonné nízkoúrovňové rozhraní mezi softwarem a hardwarem pro akceleraci grafiky. Samotný OpenGL představuje API pro programování 3D grafiky na klasických počítačích. Velkou výhodou je kompatibilita OpenGL ES s klasickým OpenGL. OpenGL ES má dva různé profily, Common a Common-Lite. Common-Lite profil se liší od Common profilu především tím, že je zaměřen na jednodušší třídu grafických systémů, které nepodporují high-performance floating-point výpočty. Common-Lite profil podporuje pouze příkazy s fixed-point argumenty, zatímco Common profil obsahuje také mnoho rovnocenných příkazů s floating-point argumenty. Dnes existují dvě verze OpenGL ES, jsou to OpenGL ES 1.x a OpenGL ES 2.x.
3.6.1. Verze 1.0 - 1.1 První verze OpenGL ES, 1.0, byla představena v roce 2003 a je založena na OpenGL 1.3, ale byly z ní odstraněny některé funkce:
6
Hra je dostupná na http://users.sch.gr//pavlos/webgl/Triliza/
22
Begin/end – paradigma. Tato funkce již byla považována za zastaralou, jelikož upřednostňovala především vrcholové vektory. Quad, quad-strip a polygon drawing primitives. Tyto funkce byly odstraněny, jelikož primitives mohou být nyní sestaveny z trojúhelníků. Automatické generování texturových souřadnic. Jedno a trojrozměrné textury a krychlové čtvercové mapy, byly ponechány pouze dvourozměrné textury. Některá nastavení texturového prostředí, byly ponechány pouze jednodušší funkce jako je replace, blend, add a modulate. Display listy, důvodem je jejich složitá implementace.
Obrázek 3.6: Fixed function pipeline v OpenGL 1.5 a OpenGL ES 1.1 [13]
GLES 1.1 byla uvedena v roce 2004 a je založena na OpenGL 1.5. Nejdůležitějšími prvky, které byly nově přidány a GLES 1.0 je neobsahovala, jsou vertex buffer objects a podporují veškerá pokročilá nastavení prostředí textur v OpenGL 1.5.
3.6.2. Verze 2.0 Poslední verze GLES 2.0 byla aktualizována v roce 2007 [16]. Je založena na OpenGL 2.0 a na vysokoúrovňových shaderech. Na rozdíl od OpenGL 2.0 však GLES 2.0 definitivně 23
přestává podporovat fixed function pipeline. Důsledkem toho je, že GLES 2.0 není zpětně kompatibilní s předchozími verzemi GLES. Shaders jsou specifikovány ve verzi GLSL zvané GLSL ES. GLES 2.0 podporuje pouze Common profile a podpora fixed point byla omezena na vrcholové vektory.
Obrázek 3.7: Programovatelná linie OpenGL ES 2.0 [xiii]
Nejpodstatnější funkce, které byly z OpenGL 2.0 odstraněny: Begin/end-paradigma. Speciální vrcholové vektory pro atributy jako pozice, normály a texturové souřadnice. Tyto funkce byly odstraněny ve prospěch obecné funkce glVertexAttribPointer. Quad, quad-strip a polygon drawing primitives. Veškeré funkce, které upravují transformace aktuálních matic. Náhled modelu a projekční matice byly rovněž odstraněny, programátoři si nyní vybírají, jaké transformace potřebují a předávají je jako uniforms do shaderů. Automatické generování texturových souřadnic. To je nyní možno realizovat přes vertex shaders. Veškeré funkce, které operují se světlem a stavem materiálu. Programátoři implementují zákaznické řešení osvětlení se shadery a feed daty do shaderů s generickými uniformy a atributy vrcholů. Jedno a trojrozměrné textury, přičemž byly ponechány pouze dvourozměrné textury a čtvercové mapy. Nastavení texturového prostředí. To již není potřeba, protože shadery jsou přímou náhradou a jsou mnohem výkonnější. Nastavení mlhy, nyní realizované pomocí shaderů. Display listy. GLES 2.0 přímo podporuje framebuffer objects, které jsou dostupné pouze jako dodatek k OpenGL 2.1. Framebuffer objects umožňují vytváření několikanásobných off-screen framebuffers a jejich renderování. To umožňuje rychlé renderování textur a podporu 24
renderování větších textur než je framebuffer na obrazovce. To je důležité zejména při renderování map, prostředí map nebo vytváření dalších efektů jako jsou odrazy, refrakce nebo postprocesing. GLSL ES je velice podobný GLSL, ale jsou mezi nimi dva hlavní rozdíly: v GLSL ES byly odstraněny speciální proměnné, které jsou vázány na fixed function pipeline, a naopak byla přidána klíčová slova pro specifikaci proměnných (lowp, mediump a highp).
3.7. M3G Mobile 3D Graphics API nebo M3G představuje standard pro programování 3D grafiky v jazyce Java. Jedná se o API, který je určen pro mobilní zařízení podporující platformu J2ME (verze jazyka Java pro mobilní zařízení). Tento standard byl vyvinut expertní skupinou JSR s cílem vytvořit malý, rychlý a jednoduchý systém, který by mohl fungovat na různých zařízeních podporujících Java programování. Tento API je zaměřen na třídu CLDC (Connected Limited Device Configuration) zařízení, která mají obvykle velmi malý výpočetní výkon a paměť a žádnou hardwarovou podporu pro 3D grafiku nebo floating-point operaci. API je nicméně vhodné i pro tzv. high-end zařízení, která mají hardwarovou podporu pro 3D grafiku a operaci floating-point. Pro splnění širokého spektra potřeb 3D grafiky na mobilnich zařízeních je M3G API rozdělen do 2 typů: vysokoúrovňového (retained mode) a nízkoúrovňového (immediate mode) API. V režimu immediate mode lze přímo kreslit 3D objekty. V retained mode režimu se pracuje s grafy scény, lze tedy nadefinovat a zobrazit celý svět (World) s 3D objekty, včetně informací o jejich vzhledu. Můžete použít buď jeden režim, nebo oba současně, v závislosti na úkolu. M3G lze představit jako objektově-orientované rozhraní OpenGL ES na nízké úrovni (low-level nebo immediate mode) a jako odkaz na nástroje pro vykreslování 3D grafiky na vysoké úrovni (high-level nebo retained mode). Tímto nástrojem může být libovolný software, který podporuje export do speciálního formátu .m3g, např. Autodesk 3ds Max, Autodesk Maya nebo Blender. Když skupina JSR vyvíjela M3G, jedním z jejích cílů bylo také implementovat API nad OpenGL ES, za účelem zvýšení použitelnosti API na různých typech zařízení. Téměř všechny důležité funkce OpenGL ES verze 1.0 jsou v M3G podporovány, avšak některé byly buď zjednodušeny, např. blending a test hloubky ostrosti, anebo zcela vypuštěny, např. tečky a čáry (lines). Bylo také zrušeno vše, co je volitelné v OpenGL ES a méně podporované funkce, jako např. Stencil buffering, což nabídlo vývojářům méně roztříštěnou platformu. Objektově orientované rozhraní M3G sestává ze 30 tříd a kolem 400 metod, které mohou být použity ke kreslení složitých animovaných 3D scén. M3G byl vyvinut v rámci Java Community Process jako JSR 184, aktuální verze je 1.1 M3G, zatímco verze 2.0 (JSR 297) je od roku 2007 ve vývoji. 25
3.8. XNA
XNA (XNA's Not Acronymed) je sada nástrojů a technologií od společnosti Microsoft, která významně usnadňuje rozvoj a správu počítačových her. XNA byla vydaná 24. března 2004 na Game Developers Conference v San Jose v Kalifornii. Všechny komponenty XNA Frameworku lze relativně snadno rozdělit do 4 úrovní abstrakce (obr. 3.8): Platform – nejnižší úroveň, která představuje wrapper nad platformě závislého API, např. DirectX (Direct3d, XINPUT, XACT); Core Framework - dolní platformě nezávislá úroveň XNA, která poskytuje základní funkčnost. Je umístěna v sestavě Microsoft.Xna.Framework.dll a obsahuje 5 komponentů: Graphics (práce s grafikou), Audio (práce se zvukem), Input (Práce s I/O zařízením), Math (matematické výpočty), Storage (práce se souborovým systémem). Extended Framework – sada vysokoúrovňových tříd, které řeší typické problémy pro vývojáře, např. inicializaci grafického zařízení a export modelů a textur z grafických editorů. Ve skutečnosti lze Extended Framework považovat za univerzální entry-level herní engine (Game Engine). Je umístěna v sestavě Microsoft.Xna.Framework.Game.dll. Game – tato úroveň představuje všechny hry vytvořené vývojáři. Sada XNA přichází s několika jednoduchými příklady her (Starter Kits), které lze použít jako základ pro aplikace. vlastní
Obrázek 3.8: Architektura XNA.
Pomocí XNA lze vyvíjet hry pro Windows (XP, Vista, 7), XBOX360, WindowsPhone 7, a Zune (ovšem pouze 2D, protože současné modely nepodporují 3D u Zune). XNA se programuje c C#. 26
4. Praktické využítí knihoven 1 4.1. Začínáme v M3G Balíček M3G byl zpočátku vyvinut pro grafiku na menších zařízeních. M3G se programuje v jazyce Java. Tento standard funguje nad J2ME (Java 2 Platform, Micro Edition), která představuje prostředí pro vývoj aplikací Java pro malá výpočetní zařízení. J2ME sestává z konfigurace a profilu. Obsahuje 2 konfigurace - CDC a CLDC a profil MIDP. Všechny aplikace pro mobilní zařízení se programují nad CLDC/MIDP, která je v současné době podporována většinou mobilních zařízení. MIDP (Mobile Information Device Profile) je aplikační rozhraní, které definuje jakým způsobem softwarové aplikace spolupracují s mobilními telefony. Umožňuje vytvářet aplikace pro mobilní telefony. Aplikace, která je vytvořena podle tohoto standardu se nazývá MIDlet a je umístěna v balíčku javax.microedition.midlet. Tři možné stavy běžící MIDlet aplikace: • paused: MIDlet běží, ale není aktivní. • active: MIDlet je aktivní. • destroyed: MIDlet byl zastaven a je připraven zahájit čištění. V MIDlet aplikaci fungují hry a grafika pomocí 2 tříd: MIDlet a Canvas. Funkce MIDlet již byla popsána výše. Canvas představuje prázdnou obdélníkovou oblast displeje do které bude aplikace vykreslovat grafiku. Canvas poskytuje vývojářům metody ovládání herních akcí, key event a pointer event.
4.2. Nastavení prostředí Je známo, že programování jakékoli aplikace vždy vyžaduje nastavení vlastního prostředí. Pro Java s podporou M3G potřebujeme postupně nainstalovat: -
JDK (Java SE Development Kit) 1.6 nebo vyšší [i] Active Sync 4.5 nebo Windows Mobile Device Center pro Windows Vista/7 [ii] SDK (Software Development Kit) [iii]
Existuje více druhů SDK: Sun Java ME SDK 3.0, NetBeans 7.0 IDE, MOTODEV Studio for Java ME, a též SDK od mobilních výrobců NOKIA, Sony Ericsson a LG. Z uvedených SDK jsem zvolila Sun Java SDK 3.0. Tento SDK zahrnuje vývojové prostředí, několik typů emulátorů, příklady Java aplikací, a navíc dokáže ladit aplikaci v reálném mobilním zařízení. Tato funkce je ovšem k dispozici pouze pro zařízení s Windows Mobile 6. 27
Obrázek 4.1. : Sun Java SDK 3.0[i]
4.3. New Project Vytvoříme nový projekt: File → New Project → MIDP Application:
Obrázek 4.2. : Sun Java SDK , wizard nového projektu.
28
Napíšeme název nového projektu (popř. nové umístění) → Next:
Obrázek 4.3. : Sun Java SDK , wizard nového projektu.
Pokračujeme dál a vybereme typ zařízení (emulátor), konfiguraci a profil.
Obrázek 4.4. : Sun Java SDK , wizard nového projektu, výber nastavení.
29
Vytvoří se výchozí „Hello World― projekt. Spustíme projekt a vidíme naběhnutí emulátoru.
Obrázek 4.5. : Sun Java SDK , spouštění projektu, a Hello World okno v emulatore.
Pokud jsme zapomněli na některé nastavení nebo udelali chybu, klikneme pravým tlačítkem myši na project Name → Properties a zvolíme nové nastavení:
Obrázek 4.6. : Sun Java SDK , okno vlastnosti projektu
30
Po spuštění emulátoru v „dist― složce projektu se vytvoří 2 soubory: *.jar a *.jad. Jar soubor představuje archiv, který obsahuje soubory s třídami, zdroje a manifest. Jad soubor (deskriptor) obsahuje popisné informace, které přístroji pomohou stáhnout MIDlet. Velikost aplikace a URL *.jar MIDletu musí být popsány v Jad souboru.
4.4. Java a Windows Mobile Při programování v Javě pro WM jsem se setkala se dvěma hlavními problémy: 1. Zjistila jsem, že vlasnost J2ME SDK, kterou jsem potřebovala mně nevyhovovala. Java SDK 3.0 nabízí možnost CLDC emulace na WM 6.0, ale tento balíček nepodporuje standard JSR 184(M3G), proto bylo od vývoje aplikace s emulátorem na zařízení WM upuštěno. Jedinou možností je programování M3G v uvedeném SDK za použití dostupných emulátorů, a poté ruční spuštění programu na WM zařízení. 2. Microsoft Javu nepodporuje, a to z toho důvodu, že Java byla od počátku konkurentem .NET (Compact) frameworku. To znamená, že MIDlety nepoběží na WM zařízeních bez dodatečné pomoci. Onou pomocí jsou tzv. MIDlet manažery od třetích stran.
4.5. MIDlet Managers Existují 2 MIDlet emulátory, které podporují M3G – Jblend[iv] od Aplix a TAO Intent[v]. Aplix Jblend je kompatibilní s WM 5 – 6 (Professional a Smartphone) a není kompatibilní s Windows Mobile Classic. MIDlet od Aplix má podporu M3G, ale neumí přehrávat MP3/midi zvuky. Aplix Jblend lze nainstalovat na paměťovou kartu. Podporuje softkey. TAO Intent podporuju většinu WM zařízení. Existují 2 verze MIDletu - 10.1 (pro WM2003(SE) a MS Smartphone) a 11.1 (pro WM5+ & Pocket PC). TAO Intent má oproti Jblendu podporu MP3, ovšem nedostatečnou. Stejně jako Jblend lze TAO Intent nainstalovat na paměťovou kartu. Nepodporuje softkey. Vývoj TAO Intent se od roku 2007 zastavil. Výběr MIDletu zde závisí na zařízení. Vlastním mobilním zařízením HTC Touch(Elf) s Windows Mobile 6.0 Professional. Ze dvou MIDlet manažerů dokázal TAO Intent spustit MIDlety s M3G.
4.6. Instalace a spuštění MIDletu Pro instalaci MIDlet emulátoru stačí nakopírovat soubor *.cab na zařízení a spustit, WM 31
ho sám automaticky nainstaluje. Po instalaci emulátoru na zařízení sdružuje MIDlet manažer soubory *.jar a *.jad na sebe, proto pro spuštění stačí kliknout na *.jar nebo *.jad soubor v průzkumníku Windows. MIDlety lze také spouštět přímo z emulátoru. Pro tuto funkci je třeba otevřít emulátor, stisknout Menu→Install→Local a emulátor již najde všechny *.jar a *.jad soubory v zařízení nebo na paměťové kartě. Z vypsaného seznamu vyberete potřebné MIDlety a stisknete Send. Po instalaci v emulátoru se objeví MIDlet s konkrétní ikonou.
Obrázek 4.7. : TAO Intent běžící na mem HTC Touch (Elf)
4.7. Immediate Mode vs Retained Mode Jak již bylo zmíněno výše, M3G je soubor tříd umístěných v balíčku javax.microedition.m3g, a ve skutečnosti je wrapper knihovny OpenGL ES. Balíček obsahuje 30 tříd a má 2 režimy aplikace:
Immediate mode — režim, v němž lze přímo vytvářet a manipulovat s 3D objekty.
Základní třídy v tomto režimu jsou: VertexArray, VertexBuffer, IndexBuffer, Appearance a Transform. Triangle Strip je jediné podporované primitivum v tomto řežimu. Práce s velkým světem pomocí tohoto režimu je poměrně pracná. Retained mode — tento režim je na vyšší úrovni abstrakce ve srovnání s režimem Immediate. Základní třídy tohoto režimu jsou potomky třídy Node, pomoci nichž lze snadno postavit nebo stáhnout komplexní graf scény. Práce s tímto režimem je mnohem snadnější a intuitivně jasnější, výstup grafiky se provádí pomocí přikazu graphics3d.render(world), který jedním voláním provede výstup celého grafu scény na obrazovku.
32
Obrázek 4.8. Příklad M3G - Immediate Mode běžící na emulátoru. Krychle je vytvořena pomocí Triangle Strip, poté je na ni aplikována textura. Jako pozadí je nastaven obrázek.
4.7.1. Retained Mode Programování v retained mode začíná s vývojem 3D světa. Svět musí být ve formátu *.m3g. Bohužel neexistují žádné 3D editory, které by přimo editovaly modely v tomto formátu. Lze ovšem použít široce znamé 3D redaktory a konvertory, které jsou navrženy pro převod modelu z nativního formátu editoru do formátu Mobile 3D Graphics. Pro modelování scény jsem použila Autodesk 3ds Max[vi], který od verze 2008 umí naexportovat scénu do M3G. Jedinou možností pořízení Autodesku 3ds Max je zkušební verze dostupná po dobu 30 dnů. Existuje také 3D editor Blender[vii], který je zcela zdarma, ale nemá bohužel zabudovaný konvertor do M3G. Konvertor je také dostupný [viii], ale občas při importu modelu nefunguje správně s texturami. Poslední věcí, kterou by vývojář mohl potřebovat je M3GViewer[ix]. Je to program volně ke stažení, který slouží pro zobrazení struktury scény v formátu *.m3g. Umožňuje vybrat a uložit jakoukoli část scény do samostatného souboru pro další použiti ve vlastním programu.
4.7.2. Píšeme aplikaci v Retained Mode Nyní napíšeme triviální aplikaci, ve které bude rovina po níž lze chodit a zobrazíme animovaný objekt. Nejprve potřebujeme vymodelovat 3D scénu a naexportovat ji do M3G. Vymodelovala jsem Windows Logo, které je umistěno na texturované rovině. 33
Obrázek 4.9.. Scéna v 3ds Max.
Exportovaný soubor najdeme ve složce ..\Documents\3dsMaxDesign\export. Potřebujeme ho přenést do složky \JavaMESDKProjects\NazevProjektu\res\res. Složka \res je umistěna ve všech externích souborech, které budeme načítat do naší aplikace. Přidání složky do našeho projektu: -
pravým tlačítkem myši klikneme na složku Resources v okně našeho projektu v otevřeném okně vybereme složku \res, kterou jsme vytvořili výše tato složka a soubory v ní se musí zobrazit v okně Projects ve složce Resources.
Retained Mode programování začiná s nastavením třídy MIDlet. MIDlet spustí Canvas (plátno) kde bude naše grafika vykreslena. Canvas zavolá metodu paint( ) a provede všechny inicializované operace. Načítání naší scény (World) provede metoda Load. Tato metoda vždy vrátí pole Object3D: try { Object3D[] buffer = Loader.load("/res/mymap.m3g"); for(int i = 0; i < buffer.length; i++) { if(buffer[i] instanceof World) {
34
zWorld = (World)buffer[i]; break; } } buffer = null;
Vytvoříme světlo a přidáme ho do grafu scény: Light zLight = new Light(); zLight.setMode(Light.AMBIENT); // Ambientní světlo zLight.setIntensity(10.0f);// Přidáme intenzitu zWorld.addChild(zLight); //Přidáme do Světa v grafu scény
Nyní bychom chtěli přidat do aplikace nějakou aktivitu, umožnit aplikaci pohybovat se ve scéně. Proto je třeba rozbalit kameru ze Světa(World) pomocí getActiveCamera(). To nám vrátí kameru, kterou jsme naexportovali v souboru *.m3g. zCamera = zWorld.getActiveCamera();
Dále naučíme kameru pohybu a otáčení: if(zKey[LEFT]) {camRotation += 5.0f;} else if(zKey[RIGHT]) {camRotation -= 5.0f;} zCamera.setOrientation(camRotation, 0.0f, 1.0f, 0.0f); // Výpočet trigonometrie pro pohyb kamery double radians = Math.toRadians(camRotation); camAngleSin = Math.sin(radians); camAngleCos = Math.cos(radians);
// Nastavíme orientaci
if(zKey[UP]) // Krok dopředu { zCamera.translate(-2.0f*(float)camAngleSin, 0.0f, -2.0f*(float)camAngleCos);} else if(zKey[DOWN]) // Krok dozadu {zCamera.translate(2.0f*(float)camAngleSin, 0.0f, 2.0f*(float)camAngleCos);} if(zKey[FIRE]) RModeMidlet.die(); // stisknutím tlačítka FIRE, se MIDlet zastaví
Přidáme animaci Windows Logo. Potřebujeme najít objekt Logo ve scéně za použití metody find( ): Mesh zLogo = (Mesh) zWorld.find(45); zLogo.postRotate(-2.0f, 0.5f, 0.5f, 1.0f);
Metoda find() hledá objekt Logo podle jeho ID ve scéně, zjistit ID nám pomůže M3GViewer. Pro rendering se využívá nejvýkonnější třída Graphics3D. Zde probíhá veškeré vykreslování a řízení uvedené operace: zGraphics3D = Graphics3D.getInstance(); zGraphics3D.bindTarget(graphics); zGraphics3D.render(zWorld); zGraphics3D.releaseTarget();
Celý postup renderingu se provádí ve 4 krocích: 1. Vytvoření Graphics3D objektu 2. Spojení (bind) 2D grafického objektu pomocí spojení Graphics3D objektu a 2D bufferu 3. Vyrenderování objektů 4. Uvolnění (release) grafického objektu - tento krok je obráceným krokem 2.
35
Posledním krokem bude vytvoření vlákna (Thread s metodou run( )), které bude volat metodu repaint(): Thread myThread = new Thread(this); zRunning = true; zDone = false; myThread.start(); // Start /** Run, spustí celé vlákno. */ public void run() { while(zRunning) { try { // Volá metodu process(počítá klíče(keys) vstupní data z kláves) process(); // Kreslíme všechno draw(getGraphics()); flushGraphics(); Mesh zLogo = (Mesh) zWorld.find(45); zLogo.postRotate(-2.0f, 0.5f, 0.5f, 1.0f); repaint(); try { Thread.sleep(30); } // Sleep, aby se zabránilo vyčerpání zdrojů catch(Exception e) {} } catch(Exception e) { e.printStackTrace();} } zDone = true; // oznámí dokončení }
Obrázek 4.10.. Výsledek příkladu na M3G Retained Mode.
36
5. Praktické využítí knihoven 2 5.1. Začínáme s OpenGL ES Na obě verze OpenGL ES (1.x a 2.x) lze pohlížet jako na samostatné knihovny, a to z toho důvodu, že každá verze byla vyvinuta z různých verzí Open GL.
Obrázek 5.1. : hierarchie vývoje OpenGL ES.
OpenGL ES 1.1 zdůrazňuje hardwarovou akceleraci API. Tato verze knihovny poskytuje rozšířenou funkcionalitu, lepší kvalitu obrazu a optimalizace pro zvýšení výkonu tím, že sníží využití paměťové propustnosti (memory bandwith) z důvodu úspory energie. Open GL ES 1.1 implementuje fixed function pipeline, to znamená, že lze nastavit různé parametry, jako je pozice světla, barva, atd., ale nelze řešit jak bude vypočítána barva každého pixelu. Oproti tomu OpenGL ES 2.0 implementuje programmable graphics pipeline, což umožňuje napsání vlastních programů shaderu (shader programms), které vypočítají barvy pixelu. OpenGL ES 2.0 se skládá ze dvou specifikací: OpenGL ES 2.0 API Specification a OpenGL ES Shading Language Specification (OpenGL ES SL). Verze 2.0 není zpětně kompatibilní s verzí OpenGL 1.1.
37
5.2. OpenGL ES a Windows Mobile OpenGL ES není Windows Mobile API, a to z důvodu obchodní výhody, protože Microsoft podporuje vlastní DirectX API. Existují ale mobilní zařízení, která mají zabudovanou podporu OpenGL ES, např. HTC (modely: Touch HD, HD2, Diamond, Touch Pro), Toshiba, Acer. Na různých zařízeních jsou tedy podporovány různé verze OpenGL ES. Mezi nimi má např. HTC HD2 podporu obou verzi (1.1 a 2.0) a běží na Windows Mobile 6.*. V případě zařízení, které nemá zabudovanou hardwarovou podporu OpenGL ES 2.0, neexistuje jiné řešení. U verze OpenGL 1.1 je možné přidat softwarovou implementaci knihovny pomocí open source knihovny – Vincent[x]. Tato knihovna přichází s funkcí správy oken, a tím umožňuje snadné a rychlé nastavení aplikace. Pro správu oken a řízení lze připojit knihovnu GLUT ES; analog GLUT pro OpenGL pouze pro menší zařízení.
5.3. Nastavení prostředí Pro vývoj aplikace Windows Mobile je potřeba následující: -
Microsoft Visual Studio 2005/2008[xi] Windows Mobile 6 SDK Tools (professional – podporuje displeje Touch, zahrnuje Emulator, výběr závisí na cílovém zařízení)[xii] Microsoft .NET Compact Framework 3.5[xiii] Implementace OpenGL ES Z výše uvedených postupně nainstalujeme první tři programy. Jedná se o běžné instalace systému Windows.
38
Obrázek 5.1. : Start Page Visual Studio 2008.
Nyní je důležitý krokem výběr verze OpenGL ES k programování. Pro OpenGL ES 1.1 je potřeba: - Vincent 3D Rendering Library (UG nebo GLUT ES[xiv] pro okno OpenGL) - nebo PowerVR OpenGL ES 1.1 SDK[xv], jiná implementace OpenGL ES 1.1 - Obyčejný WM emulátor (který již existuje v WM 6 SDK) Pro OpenGL ES 2.0: - PowerVR SGX OpenGL ES 2.0 SDK[xv] - ARM OpenGL ES 2.0 Emulator[xvi] - nebo AMD OpenGL ES 2.0 Emulator (osobně tento emulátor používám, bohužel nyní již není podporován AMD, jedinou možností je stažení poslední verze od vývojářů)
5.3.1. Výběr správné verze
OpenGL ES 2.0 představuje mocné prostředí pro vývoj vysoce kvalitní grafiky, což je umožněno díky programovatelné API, o to je ovšem komplikovanější. Největším problémem jsou nedostatečně podporované emulátory pro vývoj na WM. V dnešní době se pouze PowerVR SDK umí připojit k bežnému WM emulátoru, a to jen pro OS Windows Mobile Standart 6.1. Podmínkou je podpora OpenGL 2.0 grafickou kartou počitače. Obdobně fungují také PC emulátory od AMD a ARM. Tyto emulátory běží na většině grafických karet Radeon a Nvidia, ovšem ne na Intelu. OpenGL ES 1.1 je více příjemná k programování, její syntaxe se příliš neliší od OpenGL 1.*. Tato verze prohrává s ES 2.0 v kvalitě grafiky, ale má tu výhodu, že je lépe přenositelná, protože lze její podporu doplnit knihovnou Vincent 3D Rendering Library. Z toho důvodu byla jako přiklad v této bakalářské práci zvolena verze OpenGL ES 1.1 se zmíněnou knihovnou.
5.3.2. Instalace Vincent 3D Rendering Library K instalaci je potřeba stáhnout Vincent 3D a GLUT ES včetně knihovny GLU ES. Rozbalíme archivy a postupně nakopírujeme soubory pro umístění do SDK, a to v následujícím pořadí: - všechny soubory ze složky ArchivVincent/include/ do sdk/PocketPC/Include/Armv4i - všechny soubory kromě libGLES_CM.dll ze složky ArchivVincent /bin/arm/Debug/ do /sdk/PocketPC/Lib/Armv4i - všechny soubory kromě libGLES_CM.dll ze složky ArchivVincent/bin/emu/Release do /sdk/PocketPC/Lib/Emulator - všechny soubory ze složky GLUTES/Inc do sdk/PocketPC/Include/Armv4 - všechny soubory ze složky GLUES do sdk/PocketPC/Include/Armv4 39
-
stáhneme zkompilovanou knihovnu glutes_static.lib pro ARM CPU zde[xvii] a aktualizujeme tento soubor ve složce SDK/PocketPC/Lib.
5.4. New project a nastavení emulátoru Vytvoříme nový projekt: File→New→Project. V otevřeném okně vybereme Visual C++ → Smart Device → Win32 Smart Device Project a zadáme název projektu:
Obrázek 5.2. : Visual Studion 2008 , wizard nového projektu
Pokračujeme dále (Next). V dalším okně je třeba zvolit platformu pro práci, např. Windows Mobile 6.0 Professional SDK:
40
Obrázek 5.3. : VS2008 , wizard nového projektu, výber SDK
Stiskněte Next a dostanete do posledního okna Wizardu, kde výberte Windows application:
Obrázek 5.4. : VS2008 , wizard nového projektu, výber typu aplikaci
41
Vytvoří se šablonový projekt, který je třeba ještě nastavit pro emulátor. V horní části Visual Studio se lze podívat pro jaké zařízení emulátor běží:
Obrázek 5.5. : VS2008 , nový projekt.
Spustíme Debug(F5) a naběhne emulátor s prázdným oknem:
Obrázek 5.6. : Emulator WM SDK 6 Proffesional
42
Nastavíme sdílenou složku mezi emulátorem a PC: Výběr File→ Configure → ukázání cesty k Shared Folder:
Obrázek 5.7. : vlastnosti Emulatoru
-
Do nové sdílené složky nakopírujeme soubory libGLES_CM.dll ze složky ArchivVincent/bin/arm/Debug, a glutes.dll ze složky glutes-1.11\Lib\ppcarmv4rel
V posledním kroku je nutné přenést všechny soubory ze sdílené složky do složky Windows na zařízení. Na emulátoru proto otevřeme Start→File Explorer→My Device→Storage Card:
Obrázek 5.6. : File explorer Emulatoru
43
Složka bude prázdná. Soubory typu .dll jsou obvykle skryté. Stiskneme Menu → Show All Files a zobrazí se všechny soubory. Vybereme soubory a přeneseme je do složky Windows emulátoru. Zařízení je nyní připraveno k programování.
5.5. Programování v OpenGL ES 1.1 V následující části bude probrána aplikace, která zobrazí rotujucí krychli, texturovanou a umístěnou tak, aby připomínala logo Windowsu. V aplikaci bude možné přepínat světla, zapnout mlhu a přepínat průhlednost objektu. Vytvoříme nový prázdný projekt a přidáme nový soubor main.cpp Na počátku je vždy nutné připojit knihovny, které budeme používat: #pragma comment(lib, "libGLES_CM.lib") #include
#include #include
Provedeme inicializaci okna GLUT: bool init(){ glClearColor(0.0f, 0.0f,0.0f); //nastavení černé barvy pro Clear return true; } //třída inicializace void display(){}
// slouží k vykreslování všeho na displeje
int main(int argc, char*argv[]) //funkce main { glutInit(&argc, argv); // inicializování knihovny GLUT glutCreateWindow("Test OpenGL ES 1.0 - Vincent"); // vytvoření okna glutDisplayFunc(display); // funkce display if(!int()) return); glutMainLoop();‘ return 0; }
Aplikace zatím představuje jen prázdné okno a nemá žádnou funkčnost. Nyní napíšeme funkci, která bude číst vstup z klávesnice. Tato funkce bude brát za parametry key(klavesa) a pozici (x,y) v době, kdy bylo tlačítko stisknuto: void keyboard(int key, int x, int y) { switch(key) // stisknutím tlačítka dolů se aplikace zastaví { case GLUT_KEY_DOWN : exit(0); break; } // stisknutím tlačítka dolů se aplikace zastaví }
Dále nadefinujeme menu s jednou nabidkou: void myMenu(int menuItem)
44
{ switch(menuItem) { case 1 : exit(0); break; } }
Poté vytvoříme Menu v třídě main a přidáme k němu nabídku „Quit― glutCreateMenu(myMenu); glutAddMenuEntry("Quit", 1);
Menu bude vyvoláno po stisknutí levého tlačítka myši: glutAttachMenu(GLUT_LEFT_BUTTON);
V dalším kroku nastavíme matici pohledu ve funkci display(). Tato funkce musí následovat vždy po glLoadIdentity(): gluLookAtf( 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);
Ve funkci init() nastavíme světla, materiály, textury a průhlednost. OpenGL ES nabízí 4 typy světel: ambientní, difúzní, zrdcadlově odražené a vyzářené. Přidat světla a materiály do scény lze následujícími řádky kódu: GLfloat lightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; // nejprve se nadefinují vlastnosti světla GLfloat mAmbient [] = { 0.8f, 0.8f, 0.8f, 1.0f }; // a materiály
glEnable(GL_BLEND); // míchání barev v obrazu glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_LIGHTING); //světla glEnable(GL_LIGHT0); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mAmbient); glDisable(GL_DEPTH_TEST); // vypne se houbkové testování glDepthFunc(GL_LEQUAL);
V této verzi existují dva typy stínování: GL_SMOOTH a GL_FLAT. FLAT nemá žadné stínování, objekty mají jednu barvu po celému tvaru. U SMOOTH má každý vrchol vlastní barvu a celková barva objektu je interpolována. glShadeModel(GL_SMOOTH);
Všechna primitiva v OpenGL ES se kreslí pomocí pole VertexArray a jejich umístění a formát dat určuje glVertexPointer. Těchto VertexArray může být mnoho, proto umí OpenGL ES aktivovat jedno nebo více nutných polí příkazem glEnableClientState(). Pro krychli máme nadefinovaných 24 vrcholů a 24 souřadnic textury. Všechna pole budou definována způsobem popsaným výše, krychle bude nakreslena pomocí pole DrawArrays s hodnotou GL_TRIANGLE_STRIP.
45
glVertexPointer(3, GL_FLOAT, 0, box); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDrawArrays(GL_TRIANGLE_STRIP, 4, 4); glDrawArrays(GL_TRIANGLE_STRIP, 8, 4); glDrawArrays(GL_TRIANGLE_STRIP, 12, 4); glDrawArrays(GL_TRIANGLE_STRIP, 16, 4); glDrawArrays(GL_TRIANGLE_STRIP, 20, 4);
Vykreslování glDrawArrays lze přenést do samostatné funkce, a poté ji pouze volat pro kreslení. Celé pole glDrawArrays je zabaleno do funkce draw*Box, kde * zodpovídá za různé barvy krychle. Funkce draw*Box je volána v display(). Každá z krychlí má jinou barvu a je odlišně trasformovaná, proto musí být při volání zapsaná v následující konstrukci: glPushMAtrix(); glPopMAtrix();
např.: glPushMatrix(); glScalef(0.5f, 0.5f, -0.5); glRotatef(rotation, 0.0f, 1.0f, 0.0f); glTranslatef(0.4f, 0.0f, 0.0f); glRotatef(30, 0.0, 0.0, 1.0); drawBoxYellow(); glPopMatrix();
Hodnota rotation představuje úhel otočení kolem osy Y této krychle. Animace je zde implementována pomocí funkce idle(), která dynamicky zvyšuje úhel (rotation): void idle() {rotation += 6.0f; glutPostRedisplay();}
Posledním krokem zde musí být oznámení knihovny GLUT o funkci idle: glutIdleFunc(idle);
46
Výsledek:
47
Obrázek 5.7. : příklad OpenGL ES běžící na emulatoru WM SDK 6 Proffesional
48
Závěr Cílem této práce bylo prozkoumat všechny možné 3D knihovny pro zařízení s Windows Mobile. Byly popsány knihovny OpenGL ES, M3G, X3D a Java3D, internetové technologie WebGL a O3D a novější API XNA. Ve své práci jsem se zaměřila na knihovny OpenGL ES a M3G. Tyto standardy se velmi dobře uvedly na trhu. Každá z uvedených knihoven má odlišné vlastnosti. Jedna je lepší v tom, druhá v onom. Z vybraných knihoven nelze zvolit vítěze. M3G byl v minulosti dobrým standardem, v dnešní době ovšem díky konkurenci mezi vysokoúrovňovými API spíše zaostává. Přesto je M3G stále podporován většinou mobilních aplikací. OpenGL ES je dobrou API a rychle se šířícím standardem. Velká množina dnešních knihoven je postavena nad touto knihovnou. Obě její verze jsou od sebe odlišné. První verze je v praxi jednodušší, druhá je mnohem silnejší, ale také náročnější na implementaci. XNA je něco nového a odlišného. Je to pokus Microsoftu o vlastní výtvor. Tato zařízení jsou však zatím málo distribuovaná. WebGL a O3D taký v rozvojí. Ve druhé části práce jsem vytvořila přesný návod pro programování v uvedených technologiích. Všechny tutoriály jsem osobně napsala a také otestovala. Aplikace OpenGL ES a M3G byly navíc testovány na mém zařízení HTC Touch(Elf) s OS WM 6. Hlavním přínosem mojí práce je vytvoření stručného průvodce knihoven pro vývojáře, kteří zde najdou souhrn knihoven a API podporovaných Windows Mobile zařízeními.
49
Použítá literatura [1] K.Pulli, T.Aarnio, V.Miettinen, K.Roimela, J.Vaarala: Mobile 3D Graphics with OpenGL ES and M3G. Elsevier, 2008. [2] N.Haemel: OpenGL ES: OpenGL on the Small. Chapter. [3] A.Munshi, D.Ginsburg, D.Shreinere: OpenGL ES Programming Guide. Pearson Education 2009. [4] S.Li, J.Knudsen: Beginning J2ME: From Novice to Professional, Third Edition. 2005. [5] C.Petzold: Programming Windows Phone 7. Microsoft Press, 2010. [6] A.Reed: Learning XNA 3.0. O’Reilly Media, 2008. [7] S.Gaidukov: Articles on XNA. [8] Tutorialy a příklady o XNA od Techdays.ru . Dostupné z: < http://www.techdays.ru/> [9] Prispivatelé Wikipedie. Windows Mobile [online]. 2010. [cit. 27. 1. 2010]. Dostupné z: . [10] Prispivatelé Microsoft. Windows Phone [online]. 2010. Dostupné z: [11] Web 3D Consortium [online]. 2010. Dostupné z: [12] Java 3D Graphics, oficialní stranka [online]. 2010. Dostupné z: < http://www.java3d.org/> [13] Extensible 3D: XML Meets VRML. Dostupné z: [14] GapiDraw. Dostupné z: [15] Google Code Labs, O3D. Dostupné z: [16] JSR 184 official pages, Java Community Procces. Dostupné z: [17] Zeus: OpenGL ES Tutrorials Dostupné z: [18] Implemmentace WebGL na nokia N900. Dostupné z: 50
[19] Menneisyys: Java MIDlet bible Dostupné z : <: http://forum.xdadevelopers.com/showthread.php?t=339577>
[20] C.Hofele: 3D graphics for Java mobile devices. [online]. 2005. Dostupné z: < http://www.ibm.com/developerworks/wireless/library/wi-mobile1/ > [21] Všechná loga převzatý z officiálních strankách..
51
Seznam příloh Příloha A – odkázy ke stáažení potřebných souboru pro vývoj Příloha B – zdrojový kod v OpenGL ES 1.1 Příloha C – zdrojový kod v M3G immendiate mode Příloha D – zdrojový kod v M3G retained mode Příloha E – obsah přiloženého DVD
52
Příloha A – odkazy ke stažení potřebných souborů pro vývoj [i]Download JDK, Dostupné z: [ii] Download Active Sync, Dostupné z: [iii]Download Java 2 ME, Dostupné z: [iv] Aplix Jblend MIDlet Manager Dostupné z: [v] TAO Intent MIDlet Manager download URL: http://www.webalice.it/risidoro/intent/Risidoro_Intent_MIDlet_Manager_11.1.7.1036.cab [vi] Autodesk 3ds Max Dostupné z: [vii] Blender Dostupné z: [viii] Blender exporter Dostupné z: [ix] M3GViewer Dostupné z: [x] Vincent library Dostupné z: [xi] Visual Studio Dostupné z: [xii]WM SDK Dostupné z: [xiii] .NET Compact Framework Dostupné z: [xiv] GLUT ES Dostupné z: [xv] PowerVR SDKs. Dostupné z: [xvi]ARM emulator, Dostupné z: < http://www.malideveloper.com/developerresources/tools/opengl-es-20-emulator.php> [xvii] Updatecompiled library glutes_static Dostupné z: 53
Příloha B – zdrojové kody programování v OpenGL ES 1.1: main.cpp #pragma comment(lib, "libGLES_CM.lib") #define GLUTES_STATIC #include #include #include GLuint texture[1]; //Angle of rotation float rotation = 0.0f; /// Array of vertices to draw box. GLfloat box[] = { /* Front face. */ -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, /* Back face. */ -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, /* Left face. */ -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, /* Right face. */ 0.5f, -0.5f, -0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, /* Top face. */ -0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, /* Bottom face. */ -0.5f, -0.5f, 0.5f, -0.5f, -0.5f, -0.5f, 0.5f, -0.5f, 0.5f, 0.5f, -0.5f, -0.5f, }; /// Array of texture coordinates to be used on box. GLfloat texCoords[] = { // Front 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Back 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Left 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f,
54
// Right 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, // Top 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, // Bottom 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f }; GLfloat lightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f }; GLfloat mAmbient [] = { 0.8f, 0.8f, 0.8f, 1.0f }; unsigned char *loadBMP(char *filename, BITMAPINFOHEADER *bmpInfo) { FILE *file; BITMAPFILEHEADER bmpFile; unsigned char *bmpImage = NULL; unsigned char tmpRGB; TCHAR path[256]; char fullPath[256]; GetModuleFileName(NULL, path, 256); TCHAR *pos = wcsrchr(path, '\\'); *(pos + 1) = '\0'; wcstombs(fullPath, path, 256); strcat(fullPath, filename); file = fopen(fullPath,"rb"); if (!file) { MessageBox(NULL, L"Can't Find Bitmap", L"Error", MB_OK); return NULL; } fread(&bmpFile,sizeof(BITMAPFILEHEADER),1,file); if (bmpFile.bfType != 0x4D42) { MessageBox(NULL, L"Incorrect texture type", L"Error", MB_OK); fclose(file); return NULL; } fread(bmpInfo,sizeof(BITMAPINFOHEADER),1,file); fseek(file,bmpFile.bfOffBits,SEEK_SET); bmpImage = new unsigned char[bmpInfo->biSizeImage]; if (!bmpImage) { MessageBox(NULL, L"Out of Memory", L"Error", MB_OK); delete[] bmpImage; fclose(file);
55
return NULL; } fread(bmpImage,1,bmpInfo->biSizeImage,file); if (!bmpImage) { MessageBox(NULL, L"Error reading bitmap", L"Error", MB_OK); fclose(file); return NULL; } for (unsigned int i = 0; i < bmpInfo->biSizeImage; i+=3) { tmpRGB = bmpImage[i]; bmpImage[i] = bmpImage[i+2]; bmpImage[i+2] = tmpRGB; } fclose(file); return bmpImage; }
bool loadTextures() { BITMAPINFOHEADER info; unsigned char *bitmap = NULL; bitmap = loadBMP("texture.bmp", &info); if (!bitmap) return false; glGenTextures(1, texture); glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, info.biWidth, info.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, bitmap); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); delete[] bitmap; return true; } bool init() { if (!loadTextures()) { MessageBox(NULL, L"Error loading textures", L"Error", MB_OK); return false; } glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0);
56
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mAmbient); glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient); glDisable(GL_DEPTH_TEST); glDepthFunc(GL_LEQUAL); glClearColor(0.1f, 0.1f, 0.1f, 0.0f); //glClearColor(0.5f, 0.5f, 0.5f, 1.0f); glClearDepthf(1.0f); glVertexPointer(3, GL_FLOAT, 0, box); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glShadeModel(GL_SMOOTH); return true; } /// draw Red cube void drawBoxRed(){ glEnable(GL_TEXTURE_2D); glColor4f(1.0f, 0.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, glDrawArrays(GL_TRIANGLE_STRIP, 4, glDrawArrays(GL_TRIANGLE_STRIP, 8, glDrawArrays(GL_TRIANGLE_STRIP, 12, glDrawArrays(GL_TRIANGLE_STRIP, 16, glDrawArrays(GL_TRIANGLE_STRIP, 20, } /// draw Blue cube void drawBoxBlue(){ glColor4f(0.0f, 0.0f, 1.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, glDrawArrays(GL_TRIANGLE_STRIP, 4, glDrawArrays(GL_TRIANGLE_STRIP, 8, glDrawArrays(GL_TRIANGLE_STRIP, 12, glDrawArrays(GL_TRIANGLE_STRIP, 16, glDrawArrays(GL_TRIANGLE_STRIP, 20,
4); 4); 4); 4); 4); 4);
4); 4); 4); 4); 4); 4);
} /// draw Green cube void drawBoxGreen(){ glColor4f(0.0f, 1.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, glDrawArrays(GL_TRIANGLE_STRIP, 4, glDrawArrays(GL_TRIANGLE_STRIP, 8, glDrawArrays(GL_TRIANGLE_STRIP, 12, glDrawArrays(GL_TRIANGLE_STRIP, 16, glDrawArrays(GL_TRIANGLE_STRIP, 20, } /// draw Yellow cube void drawBoxYellow(){ glColor4f(1.0f, 1.0f, 0.0f, 1.0f); glDrawArrays(GL_TRIANGLE_STRIP, 0, glDrawArrays(GL_TRIANGLE_STRIP, 4, glDrawArrays(GL_TRIANGLE_STRIP, 8, glDrawArrays(GL_TRIANGLE_STRIP, 12, glDrawArrays(GL_TRIANGLE_STRIP, 16, glDrawArrays(GL_TRIANGLE_STRIP, 20, } void display() {
57
4); 4); 4); 4); 4); 4);
4); 4); 4); 4); 4); 4);
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAtf( 0.0f, 0.0f, 3.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f); glPushMatrix(); glScalef(0.5f, 0.5f, -0.5); glRotatef(rotation, 0.0f, 1.0f, 0.0f); glTranslatef(-0.6f, 1.0f, 0.0f); glRotatef(30, 0.0, 0.0, 1.0); drawBoxRed(); glPopMatrix(); glPushMatrix(); glScalef(0.5f, 0.5f, -0.5); glRotatef(rotation, 0.0f, 1.0f, 0.0f); glTranslatef(0.3f, 1.0f, 0.0f); glRotatef(30, 0.0, 0.0, 1.0); drawBoxGreen(); glPopMatrix(); glPushMatrix(); glScalef(0.5f, 0.5f, -0.5); glRotatef(rotation, 0.0f, 1.0f, 0.0f); glTranslatef(-0.6f, -0.2f, 0.0f); glRotatef(30, 0.0, 0.0, 1.0); drawBoxBlue(); glPopMatrix(); glPushMatrix(); glScalef(0.5f, 0.5f, -0.5); glRotatef(rotation, 0.0f, 1.0f, 0.0f); glTranslatef(0.4f, 0.0f, 0.0f); glRotatef(30, 0.0, 0.0, 1.0); drawBoxYellow(); glPopMatrix(); glFlush (); glutSwapBuffers(); } void idle() { rotation += 6.0f; glutPostRedisplay(); } void keyboard(int key, int x, int y) { switch(key) { case GLUT_KEY_DOWN : exit(0); break; } } void reshape(int width, int height) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, width, height); gluPerspectivef(45.0f, 1.0f * width / height, 1.0f, 100.0f); glMatrixMode(GL_MODELVIEW);
58
glLoadIdentity(); } void myMenu(int menuItem) { switch(menuItem) { case 1 : exit(0); break; default: break; } } float fogColor[] = { 0.5f, 0.5f, 0.5f, 1.0f }; int onFog = 0; void fogsMenu(int menuItem){ glFogfv(GL_FOG_COLOR, fogColor); glFogf(GL_FOG_DENSITY, 0.3); glFogf(GL_FOG_MODE, GL_EXP); if(onFog != 1){ glEnable(GL_FOG); onFog = 1; } else{ glDisable(GL_FOG); onFog = 0; } } void lightsMenu(int menuItem){ if (glIsEnabled(GL_LIGHTING)) glDisable(GL_LIGHTING); else glEnable(GL_LIGHTING); } void blendingMenu(int menuItem){ if (glIsEnabled(GL_BLEND)) { glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); } else { glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); } } int main(int argc, char *argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutCreateWindow("Test OpenGL ES 1.0 - Vincent"); int fogMenu; int lightMenu; int blendMenu; if (!init()) return 1; glutDisplayFunc(display); glutReshapeFunc(reshape);
59
glutSpecialFunc(keyboard); glutIdleFunc(idle); lightMenu = glutCreateMenu(lightsMenu); glutAddMenuEntry("ON/OFF", 1); blendMenu = glutCreateMenu(blendingMenu); glutAddMenuEntry("ON/OFF", 1); fogMenu = glutCreateMenu(fogsMenu); glutAddMenuEntry("ON/OFF", 1); glutCreateMenu(myMenu); glutAddSubMenu("Blending", blendMenu); glutAddSubMenu("Light", lightMenu); glutAddSubMenu("Fog", fogMenu); glutAddMenuEntry("Quit", 1); glutAttachMenu(GLUT_LEFT_BUTTON); glutMainLoop(); return 0; }
60
Příloha C – zdrojové kody programování v M3G: immediate mode package ImmediateMode; /* * Tento program testuje vlasnosti M3G * MIDlet pro M3G Immediate Mode * * Obsahuje hlavní třidu IModeMidlet * Tato třida vytvoři Aplikaci a nastaví časovač pro spuštění */ import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.util.*; /** * @author Rymzhan Bayekeyeva * */ public class IModeMidlet extends MIDlet { static IModeMidlet midlet; IModeCanvas displayable = new IModeCanvas(); Timer xTimer = new Timer(); /** * Konstruktor midlet */ public IModeMidlet() { IModeMidlet.midlet = this; } /** * Hlavní metoda */ public void startApp() { Display.getDisplay(this).setCurrent(displayable); xTimer.schedule( new MyTimerTask(), 0, 40 ); } /** * pozastavení MIDletu */ public void pauseApp() { } /** * ničení MIDletu */ public void destroyApp(boolean unconditional) { } /** * zastavení MIDletu */ public static void quitApp() { midlet.destroyApp(true); midlet.notifyDestroyed(); midlet = null; } /** * Časovač timer task for providing animation */ class MyTimerTask extends TimerTask {
61
public void run() { if( displayable != null ) { displayable.repaint(); } } } } package ImmediateMode; /* * Tento program testuje vlasnosti M3G * Canvas pro M3G Immediate Mode * * Obsahuje class IModeCanvas, který provádí všechny operaci s grafikou. * * Rotujucí krychle * Probrané vlastnosti: * Světla, Mlha, Material, Textura, Načitání Obrazu... */ import import import import import import import import import import import import import import import
javax.microedition.lcdui.*; javax.microedition.m3g.Graphics3D; javax.microedition.m3g.Appearance; javax.microedition.m3g.Camera; javax.microedition.m3g.Background; javax.microedition.m3g.Light; javax.microedition.m3g.Image2D; javax.microedition.m3g.Material; javax.microedition.m3g.Texture2D; javax.microedition.m3g.Transform; javax.microedition.m3g.TriangleStripArray; javax.microedition.m3g.VertexBuffer; javax.microedition.m3g.IndexBuffer; javax.microedition.m3g.VertexArray; javax.microedition.m3g.Fog;
/** * @author Rymzhan Bayekeyeva * aplikace pro bakalařskou práci "Grafické knihovny pro Windows Mobile" */ public class IModeCanvas extends Canvas { private Graphics3D private Camera private Light private float private Transform private Background private VertexBuffer texcoords private IndexBuffer strips private Appearance private Material // private Fog private Image
xGraphics3D; xCamera; xLight; xAngle = 0.0f; xTransform = new Transform(); xBackground = new Background(); xVertexBuffer; // positions, normals, colors, xIndexBuffer;
// indices to iVB, forming triangle
xAppearance; // material, texture, compositing, ... xMaterial = new Material(); xFog = new Fog(); xImage, xBackImage;
62
/** * Konstrutor Displayable. * Displayable - objekt, který má schopnost být uvedeni na displeji. */ public IModeCanvas() { // nastavuje Displayable naslouchat příkazy události(events) setCommandListener(new CommandListener() { public void commandAction(Command c, Displayable d) { if (c.getCommandType() == Command.EXIT) { // exit MIDlet IModeMidlet.quitApp(); } } }); try { init(); } catch(Exception e) { e.printStackTrace(); } } /** * Initialization komponent. */ private void init() throws Exception { // add the Exit command addCommand(new Command("Exit", Command.EXIT, 1)); // get the singleton Graphics3D instance xGraphics3D = Graphics3D.getInstance(); // vytvorime kameru xCamera = new Camera(); xCamera.setPerspective( 60.0f, (float)getWidth()/ (float)getHeight(), 1.0f, 1000.0f ); // field of view // aspectRatio // near clipping plane // far clipping plane // vytvorime svetlo xLight = new Light(); xLight.setColor(0xffffff); // xLight.setIntensity(1.5f);
// // //
// case SPOT: xLight.setMode(Light.SPOT); xLight.setSpotAngle(20.0f); xLight.setIntensity(2.0f);
// //
// case AMBIENT: xLight.setMode(Light.AMBIENT); xLight.setIntensity(2.0f);
// //
// case OMNI: xLight.setMode(Light.OMNI); xLight.setIntensity(2.0f); // case DIRECTIONAL: xLight.setMode(Light.DIRECTIONAL);
63
xLight.setIntensity(1.0f);
// nastavime pozadi xBackImage = Image.createImage( "/res/texBackground.jpg" ); // vytvorime objekt Image2D Image2D backImage = new Image2D( Image2D.RGB, xBackImage ); //xBackground.setColor(0xffffcc); // barva pozadi xBackground.setImage(backImage); // Krychle se kresli pomoci Triagle_Strips. // // 1 * * * * * 0 // * * * // * * * // * * * // 3 * * * * * 2 short[] vertices = { 7, 7, 7, -7, 7, 7, 7,-7, 7, -7,-7, 7, // front -7, 7,-7, 7, 7,-7, -7,-7,-7, 7,-7,-7, // back -7, 7, 7, -7, 7,-7, -7,-7, 7, -7,-7,-7, // left 7, 7,-7, 7, 7, 7, 7,-7,-7, 7,-7, 7, // right 7, 7,-7, -7, 7,-7, 7, 7, 7, -7, 7, 7, // top 7,-7, 7, -7,-7, 7, 7,-7,-7, -7,-7,-7 // bottom }; VertexArray vertArray = new VertexArray(vertices.length / 3, 3, 2); vertArray.set(0, vertices.length/3, vertices); //normaly byte[] normals = { 0, 0, 127, 0, 0,-127, -127, 0, 0, 127, 0, 0, 0, 127, 0, 0,-127, 0, };
0, 0, 127, 0, 0,-127, -127, 0, 0, 127, 0, 0, 0, 127, 0, 0,-127, 0,
0, 0, 127, 0, 0,-127, -127, 0, 0, 127, 0, 0, 0, 127, 0, 0,-127, 0,
0, 0, 127, 0, 0,-127, -127, 0, 0, 127, 0, 0, 0, 127, 0, 0,-127, 0
VertexArray normArray = new VertexArray(normals.length / 3, 3, 1); normArray.set(0, normals.length/3, normals); // souradnice textury short[] texPvertex = { 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, };
1, 1, 1, 1, 1, 1,
0, 0, 0, 0, 0, 0,
1, 1, 1, 1, 1, 1
VertexArray texArray = new VertexArray(texPvertex.length / 2, 2, 2); texArray.set(0, texPvertex.length/2, texPvertex); // delka kazdeho triangle strip
64
int[] stripLen = { 4, 4, 4, 4, 4, 4 }; // vytvorime VertexBuffer pro nas objekt VertexBuffer vb = xVertexBuffer = new VertexBuffer(); vb.setPositions(vertArray, 1.0f, null); // unit scale, zero bias vb.setNormals(normArray); vb.setTexCoords(0, texArray, 1.0f, null); // unit scale, zero bias // vytvorime index buffer pro nas objekt (to nam rika jak // vytvorit triangle strips z vertex bufferu). xIndexBuffer = new TriangleStripArray( 0, stripLen ); // nacitame obrazek textury xImage = Image.createImage( "/res/texture.png" ); Image2D image2D = new Image2D( Image2D.RGB, xImage ); // vytvorime Texture2D Texture2D texture = new Texture2D( image2D ); texture.setFiltering(Texture2D.FILTER_NEAREST, Texture2D.FILTER_NEAREST); texture.setWrapping(Texture2D.WRAP_CLAMP, Texture2D.WRAP_CLAMP); texture.setBlending(Texture2D.FUNC_MODULATE);
//vytvorime Mlhu //xFog.setMode(Fog.EXPONENTIAL); //xFog.setDensity(0.05f); //xFog.setColor(0x6688FF); // pale blue tint //xFog.setMode(Fog.Linear); //xFog.setLinear(0.0, 10.0);
// vytvorime Appearance xAppearance = new Appearance(); //xAppearance.setFog(xFog); xAppearance.setTexture(0, texture); xAppearance.setMaterial(xMaterial); xMaterial.setColor(Material.DIFFUSE, 0xFFFFFFFF); xMaterial.setColor(Material.SPECULAR, 0xFFFFFFFF); xMaterial.setShininess(100.0f); } /** * * Metoda paint() vykresli krychli a rotuje ji */ protected void paint(Graphics g) { xGraphics3D.bindTarget(g, true, Graphics3D.DITHER | Graphics3D.TRUE_COLOR); xGraphics3D.clear(xBackground); Transform transform = new Transform(); transform.postTranslate(0.0f, 0.0f, 30.0f); xGraphics3D.setCamera(xCamera, transform); xGraphics3D.resetLights(); xGraphics3D.addLight(xLight, transform); xAngle += 1.0f;
65
xTransform.setIdentity(); xTransform.postRotate(xAngle, 1.0f, 1.0f, 1.0f); xGraphics3D.render(xVertexBuffer, xIndexBuffer, xAppearance, xTransform); xGraphics3D.releaseTarget(); } }
66
Příloha D – zdrojové kody programování v M3G: retained mode package RetainedMode; /* * Tento program testuje vlasnosti M3G * MIDlet pro M3G Retained Mode * * Obsahuje hlavní třidu RModeMidlet * */ import import import import import import
javax.microedition.lcdui.Command; javax.microedition.lcdui.CommandListener; javax.microedition.lcdui.Display; javax.microedition.lcdui.Displayable; javax.microedition.midlet.MIDlet; javax.microedition.midlet.MIDletStateChangeException;
/** * @author Rymzhan Bayekeyeva * */
public class RModeMidlet extends MIDlet implements CommandListener { private Display xDisplay = null; // A variable that holds the unique display private RModeCanvas xCanvas = null; // canvas private static MIDlet xSelf = null; // sam MIDlet
/** * Volana pri spusteni aplikace * */ protected void startApp() throws MIDletStateChangeException { xDisplay = Display.getDisplay(this); xCanvas = new RModeCanvas(); //listener xCanvas.setCommandListener(this); // Start Canvas xCanvas.start(); xDisplay.setCurrent(xCanvas); // Set self xSelf = this; } /** Called when the game should pause, such as during a call */ protected void pauseApp(){}
67
/** Called when the application should shut down */ protected void destroyApp(boolean unconditional) MIDletStateChangeException { // Method that shuts down the entire MIDlet notifyDestroyed(); }
/** Listens to commands and processes */ public void commandAction(Command c, Displayable d) { // If we get an EXIT command we destroy the application if(c.getCommandType() == Command.EXIT) notifyDestroyed(); } /** Static method that quits our application * by using the static field 'self' */ public static void die() { xSelf.notifyDestroyed(); } } package RetainedMode; /* * Tento program testuje vlasnosti M3G * Canvas pro M3G Retained Mode * * Obsahuje class RModeCanvas, který provádí všechny operaci s grafikou. * * 3D svet.m3g: Logo Windows, texturovana rovina, a pozadi background * * pouzit GameCanvas, pro rizeni klavesami na mobilnim zarizeni * */ import javax.microedition.lcdui.Graphics; import javax.microedition.lcdui.game.GameCanvas; import javax.microedition.m3g.Camera; import javax.microedition.m3g.Graphics3D; import javax.microedition.m3g.Light; import javax.microedition.m3g.Loader; import javax.microedition.m3g.Object3D; import javax.microedition.m3g.Transform; import javax.microedition.m3g.World; import javax.microedition.m3g.Mesh; //import javax.microedition.m3g.Fog;
public class RModeCanvas extends GameCanvas implements Runnable { // Thread boolean zRunning = false; boolean zDone = true; public static boolean zEnd = false; // pokud hra konci
68
throws
boolean[] zKey = new boolean[5]; // pole Key,vstupni klice klavesnici // konstanty Key public static final int FIRE = 0; public static final int UP = FIRE + 1; public static final int DOWN = UP + 1; public static final int LEFT = DOWN + 1; public static final int RIGHT = LEFT + 1; Transform zIdentity = new Transform(); // Matice Identity Graphics3D zGraphics3D = null; // objekt Graphics3D World zWorld = null; // objekt World- Svet //
Fog zFog = null; //Mlha Camera zCamera = null; // objekt Kamera // Camera rotation float camRotation = 0.0f; double camAngleSin = 0.0f; double camAngleCos = 0.0f;
/** Konstruktor canvas */ public RModeCanvas() { super(true); setFullScreenMode(true);// nastavime fullscreen canvas loadWorld();// nacteni world loadCamera();// nacteni camera }
public void sizeChanged(int newWidth, int newHeight){}
/** * nacita kameru */ private void loadCamera() { // pokud svet neni nacten, nemuze se nacist kamera if(zWorld == null) return; // get kamera s nacteneho sveta zCamera = zWorld.getActiveCamera(); //vytvorime svetlo Light zLight = new Light(); zLight.setMode(Light.AMBIENT);//AMBIENT zLight.setIntensity(10.0f);// intenzita zareni // pridame svetlo k svetu zWorld.addChild(zLight); }
/** * nacitani sveta(World) */ private void loadWorld()
69
{ try { Object3D[] buffer = Loader.load("/res/mymap.m3g"); for(int i = 0; i < buffer.length; i++) { if(buffer[i] instanceof World) { zWorld = (World)buffer[i]; break; } } // vycisti buffer buffer = null; } catch(Exception e) { e.printStackTrace();// ERROR! } }
/** * Kreslime na obrazovku */ private void draw(Graphics g) { try { moveCamera();// pochyb kamerou zGraphics3D = Graphics3D.getInstance(); zGraphics3D.bindTarget(g); zGraphics3D.render(zWorld); } catch(Exception e) { e.printStackTrace(); } finally { // release VZDY! zGraphics3D.releaseTarget(); } }
/** * pochyby kamerou action */ private void moveCamera() { if(zKey[LEFT]) {camRotation += 5.0f;} else if(zKey[RIGHT]) {camRotation -= 5.0f;} zCamera.setOrientation(camRotation, 0.0f, 1.0f, 0.0f); // Vypocet trigonometrie pro pochyb kamery
70
double radians = Math.toRadians(camRotation); camAngleSin = Math.sin(radians); camAngleCos = Math.cos(radians); if(zKey[UP]) { // Krok dopredu zCamera.translate(-2.0f*(float)camAngleSin, 2.0f*(float)camAngleCos); } else if(zKey[DOWN]) { // Krok dozadu zCamera.translate(2.0f*(float)camAngleSin, 2.0f*(float)camAngleCos); }
0.0f,
-
0.0f,
// stisknutím tlačitka FIRE, MIDlet se zastaví if(zKey[FIRE]) RModeMidlet.die(); }
/** * Spusti canvas vypoustenim vlakna */ public void start() { Thread myThread = new Thread(this); zRunning = true; zDone = false; myThread.start();// Start }
/** Run, spusti cele vlakno */ public void run() { while(zRunning) { try { // Volá metodu process(počítá klíče(keys)) vstupni data z klaves) process(); // Kreslíme všechno draw(getGraphics()); flushGraphics(); Mesh zLogo = (Mesh) zWorld.find(45); zLogo.postRotate(-2.0f, 0.5f, 0.5f, 1.0f); repaint(); // Sleep aby se zabránilo vyčerpání zdrojů try { Thread.sleep(30); } catch(Exception e) {} } catch(Exception e) { e.printStackTrace(); } } // oznami dokonceni
71
zDone = true; } /** Pozastavi se hra */ public void pause() {} /** Stopne se hra */ public void stop() { zRunning = false; } /** Process key(vstupni data z klaves) */ protected void process() { int keys = getKeyStates(); if((keys & GameCanvas.UP_PRESSED) != 0) zKey[UP] = true; else zKey[UP] = false; if((keys & GameCanvas.DOWN_PRESSED) != 0) zKey[DOWN] = true; else zKey[DOWN] = false; if((keys & GameCanvas.RIGHT_PRESSED) != 0) zKey[RIGHT] = true; else zKey[RIGHT] = false; if((keys & GameCanvas.LEFT_PRESSED) != 0) zKey[LEFT] = true; else zKey[LEFT] = false; if((keys & GameCanvas.FIRE_PRESSED) != 0) zKey[FIRE] = true; else zKey[FIRE] = false; } /** Kontroluje bezi li vlakno */ public boolean isRunning() { return zRunning; } /** Kontroluje jestli vlakno zcela dokoncilo nabehani. */ public boolean isDone() { return zDone; }}
72
Příloha E –
obsah priloženého DVD
DVD priložené k této bakalářské práci obsahuje slozky: text - je tam text ve fotmatu PDF Img—všechná obrazky Src – zdrojové kody downloads – potřebné programy k instalaci
73