Skip to content

Instantly share code, notes, and snippets.

@evancz
Created May 15, 2014 02:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save evancz/b4eaa03e75295c610a35 to your computer and use it in GitHub Desktop.
Save evancz/b4eaa03e75295c610a35 to your computer and use it in GitHub Desktop.
A triangle that rotates, but done in a slow way. Ideally you send a transformation matrix to the GPU rather than a whole new entity!
import Math.Vector3 (..)
import Math.Matrix4 (..)
import Graphics.WebGL (..)
-- This is the main function
-- It renders the triangle then prints the points
-- of the triangle
-- Notice how the points change but the render doesn't
main = flow down <~ ( combine [ render <~ updateTriangle
, print <~ updateTriangle] )
type ColorPoint = { color : Vec3 , point : Vec3 }
type Polygon = [Triangle ColorPoint]
colorToV3 : Color -> Vec3
colorToV3 color =
let c = toRgb color
in v3 (toFloat c.red / 255)
(toFloat c.green / 255)
(toFloat c.blue / 255)
triangle : Color -> Vec3 -> Vec3 -> Vec3 -> Polygon
triangle color p1 p2 p3 =
let c = colorToV3 color
in [ (ColorPoint c p1 , ColorPoint c p2 , ColorPoint c p3) ]
-- Function to rotate a polygon about an axis
-- The inner function do the following
-- rotM creates the rotation matrix
-- rotPt rotates a single point using the rotation matrix
-- rotTr rotates a triangle of points
-- Therefore the function just does rotTr on all triangles
-- of the polygon
rotateAxis : Vec3 -> Float -> Polygon -> Polygon
rotateAxis axis angle polygon =
let rotM = makeRotate angle axis
rotPt cp = ColorPoint (cp.color) (rotM `transform` cp.point)
rotTr (cp1 , cp2 , cp3) = (rotPt cp1 , rotPt cp2 , rotPt cp3)
in map rotTr polygon
rotateX = rotateAxis (v3 1 0 0)
rotateY = rotateAxis (v3 0 1 0)
rotateZ = rotateAxis (v3 0 0 1)
defaultTriangle : Polygon
defaultTriangle = triangle blue (v3 1 0 0) (v3 0 1 0) (v3 -1 0 0)
scene : Polygon -> [Entity]
scene tris = [ entity vShader fShader tris {} ]
-- renders a polygon on the screen
render : Polygon -> Element
render = webgl (400,400) . scene
-- prints a polygon on the screen
print : Polygon -> Element
print polygon =
let printPoint pt = { point = toTuple pt.point }
printTriangle (p1 , p2 , p3) =
( printPoint p1 , printPoint p2 , printPoint p3 )
in asText (map printTriangle polygon)
getInput : Signal Float
getInput = flip (/) 100000 <~ foldp (+) 0 (fps 16)
updateTriangle : Signal Polygon
updateTriangle = foldp rotateZ defaultTriangle getInput
-------------------------------------------------------------------
vShader = [glShader|
attribute vec3 point;
attribute vec3 color;
varying vec3 vColor;
void main(){
gl_Position = vec4(point, 1.0);
vColor = color;
}
|]
fShader = [glShader|
precision mediump float;
varying vec3 vColor;
void main(){
gl_FragColor = vec4(vColor, 1.0);
}
|]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment