Elm, WebGL a elm kompilátor

V minulém díle jsme si ukázali základní použití WebGL v jazyce Elm a porovnali ho s tím, jak se používá WebGL API v JavaScriptu (bez použití knihoven). Nyní vyjdeme z druhého dílu seriálu Ondřeje Žáry WebGL: Milostný RGB trojúhelník a popsaný příklad přepíšeme do jazyka Elm. Pak se podíváme na zajimavou schopnost elm kompilátoru.

Pojďme hned na věc. V Elmu bude vypadat příklad z článku WebGL: Milostný RGB trojúhelník takto:

 

 

module Main exposing (..)

import Math.Vector3 exposing (..)
import WebGL exposing (..)
import Html exposing (Html)
import Html.App as Html
import Html.Attributes exposing (width, height)


{-
   V Javascriptovém WebGL příkladu definuje Ondra dvě pole
   jedno pro souřadnice vrcholů a jedno pro barvy vrcholů.
   A pak je propojí (binduje) s bufferem.

   V Elmu to uděláme maličko jinak.
   Souřadnice a barvu vložíme do jednoho záznamu.
   Obě hodnoty budou uloženy jako trojrozměrný vektor.

   Zde je definován typ pro vrchol.
-}


type alias Vertex =
    { position : Vec3, color : Vec3 }



{-
   V této funkci si vytvoříme data, vrcholy.
   Každý vrchol je záznamem dle výše uvedené definice a obsahuje souřadnice a barvu.
   Z vrcholů vytvoříme trojici a tu vložíme do pole.
   V poli bude jedna taková trojice, neb máme jen jeden trojuhelník.
   Aha, máme trojuhelník. Ondra ve svém článku vykresluje trojuhelníky jako čáry.
   A řeší a vysvětluje problematiku spojenou s tím, že se jednotlivé vrcholy opakují.
   Pevně doufám, že elm-webgl má tuto věc vyřešenou (zdá se, že má).
   Použijeme tedy výčtový typ (union)  Drawable http://package.elm-lang.org/packages/elm-community/elm-webgl/3.0.3/WebGL#Drawable s tagem Triangle.
   Výčtový typ Drawable obsahuje tagy pro vykreslování trojuhelníků, čar a bodů.
-}


mesh : Drawable Vertex
mesh =
    Triangle
        [ ( Vertex (vec3 0 0 0) (vec3 1 0 0)
          , Vertex (vec3 1 1 0) (vec3 0 1 0)
          , Vertex (vec3 1 -1 0) (vec3 0 0 1)
          )
        ]



{-
   Oproti minulému dílu nebudeme ve funkci main rovnou vykreslovat,
   ale použijeme elm architecture http://guide.elm-lang.org/architecture/ pattern.
-}


main : Program Never
main =
    Html.program
        { init = ( 0, Cmd.none )
        , view = view
        , subscriptions =
            (\model -> Sub.none)
        , update = (\elapsed currentTime -> ( elapsed + currentTime, Cmd.none ))
        }



{-
   Grafiku vykreslíme ve funkci view, kterou jsme předali ve funkci main do Html.program.
   Jinak je to téměř stejný kód jako v minulém díle, kdy jsme vykreslovali jeden bod.
   Rozdíl je pouze v tom, že render dostane jiné shadery a jiná data.
-}


view : Float -> Html msg
view t =
    WebGL.toHtml
        [ width 400, height 400 ]
        [ render vertexShader fragmentShader mesh {} ]



-- Shaders
{-
   Vertex shader je vysvětlený a převzatý z příkladu
   WebGL: Milostný RGB trojúhelník https://www.zdrojak.cz/clanky/webgl-milostny-rgb-trojuhelnik/

   Elm dokáže kontrolovat syntaktické chyby v kódu. O tom si popovídáme za chvíli.
   Jen si všimněte, že v anotaci funkce je ve třetím parametru definována hodnota varyingColor.
   Stejně tak tomu bude i ve fragment shaderu, který tuto hodnotu přebírá.
-}


vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]



{-
   Zde vytváříme fragment shader, glsl kód opět kompletně převzatý z příkladu
   WebGL: Milostný RGB trojúhelník
   a i zde nesmíme zapomenout na parametr varyingColor v posledním parametru anotace funkce.
-}


fragmentShader : Shader {} {} { varyingColor : Vec3 }
fragmentShader =
    [glsl|



precision mediump float;
varying vec3 varyingColor;
void main(void) {
  gl_FragColor = vec4(varyingColor, 1.0);
}
|]

Toť vše, přátelé. Takto se to dělá v Elmu. Elm-webgl je poměrně nízkoúrovňová knihovna, musíme psát i shadery v jazyce glsl, ale pojďme se podívat, jak nám pomáhá elm kompilátor.

Nejprve upravíme kód takto:

-- vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader : Shader Vertex {} {  }

a zkompilujeme. Stačí spustit elm reactor a v prohlížeči otevřít url http://localhost:8000/src/Main.elm. Vyskočí na nás nepříjemná, ale přehledná chybová hláška.

screen-01

Výborně. Elm kompilátor pozná, když shaderu nedodáme potřebný parametr použitý v jazyce glsl. Tak to zase vrátíme zpět a uděláme chybu přímo v glsls kódu.

vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
-- varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]

Ani toto nám neprojde.

screen-02

Nemám chuť se šťourat v javascriptové verzi, ale předpokládám, že pokud tam glsl kód předávám jako textový řetězec, tak asi žádná validace toho kódu není možná a chyba se objeví později, či to prostě nebude fungovat a budeme pátrat, proč. Elm je šikulka.

Ještě jeden pokus na podobné téma. Zkusme v glsl kódu udělat syntaktickou chybu.

vertexShader : Shader Vertex {} { varyingColor : Vec3 }
vertexShader =
    [glsl|



attribute vec3 position;
attribute vec3 color;
varying vec3 varyingColor;
void main(void) {
  gl_Position = vec4(position, 1.0);
  varyingColor = color;
}

|]

Místo klíčového slova varying jsem napsal varyingXX. A co na to Elm?

screen-03

Nelíbí se mu to. Jasně říká, že na řádku 7 ve sloupci 15 je něco špatně. Tak to je od kompilátoru moc pěkné a užitečné.

Tato provázanost jazyka glsl a elm kompilátoru mne příjemně překvapila.

Závěr

V totmo díle jsme implementovali do Elmu příklad z článku WebGL: Milostný RGB trojúhelník. Podobný příklad najdeme na githubu elm-webgl. V něm je navíc implementována i animace, trojuhelník se otáčí. Použil jsem tento kód a animaci vymazal, aby příklad korespondoval s článkem Ondřeje Žáry. To obnášelo smazat několik málo řádků kódu a pár drobných úprav.

Animaci v pure javascriptovém WebGL API vysvětluje Ondřej Žára v dalším díle svého seriálu. Jak dělat pokročilejší věci s WebGL v Elmu je zřejmé z příkladů na githubu elm-webgl, a tak bych tě, milý čtenáři, poslal právě tam a své povídání o WebGL v Elmu tímto článkem ukončil.

Jsem programátor na volné noze. Věnuji se především zpracování a prezentaci dat. Zajímám se o programovací jazyky. Začínal jsem s jazykem C/C++ a PHP pro web. Pak jsem se nadchnul pro Python. Když přišel Node.js, začal jsem věnovat více své pozornosti JavaScriptu. Nyní mne zajímají především jazyky Rust a Elm. Krom toho opravuji s přáteli zchátralý dětský tábor v Karpatech (nejen) z hlíny a slámy. A dělám spoustu dalších věcí, kvůli kterým mi na programování nezbývá čas.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 1

Přehled komentářů

Petr Bolf další příklady
Zdroj: https://www.zdrojak.cz/?p=19007