Skip to content

Commit

Permalink
basic picking example without offscreen rendering
Browse files Browse the repository at this point in the history
  • Loading branch information
felixguendling committed Jun 26, 2016
1 parent 0b72efc commit 5dd1040
Show file tree
Hide file tree
Showing 5 changed files with 333 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
elm-stuff
index.html
.DS_Store
.vscode
17 changes: 17 additions & 0 deletions examples/Port.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
port module Port exposing (..)


type alias MouseUpdate =
{ x : Float
, y : Float
, color : Float
}


port mouseMove : (MouseUpdate -> msg) -> Sub msg


port mouseDown : (MouseUpdate -> msg) -> Sub msg


port mouseUp : (MouseUpdate -> msg) -> Sub msg
51 changes: 51 additions & 0 deletions examples/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<!doctype html>
<html>
<head>
<title>Test</title>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<style>
html, body {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<script type="text/javascript" src="elm.js"></script>
<script type="text/javascript">
var app = Elm.Main.fullscreen();

var ports =
{ 'mousedown': app.ports.mouseDown
, 'mouseup': app.ports.mouseUp
, 'mouseout': app.ports.mouseUp
, 'mousemove': app.ports.mouseMove };

document.addEventListener('elmgl-init', function(e) {
var canvas = e.detail.canvas;
var gl = e.detail.gl;

var sendTelemetry = function(eventType) {
return function(e) {
var pixels = new Uint8Array(1 * 1 * 4);
gl.readPixels(e.clientX, gl.drawingBufferHeight - e.clientY, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
ports[eventType].send(
{ x: e.clientX
, y: e.clientY
, color: pixels[0]
});
};
};

var register = function(eventType) {
canvas.addEventListener(eventType, sendTelemetry(eventType));
};

for (var port in ports) {
register(port);
}
});
</script>
</body>
</html>
260 changes: 260 additions & 0 deletions examples/picking.elm
Original file line number Diff line number Diff line change
@@ -0,0 +1,260 @@
module Main exposing (..)

import Html exposing (..)
import Html.App
import Html.Attributes exposing (..)
import Math.Vector3 exposing (Vec3, vec3)
import Math.Matrix4 exposing (Mat4, makeOrtho2D, translate)
import Json.Decode
import Port
import WebGL
import Array


w =
500


h =
500



-- MAIN


main : Program Never
main =
Html.App.program
{ init = init
, view = view
, subscriptions =
\_ ->
Sub.batch
[ Port.mouseMove MouseMove
, Port.mouseDown MouseDown
, Port.mouseUp MouseUp
]
, update = update
}



-- INIT


generateBox : Int -> Box
generateBox i =
{ pos =
{ x = toFloat (i % 15) * 24
, y = toFloat (floor (toFloat i / 15) * 24)
}
, color = toFloat i + 1
, drag = Nothing
}


generateBoxes : List Box
generateBoxes =
Array.initialize 225 identity
|> Array.toList
|> List.map generateBox


init : ( Model, Cmd Msg )
init =
( { boxes = generateBoxes
, hover = False
}
, Cmd.none
)



-- MESH


type alias Vertex =
{ coordinate : Vec3
, color : Vec3
}


box : Float -> Float -> Float -> Float -> List ( Vertex, Vertex, Vertex )
box size x y color =
[ ( Vertex (vec3 (x + size) y 0) (vec3 (color / 255) 0 0)
, Vertex (vec3 x y 0) (vec3 (color / 255) 0 0)
, Vertex (vec3 x (y + size) 0) (vec3 (color / 255) 0 0)
)
, ( Vertex (vec3 x (y + size) 0) (vec3 (color / 255) 0 0)
, Vertex (vec3 (x + size) y 0) (vec3 (color / 255) 0 0)
, Vertex (vec3 (x + size) (y + size) 0) (vec3 (color / 255) 0 0)
)
]


getPosition : Box -> Position
getPosition { pos, drag } =
case drag of
Nothing ->
pos

Just { start, current } ->
Position (pos.x + current.x - start.x)
(pos.y + current.y - start.y)


render : Box -> List ( Vertex, Vertex, Vertex )
render b =
let
p =
getPosition b
in
box 20 p.x p.y b.color


mesh : Model -> WebGL.Drawable Vertex
mesh model =
List.map render model.boxes
|> List.concat
|> WebGL.Triangle



-- MODEL


type alias Model =
{ boxes : List Box
, hover : Bool
}


type alias Box =
{ pos : Position
, color : Float
, drag : Maybe Drag
}


type alias Position =
{ x : Float
, y : Float
}


type alias Drag =
{ start : Position
, current : Position
}



-- UPDATE


type Msg
= MouseMove Port.MouseUpdate
| MouseDown Port.MouseUpdate
| MouseUp Port.MouseUpdate


update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
( updateModel msg model, Cmd.none )


updateModel : Msg -> Model -> Model
updateModel msg model =
case msg of
MouseMove s ->
{ model
| hover = s.color /= 0
, boxes = List.map (updateBox s) model.boxes
}

MouseDown s ->
{ model
| boxes =
List.map
(\b ->
if b.color == s.color then
let
pos =
{ x = s.x, y = s.y }
in
{ b | drag = Just { start = pos, current = pos } }
else
b
)
model.boxes
}

MouseUp s ->
{ model | boxes = List.map (finishDrag s) model.boxes }


updateDrag : Port.MouseUpdate -> Drag -> Drag
updateDrag s drag =
{ drag | current = { x = s.x, y = s.y } }


updateBox : Port.MouseUpdate -> Box -> Box
updateBox s box =
{ box | drag = Maybe.map (updateDrag s) box.drag }


finishDrag : Port.MouseUpdate -> Box -> Box
finishDrag s box =
{ box | pos = getPosition box, drag = Nothing }



-- VIEW


view : Model -> Html Msg
view model =
WebGL.toHtml
[ width w
, height h
, style
[ ( "cursor"
, if model.hover then
"pointer"
else
"default"
)
]
]
[ WebGL.render vertexShader
fragmentShader
(mesh model)
{ perspective = makeOrtho2D 0.0 w h 0.0 }
]


vertexShader : WebGL.Shader { attr | coordinate : Vec3, color : Vec3 } { unif | perspective : Mat4 } { vcolor : Vec3 }
vertexShader =
[glsl|
attribute vec3 coordinate;
attribute vec3 color;
uniform mat4 perspective;
varying vec3 vcolor;
void main() {
gl_Position = perspective * vec4(coordinate, 1.0);
vcolor = color;
}
|]


fragmentShader : WebGL.Shader {} u { vcolor : Vec3 }
fragmentShader =
[glsl|
precision mediump float;
varying vec3 vcolor;
void main () {
gl_FragColor = vec4(vcolor, 1);
}
|]
5 changes: 4 additions & 1 deletion src/Native/WebGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,8 +505,11 @@ var _elm_community$elm_webgl$Native_WebGL = function() {
function renderCanvas(model) {

LOG("Render canvas");
var opt = { preserveDrawingBuffer: true };
var canvas = document.createElement('canvas');
var gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
var gl = canvas.getContext('webgl', opt) || canvas.getContext('experimental-webgl', opt);

document.dispatchEvent(new CustomEvent('elmgl-init', {detail: { canvas, gl }}));

if (gl) {
A2(List.map, function(functionCall){
Expand Down

0 comments on commit 5dd1040

Please sign in to comment.