Skip to content

Instantly share code, notes, and snippets.

@astrieanna
Created September 21, 2014 23:44
Show Gist options
  • Save astrieanna/80f69e2d9e29bc2d7e87 to your computer and use it in GitHub Desktop.
Save astrieanna/80f69e2d9e29bc2d7e87 to your computer and use it in GitHub Desktop.
modified version of http://elm-lang.org/edit/examples/WebGL/Cube.elm left-right movement of mouse controls cube rotation
import Math.Vector3 (..)
import Math.Matrix4 (..)
import Graphics.WebGL (..)
import Mouse
-- Create a cube in which each vertex has a position and color
type Vertex = { color:Vec3, position:Vec3 }
face : Color -> Vec3 -> Vec3 -> Vec3 -> Vec3 -> [Triangle Vertex]
face color a b c d =
let toV3 color =
let c = toRgb color
in vec3 (toFloat c.red / 255) (toFloat c.green / 255) (toFloat c.blue / 255)
p = Vertex (toV3 color)
in
[ (p a, p b, p c), (p c, p d, p a) ]
cube : [Triangle Vertex]
cube =
let rft = vec3 1 1 1 -- right, front, top
lft = vec3 -1 1 1 -- left, front, top
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
concat [ face green rft rfb rbb rbt -- right
, face blue rft rfb lfb lft -- front
, face yellow rft lft lbt rbt -- top
, face red rfb lfb lbb rbb -- bottom
, face purple lft lfb lbb lbt -- left
, face orange rbt rbb lbb lbt -- back
]
-- Create the scene
position : Signal Int
position = keepWhen Mouse.isDown 0 Mouse.x
main : Signal Element
main = webgl (400,400) <~ lift scene (angle (toFloat <~ position))
angle : Signal Float -> Signal Float
angle m = foldp (\dt theta -> theta + dt / 5000) 0 m
scene : Float -> [Entity]
scene angle =
[ entity vertexShader fragmentShader cube (uniforms angle) ]
uniforms : Float -> { rotation:Mat4, perspective:Mat4, camera:Mat4, shade:Float }
uniforms t =
{ rotation = mul (makeRotate (3*t) (vec3 0 1 0)) (makeRotate (2*t) (vec3 1 0 0))
, perspective = makePerspective 45 1 0.01 100
, camera = makeLookAt (vec3 0 0 5) (vec3 0 0 0) (vec3 0 1 0)
, shade = 0.8
}
-- Shaders
vertexShader : Shader { attr | position:Vec3, color:Vec3 }
{ unif | rotation:Mat4, perspective:Mat4, camera:Mat4 }
{ 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 {} { u | shade:Float } { vcolor:Vec3 }
fragmentShader = [glsl|
precision mediump float;
uniform float shade;
varying vec3 vcolor;
void main () {
gl_FragColor = shade * vec4(vcolor, 1.0);
}
|]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment