Permalink
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
155 lines (117 sloc) 3.18 KB
module Cube exposing (main)
{-
Rotating cube with colored sides.
-}
import Browser
import Browser.Events exposing (onAnimationFrameDelta)
import Html exposing (Html)
import Html.Attributes exposing (height, style, width)
import Math.Matrix4 as Mat4 exposing (Mat4)
import Math.Vector3 as Vec3 exposing (vec3, Vec3)
import WebGL exposing (Mesh, Shader)
import Json.Decode exposing (Value)
main : Program Value Float Float
main =
Browser.element
{ init = \_ -> ( 0, Cmd.none )
, view = view
, subscriptions = (\_ -> onAnimationFrameDelta Basics.identity)
, update = (\dt theta -> ( theta + dt / 5000, Cmd.none ))
}
view : Float -> Html Float
view theta =
WebGL.toHtml
[ width 400
, height 400
, style "display" "block"
]
[ WebGL.entity
vertexShader
fragmentShader
cubeMesh
(uniforms theta)
]
type alias Uniforms =
{ rotation : Mat4
, perspective : Mat4
, camera : Mat4
, shade : Float
}
uniforms : Float -> Uniforms
uniforms theta =
{ rotation =
Mat4.mul
(Mat4.makeRotate (3 * theta) (vec3 0 1 0))
(Mat4.makeRotate (2 * theta) (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 : 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
[ 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
]
|> List.concat
|> WebGL.triangles
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 : 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 : Shader {} Uniforms { vcolor : Vec3 }
fragmentShader =
[glsl|
precision mediump float;
uniform float shade;
varying vec3 vcolor;
void main () {
gl_FragColor = shade * vec4(vcolor, 1.0);
}
|]