Přejít k navigační liště

Zdroják » JavaScript » Elm, WebGL a elm kompilátor

Elm, WebGL a elm kompilátor

Články JavaScript

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.

Nálepky:

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.

Komentáře

Subscribe
Upozornit na
guest
1 Komentář
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.