Za´padoˇceska´ univerzita v Plzni Fakulta aplikovany´ch vˇed Katedra informatiky a vy´poˇcetn´ı techniky
Diplomov´ a pr´ ace GLSL editor
Plzeˇ n 2014
Bohumil Podles´ak
Prohl´ aˇ sen´ı Prohlaˇsuji, ˇze jsem diplomovou pr´aci vypracoval samostatnˇe a v´ yhradnˇe s pouˇzit´ım citovan´ ych pramen˚ u. V Plzni dne 15. kvˇetna 2014 Bohumil Podles´ak
Abstract First part of this work is an overview of existing IDE tools that can be used to edit the code and visualize the scene of graphics applications that use GLSL shaders. The advantages and disadvantages of the different tools will be evaluated. The second part of this work focuses on creating a GLSL editor. This new tool will allow the user to easily create and visualize a new effect. User will be able to create a scene using C# language and GLSL shaders in interactive editor.
Abstrakt ´ Ukolem prvn´ı ˇca´sti t´eto pr´ace je sezn´amit se s existuj´ıc´ımi v´ yvojov´ ymi prostˇred´ımi pro u ´pravu a vizualizaci GLSL shader˚ u. Budou pops´any v´ yhody a nev´ yhody jednotliv´ ych n´astroj˚ u. ´ Ukolem druh´e ˇc´asti t´eto pr´ace je navrhnout GLSL editor, kter´ y bude umoˇzn ˇovat uˇzivateli jednoduˇse vytvoˇrit a zobrazit nov´ y efekt. Uˇzivatel bude moci sestavit sc´enu v jazyce C# za pouˇzit´ı GLSL shader˚ u v interaktivn´ım editoru.
Obsah ´ 1 Uvod 2 Grafick´ yˇ rˇ etˇ ezec 2.1 OpenGL . . . . . . . . . . . . . . . 2.2 GLSL jazyk . . . . . . . . . . . . . 2.2.1 GLSL kompilaˇcn´ı model . . 2.2.2 Standardn´ı knihovn´ı funkce 2.2.3 Pˇreddefinovan´e promˇenn´e . 2.2.4 Datov´e typy promˇenn´ ych . . 2.2.5 Kvalifik´atory promˇenn´ ych .
1
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
3 GLSL shadery a fixn´ı ˇ c´ ast grafick´ eho ˇ retˇ ezce 3.1 Vertex fetch . . . . . . . . . . . . . . . . . . . 3.2 Vertex shader . . . . . . . . . . . . . . . . . . 3.3 Tessellation shader . . . . . . . . . . . . . . . 3.3.1 Tessellation control shader . . . . . . . 3.3.2 Gener´ator primitiv . . . . . . . . . . . 3.3.3 Tessellation evaluation shader . . . . . 3.4 Geometry Shader . . . . . . . . . . . . . . . . 3.5 Primitive assembly, oˇrez´av´an´ı a rasteriz´er . . . . . . . . . . . . . . . . . . . 3.6 Fragment shader . . . . . . . . . . . . . . . . 4 N´ astroje pro editaci shader˚ u 4.1 AMD RenderMonkey (verze 1.82) [7] . . 4.1.1 Funkce a charakteristiky software 4.1.2 Rozhran´ı . . . . . . . . . . . . . . 4.1.3 Editor . . . . . . . . . . . . . . . 4.1.4 Ladˇen´ı shader˚ u . . . . . . . . . . 4.1.5 Export . . . . . . . . . . . . . . . 4.2 Glsl Hacker (verze 0.5.0) [8] . . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
2 2 3 4 5 5 5 7
. . . . . . .
10 10 10 12 13 14 15 16
. . . . . . . . . 17 . . . . . . . . . 18
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
. . . . . . .
20 20 21 22 23 23 24 24
OBSAH
4.3
4.4
4.5
4.6
4.7
4.8
OBSAH 4.2.1 Funkce a charakteristiky software 4.2.2 Rozhran´ı . . . . . . . . . . . . . . 4.2.3 Editor . . . . . . . . . . . . . . . 4.2.4 Ladˇen´ı shader˚ u . . . . . . . . . . gDEBugger (verze5.8.1) [9] . . . . . . . . 4.3.1 Funkce a charakteristiky software 4.3.2 Rozhran´ı . . . . . . . . . . . . . . 4.3.3 Editor . . . . . . . . . . . . . . . 4.3.4 Ladˇen´ı shader˚ u . . . . . . . . . . 4.3.5 Statistiky . . . . . . . . . . . . . 4.3.6 Profilov´an´ı . . . . . . . . . . . . . 4.3.7 Anal´ yza . . . . . . . . . . . . . . 4.3.8 N´asledn´ıci projektu gDEBugger . GlslDevil (verze 1.1.5) [10] . . . . . . . . 4.4.1 Rozhran´ı . . . . . . . . . . . . . . 4.4.2 Ladˇen´ı shader˚ u . . . . . . . . . . 4.4.3 Funkcionalita . . . . . . . . . . . KickJs GLSL Shader Editor [11] . . . . . 4.5.1 Funkce a charakteristiky software 4.5.2 Rozhran´ı . . . . . . . . . . . . . . 4.5.3 Editor . . . . . . . . . . . . . . . 4.5.4 Ladˇen´ı shader˚ u . . . . . . . . . . OpenGL Shader Designer (Verze 1.5.9.6) [12] . . . . . . . . . . . . 4.6.1 Funkce a charakteristiky software 4.6.2 Rozhran´ı . . . . . . . . . . . . . . 4.6.3 Editor . . . . . . . . . . . . . . . 4.6.4 Ladˇen´ı shader˚ u . . . . . . . . . . Shader Maker [13] . . . . . . . . . . . . . 4.7.1 Funkce a charakteristiky software 4.7.2 Rozhran´ı . . . . . . . . . . . . . . 4.7.3 Editor . . . . . . . . . . . . . . . 4.7.4 Ladˇen´ı shader˚ u . . . . . . . . . . Shrnut´ı funkcionality testovan´ ych n´astroj˚ u . . . . . . . . . . . . . . . . . .
5 Anal´ yza vlastnost´ı vyv´ıjen´ e aplikace
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . .
24 26 26 26 27 27 28 28 29 30 31 31 32 32 33 34 34 35 35 36 36 36
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
37 37 38 38 39 39 40 40 40 41
. . . . . . . . . . . . 41 43
6 Anal´ yza komponent pro zv´ yrazˇ nov´ an´ı k´ odu 45 6.1 Scintilla [16] . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 6.1.1 ScintillaNET [17] . . . . . . . . . . . . . . . . . . . . . 46 5
OBSAH
OBSAH
. . . . . . . . . .
46 47 47 49 49 49 49 50 51 51
. . . .
52 52 52 54 55
8 Online kompilace C# k´ odu 8.1 N´avrh zp˚ usobu kompilace . . . . . . . . . . . . . . . . . . . . 8.1.1 Implementace glob´aln´ıch promˇenn´ ych . . . . . . . . . . 8.1.2 Implementace vizualizaˇcn´ı smyˇcky . . . . . . . . . . . . 8.1.3 Zmˇena hodnot uniform promˇenn´ ych za bˇehu vizualizace
57 57 58 59 61
9 Komunikace s vizualizaˇ cn´ım oknem 9.1 Tˇr´ıda AppDomain . . . . . . . . . . . . . . . . . . . . . . . . 9.2 V´ yhody uˇz´ıv´an´ı aplikaˇcn´ıch dom´en . . . . . . . . . . . . . . . 9.3 N´avrh komunikaˇcn´ıho rozhran´ı . . . . . . . . . . . . . . . . .
63 63 64 64
10 Spr´ ava zdroj˚ u 10.1 Syst´em projekt˚ u. . . . . . . . . . . . . . . . . . 10.2 Naˇc´ıt´an´ı textur . . . . . . . . . . . . . . . . . . 10.3 Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u. . . . . . . . . 10.3.1 Popis vnitˇrn´ıho form´atu rsm . . . . . . . 10.3.2 Form´at collada . . . . . . . . . . . . . . 10.3.3 Konverze do rsm souboru . . . . . . . . 10.3.4 Rozd´ıl v indexov´an´ı mezi form´aty collada
68 68 68 69 70 72 74 74
6.2 6.3
6.4 6.5
6.1.2 Testovac´ı aplikace . . . Fast ColoredTextbox[20] . . . 6.2.1 Testovac´ı aplikace . . . ICSharpCode.TextEditor [18] 6.3.1 Komponenty a tˇr´ıdy . 6.3.2 Vlastnosti editoru . . . 6.3.3 Testovac´ı aplikace . . . ChameleonRichTextBox [21] . 6.4.1 Testovac´ı aplikace . . . Zhodnocen´ı komponent . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
. . . . . . . . . .
7 Implementace editoru zdrojov´ eho k´ odu 7.1 Nastaven´ı komponenty FastColoredTextbox . 7.2 Zv´ yrazˇ nov´an´ı vlastn´ıho jazyka . . . . . . . . . 7.2.1 Vyvol´an´ı nab´ıdky pro doplˇ nov´an´ı k´odu 7.2.2 Nastaven´ı dat pro doplˇ nov´an´ı k´odu . .
. . . . . . . . . .
. . . .
. . . . . . . . . .
. . . .
. . . . . . . . . .
. . . .
. . . . . . . . . .
. . . .
. . . . . . . . . .
. . . .
. . . . . . . . . . . . . . . . . . . . . . . . a rsm
. . . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . . .
. . . .
. . . . . . .
. . . . . . . . . .
. . . .
. . . . . . .
. . . . . . .
11 Sestaven´ı aplikace
77
12 Z´ avˇ er
78
6
´ 1 Uvod C´ılem t´eto diplomov´e pr´ace je vyvinout software, kter´ y p˚ ujde jednoduˇse pouˇz´ıt pro v´ yvoj efekt˚ u pro grafick´e karty. Program mus´ı b´ yt schopen jednoduˇse a pohodlnˇe umoˇznit program´atorovi inicializovat zdroje, sestavit sc´enu, specifikovat vykreslovac´ı smyˇcku a napsat programov´ y k´od shader˚ u pro koneˇcn´e vykreslen´ı. Program´ator bude m´ıt k dispozici moˇznost upravovat program vizualizaˇcn´ı smyˇcky v jazyce C#. Shadery bude program´ator ps´at v jazyce GLSL. Teoretick´a ˇca´st bude pops´ana v kapitole vysvˇetluj´ıc´ı z´aklady grafick´eho ˇretˇezce a pouˇz´ıv´an´ı OpenGL. Bude zde vysvˇetlena terminologie cel´e problematiky a z´ıskan´e znalosti o funkci OpenGL program˚ u aplikujeme pˇri n´avrhu editoru. Souˇca´st´ı pr´ace je d´ale anal´ yza software, kter´ y se v souˇcasn´e dobˇe m˚ uˇze pouˇz´ıt pro u ´ˇcely editace, testov´an´ı, ladˇen´ı a v´ yvoj shader˚ u. Bude zhodnocena kvalita jednotliv´ ych program˚ u z hlediska zamˇeˇren´ı t´eto pr´ace. V z´avˇeru t´eto kapitoly bude shrnut´ı vlastnost´ı dan´ ych program˚ u a bude vysvˇetleno, co by bylo tˇreba udˇelat l´epe nebo ˇc´ım by se dalo inspirovat. V ˇca´sti programov´e realizace budou zhodnoceny nˇekter´e existuj´ıc´ı programov´e komponenty a technologie, kter´e mohou b´ yt pouˇzity pˇri implementaci. Z´aroveˇ n budou pops´any jednotliv´e vlastnosti v´ ysledn´e aplikace a jejich implementace. V pˇr´ıloze bude vysvˇetlena pr´ace s v´ ysledn´ ym programem na pˇripraven´ ych uk´azkov´ ych u ´loh´ach.
1
2 Grafick´y ˇrˇetˇezec Pˇri vyuˇz´ıv´an´ı fixn´ı funkcionality grafick´eho ˇretˇezce je tˇeˇzk´e dos´ahnout pokroˇcilejˇs´ıch efekt˚ u. Bud’ je tˇreba ˇcasto pˇrep´ınat stavy, nebo je nutn´e vyvinout nov´ y hardware, kter´ y dok´aˇze dan´ y efekt prov´est. S t´ım se vˇsak v´aˇz´ı probl´emy s nekompatibilitou r˚ uzn´ ych grafick´ ych karet. Nav´ıc nar˚ ust´a ne´ umˇernˇe komplexita cel´eho ˇretˇezce. Velmi ˇcasto nen´ı moˇzn´e dos´ahnout urˇcit´e kvality poˇzadovan´ ych efekt˚ u nebo dokonce nem˚ uˇzeme zobrazen´ı dan´ ych efekt˚ u dos´ahnout v˚ ubec. Trendem modern´ı doby pˇri programov´an´ı grafick´ ych aplikac´ı je vymˇenit fixn´ı funkcionalitu grafick´eho ˇretˇezce a nahradit ji za programovateln´e shadery. V´ yhody vypl´ yvaj´ı z toho, ˇze u programovateln´ ych grafick´ ych karet je moˇzn´e popsat mnohem sloˇzitˇejˇs´ı a rozmanitˇejˇs´ı efekty, neˇz v pˇr´ıpadˇe fixn´ı funkcionality. Nejˇcastˇejˇs´ı a nejjednoduˇsˇs´ı vyuˇzit´ı je pˇri zpracov´an´ı vrchol˚ u pˇrich´azej´ıc´ıch na vstupu grafick´eho ˇretˇezce (transformace pozic jednotliv´ ych bod˚ u) a zpracov´an´ı fragment˚ u, kter´e jsou v´ ystupem z rasteriz´eru. Aplikaˇcn´ı program´atoˇri mohou vyj´adˇrit programov´ ym k´odem, jak se budou primitiva (vrcholy, fragmenty, nebo jin´a) zpracov´avat v programovateln´ ych bodech grafick´eho ˇretˇezce. Jednotliv´e programy, kter´e se p´ıˇs´ı pro programovateln´e procesory zm´ınˇen´ ych bod˚ u, se naz´ yvaj´ı shadery [1].
2.1
OpenGL
OpenGL je prostˇred´ı pro vytv´aˇren´ı pˇrenositeln´ ych a interaktivn´ıch 2D ˇci 3D grafick´ ych aplikac´ı. OpenGL 1.0 bylo poprv´e vyd´ano v roce 1992. OpenGL se stalo jedn´ım z nejrozˇs´ıˇrenˇejˇs´ıch API, kter´e podporuje 2D a 3D grafick´e aplikace. Ekvivalent k OpenGL, kter´ y je pomˇernˇe rozˇs´ıˇren´ y, je DirectX, kter´ y se d´a pouˇz´ıvat pouze na platform´ach se syst´emem od Microsoftu. OpenGL API je standardem v pr˚ umyslu, neust´ale se vyv´ıj´ı a je stabiln´ı. OpenGL aplikace mohou bˇeˇzet na osobn´ıch PC, tak na pˇrenosn´ ych zaˇr´ızen´ıch. Toto API je velmi dobˇre zdokumentov´ano: bylo publikov´ano mnoho knih o OpenGL a z´aroveˇ n vyd´ano mnoho pˇr´ıklad˚ u, kde se toto API vyuˇz´ıv´a [3]. Na obr´azku 2.1 je zn´azornˇen grafick´ y ˇretˇezec. Ov´aln´e r´ameˇcky ukazuj´ı 2
Grafick´y ˇrˇetˇezec
GLSL jazyk
Vertex fetch
Vertex shader
Geometry shader
Tessellation evaluation shader
Rasterization
Fragment shader
Tessellation control shader
Primitive Generator
Frame buffer operations
Obr´azek 2.1: Grafick´ y ˇretˇezec v OpenGL 4.3 [4] ˇc´asti ˇretˇezce, kter´e jsou fixn´ı. Obd´eln´ıkov´e r´ameˇcky ukazuj´ı ˇca´sti ˇretˇezce, kter´e jsou programovateln´e. Tyto programovateln´e ˇca´sti spouˇstˇej´ı shadery, kter´e program´ator poskytuje. Shadery jsou nez´avisl´e a daj´ı se kompilovat zvl´aˇst’. Program je pak mnoˇzina shader˚ u, kter´e jsou kompilovan´e a spojen´e dohromady (t´eto f´azi se ˇr´ık´a anglicky linking). OpenGL pouˇz´ıv´a entry pointy pro manipulaci a komunikaci s tˇemito programy.
2.2
GLSL jazyk
Jazyk GLSL byl navrˇzen proto, aby dal v´ yvoj´aˇr˚ um moˇznost ps´at pˇrenositeln´e shadery, tedy bez specifick´ ych instrukc´ı hardwaru pro r˚ uzn´e grafick´e karty. Existuje nˇekolik jazyk˚ u pro shadery OpenGL, ale GLSL je jedin´ y, kter´ y je ˇc´ast´ı j´adra OpenGL. Tento jazyk sd´ıl´ı model zastar´av´an´ı urˇcit´ ych funkc´ı (deprecation model). 3
Grafick´y ˇrˇetˇezec
GLSL jazyk
GLSL je zaloˇzen na ANSI C. Pˇr´ıpady, kdy m´a tento jazyk jin´e vlastnosti, nastanou pouze tehdy, kdyˇz by stejn´a funkcionalita ve skuteˇcnosti sniˇzovala v´ ykon takto napsan´e aplikace nebo jednoduchost implementace. Na rozd´ıl od implementace ANSI C byly pˇrid´any napˇr´ıklad vektorov´e ˇci maticov´e typy (kter´e jsou hardwarovˇe podporov´any). Byly pouˇzity i nˇekter´e mechanismy z C++, jako napˇr´ıklad pˇretˇeˇzov´an´ı funkc´ı na z´akladˇe typu argumentu a schopnost deklarovat promˇenn´e kdekoliv uvnitˇr funkˇcn´ıho bloku (ne pouze na zaˇca´tku) [5].
2.2.1
GLSL kompilaˇ cn´ı model
Kompilaˇcn´ı model je podobn´ y standardu paradigma C. Je to imperativn´ı programovac´ı jazyk. Kompilac´ı GLSL k´odu z´ısk´ame GLSL objekty. GLSL objekt zapouzdˇruje kompilovan´e ˇci nalinkovan´e programy, kter´e zpracov´avaj´ı ˇc´ast ˇretˇezce. GLSL m´a sloˇzitˇejˇs´ı kompilaˇcn´ı model neˇz jin´e jazyky pro grafick´e karty. Ostatn´ı jazyky maj´ı jednof´azov´ y model, kdy pro danou f´azi grafick´eho ˇretˇezce (vertex shader, fragment shader) staˇc´ı pouze jeden ˇretˇezec (k´od shaderu). Tento ˇretˇezec se zkompiluje a z´ısk´a se objekt shaderu (v angliˇctinˇe shader object), kter´ y se pak jen nav´aˇze na kontext. V jazyce C se v jednoduch´em pˇr´ıpadˇe z jednoho zdrojov´eho souboru vytvoˇr´ı jeden objektov´ y soubor. Ve sloˇzitˇejˇs´ım pˇr´ıpadˇe zdrojov´ y soubor m˚ uˇze obsahovat reference na nˇekter´e extern´ı hlaviˇckov´e soubory. Pak se zkompiluje nˇekolik zdrojov´ ych soubor˚ u do nˇekolika objektov´ ych soubor˚ u a objektov´e soubory jsou pak mezi sebou propojeny do jednoho programu. K´od GLSL se kompiluje podobn´ ym zp˚ usobem jako k´od jazyka C. Nˇekolik zdrojov´ ych soubor˚ u se zkompiluje do objektu shaderu, coˇz je jako analogie k objektov´emu souboru. Pak se tyto objekty mus´ı nalinkkovat. GLSL model dok´aˇze nˇekolik takov´ ychto objekt˚ u spojit do jednoho programu. Pokud nem´a shader ve sv´em k´odu funkci main, pak nen´ı aktivn´ı (program vykresluje tak, jakoby shader chybˇel). Za podm´ınky, ˇze je v programu pouˇzito glEnable(GL_RASTERIZER_DISCARD), je moˇzn´e pouˇz´ıt grafick´ y ˇretˇezec pouze s vertex shaderem [4].
4
Grafick´y ˇrˇetˇezec
2.2.2
GLSL jazyk
Standardn´ı knihovn´ı funkce
Existuje mnoho standardn´ıch funkc´ı. Nˇekter´e jsou specifick´e pouze pro danou f´azi shader˚ u, ale vˇetˇsina z nich jsou pouˇziteln´e ve vˇsech f´az´ıch. Nˇekter´e funkce, jako napˇr´ıklad vzorkov´an´ı textury, se nedaly pouˇz´ıvat v niˇzˇs´ıch verz´ıch OpenGL ve vertex shaderu. Od verze OpenGL 2.0 je toto jiˇz umoˇznˇeno [6]. Pokud pˇrekladaˇc st´ale hl´as´ı chybu, m˚ uˇze to b´ yt omezen´ım hardware nebo ovladaˇc˚ u. Matematick´e funkce se vˇetˇsinou daj´ı pouˇz´ıvat ve vˇsech f´az´ıch v´ ypoˇctu. Jde napˇr´ıklad o ˇcasto pouˇz´ıvan´e funkce pro line´arn´ı interpolaci (mix), skokovou funkci (step) nebo matematick´e operace s vektory (skal´arn´ı souˇcin dot, vektorov´ y souˇcin cross).
2.2.3
Pˇ reddefinovan´ e promˇ enn´ e
Existuje urˇcit´ y poˇcet speci´aln´ıch promˇenn´ ych, kter´e jsou jiˇz definovan´e jazykem. Jsou pouˇz´ıv´any vˇetˇsinou pro komunikaci s vnˇejˇs´ımi ˇc´astmi grafick´eho ˇretˇezce, na kter´e navazuje programov´ y k´od shader˚ u. D´ıky konvenci zaˇc´ınaj´ı vˇsechny pˇreddefinovan´e promˇenn´e ˇretˇezcem gl_. Uˇzivatelem definovan´e promˇenn´e tak zaˇc´ınat nesm´ı. V programov´em k´odu shader˚ u bude program´ator ve vˇetˇsinˇe pˇr´ıpad˚ u vyuˇz´ıvat alespoˇ n promˇennou gl_Position. Pokud chceme, aby probˇehlo vykreslov´an´ı, mus´ı se tato promˇenn´a nastavit v k´odu shaderu, kter´ y pˇredch´az´ı fragment shaderu (geometry shader a tessellaˇcn´ı shadery jsou nepovinn´e, takˇze to m˚ uˇze b´ yt jak´ ykoliv z pˇredeˇsl´ ych tˇr´ı shader˚ u). Pokud se t´eto promˇenn´e nepˇriˇrad´ı platn´a vec4 hodnota, neuvid´ıme pˇri rasterizaci ˇza´dn´ y v´ ystup.
2.2.4
Datov´ e typy promˇ enn´ ych
GLSL definuje mnoho datov´ ych typ˚ u. Z´aroveˇ n definuje zp˚ usob, kter´ y je moˇzn´e vytv´aˇret vlastn´ı datov´e typy (struktury). Vektorov´e a maticov´e datov´e typy jsou sloˇzeny ze z´akladn´ıch datov´ ych typ˚ u.
5
Grafick´y ˇrˇetˇezec
GLSL jazyk
• z´akladn´ı typy – skal´arn´ı ∗ ∗ ∗ ∗
bool (true/false) int (znam´enkov´ y 32-bitov´ y int s dvojkov´ ym doplˇ nkem) uint (neznam´enkov´ y 32-bitov´ y int) float (ˇc´ıslo v plovouc´ı ˇra´dov´e ˇca´rce podle IEEE-754)
– vektorov´e (n je 2, 3 nebo 4) ∗ ∗ ∗ ∗ ∗
bvecn (vektor bool hodnot) ivecn (vektor znam´enkov´ ych int) uvecn (vektor neznam´enkov´ ych int) vecn (vektor float ˇc´ısel) dvecn (vektor double ˇc´ısel)
– matice ∗ matnxm ∗ matn – nepr˚ uhledn´e (anglicky opaque) ∗ vzorkovaˇce ∗ obr´azky ∗ atomick´e ˇc´ıtaˇce • pole • pole pol´ı Skuteˇcn´ y datov´ y typ je d´an aˇz po pˇrekladu. Velikosti a form´aty integer a float ˇc´ısel jsou d´any aˇz od GLSL 1.3 a v´ yˇse. Niˇzˇs´ı verze mohou pouˇz´ıvat r˚ uzn´e specifikace. Pro pohodln´e zach´azen´ı s promˇenn´ ymi maj´ı vektory velk´e mnoˇzstv´ı konˇ struktor˚ u. Ctyˇrsloˇzkov´ y vektor lze sloˇzit ze dvou dvousloˇzkov´ ych vektor˚ u nebo z tˇr´ısloˇzkov´eho vektoru a skal´aru apod. Lze tak´e vytvoˇrit tˇr´ısloˇzkov´ y vektor z ˇctyˇrsloˇzkov´eho (ignoruje se posledn´ı hodnota). Pˇri nastavov´an´ı hodnot vektorov´ ym promˇenn´ ym n´am pom´ahaj´ı vlastnosti glsl jazyka nazvan´e swizzling a masking. Swizzling umoˇzn ˇuje pˇreh´azet sloˇzky vektoru (hodnoty na prav´e stranˇe v´ yrazu) bez psan´ı sloˇzit´ ych a dlouh´ ych konstruktor˚ u. Masking naopak umoˇzn ˇuje pˇreh´azet hodnoty na lev´e stranˇe v´ yrazu, ˇc´ımˇz se nastav´ı, do kter´ ych hodnot se m´a zapisovat. 6
Grafick´y ˇrˇetˇezec
GLSL jazyk
vec4 vector4 = another_vector.xxyw; vector4.xw = vector2;
Pro operace s vektory jsou oper´atory pˇret´ıˇzeny tak, aby se operace prov´adˇely po sloˇzk´ach. Oba vektory mus´ı m´ıt vˇsak stejn´ y poˇcet poloˇzek. N´asoben´ı vektor˚ u skal´arem pak m´a oˇcek´avateln´ y efekt, kdy se vˇsechny sloˇzky vektoru vyn´asob´ı skal´arn´ım ˇc´ıslem. U matic se d´a pˇristupovat k jednotliv´ ym sloupc˚ um (Matrx[col]) nebo k jednotliv´ ym hodnot´am (Matrx[col][row]).
2.2.5
Kvalifik´ atory promˇ enn´ ych
GLSL jazyk specifikuje obsahuje mnoho kl´ıˇcov´ ych slov, kter´e mˇen´ı nejr˚ uznˇejˇs´ı vlastnosti datov´ ych typ˚ u. Modifikuj´ı lok´alnˇe a glob´alnˇe definovan´e promˇenn´e. Kvalifik´atory mohou ovlivˇ novat zdroj dat pro promˇenn´e, zarovn´an´ı v pamˇeti ˇci sd´ılen´ı.
Kvalifik´ atory ukl´ ad´ an´ı Lok´aln´ı promˇenn´e bez kvalifik´atoru se chovaj´ı jako standardn´ı lok´aln´ı promˇenn´e, kter´e jdou inicializovat pˇri deklaraci a mˇenit. • const (promˇenn´e se nemohou bˇehem jejich existence zmˇenit, mus´ı b´ yt inicializov´any pˇri deklaraci v´ yrazem, kter´ y mus´ı b´ yt opˇet konstanta) • in, out (promˇenn´e pro vstup a v´ ystup mezi f´azemi, nem˚ uˇze b´ yt pouˇzito na lok´aln´ı promˇenn´e) • attribute (pouˇziteln´ y pouze v kompatibility m´odu a pouze ve vertex shaderu, nahrazuje kvalifik´ator in) • uniform (glob´aln´ı promˇenn´e nastaven´e uˇzivatelem v OpenGL API, hodnota se nemˇen´ı bˇehem vykreslov´an´ı, spoleˇcn´e pro vˇsechny f´aze) • varying (pouˇziteln´ y pouze v kompatibility m´odu, nahrazuje out ve vertex shaderu a in ve fragment shaderu) 7
Grafick´y ˇrˇetˇezec
GLSL jazyk
• buffer (pouze od GL 4.3, umoˇzn ˇuje sd´ılet informaci buffer objekt˚ u mezi GLSL k´odem a OpenGL API) Vstupn´ı a v´ ystupn´ı promˇenn´e mohou m´ıt jeˇstˇe specifikov´an nav´ıc jeden ze tˇr´ı interpolaˇcn´ıch kvalifik´ator˚ u – smooth, flat nebo noperspective. Kvalifik´ator smooth je pˇrednastaven´ y, kvalifik´ator flat neprov´ad´ı ˇza´dnou interpolaci a kvalifik´ator noperspective prov´ad´ı line´arn´ı interpolaci bez ohledu na perspektivu.
Kvalifik´ atory rozvrˇ zen´ı Kvalifik´atory pro rozvrˇzen´ı ovlivˇ nuj´ı, kde je ukl´adac´ı prostor pro promˇennou. Kvalifik´atory rozvrˇzen´ı mohou m´ıt i pˇriˇrazen´e hodnoty. Existuje mnoho forem jejich deklarace: • Rozvrˇzen´ı rozhran´ı – specifikuje indexy hodnot, napˇr. layout(location=0) in vec4 color; layout(location=1) in vec2 texCoord; • binding points – bloky v pamˇeti maj´ı index, kter´ y m˚ uˇze b´ yt nav´azan´ y na binding point, bloky shaderu mohou b´ yt nav´az´any na stejn´ y binding point – dojde k vytvoˇren´ı sd´ılen´eho bloku mezi shadery • Form´aty textur – tˇri hlavn´ı form´aty – Floating point – Signed integer – Unsigned integer • Atomick´ y ˇc´ıtaˇc – lze inkrementovat v shaderu a pouˇz´ıt na sˇc´ıt´an´ı pixel˚ u, chyb nebo jin´ ych charakteristik ve v´ ysledn´em obr´azku • Uniform blok (rozvrˇzen´ı blok˚ u v pamˇeti) – shared (pˇrednastaven´e, ˇza´dn´e optimalizace a rozloˇzen´ı v pamˇeti je vˇzdy stejn´e mezi r˚ uzn´ ymi programy, pokud m´am stejn´e typy a poˇrad´ı promˇenn´ ych a explicitnˇe zadan´e d´elky pol´ı) – std140 (stejnˇe jako shared se snaˇz´ı o pˇrenositelnost, nepouˇzit´e uniformy nejsou eliminov´any) 8
Grafick´y ˇrˇetˇezec
GLSL jazyk
– packed (kaˇzd´a promˇenn´a v bloku m´a byte offset, m˚ uˇze m´ıt optimalizace, ned´a se sd´ılet mezi r˚ uzn´ ymi programy)
Kvalifik´ atory parametr˚ u Parametry funkc´ı mohou m´ıt rovnˇeˇz svoje kvalifik´atory. Parametry funkc´ım m˚ uˇzeme pˇred´avat napˇr´ıklad • in – hodnotou • inout – odkazem • out – odkazem bez inicializace • const – hodnota parametru se ve funkci nem˚ uˇze mˇenit
9
3 GLSL shadery a fixn´ı ˇc´ast grafick´ eho ˇ retˇ ezce Jak jiˇz bylo dˇr´ıve ˇreˇceno, shadery jsou specifick´e programy psan´e pro urˇcit´e programovateln´e ˇca´sti grafick´eho ˇretˇezce. Zkompilovan´e a propojen´e dohromady tvoˇr´ı program, kter´ y pˇrevede vstupn´ı data na poˇca´tku grafick´eho ˇretˇezce na v´ ysledn´e pixely na obrazovce. Shadery se spouˇstˇej´ı postupnˇe a kaˇzd´ y n´asleduj´ıc´ı pˇrij´ım´a v´ ystupn´ı data pˇredchoz´ıho. Nen´ı povinn´e specifikovat program pro vˇsechny shadery.
3.1
Vertex fetch
Tato f´aze probˇehne pˇred vertex shaderem, kter´ y je prvn´ı programovatelnou ´ ˇc´ast´ı grafick´eho ˇretˇezce. Ukolem t´eto f´aze automaticky poskytuje vstupn´ı data vertex shaderu. Kromˇe hodnot vrchol˚ u mus´ı pos´ılat vertex fetch tak´e dalˇs´ı hodnoty vrchol˚ u (norm´aly, barvy, atd.). Tˇemto r˚ uzn´ ym skupin´am dat se ˇr´ık´a atributy. Mus´ıme nastavit, jak´a data v pamˇeti grafick´e karty jsou asociov´ana s jak´ ym v´ ystupem t´eto f´aze, a tedy vstupem do vertex shaderu. Nataven´ı vertex fetch ve skuteˇcnosti prob´ıh´a bud’ pouˇzit´ım OpenGL pˇr´ıkazu glBindAttribLocation nebo pˇr´ımo ve vertex shaderu pouˇzit´ım kvalifik´atoru layout(location=0) [2].
3.2
Vertex shader
Vertex shader zpracov´av´a jednotliv´e vrcholy, kter´e vstupuj´ı do grafick´eho ˇretˇezce. Poˇrad´ı zpracovan´ ych vrchol˚ u nelze ovlivnit. Kaˇzd´ y vrchol se zpracov´av´a bez informace o dalˇs´ıch vrcholech nebo jeho sousedech. z toho vypl´ yv´a, ˇze nelze napsat v´ ypoˇcet, kter´ y by vyuˇz´ıval nˇekter´ y z atribut˚ u vrchol˚ u jako uspoˇra´danou nebo jen sd´ılenou promˇennou. Z´aroveˇ n v t´ehle ˇca´sti programu ani shader nev´ı, kter´emu primitivu vrchol patˇr´ı (primitivem je myˇslen troju ´heln´ık, troj´ uheln´ıkov´ y strip, atd.). Program´ator tedy p´ıˇse k´od, kter´ y bude vykon´an paralelnˇe pro kaˇzd´ y vrchol zvl´aˇst’. Pro kaˇzd´ y vstupn´ı vrchol program vyprodukuje v´ ystupn´ı vrchol. Vrcholy budou ˇcasto obsahovat dodateˇcn´e informace ve formˇe atribut˚ u. 10
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Vertex shader
Nejˇcastˇejˇs´ımi vstupn´ımi atributy jsou pozice, norm´ala, texturovac´ı souˇradnice nebo barva. Popˇr´ıpadˇe mohou m´ıt vrcholy definov´any dalˇs´ı dodateˇcn´e hodnoty, kter´e mohou b´ yt uˇziteˇcn´e v dalˇs´ıch f´az´ıch grafick´eho ˇretˇezce. Standardnˇe budeme cht´ıt ve vertex shaderu mˇenit pozici a norm´alu vrchol˚ u na z´akladˇe matic geometrick´ ych transformac´ı. Hodnoty jako barva a texturovac´ı souˇradnice vrcholu budou vˇetˇsinou pouze posl´any do dalˇs´ı f´aze beze zmˇeny. Kromˇe vlastn´ıch uˇzivatelsky definovan´ ych promˇenn´ ych jsou pˇrednastaven´e n´asleduj´ıc´ı atributy: in int gl_VertexID in int gl_InstanceID Atribut gl_VertexID obsahuje index vrcholu. Pˇri pouˇzit´ı instancov´an´ı atribut gl_InstanceID obsahuje index souˇcasn´e instance (bez pouˇzit´ı instancov´an´ı vrac´ı vˇzdy nulu). Grafick´a karta vnitˇrnˇe vyuˇz´ıv´a indexy vrchol˚ u pro urychlen´ı v´ ykonu. Atribut gl_VertexID obsahuje stejnou hodnotu jakou m´a vrchol pˇriˇrazenou v poli index˚ u. Pˇredt´ım, neˇz je vrchol zpracov´an se porovn´a jeho ID s dalˇs´ımi indexy, kter´e jsou uloˇzeny v cache. Pokud je v cache uloˇzeno, ˇze vrchol na tomto indexu se jiˇz zpracoval, nespouˇst´ı se znovu v´ ypoˇcet pro stejn´ y vrchol a pouze se vr´at´ı uloˇzen´ y v´ ysledek z cache [2]. D´ale jsou definov´any vnitˇrn´ı v´ ystupn´ı atributy vrchol˚ u, do kter´ ych m˚ uˇze vertex shader zapisovat: outgl_PerVertex { vec4 gl_Position; float gl_PointSize; float gl_ClipDistance[]; }; Zapisov´an´ı do tˇechto atribut˚ u nen´ı povinn´e. Pokud vˇsak je dalˇs´ı f´aze fragment shader, pak se oˇcek´av´a, ˇze bude zaps´ano do gl_Position, aby fungovala vnitˇrn´ı funkcionalita rasterizace. Atribut gl_Position ukl´ad´a v´ ystupn´ı souˇradnici vrcholu v homogenn´ıch souˇradnic´ıch.
11
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Tessellation shader
Uˇzivatel m˚ uˇze definovat vlastn´ı vstupn´ı a v´ ystupn´ı atributy a jejich typy pro kaˇzd´ y vrchol. in vec3 positionIn; in vec3 normalIn; in vec2 texCoordIn; out vec2 texCoordOut; out vec3 normalOut; Uˇzivatel d´ale m˚ uˇze definovat pojmenovan´ y blok, podobnˇe jako strukturu v jazyce C. outVertexData { vec2 texCoord; vec3 normal; } VertexOut;
3.3
Tessellation shader
Napsat a nastavit tessellaˇcn´ı ˇc´ast grafick´eho ˇretˇezce je nepovinn´e. Tessellaci pouˇzijeme, pokud chceme jedno primitivum rozdˇelit na nˇekolik menˇs´ıch. Tesselaˇcn´ı shader pˇrij´ım´a z´aplaty (patches) a generuje na jejich z´akladˇe nov´a primitiva (body, ˇc´ary, troj´ uheln´ıky). Na rozd´ıl od jin´ ych primitiv maj´ı z´aplaty uˇzivatelem specifikovan´ y poˇcet vrchol˚ u. Uˇzivatel pouˇzije funkci glPatchParameteri, aby nastavil, kolik vrchol˚ u bude z´aplata m´ıt. Tato hodnota je pak konstantn´ı v pr˚ ubˇehu vol´an´ı funkce pro vykreslen´ı. glPatchParameteri(GL_PATCH_VERTICES, pocetVrcholuNaZaplatu ); Z´aplata je pole vrchol˚ u (ˇr´ıd´ıc´ıch bod˚ u), jejichˇz atributy jsou vypoˇc´ıt´any vertex shaderem. Tessellaˇcn´ı shader pak vˇetˇsinou rozdˇel´ı z´aplatu na menˇs´ı primitiva. Existuj´ı dva druhy z´aplat – troj´ uheln´ıkov´e z´aplaty a kvady. Poˇcet vrchol˚ u v z´aplatˇe vˇsak nez´avis´ı na jej´ım druhu.
12
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Tessellation shader
Tessellaˇcn´ı ˇc´ast ˇretˇezce se dˇel´ı na tˇri dalˇs´ı ˇca´sti: • tessellationControl • Primitive Generation • tessellationEvaluation Uˇzivatel m˚ uˇze napsat vlastn´ı shader pro prvn´ı a tˇret´ı ˇca´st tessellace. F´aze Primitive Generation programovateln´a nen´ı.
3.3.1
Tessellation control shader
Tessellation control shader (d´ale jen TCS) pˇrij´ım´a vstupn´ı z´aplatu, kterou tvoˇr´ı pole ˇr´ıd´ıc´ıch bod˚ u. Tyto body nemus´ı nutnˇe tvoˇrit body na v´ ysledn´em povrchu vykreslovan´eho primitiva. TCs vypoˇc´ıt´a atributy pro kaˇzd´ y vrchol v´ ystupn´ı z´aplaty. Jeho v´ ystupem je tedy pole ˇr´ıd´ıc´ıch bod˚ u (s veˇsker´ ymi jejich atributy, kter´e chceme pˇr´ıpadnˇe pˇredat). Poˇcet ˇr´ıd´ıc´ıch bod˚ u v t´eto nov´e z´aplatˇe, kter´e vystupuj´ı z TCS, se m˚ uˇze liˇsit od poˇctu ˇr´ıd´ıc´ıch bod˚ u, kter´e do nˇej p˚ uvodnˇe vstoupily. Poˇcet ˇr´ıd´ıc´ıch bod˚ u N, kter´e TCs generuje, se nastav´ı v jeho k´odu kvalifik´atorem layout: layout (vertices = N) out; TCS se spouˇst´ı se znalost´ı vˇsech ˇr´ıd´ıc´ıch bod˚ u ve vstupn´ı z´aplatˇe. Jeho ˇ v´ ystupem je vˇsak pouze jeden ˇr´ıd´ıc´ı bod. C´ıslo N udan´e v kvalifik´atoru layout tedy ud´av´a poˇcet vol´an´ı (invokac´ı) TCS. Pro indexov´an´ı v´ ystupn´ıch ˇr´ıd´ıc´ıch bod˚ u, kter´e budeme zapisovat do v´ ystupn´ı z´aplaty, pouˇzijeme promˇennou gl_InvocationID. Jak jej´ı n´azev napov´ıd´a, tato hodnota bude m´ıt r˚ uznou hodnotu indexu v r´amci jedn´e z´aplaty pro kaˇzdou invokaci TCS. R˚ uzn´a vol´an´ı TCS dokonce mohou sd´ılet v´ ystupn´ı hodnoty – mohou ˇc´ıst v´ ystupn´ı hodnoty vol´an´ı pr´avˇe prob´ıhaj´ıc´ı f´aze, kter´a zapisuje do stejn´e z´aplaty. Aby se ale mohlo toto sd´ılen´ı uskuteˇcnit, je nutn´e pouˇz´ıt synchronizaˇcn´ı mechanismy. Z´aroveˇ n tento shader zap´ıˇse pro kaˇzdou z´aplatu (nikoliv vrchol) atributy, kter´e definuj´ı u ´roveˇ n dˇelen´ıt´eto z´aplaty. Tyto atributy se naz´ yvaj´ı u ´rovnˇe tessellace (anglicky tessellation levels), d´ale jen TL. Zapisuj´ı se do pˇreddefinovan´ ych v´ ystupn´ıch promˇenn´ ych gl_TESsLevelInner a gl_TESsLevelOuter.
13
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Tessellation shader
#version 430 core layout (vertices = 3) out; void main(void) { if(gl_InvocationID == 0) { gl_TESsLevelInner[0] = 5.0; gl_TESsLevelOuter[0] = 5.0; gl_TESsLevelOuter[1] = 5.0; gl_TESsLevelOuter[2] = 5.0; } gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position; } Tabulka 3.1: Uk´azka tessellation control shaderu Protoˇze gl_TESsLevelInner a gl_TESsLevelOuter jsou hodnoty spoleˇcn´e pro celou z´aplatu, staˇc´ı do nich zapsat pouze jednou, napˇr´ıklad pˇri prvn´ı invokaci (invokace s indexem 0). Jako vstupn´ı a v´ ystupn´ı pole TCS m˚ uˇzeme pouˇz´ıt pˇreddefinovan´e gl_in a gl_out. TCS tedy vygeneruje pole transformovan´ ych kontroln´ıch bod˚ u (vrchol˚ u z´aplaty) a d´ale pro kaˇzdou z´aplatu vygeneruje mnoˇzinu ˇc´ısel zvanou TL (zn´azornˇeno na uk´azce 3.1).
3.3.2
Gener´ ator primitiv
Gener´ator primitiv (d´ale jen PG) je ˇca´st tessellaˇcn´ıho shaderu, kter´a nen´ı programovateln´a (lze pouze konfigurovat v´ ystupn´ı topologii). Tato ˇca´st grafick´eho ˇretˇezce pˇrijme mnoˇzinu ˇc´ısel TL, kter´a je v´ ysledkem TCS a na jej´ım z´akladˇe a zvolen´e topologii vygeneruje souˇradnice u, v v parametrick´em prostoru. Z´aroveˇ n urˇc´ı konektivitu vrchol˚ u. Souˇradnice u, v jsou normalizovan´e na intervalu h0; 1i a parametrick´ y prostor tvoˇr´ı bud’ ˇctverec nebo troj´ uheln´ık v pˇr´ıpadˇe barycentrick´ ych souˇradnic. Gener´ator primitiv je ˇca´st, kter´a se d´a nastavit tak, aby vracela body nebo troj´ uheln´ıky. Pokud m´a vracet body, pouze vezme hodnoty z TL a vygeneruje 14
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Tessellation shader
layout (triangles, equal_spacing, cw) in; #version 430 core layout (triangles, equal_spacing, cw) in; void main(void) { gl_Position = (gl_TESsCoord.x * gl_in[0].gl_Position + gl_TESsCoord.y * gl_in[1].gl_Position + gl_TESsCoord.z * gl_in[2].gl_Position); } Tabulka 3.2: Uk´azka tessellation evalutation shaderu uv souˇradnice pro body a poˇsle je d´ale. Pokud m´a vracet troj´ uheln´ıky, pos´ıl´a d´ale body po tˇrech jako troj´ uheln´ıky.
3.3.3
Tessellation evaluation shader
Tessellation evaluation shader (d´ale jen TES) m´a pˇr´ıstup k transformovan´ ym vrchol˚ um z TCS a k uv souˇradnic´ım z PG. Jedna instance TES se spust´ı pro ´ kaˇzd´ y bod vygenerovan´ y pomoc´ı PG. Ukolem TES je pak z vygenerovan´ ych u ´daj˚ u sestavit hodnoty v´ ystupn´ıho vrcholu. Jelikoˇz m´a TES pˇr´ıstup k vrchol˚ um z TCS, m˚ uˇze udˇelat v´ıce neˇz jen vypoˇc´ıtat absolutn´ı pozici line´arn´ı interpolac´ı pozice vrchol˚ u. Do v´ ysledn´eho v´ ypoˇctu m˚ uˇze TES pouˇz´ıt napˇr´ıklad norm´aly, nebo jak´ekoliv jin´e informace uloˇzen´e ve vrcholech. TES mus´ı vygenerovat pr´avˇe jeden vrchol za invokaci. Nem˚ uˇze se rozhodnout vrchol vypustit. Provede tedy invokaci pro kaˇzd´ y vrchol, kter´ y m´a vzniknout ve v´ ystupn´ı z´aplatˇe. Je nutn´e d´at pozor na vysok´e hodnoty TL v kombinaci se sloˇzit´ ymi polygon´aln´ımi modely nebo se sloˇzit´ ym TES, protoˇze v koneˇcn´em d˚ usledku m˚ uˇze d´ıky velk´emu mnoˇzstv´ı vrchol˚ u znatelnˇe trpˇet v´ ykon. Nastaven´ı v uk´azce 3.2 na poˇca´tku TES ˇr´ık´a, ˇze jako m´od zvol´ıme troj´ uheln´ıky. Nov´e vrcholy by mˇeli b´ yt generov´any rovnomˇernˇe mezi vrcholy polygonu, kter´ y rozb´ıj´ıme na menˇs´ı primitiva a uspoˇr´ad´an´ı vrchol˚ u v primitivu je po smˇeru hodinov´ ych ruˇciˇcek [2].
15
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
3.4
Geometry Shader
Geometry Shader
Geometry Shader (d´ale jen GS) je stejnˇe jako tessellaˇcn´ı shadery nepovinn´ y. Je to posledn´ı f´aze pˇred rasteriz´erem. Probˇehne vˇzdy jedna invokace pro jedno primitivum (napˇr´ıklad troj´ uheln´ık). Na vstupu GS jsou jednotliv´a primitiva z pˇredchoz´ı f´aze. Pokud pˇredch´azej´ıc´ı f´aze generovala troj´ uheln´ıkov´e stripy, vˇej´ıˇre nebo jin´e smyˇcky, GS pˇrijme troj´ uheln´ıky. Na rozd´ıl od Vs m´a GS nav´ıc i informaci o vˇsech vrcholech n´aleˇz´ıc´ıch k jednomu primitivu a nav´ıc informace o sousednosti, pokud jsou specifikov´any. Dok´aˇze produkovat jin´e typy primitiv, neˇz jak´a pˇrij´ım´a. Napˇr´ıklad dok´aˇze vyprodukovat samostatn´e body z troj´ uheln´ık˚ u nebo naopak troj´ uheln´ıky z bod˚ u. Moˇzn´a vstupn´ı primitiva pro GS: • body (1 vrchol) • ˇc´ary (2 vrcholy) • ˇc´ary se sousednost´ı (4 vrcholy) • troj´ uheln´ıky (3 vrcholy) • troj´ uheln´ıky se sousednost´ı (6 vrchol˚ u) Moˇzn´a v´ ystupn´ı primitiva z GS: • body • lomen´e ˇca´ry • troj´ uheln´ıkov´e p´asy GS je jedin´a f´aze v grafick´em ˇretˇezci, kter´a dok´aˇze programovˇe vygenerovat primitiva nav´ıc nebo nevygenerovat ˇz´adn´a primitiva. Tessellaˇcn´ı shadery to prov´adˇej´ı tak´e, ale pouze automaticky na z´akladˇe nastaven´ı PG. GS m˚ uˇze pouˇz´ıt funkci EmitVertex(), kter´a vezme vˇsechny nastaven´e v´ ustupn´ı promˇenn´e a prohl´as´ı, ˇze byly v´ ychoz´ı hodnoty jednoho vrcholy nastaveny a
16
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Primitive assembly, oˇrez´av´an´ı a rasteriz´er
#version 430 core layout (triangles) in; layout (points, max_vertices = 3) out; void main(void) { int i; for (i = 0; i < gl_in.length(); i++) { gl_Position = gl_in[i].gl_Position; EmitVertex(); } }
Tabulka 3.3: Uk´azka geometry shaderu funkci EndPrimitive(), kter´a vezme vˇsechny takto vyprodukovan´e vrcholy a vytvoˇr´ı z nich primitivum. Toto primitivum je pak posl´ano do rasteriz´eru [2]. K´od v uk´azce 3.3 ukazuje program GS, kter´ y pˇrijme troj´ uheln´ıky a rozdˇel´ı je na jednotliv´e body. Prvn´ı kvalifik´ator layout ˇr´ık´a, ˇze na vstupu jsou troju ´heln´ıky. Druh´ y kvalifik´ator layout ˇr´ık´a, ˇze na v´ ystupu jsou body a jejich maxim´aln´ı poˇcet. Pokud bychom chtˇeli vykreslovat troj´ uheln´ıky, mus´ıme u kvalifik´atoru layout specifikovat, ˇze chceme vykreslovat troj´ uheln´ıky m´ısto bod˚ u. Nav´ıc mus´ıme po nastaven´ı tˇr´ı vrchol˚ u (a n´asledn´em zavol´an´ı funkce EmitVertex()) zavolat funkci EndPrimitive() pro ukonˇcen´ı troj´ uheln´ıku. Tato funkce se vol´a explicitnˇe na konci shaderu, ale pokud generujeme v´ıce troj´ uheln´ık˚ u, mus´ıme j´ı pouˇz´ıt. Maxim´aln´ı poˇcet st´ale ud´av´a maxim´aln´ı poˇcet vrchol˚ u, kter´e GS generuje.
3.5
Primitive assembly, oˇ rez´ av´ an´ı a rasteriz´ er
Tato ˇca´st ˇretˇezce vezme v´ ystupn´ı vrcholy z pˇredeˇsl´e f´aze a informaci o jejich konektivitˇe vrchol˚ u. Primitive assembly nen´ı programovateln´a ˇc´ast grafick´eho ˇretˇezce. Jej´ı chov´an´ı se vˇsak d´a urˇcit nastaven´ım parametru funkce glDraw. Po tom, co bylo primitivum sloˇzeno z jednotliv´ ych vrchol˚ u, je oˇrez´ano na 17
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Fragment shader
z´akladˇe jeho pozice a zobraziteln´e ˇc´asti. Velikost zobraziteln´e ˇc´asti ud´av´a takzvan´ y viewport, jehoˇz pozice a velikost se d´a nastavit pˇr´ıkazem OpenGL glViewport. D´ale probˇehne pˇrevod vrchol˚ u z homogenn´ıho souˇradn´eho syst´emu do normalizovan´eho euklidovsk´eho prostoru. Jak´ ykoliv vrchol, kter´ y se m´a vykreslit, m´a hodnoty vˇsech zbyl´ ych tˇr´ı souˇradnic v intervalu od nuly do jedn´e. Jak´ ykoliv bod vnˇe se m´a vylouˇcit. Nejprve ale probˇehne oˇrez´an´ı, kter´e se v t´eto pr´aci nebude prob´ırat do hloubky. K oˇrez´an´ı geometrie se pouˇzije 6 poloprostor˚ u, kter´e koresponduj´ı se stˇenami krychle, kter´a tvoˇr´ı normalizovan´ y prostor. U vˇsech zbyl´ ych ˇca´st´ı geometrie se urˇc´ı viditelnost na z´akladˇe souˇradˇ asti, kter´e jsou viditeln´e, se poˇslou rasteriz´eru. Ten urˇc´ı, kter´e pinice z. C´ xely pokr´ yvaj´ı pozice primitiv a poˇsle fragment shaderu jejich seznam (spolu s ostatn´ımi interpolovan´ ymi informacemi z´ıskan´ ymi z vrchol˚ u) [2].
3.6
Fragment shader
uniform sampler2D mySampler; in vec2 texture_coordinate; out vec4 outputColor; void main() { outputColor = texture2D(mySampler, texture_coordinate); } Tabulka 3.4: Uk´azka fragment shaderu Fragment shader je posledn´ı programovateln´a f´aze grafick´eho ˇretˇezce. Tato f´aze m´a pouze nastavit barvu fragment˚ u pˇred t´ım, neˇz jsou zasl´any do bufferu, jehoˇz obsah se nakonec zobraz´ı na obrazovce. M˚ uˇzeme zde pouˇz´ıvat pˇrednastaven´e promˇenn´e jako gl_FragCoord, kter´e obsahuj´ı pozici fragmentu v oknˇe. V praxi vˇsak vˇetˇsinou budeme poˇc´ıtat barvu pixel˚ u z osvˇetlen´ı a z textur, kter´e jsou aplikov´any na vykreslovan´e povrchy. Pro osvˇetlen´ı se vyuˇzij´ı norm´aly, kter´e jsme transformovali z´aroveˇ n s pozicemi vrchol˚ u. Fragment shader n´am nyn´ı poskytuje interpolovan´e norm´aly pro kaˇzd´ y fragment. Stejnˇe tak kdyˇz potˇrebujeme aplikovat textury, tak 18
GLSL shadery a fixn´ı ˇc´ast grafick´eho ˇretˇezce
Fragment shader
budeme pouˇz´ıvat texturovac´ı souˇradnice, kter´e byly uloˇzeny ve vrcholech a nyn´ı jsou interpolov´any ve vˇsech fragmentech, kter´e koresponduj´ı s viditeln´ ymi povrchy [2]. K´od v uk´azce 3.4 ukazuje, jak nastavit v´ ystupn´ı barvu fragmentu. Vstupn´ı promˇenn´a texture_coordinate obsahuje texturovac´ı souˇradnici, kterou jsme museli propagovat z pˇredeˇsl´ ych f´az´ı grafick´eho ˇretˇezce. Obvykle je uloˇzena ve vrcholu, ale m˚ uˇzeme s n´ı bˇehem pr˚ uchodu r˚ uzn´ ymi shadery r˚ uznˇe manipulovat. Uniform promˇenn´a mySampler obsahuje vzorkovaˇc, kter´ y je prov´azan´ y s texturou.
19
4 N´astroje pro editaci shader˚ u V souˇcasn´e dobˇe existuje nˇekolik r˚ uzn´ ych n´astroj˚ u pro editaci a ladˇen´ı shader˚ u. Liˇs´ı se v´ yˇctem sv´ ych funkc´ı a nˇekdy i podporou programovac´ıch jazyk˚ u pro grafick´e karty. Nˇekter´e z tˇechto n´astroj˚ u jsou zamˇeˇren´e v´ıce na v´ yvoj jednoduch´ ych aplikac´ı, jin´e jsou zamˇeˇren´e na ladˇen´ı program˚ u.
4.1
AMD RenderMonkey (verze 1.82) [7]
Obr´azek 4.1: Rozhran´ı n´astroje RenderMonkey Program pˇrestal b´ yt vyv´ıjen. Posledn´ı verze je z data 18. 12. 2008. Jedin´ y z Testovan´ ych program˚ u, u kter´eho neexistuje verze pro Linux. Obr´azek 4.1 ukazuje pohled na rozhran´ı. AMD RenderMonkey byl vytvoˇren tak, aby umoˇzn ˇoval ˇci obsahoval n´asleduj´ıc´ı funkce:
20
N´astroje pro editaci shader˚ u
AMD RenderMonkey (verze 1.82) [7]
• v´ yvojov´e prostˇred´ı pro vytv´aˇren´ı shader˚ u • mechanismus pro ulehˇcen´ı sd´ılen´ı shader˚ u mezi v´ yvoj´aˇri • flexibiln´ı a rozˇsiˇriteln´a platforma, kter´a podporuje integraci vlastn´ıch komponent a poskytuje z´aklad pro budouc´ı v´ yvoj • prostˇred´ı, kde mohou na v´ yvoji efekt˚ u pracovat program´atoˇri, umˇelci i hern´ı design´eˇri • n´astroj, kter´ y se d´a jednoduˇse nastavit a integrovat do pracovn´ıho postupu v´ yvoj´aˇre Na str´ank´ach AMD je ozn´ameno, ˇze v´ yvoj RenderMonkey byl ukonˇcen. v posledn´ı verzi podporuje vˇsechny ShaderModely poskytovan´e do DirectX 9.0c (Shader Model 1.0 aˇz Shader Model 3.0). Lze pouˇz´ıt programovac´ı jazyky: • HLSL (do verze DirectX 9.1) • GLSL(do verze 2.0) • Es (2.0)
4.1.1
Funkce a charakteristiky software
• schopnost exportovat GLSL efekty jako: – collada soubory (form´at pro interaktivn´ı 3D model definovan´ y otevˇren´ ym XML form´atem),collada import´er podporuje pouze troju ´heln´ıkov´e s´ıtˇe – soubory fx (Microsoft DirectX 9.0) • podpora HW tessellace pro verzi ATI Radeon 2000 a v´ yˇse • moˇznost pˇripojit ˇci naprogramovat plug-in (vygeneruje se projekt Microsoft Visual Studio 2005) • podpora pro shader model 3 (vzorkov´an´ı textur ve vertex shaderu) • knihovna pˇr´ıklad˚ u pro HLSL, GLSL, Es a assemblylanguage 21
N´astroje pro editaci shader˚ u
AMD RenderMonkey (verze 1.82) [7]
• vykreslov´an´ı na celou obrazovku • zobrazov´an´ı textur 2D, 3D a kubick´ ych map • gener´ator srsti / ˇsupin • hl´aˇsen´ı run-time chyb • editory pro v´ yvoj: – vertex shaderu – fragment shaderu
4.1.2
Rozhran´ı
• workplace – abstraktn´ı strom pro uloˇzen´ı projektu – modely – textury – efekty ∗ parametry efekt˚ u ∗ vertex shader ∗ fragmentshader (pixel shader) • okno n´ahledu na zobrazen´ı modelu a efektu • editory pro shadery a GUI editory pro parametry shader˚ u • okno zpr´av – kompilace – chyby – textov´e zpr´avy z aplikace • artist editor – editor parametr˚ u efekt˚ u
22
N´astroje pro editaci shader˚ u
4.1.3
AMD RenderMonkey (verze 1.82) [7]
Editor
Doplˇ nov´an´ı k´odu a naˇsept´avaˇc je pˇr´ıtomn´ y pouze v nejv´ıce primitivn´ı formˇe, kdy naˇsept´avaj´ı pouze sloˇzky vektor˚ u x, y, z a w po naps´an´ı teˇcky. Nikdy nenaˇsept´av´a rezervovan´a slova, funkce nebo promˇenn´e. Syntaktick´e chyby nejsou podtrh´av´any. Chyby pˇri kompilaci se nedaj´ı dohled´avat dost jednoduˇse. Editor postr´ad´a schopnost oznaˇcit kl´ıˇcov´e slovo nebo ˇr´adku, ve kter´e nastala chyba. V logu se pouze vyp´ıˇse popis chyby, kter´ y je sm´ısen´ y s dalˇs´ımi zpr´avami o kompilaci. Chybov´a hl´aˇsen´ı nejsou od dalˇs´ıho textu nijak zv´ yraznˇena. V chybov´em hl´aˇsen´ı se zobraz´ı popis chyby a odkaz na ˇra´dku. Bohuˇzel v oknˇe s programov´ ym k´odem nen´ı ˇc´ıslov´an´ı ˇra´dek a ani nikde nen´ı zv´ yraznˇeno ˇc´ıslo ˇra´dky, na kter´e se nach´az´ı kurzor.
4.1.4
Ladˇ en´ı shader˚ u
Pro vykreslen´ı sc´eny mus´ıme m´ıt minim´alnˇe model (popˇr. textury a dalˇs´ı zdroje), kter´ y pouˇzijeme na vstupu, vertex shader a fragment shader. Na model se aplikuj´ı textury a shadery a n´asledn´a vizualizace prob´ıh´a ve smyˇcce. V nastaven´ı (Edit/Preferences/General) lze nastavit ˇcasov´ y interval pro vykreslovac´ı smyˇcku, popˇr´ıpadˇe interval pro obnovov´an´ı textur a modelu. Tato funkcionalita napom´ah´a uˇzivateli prov´adˇet zmˇeny za bˇehu vizualizace. K´od ˇ ıd´ıc´ı k´od vizualizaˇcn´ı smyˇcky se prov´ad´ı shader˚ u lze tak´e mˇenit za bˇehu. R´ internˇe a nelze jej upravovat. Sc´ena lze animovat pouze pomoc´ı pouˇzit´ı promˇenn´e pro ˇcas. Do projektu se vloˇz´ı nov´a promˇenn´a (float) se s´emantikou ˇcas (Time0_X), a tato promˇenn´a se pouˇzije v k´odu shaderu. Kaˇzd´ y sn´ımek se provede inkrementace t´eto hodnoty. Protoˇze se po kaˇzd´e sekundˇe hodnota zv´ yˇs´ı o 1, nen´ı tento zp˚ usob z´avisl´ y na rychlosti sn´ımkov´an´ı. Sloˇzitˇejˇs´ı efekty vyˇzaduj´ı nˇekolik pr˚ uchod˚ u. V takov´emto pˇr´ıpadˇe se mus´ı nastavit poˇcet pr˚ uchod˚ u a pro kaˇzd´ y pr˚ uchod nastavit nov´ y vertex shader, fragment shader a popˇr´ıpadˇe dalˇs´ı parametry grafick´e pipeline (mus´ı se pˇridat takzvan´ y render state block“, kter´ y nastavuje stav OpenGL ˇci DirectX). ” Vˇsechny shadery mus´ı b´ yt zad´any staticky a mus´ı se zkop´ırovat. Nelze pouˇz´ıt jeden objekt shaderu v´ıcekr´at, a to ani pˇresto, ˇze chceme v r˚ uzn´ ych pr˚ uchodech napˇr´ıklad pouˇz´ıt identick´ y vertex shader. Takov´eto chov´an´ı je jednoduch´e pro pouˇzit´ı, ale nen´ı dostateˇcnˇe flexi23
N´astroje pro editaci shader˚ u
Glsl Hacker (verze 0.5.0) [8]
biln´ı. Nelze prov´adˇet ˇz´adn´e pokroˇcilejˇs´ı operace, jako napˇr´ıklad programovˇe zadan´ y poˇcet pr˚ uchod˚ u. Zobrazov´an´ı v´ıce objekt˚ u se d´a emulovat pouze t´ım zp˚ usobem, ˇze se vyuˇzije syst´em pr˚ uchod˚ u – kaˇzd´ y dalˇs´ı objekt se vykresl´ı v nov´em pr˚ uchodu. Samozˇrejmˇe je t´ım znemoˇznˇeno napˇr´ıklad zobrazov´an´ı procedur´alnˇe generovan´ ych objekt˚ u, protoˇze kaˇzd´ y objekt mus´ı b´ yt nastaven zvl´aˇst’ v oknˇe Workplace.
4.1.5
Export
RenderMonkey umoˇzn ˇuje export zdroj˚ u do soubor˚ u fx nebo collada, kter´e n´aslednˇe mohou pouˇz´ıt dalˇs´ı aplikace. Exportem se ale nevytvoˇr´ı aplikace se zobrazovac´ı smyˇckou, z´ısk´ame j´ım pouze tyto soubory. Pokud bychom chtˇeli napodobit programovˇe vizualizaci programu Render Monkey, museli bychom sami naprogramovat zobrazovac´ı smyˇcku a v n´ı pouˇz´ıt tyto shadery.
4.2
Glsl Hacker (verze 0.5.0) [8]
Byla vyzkouˇsena verze z 9. 5. 2013. N´astroj navrˇzen pro rychl´e 3D prototypov´an´ı shader˚ u. Glsl Hacker m´a svoje API na niˇzˇs´ı u ´rovni abstrakce. Je zapotˇreb´ı v´ıce k´odu, ale t´ım poskytuje v´ıce moˇznost´ı, co se t´ yˇce vykreslov´an´ı sc´eny. Bohuˇzel, tyto moˇznosti je moˇzno vyuˇz´ıt jen pokud chceme sestavit sc´enu ve skriptovac´ıch jazyc´ıch Python nebo Lua. Tato verze existuje pouze na 64bitov´e syst´emy. Posledn´ı vyv´ıjen´a verze 0.6.0 bude spustiteln´a i na 32bitov´ ych syst´emech. Obr´azek 4.2 ukazuje pohled na rozhran´ı. Tato verze neobsahuje skoro ˇza´dn´e grafick´e rozhran´ı. M´a stavovou ˇr´adku, kter´a umoˇzn ˇuje napsat pˇr´ıkaz ve skriptovac´ım jazyce a ihned jej vykonat. V jazyc´ıch Lua nebo Python se nap´ıˇse jeden ˇci nˇekolik inicializaˇcn´ıch skript˚ u a d´ale se nap´ıˇse jeden ˇci nˇekolik skript˚ u pro vykreslov´an´ı sn´ımk˚ u.
4.2.1
Funkce a charakteristiky software
• umoˇzn ˇuje mˇenit za bˇehu aplikace: – GLSL programov´ y k´od ∗ vertex shader 24
N´astroje pro editaci shader˚ u
Glsl Hacker (verze 0.5.0) [8]
Obr´azek 4.2: Rozhran´ı n´astroje GLSL Hacker ∗ ∗ ∗ ∗ ∗
fragment shader geometry shader tessellation control shader tessellation evaluation shader computation shader
– vykreslovac´ı smyˇcka (Lua skript nebo Python skript) ∗ init ∗ resize ∗ update • S´ıt’ov´e pˇripojen´ı pro ladˇen´ı programu na jin´em stroji
25
N´astroje pro editaci shader˚ u
4.2.2
Glsl Hacker (verze 0.5.0) [8]
Rozhran´ı
Rozhran´ı je velice minimalistick´e. Obsahuje pouze hlavn´ı nab´ıdku a plochu, kde se bude zobrazovat vykreslen´a sc´ena. V hlavn´ı nab´ıdce je volba naˇc´ıt´an´ı sc´eny a na zobrazen´ı n´apovˇedy ˇci dokumentace. Hlavn´ı funkcionalita tohoto software je dostupn´a v n´astroj´ıch. Zde se d´a editovat skript inicializace, zobrazovac´ı smyˇcky i GLSL k´od. Editace k´odu se m˚ uˇze prov´adˇet bud’ na pˇr´ıkladu, kter´ y je spuˇstˇen´ y pˇr´ımo v aplikaci, nebo je moˇzn´e se pˇripojit pˇres s´ıt’ na jin´ y server, na kter´em je tento program spuˇstˇen´ y.
4.2.3
Editor
Editor je velmi minimalistick´ y. Nem´a ˇza´dn´e zv´ yrazˇ nov´an´ı k´odu, ˇz´adn´e naˇsept´av´an´ı k´odu ani ˇza´dn´e funkce na rozbalov´an´ı funkˇcn´ıch blok˚ u. Jedn´a se pouze o jednoduch´ y textov´ y box. Dokonce uˇz´ıv´a neproporcion´aln´ı font, kter´ y se norm´alnˇe pro programov´ y k´od nepouˇz´ıv´a. Dalˇs´ı vlastnost´ı tohoto editoru je, ˇze neobsahuje v˚ ubec ˇz´adn´e ovl´adac´ı prvky. Volby Zpˇet a Vpˇred obsahuje pouze po prav´em kliknut´ı do textov´eho boxu, nem´a ˇza´dn´e vyhled´av´an´ı ˇretˇezc˚ u, nem´a ˇc´ıslov´an´ı ˇra´dek a nem´a dokonce ani volbu uloˇzen´ı zmˇen. M´ısto toho se zmˇeny aplikuj´ı vˇzdy okamˇzitˇe. Pokud se v k´odu objev´ı chyba, vizualizace jednoduˇse ukazuje posledn´ı funkˇcn´ı verzi a v jednoduch´em editoru se objev´ı pouze indikace, jestli je k´od syntakticky v poˇr´adku ˇci nikoliv. V editoru, kter´ y je vytvoˇren pro s´ıt’ovou verzi, je m´ısto t´eto ˇra´dky log ud´alost´ı, ale chyby jsou rovnˇeˇz bez jak´ehokoliv popisu.
4.2.4
Ladˇ en´ı shader˚ u
Pˇri ladˇen´ı shader˚ u, jeˇz vyuˇz´ıvaj´ı funkce, kter´e nejsou hardwarovˇe podporov´any na pˇr´ısluˇsn´em stroji, se nedaˇr´ı mˇenit k´od shader˚ u. V takov´em pˇr´ıpadˇe se dokonce ani neukl´adaj´ı zmˇeny. V pˇr´ıpadech, kdy je vˇse podporov´ano je moˇzno mˇenit shadery za bˇehu vizualizace. Vlastnost, kter´a zp˚ usobuje, ˇze se vizualizace aktualizuje po zmˇenˇe kaˇzd´eho znaku v k´odu shader˚ u, m˚ uˇze b´ yt nˇekdy velmi nepˇr´ıjemn´a.
26
N´astroje pro editaci shader˚ u
4.3
gDEBugger (verze5.8.1) [9]
gDEBugger (verze5.8.1) [9]
Obr´azek 4.3: Rozhran´ı n´astroje gDEBugger Profesion´aln´ı aplikace pro ladˇen´ı program˚ u vyuˇz´ıvaj´ıc´ıch OpenGL a OpenCL. Testovan´a verze vyˇsla 11. 12. 2012. Sleduje aktivitu nad OpenGL nebo OpenCL programem a poskytuje informace potˇrebn´e pro nalezen´ı chyb v aplikaci nebo pro jej´ı u ´pravu za u ´ˇcelem optimalizace. Aplikace gDEBugger GL umoˇzn ˇuje sledovat aktivitu ˇca´st´ı k´odu v uˇzivatelem spuˇstˇen´e OpenGL aplikaci. Uk´azka rozhran´ı je na obr´azku 4.3.
4.3.1
Funkce a charakteristiky software
• profesion´aln´ı n´astroj na ladˇen´ı grafick´ ych OpenGL aplikac´ı • schopnost krokov´an´ı aplikac´ı z pohledu vol´an´ı OpenGL funkc´ı • moˇznost upravovat GLSL k´od shader˚ u • tˇri z´akladn´ı m´ody – ladˇen´ı, profilov´an´ı a analyz´ator pamˇeti
27
N´astroje pro editaci shader˚ u
4.3.2
gDEBugger (verze5.8.1) [9]
Rozhran´ı
• historie volan´ ych funkc´ı • v´ ykonnostn´ı graf • sledov´an´ı OpenGL promˇenn´ ych (projekˇcn´ı matice, modelview matice,. . . ) • z´asobn´ık volan´ ych funkci • log ud´alost´ı • vlastnosti (poloˇzek oznaˇcen´ ych ve v´ ykonnostn´ım grafu) • dashboard na zobrazov´an´ı statistik (vyuˇzit´ı procesoru, sn´ımky za sekundu, OpenGL vol´an´ı za sekundu)
4.3.3
Editor
Editor programu Editor zdrojov´eho k´odu m´a zv´ yrazˇ nov´an´ı syntaxe, postr´ad´a ale naˇsept´av´an´ı k´odu. Zv´ yrazˇ nov´an´ı syntaxe se d´a zvolit pro jazyky: Ada, Assembler, C++, CS, CSS, Fortran, GLSL, CL, HTML, Java, Javascript, Objective-C ,Pascal, Pearl, PHP, Python, Visual Basic a VB skript. M´a schopnost rozvinut´ı a kolapse k´odu funkc´ı v editoru. Nedok´aˇze podtrh´avat syntaktick´e chyby bˇehem editace k´odu. Nen´ı propojen s kompil´atorem. Nen´ı tedy moˇzn´e editovat k´od aplikace za bˇehu. Je tomu tak vzhledem k tomu, ˇze program je urˇcen k ladˇen´ı v´ ysledn´ ych bin´arn´ıch aplikac´ı.
Editor shader˚ u Editov´an´ı k´odu za bˇehu je moˇzn´e pouze u zdrojov´eho k´odu shader˚ u. V oknˇe historie volan´ ych funkc´ı lze oznaˇcit funkci, kter´a m´a shader jako sv˚ uj asociovan´ y parametr. Pˇres okno vlastnost´ı (properties) se m˚ uˇzeme dostat na editaci k´odu shaderu. Tento editor m´a zabudov´ano zv´ yrazˇ nov´an´ı syntaxe GLSL. Nem´a ˇza´dn´e naˇsept´av´an´ı k´odu ani podtrh´av´an´ı neplatn´e syntaxe. Pouze se po kompilaci 28
N´astroje pro editaci shader˚ u
gDEBugger (verze5.8.1) [9]
odk´aˇze na ˇc´ıslo ˇra´dky, ve kter´e nastala chyba. V´ ystup kompilace je vidˇet v pˇrehledn´e tabulce. Na chybn´e ˇra´dky se d´a pˇrej´ıt hypertextov´ ym odkazem. Nav´ıc se d´a zapnout ˇc´ıseln´e oznaˇcen´ı ˇr´adek pomoc´ı volby View. Editor d´ale dok´aˇze zobrazovat mezery a odˇra´dkov´an´ı. Stejnˇe jako druh´a verze editoru pro zdrojov´ y k´od, dok´aˇze prov´est rozvinut´ı a kolaps podprogram˚ u. Jakmile je shader zkompilov´an a sestaven, m˚ uˇzeme opˇet rozbˇehnout program a zmˇeny se okamˇzitˇe projev´ı na v´ ystupu bez nutnosti restartovat program. Vˇsechny zmˇeny, kter´e uˇzivatel uˇcin´ı pomoc´ı programu gDEBugger budou ale zapomenuty po restartov´an´ı aplikace.
4.3.4
Ladˇ en´ı shader˚ u
Podporuje vertex shader, fragment shader a geometry shader. Tato aplikace byla vytvoˇrena zcela za u ´ˇcelem lazen´ı. Vˇetˇsina informac´ı se ale objevuje pouze, kdyˇz je aplikace pozastavena. Pokud se aplikace pozastav´ı na break pointu, zastaven´ı nenastane ihned, ale pouze na dalˇs´ım OpenGL vol´an´ı (pˇri spuˇstˇen´em m´odu pro ladˇen´ı nebo pro anal´ yzu) nebo na konci sn´ımku (pˇri spuˇstˇen´em m´odu pro profilov´an´ı). Je moˇzn´e pˇrid´avat break pointy na zaˇca´tek OpenGL. To se vykon´a pˇrid´an´ım v oknˇe vyvolan´em zkratkou Ctrl+B. Pokud si d´ame breakpoint napˇr´ıklad jako glBegin, m˚ uˇzeme sledovat postup algoritmu bud’ po jednotliv´ ych kroc´ıch (Single Step), pˇreskoˇcit dalˇs´ı funkce dokud nenaraz´ıme na dalˇs´ı vykreslen´ı (Draw Step) nebo m˚ uˇzeme pˇreskoˇcit na stejn´ y breakpoint v dalˇs´ım sn´ımku (Frame Step). Pouˇzit´ım tohoto prostˇred´ı se d´a snadno prov´est oprava aplikace, protoˇze m˚ uˇzeme naj´ıt a opravit probl´emy typu: • chyby OpenGL (volba break on OpenGLErrors) – vrac´ı OpenGL implementace; zp˚ usobeny ˇspatn´ ymi v´ yˇcty ˇci vol´an´ım funkc´ı kdyˇz nejsou relevantn´ı • detekovan´e chyby – napˇr´ıklad pokud se pouˇz´ıv´a pixel form´at, kter´ y nen´ı hardwarovˇe akcelerovan´ y • nadbyteˇcn´e zmˇeny OpenGL stav˚ u • pouˇz´ıv´an´ı nedoporuˇcen´ ych OpenGL funkc´ı 29
N´astroje pro editaci shader˚ u
gDEBugger (verze5.8.1) [9]
• software fallback – nast´av´a, pokud kombinace OpenGL stav˚ u nen´ı podporov´ana nebo akcelerov´ana na grafick´em hardware; v takov´em pˇr´ıpadˇe se pˇrep´ın´a do softwarov´eho m´odu a t´ım je znaˇcnˇe sn´ıˇzen v´ ykon Kdyˇz je aplikace vyˇciˇstˇena od vˇsech probl´em˚ u zp˚ usoben´ ych vol´an´ım OpenGL funkc´ı, d´a se n´astroj pouˇz´ıt pro detekov´an´ı a opraven´ı pˇr´ıpad˚ u neuvolnˇen´ ych grafick´ ych objekt˚ u z pamˇeti. N´astroj gDEBugger dok´aˇze nav´ıc zobrazovat informace o textur´ach a bufferech. Tyto informace jsou sb´ır´any za bˇehu a daj´ı se zobrazit v oknˇe vyvolan´em Ctrl+T. Zde lze vybrat libovolnou texturu ˇci buffer (DepthBuffer, Front Buffer, BackBuffer apod.), a pak v prav´e ˇca´sti okna vid´ıme obsah textury ˇci bufferu s pˇresn´ ymi informacemi o barvˇe v kaˇzd´em pixelu. Lze zapnout ˇci vypnout kan´aly RGB, popˇr´ıpadˇe kan´al alfa. V druh´em listu nazvan´em Data View m˚ uˇzeme vidˇet obr´azek pouze v numerick´ ych hodnot´ach. U 3D textur lze navigovat mezi vrstvami textury, podobˇe u pole textur. Lze zobrazit i Vertex BufferObject, ale pouze v reˇzimuData View.
4.3.5
Statistiky
Program dok´aˇze vypsat statistiky Ctrl+Shift+S. V tˇechto statistik´ach m˚ uˇzeme vidˇet procentu´aln´ı pomˇer zastoupen´ı volan´ ych OpenGL funkc´ı dle jejich typu (texturovac´ı, maticov´e, resterizaˇcn´ı). Pomˇer zastoupen´ı jednotliv´ ych funkc´ı zn´azornˇen´ y ve sloupcov´em grafu lze vidˇet v doln´ı ˇca´sti okna. Toto okno m´a speci´aln´ı z´aloˇzku na zobrazen´ı zastaral´ ych (tzv. deprecated) funkc´ı, kde jsou vˇsechny pouˇzit´e vyps´any vˇcetnˇe detail˚ u, kdy byla funkce takto oznaˇcena, ve kter´e verzi byla pˇr´ıpadnˇe vymaz´ana, poˇcet vol´an´ı funkce do aktu´aln´ıho breakpointu ˇci procentu´aln´ı zastoupen´ı vzhledem k ostatn´ım funkc´ım. Ostatn´ı volan´e funkce m˚ uˇzeme vidˇet v z´aloˇzce FunctionCalls, kde jsou uvedeny ke kaˇzd´e funkci dalˇs´ı podrobnosti. Zejm´ena jsou pak zv´ yraznˇena doporuˇcen´ı pˇr´ıpadnˇe nepouˇz´ıvat nevhodnou a nahradit ji za jinou. Dalˇs´ı zaj´ımavou statistikou je poˇcet skupin vrchol˚ u, kter´e se bˇehem jednoho sn´ımku pos´ılaj´ı na zpracov´an´ı. Je zvykem snaˇzit se ps´at program tak, aby se najednou pos´ılalo vˇzdy co nejvˇetˇs´ı mnoˇzstv´ı vertex˚ u, ˇc´ımˇz se zv´ yˇs´ı v´ ykon aplikace. 30
N´astroje pro editaci shader˚ u
4.3.6
gDEBugger (verze5.8.1) [9]
Profilov´ an´ı
V hlavn´ım oknˇe m˚ uˇzeme vidˇet ˇcasovou osu, na kter´e je zn´azornˇen v´ ykonnostn´ı graf. Existuj´ı tˇri skupiny ˇc´ıtaˇc˚ u: • ˇc´ıtaˇce specifick´e pro operaˇcn´ı syst´em – sleduj´ı v´ ykon z pohledu spr´avy syst´emov´ ych zdroj˚ u (spr´ava pamˇeti, vyuˇzit´ı procesoru apod.). • ˇc´ıtaˇce specifick´e pro grafick´ y hardware – pouze pouˇziteln´e pro nˇekter´ y hardware (NVIDIA, ATI/AMD, S3 Graphicsa 3DLabs), za podm´ınky ˇze jsou instalov´any pˇr´ısluˇsn´e ovladaˇce. • gDEBugger ˇc´ıtaˇce – zde lze sledovat napˇr´ıklad poˇcet sn´ımk˚ u za sekundu, poˇcet vol´an´ı OpenGL funkc´ı a ˇc´ıtaˇc˚ u, poˇcet troj´ uheln´ık˚ u ˇci vrchol˚ u na sn´ımek atd.
4.3.7
Anal´ yza
M´od anal´ yzy umoˇzn ˇuje sledov´an´ı podrobn´ ych informac´ı o funkc´ıch na zmˇenu stavu a vyhled´av´an´ı redundantn´ıch pouˇzit´ı takov´ ychto funkc´ı. Z´ısk´av´an´ı informac´ı pro pouˇzit´ı tohoto sledov´an´ı vˇsak m´a velk´ y dopad na v´ ykon aplikace. Tento m´od funguje podobnˇe jako m´od na z´ısk´av´an´ı statistik. Zpomalen´ı je zp˚ usobeno t´ım, ˇze se mus´ı vyhodnocovat a ukl´adat vˇetˇs´ı mnoˇzstv´ı ukazatel˚ u, aby se redundantn´ı stavy odhalily. Ty se na rozd´ıl od obyˇcejn´ ych statistik, kdy se sˇc´ıt´a poˇcet v´ yskyt˚ u vol´an´ı, mus´ı obohatit o porovn´av´an´ı hodnot ve vˇsech pˇredchoz´ıch stavech. D´ıky tˇemto porovn´an´ım se m˚ uˇze napˇr´ıklad zjistit, ˇze dan´e konkr´etn´ı vol´an´ı vˇzdy nastavuje stav na stejnou hodnotu, jak´a byla pˇred t´ımto vol´an´ım. Okno na statistiky z´ıskan´e v m´odu anal´ yzy se vyvol´av´a pomoc´ı zkratky Ctrl+Shift+S. Jedn´a se st´ale o stejn´e okno. Tentokr´at n´as zaj´ım´a hlavnˇe z´aloˇzka StateChange, kter´a zde m˚ uˇze m´ıt nˇekolik z´aznam˚ u o vol´an´ı, jeˇz ve 100% pˇr´ıpad˚ u nastavila stejn´ y stav, kter´ y byl pˇred zavol´an´ım dan´eho nastaven´ı.
31
N´astroje pro editaci shader˚ u
4.3.8
GlslDevil (verze 1.1.5) [10]
N´ asledn´ıci projektu gDEBugger
gDEBugger AMD (verze 6.2) [14] Verze gDEBuggeru pro AMD grafick´e karty, kter´a vyˇsla 20. 4. 2012. Rozhran´ı t´eto verze se liˇs´ı od p˚ uvodn´ı. Nem´a napˇr´ıklad rozdˇelen´ı na tˇri m´ody (ladˇen´ı, profilov´an´ı a anal´ yza pamˇeti). Nen´ı moˇzn´e spustit profilov´an´ı a sledovat tak zvolen´e promˇenn´e v grafu pˇri bˇehu aplikace. Z pohledu vlastnost´ı, kter´e je vhodn´e uv´aˇzit pro zpracov´an´ı t´eto diplomov´e pr´ace, nepˇrin´aˇs´ı aplikace nic nov´eho oproti jej´ı druh´e verzi. Zd´a se, ˇze sp´ıˇse nˇekter´e funkce ztr´ac´ı (kompilace shader˚ u a profilaˇcn´ı m´od). Na str´ance projektu je uvedeno, ˇze jiˇz nebudou ˇz´adn´e dalˇs´ı verze gDEBuggeru, kromˇe moˇzn´ ych oprav chyb. Projekt, kter´ y je n´asledn´ıkem gDEBuggeru se naz´ yv´a CodeXL.
CodeXL (verze 1.3) [15] Jako n´astupce gDEBuggeru je CodeXL takt´eˇz pokroˇcil´ y n´astroj pro ladˇen´ı program˚ u vyuˇz´ıvaj´ıc´ıch OpenGL nebo OpenCL. Stejnˇe jako jeho pˇredch˚ udce m´a mnoho n´astroj˚ u pro ladˇen´ı, profilov´an´ı a anal´ yzu aplikac´ı z pohledu na GPU, CPU a novˇe i APU. Nab´ız´ı rovnˇeˇz statickou anal´ yzu j´adra OpenCL. Testovan´ y program vyˇsel 11. 11. 2013. Tento program nab´ız´ı opˇet tˇri m´ody (ladˇen´ı, profilov´an´ı a anal´ yza pamˇeti). Na druhou stranu ale st´ale nedok´aˇze mˇenit program shader˚ u. V´ yvoj tohoto programu se ub´ır´a mnohem v´ıce smˇerem ladˇen´ı a anal´ yzy jiˇz zkompilovan´ ych program˚ u. Prvn´ı zkouman´a verze m´a v´ yhodnou vlastnost, kter´a n´am umoˇzn ˇuje mˇenit program shader˚ u za bˇehu programu. Tato vlastnost se ale pravdˇepodobnˇe autor˚ um nejev´ı jako d˚ uleˇzit´a pro hlavn´ı u ´ˇcel aplikace – profilov´an´ı a zjiˇst’ov´an´ı v´ ykonnosti a moˇzn´ ych chyb v programu. Proto n´asleduj´ıc´ı verze programu jiˇz tuto vlastnost neimplementuj´ı.
4.4
GlslDevil (verze 1.1.5) [10]
N´astroj pro ladˇen´ı OpenGL grafick´eho ˇretˇezce. Stejnˇe jako gDEBugger dok´aˇze ladit OpenGL programy bez nutnosti opˇetovn´e kompilace nebo dokonce 32
N´astroje pro editaci shader˚ u
GlslDevil (verze 1.1.5) [10]
Obr´azek 4.4: Rozhran´ı n´astroje GlslDevil bez zdrojov´eho k´odu (data pro ladˇen´ı jsou z´ısk´av´ana z hardwarov´e realizace ˇretˇezce). Posledn´ı verze (1.1.5) nepodporuje ladˇen´ı aplikac´ı, kter´e jsou v´ıcevl´aknov´e. Nav´ıc, nelze ladit 32bitov´e aplikace za pouˇzit´ı 64bitov´e verze GlslDevil. Posledn´ı verze byla nahr´ana v roce 16. 2. 2010. Obr´azek 4.4 ukazuje rozhran´ı n´astroje.
4.4.1
Rozhran´ı
• OpenGL trace – poskytuje funkcionalitu pro ovl´ad´an´ı ladˇen´ı, zobrazuje proud OpenGL pˇr´ıkaz˚ u, umoˇzn ˇuje krokov´an´ı, pˇreskakov´an´ı funkc´ı a dokonce i u ´pravu OpenGL funkc´ı a jejich parametr˚ u 33
N´astroje pro editaci shader˚ u
GlslDevil (verze 1.1.5) [10]
– umoˇzn ˇuje spustit program a z´aroveˇ n vypisovat lad´ıc´ı informace, coˇz ale velmi zpomaluje bˇeh programu – je moˇzn´e skoˇcit na dalˇs´ı vykreslen´ı, dalˇs´ı zmˇenu shaderu nebo vol´an´ı dalˇs´ı funkce (zadan´e uˇzivatelem) • shader source – editory pro vertex, fragment a geometry shadery • GL trace statistics – pˇrehled volan´ ych OpenGL funkc´ı • Watch • Shader Variables • GL Buffer View
4.4.2
Ladˇ en´ı shader˚ u
Podporuje vertex shader, fragment shader a geometry shader. Pˇri ladˇen´ı geometry shaderu se m˚ uˇzeme pod´ıvat na detailn´ı informace o kaˇzd´em primitivu, aktu´aln´ı hodnoty dat a v´ ystupn´ı vrcholy. Lze dokonce vizualizovat data z geometry shaderu. Vizualizace m˚ uˇze napˇr´ıklad pouˇz´ıvat r˚ uzn´e barvy pro generovan´e vertexy dle jejich indexu. Ladˇen´ı shaderu se vykon´av´a na u ´rovni jednoho vykreslen´ı, kde vˇsechny dotyˇcn´e elementy jsou krokov´any souˇcasnˇe. Aby bylo moˇzn´e ladit shader, je nutn´e, aby byl program ve specifick´em stavu, a tud´ıˇz po vol´an´ı vykreslovac´ı funkce.
4.4.3
Funkcionalita
Tento program je bohuˇzel neudrˇzovan´ y a mˇel probl´emy s ladˇen´ım shader˚ u na vˇsech Testovan´ ych stanic´ıch. Velmi ˇcasto se st´avalo, ˇze se program zastavil pˇri spuˇstˇen´ı na chybˇe nazvan´e Internal debugger error“. V pˇr´ıpadˇe program˚ u, ” kter´e ˇsly spustit, nebylo nikdy moˇzn´e prov´est ladˇen´ı shader˚ u. Aplikace vˇzdy skonˇcila pˇri prvn´ım pokusu o jejich krokov´an´ı. Vzhledem k tomu, ˇze se nedaˇrilo naleznout ˇreˇsen´ı pro chyby, kter´e nast´avaly, a vzhledem k tomu, ˇze je projekt neudrˇzovan´ y, nemohlo b´ yt Testov´an´ı programu dokonˇceno.
34
N´astroje pro editaci shader˚ u
4.5
KickJs GLSL Shader Editor [11]
KickJs GLSL Shader Editor [11]
Obr´azek 4.5: Rozhran´ı webov´e str´anky KickJs KickJs GLSL Shader Editor je aplikace, kter´a se d´a spustit ve webov´em prohl´ıˇzeˇci. Uk´azka rozhran´ı prohl´ıˇzeˇce je na obr´azku 4.5. Podle dokumentace jsou podporov´any (toho ˇcasu) nejnovˇejˇs´ı prohl´ıˇzeˇce Mozilla Firefox a Google Chrome. Internet Explorer verze 10 nepodporuje KickJS. Aplikace fungovala i v prohl´ıˇzeˇc´ıch Firefox verze 23.0, Chrome verze 30 a Opera verze 17.0. Posledn´ı aktualizace pˇred Testov´an´ım aplikace probˇehla 21. 7. 2013.
4.5.1
Funkce a charakteristiky software
• testov´an´ı shader˚ u (fragment shader, vertex shader) • nastavov´an´ı uniform promˇenn´ ych spoleˇcn´ ych pro oba shadery • v animaˇcn´ı smyˇcce lze mˇenit pouze – textury (pouze obr´azky pˇr´ıstupn´e ze str´anky www.kickjs.org ve sloˇzce /example/shader editor/) – glob´aln´ı nastaven´ı pipeliny (face curling, z-TESt atd.) – ortogon´aln´ı nebo perspektivn´ı kamera – v´ ybˇer jednoho z pˇrednastaven´ ych model˚ u 35
N´astroje pro editaci shader˚ u
KickJs GLSL Shader Editor [11]
– pohyb modelu (model bude statick´ y nebo bude rotovat)
4.5.2
Rozhran´ı
Internetov´a aplikace rozdˇeluje okno na nˇekolik pomysln´ ych ˇca´st´ı. V horn´ı ˇc´asti okna jsou volby, kter´e se u vˇetˇsiny aplikac´ı nach´az´ı na liˇstˇe pod volbou soubor (file). Bohuˇzel, akce naˇc´ıst a uloˇzit ukl´adaj´ı pouze stav aplikace (lze je prov´est pouze po pˇrihl´aˇsen´ı na google u ´ˇcet). V´ ysledek se ned´a nijak exportovat. Uloˇzen´e z´achytn´e body se mohou pouze pouˇz´ıt pro dalˇs´ı Testov´an´ı chodu v aplikaci KickJS. V´ ysledn´a sc´ena je vidˇet v mal´em oknˇe vlevo nahoˇre. Je moˇzno zapnout reˇzim na celou obrazovku.
4.5.3
Editor
Jsou zv´ yrazˇ nov´ana vyhrazen´a slova, funkce a zabudovan´e OpenGL promˇenn´e. Naˇsept´av´an´ı k´odu nen´ı. Syntaktick´e chyby nejsou podtrh´av´any. Chyby jsou ohlaˇsov´any ve speci´aln´ı chybov´e konzoli, kter´a funguje jako log ud´alost´ı. V popisu chyby je moˇzn´e z´ıskat ˇc´ıslo ˇra´dku. Editoru k´odu m´a ˇc´ıslov´an´ı ˇra´dek. V´ ysledky kompilace nemaj´ı ˇza´dn´e zv´ yraznˇen´ı u chyb ani interaktivn´ı odkazy, pˇresto vypad´a v´ ypis velmi pˇrehlednˇe. Nen´ı zde moˇzn´e ukl´adat zmˇeny v editoru jinak neˇz automaticky. Editor okamˇzitˇe pˇreloˇz´ı shader pokaˇzd´e zmˇenˇe. Pokud uˇzivatel nap´ıˇse nˇekolik znak˚ u za sebou, zmˇeny se projev´ı aˇz po tom, co uˇzivatel udˇel´a pˇrest´avku v psan´ı.
4.5.4
Ladˇ en´ı shader˚ u
Tato aplikace umoˇzn ˇuje pouze naps´an´ı vlastn´ıho shaderu pro vykreslov´an´ı jednoho objektu (z nˇekolika pˇrednastaven´ ych). Tento objekt m˚ uˇze m´ıt pouze jednu z nˇekolika pˇrednastaven´ ych textur. Vykreslovac´ı smyˇcka je pevnˇe d´ana. K´od shader˚ u se d´a libovolnˇe editovat. Jinak zde nejsou ˇz´adn´e pokroˇcilejˇs´ı moˇznosti krokov´an´ı programu.
36
OpenGL Shader Designer (Verze 1.5.9.6) [12]
N´astroje pro editaci shader˚ u
4.6
OpenGL Shader Designer (Verze 1.5.9.6) [12]
Obr´azek 4.6: Rozhran´ı n´astroje ShaderDesigner OpenGL Shader Designer je v´ yvojov´e prostˇred´ı pro vytv´aˇren´ı shader˚ u v OpenGL. Je zde moˇzn´e vytv´aˇret vertex a fragment shadery. Posledn´ı dokumentace byla vytvoˇrena k datu 12. 6. 2004. Obr´azek 4.6 ukazuje grafick´e rozhran´ı n´astroje.
4.6.1
Funkce a charakteristiky software
• testov´an´ı shader˚ u (fragment shader, vertex shader) • v animaˇcn´ı syˇcce lze pouze – mˇenit textury (lze naˇc´ıtat vlastn´ı) – mˇenit modely (lze naˇc´ıtat vlastn´ı ve form´atu gsd) 37
OpenGL Shader Designer (Verze 1.5.9.6) [12]
N´astroje pro editaci shader˚ u
• model se pohybuje taˇzen´ım myˇsi • lze exportovat jako AVI video
4.6.2
Rozhran´ı
• zobrazen´ı sc´eny • n´ahled jedn´e z textur • editor pro vertex shader nebo fragment shader • pˇrehled uniform promˇenn´ ych • v´ ysledky kompilace • nastaven´ı svˇetla
4.6.3
Editor
Jsou zv´ yrazˇ nov´ana vyhrazen´a slova, funkce a zabudovan´e OpenGL promˇenn´e. D´ale program dok´aˇze naj´ıt druh´ y p´ar znak˚ u v´ıceˇra´dkov´eho koment´aˇre, pokud se kurzor um´ıst´ı pˇred znaky * nebo /. Program um´ı naˇsept´avat symboly s v´ yjimkou uˇzivatelem definovan´ ych promˇenn´ ych. Chybou pˇri naˇsept´av´an´ı je to, ˇze pokud se naˇsept´av´an´ı vyvol´a (Ctrl+Space), pokraˇcuje se v psan´ı a uˇzivatel se rozhodne, ˇze chce napsat promˇennou, kterou naˇsept´avaˇc nezn´a, pak se bohuˇzel automaticky dopln´ı nˇejak´ y symbol z naˇsept´avaˇce, kter´ y m´a k napsan´emu ˇretˇezci nejbl´ıˇze. Syntaktick´e chyby nejsou podtrh´av´any. Chyby jsou ohlaˇsov´any ve v´ ysledc´ıch kompilace. Bohuˇzel nejsou v´ıce specifick´e v popisu chyby, neˇz ˇze vyp´ıˇsou hl´aˇsen´ı o nezdaˇren´e kompilaci fragment shaderu ˇci vertex shaderu. Editoru m´a ˇc´ıslovan´e ˇra´dky, ale bez odkazu na ˇra´dku s chybou je tato vlastnost mnohem m´enˇe uˇziteˇcn´a. Editor dok´aˇze zkolabovat nebo rozvinout funkˇcn´ı bloky. Zmˇeny v shaderu je nutn´e uloˇzit a zkompilovat, neˇz se zmˇeny uplatn´ı. Sc´ena se pak automaticky pˇrekresl´ı.
38
N´astroje pro editaci shader˚ u
4.6.4
Shader Maker [13]
Ladˇ en´ı shader˚ u
Tato aplikace umoˇzn ˇuje pouze naps´an´ı vlastn´ıho shaderu pro vykreslov´an´ı jednoho objektu, kter´ y lze ot´aˇcet v oknˇe v´ ystupu. Vykreslovac´ı smyˇcka je pevnˇe d´ana. K´od shader˚ u se d´a libovolnˇe editovat. Nejsou zde ˇz´adn´e moˇznosti krokov´an´ı vykreslovac´ı smyˇcky ˇci shader˚ u. Z´aznamy pro vertex a fragment shader maj´ı napojen´ı na komponentu PropertyGrid. M˚ uˇzeme nastavovat pouze stav OpenGL, kter´ y se v´aˇze na danou f´azi, napˇr´ıklad test hloubky nebo test pr˚ uhlednosti. Nastavov´an´ı uniform promˇenn´ ych nen´ı umoˇznˇeno.
4.7
Shader Maker [13]
Obr´azek 4.7: Rozhran´ı n´astroje ShaderMaker Shader Maker je multiplatformn´ı editor shader˚ u vyvinut´ y v QT. Projekt je opensource. Program neumoˇzn ˇuje ukl´ad´an´ı projektu. Umoˇzn ˇuje vˇsak rychl´e vytv´aˇren´ı prototyp˚ u shader˚ u, s ˇc´ımˇz mu pom´ah´a jeho minimalistick´ y
39
N´astroje pro editaci shader˚ u
Shader Maker [13]
vzhled. Posledn´ı update projektu probˇehl 14. 3. 2013. N obr´azku 4.7 je vidˇet rozhran´ı n´astroje.
4.7.1
Funkce a charakteristiky software
• testov´an´ı shader˚ u (fragment shader, vertex shader, geometry shader) • v animaˇcn´ı smyˇcce lze mˇenit pouze – textury (lze naˇc´ıtat vlastn´ı) – modely (lze naˇc´ıtat vlastn´ı ve form´atu obj) – osvˇetlen´ı – materi´aly – projekˇcn´ı matice – view port • model se pohybuje taˇzen´ım myˇsi
4.7.2
Rozhran´ı
N´astroj umoˇzn ˇuje prohl´ıdnut´ı sc´eny v hlavn´ım oknˇe. M´a z´aloˇzky pro prohl´ıˇzen´ı informac´ı o logu ud´alost´ı, osvˇetlen´ı, materi´al, uniform promˇenn´e a textury. Posledn´ı z´aloˇzka obsahuje informace z´ıskan´e z dan´eho hardware a informace o nainstalovan´em OpenGL. V tabulce uniform promˇenn´ ych se mohou nastavovat uniformy, kter´e jsou obsaˇzeny ve zkompilovan´em programu (s v´ yjimkou sampler˚ u). Kaˇzd´a promˇenn´a m´a v grafick´em rozhran´ı moˇznost pˇristupovat aˇz ke ˇctyˇrem jej´ım poloˇzk´am. V pˇr´ıpadˇe matic lze pˇristupovat i k dalˇs´ım sloupc˚ um.
4.7.3
Editor
Jsou zv´ yrazˇ nov´ana vyhrazen´a slova, funkce a zabudovan´e OpenGL promˇenn´e. Nejsou zv´ yrazˇ nov´any uˇzivatelsk´e promˇenn´e. Editor neum´ı naˇsept´avat symboly.
40
Shrnut´ı funkcionality testovan´ych n´astroj˚ u
N´astroje pro editaci shader˚ u
Program je nutn´e pˇrekompilovat, aby se zmˇeny projevily. Pak jsou zmˇeny znateln´e pˇri bˇehu programu. Shader se d´a opˇetovnˇe nalinkovat (restartuj´ı se vˇsechny promˇenn´e). Syntaktick´e chyby jsou pops´any v logu ud´alost´ı. Obsahuj´ı odkaz na ˇr´adku v editoru. Editor sice nem´a ˇc´ıslov´an´ı ˇra´dek, ale ukazuje ˇc´ıslo ˇra´dky, na kter´e je kurzor. Nen´ı pˇr´ıliˇs vhodn´e, ˇze okno ud´alost´ı ukazuje jen posledn´ı kompilaci a nijak nezv´ yrazˇ nuje chybov´a hl´aˇsen´ı nebo varov´an´ı. Vˇsechny tˇri shadery (vertex, fragment, geometry) se daj´ı uloˇzit pouze zvl´aˇst’. Nen´ı moˇzno nˇejak´ ym zp˚ usobem ukl´adat projekt.
4.7.4
Ladˇ en´ı shader˚ u
Stejnˇe jako pˇredchoz´ı aplikace Shader Maker umoˇzn ˇuje pouze naps´an´ı vlastn´ıho shaderu pro vykreslov´an´ı jednoho objektu. Tento lze ot´aˇcet v oknˇe v´ ystupu. Vykreslovac´ı smyˇcka je pevnˇe d´ana. K´od shader˚ u se d´a libovolnˇe editovat za bˇehu programu. Aplikace neumoˇzn ˇuje krokov´an´ı smyˇcky nebo shader˚ u.
4.8
Shrnut´ı funkcionality testovan´ ych n´ astroj˚ u
Testovan´e programy vˇetˇsinou bylo moˇzn´e pouˇz´ıt podle jejich dokumentace. V´ yjimka vˇsak nastala u neudrˇzovan´eho projektu GlslDevil, kter´ y nebylo moˇzn´e pouˇz´ıt podle instrukc´ı. Nemˇel peˇclivˇe zdokumentovan´a chybov´a hl´aˇsen´ı a online podpora k dan´ ym probl´em˚ um byla tak´e nedostateˇcn´a. Programy, kter´e byly pouˇz´ıv´any zejm´ena na ladˇen´ı, nebyly skuteˇcnˇe pˇr´ıliˇs vhodn´e pro v´ yvoj GLSL aplikac´ı. Tyto programy se hod´ı na ladˇen´ı v´ ysledn´e aplikace. Jen prvn´ı Testovan´a verze gDEBuggeru byla schopn´a upravovat GLSL k´od za bˇehu aplikace. Ostatn´ı verze byly speci´alnˇe vytvoˇreny hlavnˇe na profilov´an´ı, ladˇen´ı a statistiky. Tyto funkce vˇsak umoˇzn ˇovaly prov´adˇet v´ yvoj pˇr´ımo v dan´em prostˇred´ı. Vˇetˇsina ostatn´ıch program˚ u byla jednoduˇse pouˇziteln´e pro v´ yvoj shader˚ u. Tyto programy vˇsak mˇely nˇekolik nedostatk˚ u. Nebylo moˇzn´e upravovat zobrazovac´ı smyˇcku. V jedin´em programu, ve kter´em toto bylo moˇzn´e, se k´od 41
Shrnut´ı funkcionality testovan´ych n´astroj˚ u
N´astroje pro editaci shader˚ u
zobrazovac´ı smyˇcky psal pouze v Pythonu. Tento program nav´ıc nemˇel v˚ ubec ˇz´adn´e pokroˇcilejˇs´ı vlastnosti editoru k´odu. V aplikac´ıch, kter´e umoˇzn ˇovaly doplˇ nov´an´ı k´odu, bylo toto omezeno pouze na p´ar kl´ıˇcov´ ych slov ˇci funkc´ı. Nejkomplexnˇejˇs´ım programem, kter´ y by mohl splˇ novat nejv´ıce bod˚ u zad´an´ı t´eto pr´ace, byl AMD RenderMonkey. Tento program znovu ale neobsahoval ˇz´adn´e v´ıce upraviteln´e moˇznosti pro u ´pravu vykreslovac´ı smyˇcky. Z toho plynulo mnoho probl´em˚ u, zejm´ena obt´ıˇznˇejˇs´ı pr´ace s v´ıce modely (kaˇzd´ y musel b´ yt pˇrid´an ve zvl´aˇstn´ım pr˚ uchodu). Nav´ıc byl v´ yvoj RenderMonkey zastaven a tento n´astroj jiˇz nepodporuje vyˇsˇs´ı verze GLSL neˇz 2.0.
42
5 Anal´yza vlastnost´ı vyv´ıjen´e aplikace Cel´a aplikace bude naprogramov´ana v jazyku C# z d˚ uvodu rychlosti v´ yvoje a jednoduchosti vytv´aˇren´ı grafick´eho rozhran´ı pro aplikaci. V projektu se budou pouˇz´ıvat vol´an´ı OpenGL. OpenGL je dynamicky linkovan´a knihovna. Nejv´ yhodnˇejˇs´ı bylo pouˇzit´ı knihovny OpenTK pro extern´ı vol´an´ı funkc´ı OpenGL v jazyce C#. Tato knihovna je pˇr´ıjemnˇejˇs´ı na pouˇzit´ı neˇz napˇr´ıklad knihovna Tao. OpenTK m´a rozdˇelen´e v´ yˇcty podle typ˚ u ke kter´ ym patˇr´ı, m´a siln´e typov´an´ı promˇenn´ ych, zaveden´e struktury pro nejˇcastˇeji potˇrebn´e datov´e typy (vektory, matice), m´a implementovan´e n´asoben´ı vektor˚ u a matic pˇret´ıˇzen´ım oper´atoru, m˚ uˇze pouˇz´ıvat generick´e datov´e typy a je v´ıce udrˇzovan´e. Funkcionalita aplikace bude z pohledu vˇetˇsiny vlastnost´ı motivov´ana Testovan´ ym programem Render Monkey. Uˇzivatel mus´ı b´ yt schopen vytvoˇrit sv˚ uj vlastn´ı jednoduch´ y efekt naˇcten´ım modelu, textury a specifikac´ı nˇekolika shader˚ u. N´avrh mus´ı umoˇznit, aby bylo moˇzn´e specifikovat v jednom projektu v´ıce program˚ u i v´ıce model˚ u. Vytv´aˇren´ y GLSL editor mus´ı m´ıt n´asleduj´ıc´ı vlastnosti: • pomoc´ı skriptu v jazyce C# m˚ uˇze sestavit sc´enu v interaktivn´ım editoru • poskytuje moˇznost upravovat shadery • jednoduch´ y zp˚ usob pro naˇc´ıt´an´ı objekt˚ u a textur • zv´ yrazˇ nov´an´ı syntaxe programov´eho k´odu • jednoduch´a u ´prava uniform promˇenn´ ych • prohl´ıˇzen´ı naˇcten´ ych dat • sada uk´azkov´ ych u ´loh Vˇetˇsina Testovan´ ych n´astroj˚ u pro v´ yvoj splˇ novala velkou ˇca´st vyˇcten´ ych bod˚ u. Pomˇernˇe ˇcasto ale vˇsak chybˇela moˇznost definovat k´od vykreslovac´ı
43
Anal´yza vlastnost´ı vyv´ıjen´e aplikace
smyˇcky. K´od v jazyce C# je dostateˇcnˇe pˇr´ıvˇetiv´ y pro vytv´aˇren´ı prototyp˚ u jednoduch´ ych shader˚ u d´ıky spr´avˇe pamˇeti a rychl´emu pˇrekladu. Je nutn´e vyˇreˇsit, jak´ ym zp˚ usobem budou implementov´any jednotliv´e funkce. Aplikace, kter´a je schopn´a splnit vˇsechny pˇredch´azej´ıc´ı poˇzadavky mus´ı splnit n´asleduj´ıc´ı u ´koly: • pouˇzit´ı a nastaven´ı grafick´ ych komponent prozv´ yrazˇ nov´an´ı a doplˇ nov´an´ı zdrojov´eho k´odu • kompilace C# k´odu za bˇehu editoru a zmˇena hodnot glob´aln´ıch promˇenn´ ych za bˇehu vizualizaˇcn´ıho okna • spuˇstˇen´ı programu napsan´eho za bˇehu editoru a komunikace s n´ım • spr´ava (shader˚ u, program˚ u, model˚ u a textur) V dalˇs´ıch kapitol´ach budou uvedeny podrobnosti ˇreˇsen´ı nast´ınˇen´ ych probl´em˚ u. Jazyk C# zjednoduˇsuje ˇreˇsen´ı nˇekter´ ych probl´em˚ u, ale i tak je nˇekdy nutn´e prov´est sofistikovanˇejˇs´ı nastaven´ı existuj´ıc´ıch komponent nebo implementovat vlastn´ı.
44
6 Anal´yza komponent pro zv´ yrazˇ nov´ an´ı k´ odu Jednou z hlavn´ıch vlastnost´ı implementovan´eho editoru je zv´ yrazˇ nov´an´ı textu a doplˇ nov´an´ı k´odu. Existuje nˇekolik komponent pouˇziteln´ ych v C#, kter´e jiˇz tuto funkcionalitu implementuj´ı. v n´asleduj´ıc´ıch kapitol´ach budou analyzov´any vlastnosti komponent.
6.1
Scintilla [16]
Scintilla je free source komponenta pouˇziteln´a pro editov´an´ı k´odu. Lze pouˇz´ıt pro jak´ ykoliv komerˇcn´ı ˇci nekomerˇcn´ı projekt. M´a vlastnosti potˇrebn´e pro standardn´ı editory textu. Scintilla m´a vlastnosti, kter´e jsou uˇziteˇcn´e pro editov´an´ı k´odu: • r˚ uzn´e styly syntaxe (proporcion´aln´ı/neproporcion´aln´ı fonty, tuˇcn´e p´ısmo, kurz´ıva, barva popˇred´ı, pozad´ı, zmˇena font˚ u) • indik´ator chyb • doplˇ nov´an´ı k´odu V´ yvoj Scintilly zaˇcal jako snaha vylepˇsit text editor PythonWin. PythonWin pouˇz´ıval Richedit grafickou komponentu, kter´a zmˇeny stylu klasifikovala do stejn´e kategorie, do kter´e se ukl´adaly zmˇeny z´asobn´ıku pro volbu zpˇet. Nav´ıc tato komponenta nastavovala flag dirty. Jeden z program˚ u, kter´ y byl vytvoˇren pomoc´ı t´eto komponenty je SciTE. P˚ uvodnˇe byl SciTE pouze vytvoˇren pro demonstraci Scintilly. Nejl´epe se hod´ı pro menˇs´ı projekty, do kter´ ych se daj´ı zahrnout Testovac´ı programy. Scintilla je psan´a v C++. Jej´ı k´od vˇsak pouˇz´ıv´a pouze podmnoˇzinu vlastnost´ı jazyka C++, protoˇze Scintilla m˚ uˇze b´ yt pouˇz´ıv´ana i v projektech psan´ ych v C.
45
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
6.1.1
Scintilla [16]
ScintillaNET [17]
ScintillaNET je wrapper Scintilly pro platformu .NET. Dle autor˚ u jsou zde k nalezen´ı funkce, kter´e v jin´ ych wrapperech neexistuj´ı: • doplˇ nov´an´ı snipplet˚ u (doplˇ nov´an´ı ˇcasto pouˇz´ıvan´e mal´e ˇc´asti k´odu, napˇr´ıklad try/catch nebo property) • integrovan´e hled´an´ı a n´ahrada ˇretˇezc˚ u • hled´an´ı regul´arn´ıch ˇretˇezc˚ u • dopˇredn´a ˇci zpˇetn´a navigace v textu Bylo jiˇz plnˇe konfigurov´ano nˇekolik jazyk˚ u pro zv´ yrazˇ nov´an´ı syntaxe. Mezi jazyky s hotovou podporou zv´ yrazˇ nov´an´ı syntaxe je C#, GLSL mezi nimi ale nen´ı. Posledn´ı update byl zaznamen´an 18. 3. 2013.
6.1.2
Testovac´ı aplikace
Projekt nem´a k dispozici ˇza´dnou Testovac´ı aplikaci. Proto byla naprogramov´ana vlastn´ı aplikace pomoc´ı n´avodu k ovˇeˇren´ı funkcionality t´eto komponenty. Postup vytvoˇren´ı programu: • st´ahnut´ı knihoven ScintillaNET.dll, SciLexer.dll, a SciLexer64.dll • konfigurace promˇenn´e Path, aby Windows mohl nal´ezt knihovny • pˇrid´an´ı komponenty do n´avrh´aˇre Windows formul´aˇr˚ u ve Visual Studiu. D´ale je na str´ank´ach ScintillaNET pops´ano jak zaˇc´ıt programovat aplikace s touto komponentou. Jsou vysvˇetleny pˇr´ıklady pro: • vlastn´ı konfiguraˇcn´ı soubory • zprovoznˇen´ı zv´ yrazˇ nov´an´ı syntaxe 46
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
Fast ColoredTextbox[20]
• zobrazen´ı ˇc´ısel ˇra´dek • implementace vlastn´ıho lexeru (objektu, kter´ y prov´ad´ı lexik´aln´ı anal´ yzu)
6.2
Fast ColoredTextbox[20]
Fast ColoredTextbox je komponenta pro editov´an´ı textu. Je nejbohatˇs´ı co se t´ yk´a pˇr´ıklad˚ u (posledn´ı update probˇehl 1. 11. 2013). Komponenta byla vytvoˇrena jako lepˇs´ı verze komponenty RichTextBox, kter´ y zv´ yrazˇ noval vˇetˇs´ı mnoˇzstv´ı fragment˚ u (nad 200) jen velice pomalu. Cel´e vykreslov´an´ı textu v novˇe vytvoˇren´e komponentˇe je naprogramov´ano pomoc´ı GDI+, coˇz je C/C++ API. GDI+ umoˇzn ˇuje aplikac´ım pouˇz´ıvat grafick´e form´atov´an´ı textu pro displeje i pro tisk´arny [19]. K textu lze pˇristupovat pouˇzit´ım regul´arn´ıch v´ yraz˚ u. Mimo jin´e Je podporov´ano zalomen´ı ˇra´dek, najdi/nahrad’, ˇci zpˇet/vpˇred.
6.2.1
Testovac´ı aplikace
Tato komponenta pˇrich´az´ı s Testovac´ım pˇr´ıkladem. Testovac´ı pˇr´ıklad je tvoˇren jedn´ım hlavn´ım formul´aˇrem aplikace, ze kter´eho se daj´ı vyvolat r˚ uzn´e verze editor˚ u pro r˚ uzn´e u ´ˇcely. Aplikace obsahuje pˇr´ıklady pro: • zv´ yrazˇ nov´an´ı syntaxe (vˇcetnˇe zv´ yrazˇ nov´an´ı vˇsech v´ yskyt˚ u t´e promˇenn´e v k´odu, na kter´e se nach´az´ı kurzor) • nastaven´ı vlastn´ı syntaxe • vytvoˇren´ı zv´ yrazˇ novaˇce ˇra´dky • vytvoˇren´ı vlastn´ıho stylu zv´ yrazˇ nov´an´ı textu • zv´ yrazˇ nov´an´ı syntaxe pro dlouh´e texty (statis´ıce ˇra´dek) • pr´ace s extr´emnˇe dlouh´ ymi texty (miliony ˇra´dek, st´ale zab´ır´a pouze 120 MB v pamˇeti)
47
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
Fast ColoredTextbox[20]
• C# editor obsahuj´ıc´ı z´akladn´ı funkce (vpˇred, zpˇet, ukl´ad´an´ı, tisk, pr´ace se schr´ankou, vyhled´av´an´ı ˇretˇezce, zobrazov´an´ı b´ıl´ ych znak˚ u) • vkl´ad´an´ı obr´azk˚ u do textov´eho pole • podpora logov´an´ı • split-screen • naˇc´ıt´an´ı velk´ ych soubor˚ u technikou l´ın´eho naˇc´ıt´an´ı (anglicky lazyloading) • uk´azka jak form´atovat k´od obsahuj´ıc´ı ˇretˇezce z v´ıce jazyk˚ u (HTML a PHP) • hypertextov´ y odkaz • animovan´ y text • kolapse a rozv´ıjen´ı funkˇcn´ıch blok˚ u textu (anglicky codefolding) • automatick´e doplˇ nov´an´ı k´odu (doplˇ nov´an´ı staticky zadan´ ych ˇretˇezc˚ u, snipplet˚ u dynamick´e doplˇ nov´an´ı) • tooltip • dynamick´e zv´ yrazˇ nov´an´ı k´odu (zv´ yrazˇ nov´an´ı z´avorek, zv´ yrazˇ nov´an´ı promˇenn´ ych) • zv´ yrazˇ nov´an´ı syntaxe popsan´e XML souborem ˇ ınsk´ • zobrazov´an´ı ciz´ıch znak˚ u (Arabsk´ ych, C´ ych, Japonsk´ ych apod.) • automatick´e odsazov´an´ı • spr´ava z´aloˇzek • emul´ator konzole • n´apovˇedy • bloky jen pro ˇcten´ı (nelze upravit strukturu tag˚ u, pouze jejich obsah) • text s pˇreddefinovan´ ym stylem a hypertextov´ ymi odkazy • vytv´aˇren´ı maker (nahraje se posloupnost stisknut´ ych kl´aves, a takto vytvoˇren´e makro se d´a pouˇz´ıt pro opakovanou u ´pravu textu) 48
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
ICSharpCode.TextEditor [18]
• otevˇren´e fonty • prav´ıtko • mapa dokumentu (n´ahled dokumentu)
6.3
ICSharpCode.TextEditor [18]
SharpDevelop m´a grafickou komponentu, kter´a pln´ı funkci textov´eho editoru. D´a se pouˇz´ıt na u ´pravu, ukl´ad´an´ı ˇci n´ahradu ˇretˇezc˚ u. Dok´aˇze prov´adˇet akce s pomoc´ı syst´emov´e schr´anky, um´ı zv´ yrazˇ novat ˇretˇezce, rozv´ıjet ˇci kolabovat bloky textu, pouˇz´ıvat z´aloˇzky a mˇenit nastaven´ı zobrazen´ı. Existuje jen jedna verze publikovan´a 13. 11. 2008. Vyˇzaduje C# 3.0 kompil´ator. Cel´ y projekt byl v posledn´ı dobˇe pˇredˇel´an do WPF (Windows Presentation Foundation). Nyn´ı se naz´ yv´a AvalonEdit.
6.3.1
Komponenty a tˇ r´ıdy
Textov´ y editor obsahuje propojen´e grafick´e komponenty TextEditorControl, TextAreaControl a TextArea. TextEditorControl je na nejvyˇsˇs´ı u ´rovni. TextAreaControl zapouzdˇruje komponentu TextArea a jej´ı scrollbary. TextArea zpracov´av´a vstup z kl´avesnice a vykresluje text.
6.3.2
Vlastnosti editoru
Editor m´a implementovanou volbu zpˇet a opˇetovn´e vr´acen´ı zmˇen. Dok´aˇze doˇcasnˇe vyznaˇcit slova pomoc´ı marker˚ u. Implementuje z´aloˇzky, skl´ad´an´ı blok˚ u k´odu, automatick´e zarovn´an´ı k´odu a zv´ yraznˇen´ı syntaxe.
6.3.3
Testovac´ı aplikace
Aplikace m˚ uˇze otevˇr´ıt nˇekolik z´aloˇzek, ve kter´ ych budou r˚ uzn´e soubory se zdrojov´ ym k´odem. Umoˇzn ˇuje naˇc´ıt´an´ı a ukl´ad´an´ı. V u ´prav´ach jsou volby
49
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
ChameleonRichTextBox [21]
typick´e pro u ´pravy v aplikac´ıch (pr´ace se schr´ankou a hled´an´ı ˇci nahrazen´ı ˇretˇezce). Nav´ıc je v u ´prav´ach moˇznost vkl´adat a navigovat mezi z´aloˇzkami. M˚ uˇzeme d´ale zvolit dalˇs´ı moˇznosti, kter´e se t´ ykaj´ı hlavnˇe zobrazov´an´ı k´odu: • split-screen • zobrazen´ı b´ıl´ ych znak˚ u • zobrazen´ı ˇc´ısel ˇra´dek • zv´ yraznˇen´ı aktu´aln´ı ˇr´adky • zv´ yraznˇen´ı p´arov´e z´avorky • nastaven´ı velikosti tabul´atoru • nastaven´ı velikosti fontu
6.4
ChameleonRichTextBox [21]
Tato komponenta je souˇca´st´ı projektu CleanCode. CleanCode jsou knihovny pro v´ yvoj´aˇre .NET, PowerShell, SQL, Java, Perl, a Javascript aplikac´ı. ChameleanRichTextBox je komponenta, kter´a dˇed´ı od RichTextBox. Je dalˇs´ım vylepˇsen´ım komponenty SyntaxHilightTextBox. Posledn´ı update probˇehl 30. 6. 2013. Mezi jej´ı vlastnosti patˇr´ı: • zmˇena zv´ yrazˇ nov´an´ı syntaxe bez implementace nov´e komponenty pouˇzit´ım dˇediˇcnosti • doplˇ nov´an´ı k´odu • v´ ykonnˇejˇs´ı neˇz SyntaxHilightTextBox • doplˇ nov´an´ı kl´ıˇcov´ ych slov • najdi a nahrad’ • podpora maker 50
Anal´yza komponent pro zv´yrazˇ nov´an´ı k´odu
Zhodnocen´ı komponent
• kl´avesov´e zkratky pro form´atov´an´ı • konfigurace XML souborem
6.4.1
Testovac´ı aplikace
Existuje Testovac´ı aplikace [22]. Tato aplikace TEStuje mnoho implementovan´ ych ˇca´st´ı projektu CleanCode. Zaj´ım´a n´as hlavnˇe komponenta ChameleonRichTextBox. Testovanou komponentu bylo moˇzn´e pouˇz´ıt pro zv´ yrazˇ nov´an´ı syntaxe pro nˇekolik pˇrednastaven´ ych jazyk˚ u (SqlServer, Oracle, MySql a Odbc). Ukazuje jak pracovat s tabul´atory a zv´ yrazˇ nov´an´ım. Bohuˇzel tento pˇr´ıklad neukazuje ˇza´dn´e pokroˇcilejˇs´ı funkce. Nepodaˇrilo se naj´ıt ˇza´dn´e obs´ahlejˇs´ı pˇr´ıklady k t´eto komponentˇe.
6.5
Zhodnocen´ı komponent
Vˇsechny komponenty dok´azaly zv´ yrazˇ novat syntaxi a doplˇ nov´an´ı k´odu. Udrˇzovanost tˇechto komponent se vˇsak liˇs´ı. • SCIntilla je sice velmi rozˇs´ıˇren´a, ale jej´ı .NET wrapper je udrˇzovan´ ya dokumentovan´ y o nˇeco m´enˇe kvalitnˇeji. Pˇr´ıklad˚ u pouˇzit´ı je velmi m´alo. • ICSharpCode.TextEditor splˇ nuje z´akladn´ı poˇzadavky, kter´e budou potˇreba v t´eto pr´aci. Tato komponenta m´a pro Window Form grafick´e rozhran´ı nejstarˇs´ı verzi. • ChameleonRichTextBox je souˇc´ast´ı vˇetˇs´ıho projektu a bylo velmi obt´ıˇzn´e nal´ezt uˇziteˇcn´ y pˇr´ıklad nebo dokumentaci. • FastColoredTextbox vych´az´ı jako nejlepˇs´ı volba z dan´ ych komponent. Tento projekt je velmi rozs´ahl´ y, udrˇzovan´ y a m´a velk´e mnoˇzstv´ı featur a pˇr´ıklad˚ u, kter´e vˇsechny d˚ uleˇzit´e funkce demonstruj´ı.
51
7 Implementace editoru zdrojov´eho k´ odu Pro editaci zdrojov´eho k´odu se bude pouˇz´ıvat komponenta FastColoredTextbox [20]. Tato komponenta umoˇzn ˇuje zv´ yrazˇ nov´an´ı k´odu a doplˇ nov´an´ı syntaxe. Byla vybr´ana kv˚ uli velk´emu mnoˇzstv´ı vlastnost´ı a pˇr´ıklad˚ u, na kter´ ych jsou vlastnosti demonstrov´any.
7.1
Nastaven´ı komponenty FastColoredTextbox
Komponenta je pˇripraven´a pro zv´ yrazˇ nov´an´ı k´odu C#. Staˇc´ı pouze pˇrepnout jej´ı vlastnost Language na hodnotu Language.CSharp, a veˇsker´e zv´ yrazˇ nov´an´ı syntaxe C# funguje. Pˇresto ale existuj´ı drobn´e vady. St´ale se zv´ yrazˇ nuj´ı ˇretˇezce uvnitˇr koment´aˇr˚ u. Zdrojov´ y k´od od poˇca´tku souboru se zv´ yrazn´ı jako v´ıceˇra´dkov´ y koment´aˇr, a to pokud m´a v´ıceˇr´adkov´ y koment´aˇr v k´odu pˇr´ıtomen ukonˇcovac´ı token, ale ˇz´adn´ y startovac´ı token. Vˇetˇsina editor˚ u v takov´em pˇr´ıpadˇe podtrhne ukonˇcovac´ı token v´ıceˇr´adkov´eho koment´aˇre. I kdyˇz se chov´an´ı liˇs´ı od vˇetˇsiny jin´ ych editor˚ u, st´ale upozorˇ nuje uˇzivatele, ˇze je v k´odu chyba. Pro vlastn´ı nastaven´ı zv´ yrazˇ nov´an´ı k´odu umoˇzn ˇuje komponenta pˇridat implementaci metody na ud´alost TextChanged. Komponenta nezv´ yrazˇ nuje k´od na z´akladˇe lexik´aln´ı ani syntaktick´e anal´ yzy, ale na z´akladˇe regul´arn´ıch v´ yraz˚ u. Po kaˇzd´e zmˇenˇe textu se mus´ı zv´ yraznˇen´ı znovu vyhodnotit.
7.2
Zv´ yrazˇ nov´ an´ı vlastn´ıho jazyka
Jazyk GLSL nen´ı standardnˇe podporov´an komponentou FastColoredTextBox. Nejprve mus´ıme vytvoˇrit regul´arn´ı v´ yrazy, kter´e odpov´ıdaj´ı konstrukc´ım jazyka GLSL a mus´ıme jim nastavit r˚ uzn´e styly. Styly se mus´ı aplikovat ve spr´avn´em poˇrad´ı. Nastaven´ım komponenty na jazyk Language.Custom komponenta uˇz d´ale 52
Implementace editoru zdrojov´eho k´odu
Zv´yrazˇ nov´an´ı vlastn´ıho jazyka
GreenStyle = new TextStyle(Brushes.Green, null, FontStyle.Italic); ... range.ClearStyle(GreenStyle); range.SetStyle(GreenStyle, @"//.*$", RegexOptions.Multiline); Tabulka 7.1: Uk´azka zruˇsen´ı a znovu nastaven´ı stylu range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(/\*.*)", RegexOptions.Singleline); range.SetStyle(GreenStyle, @"(/\*.*?\*/)|(.*\*/)", RegexOptions.Singleline | RegexOptions.RightToLeft); Tabulka 7.2: Uk´azka nastaven´ı z´ yraznˇen´ı v´ıceˇr´adkov´eho koment´aˇre nezv´ yrazˇ nuje k´od na z´akladˇe pˇrednastaven´ ych pravidel.D´ale je tˇreba pˇripojit metodu na ud´alost TextChanged. V napojen´e metodˇe mus´ıme zruˇsit vˇsechny pouˇz´ıvan´e styly danou instanc´ı FastColoredTextbox. Stejn´e styly se znovu nastav´ı. Na uk´azce 7.1 vid´ıme zruˇsen´ı a znovu nastaven´ı stylu. Pro jednoˇra´dkov´e koment´aˇre nastav´ıme volbu hled´an´ı regul´arn´ıho v´ yrazu v´ıceˇra´dkovˇe. M˚ uˇze se zd´at, ˇze bychom mˇeli nastavit volby obr´acenˇe a hledat jednoˇra´dkovˇe. Regul´arn´ı v´ yraz ale pˇri nastaven´ı volby v´ıceˇra´dkov´eho prohled´av´an´ı Testuje kaˇzdou ˇr´adku zvl´aˇst’. Znak dolaru m´ame na konci v´ yrazu, protoˇze hled´ame u jednoˇra´dkov´eho koment´aˇre konec ˇr´adky. U v´ıceˇra´dkov´eho koment´aˇre naopak nastav´ıme volbu prohled´av´an´ı jednoˇra´dkovˇe. Je to proto, ˇze cel´ y text pak bude br´at regul´arn´ı v´ yraz jako jednu ˇra´dku. Nebude se tedy zastavovat na znac´ıch pro odˇra´dkov´an´ı. Na uk´azce 7.2 vid´ıme nastaven´ı koment´aˇre na v´ıce ˇr´adek. Nejprve se specifikuje zaˇc´atek v´ıceˇra´dkov´eho koment´aˇre a nastav´ı se prohled´av´an´ı cel´eho textu jako by byl jednou ˇr´adkou. N´aslednˇe se specifikuje regul´arn´ı v´ yraz pro konec v´ıceˇra´dkov´eho koment´aˇre a rovnˇeˇz se hled´a v cel´em textu jako by byl jednou ˇra´dkou. Na rozd´ıl od pˇredchoz´ıho pˇr´ıpadu se hled´a zprava doleva. Pro zv´ yraznˇen´ı dalˇs´ıch token˚ u bylo tˇreba nal´ezt cel´ y v´ yˇcet vˇsech pˇreddefinovan´ ych funkc´ı promˇenn´ ych, kl´ıˇcov´ ych slov a direktiv preprocesoru pro GLSL verzi 4.3. Vzhledem k tomu, ˇze se pouˇz´ıvaj´ı pouze regul´arn´ı v´ yrazy,
53
Implementace editoru zdrojov´eho k´odu
Zv´yrazˇ nov´an´ı vlastn´ıho jazyka
@"\b(gl_NumWorkGroups|gl_WorkGroupSize|gl_WorkGroupID|...)\b";
Tabulka 7.3: Uk´azka nastaven´ı z´ yraznˇen´ı vˇsech pˇreddefinovan´ ych promˇenn´ ych nen´ı v ˇz´adn´em pˇr´ıpadˇe zv´ yrazˇ nov´an´ı zdrojov´eho k´odu dokonal´e. Nem˚ uˇzeme zv´ yrazˇ novat promˇenn´e se stejn´ ym jm´enem v jednom bloku, nem˚ uˇzeme odliˇsovat uˇzivatelsky definovan´e funkce od uˇzivatelsky definovan´ ych promˇenn´ ych atd. Bylo zvoleno, ˇze vˇsechny shadery budou m´ıt stejn´e zv´ yrazˇ nov´an´ı syntaxe. Tento postup byl aplikov´an kv˚ uli jednoduchosti implementace. Mnoˇzstv´ı pˇreddefinovan´ ych promˇenn´ ych a funkc´ı je pomˇernˇe velk´e. Regul´arn´ı v´ yraz, kter´ y hled´a kl´ıˇcov´a slova, mus´ı obsahovat celou mnoˇzinu kl´ıˇcov´ ych slov. Na uk´azce 7.3 vid´ıme, jak´ y zp˚ usobem se vytvoˇr´ı regul´arn´ı v´ yraz pro hled´an´ı pˇreddefinovan´ ych promˇenn´ ych. Seznam vˇsech promˇenn´ ych, funkc´ı, kl´ıˇcov´ ych slov a preprocesorov´ ych direktiv byl z´ısk´an ze specifikace GLSL jazyka verze 4.3 [31].
7.2.1
Vyvol´ an´ı nab´ıdky pro doplˇ nov´ an´ı k´ odu
Doplˇ nov´an´ı k´odu je implementov´ano stejnˇe jako zv´ yrazˇ nov´an´ı syntaxe na principu hled´an´ı regul´arn´ıch v´ yraz˚ u. Tˇr´ıda AutocompleteMenu m´a speci´aln´ı promˇennou SearchPattern, kter´a obsahuje regul´arn´ı v´ yraz pro v´ yˇcet mnoˇziny znak˚ u, kter´e si bude komponenta ukl´adat do svoj´ı vnitˇrn´ı doˇcasn´e promˇenn´e fragment. V pˇr´ıpadˇe, ˇze nap´ıˇseme znak, kter´ y nen´ı ve v´ yˇctu, ukl´ad´an´ı do fragmentu se restartuje. Kdyˇz uˇzivatel nap´ıˇse minim´alnˇe dva znaky a pˇrestane na chv´ıli ps´at (nebo pˇrik´aˇze vyps´an´ı nab´ıdky pro doplˇ nov´an´ı k´odu kl´avesami SHIFT + mezern´ık), zaˇcne komponenta ze sv´eho seznamu vyb´ırat poloˇzky, kter´e nab´ıdne k doplnˇen´ı. Pˇrednastaven´ y obsah promˇenn´e SearchPattern pro doplˇ nov´an´ı C# k´odu: @"[\w\.:=!<>]" V´ yznam uveden´eho ˇretˇezce je takov´ y, ˇze se maj´ı do fragmentu ukl´adat znaky slov (p´ısmena, ˇc´ıslice), teˇcky, dvojteˇcky, rovn´ıtka, vykˇriˇcn´ıky a zna54
Implementace editoru zdrojov´eho k´odu
Zv´yrazˇ nov´an´ı vlastn´ıho jazyka
AutocompleteMenu popupMenu = new AutocompleteMenu(fastColoredTextBox); DynamicCollectionCs items = new DynamicCollectionCs( popupMenu, autoCompleteCs, fastColoredTextBox, prjFile); popupMenu.Items.SetAutocompleteItems(items);
Tabulka 7.4: Uk´azka vytvoˇren´ı menu pro doplˇ nov´an´ı k´odu m´enka vˇetˇs´ı a menˇs´ı. Speci´aln´ı znaky jsou zde proto, ˇze kromˇe promˇenn´ ych ukazuj´ı pˇr´ıklady komponenty FastColoredTexbox pouˇzit´ı pˇri doplˇ nov´an´ı snipplet˚ u (rychl´ ych ˇca´st´ı k´odu, napˇr´ıklad vyps´an´ı anotace pro klausule if nebo switch) a vkl´ad´an´ı mezer mezi oper´atory a ˇc´ısla. Pro u ´ˇcely t´eto pr´ace mus´ıme zmˇenit SearchPattern na n´asleduj´ıc´ı: "[\\w\\.\\[\\]\":=!<>]" Zavin´aˇc, kter´ y v jazyce C# pom´ah´a vypnout vlastnost zpˇetn´eho lom´ıtka jako escape symbolu nem˚ uˇzeme vyuˇz´ıt. Je nutn´e pˇridat do ˇretˇezce uvozovky, kter´e se jinak berou jako konec ˇretˇezce. Uvozovky mus´ıme pˇridat proto, aby uˇzivateli editor pohodlnˇe naˇsept´aval ˇretˇezcov´e konstanty, kter´e se budou pouˇz´ıvat pˇri vyb´ır´an´ı objekt˚ u ze slovn´ık˚ u.
7.2.2
Nastaven´ı dat pro doplˇ nov´ an´ı k´ odu
Vˇsechny ˇretˇezce, kter´e nab´ıdka doplˇ nuje, uloˇz´ıme do ˇc´ıseln´ıku a nastav´ıme tˇr´ıdˇe AutocompleteMenu jako vlastnost Items. Tento ˇc´ıseln´ık se m˚ uˇze dynamicky mˇenit. Abychom mohli doplˇ novat ˇretˇezce a reagovat na zmˇeny v projektu, vytvoˇr´ıme vlastn´ı ˇc´ıseln´ık DynamicCollectionCs. Na uk´azce 7.4 je vidˇet jednoduch´a posloupnost pˇr´ıkaz˚ u, kter´a vytvoˇr´ı menu doplˇ nuj´ıc´ı k´od pro instanci editoru FastColoredTextBox. Objekt typu DynamicCollectionCs poskytuje seznam vˇsech ˇretˇezc˚ u, kter´e se mohou objevit v nab´ıdce. Objekty ProjectFile pˇristupuj´ı k soubor˚ um se zdrojov´ ymi k´ody. Promˇenn´a prjFile v pˇr´ıkladu je instance tˇr´ıdy ProjectFile. Objekt popupMenu je pouˇz´ıv´an na z´ısk´an´ı fragmentu a objekt autoCompleteCs obsahuje uloˇzen´e nemˇenn´e pˇrednastaven´e promˇenn´e, metody a kl´ıˇcov´a slova.
55
Implementace editoru zdrojov´eho k´odu
Zv´yrazˇ nov´an´ı vlastn´ıho jazyka
public class DynamicCollectionCs : IEnumerable
{ ... public IEnumerator GetEnumerator() { ... foreach (var modelFile in listOfModels) { name = StrinGS.DICT_VAR_MODELs + "[\"" + modelFile.NameWithoutExtension + "\"]"; yield return new DictionaryAutocompleteItem(name); yield return new DictionaryAutocompleteItem( name + StrinGS.CLASS_MODEL_METHOD_DRAW); } ...
Tabulka 7.5: Uk´azka vr´acen´eho ˇc´ıseln´ıku tˇr´ıdy DynamicCollectionCs Na uk´azce 7.5 je vidˇet z´akladn´ı myˇslenka, jak budeme vracet seznam ˇretˇezc˚ u, kter´e chceme doplˇ novat. Platforma .NET n´am poskytuje kl´ıˇcov´e slovo yield. Kdyˇz nepouˇz´ıv´ame yield a m´ame metodu, kter´a vrac´ı v´ yˇcet (ˇc´ıseln´ık) hodnot, mus´ıme ˇc´ıseln´ık nejdˇr´ıve vytvoˇrit, pak naplnit a nakonec vr´atit. v pˇr´ıpadˇe, ˇze yield pouˇz´ıv´ame, m˚ uˇzeme vracet poloˇzky ˇc´ıseln´ıku pr˚ ubˇeˇznˇe pomoc´ı yield return. Vr´acen´a hodnota se tak nastav´ı implicitnˇe vytvoˇren´eho ˇc´ıseln´ıku. V uveden´em pˇr´ıkladˇe vrac´ıme objekt typu DictionaryAutocompleteItem, kter´ y dˇed´ı od tˇr´ıdy MethodAutoCompleteItem poskytovan´e knihovnou dis´ tribuovanou s komponentou FastColoredTextbox. Ukolem objektu DictionaryAutocompleteItem je uloˇzit ˇretˇezec nab´ızen´ y k doplnˇen´ı k´odu a z´aroveˇ n porovn´an´ı s aktu´aln´ım fragmentem, kter´ y vznikl pˇri psan´ı k´odu. Pˇri vyb´ır´an´ı poloˇzek, kter´e budou nakonec zobrazeny v seznamu s nab´ızen´ ymi ˇretˇezci, se porovn´a jiˇz napsan´ y fragment s prvn´ı ˇc´ast´ı ˇretˇezce v seznamu. Pokud dosud napsan´ y fragment m˚ uˇze pokraˇcovat tak, ˇze sloˇz´ı v´ ysledn´ y ˇreˇ ezce se porovn´avaj´ı stantˇezec, tak se tento ˇretˇezec v seznamu ponech´a. Retˇ dardn´ımi metodami C# pro pr´aci s ˇretˇezci. Pro zjiˇstˇen´ı, zda ˇretˇezce zaˇc´ınaj´ı stejnˇe, se pouˇz´ıv´a metoda StartsWith. Nejsou poskytov´any ˇza´dn´e n´astroje pro optimalizaci. 56
8 Online kompilace C# k´odu Hlavn´ı funkce, bez kter´e se aplikace neobejde, je moˇznost kompilovat C# k´od za bˇehu editoru. Grafick´a komponenta pro zv´ yrazˇ nov´an´ı a doplˇ nov´an´ı k´odu pom´ah´a uˇzivateli s v´ yvojem k´odu. Bez moˇznosti zkompilovat a spustit k´od je vˇsak n´astroj nefunkˇcn´ı. P˚ uvodn´ı pˇredstava byla takov´a, ˇze skoro veˇsker´ y kompilovan´ y k´od bude m´ıt uˇzivatel pˇr´ıstupn´ y k editaci. Tento k´od by se objevil ve formˇe nˇekolika metod (napˇr´ıklad metody pro aktualizaci, metody pro vykreslen´ı a podobnˇe). V´ ysledek by se zkompiloval do dll knihovny. Tato knihovna by se naˇcetla, vytvoˇrila by se jej´ı instance v editoru, a tato instance by se pouˇzila k bˇehu vizualizace. Probl´em zam´ yˇslen´eho pˇr´ıstupu je ten, ˇze upravovat k´od jiˇz bˇeˇz´ıc´ı aplikace nen´ı trivi´aln´ı probl´em. Pro doc´ılen´ı tohoto efektu mus´ıme b´ yt schopni zkompilovan´ y k´od za bˇehu naˇc´ıst a spustit. Protoˇze se ale bude k´od mnohokr´at pˇredˇel´avat bˇehem v´ yvoje, je nutn´e pˇredchoz´ı verze k´odu odstranit z pamˇeti. Existuje jen jedna moˇznost, jak odstranit z pamˇeti assembly (zkompilovan´ y C# k´od ve spustiteln´e formˇe), kter´e bylo jednou pˇripojeno k bˇeˇz´ıc´ı aplikaci. Je nutn´e naˇc´ıst assembly do zvl´aˇstn´ı aplikaˇcn´ı dom´eny, kter´e poskytuje urˇcitou izolaci od ostatn´ıho k´odu. K´od v dalˇs´ı vytvoˇren´e aplikaˇcn´ı dom´enˇe se m˚ uˇze spustit nez´avisle na k´odu v hlavn´ı aplikaˇcn´ı dom´enˇe. Kdyˇz chceme odstranit starou pˇreloˇzenou verzi programu z pamˇeti, mus´ıme bˇeˇz´ıc´ı pˇreloˇzen´ y program ukonˇcit a pak zruˇsit aplikaˇcn´ı dom´enu. Je nutn´e ˇreˇsit dva probl´emy. Jak vypad´a k´od, kter´ y chceme kompilovat a jak´ ym zp˚ usobem bude prob´ıhat komunikace mezi hlavn´ı programem (editorem) a vizualizaˇcn´ım programem (vizualizaˇcn´ım oknem).
8.1
N´ avrh zp˚ usobu kompilace
Pro kompilaci k´odu pouˇz´ıv´ame tˇr´ıdu Microsot.CSharp.CSharpCodeProvider. Tato tˇr´ıda n´am umoˇzn ˇuje pˇr´ıstup k pˇrekladaˇci. Vytvoˇr´ıme jej´ı instanci, dod´ame zdrojov´e soubory a parametry pˇrekladu pro proveden´ı kompilace. V´ ysledkem kompilace m˚ uˇze b´ yt spustiteln´ y soubor nebo dynamicky linkovan´a knihovna. 57
Online kompilace C# k´odu
N´avrh zp˚ usobu kompilace
public class GlobalVarSetCustom : GlobalVarSet { [DisplayName("Blue Background Color")] public InterfaceVector3 vColor { get; set; } [DisplayName("Matrix Projection")] public InterfaceMatrix4 mProjection { get; set; } [DisplayName("Matrix View")] public InterfaceMatrix4 mView { get; set; } [DisplayName("Matrix Model")] public InterfaceMatrix4 mModel { get; set; } public Init() { this.vColor.Val = new Vector3(0.5f, 0.5f, 0.0f); } }
Tabulka 8.1: Uk´azka implementace glob´aln´ıch promˇenn´ ych V´ ysledn´a aplikace by nemˇela fungovat tak, ˇze uˇzivatel bude ps´at veˇsker´ y k´od vizualizaˇcn´ıho okna. Vˇetˇsina k´odu bude jiˇz napsan´a pˇredem. Uˇzivatel bude specifikovat pouze k´od dvou tˇr´ıd. Jedna z tˇechto tˇr´ıd implementuje souhrn glob´aln´ıch promˇenn´ ych, druh´a popisuje inicializaci, aktualizaci a vykreslov´an´ı vizualizace.
8.1.1
Implementace glob´ aln´ıch promˇ enn´ ych
Tˇr´ıda GlobalVarSetCustom obsahuje glob´aln´ı promˇenn´e, jejichˇz hodnoty bude uˇzivatel cht´ıt za bˇehu mˇenit bez toho, aby musel mˇenit k´od (mˇenit C# implementaci za bˇehu ve v´ ysledn´e aplikaci nelze). Protoˇze chceme nastavovat nˇekolik typ˚ u glob´aln´ıch promˇenn´ ych, je nutn´e poskytnout uˇzivateli nˇejak´e aplikaˇcn´ı rozhran´ı, kter´e se postar´a o pˇr´ıstup k tˇemto promˇenn´ ym. Kompil´ator oˇcek´av´a, ˇze tato tˇr´ıda bude m´ıt promˇenn´e dostupn´e pˇres vlastnosti a konstruktor, kter´ y vˇsechny promˇenn´e inicializuje. Na uk´azce 8.1 je vidˇet implementace tˇr´ıdy GlobalVarSetCustom. Tˇr´ıda, kterou bude uˇzivatel takto implementovat, mus´ı dˇedit od tˇr´ıdy GlobalVarSet. 58
Online kompilace C# k´odu
N´avrh zp˚ usobu kompilace
Rodiˇcovsk´a tˇr´ıda m´a automatick´ y konstruktor, kter´ y vytvoˇr´ı instance objekt˚ u pro vˇsechny uˇzivatelem deklarovan´e vlastnosti. Pro inicializaci objekt˚ u, kter´e ani nem´a rodiˇcovsk´a tˇr´ıda v sobˇe definovan´e se pouˇz´ıv´a System.Reflection. Instance tˇr´ıdy GlobalVarSetCustom se nastav´ı jako zdroj komponenty PropertyGrid, kter´a se pak pouˇz´ıv´a pro nastavov´an´ı hodnot promˇenn´ ych za bˇehu programu. Existuje nˇekolik tˇr´ıd, kter´e jsou pˇripraveny pro pouˇzit´ı s komponentou PropertyGrid. Tyto tˇr´ıdy v sobˇe obsahuj´ı data v podobˇe OpenTK struktur. Jm´ena tˇechto tˇr´ıd skl´adaj´ı ze slova Interface a datov´eho typu, kter´ y tˇr´ıda obaluje. Kaˇzd´a tˇr´ıda pak m´a jeden veˇrejn´ y atribut Val. N´azev tˇr´ıdy napov´ıd´a o tom, jak´eho je atribut datov´eho typu. Existuje nˇekolik tˇr´ıd, kter´e obaluj´ı primitivn´ı datov´e typy nebo struktury OpenTK. Jsou to tˇr´ıdy pro obalen´ı ˇc´ısel float, double, integer a pro obalen´ı vektor˚ u a matic. Vˇetˇsina z tˇechto tˇr´ıd m´a tˇri konstruktory. Jeden pr´azdn´ y, kter´ y inicializuje strukturu nebo jednoduch´ y datov´ y typ na nulov´e hodnoty. Dalˇs´ı konstruktor pˇrij´ım´a ˇca´rkami oddˇelen´e hodnoty ˇc´ısel, kter´a jsou pouˇzita na inicializaci struktur. Matice a vektory pˇrij´ımaj´ı jako datov´e typy pouze ˇc´ısla float. Matice a vektory maj´ı jeˇstˇe tˇret´ı konstruktor, do kter´eho m˚ uˇzeme vloˇzit rovnou celou OpenTK strukturu, dle typu tˇr´ıdy.
8.1.2
Implementace vizualizaˇ cn´ı smyˇ cky
Tˇr´ıda VisualizationModulCustom dˇed´ı od tˇr´ıdy VisualizationModul. v rodiˇcovsk´e tˇr´ıdˇe je definov´ano mnoho chr´anˇen´ ych atribut˚ u, ke kter´ ym m´a uˇzivatel pˇri implementaci pˇr´ıstup: • instance tˇr´ıdy s glob´aln´ımi promˇenn´ ymi globalVarSet, popsan´a v´ yˇse • slovn´ıky (System.Collections.Generic.Dictionary) – shaderPrograms – hotov´e programy obsahuj´ıc´ı zkompilovan´e a pˇripraven´e shadery – models – modely, kter´e bude aplikace vykreslovat – textures – textury, kter´e jsou jiˇz nahran´e na grafickou kartu • ˇcasy pro animaˇcn´ı smyˇcku 59
Online kompilace C# k´odu
N´avrh zp˚ usobu kompilace
– elepsedMilliseconds – celkov´ y ˇcas od startu vizualizace v milisekund´ach – elapsedSeconds – celkov´ y ˇcas od startu vizualizace v sekund´ach – elapsedMinuTES – celkov´ y ˇcas od startu vizualizace v minut´ach • azimuth – azimut vypoˇcten´ y z taˇzen´ı myˇsi se stisknut´ ym lev´ ym tlaˇc´ıtkem • zenith – zenith vypoˇcten´ y z taˇzen´ı myˇsi se stisknut´ ym lev´ ym tlaˇc´ıtkem • screenWidth – ˇs´ıˇrka zobrazovac´ı plochy komponenty glControl • screenHeight – v´ yˇska zobrazovac´ı plochy komponenty glContorl • near – oˇrez´avac´ı rovina near nastavovan´a ze speci´aln´ı komponenty na vizualizaˇcn´ım oknˇe • far – oˇrez´avac´ı rovina far nastavovan´a ze speci´aln´ı komponenty na vizualizaˇcn´ım oknˇe • distance – vzd´alenost objekt˚ u od kamery nastavovan´a ze speci´aln´ı komponenty na vizualizaˇcn´ım oknˇe • size – velikost objekt˚ u nastavovan´a koleˇckem myˇsi • loopUpdateAllowed – povolen´ı aktualizace metody LeepUpdatenastavov´ano zaˇskrt´avac´ım pol´ıˇckem na vizualizaˇcn´ım oknˇe Slovn´ıky jsou naplnˇeny pˇripraven´ ymi objekty. K tˇemto objekt˚ um m˚ uˇzeme pˇristoupit pomoc´ı ˇretˇezcov´ ych kl´ıˇc˚ u. Kaˇzd´ y objekt je ve slovn´ıku uloˇzen pod stejn´ ym jm´enem, pod jak´ ym jm´enem je jeho zdroj uveden v editoru. U textur a model˚ u se jedn´a o n´azvy soubor˚ u. U program˚ u se jedn´a o n´azvy program˚ u uloˇzen´ ych v nastaven´ı projektu. Mnoho promˇenn´ ych se nastavuje automaticky pˇri aktualizaci, kter´a nastane pˇri manipulaci s uˇzivatelsk´ ym rozhran´ım. Promˇenn´e jsou pojmenov´any podle jejich zam´ yˇslen´eho uˇzit´ı. Nikdo vˇsak uˇzivatele nedonut´ı pouˇz´ıvat napˇr´ıklad promˇenn´e pro azimut a zenit. Tyto atributy byly pouze vybr´any jako nejˇcastˇejˇs´ı potˇrebn´e pˇri jak´ekoliv vizualizaci. Nˇekter´e z promˇenn´ ych je pˇr´ıhodnˇejˇs´ı nastavovat speci´aln´ım zp˚ usobem, m´ısto nastavov´an´ı vˇsech v komponentˇe PropertyGrid. Napˇr´ıklad ot´aˇcen´ı modelu taˇzen´ım myˇsi je mnohem pˇr´ıjemnˇejˇs´ı neˇz psan´ı ˇc´ıseln´ ych hodnot do r˚ uzn´ ych pol´ı transformaˇcn´ıch matic zobrazen´ ych v komponentˇe PropertyGrid. 60
Online kompilace C# k´odu
N´avrh zp˚ usobu kompilace
Vˇetˇsina ze zm´ınˇen´ ych atribut˚ u je nastavov´ana pouze pˇri uˇzivatelsk´em vstupu. Aktualizace probˇehne, pokud uˇzivatel zad´a na kl´avesnici ˇc´ıseln´e hodnoty do pˇripraven´ ych komponent, pokud t´ahne myˇs´ı se stisknut´ ym lev´ ym tlaˇc´ıtkem nad komponentou pro zobrazen´ı vizualizace, pokud rozt´ahne okno, pokud klikne na ˇsipku u komponent NumericUpDown nebo pokud roluje koleˇckem myˇsi. Uplynul´ y ˇcas aplikace je jedin´a informace, kter´a se aktualizuje zvl´aˇst’ kaˇzd´ y sn´ımek. Uˇzivatel m˚ uˇze pˇret´ıˇzit n´asleduj´ıc´ı metody: • Init – nastaven´ı jak´ ychkoliv promˇenn´ ych pˇri inicializaci; aktualizace slovn´ık˚ u a glob´aln´ıch promˇenn´ ych prob´ıh´a automaticky pˇred zavol´an´ım t´eto metody • InputUpdate –aktualizace promˇenn´ ych ze vstup˚ u; probˇehne aˇz po aktualizaci chr´anˇen´ ych atribut˚ u tˇr´ıdy z uˇzivatelsk´eho rozhran´ı • LoopUpdate – implementace aktualizace promˇenn´ ych pˇri animaci z´avisl´e na ˇcase; probˇehne kaˇzd´ y sn´ımek po tom, co se aktualizuj´ı chr´anˇen´e promˇenn´e pro ˇcas; z uˇzivatelsk´eho rozhran´ı (nebo i programovˇe) lze vol´an´ı t´eto metody zak´azat • Render – implementace vykreslen´ı na plochu komponenty glControl; prob´ıh´a kaˇzd´ y sn´ımek, nelze zak´azat Pokud v kter´ekoliv z tˇechto metod vznikne v´ yjimka, je odchycena ve fixn´ım k´odu, kter´ y vyjmenovan´e metody vol´a. D˚ uvodem popsan´eho chov´an´ı je, ˇze uˇzivatel by mohl napsat k´od, kter´ y skonˇc´ı v´ yjimkou v kaˇzd´em sn´ımku. Kdyby se vykreslov´an´ı nezastavilo, zaplavil by se log v´ ypisy v´ yjimek. Jedin´a moˇznost jak v pˇr´ıpadˇe v´ yjimky pokraˇcovat je restartovat vizualizaˇcn´ı okno nebo nahr´at znovu zdroje. Pokud je ale v´ yjimka zp˚ usobena nˇeˇc´ım jin´ ym neˇz chybˇej´ıc´ımi zdroji, nastane pravdˇepodobnˇe znovu.
8.1.3
Zmˇ ena hodnot uniform promˇ enn´ ych za bˇ ehu vizualizace
Protoˇze zmˇenou nastaven´ı glob´aln´ıch hodnot mˇen´ıme zdrojov´ y k´od vizualizaˇcn´ıho okna, nem˚ uˇzeme na seznam glob´aln´ıch hodnot napojit ˇz´adnou komponentu v editoru. M´ısto toho se hodnoty glob´aln´ıch promˇenn´ ych mˇen´ı 61
Online kompilace C# k´odu
N´avrh zp˚ usobu kompilace
v komponentˇe, kter´a se nach´az´ı na zkompilovan´em a spuˇstˇen´em vizualizaˇcn´ım oknˇe. Pro nastavov´an´ı uniform promˇenn´ ych mus´ı uˇzivatel napsat k´od v C# pouˇzit´ım metod OpenTK. Pokud nechce pouˇz´ıvat animace, bude tento k´od ps´at pouze do metody InputUpdate. Pokud chce aktualizaci v z´avislosti na ˇcase, bude muset tento k´od napsat do metody LoopUpdate. Pokud chce uˇzivatel k´od napsat tak, aby mohl hodnoty uniform promˇenn´ ych mˇenit za bˇehu vizualizace, mus´ı z´ısk´avat data pro nastaven´ı uniform promˇenn´ ych z objektu globalVarSet. Kdyˇz se uˇzivatel rozhodne, ˇze se tyto promˇenn´e zobrazovan´e v komponentˇe PropertyGrid budou aktualizovat na z´akladˇe chr´anˇen´ ych promˇenn´ ych tˇr´ıdy VisualizationModul v kaˇzd´em sn´ımku, pak jsou tyto promˇenn´e prakticky zobrazeny pouze pro ˇcten´ı. Pokud uˇzivatel uprav´ı jejich hodnoty, tak se v dalˇs´ım sn´ımku aktualizuj´ı na z´akladˇe k´odu, kter´ y napsal s´am uˇzivatel. Uˇzivatel si tedy mus´ı d´avat pozor na to, kdy a jak´ ym zp˚ usobem se mˇen´ı hodnoty glob´aln´ıch promˇenn´ ych. Nav´ıc zde existuje moˇznost vypnout vol´an´ı metody LoopUpdate, aby mohl uˇzivatel mˇenit za bˇehu i promˇenn´e, kter´e se sami ve smyˇcce automaticky aktualizuj´ı na z´akladˇe jin´ ych hodnot.
62
9 Komunikace s vizualizaˇcn´ım oknem Uˇzivatel bude bˇehem jednoho bˇehu n´astroje editoru GLSL potˇrebovat nˇekolikr´at zdrojov´ y k´od upravit, nˇekolikr´at jej zkompilovat a nˇekolikr´at jej naˇc´ıst a vyuˇz´ıt. Platforma .NET sice dok´aˇze dynamicky naˇc´ıtat knihovny v r´amci jedn´e aplikaˇcn´ı dom´eny bˇehem bˇehu aplikace, nedok´aˇze vˇsak tyto naˇcten´e knihovny bˇehem bˇehu aplikace uvolˇ novat z pamˇeti stejn´e aplikaˇcn´ı dom´eny. Pokud by uˇzivatel mnohokr´at zkompiloval cel´ y projekt i tˇreba s mal´ ymi zmˇenami, po kaˇzd´e by vytvoˇril novou dynamicky linkovanou knihovnu, kterou by naˇcetl do aplikace a jej´ı pamˇet’ov´a n´aroˇcnost by se nekoneˇcnˇe zvyˇsovala. Nav´ıc takov´ato knihovna by se uloˇzila na disk a byla by zamˇcen´a – chr´anˇen´a proti pˇreps´an´ı nebo smaz´an´ı. Pokud chceme, abychom mohli nˇejakou dobu vykon´avat urˇcit´ y k´od a po libovoln´e dobˇe pˇrestat k´od pouˇz´ıvat a odstranit jej z pamˇeti, mus´ıme pouˇz´ıt tˇr´ıdu System.AppDomain. Kromˇe st´avaj´ıc´ı aplikaˇcn´ı dom´eny, ve kter´e bˇeˇz´ı editor, vytvoˇr´ıme novou aplikaˇcn´ı dom´enu, ve kter´e bude bˇeˇzet pouze vizualizaˇcn´ı okno.
9.1
Tˇ r´ıda AppDomain
Jin´ ym zp˚ usobem, neˇz uˇz´ıv´an´ım aplikaˇcn´ıch dom´en, nen´ı moˇzn´e uvolˇ novat z pamˇeti jednotliv´e assembly nebo definice typ˚ u. Veˇsker´ y k´od, jehoˇz assembly chceme uvolnit, se mus´ı nach´azet uvnitˇr aplikaˇcn´ı dom´eny a z´aroveˇ n mus´ı bˇeˇzet uvnitˇr aplikaˇcn´ı dom´eny. Pokud vytvoˇr´ıme v r´amci jedn´e aplikaˇcn´ı dom´eny instanci urˇcit´eho typu, nem˚ uˇzeme definici t´eto instance dostat z pamˇeti jin´ ym zp˚ usobem neˇz zruˇsen´ım cel´e aplikaˇcn´ı dom´eny. Pokud vytvoˇr´ıme novou aplikaˇcn´ı dom´enu, vytvoˇr´ıme urˇcitou izolaci, kter´a n´am oddˇeluje novˇe vytvoˇren´ y typ od hlavn´ı aplikace, ale z´aroveˇ n st´ale umoˇzn ˇuje urˇcitou u ´roveˇ n interakce[23]. Nˇekdy m˚ uˇze b´ yt probl´emem garbage collector, kter´ y uvoln´ı z pamˇeti st´ale jeˇstˇe pouˇz´ıvan´e objekty pˇri vzd´alen´e komunikaci. Po urˇcit´e dobˇe se uvoln´ı z pamˇeti objekty server˚ u. Aplikace, kter´a s t´ımto chov´an´ım nepoˇc´ıt´a, pak skonˇc´ı na v´ yjimce. U aplikac´ı se vzd´alen´ ym pˇr´ıstupem se poˇc´ıt´a s t´ım, ˇze m˚ uˇze b´ yt vytvoˇreno obrovsk´e mnoˇzstv´ı klient˚ u. Zde je tradiˇcn´ı garbage collector nahrazen syst´emem, kter´ y uvolˇ nuje objekty po urˇcit´em ˇcase. v na63
Komunikace s vizualizaˇcn´ım oknem
V´yhody uˇz´ıv´an´ı aplikaˇcn´ıch dom´en
ˇsem pˇr´ıpadˇe ale poˇc´ıt´ame s aplikac´ı, kter´a bude m´ıt pouze jednoho klienta za jak´ ychkoliv okolnost´ı. z toho d˚ uvodu m˚ uˇzeme probl´em vyˇreˇsit jednoduch´ ym pˇret´ıˇzen´ım metody GetLifetimeService. Toto je metoda tˇr´ıdy, kter´a dˇed´ı od MarshalByRefObject. v naˇsem pˇr´ıpadˇe je to formul´aˇr. Pokud pˇret´ıˇz´ıme metodu tak, aby m´ısto objektu vr´atila null, nebude ˇz´adn´ y objekt pro vzd´alenou komunikaci z pamˇeti vymaz´an [25].
9.2
V´ yhody uˇ z´ıv´ an´ı aplikaˇ cn´ıch dom´ en
Hlavn´ı v´ yhodou je hlavnˇe jiˇz dˇr´ıve zm´ınˇen´a moˇznost uvolnˇen´ı pouˇzit´ ych assembly z pamˇeti. Na rozd´ıl od komunikace mezi procesy poskytuje pouˇz´ıv´an´ı aplikaˇcn´ıch dom´en prostˇredek ke komunikaci na vyˇsˇs´ı u ´rovni. Data m˚ uˇzeme serializovat a pos´ılat do druh´e aplikaˇcn´ı dom´eny. Aplikace bˇeˇz´ıc´ı v jin´e dom´enˇe se d´a zastavit bez toho, aby toto ovlivnilo cel´ y proces. Chyby v jedn´e aplikaci nemohou ovlivˇ novat druh´e aplikace. K´od bˇeˇz´ıc´ı v jedn´e dom´enˇe nem˚ uˇze ovlivnit jin´e dom´eny ve stejn´em procesu, co se t´ yˇce chyb v pamˇeti. Pokud uˇzivatelsk´ y k´od bude zp˚ usobovat chyby s pamˇet´ı (neuvolnˇen´e objekty, pˇr´ıstup na nepovolen´a m´ısta v pamˇeti d´ıky vyuˇz´ıv´an´ı chybn´ ych ukazatel˚ u pˇri pouˇz´ıv´an´ı OpenGL funkc´ı), hlavn´ı aplikace editoru by mˇela v poˇra´dku pokraˇcovat. Pˇri probl´emech staˇc´ı pouze restartovat vizualizaˇcn´ı okno. K´od, kter´ y bˇeˇz´ı v jedn´e dom´enˇe, nem˚ uˇze pˇr´ımo pˇristupovat ke k´odu ani zdroj˚ um druh´e dom´eny. Nelze pouˇz´ıvat pˇr´ım´a vol´an´ı mezi objekty. Objekty, kter´e se pos´ılaj´ı mezi dom´enami, jsou kop´ırov´any nebo je k nim pˇristupov´ano pˇres proxy. Pokud je objekt zkop´ırov´an, veˇsker´ y pˇr´ıstup k nˇemu je pouze lok´aln´ı. Pokud je k objektu pˇristupov´ano pˇres proxy, pouˇz´ıvaj´ı se vzd´alen´a vol´an´ı na objekt. V takov´em pˇr´ıpadˇe je objekt v jin´e dom´enˇe neˇz ten, kdo ho vol´a. Aplikace v hlavn´ı dom´enˇe m˚ uˇze udˇelovat opr´avnˇen´ı, s jak´ ymi bude k´od v druhotn´e dom´enˇe bˇeˇzet.
9.3
N´ avrh komunikaˇ cn´ıho rozhran´ı
Pˇri pouˇz´ıv´an´ı aplikaˇcn´ıch dom´en m˚ uˇzeme vyuˇz´ıt dvou zp˚ usob˚ u komunikace: 64
Komunikace s vizualizaˇcn´ım oknem
N´avrh komunikaˇcn´ıho rozhran´ı
• nastaven´ım dat do aplikaˇcn´ı dom´eny funkc´ı SetData() a n´asledn´ ym z´ısk´an´ım dat v druh´e dom´enˇe pˇristoupen´ım k objektu dom´eny a zavol´an´ım metody GetData() • pouˇzit´ım tˇr´ıd, kter´e implementuj´ı MarshalByRefObject Prvn´ı zp˚ usob pos´ıl´an´ı dat nastav´ı data, ale aplikace bˇeˇz´ıc´ı v druh´e dom´enˇe nez´ısk´a ˇza´dn´e upozornˇen´ı, ˇze data byla posl´ana. Pˇr´ıhodnˇejˇs´ı je vyuˇz´ıv´an´ı implementace tˇr´ıdy MarshalByRefObject, d´ıky ˇcemuˇz m˚ uˇzeme vyuˇz´ıvat vzd´alen´a vol´an´ı na objektech v jin´e dom´enˇe. D´a se vyuˇz´ıt toho, ˇze tˇr´ıda Form pro vytv´aˇren´ı formul´aˇr˚ u jiˇz implementuje MarshalByRefObject. Zde se bohuˇzel nach´az´ı probl´em.Nen´ı vˇzdy bezpeˇcn´e pouˇz´ıvat vzd´alen´ y pˇr´ıstup na objekty, kter´e maj´ı sloˇzit´e uˇzivatelsk´e rozhran´ı, jako jsou pr´avˇe formul´aˇre. Ve v´ ysledn´e aplikaci je na vizualizaˇcn´ım oknˇe znaˇcn´e mnoˇzstv´ı komponent, coˇz jeˇstˇe potvrzuje nutnost ˇreˇsit tento probl´em. Nestaˇc´ı, ˇze je formul´aˇr potomek tˇr´ıdy pro komponentu, kter´a dˇed´ı od MarshalByRefObject. Nen´ı totiˇz podporov´an vztah rodiˇc/potomek mezi dom´enami. Rozhran´ı, kter´a pracuj´ı s formul´aˇrem, mohou b´ yt u ´spˇeˇsnˇe pouˇzita pro vzd´alen´ y pˇr´ıstup, ale API takov´eto komponenty vzd´alen´ y pˇr´ıstup neumoˇzn ˇuje. Pokud si v´ yvoj´aˇr tuto skuteˇcnost neuvˇedom´ı, m˚ uˇze pˇri v´ yvoji narazit na v´ yjimky pˇri serializaci [24]. Zp˚ usob, jak ˇreˇsit popsan´ y probl´em je vˇzdy pouˇz´ıt rozhran´ı. Formul´aˇr (vizualizaˇcn´ı okno) bude implementovat rozhran´ı pro manipulaci s oknem. Pˇri vytv´aˇren´ı proxy objektu nebudeme pˇretypov´avat objekt na Form, ale na rozhran´ı, kter´e Form implementuje. Rozhran´ı pro komunikaci specifikuje n´asleduj´ıc´ı metody: • ShowWindow – zobraz okno • CloseWindow – zavˇri okno • SetTexture – nastav texturu • SetShader – nastav shader • SetMesh – nastav model • SetShaderProgram – nastav program • InitializationFinished – oznam, ˇze inicializace byla dokonˇcena 65
Komunikace s vizualizaˇcn´ım oknem
N´avrh komunikaˇcn´ıho rozhran´ı
• SetCloseDelegate – nastav´ı deleg´at pro ozn´amen´ı o zavˇren´ı vizualizaˇcn´ıho okna • SetLogDelegate – nastav´ı deleg´at pro posl´an´ı zpr´av z vizualizaˇcn´ıho okna • SetErrorLineDelegate – nastav´ı deleg´at pro pos´ıl´an´ı chyb vznikl´ ych pˇri kompilaci GLSL k´odu (poˇsle zpr´avu o chybˇe, soubor a ˇra´dku ve kter´e vznikla) Metoda na zobrazen´ı okna m´a vyvolat stejnou ud´alost, jakou by vyvolala stejnˇe pojmenovan´a metoda u formul´aˇre. Stejn´e je to i u zavˇren´ı okna. Nastaven´ı zdroj˚ u pos´ıl´a vizualizaˇcn´ımu oknu data pro n´asledn´e zobrazen´ı. Data mus´ı b´ yt jednoduch´e datov´e typy, nebo objekty, kter´e maj´ı nastaven´ y atribut Serializable. Metoda pro ozn´amen´ı, ˇze vˇsechny zdroje jiˇz byly nahr´any, je nutn´a, protoˇze vizualizaˇcn´ı okno mus´ı vˇedˇet, ve kterou chv´ıli jsou jiˇz vˇsechny zdroje pˇr´ıtomny. Pokud by se pokusilo inicializovat (nebo obnovit) inicializaci dˇr´ıve, neˇz se nahraj´ı vˇsechny zdroje, nastala by chyba. v takov´em pˇr´ıpadˇe by se vˇsechny zdroje stejnˇe museli nahr´at znovu. Pˇr´ıpadnˇe by se muselo okno restartovat. Pˇri prvn´ım spuˇstˇen´ı se nejdˇr´ıv nastav´ı vˇsechny zdroje, pak se zavol´a InitializationFinished a aˇz po t´e se zavol´a metoda pro zobrazen´ı formul´aˇre. Pokud se metody SetTexture, SetShader nebo SetMesh zavolaj´ı bˇehem doby, kdy je okno zobrazeno, nastav´ı se pˇr´ıznak, ˇze jsou dostupn´e nov´e zdroje. Ve chv´ıli, kdy se zavol´a metoda InitializationFinished je vykreslov´an´ı pozastaven´e do t´e doby, dokud nejsou vˇsechny zdroje naˇcteny. Jakmile jsou zdroje naˇcteny, zpracov´any a pˇrid´any do slovn´ık˚ u objekt˚ u, vykreslov´an´ı se opˇet spust´ı. Je nutno poznamenat, ˇze pˇri jednom bˇehu okna nen´ı moˇzn´e mˇenit k´od vizualizaˇcn´ı smyˇcky, jej´ı inicializace ani ˇza´dn´e jin´e metody ˇci deklarace v C# jazyku. z tohoto d˚ uvodu je naprosto nutn´e, aby pˇr´ıpadn´e zmˇeny v datech byly pouze zmˇeny obsahu a nikoliv zmˇeny v rozhran´ı. T´ım se mysl´ı, ˇze uˇzivatel nesm´ı pˇrejmenov´avat shadery, programy ani modely, nesm´ı ruˇsit uniform promˇenn´e, nem˚ uˇze oˇcek´avat, ˇze po vytvoˇren´ı nov´ ych promˇenn´ ych se aktualizuje rozhran´ı na jejich editaci atd. Pokud chce uˇzivatel prov´est zmˇeny v C# implementaci, mus´ı restartovat okno vizualizace.
66
Komunikace s vizualizaˇcn´ım oknem
N´avrh komunikaˇcn´ıho rozhran´ı
Metody SetCloseDelegate, SetLogDelegate, a SetErrorLineDelegate nastav´ı deleg´at, kter´ y se d´a pouˇz´ıvat pro zpˇetnou komunikaci mezi vizualizaˇcn´ım oknem a editorem. Editor si vytvoˇr´ı deleg´at, kter´ y bude po zavol´an´ı vykon´avat urˇcitou ˇcinnost. Tento deleg´at se poˇsle vizualizaˇcn´ımu oknu pˇri vytv´aˇren´ı okna. Vizualizaˇcn´ı okno pak deleg´at m˚ uˇze zavolat a t´ım spust´ı ud´alost v editoru. M˚ uˇzeme rovnˇeˇz pos´ılat parametry s hodnotami. Plat´ı zde znovu pˇrirozen´ y pˇredpoklad, ˇze parametry budou jednoduch´e datov´e typy nebo instance tˇr´ıd s atributem Serializable.
67
10 Spr´ava zdroj˚ u Editor bude obsahovat podporu pro tˇri typy zdroj˚ u – shadery, 3D modely a textury. Spr´ava k´odu shader˚ u jiˇz byla vysvˇetlena v pˇredch´azej´ıc´ıch kapitol´ach o editorech zdrojov´eho k´odu. D´ale bude uveden zp˚ usob zpracov´an´ı soubor˚ u, do kter´ ych se zdroje ukl´adaj´ı.
10.1
Syst´ em projekt˚ u
Pro vytvoˇren´ı jak´ehokoliv efektu mus´ı uˇzivatel spravovat nˇekolik soubor˚ u najednou. Vˇsechny soubory, kter´e uˇzivatel potˇrebuje na vytvoˇren´ı jedn´e vizualizace, se ukl´adaj´ı do projektu. Projekt obsahuje souhrn vˇsech uˇzivatelsk´ ych zdrojov´ ych k´od˚ u (GLSL i C# soubor˚ u), textur a model˚ u. Dalˇs´ı informaci, kterou v projektu potˇrebujeme uloˇzit, ale nen´aleˇz´ı logicky ˇz´adn´emu z uveden´ ych zdroj˚ u, uloˇz´ıme do vlastnost´ı projektu. Ve vlastnostech projektu je uloˇzen seznam program˚ u a seznam referenc´ı. Seznam program˚ u obsahuje shadery, ze kter´ ych se programy skl´adaj´ı. Nav´ıc obsahuje seznam atribut˚ u pro dan´ y program, kter´e vstupuj´ı do vertex shaderu. Kaˇzd´a poloˇzka v seznamu m´a ˇretˇezcov´ y n´azev a celoˇc´ıseln´ y index, na kter´ y je atribut nav´az´an. Kdyˇz se pos´ıl´a informace o programech do vizualizaˇcn´ıho okna, okno nastav´ı indexy atribut˚ u podle uloˇzen´ ych z´aznam˚ u v seznamu. Uˇzivatel samozˇrejmˇe m˚ uˇze stejnou informaci napsat do zdrojov´eho k´odu vertex shaderu pomoc´ı layout kvalifik´atoru, jak je uvedeno v teoretick´e ˇc´ast (kapitola 2.2.5). Reference potˇrebuje projekt pro kompilaci zdrojov´ ych k´od˚ u. Standardn´ı reference odkazuj´ı na syst´emov´e knihovny a na knihovny OpenTK. Uˇzivateli je umoˇznˇeno pˇrid´avat reference na jin´e dalˇs´ı knihovny.
10.2
Naˇ c´ıt´ an´ı textur
Editor podporuje pouze naˇc´ıt´an´ı dvourozmˇern´ ych textur. Textury jsou naˇc´ıt´any v podobˇe obr´azk˚ u. Editor dok´aˇze obr´azky pouze zobrazovat, nedok´aˇze 68
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
je upravovat. Obr´azky se mezi aplikaˇcn´ımi dom´enami nedaj´ı pos´ılat jako objekt tˇr´ıdy Bitmap [30]. Pokud otevˇreme obr´azek na disku a naˇcteme jej do objektu Bitmap, existuje zde propojen´ı mezi daty na disku a mezi objektem v pamˇeti. Cel´ y obr´azek se nekop´ıruje do pamˇeti, protoˇze by mohl zabrat pˇr´ıliˇs m´ısta. Bitmapy, kter´e se pos´ılaj´ı vizualizaˇcn´ımu oknu, se pˇrevedou na pole byt˚ u, kter´e se n´aslednˇe d´a serializovat. Vizualizaˇcn´ı okno si opˇet vytvoˇr´ı bitmapu z doˇsl´ ych dat. Aby textury nezabraly pˇr´ıliˇs mnoho pamˇeti, tak se po inicializaci vizualizace nahraj´ı na grafickou kartu a smaˇzou se z operaˇcn´ı pamˇeti. Kaˇzd´a textura je pak pˇr´ıtomna v k´odu vizualizace jen jednou, i kdyˇz ji pouˇz´ıvaj´ı r˚ uzn´e programy. Na uk´azce 10.1 je vidˇet nastaven´ı textury pro program SP1. Program SP1 vyuˇz´ıv´a tuto texturu na pozici TextureUnit.Texture0. Pro pouˇzit´ı ji mus´ıme pˇred vykreslen´ım objektu nav´azat na stav OpenGL pro program SP1. Kdyˇz chce uˇzivatel pro jeden program pouˇz´ıt nˇekolik textur, mus´ı pˇred vykreslen´ım vˇsechny potˇrebn´e textury nav´azat na OpenGL. Kaˇzdou texturu mus´ı nav´azat pod jin´ ym indexem. OpenTK verze 1.1 dovoluje nastavit textury TextureUnit.Texture0 aˇz TextureUnit.Texture31. textures["scales"].SetShaderProgramUniform(shaderPrograms["SP1"], "scales", TextureUnit.Texture0); ... textures["scales"].Bind(shaderPrograms["SP1"]);
Tabulka 10.1: Uk´azka nastaven´ı textury
10.3
Naˇ c´ıt´ an´ı a pouˇ z´ıv´ an´ı 3D model˚ u
Spr´ava model˚ u souvis´ı se spr´avou shader˚ u. Kdyˇz potˇrebujeme vykreslit 3D model na sc´enˇe pomoc´ı nˇekter´eho efektu, mus´ıme propojit atributy programu s atributy modelu. Bud’ bude m´ıt vextex shaderpro kaˇzd´ y vstupn´ı atribut kvalifik´atory zarovn´an´ı, nebo uloˇz´ıme informaci zvl´aˇst’ do programu pomoc´ı grafick´eho rozhran´ı. Aby mohly m´ıt 3D modely propojen´e atributy s atributy shader˚ u, je 69
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
vhodn´e ukl´adat index atribut˚ u modelu do samotn´eho souboru s modelem. V takov´em pˇr´ıpadˇe nen´ı nutn´e ukl´adat tuto informaci nˇekam stranou do zvl´aˇstn´ıho souboru s nastaven´ım model˚ u a m˚ uˇzeme spravovat jedin´ y soubor. Existuj´ıc´ı form´aty pro 3D modely ale nebudou podporovat ukl´ad´an´ı t´eto dodateˇcn´e informace. Pokud vˇsak nechceme, aby byla vizualizace model˚ u specifick´a pouze na implementovan´ y n´astroj, je vhodn´e pouˇz´ıt nˇekter´ y z existuj´ıc´ıch a pouˇz´ıvan´ ych form´at˚ u pro 3D polygon´aln´ı modely. Nejv´ yhodnˇejˇs´ı se jevilo pouˇz´ıt form´at collada, protoˇze se ukl´ad´a ve form´atu XML. Platforma .NET umoˇzn ˇuje jednoduch´e naˇc´ıt´an´ı XML soubor˚ u. Form´at collada m´a ale velmi sloˇzitou strukturu. Dok´aˇze ukl´adat velk´e mnoˇzstv´ı vlastnost´ı, kter´e se v implementovan´e aplikaci nevyuˇzij´ı a nem˚ uˇze jednoduˇse uloˇzit informaci o indexu atribut˚ u. Pracovat s objektem, takov´eho typu, kter´ y by v pamˇeti uchov´aval vˇsechny informace ze souboru collada je pl´ ytv´an´ı pamˇet´ı. Z toho d˚ uvodu byl zaveden jednoduch´ y vnitˇrn´ı form´at model˚ u. Form´at m´a pˇr´ıponu rsm (render shader model). Objekt obsahuj´ıc´ı data ve form´atu rsm pouˇz´ıv´a editor i vizualizaˇcn´ı okno. z toho d˚ uvodu je jeho implementace souˇc´ast´ı knihovny Interfaces, kter´a je zodpovˇedn´a za komunikaci mezi editorem a vizualizaˇcn´ım oknem. Aplikace um´ı upravovat hodnoty objektu form´atu rsm v editoru a z´aroveˇ n um´ı pouˇz´ıt instanci objektu rsm form´atu pˇr´ımo ve vizualizaˇcn´ım oknˇe pro vykreslen´ı modelu. Pouˇzit´ı vnitˇrn´ıho form´atu m´a tu v´ yhodu, ˇze pˇri pˇr´ıpadn´e implementaci naˇc´ıt´an´ı z dalˇs´ıch form´at˚ u bude pˇr´ıtomna jednotn´a reprezentace model˚ u.
10.3.1
Popis vnitˇ rn´ıho form´ atu rsm
Form´at rsm m´a omezenˇejˇs´ı vlastnosti neˇz form´at collada. Byl navrˇzen tak, aby neobsahoval ˇza´dn´e jin´e informace neˇz popis geometrie a aby vyuˇz´ıval technologie .NET (export do xml, nastavov´an´ı jeho hodnot pomoc´ı komponenty PropertyGrid a serializaci). Z´aroveˇ n byl navrˇzen tak, aby uˇzivatel, kter´ y bude pouˇz´ıvat editor GLSL byl schopn´ y jej intuitivnˇe pouˇz´ıvat v programov´em k´odu. Kaˇzd´ y rsm model obsahuje n´asleduj´ıc´ı: • seznam atribut˚ u
70
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
– jm´eno (ˇretˇezcov´a promˇenn´a, s´emantick´a informace o druhu atributu) – seznam parametr˚ u (seznam ˇretˇezcov´ ych jmen parametr˚ u, napˇr´ıklad X, Y, Z) – index pro sv´az´an´ı s atributem shaderu (ˇc´ıslo, kter´e vyuˇz´ıv´a prvn´ı f´aze grafick´eho ˇretˇezce – vertex fetch) – index pro sv´az´an´ı s OpenGL bufferem pˇri vykreslov´an´ı • pole index˚ u • typ primitiva Model rsm, v jehoˇz seznamu atribut˚ u se ˇza´dn´ y atribut nenach´az´ı, je st´ale validn´ı. Soubor s pr´azdn´ ym seznamem atribut˚ u ale nem˚ uˇze popisovat ˇz´adn´ y polygon´aln´ı model. Pˇredpokl´ad´a se, ˇze hodnoty v pol´ıch atribut˚ u jsou vˇzdy ˇc´ısla s pohyblivou ˇr´adovou ˇca´rkou typu float. Pole index˚ u je vˇzdy pole cel´ ych nez´aporn´ ych ˇc´ısel typu uint. Form´at rsm m˚ uˇze pouze uchovat jednu geometrii. Nem˚ uˇze v sobˇe uchov´avat v´ıce ˇca´st´ı. Pˇredpokl´ad´a se, ˇze jeho atributy jsou vˇzdy hodnoty jeho pole vrchol˚ u. Poˇcet hodnot v poli lomeno poˇctem parametr˚ u kaˇzd´eho atributu mus´ı d´avat konstantn´ı hodnotu. Standardnˇe bude v seznamu atribut˚ u nejm´enˇe jedno pole float ˇc´ısel, kter´e urˇcuje pozice vrchol˚ u. Na rozd´ıl od form´atu collada je vnitˇrn´ı form´at pomˇernˇe n´aroˇcn´ y na velikost uloˇzen´e souboru. Kaˇzd´e float ˇc´ıslo ukl´ad´a do souboru zvl´aˇst’ mezi dvojici tag˚ u, kter´e ud´avaj´ı jeho typ. Jako vlastnost to m˚ uˇze b´ yt nepˇr´ıjemn´e pˇri ukl´ad´an´ı vˇetˇs´ıch model˚ u. Efektivita vykreslov´an´ı ani n´aroˇcnost na pamˇet’ ale ovlivnˇena nen´ı, protoˇze tato vlastnost se t´ yk´a pouze textov´eho xml souboru na disku. Form´at XML souboru je navrˇzen kv˚ uli standardn´ımu chov´an´ı tˇr´ıdy XmlSerializer a snadn´emu uloˇzen´ı. Ve chv´ıli, kdy je objekt naˇcten do pamˇeti, nen´ı v n´ı uchov´av´ana ˇz´adn´a redundantn´ı informace.
Pˇ r´ıklad M´ame 10 vrchol˚ u, kter´e maj´ı tˇri souˇradnice X, Y, z a z´aroveˇ n maj´ı texturovac´ı souˇradnice U a V. Uloˇzen´ y model bude m´ıt pr´avˇe dva atributy v seznamu atribut˚ u (standardnˇe pojmenovan´e POSITION a TEXCOORD, ale mohou m´ıt libovoln´a ˇretˇezcov´a jm´ena). Prvn´ı atribut pro pozici bude m´ıt pˇriˇrazen 71
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
jedno pole 30 float ˇc´ısel. Druh´ y atribut pro texturovac´ı souˇradnice bude m´ıt pˇriˇrazen jedno pole 20 float ˇc´ısel. Pokud bude m´ıt model nastaven typ primitiva jako troj´ uheln´ıky, bude se pole index˚ u ch´apat, jako ˇze jsou hodnoty sdruˇzeny ve skupin´ach po tˇrech. Kaˇzd´a trojice index˚ u ukazuje na tˇri vrcholy, kter´e tvoˇr´ı jeden troj´ uheln´ık.
10.3.2
Form´ at collada
Collada podporuje nejv´ıce vlastnost´ı v porovn´an´ı s ostatn´ımi form´aty. Hlavn´ım d˚ uvodem pro v´ ybˇer form´atu collada byla moˇznost jednoduˇse naˇc´ıst data z tohoto form´atu do pamˇeti. Collada soubor je XML soubor. Jazyk C# nab´ız´ı celkem jednoduch´e n´astroje pro z´ısk´av´an´ı dat z XML soubor˚ u. Pokud jsou vˇsechny vlastnosti objektu veˇrejn´e a neexistuje ˇza´dn´ y konstruktor s parametry, je ukl´ad´an´ı do XML a naˇc´ıt´an´ı z XML soubor˚ u trivi´aln´ı. Pro naˇcten´ı form´atu do struktury v pamˇeti byla staˇzena jiˇz existuj´ıc´ı implementace struktury collada [28].
Pouˇ z´ıvan´ e elementy[27] Protoˇze chceme pˇrev´adˇet model z form´atu collada do form´atu rsm, bude nejprve uveden a vysvˇetlen seznam relevantn´ıch element˚ u, kter´e collada pouˇz´ıv´a pro uloˇzen´ı dat t´ ykaj´ıc´ıch se geometrie: • library_geometries – obsahuje elementy geometry – collada form´at m˚ uˇze m´ıt definov´ano nˇekolik geometri´ı v jednom souboru • geometry – obsahuje element mesh – popisuje vizu´aln´ı tvar a vzhled objektu na sc´enˇe • mesh – obsahuje popis geometrie – elementy source, vertices, triangles a vˇsechny ostatn´ı elementy podle typu primitiv 72
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
– popisuje polygon´aln´ı model na z´akladˇe vrchol˚ u a informac´ı o pouˇzit´ ych primitivech • source – obsahuje napˇr´ıklad elementy float_array nebo technique_common – deklaruje data, na kter´a se odkazuje element input • input – vyuˇz´ıv´a se napˇr´ıklad v elementu vertices nebo v elementu triangles – popisuje s´emantiku datov´eho zdroje • vertices – obsahuje elementy input – popisuje atributy a identitu vrchol˚ u polygon´aln´ıho modelu • triangles, trifans, tristrips, lines, line_strips, polygons, polylist, spline – obsahuje elementy input – poskytuje informaci potˇrebnou k sv´az´an´ı atribut˚ u vrchol˚ u a vytvoˇren´ı jednotliv´ ych primitiv z dan´ ych vrchol˚ u (troj´ uheln´ık˚ u, troju ´heln´ıkov´ ych vˇej´ıˇr˚ u, troj´ uheln´ıkov´ ych p´as˚ u, ˇcar a dalˇs´ıch druh˚ u primitiv) • technique_common – v r´amci geometrie obsahuje elementy accessor – specifikuje informaci o atributu, vˇsechny implementace form´atu collada mus´ı podporovat tento element • accessor – obsahuje elementy param – popisuje pˇr´ıstup k pol´ım jako napˇr´ıklad floar_array • param – vyuˇz´ıv´a se v elementu accessor – popisuje jm´eno a typ jednoho parametru
73
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
• float_array – vyuˇz´ıv´a se v elementu source – obsahuje jednorozmˇern´e pole float ˇc´ıseln´ ych hodnot Form´at collada m˚ uˇze m´ıt sloˇzit´e indexov´an´ı. Sice podporuje pouze jedno pole idex˚ u pro jednu geometrii, ale v tomto poli m˚ uˇze ukl´adat nˇekolik skupin najednou. V takov´em pˇr´ıpadˇe nastav´ı u kaˇzd´eho elementu input vlastnost offset, kter´a urˇc´ı pozici, nakter´e zaˇc´ın´a v poli index˚ u prvn´ı hodnota pro dan´ y element input. Hodnota stride se pak rovn´a poˇctu element˚ u input v jednom z element˚ u pro specifikaci primitiva.
10.3.3
Konverze do rsm souboru
Form´at collada je velice obs´ahl´ y. Pˇri importu se bude poˇc´ıtat pouze s nejˇcastˇejˇs´ımi z´apisy model˚ u. Model ve form´atu collada mus´ı splˇ novat nˇekter´e poˇzadavky, aby bylo moˇzn´e jej pˇrev´est. Model mus´ı b´ yt sloˇzen´ y z troj´ uheln´ık˚ u nebo z´aplat. Veˇsker´a jeho data mus´ı b´ yt uloˇzena v pol´ıch float ˇc´ısel. Model mus´ı b´ yt nav´ıc vˇzdy indexovan´ y. Form´at rsm podporuje pr´avˇe jedno pole index˚ u. Z toho vypl´ yv´a, ˇze pˇri pˇrevodu se m˚ uˇze ztratit nˇekter´a informace. Form´at rsm nav´ıc m˚ uˇze uloˇzit pouze jednu geometrii. Pokud m´a soubor dae uloˇzeno v sobˇe v´ıce ˇc´ast´ı geometrie, export´er vybere vˇsechny geometrie a z kaˇzd´e vytvoˇr´ı jeden rsm soubor.
10.3.4
Rozd´ıl v indexov´ an´ı mezi form´ aty collada a rsm
Form´at collada m˚ uˇze indexovat vrcholy a jeho dodateˇcn´e informace zvl´aˇst’. Poˇcty vrchol˚ u a poˇcty norm´al se napˇr´ıklad nemus´ı rovnat. Pokud m´ame vrcholy tvoˇr´ıc´ı krychli a chceme m´ıt v souboru uloˇzeny i norm´aly, budeme pravdˇepodobnˇe cht´ıt, aby kaˇzd´ y vrchol krychle mˇel tˇri r˚ uzn´e norm´aly. Ve vrcholech krychle se ostˇre mˇen´ı smˇer norm´aly, a nem˚ uˇzeme pro dobr´ y efekt pouˇz´ıt pr˚ umˇernou hodnotu norm´al sousedn´ıch povrch˚ u nebo stˇen. Form´at collada v takov´emto pˇr´ıpadˇe umoˇzn ˇuje m´ıt uloˇzeno tˇreba jen pouze 8 vrchol˚ u a 6 norm´al. V´ ysledn´e pole index˚ u bude popisovat 12 troj´ uheln´ık˚ u (6 stˇen, kaˇzd´a se skl´ad´a z 2 troj´ uheln´ık˚ u), tud´ıˇz bude m´ıt 36 hodnot. 74
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
Potˇrebujeme jeˇstˇe jedno pole index˚ u, kter´e bude popisovat norm´aly. Toto pole bude stejnˇe dlouh´e, ale bude se muset skl´adat z jin´ ych hodnot. Form´at rsm takto strukturovan´ y nen´ı, protoˇze OpenGL nedok´aˇze s podobnou informac´ı pracovat. Pokaˇzd´e, kdyˇz poˇsleme do vertex shaderu vrchol, pˇredpokl´ad´ame, ˇze jeho pozice je posl´ana z´aroveˇ n se vˇsemi atributy dan´eho vrcholu. Nem˚ uˇzeme shaderu poslat 8 pozic a 6 norm´al. Mus´ıme v tomto pˇr´ıpadˇe shaderu poslat nejm´enˇe 24 z´aznam˚ u (3 kr´at 8 vrchol˚ u) Kaˇzd´ y fyzick´ y vrchol se objevuje ve tˇrech kopi´ıch. Kaˇzd´a z tˇechto kopi´ı m´a jinou norm´alu. Algoritmus pro pˇrevod index˚ u z form´atu collada do form´atu dae funguje n´asleduj´ıc´ım zp˚ usobem: 1. rozdˇel´ıme pole index˚ u (a) Ivrcholy – pole index˚ u indexuj´ıc´ı souˇradnice vrchol˚ u (b) I1 . . . In – pole index˚ u indexuj´ıc´ı hodnoty dalˇs´ıch atribut˚ u v jin´ ych pol´ıch 2. m´ame pole atribut˚ u (a) Vvrcholy – pole float ˇc´ısel se souˇradnicemi vrchol˚ u se sloˇzkami X, Y, Z (b) V1 . . . Vn – pole float ˇc´ısel s hodnotami dalˇs´ıch atribut˚ u n´aleˇz´ıc´ıch vrchol˚ um 3. chceme vytvoˇrit nov´a pole atribut˚ u, kter´a maj´ı jin´e velikosti a jin´a poˇrad´ı hodnot (a) W1 . . . Wn – pole float ˇc´ısel s hodnotami dalˇs´ıch atribut˚ u uspoˇra´d´ana tak, aby aby na nˇe m´ısto index˚ u I1 . . . In odkazovaly pouze indexy Ivrcholy 4. kaˇzd´e pole hodnot Vvrcholy, V1 . . . Vn m´a jin´ y poˇcet float ˇc´ısel na jeden atribut (a) avrcholy = 3; vrcholy maj´ı z pravidla tˇri souˇradnice X, Y , Z (b) a1 . . . an jsou r˚ uzn´a ˇc´ısla; z´avis´ı na tom, kolik v souboru collada obsahuje element accessor element˚ u parametr pro kaˇzd´e pole atribut˚ u 5. pro vˇsechny i od 1 do n (vytv´aˇr´ıme Wi za pomoc´ı Ii ) 75
Spr´ava zdroj˚ u
Naˇc´ıt´an´ı a pouˇz´ıv´an´ı 3D model˚ u
(a) Wi = new uint[Vvrcholy .Length / avrcholy * ai ] (b) pro vˇsechny j od 1 do Ii .Length i. star´ y index o = Ivrcholy [j] ii. nov´ y index p = Ii [j] iii. zkop´ırujemprvek z pole Vi a pozice o do pole Wi na pozici p Ve v´ yˇse nast´ınˇen´em algoritmu je vynech´an pouze implementaˇcn´ı detail, kdy kop´ırujeme element z pole Vi do pole Wi . Elementem se mysl´ı ai po sobˇe jdouc´ıch ˇc´ısel, protoˇze pole Vi i Wi jsou pouze jednorozmˇern´a pole float ˇc´ısel. Pokud m´ame pole barev s hodnotami RGB, bude ai = 3 a proto budeme kop´ırovat tˇri hodnoty z pole Vi do pole Wi . Index o i index p se pak n´asob´ı tˇremi a kop´ıruj´ı se tˇri ˇc´ısla. Nev´ yhoda pˇredeˇsl´eho algoritmu je ta, ˇze se spol´eh´ame na to, ˇze pole vrchol˚ u ud´av´a spr´avn´e poˇrad´ı a spr´avn´ y poˇcet vrchol˚ u. Pokud by se na jeden vrchol (se stejn´ ym indexem) v poli hodnot Vvrcholy odkazovalo pˇri indexov´an´ı v´ıcekr´at a po kaˇzd´e by mu byla pˇriˇrazenajin´a skupina ˇc´ısel z pole Vi , pak se dost´av´ame do situace, kterou nejde popsan´ ym algoritmem ˇreˇsit. v tomto pˇr´ıpadˇe aplikace pouze ozn´am´ı, ˇze doˇslo k pˇr´ıpadu, kdy je jednomu vrcholu pˇriˇrazov´ano v´ıce r˚ uzn´ ych atribut˚ u a pouˇzije pouze prvn´ı pˇriˇrazen´ y.
76
11 Sestaven´ı aplikace Aplikace se skl´ad´a z editoru programov´eho k´odu a z vizualizaˇcn´ıho okna. Hlavn´ı projekt implementuje vzhled a funkcionalitu editoru. Vizualizaˇcn´ı okno se vytv´aˇr´ı aˇz za bˇehu aplikace kompilac´ı zdrojov´ ych k´od˚ u pˇriloˇzen´ ych k aplikaci. Existuje fixn´ı ˇca´st zdrojov´ ych k´od˚ u, kter´a vytv´aˇr´ı vzhled vizualizaˇcn´ıho okna a jeho z´akladn´ı funkˇcnost. Knihovny, kter´e jsou distribuov´any s vytvoˇren´ ym editorem:: • Interfaces.dll – vlastn´ı knihovna, kter´a se pouˇz´ıv´a k manipulaci s vizualizaˇcn´ım oknem; d˚ uvod pro pouˇz´ıv´an´ı rozhran´ı je vysvˇetlen v kapitole 9.3 • OpenTK.dll 1.1.0 – manipulace s OpenGL funkcemi [29] • FATabStip – grafick´a komponenta z´aloˇzky pro otevˇren´e soubory [26] • FastColoredTextbox – grafick´a komponenta pro editov´an´ı a doplˇ nov´an´ı k´odu [20] Editor m´a pro zobrazov´an´ı zavedeny ˇctyˇri perspektivy, kter´e odpov´ıdaj´ı sloˇzk´am v projektu: • zobrazov´an´ı C# k´odu – sloˇzka customCode • zobrazov´an´ı GLSL k´odu – sloˇzka shaders • zobrazov´an´ı model˚ u – sloˇzka models • zobrazov´an´ı obr´azk˚ u – sloˇzka textures Kaˇzd´a perspektiva nastav´ı jednu z komponent FATabStrip [26] na viditelnou. Podle perspektivy se pˇrepneme bud’ na editor C# k´odu, editor GLSL k´odu, zobrazov´an´ı model˚ u nebo zobrazov´an´ı obr´azk˚ u. Pro kaˇzd´ y soubor, kter´ y otevˇreme z adres´aˇrov´eho stromu vlevo, se n´am otevˇre nov´a z´aloˇzka. v z´aloˇzce se objev´ı bud’ editor pro u ´pravu zdrojov´eho k´odu, PropertyGrid na u ´pravu vlastnost´ı modelu, nebo bitmapa na prohl´ednut´ı textury.
77
12 Z´avˇer Pˇredmˇetem diplomov´e pr´ace bylo vyvinout editor pro snadnou u ´pravu GLSL k´odu a n´aslednou vizualizaci v´ ysledk˚ u pr´ace. Bylo provedeno vyhodnocen´ı existuj´ıc´ıch n´astroj˚ u, kter´e se pro podobn´e u ´ˇcely pouˇz´ıvaj´ı. Nejprofesion´alnˇejˇs´ı a nejrozs´ahlejˇs´ı projekty, kter´e umoˇzn ˇuj´ı uˇzivateli mˇenit GLSL k´od a sledovat proveden´e zmˇeny, jsou n´astroje, kter´e jsou v prvn´ı ˇradˇe urˇcen´e pro ladˇen´ı jiˇz hotov´ ych OpenGL aplikac´ı. N´astroje pro ladˇen´ı aplikac´ı se zamˇeˇruj´ı pˇredevˇs´ım na sledov´an´ı v´ ykonu a krokov´an´ı. Z aplikac´ı, kter´e d´avaly d˚ uraz na u ´pravu shader˚ u a cel´e sc´eny, se nejv´ıce osvˇedˇcil program AMD RenderMonkey. RenderMonkey m´a nˇekolik nev´ yhod. Zejm´ena jeho ukonˇcen´ y v´ yvoj a neschopnost upravovat vykreslovac´ı smyˇcku. Byl implementov´an n´astroj pro rychl´e prototypov´an´ı GLSL projekt˚ u. Vyvinut´ y n´astroj umoˇzn ˇuje v´ yvoj efekt˚ u psan´ ych v GLSL a jejich vizualizaci. Editor d´av´a uˇzivateli pˇri v´ yvoji v´ıce moˇznost´ı neˇz jin´e testovan´e n´astroje pouˇz´ıvan´e pro rychl´e zobrazov´an´ı efekt˚ u. Uˇzivatel si m˚ uˇze napsat sv˚ uj vlastn´ı k´od pro inicializaci vizualizace a vykreslovac´ı smyˇcku. Uˇzivatel m˚ uˇze vytvoˇrit projekt s nˇekolika objekty, texturami a programy, kter´e budou pouˇzity k vykreslen´ı sc´eny. Protoˇze se ˇr´ıd´ıc´ı k´od vizualizaˇcn´ı smyˇcky p´ıˇse v jazyce C#, nen´ı uˇzivatel omezen´ y pˇri vytv´aˇren´ı vlastn´ıch efekt˚ u tolik, jako pˇri pr´aci s jin´ ymi n´astroji, kter´e umoˇzn ˇuj´ı pouze fixn´ı nastaven´ı vizualizace. Editor pom´ah´a uˇzivateli se orientovat v k´odu pomoc´ı zv´ yrazˇ nov´an´ı a z´aroveˇ n umoˇzn ˇuje uˇzivateli do jist´e m´ıry doplˇ novat k´od. Omezen´ı vyuˇzit´ı tohoto n´astroje plynou hlavnˇe z pouˇzit´e komponenty pro editaci zdrojov´eho k´odu. Zv´ yrazˇ nov´an´ı i doplˇ nov´an´ı k´odu funguje na z´akladˇe regul´arn´ıch v´ yraz˚ u. Nen´ı implementov´an pˇr´ıstup k ˇza´dn´e abstrakci zdrojov´eho k´odu. Pˇri doplˇ nov´an´ı k´odu nen´ı implementovan´ y ˇza´dn´ y sofistikovan´ y syst´em pro zapamatov´an´ı uˇzivatelsky definovan´ ych promˇenn´ ych. Dalˇs´ım omezen´ım n´astroje je nutnost pˇreloˇzit cel´ y zdrojov´ y k´od a restartovat vizualizaˇcn´ı aplikaci pokaˇzd´e, kdyˇz se provede zmˇena v C# zdrojov´em k´odu. Pro jednoduch´e vizualizace nen´ı probl´em okno restartovat, protoˇze pˇreklad trv´a pouze p´ar sekund. Kdyby bylo umoˇznˇeno uˇzivateli mˇenit prob´ıhaj´ıc´ı k´od pˇr´ımo pˇri bˇehu, byla by kladena na uˇzivatele mnohem vˇetˇs´ı zodpovˇednost. Uˇzivatel by se v nˇekter´ ych pˇr´ıpadech musel s´am starat o spr´avn´e naˇc´ıt´an´ı, pouˇz´ıv´an´ı a uvolˇ nov´an´ı zdroj˚ u.
78
Pˇ rehled term´ın˚ u wrapper – tenk´a vrstva k´odu, kter´ y pˇrev´ad´ı rozhran´ı nativn´ı knihovny do rozhran´ı kompatibiln´ı s jin´ ym jazykem IDE – v´ yvojov´e prostˇred´ı ˇci software usnadˇ nuj´ıc´ı pr´aci program´ator˚ u proxy – prostˇredn´ık pˇri vzd´alen´em vol´an´ı mezi klientem a serverem assembly – kompilovan´ y k´od .NET aplikace pˇripraven´ y pro nasazen´ı; m˚ uˇze se jednat o spustiteln´ y soubor (exe) nebo dynamicky linkovanou knihovny (dll); tento k´od je kompilov´an za bˇehu aplikace do strojov´eho jazyka shader – mnoˇzina ˇretˇezc˚ u kompilovan´a pro urˇcitou f´azi v grafick´em ˇretˇezci (GLSL terminologie) Vs – vertex shader TCs – tessellation control shader PG – gener´ator primitiv TES – tessellation evaluation shader GS – geometry shader Fs – fragment shader GLSL – jazyk pro programovac´ı grafick´e karty pro OpenGL OpenGL – API grafick´e knihovny pro vykreslov´an´ı 2D a 3D grafiky; je multiplatformn´ı a nez´avisl´e na programovac´ım jazyku API – programov´e rozhran´ı knihovny, kter´e specifikuje, jak maj´ı jednotliv´e
softwarov´e komponenty spolu komunikovat MDI – anglicky Multiple Document Interface je popis grafick´eho rozhran´ı, kdy jedno hlavn´ı okno obsahuje jedno nebo v´ıce oken; okna, kter´a jsou potomky hlavn´ıho okna nen´ı moˇzn´e zobrazit samostatnˇe bez aplikace a nelze je zobrazit mimo plochu pokrytou hlavn´ım oknem snipplet – mal´a ˇca´st k´odu znovu pouˇziteln´eho programov´eho k´odu
Literatura [1] ROST, Randi J. OpenGL Shading Language. Hillsboro, OR, U.S.A.: Addison-Wesley, 2004. ISBN 0-321-19789-5, str. 34. [2] SELLERS, Graham, WRIGHT, JR. a Nicholas HAEMEL. OpenGL SuperBible: Sixth Edition. Portland, OR, U.S.A.: Addison-Wesley, 2014. ISBN 978-0-321-90294-8. [3] OpenGL - The Industry Standard for High Performance Graphics [online]. 1997, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.opengl.org [4] OpenGL Shading Language - OpenGL.org [online]. 2009, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.opengl.org/wiki/OpenGL Shading Language [5] OpenGL Shading Language [online]. 1997, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.opengl.org/documentation/glsl/ [6] KESSENICH, John, Dave BALDWIN a Randi ROST. The OpenGL Shading Language [online]. 2004 [cit. 2014-05-14], str 56. Dostupn´e z: http://www.opengl.org/registry/doc/GLSLanGSpec.Full.1.10.59.pdf. [7] RenderMonkeyTM Toolsuite | AMD [online]. 2008 [cit. 2014-05-14]. Dostupn´e z: http://developer.amd.com/resources/archive/archivedtools/gpu-tools-archive/rendermonkey-toolsuite/ [8] GLSL Hacker - Pixel hacking with GLSL, Lua and Python - Scriptable 3D Game Engine | Geeks3D.com [online]. 2012, 2013 [cit. 2014-05-14]. Dostupn´e z: http://www.geeks3d.com/glslhacker/overview.php [9] GDEBugger Tutorial - OpenGL Debugger and Profiler [online]. 2004, 2010 [cit. 2014-05-14]. Dostupn´e z: http://www.gremedy.com/tutorial/
[10] GlslDevil - OpenGL GLSL Debugger [online]. 2007, 2010 [cit. 2014-05-14]. Dostupn´e z: http://www.vis.uni-stuttgart.de/glsldevil/ [11] Kick.js | Shader Editor [online]. 2012, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.kickjs.org/example/shader editor/shader editor.html [12] TyphoonLabs’ OpenGL Shader Designer [online]. 1997, 2012 [cit. 2014-05-14]. Dostupn´e z: http://www.opengl.org/sdk/tools/ShaderDesigner/ [13] GLSL Shader Maker [online]. 2013, 2013 [cit. 2014-05-14]. Dostupn´e z: http://shadermaker.codeplex.com [14] GDEBugger | AMD [online]. 2012, 2012 [cit. 2014-05-14]. Dostupn´e z: http://developer.amd.com/tools-and-sdks/archive/amd-gdebugger/ [15] CodeXL | AMD [online]. 2014, 2014 [cit. 2014-05-14]. Dostupn´e z: http://developer.amd.com/tools-and-sdks/opencl-zone/opencl-toolssdks/codexl/ [16] Scintilla and SciTE [online]. 1999, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.scintilla.org [17] ScintillaNET [online]. 2007, 2014 [cit. 2014-05-14]. Dostupn´e z: http://scintillanet.codeplex.com [18] Using ICSharpCode.TextEditor - CodeProject [online]. 2008 [cit. 2014-05-14]. Dostupn´e z: http://www.codeproject.com/Articles/30936/Using-ICSharpCodeTextEditor [19] GDI+ (Windows) [online]. 2012 [cit. 2014-05-14]. Dostupn´e z: http://msdn.microsoft.com/enus/library/windows/desktop/ms533798(v=vs.85).aspx [20] Fast Colored TextBox for Syntax Highlighting - CodeProject [online]. 2013, 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.codeproject.com/Articles/161871/Fast-Colored-TextBoxfor-syntax-highlighting [21] CleanCode C# Libraries v1.2.03 API [online]. 2001, 2013 [cit. 2014-05-14]. Dostupn´e z: http://cleancode.sourceforge.net/api/csharp/
[22] Clean Code [online]. 2013 [cit. 2014-05-14]. Dostupn´e z: http://en.sourceforge.jp/projects/sfnet cleancode/downloads/ cleancode/csharp/cleancode-csharp-v1 1 04.zip [23] Application Domains [online]. 2014 [cit. 2014-05-14]. Dostupn´e z: http://msdn.microsoft.com/en-us/library/2bh4z9hs(v=vs.110).aspx [24] Do The Right ThinGS [online]. 2009 [cit. 2014-05-14]. Dostupn´e z: http://do-the-right-thinGS.bloGSpot.cz/2009/07/cross-appdomainwinform-implementation.html [25] LifetimeServices Class (System.Runtime.Remoting.Lifetime) [online]. 2014 [cit. 2014-05-14]. Dostupn´e z: http://msdn.microsoft.com/en-us/library/system.runtime.remoting. lifetime.lifetimeservices(v=vs.110).aspx [26] FATabStrip.cs - A TabControl in the Visual Studio 2005 S [online]. 2006 [cit. 2014-05-14]. Dostupn´e z: http://www.codeforge.com/read/54729/FATabStrip.cs html [27] COLLADA - 3D Asset Exchange Schema [online]. 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.khronos.org/collada/ [28] C# Collada 1.5 Classes [online]. 2013 [cit. 2014-05-14]. Dostupn´e z: http://sourceforge.net/projects/csharpcollada [29] The Open Toolkit library | OpenTK [online]. 2014 [cit. 2014-05-14]. Dostupn´e z: http://www.opentk.com/project/opentk [30] Bitmap Class (System.Drawing) [online]. 2014 [cit. 2014-05-14]. Dostupn´e z: http://msdn.microsoft.com/enus/library/system.drawing.bitmap(v=vs.110).aspx [31] KESSENICH, John, Dave BALDWIN a Randi ROST. GLSLanGSpec.4.30.6. OpenGL Shading Language. 2012, str. 10 - 72. Dostupn´e z: www.opengl.org/registry/doc/GLSLanGSpec.4.30.6.pdf 50
Pˇ r´ılohy
Uˇ zivatelsk´ a pˇ r´ıruˇ cka Poˇ zadavky Pro spuˇstˇen´ı aplikace je nutn´e, aby uˇzivatel mˇel nainstalov´ano n´asleduj´ıc´ı: • operaˇcn´ı syst´em Windows Vista nebo vyˇsˇs´ı verzi • platformu .NET verzi 4.5 • knihovnu OpenGL verzi 4.3
Grafick´ e rozhran´ı Aplikace spouˇst´ı editor pro u ´pravu zdrojov´eho k´odu a dalˇs´ıch zdroj˚ u (obr´azek 12.1). V horn´ı ˇc´asti okna je hlavn´ı liˇsta. Pod n´ı panel n´astroj˚ u. V lev´e stranˇe okna je strom projekt˚ u. V prav´e ˇc´asti okna je spr´ava program˚ u (zobrazuje se pouze pˇri spuˇstˇen´e perspektivˇe pro shadery). V doln´ı ˇc´asti okna je logovac´ı box pro popis ud´alost´ı.
Panel n´ astroj˚ u Na panelu n´astroj˚ u je mnoho voleb zn´azornˇen´ ych ikonkami. Prvn´ı skupina obsahuje volby pro pr´aci s projektem. Druh´a skupina obsahuje volby pro u ´pravy zdrojov´ ych soubor˚ u. Tˇret´ı skupina ovl´ad´a zobrazov´an´ı pomocn´e informace, jako zobrazov´an´ı netisknuteln´ ych znak˚ u, zv´ yrazˇ nov´an´ı ˇr´adky s kurzorem nebo vod´ıc´ı teˇcky u blok˚ u k´odu. 1
Obr´azek 12.1: Vzhled aplikace V hlavn´ı nab´ıdce m˚ uˇzeme naˇc´ıst existuj´ıc´ı projekt, vytvoˇrit nov´ y projekt nebo vytvoˇrit projekt z uk´azkov´eho pˇr´ıkladu pod jin´ ym jm´enem. Pro prvn´ı pouˇz´ıv´an´ı se doporuˇcuje vytvoˇrit k´od z uk´azkov´eho pˇr´ıkladu, protoˇze pro spuˇstˇen´ı a rozbˇehnut´ı pr´azdn´eho projektu je zapotˇreb´ı udˇelat nˇekolik u ´prav. Uk´azkov´e pˇr´ıklady je moˇzn´e spustit ihned. Je moˇzn´e vytvoˇrit projekt z poskytnut´ ych pˇr´ıklad˚ u. Nejprve naˇcteme jeden z uk´azkov´ ych projekt˚ u (File/Import Project from Example/. . . ). Nov´ y projekt je moˇzno vytvoˇrit podle obr´azku 12.2. Pojmenujeme projekt nov´ ym jm´enem. Vˇsechny soubory, kter´e tvoˇrily uk´azkov´ y projekt, se zkop´ıruj´ı do sloˇzky s projekty (projects) a projekt se pˇrejmenuje. Dalˇs´ı skupina obsahuje n´astroje pro ovl´ad´an´ı vizualizace. Prvn´ı volba zkompiluje projekt a okamˇzitˇe ho spust´ı. Druh´a volba spust´ı posledn´ı pˇreloˇzenou verzi projektu. Pokud jeˇstˇe ˇz´adn´a pˇredeˇsl´a verze nen´ı, nebo pokud je posledn´ı pˇreloˇzen´ y projekt ze sloˇzky manu´alnˇe smaz´an, volba spuˇstˇen´ı posledn´ı pˇreloˇzen´e verze skonˇc´ı chybou. Dalˇs´ı pˇr´ıpad, kdy volba skonˇc´ı chybou je tehdy, kdyˇz nen´ı naˇcten´ y projekt v lok´aln´ı sloˇzce s ostatn´ımi projekty. 2
Obr´azek 12.2: Vytvoˇren´ı nov´eho projektu z pˇr´ıkladu Volba kompilace provede kompilaci pouze C# zdrojov´ ych k´od˚ u. Kompilace shader˚ u prob´ıh´a a pˇri spuˇstˇen´ı vizualizace, protoˇze shadery jsou kompilov´any ve spuˇstˇen´em oknˇe. Dalˇs´ı tˇri volby funguj´ı jen pokud je vizualizace spuˇstˇena. Slouˇz´ı pro aktualizaci textur, shader˚ u a model˚ u za bˇehu programu. Vˇsechny zdroje jedn´e kategorie se aktualizuj´ı najednou. Pokud je v nov´ ych zdroj´ıch chyba nebo jsou jinak pojmenov´any, vizualizace se zastav´ı. Zdrojov´ y k´od aplikace z˚ ust´av´a stejn´ y, takˇze automatick´e zpracov´an´ı zdroj˚ u je mus´ı naj´ıt podle pˇredchoz´ıch ˇretˇezcov´ ych jmen.
Spr´ ava program˚ u Spr´ava program˚ u se objevuje pouze pˇri aktivn´ı perspektivˇe pro shadery (obr´azek 12.3). v horn´ı ˇca´sti je tabulka, kter´a popisuje mapov´an´ı atribut˚ u mezi programy a modely. Program se skl´ad´a ze shader˚ u, kter´e jsou vybr´any v doln´ı ˇc´asti panelu pro spr´avu program˚ u. Pokud chceme vytvoˇrit nov´ y program, mus´ıme nejdˇr´ıve napsat jeho n´azev (totoˇzn´ y n´azev budeme pouˇz´ıvat v C# k´odu pˇri vyb´ır´an´ı ze slovn´ıku), d´ale vybereme shadery, kter´e bude pouˇz´ıvat, a nakonec klikneme na tlaˇc´ıtko Save Shader Program. Pokud chceme nˇekter´ y program vymazat, vybereme jej a klikneme na tlaˇc´ıtko Delete Shader Program. K existuj´ıc´ım program˚ um m˚ uˇzeme pˇridat do tabulky mapov´an´ı atribut˚ u bud’ manu´alnˇe pˇrid´an´ım nov´eho z´aznamu, nebo 3
Obr´azek 12.3: Panel spr´avy program˚ u automaticky stiskem tlaˇc´ıtka Match AttribuTES to Model. Zobraz´ı se nab´ıdka, ve kter´e vybereme model, jehoˇz atributy chceme pouˇz´ıt. Atributy modelu a jeho indexy se zkop´ıruj´ı do tabulky. Pokud bychom nˇekter´ y atribut pouˇz´ıt nechtˇeli, oznaˇc´ıme ˇr´adek v tabulce kliknut´ım nalevo od dan´eho ˇra´dku a stiskem kl´avesy delete smaˇzeme z´aznam. Pokud zjist´ıme, ˇze model obsahuje chybn´e atributy, mus´ıme je opravit pˇr´ımo v nastaven´ı modelu.
Strom projektu V lev´e ˇc´asti okna je strom otevˇren´ ych projekt˚ u (obr´azek 12.4). Otev´ıran´ y projekt automaticky naˇcte do stromu vˇsechny soubory se spr´avn´ ymi pˇr´ıponami ve sv´ ych sloˇzk´ach. v tomto stromu m˚ uˇzeme vybrat jak´ ykoliv zdroj dvoj´ım 4
poklep´an´ım na jeho ikonu soubor.
Obr´azek 12.4: Strom projekt˚ u Prav´ ym kliknut´ım kdekoliv na strom se objev´ı dialogov´e okno, kter´e umoˇzn´ı nastavit oznaˇcen´ y projekt jako hlavn´ı projekt, zmˇenit reference projektu, pˇridat nov´ y zdrojov´ y soubor, importovat model a smazat nebo pˇrejmenovat oznaˇcen´ y soubor. Pˇrejmenovat soubor lze tak´e dvoj´ım kliknut´ım na text souboru. Zmˇenit pˇr´ıponu souboru je zak´az´ano. Pˇrejmenov´avat sloˇzky je tak´e zak´az´ano.
Textov´ y log Vypisuje nˇekter´e d˚ uleˇzit´e ud´alosti. Nejd˚ uleˇzitˇejˇs´ı ud´alost´ı jsou chyby pˇri kompilaci. Vyp´ıˇse typ chyby a ˇra´dku, ve kter´e chyba nastala. Editor z´aroveˇ n 5
otevˇre soubor, ve kter´em se nach´az´ı chyba a oznaˇc´ı ˇcervenˇe chybnou ˇra´dku v k´odu.
Obr´azek 12.5: Vzhled logovac´ıho okna V logovac´ım oknˇe (viz 12.5) jsou obyˇcejn´e ud´alosti vypisov´any ˇcernou barvou, chyby ˇcervenou barvou a varov´an´ı modrou barvou. Logovac´ı okno se automaticky posunuje na konec kdyˇz v nˇem nen´ı um´ıstˇen kurzor.
Pr´ ace s vizualizaˇ cn´ım oknem Pˇri spuˇstˇen´ı projektu se objev´ı nov´e okno ve formˇe MDI potomka. v doln´ı ˇc´asti vizualizaˇcn´ıho okna se nach´az´ı komponenty pro vkl´ad´an´ı nejˇcastˇeji pouˇz´ıvan´ ych vstup˚ u, jako vzd´alenost objektu od kamery, rychlost zmˇeny velikosti pˇri rolov´an´ı koleˇcka myˇsi a oˇrez´avac´ı roviny. V prav´e ˇc´asti okna (viz 12.6) vid´ıme komponentu PropertyGrid, kter´a zobrazuje a nastavuje uˇzivatelsk´e glob´aln´ı promˇenn´e. Ot´aˇcen´ı modelu v poskytovan´ ych pˇr´ıkladech (jen v tˇech, ve kter´ ych jsou implementov´any transformace) se prov´ad´ı stisknut´ım a drˇzen´ım lev´eho tlaˇc´ıtka myˇsi nad kreslic´ı plochou a n´asledn´ ym pohybem myˇsi. Kdyˇz pracujeme s vizualizaˇcn´ım oknem a kurzor nen´ı v ˇz´adn´e komponentˇe pro uˇzivatelsk´ y vstup, koleˇcko myˇsi ovlivˇ nuje ˇsk´alov´an´ı sc´eny. v prav´e horn´ı ˇc´asti vizualizaˇcn´ıho okna se d´a vypnout aktualizace sc´eny vyvolan´e pˇr´ıchodem dalˇs´ıch sn´ımk˚ u. Vˇsechny vstupy vytvoˇren´e v grafick´em rozhran´ı maj´ı svoj´ı funkcionalitu implementovanou v k´odu, kter´ y m˚ uˇze uˇzivatel mˇenit. Automaticky prob´ıh´a pouze propagace hodnot do tˇr´ıd, ke kter´ ym m´a uˇzivatel pˇr´ıstup. Uˇzivatel se m˚ uˇze rozhodnout napojit u ´plnˇe jin´ y obsluˇzn´ y k´od na zmˇenu ˇc´ıseln´e hodnoty pro ˇsk´alov´an´ı, vyvolan´e pohybem koleˇcka myˇsi. Rozhran´ı vizualizaˇcn´ıho okna bylo takto navrˇzeno pouze z toho d˚ uvodu, ˇze ˇsk´alov´an´ı je jedna z akc´ı, kterou uˇzivatel bude cht´ıt prov´adˇet nejˇcastˇeji, a napojit ji na posuv koleˇcka myˇsi je 6
Obr´azek 12.6: Vzhled vizualizaˇcn´ıho okna s naˇcten´ ym uk´azkov´ ym tessellaˇcn´ım projektem nejv´ıce intuitivn´ı chov´an´ı. Mˇenit ˇsk´alov´an´ı sc´eny nebo natoˇcen´ı modelu psan´ım ˇc´ıseln´ ych hodnot do komponenty PropertyGrid nen´ı pˇr´ıliˇs uˇzivatelsky pˇr´ıvˇetiv´e.
´ Upravy shader˚ u v editoru V adres´aˇrov´em stromˇe projektu si m˚ uˇzeme naj´ıt soubory GLSL, kter´e projekt pouˇz´ıv´a. Editor shader˚ u doplˇ nuje pˇrednastaven´e promˇenn´e, funkce a vyhrazen´a slova. Nav´ıc editor doplˇ nuje n´azvy uniform promˇenn´ ych, kter´e jsou uloˇzen´e v programu. N´azvy uniform promˇenn´ ych se poˇslou naˇsept´avaˇci pokaˇzd´e, kdy je uloˇzen shader. Uniform promˇenn´e se sd´ıl´ı pouze mezi shadery v r´amci jednoho programu, proto je nutn´e nejdˇr´ıve shadery spojit, neˇz se m˚ uˇze zaˇc´ıt vyuˇz´ıvat t´eto vlastnosti. Shadery se spojuj´ı do programu v prav´e ˇca´sti okna pˇri zapnut´e perspektivˇe pro shadery. Po nastaven´ı shader˚ u pro vybran´ y (nebo nov´ y) program je nutn´e kliknout na tlaˇc´ıtko pro uloˇzen´ı programu. 7
´ Upravy C# zdrojov´ eho k´ odu v editoru Zdrojov´ y k´od napsan´ y v C# mus´ı b´ yt poskytnut nejm´enˇe pro implementaci vlastn´ıho vizualizaˇcn´ıho modulu a vlastn´ıho souboru glob´aln´ıch promˇenn´ ych. Uˇzivatel si m˚ uˇze vytvoˇrit dalˇs´ı cs soubory s vlastn´ım k´odem, kter´ y se d´a vyuˇz´ıvat pˇri implementaci k´odu projektu. Uˇzivatel by se mˇel ˇr´ıdit podle n´apovˇedy psan´e v koment´aˇr´ıch uk´azkov´ ych projekt˚ u. U kaˇzd´e metody, kterou m˚ uˇze uˇzivatel implementovat, je pops´ano, kdy se vol´a a pro jakou ˇcinnost se hod´ı.
Metoda Init Metoda Init se vol´a po automatick´e inicializaci vˇsech zdroj˚ u. Uˇzivatel si v n´ı bude cht´ıt hlavnˇe uloˇzit indexy uniform promˇenn´ ych pro n´asledn´e nastavov´an´ı jejich hodnot. Je samozˇrejmˇe moˇzn´e neust´ale pˇristupovat ke vˇsem hodnot´am pˇres ˇretˇezcov´e konstanty, ale tento pˇr´ıstup m˚ uˇze b´ yt velice pomal´ y. V pˇr´ıpadˇe, ˇze prov´ad´ıme aktualizaci v kaˇzd´em sn´ımku, tak se jev´ı nesmysln´e zjiˇst’ovat index uniform promˇenn´e z jej´ı ˇretˇezcov´e konstanty pˇred kaˇzd´ ym nastaven´ım jej´ı hodnoty. Tato informace by se nemˇela ukl´adat nikde jinde neˇz v metodˇe Init. Pokud se zmˇen´ı mnoˇzina nebo poˇrad´ı uniform promˇenn´ ych, mohlo by se st´at, ˇze stejn´e uniform promˇenn´e budou m´ıt po aktualizaci jin´e indexy. Pokud nastaven´ı index˚ u bude prob´ıhat v metodˇe Init, zmˇeny nezp˚ usob´ı pot´ıˇze, protoˇze Init se vol´a pˇri kaˇzd´em restartu zdroj˚ u.
Metoda InputUpdate Metoda InputUpdate se vol´a pˇri kaˇzd´e zmˇenˇe hodnot zp˚ usoben´e interakc´ı s uˇzivatelsk´ ym rozhran´ım. Je vytvoˇrena za u ´ˇcelem volat k´od, kter´ y propaguje hodnoty z´ıskan´e z uˇzivatelsk´eho rozhrann´ı do shader˚ u. Vˇsechny hodnoty z uˇzivatelsk´eho rozhran´ı jsou uloˇzeny bud’ v chr´anˇen´ ych atributech tˇr´ıdy nebo v objektu globalVarSet. Vol´an´ı metody nast´av´a v pˇr´ıpadech: • drˇzen´ı lev´eho tlaˇc´ıtka myˇsi a taˇzen´ı po zobrazovac´ı ploˇse • ot´aˇcen´ı koleˇcka myˇsi
8
• roztahov´an´ı okna • nastavov´an´ı hodnot v komponentˇe PropertyGrid • nastavov´an´ı hodnot ve vˇsech ostatn´ıch komponent´ach pod zobrazovac´ı plochou (s v´ yjimkou rychlosti ˇsk´alov´an´ı, protoˇze se nemˇen´ı hodnota ˇsk´alov´an´ı ale pouze velikost kroku pˇri ot´aˇcen´ı koleˇcka myˇsi)
Metoda LoopUpdate Metoda LoopUpdate se vol´a pˇred kaˇzd´ ym vykreslen´ım sn´ımku, pokud uˇzivatel v grafick´em rozhran´ı m´a zaˇskrtnut´e pol´ıˇcko (vpravo nahoˇre) pro aktualizaci ve smyˇcce. D˚ uvod pro moˇznost zak´azat vol´an´ı metody je v aktualizaci glob´aln´ıch promˇenn´ ych, kter´e se zobrazuj´ı v komponentˇe PropertyGrid. Pokud je v´ ypoˇcet jejich hodnot prov´adˇen v t´eto metodˇe na z´akladˇe pouze jiˇz nastaven´ ych hodnot, nem˚ uˇze uˇzivatel zmˇenit ˇza´dn´e hodnoty, kter´e se v t´eto metodˇe aktualizuj´ı. V dalˇs´ım sn´ımku po vykonan´e zmˇenˇe by se hodnoty opˇet pˇrehr´aly na hodnoty vypoˇcten´e pˇri aktualizaci animace. Komponenta PropertyGrid je nastavena tak, aby se pˇrestala aktualizovat v okamˇziku, kdy do n´ı vstoup´ı kurzor. Zdroj dat pro komponent se neust´ale aktualizuje. Uˇzivatel m˚ uˇze d´ıky zastaven´e aktualizaci uˇzivatelsk´eho rozhran´ı mˇenit hodnoty glob´aln´ıch promˇenn´ ych, kter´e nejsou poˇc´ıt´any ve smyˇcce. Doporuˇcuje se do t´eto metody ps´at pouze k´od, kter´ y se opravdu mus´ı aktualizovat v kaˇzd´em sn´ımku, jako napˇr´ıklad animace z´avisl´a na ˇcase. Pokud staˇc´ı aktualizace na uˇzivatelsk´ y vstup, mˇel by se k´od ps´at do metody InputUpdate.
Metoda Render Metoda Render se vol´a v kaˇzd´em sn´ımku. Je moˇzn´e zde ps´at k´od pro aktualizaci promˇenn´ ych, ale u ´ˇcel t´eto metody je napsat k´od pro vykreslen´ı sc´eny z jiˇz vypoˇc´ıtan´ ych hodnot. V metodˇe Render se bude volat pouˇz´ıv´an´ı program˚ u, nastavov´an´ı textur, vykreslov´an´ı model˚ u a pˇr´ıpadˇe zmˇeny nastaven´ı OpenGL.
9
Uk´ azkov´ e pˇ r´ıklady V projektu je pˇrednastaveno nˇekolik uk´azkov´ ych pˇr´ıklad˚ u pro ilustraci a jako n´apovˇeda pˇri pouˇz´ıv´an´ı n´astroje. Pˇr´ıklady jsou vytvoˇreny jako uk´azky, jak ps´at jednotliv´e shadery, jak nastavovat zdroje aplikace, jak implementovat transformaˇcn´ı matice a jak pouˇz´ıvat naˇcten´e zdroje v k´odu vizualizaˇcn´ı smyˇcky.
Nejjednoduˇ sˇ s´ı shader (Simplest Shader) Nejjednoduˇsˇs´ı shader ukazuje vykreslen´ı jednoho troj´ uheln´ıku. Nen´ı implementov´ana ˇza´dn´a animace ani interaktivn´ı funkcionalita.
Z´ akladn´ı shader (Basic Shader) Uk´azka nejjednoduˇsˇs´ıho projektu s vertex shaderem a fragment shaderem. Soubor s glob´aln´ımi promˇenn´ ymi obsahuje pouze promˇenn´e potˇrebn´e pro geometrick´e transformace a smˇer svˇetla. Zobrazovan´a krychle nepouˇz´ıv´a barvy ani texturu.
Geometry shader (Geometry Shader) Uk´azka pouˇzit´ı geometry shaderu. Tento shader pouze demonstruje jednoduch´e generov´an´ı dalˇs´ıch troj´ uheln´ık˚ u, kter´e jsou posunut´e ve smˇeru osy x na obˇe strany od p˚ uvodn´ıho troj´ uheln´ıku. V´ ysledkem jsou tˇri krychle z p˚ uvodn´ı jedn´e. Tato uk´azka nav´ıc pˇredv´ad´ı pr´aci s animac´ı, kde se mˇen´ı barva pozad´ı. Uk´azka pouˇz´ıv´a vˇsechny glob´aln´ı promˇenn´e jako pˇredchoz´ı uk´azka a nav´ıc se pouˇz´ıv´a textura. Textura se mus´ı v metodˇe Init sv´azat s programem, kter´ y ji bude pouˇz´ıvat a mus´ı se nastavit pozice textury pro tento program. Kaˇzd´ y program m˚ uˇze v jednu chv´ıli pouˇz´ıvat pouze omezen´e mnoˇzstv´ı textur. OpenTK verze 1.1 obsahuje konstanty pro TextureUnit.Texture0 aˇz do TextureUnit.Texture31.
10
Tessellation shader (Tessellation Shader) Uk´azka TESselaˇcn´ıho shaderu. Kaˇzdou sekundu se mˇen´ı vnitˇrn´ı a vnˇejˇs´ı dˇelen´ı troj´ uheln´ık˚ u. Po zastaven´ı animace (zaˇskrt´avac´ım pol´ıˇckem vpravo nahoˇre) m˚ uˇze uˇzivatel zadat svoje vlastn´ı dˇelen´ı do komponenty PropertyGrid. Uk´azka pouˇz´ıv´a stejn´e glob´aln´ı promˇenn´e jako nejjednoduˇsˇs´ı shader.
Nˇ ekolik program˚ u (Multiple Programs) Posledn´ı uk´azka pˇredv´ad´ı moˇznost pouˇzit´ı nˇekolika model˚ u, nˇekolika textur a nˇekolika program˚ u najednou. Indexy uniform˚ u kaˇzd´eho programu se mus´ı uloˇzit. Pokud budou nˇekter´e programy pouˇz´ıvat spoleˇcn´e hodnoty promˇenn´ ych, bude se jim v metodˇe InputUpdate pˇriˇrazovat stejn´a hodnota. Jeden z program˚ u pouˇz´ıv´a texturu dˇreva na pozici TextureUnit.Texture1, jin´ y program pouˇz´ıv´a texturu dˇreva na pozici TextureUnit.Texture0. Zde je vidˇet d˚ uvod, proˇc pˇri pouˇz´ıv´an´ı textur v metodˇe Render mus´ıme specifikovat, pro kter´ y program texturu pouˇz´ıv´ame.
11