PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITY PALACKÉHO KATEDRA INFORMATIKY
DIPLOMOVÁ PRÁCE
Grafický model zahrady ve 3D
2010
Petr Šebesta
Anotace Práce se zabývá vytvořením aplikace, umožňující graficky navrhnout zahradu, prohlížet ji 2D i 3D pohledem, editovat ji a následně zahradu vytisknout, v technologii Windows Presentation Foundation. Se zaměřením na vytvoření 3D scény srovnává použitou technologii Windows Presentation Foundation s technologií OpenGL.
Děkuji všem, kteří přispěli připomínkou či podnětem k výsledné podobě této práce. Zvláště pak vedoucímu diplomové práce RNDr. Peteru Sebestyénovi, Ph.D.
Obsah 1. Motivace
8
2. Úvod
8
3. Technologie WPF 3.1. Role WPF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2. Vlastnosti WPF . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3. Viewport3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4. Definice 3D objektu . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.1. Positions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.2. TriangleIndices . . . . . . . . . . . . . . . . . . . . . . . . 3.4.3. Normals . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.4.4. TextureCoordinates . . . . . . . . . . . . . . . . . . . . . . 3.4.5. Příklad definice 3D objektu . . . . . . . . . . . . . . . . . 3.5. Transformace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.5.1. Změna velikosti, posunutí . . . . . . . . . . . . . . . . . . 3.5.2. Rotace . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6. Světlo a stínování . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.6.1. Všesměrové světlo - AmbientLight . . . . . . . . . . . . . . 3.6.2. Směrové světlo - DirectionalLight . . . . . . . . . . . . . . 3.6.3. Bodové světlo, reflektor - PointLight, SpotLight . . . . . . 3.6.4. Stínování - Shading . . . . . . . . . . . . . . . . . . . . . . 3.7. Kamera . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.8. Materiály a textury objektů . . . . . . . . . . . . . . . . . . . . . 3.8.1. Štětec - Brush . . . . . . . . . . . . . . . . . . . . . . . . . 3.8.2. Difuzní materiál - DiffuseMaterial . . . . . . . . . . . . . . 3.8.3. Zrcadlící materiál - SpecularMaterial, Emisní materiál EmissiveMaterial, Skupina materiálů - MaterialGroup . . .
8 8 9 9 10 11 11 11 12 12 13 13 14 14 15 15 15 15 16 17 17 17
4. Technologie OpenGL 4.1. Role a vlastnosti OpenGL . . . 4.2. Definice 3D objektu . . . . . . . 4.3. Transformace . . . . . . . . . . 4.4. Světlo a stínování . . . . . . . . 4.4.1. Druhy světelných zdrojů 4.4.2. Druhy stínování . . . . . 4.5. Kamera . . . . . . . . . . . . . 4.6. Materiály a textury . . . . . . .
19 19 19 20 21 22 22 22 23
4
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
. . . . . . . .
18
5. Porovnání technologií 5.1. Vytváření grafické scény . 5.2. Transformace . . . . . . . 5.3. Kamery . . . . . . . . . . 5.4. Světelné modely . . . . . . 5.5. Texturování a materiály . 5.6. Další odlišnosti technologií
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
24 24 25 25 25 26 26
6. Aplikace 3D Zahrada
27
7. Programátorská dokumentace 7.1. Použité technologie . . . . . . . . . . . . . . . . . . . . 7.2. Objektová hierarchie System.Windows.Media.Media3D 7.3. Datová vrstva . . . . . . . . . . . . . . . . . . . . . . . 7.3.1. Třída DataManager.cs . . . . . . . . . . . . . . 7.3.2. Datové soubory . . . . . . . . . . . . . . . . . . 7.3.3. Nastavení aplikace . . . . . . . . . . . . . . . . 7.4. Logická vrstva . . . . . . . . . . . . . . . . . . . . . . . 7.4.1. Třída GUIManager.cs . . . . . . . . . . . . . . 7.5. Prezentační vrstva . . . . . . . . . . . . . . . . . . . . 7.5.1. Hlavní okno aplikace . . . . . . . . . . . . . . . 7.5.2. Další okna aplikace . . . . . . . . . . . . . . . . 7.5.3. Reprezentace grafických objektů . . . . . . . . .
. . . . . . . . . . . .
28 28 28 30 30 31 31 31 31 33 33 37 37
. . . . . . . . . . . .
38 38 38 38 40 41 41 42 42 43 44 44 44
8. Uživatelská dokumentace 8.1. Požadavky, instalace a spuštění aplikace 8.2. Hlavní okno aplikace . . . . . . . . . . . 8.2.1. Menu . . . . . . . . . . . . . . . . 8.2.2. Menu objektů zahrady . . . . . . 8.2.3. Zobrazení zahrady . . . . . . . . 8.3. Vrstvy . . . . . . . . . . . . . . . . . . . 8.4. Zaharady . . . . . . . . . . . . . . . . . 8.5. Tisk . . . . . . . . . . . . . . . . . . . . 8.6. Parametry objektu zahrady a manipulace 8.7. Číselník rostlin . . . . . . . . . . . . . . 8.8. Nastavení kamery a pozice kamery . . . 8.9. Nápověda . . . . . . . . . . . . . . . . .
. . . . . . . . s . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . objekty . . . . . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . .
Závěr
46
Conclusions
47
Reference
48
5
I. Popis obsahu přiloženého DVD
49
6
Seznam obrázků 1. 2. 3. 4. 5. 6.
Hlavní okno aplikace . . . . . . . Parametry objektu . . . . . . . . Číselník rostlin . . . . . . . . . . Prvek zobrazení pozice a natočení Tlačítka nastavení kamery . . . . Okno nápovědy aplikace . . . . .
7
. . . . . . . . . . . . . . . kamery . . . . . . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
. . . . . .
39 43 44 45 45 45
1.
Motivace
Cílem této práce bylo vytvoření aplikace sloužící k návrhu, editaci, uchování a tisku modelu zahrady v technologii Windows Presentation Foundation (WPF). Aplikace nebyla vytvořena jako konkurentní aplikacím zabývajících se modelováním zahrady v prostoru. Je chápána jako výzkum možností technologie WPF v oblasti vytváření 3D modelů a dalších aspektech při vytváření aplikace s danými požadavky. Významnou součástí práce je také část zabývající se popisem technologie WPF a srovnáním technologie WPF s odlišně zaměřenou technologií pro vytváření 3D scény - technologií OpenGL. Porovnání bylo směřováno na podstatné části nutné pro vytvoření 3D scény.
2.
Úvod
Vytvoření modelu zahrady v třídimenzionálním prostoru lze jistě realizovat mnoha způsoby s rozličnými úrovněmi složitosti. Náročnost ztvárnění by měla odpovídat účelu, ke kterému je model vytvořen. V této práci, která se zabývá vytvořením aplikace umožňující zobrazení zahrady z různých úhlů pohledu (2D i 3D) pomocí technologie WPF a srovnáním 3D aparátu této technologie s jiným aparátem pro vytvoření 3D, jsem se snažil o naplnění předchozí věty. Práce by měla čtenáři poskytnout informace jak lze aplikaci v této technologii vytvořit a v určitých bodech přinést srovnání s odlišnou technologií.
3.
Technologie WPF
Windows Presentation Foundation (WPF) je grafický subsystém pro vytváření uživatelských rozhraní v aplikacích založených na platformě Windows. WPF nabízí konzistentní programovací model pro vytváření aplikací a poskytuje oddělení vrstvy uživatelského rozhraní od aplikační logiky. Pro definici uživatelského rozhraní disponuje deklarativním značkovacím jazykem XAML, který vznikl na základě XML. WPF obsahuje aparát pro práci s 2D a 3D grafikou, animacemi, vazbou dat, audiem, atd. V tomto textu se budeme, jak již bylo zmíněno výše, zabývat aparátem pro 3D grafiku. Při vytváření této části textu bylo čerpáno nejvíce z [4], dále pak z [1, 2, 3]. Demonstrační příklady budou prezentovány pomocí jazyka XAML. Ovšem stejného výsledku lze dosáhnout i použitím jazyka C# či některého dalšího jazyka z rodiny .NET.
3.1.
Role WPF
Technologie WPF není určena pro vývoj 3D her, ani pro modelování impozantních 3D scén. WPF poskytuje možnost integrace 3D grafiky do klientských aplikací. Tyto možnosti jsou například vhodné pro modelovaní jednodušších 3D 8
scén. WPF je postaveno na technologii DirectX, což přináší hardwarovou podporu vektorového vykreslování.
3.2.
Vlastnosti WPF
V této kapitole jsou popsány některé třídy technologie WPF, které slouží pro modelování 3D scény.
3.3.
Viewport3D
Viewport3D je prvek, ve kterém je samotná 3D scéna modelována. Má vestavěnou podporu pro obsluhu událostí z myši a klávesnice. Ve vlastnosti Children prvku Viewport3D je uložena kolekce objektů typu ModelVisual3D, která 3D scénu tvoří. Definice prvku Viewport3D modelujícího jednoduchou 3D scénu by mohla vypadat následovně:
<ModelVisual3D> <ModelVisual3D.Content> ... <ModelVisual3D> <ModelVisual3D.Content> Viewport3D v příkladu obsahuje definici jednoho 3D objektu, definici světla a kamery. Jednotlivé složky jsou podrobněji rozebrány v textu níže. Na příkladu je také vidět, že světlo je modelováno také jako 3D objekt. Prvek Viewport3D může obsahovat pouze jednu kameru, pokud je potřeba vícenásobný pohled na scénu, je nutno použít více prvků typu Viewport3D. Světelné zdroje prvku Viewport3D osvětlují všechny objekty ve scéně. Pokud požadujeme osvětlit nějaké prvky jiným světelným zdrojem, musíme opět použít více prvků typu Viewport3D. 9
3.4.
Definice 3D objektu
Obvykle v 3D počítačové grafice je objekt reálného světa (tvar) reprezentován polygoniální sítí skládající se z polygonů, což je vlastně množina bodů v prostoru uspořádaná do daného tvaru. Se složitostí objektu roste počet polygonů a bodů v něm obsažených. Ve WPF je základním polygonem pro modelování objektů trojúhelník. Složitější objekty jsou modelovány pomocí základních polygonů (trojúhelníků). Objekt jako celek je definován třídou ModelVisual3D. Obsahuje informace o tom, jakou má objekt geometrii, a také informace o transformaci objektu. ModelVisual3D představuje objekt, který má definovanou vizuální podobu a může být vykreslen na obrazovku. GeometryModel3D poskytuje ModelVisual3D geometrii, podle níž se ModelVisual3D vykresluje. Pokud objekt ModelVisual3D modeluje světlo, geometrie u něj nemusí být definována. Vlastní definice objektu ve 3D pomocí ModelVisual3D může být provedena následujícími způsoby. Buď je definován jen jeden objekt typu ModelVisual3D s kolekcí geometrií: <ModelVisual3D> <ModelVisual3D.Content> <Model3DGroup>
....
<Model3DGroup> <ModelVisual3D.Content> <ModelVisual3D> Nebo je definováno více objektů typu ModelVisual3D a každý s vlastní geometrií: <ModelVisual3D> <ModelVisual3D.Content>
.... <ModelVisual3D> <ModelVisual3D.Content>
Druhý popsaný způsob definice 3D objektů je vhodnější, protože umožňuje na základě polohy kurzoru myši zjistit, který prvek (model) se nachází pod kurzorem. 10
Pokud bychom použili první popsaný postup, s jedním prvkem ModelVisual3D, nebyli bychom poté schopni určit, na kterou jeho část se kliklo. Doporučení tedy zní: objekty 3D scény, se kterými chceme pracovat jako se samostatnými celky, je dobré definovat každý samostatně pomocí třídy ModelVisual3D. Geometrie objektu je ve WPF popsána třídou MeshGeometry3D. Ta má vlastnosti Positions, TriangleIndices, TextureCoordinates a Normals. 3.4.1.
Positions
Vlastnost Positions obsahuje kolekci vrcholů modelovaného objektu. Každý prvek kolekce je tvořený třemi souřadnicemi a popisuje jeden vrchol (bod) v prostoru. 3.4.2.
TriangleIndices
Vlastnost TriangleIndices je tvořena kolekcí trojic čísel, která jsou indexy do kolekce Positions. Počet trojic v kolekci je roven počtu trojúhelníků tvořících objekt. Souřadnice vrcholu trojúhelníku jsou uloženy v kolekci Positions pod indexem, který je přiřazen danému vrcholu v kolekci TriangleIndices. Uveďme příklad definice trojúhelníku, jehož vrcholy jsou určeny prvním, druhým a třetím bodem v kolekci Positions: <MeshGeometry3D Positions="0 0 0, 0 1 -1, 0 0 -2" TriangleIndices="0 1 2" /> Na pořadí indexů v TriangleIndices záleží. Aby byl trojúhelník korektně vykreslen musí pořadí indexů splňovat tzv. righ hand rule. Nabízí se otázka, zda není zbytečné takto reprezentovat objekty. Nepostačoval by jen jeden seznam vrcholů pro každý trojúhelník? Postačoval, v praxi ovšem systém používaný ve WPF (tedy použití dvou kolekcí) umožňuje sdílení jednoho vrcholu více trojúhelníky. Takto je docíleno úspory kódu při definici objektu. 3.4.3.
Normals
Vlastnost Normals obsahuje kolekci vektorů. Každý obsažený vektor představuje normálu vrcholu trojúhelníku, která ovliňuje velikost odraženého světla od trojúhelníku (více v kapitole 3.7). Pro každý vrchol v kolekci Position je definována jeho normála v kolekci Normals. U vektorů v kolekci Normals jsou jejich délky při výpočtu ignorovány, důležitý je jen jejich směr. Vlastnost Normals nemusí být explicitně zadána, WPF vypočítá normály vrcholů automaticky. Normála vrcholu je vypočtena interpolací normál povrchů trojúhelníků, ve kterých je daný vrchol použit (sdílen). Vrchol trojúhelníku je sdílen tolikrát, kolikrát je
11
jeho index uveden v kolekci TriangleIndices. Například, pokud je index daného vrcholu v TriangleIndices třikrát, je tento vrchol sdílen třemi trojúhelníky. Normála vrcholu je poté vypočtena jako průměr tří normál povrchů těchto trojúhelníků. Ovšem je zde i jedno proti u sdílení vrcholů trojúhelníků. V případě že nechceme, aby byla hrana objektu vyhlazena, například u krychle či kvádru, nemůžeme použít sdílení vrcholů. Míra odraženého světla vrcholem je totiž závislá na počtu trojúhelníků, které se v tomto vrcholu setkávají. Jsou-li vrcholy definovány odděleně, je vrchol vždy součástí jen jednoho trojúhelníku. Jsou-li ovšem vrcholy sdíleny, je jeden vrchol součástí více trojúhelníků, a výsledné světlo je počítáno jako průměr normál povrchů trojúhelníků sdílejících tento vrchol. To má za následek vyhlazení hran. Pokud nechceme hrany vyhlazovat, nesmíme sdílet vrcholy trojúhelníků, které nejsou ve stejné rovině. Vlastnost Normals u takového objektu nemusíme definovat. Pokud chceme hrany vyhlazovat nebo chceme vytvořit kulatý povrch, musíme sdílet vrcholy všech trojúhelníků, jejichž normály povrchů chceme do normály vrcholu zahrnout. U takového objektu musíme definovat vlastnost Normals. 3.4.4.
TextureCoordinates
Vlastnost TextureCoordinates je typu kolekce 2D bodů (nikoli 3D bodů). Jelikož povrch objektu je definován 2D souřadnicemi, je nutno definovat mapování z 2D souřadného systému povrchu do 3D souřadného systému, kterým je definován 3D objekt. A toto mapování popisuje vlastnost TextureCoordinates. Jak již bylo napsáno, souřadnice vrcholu trojúhelníku se určí aplikováním jeho indexu z kolekce TriangleIndices na kolekci Position obsahující souřadnice všech vrcholů objektu. A stejný index z kolekce TriangleIndices je použit pro získání 2D souřadnic povrchu. Pokud jsou v kolekci Position definovány stejné body vícekrát, můžeme každému z nich přiřadit jiný bod v kolekci TextureCoordinates. 3.4.5.
Příklad definice 3D objektu
Na závěr této sekce uveďme příklad kompletní definice 3D objektu. Pro každý vrchol určený souřadnicemi je definována normála upravující dopadající světlo na objekt. Objekt je pokryt texturou z difuzního materiálu se specifikovanými pozicemi textury pro každý vrchol. Vrcholy trojúhelníku jsou sdíleny. <ModelVisual3D> <ModelVisual3D.Content>
12
<MeshGeometry3D x:Name="PovrchMeshGeometry" Normals="0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1 0,0,1" Positions="0,0,-6 0,58,-6 35,29,-6 70,58,-6 70,0,-6" TriangleIndices="0 2 1 1 2 3 3 2 4 4 2 0" TextureCoordinates="0 1, 0 0, 0.5 0.5, 1 0, 1 1">
3.5.
Transformace
Transformaci můžeme chápat jako změnu, která je aplikována na každý prvek kolekce - například na každý prvek kolekce Positions třídy MeshGeometry3D, která popisuje geometrii objektu. Ve skutečnosti se hodnoty v kolekci Positions nezmění, ale transformace modifikuje body použité k vykreslení objektu. Transformaci definuje abstraktní třída Transform3D. Ve jmenném prostoru System.Windows.Media.Media3D jsou tři třídy definující vlastnost Transform typu Transform3D. Jsou to třídy Camera, Model3D a ModelVisual3D. Třída Camera je abstraktní třídou všem třídám reprezentujícím kameru. Model3D je rodičovskou třídou pro GeometryModel3D, Light a Model3DGroup. ModelVisual3D je třída reprezentující vykreslitelný objekt scény. Transformace může být tedy ve WPF aplikována na samostatný model objektu (geometrii objektu), světlo, kolekci modelů objektů, kameru a vykreslitelný objekt scény. Nastavením transformace pro objekt typu ModelVisual3D ji aplikujeme na všechno co ModelVisual3D obsahuje. To může být samostatný objekt, kolekce objektů, nebo objekty dohromady se světly. Může také obsahovat potomky typu ModelVisual3D. Uvažujeme-li definici transformace u objektů typu GeometryModel3D, Model3DGroup, ModelVisual3D a Camera, bylo by pořádí prováděných transformací následující. Nejprve je aplikována na prvek GeometryModel3D, poté je aplikována transformace pro skupinu Model3DGroup. Pokračuje se aplikací u prvku typu ModelVisual3D a jako poslední je aplikována transformace u prvku typu Camera. Transformace se aplikují dle stromové hierachie tříd zdola nahoru (hierarchie tříd je uvedena v kapitole 7). 3.5.1.
Změna velikosti, posunutí
Z objektové hierarchie je také patrné, že transformace pro posun, změnu velikosti a rotaci jsou afinní transformace. Naopak maticové transformace re13
prezentovány typem MatrixTransform3D nejsou ve WPF chápány jako afinní. Podotkněme ještě, že perspektivní projekce, která je promítána kamerou PerspectiveCamera, není afinní transformací a ortografická projekce realizována kamerou OrtographicCamera afinní transformací je. Uveďme příklad transformace: <ModelVisual3D.Transform>
<ScaleTransform3D ScaleX="3.56" ScaleY="2.93" ScaleZ="1"/> Příklad ukazuje aplikaci kolekce transformací Transform3DGroup, která slouží k zapouzdření více transformací. Kolekce obsahuje transformaci změny měřítka (ScaleTransform3D) o zadané hodnoty ScaleX, ScaleY a ScaleZ a transformaci posunutí (TranslateTransform3D) o hodnoty OffsetX, OffsetY a OffsetZ. Na pořadí aplikace jednotlivých transformací záleží, kombinování transformací odpovídá totiž násobení matic a to obecně není komutativní. Pokud bychom zaměnili pořadí transformací v kolekci, dostali bychom obecně jiný výsledek. 3.5.2.
Rotace
U transformace rotace (RotateTransform3D) je možné určit její střed, t.j. bod, který při provádění rotace zůstane na stejném místě a rotaci, která je typu Rotation3D. Z objektové hierarchie je patrné, že do Rotation3D může být přiřazen typ AxisAngleRotation3D nebo QuaternionRotation3D. AxisAngleRotation3D představuje rotaci kolem paralelní osy definované vektorem směru rotace a úhlem rotace. QuaternionRotation3D je alternativní možností pro definování rotací v 3D prostoru. Následuje příklad definice rotace kolem osy Z o úhel 90 stupňů.
3.6.
Světlo a stínování
3D scéna obyčejně vyžaduje světlo. Světlo je jedním ze základních prvků tvořících 3D scénu. WPF nabízí několik drůhů světel.
14
3.6.1.
Všesměrové světlo - AmbientLight
Nejzákladnějším typem světla je AmbientLight. Toto světlo osvětluje všechny objekty ve scéně stejnoměrně a nevytváří žádné stíny. Výchozí hodnota ambientního bílého světla může být změněna na jinou barvu. Povrch objetku odrazí ambientní světlo v případě, že barva povrchu obsahuje jako svou složku barvu ambientního světla. Například je-li barva povrchu objektu modrozelená a barva ambientního světla červená, nebude žádné světlo odraženo. 3.6.2.
Směrové světlo - DirectionalLight
Druhým typem světla je DirectionalLight. Stejně jako světlo ambientní má definovanou barvu a navíc, jelikož jde o světlo směrové, i vektor směru. Výchozí hodnota směrového vektoru je (0,0,-1). Směrové (DirectionalLight) dopadá na povrch objektu pod určitým úhlem α. Množství odraženého světla je úměrné hodnotě sin α, kde α je úhel, pod kterým dopadá světlo na porvch objektu. Pokud bychom uvažovali za objekt rovinu, směrové světlo dopadá na všechny body této roviny pod stejným úhlem. 3.6.3.
Bodové světlo, reflektor - PointLight, SpotLight
Jde o světla, která jsou umístěna blíže k cíli než světla zmíněná výše. PointLight představuje světlo, které žárovka vyzařuje do všech směrů. Má pevně určenou pozici v prostoru a na rovný povrch dopadají jeho paprsky pod různým úhlem. SpotLight také vyzařuje paprsky, které dopadají na rovný povrch pod různým úhlem, ale paprsky tvoří kužel - nejsou vyzařovány do všech směrů. Má též určenou pozici v prostoru a navíc směr, kterým je světlo natočeno. 3.6.4.
Stínování - Shading
Vzájemné působení světla s objektem vytváří jev zvaný stín. Stínovací algoritmy implementované ve WPF využívají normály (normals) definované u prvku MeshGeometry3D, který definuje geometrii objektu. Normály nezaměňujme s normálovými vektory. Normálový vektor je vektor s velikostí rovnou jedné, kdežto normála je vektor, který je kolmý na plochu (v našem případě na plochu trojúhelníku). Normála určuje, jak povrch odrazí dopadající směrové (directional) světlo. Procento odraženého světla difuzního materiálu je rovno − cos α, kde α je úhel, který svírá normála trojúhelníku a vektor dopadajícího směrového světla (Lambertovo pravidlo intenzity světla). S výše popsaným systémem stínování nelze vytvořit modely s kulatým povrchem, protože při použití jedné normály povrchu by byl celý povrch (trojúhelník) stínován stejnoměrně. To by způsobovalo zobrazení hran. Tento problém WPF řeší použitím Gouraudova stínování. Trojúhelníky sice zůstávají ploché, ale různé části trojúhelníku odrážejí světlo rozdílně. To vytváří dojem zaoblených povrchů. Pro více trojúhelníků můžeme pro sousední vrcholy 15
definovat stejné normály. To vytvoří dojem zaobleného povrchu. Nebo definovat pro sousední vrcholy různé normály a tím hranu mezi nimi zvýraznit. Princip Gouraudova stínování je následující. Pro každý vrchol trojúhelníku je definována normála vrcholu. Pro každou normálu vrcholu (vertex normal) se spočítá hodnota − cos α, kde α je velikost úhlu, který svírá normála a vektor směrového světla. Osvětlení každého bodu v trojúhelníku je poté spočítáno jako interpolant. Pro body na hraně je interpolant počítán z vrcholů na koncích hrany. Pro vrcholy uvnitř trojúhelníku je interpolant počítán z dvou bodů na rozdílných hranách.
3.7.
Kamera
Kamera ve 3D reprezentuje pohled na scénu. Perspektivní projekci získáme použitím perspektivní kamery a ortografickou projekci použitím ortografické kamery. WPF umožňuje použití obou typů kamer. Poznamenejme ještě, že perspektivní kamera zobrazí objekt o určité velikosti umístěný blíže kameře větší, než objekt totožné velikosti umístěný dále od kamery. U ortografické kamery nemá velikost vzdálenosti objektu od kamery na jeho zobrazovanou velikost vliv. Prostor zobrazovaný perspektivní kamerou tvoří komolý jehlan a prostor zobrazovaný ortografickou kamerou tvoří kvádr. Způsob jakým lze vytvořit a použít kameru demonstrujeme na příkladu perspektivní kamery:
Kamera musí být umístěna v nějakém bodě 3D prostoru, toto umístění specifikuje vlastnost Position. Po umístění kamery je důležité nastavit směr, kterým bude kamera natočena. Nastavením souřadnic směrového vektoru do vlastnosti LookDirection kamery směr určíme. Tento směrový vektor nemusí být zadán normalizovaný, protože v úvahu je brán pouze směr a ne jeho velikost. Vlastnost UpDirection je vektor a určuje orientaci kamery. Výchozí hodnota je (0,1,0) a specifikuje, že vrch zobrazení je v kladném směru osy Y. Vlastnost FieldOfView vyjadřuje viditelný úhel ve stupních, který kamera zobrazuje. Vyšší hodnota úhlu způsobí, že objekty před kamerou jsou blíže než při nižší hodnotě. Dvojice vlastností FarPlaneDistance a NearPlaneDistance specifikuje interval vzdálenosti od kamery, který bude zobrazen. Hodnota NearPlaneDistance eliminuje objekty s hodnotou vzdálenosti menší a hodnota FarPlaneDistance objekty s hodnotou vzdálenosti větší. 16
Ortografická kamera postrádá vlasnost FieldOfView. Místo ní obsahuje vlastnost Width určující šíři zobrazované scény. Ostatní vlastnosti mají stejný význam jako u perspektivní kamery.
3.8.
Materiály a textury objektů
Obrazec, který je nanesen na povrch tělesa, se nazývá textura a může být vytvořen pomocí různých materiálů. Důležité je, že při nanášení textury není změněna geometrická vlastnost tělesa. U objektů je také rozlišována přední a zadní strana, proto abychom pro ně mohli definovat různé materiály. 3.8.1.
Štětec - Brush
Vzhled povrchu modelovaného 3D objektu tvoří štětec (brush). Štětec nemá určenou svoji velikost, přizpůsobí se objektu, na který je aplikován jako smršťovací fólie obalující nějaký předmět. Štětec i při použití v 3D grafice je definován pomocí čtverce a 2D souřadnicového systému. To znamená že, levý horní roh čtverce má souřadnice (0,0) a pravý dolní roh má souřadnice (1,1). Zvětšujeme-li souřadnici Y, jdeme dolů, což je přesně opačné chování jako ve 3D souřadném systému a může to být matoucí. Pro použití štětce definovaného 2D souřadnicemi na povrchu objektu definovaného vrcholy v 3D souřadném systému musíme popsat jejich vzájemný vztah. To popisuje vlastnost objektu MeshGeometry3D pojmenovaná TextureCoordinates. Vzhled povrchu může být různý. Definovaný může být pouze barvou (SolidColorBrush), barevným přechodem (GradientBrush) nebo vzorkem (DrawingBrush, ImageBrush, Visual Brush). Štětce DrawingBrush, ImageBrush a VisualBrush slouží k definování textur 3D objektů. ImageBrush slouží k pokrytí objektu rastrovým obrázkem, definuje vlastnost ImageSource uchovávající cestu k definovanému rastru. DrawingBrush slouží k pokrytí objektu vektorovým obrázkem, který může obsahovat například elipsy, Bezierovy křivky, atd. VisualBrush umožňuje pokrýt objekt 2D prvkem typu Visual - tedy například tlačítkem, rozbalovacím seznamem, zaškrtávátkem, atd. Prvky textury nejsou funkčními prvky, jde jen o jejich obrázky. 3.8.2.
Difuzní materiál - DiffuseMaterial
Tento materiál je u objektů nejvíce používaný. Má několik vlastností, které ho definují. Ty si nyní představíme. Vlastnost Brush specifikuje vzhled povrchu - více předchozí odstavec. Brush je nejdůležitější vlastnost, pokud by nebyla nastavena, byl by materiál transparentní. Vlastnost Color určuje množství světla, které bude odraženo od směrového světla (DirectionalLight) a vlastnost AmbientColor určuje množství světla odraženého od všesměrového světla (AmbientLight). Vlastnosti Color i AmbientColor představují barvy s výchozí hodnotou bílá. Bílá barva 17
totiž odráží veškeré světlo. Vlastnosti Color a AmbientColor si můžeme představit jako vlastnosti indikující, jaké světlo objekt odrazí a vlastnost Brush můžeme chápat jako filtr, který nechá barvy světla projít nebo je blokuje. Výsledné stínování je totiž podřízeno barvě vlastnosti Brush a úhlu dopadajícího světla. Kdyby měla vlastnost Color hodnotu barvy černou, nebylo by žádné světlo odraženo bez ohledu na hodnotu vlastnosti Brush. V případě, že je hodnota Color nastavena na bílou (výchozí) barvu, je veškeré světlo odraženo a barva objektu závisí plně na vlastnosti Brush. V případě, že máme scénu osvětlenou světly AmbientLight i DirectionalLight, je výsledná barva objektu určena jako součet barvy směrového světla vzhledem k vlastnosti Color materiálu DiffuseMaterial a barvy všesměrového světla vzhledem k vlastnosti AmbientColor materiálu DiffuseMaterial. Výsledná suma je poté ještě filtrována hodnotou vlastnosti Brush. 3.8.3.
Zrcadlící materiál - SpecularMaterial, Emisní materiál - EmissiveMaterial, Skupina materiálů - MaterialGroup
Třída MaterialGroup umožňuje povrch objektu složit z více typů materiálů. Definuje vlastnost Children typu kolekce materiálů. Prvkem této kolekce tedy může být jeden z výše zmíněných materiálů. Podotkněme ještě, že vrstvit materiály typu DiffuseMaterial nemá smysl, pokud alespoň nějaká část materiálu není transparentní. EmissiveMaterial je vytvořený za účelem napodobit povrch, který vyzařuje světlo. Povrch pokrytý tímto druhem materiálu bude mít viditelnou barvu i bez použití jakéhokoliv světla ve scéně. EmissiveMaterial jednoduše přidává jas do objektu pokrytého již materiálem typu DiffuseMaterial. Neznamená to ovšem, že tento objekt bude osvětlovat ostatní objekty ve scéně jako zdroj světla. SpecularMaterial také přidává jas objektu, ale složitějším způsobem. Je vytvořen pro modelování odlesků objektů scény. Objekt pokrytý materiálem typu DiffuseMaterial je zobrazen stejnou barvou bez ohledu na úhel dopadajícího světla. SpecularMaterial je jiný, protože úhel dopadajícího světla ovlivňuje barvu objektu. SpecularMaterial přidá jas objektu (modeluje odlesk), pokud úhel dopadajícího světla na povrch objektu je opačný než úhel, který svírá kamera s normálou povrchu objektu. Použití materiálu typu SpecularMaterial nebo EmissiveMaterial samostatně není vhodné. Oba typy přidávají jas do modelované scény (pokud je to možné, hodnota barvy nepřekročí hodnotu 255). Pokud chceme použít efekt těchto materiálů samostatně, je vhodné je použít s materiálem typu DiffuseMaterial s vlastností Brush nastavenou na černou barvu.
18
4. 4.1.
Technologie OpenGL Role a vlastnosti OpenGL
OpenGL grafická knihovna navržena pro použití s i bez grafického akcelerátoru (softwarová simulace) a její primární zaměření je na real-time grafiku. Je možné ji použít také na různých platformách (narozdíl od Direct3D). Byla navržena s možností využít ji na různých grafických ovladačích a různých správcích oken, z tohoto důvodu neobsahuje funkce pro tvorbu grafického uživatelského rozhraní, práci s okny ani funkce pro zpracování událostí. Pokud bychom nějakou jmenovanou funkčnost požadovali, můžeme využít některou z nadstavbových knihoven OpenGL - například knihovnu GLUT (OpenGL Utility Toolkit) či knihovnu GLU (OpenGL Utility Libary). Chování technologie OpenGL lze přirovnat k chování stavového automatu - stav zůstane nezměněn, dokud není explicitně vyvolána jeho změna. Při vytváření této části textu bylo čerpáno ze zdrojů [5, 6]. Voláním funkcí OpenGL je vykreslen výsledný obraz, který je poté uložen do framebuferu. Zde je mu přiřazena barva, hloubka a další parametry. Z framebuferu je obraz vykreslen na obrazovku. Funkce1 v OpenGL mají vlastní sofistikovanou syntax. Začínají prefixem gl (pro nadstavbovou knihovnu GLUT začínají prefixem glut), poté následuje jméno funkce, číslo vyjadřující počet parametrů a typ parametrů. Knihovna OpenGL pro dosažení nezávislosti používá vlastní datové typy s pevnou bitovou délkou (jména datových také začínají prefixem GL). Použití těchto vlastních datových typů by pro dosažení přenositelnosti mělo být upřednostněno před použitím datových typů zvoleného programovacího jazyka. Příklad volání funkce OpenGL: glVertex3d(d1, d2, d3); Funkce je z knihovny OpenGL (prefix gl), její název je Vertex a má tři parametry typu double. Nastaví souřadnice vrcholu na hodnoty zadané v parametrech.
4.2.
Definice 3D objektu
Modely objektů jsou složeny z grafických primitiv. Grafickým primitivem rozumíme bod - GL POINTS, úsečku - GL LINES, řetězec úseček - GL LINE STRIP, smyčku z úseček - GL LINE LOOP, trojúhelník - GL TRIANGLES, trs trjúhelníků - GL TRIANGLE FAN, pás trojúhelníků - GL TRIANGLE STRIP, čtyřúhelník - GL QUADS, pás čtyřúhelníků - GL QUAD STRIP, konvexní polygon GL POLYGON, bitmapu a pixmapu. Při modelování 3D scény musíme pro každý vrchol grafického primitiva zadat minimálně jeho souřadnice v prostoru, ve skutečnosti 1
Pokud bude v této sekci v příkladu použítí funkce uvedena hvězdička (*), značí to fakt, že tato funkce může být zavolána s různým počtem parametrů nebo s různými typy parametrů.
19
však pro většinu modelů musíme určit barvu vrcholu, normálu a materiál. Zadávání vlastností primitiva vždy začíná voláním funkce glBegin(typ primitiva) a končí voláním funkce glEnd(). Mezi těmito funkcemi definujeme vrcholy modelovaného objektu. Vytvoření grafického primitiva demonstrujeme na příkladu vytvoření trojúhelníku. glBegin(GL_TRIANGLES); glVertex3f( 0.0f, 1.0f, 0.0f); glVertex3f(-1.0f,-1.0f, 0.0f); glVertex3f( 1.0f,-1.0f, 0.0f); glEnd(); Posloupnost příkazů definuje trojúhelník o vrcholech zadaných funkcí glVertex3f. Aplikací transformace na vrcholy grafických primitiv lze objekty rotovat, posouvat či jiným způsobem upravovat. Model objektu je také možné pokrýt texturou a osvětlit různými druhy světla. Grafická primitiva lze podle jejich vlastností rozdělit na body, úsečky a polygony. Primitivu lze nastavit různé vlastnosti podle příslušnosti ke skupině. Bodům můžeme nastavit jejich barvu, velikost a zapnout či vypnout vyhlazování hran bodu (antialiasing). U úseček je možno specifikovat barvu, tloušťku, masku udávající, které části úsečky budou vykresleny a zapnout či vypnout vyhlazování. Polygonům můžeme definovat barvu, mód vykreslení polygonu (vykreslení stran, vrchlolů, hran či vyplněného polygonu), orientaci vrcholů polygonu a vzorek, kterým je polygon pokryt.
4.3.
Transformace
Transformace v OpenGL jsou realizovány transformačními maticemi, které jsou aplikovány na vrcholy grafických primitiv. Nejzákladnějšími maticemi jsou: ModelView matice - obsahuje transformace objektů a nastavení kamery, Projection matice - obsahuje nastavení perspektivní (výřez prostoru snímaného kamerou tvoří komolý jehlan) nebo ortogonální (výřez prostoru snímaného kamerou tvoří kvádr) projekce kamery a Texture matice - použita pro mapování textur na povrch objektů. Zvláštní postavení má matice ViewPort, která se používá k mapování abstraktních souřadnic (po provedení perspektivní projekce) do souřadnic okna. Před provedením transformace musíme nejprve určit matici, na kterou chceme transformaci aplikovat. Změna obsahu příslušné matice je prováděna funkcemi OpenGL. Pro provedení nejčastěji užívaných transformací, mezi které patří rotace, posun a změna měřítka by jsme použili následující funkce: glRotate*(); //rotace, glTranslate*(); //posun, glScale*(); //změna měřítka. 20
Pokud chceme na objekt aplikovat více transformací, použijeme volání více funkcí realizujících požadované transformace. V tomto případě provádíme skládání jednotlivých transformací. Matice těchto transformací budou knihovnou OpenGL vynásobeny a aplikována bude pouze výsledná matice. Toto chování je velmi praktické. Při skládání transformací je nutno dát pozor na pořadí aplikování jednotlivých matic, protože násobení matic není obecně komutativní. Pokud ovšem nechceme transformace skládat, zařídíme to voláním funkce, která do aktuálně zvolené matice nahraje jednotkovou matici. glLoadIdentity(); Transformace jsou aplikovány v opačném pořadí, než jsou volány funkce, které je provádějí. OpenGL obsahuje zásobníky pro uložení transformačních matic - pro každý druh matice zvláštní zásobník. Největší kapacitu má zásobník pro matice typu ModelView - protože je v praxi využívána nejčastěji.
4.4.
Světlo a stínování
Osvětlení v OpenGL je realizováno pomocí Phongova osvětlovacího modelu. Tento model je zvolen pro dosažení kompromisu mezi realističností a rychlostí vykreslení výsledného obrazu. Světlo v OpenGL musíme před použitím globálně zapnout. Světlo v tomto modelu se skládá ze tří světelných složek. Ambientní (ambient) světlo je první složkou. Vzniká odrazem od objektu ve scéně a je všesměrové. Druhou je složka difuzní (diffuse). Představuje světlo, které vzniká ve světelném zdroji. Toto světlo je ovlivněno pozicí objektu a světelného zdroje. Pozice kamery nemá na tuto světelnou složku vliv. Poslední složkou modelu jsou odlesky (specular). Tvoří ji odražené paprsky od povrchu modelu. Celková intenzita světla se skládá z intenzit vypočítaných pro každou barevnou složku světla zvlášť (světlo v Phongově modelu je tvořeno třemi barevnými složkami - R, G, B). Pro výpočet osvětlení je nutné zadat normálu vrcholu. Pokud není normála nastavena je použita implicitní a to normála ve směru osy z. Normála musí být zadána jako normalizovaný vektor a jednu normálu je možné sdílet pro více vrcholů. Uveďme příklad definice normály: glNormal3f(1.0f, 0.0f, 0.0f); Vrcholům je nastavena poslední definovaná normála, dokud není explicitně změněna. V praxi se pro osvětlení používá vzájemná kombinace světelných složek. Při použití všech tří složek světla dostaneme nejrealističtější model. Pokud bychom například použili jen světlo ambientní, 3D objekt scény by se jevil jako plošný. Ve standardu OpenGL lze použít až osm světelných zdrojů současně. U každého světelného zdroje je možno nastavit jeho parametry. 21
4.4.1.
Druhy světelných zdrojů
Bodové světlo je nejjednodušší variantou. Vyzařuje světlo ze zadané pozice do všech směrů se stejnou intenzitou. Druhým typem světla je směrové světlo. Můžeme si ho představit jako světelný zdroj, který vyzařuje paprsky ve specifikovaném směru a je umístěn v nekonečné vzdálenosti od zobrazované scény. Toto světlo nemá danou pozici, při výpočtech je brán v úvahu jen vektor šíření světla. Světlo, které je určeno pozicí a vektorem směru vyzařování světla, je v OpenGL nazýváno reflektorové světlo. Pro toto světlo je také ještě možné zadat úhel šíření světla (spolu s vektorem směru vytvoří světelný kužel), ve kterém intenzita se vzrůstající vzdáleností od zdroje světla postupně klesá. Úhel světla je možné zadat od nuly, kdy je světelný paprsek úzký, do devadesáti, kdy svítí do největšího prostoru. 4.4.2.
Druhy stínování
V OpenGL se nejčastěji používají dva typy stínování. Prvním je konstantní stínování, kdy je pro celé grafické primitivum stanovena jedna barva z barev vrcholů a primitivum je vykresleno touto barvou. Druhým typem je Gouraudovo stínování, kdy grafické primitivum je pokryto přechodem mezi barvami jednotlivých vrcholů primitiva.
4.5.
Kamera
Nastavení kamery lze v OpenGL provést nastavením transformačních matic Projection a ModelView nebo využitím funkcí OpenGL pro práci s kamerou. Funkce glOrtho() nastaví matici Projection pro ortografickou projekci, tj. takovou, kde není zkreslována velikost objektů se vzdáleností od kamery. Parametry funkce určují ořezávací roviny (paralelní s osami souřadného systému) a zobrazovaný prostor poté tvoří kvádr. Příklad volání funkce glOrtho(), kde jednotlivé parametry určují souřadnice ořezávacích rovin: glOrtho(leva, prava, spodni, horni, blizsi, vzdalena); Funkce glFrustrum(), která nastaví perspektivní kameru, tj. takovou, která s rostoucí vzdálenosti objektů od kamery zmenšuje jejich velikost. Parametry funkce určují ořezávací roviny a zobrazovaný prostor poté tvoří komolý jehlan. Příklad volání funkce glFrustrum(): glFrustum(leva, prava, spodni, horni, blizsi, vzdalena); Dalším krokem pro nastavení kamery je určení směru, kterým bude kamera natočena. To lze provést změnou matice ModelView. Lepší je však využít funkce gluLookAt() z nadstavbové knihovny GLU, která poskytuje abstrakci pro změnu matice ModelView. 22
gluLookAt(poziceX, poziceY, poziceZ, bodX, bodY, bodZ, vrchX, vrchY, vrchZ); Parametry poziceX, poziceY a poziceZ určují pozici kamery. Parametry bodX, bodY a bodZ určují bod, kam se kamera dívá. Bod pozice kamery a bod, kam se kamera dívá, nesmí být shodné. Parametry vrchX, vrchY a vrchZ určují souřadnice vektoru, který specifikuje vrch zobrazení. Tento vektor nesmí být rovnoběžný s vektorem vypočítaným mezi pozicí kamery a bodem, kam se kamera dívá. Jelikož funkce pro práci s kamerou ve skutečnosti nastavují transformační matice, je zpravidla nutné před jejich voláním nastavit měněnou matici na jednotkovou voláním funkce glLoadIdentity().
4.6.
Materiály a textury
Povrch objektu v OpenGL tvoří materiál, ten se skládá z textury a vlastností, jak má reagovat na jednotlivé světelné složky použité ve scéně. Pro vytvoření textury převážně používáme rastrové obrázky. Rastrový obrázek je reprezentován primitivem bitmapa (pole bitů s hodnotami 0 nebo 1 signalizující, zda se daný pixel má vykreslit či nikoli) a pixmapa (rastr o barevné hloubce reprezentované více než jedním bitem). Rozměry textury musí být mocninou čísla 2 (například 16x16 pixelů). Dále pro korektní aplikaci textury na objekt je potřeba vytvořit pro danou texturu texturovací objekt a texturu do něj přiřadit. Je potřeba také zapnout texturování pro danou scénu. Jako ve WPF i zde musíme specifikovat, jaká souřadnice textury danému vrcholu objektu přísluší. Každá textura, bez ohledu na její velikost, má souřadnice od 0.0 do 1.0 - tedy v případě 2D textury, textura tvoří čtverec o velikosti 1. Souřadnice textury k danému vrcholu definujeme pomocí následující funkce: glTexCoord*(); Zadání souřadnice textury ke konkrétnímu vrcholu tedy provedeme dvojicí příkazů: glTexCoord*(); glVertex*(); Možné je také nastavovat parametry textury. Definovat můžeme opakování textury na povrchu objektu či roztažení textury. Parametry textury nastavíme následujícím příkazem: glTexParameter*();
23
Materiál na povrchu objektu může mít pro každou složku světla (ambientní, difuzní, odleskovou) nastavenu barvu, na základě níž se materiál ke světelné složce chová. Pokud u materiálu barvu pro jednotlivou složku světla nenastavíme, pak daný materiál na danou složku světla nereaguje, například nezobrazuje odlesky. Funkce, která slouží pro definování vlastností materiálu na povrchu objektu má tvar: glMaterial*();
5.
Porovnání technologií
V této části textu budeme porovnávat principy a možnosti vytváření 3D scény v obou technologiích. Technologie OpenGL byla již použita v mnoha programech a počítačových hrách. Jde o vývojáři hojně používanou grafickou knihovnu. Naopak technologie WPF využívající aparát DirectX je poměrně novou a stále se dynamicky vyvíjející technologií. Použití OpenGL pro náročné aplikace z hlediska 3D grafiky je předpokládané, naopak WPF je určeno pro vytváření méně náročných aplikací. Tento kontrast je právě předmětem srovnání.
5.1.
Vytváření grafické scény
Pro vytvoření kompletního modelu scény je v obou technologiích potřeba specifikovat pozice vrcholů modelovaného objektu, zadat vektory normál příslušné každému vrcholu a specifikovat mapování textury objektu na povrch objektu. Kompletní model scény, jak již bylo v textu uvedeno, je složen z jednodušších objektů - grafických primitiv. WPF nabízí pouze jedno grafické primitivum a to trojúhelník. Naopak OpenGL disponuje více grafickými primitivy. Tento rozdíl se znatelně projeví na velikosti dat potřebných pro reprezentaci složitého 3D objektu. Velikost dat potřebných pro reprezentaci modelu v OpenGL bude díky možnosti složit objekt z více druhů grafických primitiv podstatně menší, než velikost dat potřebných pro reprezentaci modelu ve WPF. WPF nabízí možnost sdílení jedné souřadnice vrcholu více vrcholy 3D objektu. Toto sdílení ovšem není možné aplikovat u každého modelu, protože jejich sdílení má vliv na světelné vlastnosti povrchu objektu. I při využití sdílení bude například obdélník v OpenGL popsán méně daty než ve WPF, protože ve WPF musí být modelován pomocí minimálně dvou trojúhelníků. Definovat modely ve WPF lze dvěma způsoby. Prvním je použití deklarativního jazyka XAML, který je derivátem jazyka XML. Pro příklady technologie WPF v tomto textu byl tento jazyk využit. Druhým způsobem je využití některého jazyka z rodiny .NET. Oba způsoby řešení jsou stejně silné, výrazové schopnosti obou řešení jsou ekvivalentní. OpenGL nabízí pouze jednu možnost a to vytváření modelů pomocí volání funkcí knihovny. 24
5.2.
Transformace
Transformace jsou v obou technologiích realizovány pomocí transformačních matic. Obě technologie poskytují abstrakci v tom smyslu, že například pro posunutí nemusíme zadávat kompletní matici, ale stačí specifikovat jen vektor směru tohoto posunutí. Dále například u změny velikosti stačí specifikovat koeficient změny velikosti pro zvolený rozměr. Při aplikaci více transformací jsou jednotlivé transformační matice mezi sebou násobeny. Násobení matic není obecně komutativní, a proto je potřeba dát pozor na pořadí násobení jednotlivých matic. OpenGL poskytuje pro uchování jednotlivých typů transformačních matic zásobníky. Do nich je možné uložit zvolenou transformační matici, u které předpokládáme, že ji využijeme někdy v budoucnu. Matice, která se vyskytuje na vrcholu zásobníku, je použita k trasformaci. Zásobníky pro jednotlivé typy transformačních matic nejsou neomezené. Největší kapacitu mívá zásobník pro matice typu ModelView, protože ty jsou používány nejčastěji. WPF takovou možnost neposkytuje. Jde ovšem o trochu odlišně orientovanou technologii.
5.3.
Kamery
V obou technologiích je možné používat a nastavovat kamery pro perspektivní i ortografickou projekci. Vždy je nutné definovat ořezávací roviny, pomocí kterých specifikujeme prostor zobrazovaný danou kamerou. Ve WPF jsou k dispozici prostředky k nastavení těchto rovin na vyšší úrovni abstrakce. To odpovídá zaměření WPF, poskytnout programátorovi jednodušší způsob manipulace s 3D scénou, ovšem na úkor propracovaných možností nastavení v OpenGL. Samotná knihovna OpenGL neposkytuje příliš intuitivní nastavení kamer - zvláště perspektivní kamery. Vhodné je použít funkce z nadstavbové knihovny GLU, která poskytuje funkce s intuitivnějším nastavením kamer.
5.4.
Světelné modely
Osvětlovací model ve WPF je založen na Gouraudově stínování. Normála vrcholu je vektor definovaný pro každý vrchol trojúhelníku. Pro každou normálu vrcholu je spočítána hodnota − cos α, kde α je úhel, který svírá normála a vektor směrového světla. Osvětlení každého bodu v trojúhelníku je poté spočítáno jako interpolant. Pro body na hraně je interpolant počítán z vrcholů na koncích hrany. Pro vrcholy uvnitř trojúhelníku je interpolant počítán z dvou bodů na rozdílných hranách. Phongův osvětlovací model, který používá OpenGL provádí výpočet odlišným způsobem. Nejprve je normála vrcholu určena interpolantem přes povrch trojúhelníka a hodnoty cos α mohou být vypočítány až po určení normál vrcholů. Hodnota úhlu α je určena jako úhel mezi vypočtenou normálou a vektorem dopadajícího světla. Phongův osvětlovací model dává lepší výsledky než Gouraudův, 25
ale je výpočetně náročnější.
5.5.
Texturování a materiály
Povrch objektu je v obou případech reprezentován texturou, která tvoří vzhled povrchu, a materiálem, který specifikuje chování povrchu vůči různým světelným zdrojům. Dále je také nutné určit mapování textury na povrch objektu. Ve WPF k tomu slouží vlastnost TextureCoordinates objektu ModelVisual3D, v OpenGL k tomu slouží funkce glTextCoord*(), kterou specifikujeme jaké souřadnice textury se mají mapovat k příslušnému vrcholu objektu. Ve WPF je možné pokrýt objekt texturou vytvořenou z rastrového a vektorového obrázku, nebo pokrýt objekt vzhledem nějakého vizuálního prvku (vizuálním prvkem rozumíme například tlačítko, rozbalovací seznam, posuvník, atd.). OpenGL nabízí širší možnosti pokrytí povrchu objektu texturou. Je možné použít jednodimenzionální, dvoudimenzionální, nebo třídimenzionální textury. Jednodimenziální textura slouží k realizaci barevného přechodu, dvoudimenzionální textury jsou používány k aplikaci bitmap a pixmap na povrch objektu, a třídimenzionální textury, které slouží k zobrazení objemových dat (tyto textury nejsou na běžných dnešních grafických kartách podporované a nalézají využití ve specializovaných aplikacích). WPF i OpenGL umožňují pokrýt objekt materiálem, který reaguje na ambientní složku světla, difuzní složku světla i na složku vytvářející odlesky. Rozdíl můžeme pozorovat ve způsobu definování materiálu objektu. Ve WPF je nutné pro použití povrchu reagujícího na všechny tři složky světla aplikovat na objekt více materiálů umístěných ve skupině. V OpenGL se reakce materiálu na jednotlivé složky světla určuje definováním parametru daného materiálu.
5.6.
Další odlišnosti technologií
Pro korektní vykreslení 3D scény je nutno určit pořadí vykreslování jednotlivých částí objektů. Nejjednodušším řešením je zvolit pořadí vykreslování podle pořadí umístění ve zdrojovém kódu. Toto řešení ovšem nepoužívá ani jedna ze srovnávaných technologií. WPF používá pro určení pořadí vykreslování techniku pojmenovanou malířův algoritmus. Princip spočívá v nalezení nejmenší souřadnice z pro vykreslovanou část a seřazení vykreslovaných částí do seznamu podle této souřadnice. Seznam je poté procházen a první jeho prvek je testován, zda leží za všemi ostatními. Pokud podmínku splňuje je vykreslen a vyjmut ze seznamu. U tohoto způsobu může za jistých podmínek dojít k nejednoznačnostem, které můžeme řešit rozdělením vykreslované části na více částí. OpenGL používá k určení pořadí vykreslování paměť hloubky (depth buffer). Jde o jednorozměrné pole o velikosti zobrazovaného okna. Pokud je kandidátů na vykreslení jednoho
26
bodu na obrazovce více, je každý z nich testován na hloubku (kolmou vzdálenost od projekční roviny), bod, který je nejblíže, bude vykreslen. Paměť hloubky je sofistikovanějším řešením než malířův algoritmus a také nalezne jednoznačné řešení vždy. Opět zde nalézáme spojitost se zaměřením obou technologií.
6.
Aplikace 3D Zahrada
Aplikace 3D zahrada je vytvořena v technologii WPF. Důvodem pro zvolení byla motivace realizovat aplikaci specifikovanou v zadání novou a stále se vyvíjející technologií. WPF není zaměřeno jako konkurenční technologie k OpenGL, je určeno pro vytváření méně náročných 3D aplikací. WPF navíc obsahuje vestavěnou podporu spravování oken a reakci na uživatelské vstupy. Tento fakt byl také důvodem zvolení WPF pro vytvoření aplikace. Architektura aplikace je realizována třívrstvým modelem - datovou, logickou a prezentační vrstvou. Datová vrstva je realizována datovým manažerem, který řídí přístup k datovým souborům. Pro uložení dat byl zvolen formát XML, protože umožňuje snadný přístup k vybrané části z uložených dat a je blízký jazyku XAML, který technologie WPF využívá. Logickou vrstvu reprezentuje GUI manažer, který realizuje výpočty potřebné pro chod aplikace. Prezentační vrstva je tvořena jednotlivými okny a dialogy vytvořenými v jazyce XAML spolu s kódem pro obsluhu událostí vyvolaných na oknech a dialozích. Definice 3D objektu v aplikaci je představována třídou ModelVisual3D. Každý 3D grafický objekt v aplikaci je tohoto typu. Nejprve je definice objektu načtena ze serializované podoby jako řetězec z datového souboru datovým manažerem a poté deserializována do objektu typu ModelVisual3D metodou Load třídy XamlReader. Pro povrch objektů je v aplikaci použit difuzní (diffuse) materiál ve spojení s texturou tvořenou jednou barvou (Brush) nebo texturou vytvořenou z rastrového obrázku (ImageBrush). 3D modely objektů v aplikaci byly převzaty ze zdroje [7] a převedeny do jazyka XAML programem Viewer3ds dostupného na [8]. Transformace - posunutí a zvětšení či zmenšení 3D objektu scény - jsou realizovány pomocí násobení matic. GUI manažer aplikace při realizaci posunutí nebo změny měřítka objektu nejprve zjistí transformační matici objektu a tuto matici vynásobí příslušnou maticí transformace posunu nebo maticí změny měřítka. Výslednou matici poté přiřadí jako transformační matici danému 3D objektu. Pro pohled na scénu aplikace využívá pouze perspektivní kamery. Ortografické kamery v aplikaci využito není. Aplikace má dvě základní nastavení perspektivní kamery. První reprezentuje virtuální prohlídku zahrady a druhé perspektivní pohled na modelovanou zahradu. Při přepnutí mezi jednotlivými nastaveními je měněn směr pohledu kamery definovaný vektorem LookDirection a orientace 27
kamery, kterou určuje vektor UpDirection. V režimu aplikace - 3D virtuální prohlídka - je možné měnit pozici perspektivní kamery, měnit natočení kamery aplikací transformace rotace na perspektivní kameru a měnit směr pohledu změnou vlastnosti LookDirection. Pri virtuální prohlídce i perspektivním pohledu na modelovanou zahradu lze kameru přibližovat a oddalovat od modelované scény. To je zajištěno změnou pozice kamery. Osvětlení modelované 3D scény je realizováno směrovým (directional) světlem bílé barvy a se směrovým vektorem (0, 0, −1). Aplikace byla testována lidmi zabývajícími se návrhem a realizací zahrad a přírodních terénů. Aplikace není konkurenceschopná profesionálním aplikacím pro modelování zahrad. Pokud by aplikace obsahovala více modelů grafických objektů, byla by užitečná pro prezentování zahrad ve finální podobobě (tzn. až všechny rostliny dosáhnou své konečné velikosti).
7. 7.1.
Programátorská dokumentace Použité technologie
Aplikace je vytvořena na platformě .NET. Pro vytvoření uživatelského rozhraní je použito grafického subsystému Windows Presentation Foundation (WPF), který je součástí platformy .NET. Data aplikace včetně modelů 3D objektů jsou uložena v XML souborech. V přístupu k datům je využito technologie LINQ. Zdrojový kód programu je napsán v jazyce XAML a jazyce C#. Deklarativní jazyk XAML je použit pro definování vzhledu aplikace a jazyk C# je využit pro obsluhu uživatelských vstupů a dalších výpočtů v aplikaci. Aplikace byla vytvořena ve vývojovém prostředí Microsoft Visual Studio 2010 s využitím editoru Expression Blend 4.
7.2.
Objektová hierarchie System.Windows.Media.Media3D
Pro lepší orientaci mezi použitými třídami uvedeme objektovou hierarchii jmenného prostoru System.Windows.Media.Media3D, který definuje třídy používané v aplikaci. Object DispatcherObject (abstract) DependencyObject Visual (abstract) UIElement FrameworkElement 28
ViewPort3D Freezable (abstract) Animatable (abstract) Camera (abstract) ProjectionCamera (abstract) PerspectiveCamera (sealed) OrtographicCamera (sealed) MatrixCamera (sealed) Brush (abstract) SolidColorBrush (sealed) GradientBrush (abstract) LinearGradientBrush (sealed) RadialGradientBrush (sealed) TileBrush (abstract) DrawingBrush (sealed) ImageBrush (sealed) VisualBrush (sealed) Model3D (abstract) GeometryModel3D (sealed) Light (abstract) AmbientLight (sealed) DirectionalLight (sealed) PointLightBase (abstract) PointLight (sealed) SpotLight (sealed) Model3DGroup (sealed) Geometry3D (abstract) MeshGeometry3D (sealed) Transform3D (abstract) AffineTransform3D (abstract) TranslateTransform3D (sealed) RotateTransform3D (sealed) ScaleTransform3D (sealed) MatrixTransform3D (sealed) Transform3DGroup (sealed) Rotation3D (abstract) AxisAngleRotation3D (sealed) QuaternionRotation3D (sealed) Material (abstract) DiffuseMaterial (sealed) EmissiveMaterial (sealed) SpecularMaterial (sealed) MaterialGroup (sealed) 29
Visual3D (abstract) ModelVisual3D
7.3.
Datová vrstva
Datovou vrstvu aplikace tvoří třída DataManager.cs. Obsahuje metody pro načítání dat do aplikace a metody pro ukládání dat z aplikace. 7.3.1.
Třída DataManager.cs
Obsahuje instance objektů typu XDocument reprezentující datové soubory a obalující metody umožňující přístup k datům. Následuje popis těchto metod: public List<string> VratNazvyRostlin() Metoda vracející seznam názvů rostlin uložených v datovém souboru s rostlinami. public void UlozRostlinu(string nazevRostliny) Uloží nový název rostliny specifikovaný parametrem nazevRosliny do datového souboru s rostlinami. public void OdstranRostlinu(string nazevRostliny) Odstraní název specifikovaný parametrem nazevRosliny z datového souboru s rostlinami. public IEnumerable<XElement> VratObjektyZahrady(string cesta) Metoda vracející seznam objektů zahrady uložených v souboru, který je určen parametrem cesta. Využívá LINQ. public IEnumerable<XElement> VratVrstvyZahrady(string cesta) Metoda vracející seznam vrstev zahrady uložených v souboru, který je určen parametrem cesta. Využívá LINQ. public IEnumerable<XElement> VratNastaveniZahrady(string cesta) Metoda vracející nastavení zahrady uložené v souboru, který je určen parametrem cesta. Využívá LINQ. public void UlozZahradu(string cesta, string jmenoSouboru, List
objekty, UIElementCollection vrstvy, double sirkaZahrady, double vyskaZahrady) Uloží zahradu s objekty zahrady v parametru objekty a s vrstvami v parametru vrstvy do datového souboru zahrady. Soubor je uložen na místo určené parametrem cesta a pod jménem specifikovaným parametrem jmenoSouboru. public ModelVisual3D Nacti3DModel(string nazevObjektu) Načte 3D model určený parametrem nazevObjektu z datového souboru s modely. 30
7.3.2.
Datové soubory
Aplikace pracuje se třemi datovými soubory. Soubory Modely.xml a Modely2.xml uchovávají modely 3D objektů. Datový soubor Rostliny.xml uchovává názvy rostlin, které je možné přiřadit objektům zahrady. 7.3.3.
Nastavení aplikace
Pro sdílení důležitých hodnot nastavení programu je vytvořena statická třída Nastaveni.cs. Do této třídy jsou ostatními třídami ukládány hodnoty sdílené a přístupné ostatním třídám aplikace.
7.4.
Logická vrstva
Logickou vrstvu aplikace tvoří třída GUIManager.cs. Umožňuje vkládat, měnit a nastavovat objekty v 3D pohledu na zahradu. Zajišťuje nastavování pozice a směru kamery, která zobrazuje 3D scénu. 7.4.1.
Třída GUIManager.cs
Pro zajištění přístupu k grafickým prvkům obsahuje reference na 2D pohled na zahradu Pohled2DCNV, na 3D pohled na zahradu VP3D a na prvek zobrazující pozici kamery zobrazeniPoziceKamery. Obsahuje tyto metody: public void ZmenKameru(double lookDirX, double lookDirY, double lookDirZ, double poziceKameryX, double poziceKameryY, double poziceKameryZ) Přičte k vektoru směru pohledu kamery a k pozici kamery v 3D pohledu hodnoty zadané v parametrech. public void NastavKameru3DProhlidky() Nastaví kameru v 3D zobrazení zahrady na režim 3D prohlídky. public void NastavKameru3DPerspektivy() Nastaví kameru v 3D zobrazení zahrady na režim 3D perspektivy. public void KameraDoleva() public void KameraDoprava() public void KameraNahoru() public void KameraDolu() 31
Jsou metody manipulující se směrem natočení kamery v 3D pohledu ekvivalentně názvu příslušné metody. public void KameraPriblizit() public void KameraOddalit() Jsou metody přibližující nebo oddalující kameru od povrchu zahrady. public Point3D KameraPoziceDopredu(Point3D aktualniPocatek3DZahrady, Point3D aktualniKonec3DZahrady) public Point3D KameraPoziceDozadu(Point3D aktualniPocatek3DZahrady, Point3D aktualniKonec3DZahrady) Metody nastavující pozici kamery dopředu nebo dozadu, vždy vzhledem k aktuálnímu směru natočení kamery. public PrvekGui VratPrislusnyPrvekGui(FrameworkElement oznacenyPrvek, List seznamPrvkuGuiPlatna) Na základě parametru oznacenyPrvek vrátí příslušný PrvekGui, kterého je oznacenyPrvek součástí. public void OdstranOznaceniPrvku(List<Path> seznamOznaceniPrvku, List seznamPrvkuGuiPlatna) Metoda zruší označení všech prvků v 2D zobrazení zahrady. public void Pridej3DObjekt(string Id, ModelVisual3D objekt, Point startBod2DPohled, Point pozicePrvkuV2DPohledu, double pomerVelikostiX, double pomerVelikostiY, Point3D aktualniPocatek3DZahrady) Metoda zajistí vložení 3D objektu do 3D zobrazení zahrady. Vkládaný objekt je určen parametrem objekt a je umístěn na pozici ekvivalentní pozici v 2D zobrazení. public void Posun3DObjektOVektor(ModelVisual3D objekt, Vector3D vektor) Metoda zajistí posunutí objektu v 3D zobrazení o vektor předaný v parametru vektor. public void ZmenVelikost3DObjektu(ModelVisual3D objekt, double scaleX, double scaleY, double scaleZ) 32
Metoda použita u 3D objektů, u kterých lze upravovat velikost. Na 3D objekt zadaný v parametru objekt aplikuje transformaci změny velikosti o hodnoty zadané v parametrech scaleX, scaleY, scaleZ. public bool Nastav2DObjektNaPozici(PrvekGui objekt, Point startPozice, Point cilovaPozice) Metoda nastavující 2D reprezentaci objektu v 2D zobrazení i 3D reprezentaci objektu v 3D zobrazení na pozici zadanou parametrem cilovaPozice public Point3D Vrat3DSouradniciVZahrade(Point aktualniPozice, Canvas pohled2D, Viewport3D pohled3D, double konstantaSirky, double konstantaVysky) Metoda vracející pozici v 3D pohledu zahrady na základě pozice objektu v 2D pohledu. Přepočet je realizován na základě poměru umístění objektu v 2D pohledu vzhledem k velikosti zahrady v 2D pohledu. public FrameworkElement UpravVisualProTisk(FrameworkElement prvek, PrintQueue pq) Zajišťuje úpravu velikosti tisknutého objektu. Na základě maximální tisknutelné velikosti upraví grafický prvek zadaný v parametru prvek na rozměry, které je tiskárna schopna vytisknout.
7.5.
Prezentační vrstva
Prezentační vrstva tvoří vzhled aplikace. Je tvořena okny, dialogy a grafickými prvky. Každé okno v aplikaci je reprezentováno dvěma soubory, kde v prvním s příponou .xaml jsou definovány grafické prvky obsažené v okně a v druhém s příponou .cs je obslužný kód pro události vyvolané na okně. 7.5.1.
Hlavní okno aplikace
Hlavní okno aplikace je stěžejní částí programu. Pro prezentaci 2D pohledu zahrady obsahuje prvek typu Canvas a pro prezentaci 3D pohledu obsahuje prvek ViewPort3D. Funkce nabízené programem jsou prezentovány v menu hlavního okna. Pro výběr a vložení vybraného prvku na zahradu slouží levé menu hlavního okna. Přemisťování objektů v 2D pohledu na zahradu je realizováno technikou dragand-drop. Tuto funkčnost realizují tyto metody a obsluhy událostí: private void Pohled2DCNV_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 33
Obsluha události kliku levého tlačítka myši do 2D pohledu. Zjistí zda se kliklo na nějaký objekt zahrady. private void Pohled2DCNV_PreviewMouseMove(object sender, MouseEventArgs e) Obsluha události tažení myší v 2D pohledu. V závislosti na tom, zda je objekt přesouván či je upravována jeho velikost, zajistí přesun objektu nebo úpravu jeho velikosti. private void Pohled2DCNV_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) Obsluha události uvolnění levého tlačítka myši. Zajistí ukončení přesunu objektu nebo změny velikosti objektu. private void TazeniZacatek() Uloží původní pozici taženého prvku. private void TazeniPrubeh() Pokud je objekt zahrady posouván, zajistí volání metody pro změnu pozice objektu. private void TazeniKonec(bool zruseno) Je volána při ukončení změny pozice objektu. Nastaví příznaky pro změnu pozice objektu na původní hodnoty. Z hlavního okna je umožněno spravovat vrstvy 2D pohledu. Následuje popis metod a obsluh událostí pro práci s vrstvami: private void VrstvaRB_Click(object sender, RoutedEventArgs e) Obsluha události kliku na prvek vrstvy, který je reprezentovaný třídou RadioButton. Nastaví aktuální vrstvu 2D pohledu podle prvku, na který se kliklo. private void VrstvaVseRB_Click(object sender, RoutedEventArgs e) Obsluha události kliku na vrstvu pojmenovanou Vše. Aktuální vrstvu nastaví na vrstvu Vše. private void pridejVrstvuMI_Click(object sender, System.Windows.RoutedEventArgs e) 34
Vyvolá dialog pro vložení nové vrstvy. private void odstranVrstvuMI_Click(object sender, RoutedEventArgs e) Obsluha události testuje, zda je možné aktuální vrstvu 2D pohledu odebrat. Pokud ano, odebere ji. private void prejmenujVrstvuMI_Click(object sender, System.Windows.RoutedEventArgs e) Zajistí přejmenování aktuální vrstvy v 2D pohledu. Hlavní okno aplikace má definované obsluhy událostí stisku klávesových zkratek. Obsluha události po stisku klávesové zkratky vyvolá příslušnou akci. Pod levým menu jsou při zobrazeném 3D pohledu zobrazena tlačítka pro pohyb a natáčení kamery. Obsluha události kliku na tato tlačítka zavolá příslušné metody třídy GUIManager.cs z logické vrstvy, které implementují manipulaci s kamerou. S využitím grafického manažeru (třída GUIManager.cs) a datového manažeru (třída DataManager.cs) zajišťuje hlavní okno funkcionalitu pro vkládání, editaci a odstraňování zahrad. Dále pro nastavování pohledů na zahradu a pro tisk zahrady. Zajišťují ji tyto metody: private void VycistiZahradu() Pomocná metoda, která odstraní veškeré prvky z 2D i 3D pohledu na zahradu a připraví aplikaci pro vložení nové zahrady. private void pridejZahraduMI_Click(object sender, System.Windows.RoutedEventArgs e) S využitím předchozí metody a okna pro vložení nové zahrady umožní vložení nové zahrady o zadaných rozměrech do aplikace. private void UlozZahraduMI_Click(object sender, System.Windows.RoutedEventArgs e) S využitím datového manažeru a dialogu pro uložení souborů zajistí uložení aktuálně zobrazené zahrady v aplikaci do souboru. private void nactiZahraduMI_Click(object sender, System.Windows.RoutedEventArgs e) S využitím datového manažeru a dialogu pro otevření souborů načte zahradu ze souboru zvoleného uživatelem do aplikace. 35
private void zvetsiSirkuZahradyMI_Click(object sender, System.Windows.RoutedEventArgs e) private void zvetsiVyskuZahrady_Click(object sender, System.Windows.RoutedEventArgs e) private void zmensiSirkuZahrady_Click(object sender, System.Windows.RoutedEventArgs e) private void zmensiDelkuZahrady_Click(object sender, System.Windows.RoutedEventArgs e) Obsluhy událostí zajišťující zvětšení nebo zmenšení velikosti zahrady v aplikaci. private void zadatRozmeryZahrady_Click(object sender, System.Windows.RoutedEventArgs e) Obsluha události zobrazí okno pro editaci rozměrů aktuálně zobrazené zahrady v aplikaci. private void pohled2DMI_Click(object sender, System.Windows.RoutedEventArgs e) Nastaví hlavní okno pro zobrazení 2D plánu na zahradu a zobrazí 2D plán. private void pohled3DMI_Click(object sender, System.Windows.RoutedEventArgs e) Nastaví hlavní okno pro zobrazení 3D prohlídky a zobrazí 3D prohlídku zahrady. private void pohled3DperspektivaMI_Click(object sender, System.Windows.RoutedEventArgs e) Nastaví hlavní okno pro zobrazení 3D perspektivy a 3D perspektivu zobrazí. private void TiskAktualnihoZobrazeni() Metoda na základě aktuálně zobrazeného pohledu na zahradu vygeneruje tiskový výstup a zobrazí dialog pro výběr, kam se má tiskový výstup vytisknout.
36
7.5.2.
Další okna aplikace
Mimo hlavní okno aplikace je možné ještě zobrazit tyto okna: • Okno pro zadání dvou hodnot reprezentované třídou OknoDvouHodnot. Tvoří prototyp pro zadání dvou hodnot od uživatele. • Okno pro zadání jedné hodnoty reprezentované třídou OknoJedneHodnoty. Tvoří prototyp pro zadání jedné hodnoty od uživatele. • Okno pro vložení nové zahrady do aplikace reprezentované třídou PridejZahradu. • Okno pro zobrazení vlastností objektu zahrady reprezentované třídou VlastnostiObjektu. • Okno pro zobrazení VyberNazevPrvku. 7.5.3.
číselníku
rostlin
reprezentované
třídou
Reprezentace grafických objektů
Prvek zahrady je v aplikaci a při uložení do souboru reprezentován třídou odvozenou od třídy PrvekGui.cs. Třída PrvekGui.cs představuje rodičovskou třídu definující společné vlastnosti pro prvky zahrady. Obsahuje atribut zobrazeniPTH obsahující schématickou značku prvku a identifikátor typu Tag2DPrvku uložený v atributu Tag. Identifikátor uchovává informace o vrstvě, které prvek přísluší, o názvu prvku zobrazovaného v aplikaci a o typu 3D modelu, který prvek reprezentuje v 3D pohledu. Každý prvek zahrady má v aplikaci dvě zobrazení. Identifikace obou zobrazení je zajištěna pomocí jednoznačného identifikátoru přiřazeného oběma zobrazením. Prvním zobrazením je schématická značka (tvar), která reprezentuje objekt v 2D zobrazení. Druhým je model objektu, který reprezentuje prvek v 3D zobrazení.
37
8.
Uživatelská dokumentace
8.1.
Požadavky, instalace a spuštění aplikace
Aplikace 3D Zahrada umožňuje návrh, editaci a tisk 2D a 3D plánů zahrad. Na zahradu je možno nahlížet z různých úhlů pomocí pohyblivé kamery. Jde o 32-bitovou aplikaci určenou pro systém Microsoft Windows. Pro spuštění a chod je nutné mít nainstalován .NET Framework 3.5 SP1 nebo vyšší. Pro zobrazení a tisk 2D a 3D plánů zahrady je zapotřebí mít nainstalován Microsoft XPS Essentials Pack. Oba instalační balíčky je možné stáhnout z webové stránky www.microsoft.com/downloads. Doporučená hardwarová konfigurace pro aplikaci 3D Zahrada: procesor Intel Core 2 Duo 2500 MHz, 2 GB operační paměti, grafická karta NVIDIA GeForce 8600 GT, 2 GB volného místa na pevném disku a operační systém Windows 7 Professional. Instalaci aplikace uživatel provede překopírováním obsahu adresáře bin z přiloženého CD do adresáře na pevném disku. Aplikaci je poté možné spustit z cílového adresáře otevřením souboru 3D Zahrada.exe. Po spuštění se zobrazí hlavní okno aplikace s předdefinovanou prázdnou zahradou, kterou je možné editovat.
8.2.
Hlavní okno aplikace
Hlavní okno aplikace se zobrazí po spuštění programu. Je funkčně rozděleno na tři části. První část tvoří menu aplikace, druhou levé menu pro výběr objektů určených pro vložení do 2D plánu zahrady a třetí část vyplňuje plocha zobrazující pohled na zahradu. V aplikaci existují tři druhy zobrazení zahrady: 2D plán, 3D prohlídka, 3D perspektiva. Při třídimenzionálním pohledu na scénu hlavní okno také zobrazuje tlačítka pro nastavení kamery a prvek zobrazující pozici kamery v 3D prostoru. Hlavní okno aplikace je zobrazeno na obrázku 1.. 8.2.1.
Menu
Menu obsahuje všechny volby a nastavení programu. Kliknutím na vybranou z nich se spustí daná akce (jejich popis níže). • Soubor – Nová zahrada - vyvolá dialog pro vložení nové zahrady. – Načíst zahradu - vyvolá dialog pro načtení dříve uložené zahrady ze souboru. – Uložit zahradu - vyvolá dialog pro uložení aktuálně zobrazené zahrady do souboru. 38
Obrázek 1. Hlavní okno aplikace
39
– Číselník rostlin - otevře okno s názvy rostlin, které je možno přiřadit objektům na zahradě. – Konec - ukončí aplikaci. • Zahrada – Zvětšit šířku zahrady - zvětší šířku zahrady o 10 metrů. – Zvětšit délku zahrady - zvětší délku zahrady o 10 metrů. – Zmenšit šířku zahrady - zmenší šířku zahrady o 10 metrů. – Zmenšit délku zahrady - zmenší délku zahrady o 10 metrů. – Upravit velikost zahrady - otevře okno, ve kterém je možné zadat rozměry zahrady. • Vrstvy – Vložit novou vrstvu - otevře okno pro vložení nové vrstvy. – Odstranit aktuální vrstvu - odstraní aktuální vrstvu pokud do ní nepřísluší žádné objekty. – Přejmenovat aktuální vrstvu - otevře okno pro zadání nového názvu aktuální vrstvy. • Pohled – 2D plán - zobrazí 2D plán zahrady. – 3D prohlídka - zobrazí 3D prohlídku zahrady. – 3D perspektiva - zobrazí 3D perspektivu zahrady. • Tisk – Tisk aktuálního zobrazení - vyvolá dialog pro vytištění aktuálně zobrazeného pohledu na zahradu. • Nápověda – Obsah - zobrazí nápovědu programu. – O aplikaci - zobrazí okno s informacemi o aplikaci. 8.2.2.
Menu objektů zahrady
Menu objektů zahrady slouží k výběru objektu, který chce uživatel na zahradu vložit. Uživatel označí objekt, který chce na zahradu vložit, drží levé tlačítko myši a přetažením objektu na vybrané místo zahrady umístí objekt. Vložený objekt má výchozí jméno shodné se jménem prvku v menu. Je možné jej změnit na libovolné jméno z číselníku rostlin ve vlastnostech prvku. Vkládat objekty zahrady je možné pouze do 2D plánu zahrady. 40
8.2.3.
Zobrazení zahrady
Aplikace 3D Zahrada umožňuje tři pohledy na vytvořenou zahradu. Prvním je 2D plán zahrady. Vyvoláme ho stiskem klávesy s číslem jedna nebo kliknutím na položku 2D plán v menu Pohled. Tento pohled schématicky zobrazuje objekty na zahradě a jejich rozmístění. Prvky v něm lze posouvat technikou drag-and-drop. U prvků, které reprezentují terén je možné měnit jejich velikost. 2D pohled obsahuje také po stranách prvky zobrazující rozměry zahrady v jednotkách metrů. Přibližovat nebo oddalovat 2D plán zahrady je možné při stisknuté levé klávese CTRL a použití kolečka myši. Druhým z možných pohledů je 3D prohlídka navržené zahrady. Vyvoláme ji stiskem klávesy s číslem dvě nebo kliknutím na položku 3D prohlídka v menu Pohled. Při volbě tohoto pohledu je kamera umístěna do středu zahrady a je možné s ní pohybovat a natáčet ji. Kliknutím na tlačítko v nastavení kamery nebo stiskem klávesy směrové šipky na klávesnici kameru natočíme v daném směru. Při držení levé klávesy CTRL spolu s směrovou šipkou nahoru nebo dolů změníme pozici kamery. Pozici kamery není dovoleno nastavit mimo rozměry zahrady. Pozice kamery je schématicky zobrazena v prvku Pozice kamery. Třetím pohledem na zahradu je 3D perspektiva. Vyvoláme ji stiskem klávesy s číslem tři nebo kliknutím na položku 3D perspektiva v menu Pohled. Kamera je jako v předcházejícím pohledu umístěna do středu zahrady ale nyní zobrazuje zahradu z perspektivy. Kolečkem myši nebo stiskem tlačítka s lupou v nastavení kamery můžeme pohled na zahradu přibližovat a oddalovat.
8.3.
Vrstvy
Každý objekt na zahradě přísluší do nějaké vrstvy. Vrstvy v aplikaci slouží k rozdělení objektů zahrady do skupin. Každá zahrada v aplikaci vždy obsahuje vrstvu Vše. Při její volbě jsou v 2D plánu zahrady zobrazeny všechny objekty zahrady. Další vrstvy je možné libovolně vkládat, odebírat a přejmenovávat. Vložení nové vrstvy provedeme výběrem položky Vložit novou vrstvu v menu Vrstvy a zadáním názvu vrstvy ve vyvolaném dialogu. Odstranění aktuální vrstvy provedeme výběrem položky Odstranit aktuální vrstvu v menu Vrstvy. Vrstvu není povoleno odstranit, pokud existují objekty zahrady příslušné této vrstvě. Přejmenování aktuální vrstvy provedeme výběrem položky Přejmenovat aktuální vrstvu v menu Vrstvy a zadáním nového názvu vrstvy ve vyvolaném dialogu. Mezi jednotlivými vrstvami přepínáme kliknutím myší na zvolený název vrstvy. Při výběru určité vrstvy jsou v 2D plánu zobrazeny pouze ty objekty, které do vybrané vrstvy přísluší. Při zvolení vrstvy Vše jsou v 2D plánu zobrazeny všechny objekty zahrady.
41
8.4.
Zaharady
Práce se zahradami patří k hlavním vlastnostem aplikace 3D Zahrada. Po startu aplikace je zobrazena výchozí prázdná zahrada, kterou je možné začít editovat. Vložení nové zahrady do programu provedeme vybráním volby Nová zahrada v menu Soubor. Je vyvoláno dialogové okno, kde zadáme název vkládané zahrady a můžeme také určit rozměry nové zahrady v jednotkách metrů. Pro potvrzení vložení stiskneme tlačítko Vložit. Dialogové okno pro vložení nové zahrady můžeme také vyvolat stiskem klávesové zkratky CTRL + N. Délka názvu vkládané zahrady je omezena na 25 znaků. Uložení aktuálně zobrazené zahrady provedeme volbou položky Uložit zahradu v menu Soubor. Je zobrazeno dialogové okno, kde zvolíme místo uložení souboru se zahradou a název tohoto souboru. Pro potvrzení stiskneme tlačítko Uložit. Zahrada je uložena do souboru se zvoleným názvem a příponou .3dz. Jméno aktuálně uloženého souboru je zobrazeno v titulku hlavního okna. Uživatel je o stavu uložení zahrady informován v zobrazeném dialogovém okně. Vyvolání dialogového okna pro uložení zahrady můžeme také provést stiskem klávesové zkratky CTRL + S. Načtení dříve uložené zahrady provedeme klikem na položku Načíst zahradu v menu Soubor. Je zobrazeno dialogové okno, ve kterém vybereme soubor s dříve uloženou zahradou. Pro potvrzení načtení zahrady stiskneme tlačítko Otevřít. Zvolená zahrada je načtena do aplikace. Vyvolání dialogového okna pro načtení zahrady můžeme také provést stiskem klávesové zkratky CTRL + O. Změnit velikost zahrady můžeme provést dvěma způsoby. Zvolením položky Zvětšit šířku zahrady, Zvětšit délku zahrady, Zmenšit šířku zahrady nebo Zmenšit délku zahrady v menu Zahrada velikost zahrady upravíme o pevně dané hodnoty velikosti. Druhou možností je vyvolání dialogu Upravit velikost zahrady po kliku pravým tlačítkem myši do prázdné plochy zahrady nebo vybráním položky Upravit velikost zahrady v menu Zahrada. Zde můžeme zadat novou požadovanou šířku a výšku zahrady v jednotkách metrů.
8.5.
Tisk
Aplikace umožňuje vytvořit tiskové výstupy zobrazených pohledů na zahradu. Tisk aktuálně zobrazeného pohledu na zahradu provedeme stiskem klávesové zkratky CTRL + P nebo klikem na položku Tisk aktuálního zobrazení v menu Tisk. Pokud máme zvolený pohled na zahradu 2D plán, je vždy jeho velikost přizpůsobena velikosti stránky tak, aby se 2D plán zahrady vešel na stránku celý (i případně s nezobrazenou částí). V případě, že by byl větší než velikosti tisknutelné oblasti je zmenšen, v případě, že by byl menší než velikost tisknutelné oblasti je 42
zachován a zarovnán na střed stránky. Při zvoleném pohledu 3D prohlídka nebo 3D perspektiva je vždy tisknuta jen aktuálně viditelná oblast pohledu. Pokud je oblast větší než velikost tisknutelné oblasti je proporcionálně zmenšena. Je-li její velikost menší pak je zachována a zarovnána na střed tisknutelné oblasti.
8.6.
Parametry objektu zahrady a manipulace s objekty
Každý objekt zahrady má jméno, po vložení nastavené na Objekt. Jméno objektu lze změnit po kliku pravým tlačítkem na vybraný objekt a vybráním volby vlastnosti z kontextového menu objektu. Zde je možné z rozbalovacího seznamu vybrat jiné jméno objektu. Položky rozbalovacího seznamu jsou ekvivalentní položkám z číselníku rostlin. Druhým parametrem objektu je vrstva, do které objekt patří. Tuto vrstvu lze opět změnit ve vlastnostech objektu. Objekt lze přiřadit do libovolné vrstvy zahrady vyjma vrstvy Vše. Parametry objektu jsou zobrazeny na obrázku 2..
Obrázek 2. Parametry objektu Odstranění objektu ze zahrady provedeme vyvoláním kontextového menu objektu (klikem pravým tlačítkem na objekt) a vybráním volby Odstranit objekt. Touto akcí objekt ze zahrady odstraníme. Změnu pozice objektu můžeme provést uchopením objektu myší a tažením objektu na cílovou pozici nebo vyvoláním kontextového menu objektu a vybráním volby Upravit pozici. Ve vyvolaném dialogovém okně můžeme zadat novou pozici objektu v jednotkách metrů. Uložení nové pozice potvrdíme stiskem tlačítka OK na vyvolaném dialogovém okně. Nová pozice prvku je nastavena jen pokud nepřevyšuje rozměry zahrady. U objektů, které reprezetují povrch, je možné změnit jejich velikost. Změnu velikosti provedeme uchopením čtverečku v pravém dolním rohu objektu zobrazeného v 2D plánu a tažením upravíme velikost objektu.
43
8.7.
Číselník rostlin
Číselník rostlin slouží jako zdroj názvů, které je možné přiřadit objektům na zahradě. Tyto názvy je možné vkládat a odebírat. Číselník rostlin vyvoláme výběrem položky Číselník rostlin v menu Soubor. V rozbalovacím seznamu jsou obsažena abecedně setřízená jména, která lze objektům přiřadit. Nové jméno vložíme po kliku na tlačítko Vložit rostlinu v číselníku rostlin. Do vyvolaného dialogu zadáme požadovaný název a stiskneme tlačítko OK. Pro odstranění vybraného názvu jej vybereme v rozbalovacím seznamu s stiskneme tlačítko Odstranit roslinu v číselníku rostlin. Číselník rostlin je zobrazen na obrázku 3..
Obrázek 3. Číselník rostlin
8.8.
Nastavení kamery a pozice kamery
Při aktivní 3D perspektivě nebo při aktivní 3D prohlídce jsou pod menu objektů zobrazena tlačítka pro nastavení kamery a prvek zobrazující pozici a natočení kamery na zahradě. Při zvoleném pohledu 3D perspektiva lze kameru přibližovat a oddalovat kolečkem myši nebo stiskem tlačítka s obrázkem lupy a symbolem plus nebo minus. Při zvoleném pohledu 3D prohlídka je možné kameru natáčet stiskem tlačítka se šipkou v požadovaném směru. Měnit pozici kamery lze po stisku klávesy šipky dopředu nebo dozadu spolu se stisknutou levou klávesou CTRL. Nastavení kamery do výchozího stavu v obou 3D zobrazeních zahrady provedeme stiskem na tlačítko se dvěma šipkami v nastavení kamery. Tlačítka pro nastavení kamery jsou zobrazena na obrázku 5.. Prvek zobrazující pozici a natočení kamery je zobrazen na obrázku 4..
8.9.
Nápověda
Popis aplikace je uveden také v nápovědě. Nápovědu zobrazíme volbou položky Obsah v menu Nápověda nebo stiskem klávesové zkratky F1. Okno nápovědy je zobrazeno na obrázku 6..
44
Obrázek 4. Prvek zobrazení pozice a natočení kamery
Obrázek 5. Tlačítka nastavení kamery
Obrázek 6. Okno nápovědy aplikace
45
Závěr Cílem této práce bylo vypracovat srovnání dvou odlišných technologií pro vytváření 3D scény a vytvořit aplikaci, na které bude demonstrováno použití technologie Windows Presentation Foundation. Technologie OpenGL a Windows Presentation Foundation byly popsány a srovnány v prvcích, které jsou pro vytvoření 3D scény podstatné. Aplikace vytvořená ve WPF umožňuje vytvoření, editaci a prohlížení navržené zahrady. Nabízí funkcionalitu požadovanou v zadání práce, čímž bylo zadání splněno. Aplikace byla testována lidmi zabývajícími se návrhem a realizací zahrad se závěrem, že pokud by byla rozšířena o více modelů 3D objektů, bylo by možné ji použít pro prezentaci finální podoby zahrady.
46
Conclusions The two main goals of this thesis are: (1) to compare two different technologies used for creation of the 3D scene and (2) to create an application that would demonstrate the use of the Windows Presentation Foundation technology. The technologies OpenGL and Windows Presentation Foundation were described and compared to fully understand the whole process of creation of the 3D scene. The application created in the WPF can be used to design, edit, and browse a draft of a garden. The application gives a full response to all tasks addressed by the thesis. It was also tested by professionals who concluded that, if modified the application could be used for presentation of the final version of the draft of the garden.
47
Reference [1] Noble, S. — Burton, S. — Jones, A. WPF Recipes in C# 2008. Apress, 2008. [2] Feldman, A. — Daymon, M. WPF in action Manning, 2008. [3] Griffiths, I. — Sells, Ch. Programming WPF OŔeilly, 2007. [4] Petzold, Ch. Three-Dimensional Graphics Programming for the Windows Presentation Foundation. Microsoft Press, 2007. [5] Shreiner, D. OpenGL Programming Guide Seventh Edition Addison-Wesley, 2010. [6] Tišnovský, P. Grafická knihovna OpenGL [online]. 2003, [cit. 2010-04-16]. Dostupné z: . [7] Archibase [online]. [cit. 2010-01-12]. .
Dostupné
z:
[8] Viewer3ds [počítačový program]. Ver. 2.1.3624. 2009 [cit. 2010-01-12]. Dostupné z: . Software pro konverzi 3ds modelů do formátu XAML. Vyžaduje .NET Framework 3.5.
48
I.
Popis obsahu přiloženého DVD Součástí této práce je i DVD. Jeho obsahem jsou tři adresáře a jeden soubor. • Adresář bin obsahuje zkompilovanou aplikaci. Obsahuje také spustitelný soubor nápovědy a adresář s aplikačními daty. • Adresář doc obsahuje dokumentaci této práce ve spustitelné podobě a zdrojové kódy dokumentace. • Třetí adresář src obsahuje v podadresáři 3D Zahrada zdrojové kódy programu a v podadresáři Napoveda zdrojové kódy nápovědy programu. • V souboru readme.txt je popsáno, jak lze aplikaci spustit.
49