forked from elm/elm-lang.org
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
590 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
-- elm install elm-explorations/linear-algebra | ||
-- elm install elm-explorations/webgl | ||
|
||
|
||
import Browser | ||
import Browser.Events as E | ||
import Html exposing (Html) | ||
import Html.Attributes exposing (width, height, style) | ||
import Math.Matrix4 as Mat4 exposing (Mat4) | ||
import Math.Vector3 as Vec3 exposing (Vec3, vec3) | ||
import WebGL | ||
|
||
|
||
|
||
-- MAIN | ||
|
||
|
||
main = | ||
Browser.element | ||
{ init = init | ||
, view = view | ||
, update = update | ||
, subscriptions = subscriptions | ||
} | ||
|
||
|
||
|
||
-- MODEL | ||
|
||
|
||
type alias Model = | ||
Float | ||
|
||
|
||
init : () -> (Model, Cmd Msg) | ||
init () = | ||
( 0, Cmd.none ) | ||
|
||
|
||
|
||
-- UPDATE | ||
|
||
|
||
type Msg | ||
= TimeDelta Float | ||
|
||
|
||
update : Msg -> Model -> (Model, Cmd Msg) | ||
update msg angle = | ||
case msg of | ||
TimeDelta dt -> | ||
( angle + dt / 5000, Cmd.none ) | ||
|
||
|
||
|
||
-- SUBSCRIPTIONS | ||
|
||
|
||
subscriptions : Model -> Sub Msg | ||
subscriptions _ = | ||
E.onAnimationFrameDelta TimeDelta | ||
|
||
|
||
|
||
-- VIEW | ||
|
||
|
||
view : Model -> Html Msg | ||
view angle = | ||
WebGL.toHtml | ||
[ width 400, height 400, style "display" "block" | ||
] | ||
[ WebGL.entity vertexShader fragmentShader cubeMesh (uniforms angle) | ||
] | ||
|
||
|
||
type alias Uniforms = | ||
{ rotation : Mat4 | ||
, perspective : Mat4 | ||
, camera : Mat4 | ||
, shade : Float | ||
} | ||
|
||
|
||
uniforms : Float -> Uniforms | ||
uniforms angle = | ||
{ rotation = | ||
Mat4.mul | ||
(Mat4.makeRotate (3 * angle) (vec3 0 1 0)) | ||
(Mat4.makeRotate (2 * angle) (vec3 1 0 0)) | ||
, perspective = Mat4.makePerspective 45 1 0.01 100 | ||
, camera = Mat4.makeLookAt (vec3 0 0 5) (vec3 0 0 0) (vec3 0 1 0) | ||
, shade = 0.8 | ||
} | ||
|
||
|
||
|
||
-- MESH | ||
|
||
|
||
type alias Vertex = | ||
{ color : Vec3 | ||
, position : Vec3 | ||
} | ||
|
||
|
||
cubeMesh : WebGL.Mesh Vertex | ||
cubeMesh = | ||
let | ||
rft = vec3 1 1 1 | ||
lft = vec3 -1 1 1 | ||
lbt = vec3 -1 -1 1 | ||
rbt = vec3 1 -1 1 | ||
rbb = vec3 1 -1 -1 | ||
rfb = vec3 1 1 -1 | ||
lfb = vec3 -1 1 -1 | ||
lbb = vec3 -1 -1 -1 | ||
in | ||
WebGL.triangles <| List.concat <| | ||
[ face (vec3 115 210 22 ) rft rfb rbb rbt -- green | ||
, face (vec3 52 101 164) rft rfb lfb lft -- blue | ||
, face (vec3 237 212 0 ) rft lft lbt rbt -- yellow | ||
, face (vec3 204 0 0 ) rfb lfb lbb rbb -- red | ||
, face (vec3 117 80 123) lft lfb lbb lbt -- purple | ||
, face (vec3 245 121 0 ) rbt rbb lbb lbt -- orange | ||
] | ||
|
||
|
||
face : Vec3 -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> List ( Vertex, Vertex, Vertex ) | ||
face color a b c d = | ||
let | ||
vertex position = | ||
Vertex (Vec3.scale (1 / 255) color) position | ||
in | ||
[ ( vertex a, vertex b, vertex c ) | ||
, ( vertex c, vertex d, vertex a ) | ||
] | ||
|
||
|
||
|
||
-- SHADERS | ||
|
||
|
||
vertexShader : WebGL.Shader Vertex Uniforms { vcolor : Vec3 } | ||
vertexShader = | ||
[glsl| | ||
attribute vec3 position; | ||
attribute vec3 color; | ||
uniform mat4 perspective; | ||
uniform mat4 camera; | ||
uniform mat4 rotation; | ||
varying vec3 vcolor; | ||
void main () { | ||
gl_Position = perspective * camera * rotation * vec4(position, 1.0); | ||
vcolor = color; | ||
} | ||
|] | ||
|
||
|
||
fragmentShader : WebGL.Shader {} Uniforms { vcolor : Vec3 } | ||
fragmentShader = | ||
[glsl| | ||
precision mediump float; | ||
uniform float shade; | ||
varying vec3 vcolor; | ||
void main () { | ||
gl_FragColor = shade * vec4(vcolor, 1.0); | ||
} | ||
|] |
Oops, something went wrong.