on master help sign in
webgl textures!
b01cf1dJohn P Mayer Jr
compiler/Parse/Helpers.hs+2
@@ -355,9 +355,11 @@ glSource src =
355 then case tipe of
355 then case tipe of
356 GLS.Int -> return (qual,Literal.Int,name)
356 GLS.Int -> return (qual,Literal.Int,name)
357 GLS.Float -> return (qual,Literal.Float,name)
357 GLS.Float -> return (qual,Literal.Float,name)
358+ GLS.Vec2 -> return (qual,V2,name)
358 GLS.Vec3 -> return (qual,V3,name)
359 GLS.Vec3 -> return (qual,V3,name)
359 GLS.Vec4 -> return (qual,V4,name)
360 GLS.Vec4 -> return (qual,V4,name)
360 GLS.Mat4 -> return (qual,M4,name)
361 GLS.Mat4 -> return (qual,M4,name)
362+ GLS.Sampler2D -> return (qual,Texture,name)
361 _ -> []
363 _ -> []
362 else []
364 else []
363 _ -> []
365 _ -> []
compiler/SourceSyntax/Literal.hs+2−1
@@ -21,12 +21,13 @@ instance Pretty Literal where
21 Str s -> PP.text . show $ s
21 Str s -> PP.text . show $ s
22 Boolean bool -> PP.text (show bool)
22 Boolean bool -> PP.text (show bool)
23
23
24−data GLTipe = Int | Float | V3 | V4 | M4 | Texture
24+data GLTipe = Int | Float | V2 | V3 | V4 | M4 | Texture
25 deriving (Show)
25 deriving (Show)
26
26
27glTipeName :: GLTipe -> String
27glTipeName :: GLTipe -> String
28glTipeName Int = "Int"
28glTipeName Int = "Int"
29glTipeName Float = "Float"
29glTipeName Float = "Float"
30+glTipeName V2 = "MJS.V2"
30glTipeName V3 = "MJS.V3"
31glTipeName V3 = "MJS.V3"
31glTipeName V4 = "MJS.V4"
32glTipeName V4 = "MJS.V4"
32glTipeName M4 = "MJS.M4x4"
33glTipeName M4 = "MJS.M4x4"
compiler/Type/Constrain/Expression.hs+5−2
@@ -9,7 +9,6 @@ import qualified Data.Map as Map
9import qualified Text.PrettyPrint as PP
9import qualified Text.PrettyPrint as PP
10
10
11import SourceSyntax.Literal as Lit
11import SourceSyntax.Literal as Lit
12−import SourceSyntax.Pattern (Pattern, boundVars)
13import SourceSyntax.Annotation as Ann
12import SourceSyntax.Annotation as Ann
14import SourceSyntax.Expression
13import SourceSyntax.Expression
15import qualified SourceSyntax.Pattern as P
14import qualified SourceSyntax.Pattern as P
@@ -39,7 +38,11 @@ constrain env (A region expr) tipe =
39 let
38 let
40 shaderTipe a u v = Env.get env Env.types "Graphics.WebGL.Shader" <| a <| u <| v
39 shaderTipe a u v = Env.get env Env.types "Graphics.WebGL.Shader" <| a <| u <| v
41 glTipe = Env.get env Env.types . Lit.glTipeName
40 glTipe = Env.get env Env.types . Lit.glTipeName
41+ makeRec accessor baseRec =
42+ let decls = accessor gltipe
43+ in if Map.size decls == 0
44+ then baseRec
42− makeRec accessor baseRec = record (Map.map (\t -> [glTipe t]) $ accessor gltipe) baseRec
45+ else record (Map.map (\t -> [glTipe t]) decls) baseRec
43 attribute = makeRec Lit.attribute attr
46 attribute = makeRec Lit.attribute attr
44 uniform = makeRec Lit.uniform unif
47 uniform = makeRec Lit.uniform unif
45 varying = makeRec Lit.varying (TermN EmptyRecord1)
48 varying = makeRec Lit.varying (TermN EmptyRecord1)
libraries/Graphics/WebGL.elm+8−1
@@ -1,10 +1,12 @@
1
1
2−module Graphics.WebGL (mapTriangle, zipTriangle, model, webgl) where
2+module Graphics.WebGL (mapTriangle, zipTriangle, loadTex, model, webgl) where
3
3
4{-| WebGL -}
4{-| WebGL -}
5
5
6import Graphics.Element (Element)
6import Graphics.Element (Element)
7+import Http (Response)
7import Native.Graphics.WebGL
8import Native.Graphics.WebGL
9+import Signal (Signal)
8
10
9type Triangle a = (a,a,a)
11type Triangle a = (a,a,a)
10
12
@@ -16,6 +18,11 @@ zipTriangle f (x,y,z) (x',y',z') = (f x x', f y y', f z z')
16
18
17data Shader attr unif vary = Shader
19data Shader attr unif vary = Shader
18
20
21+data Texture = Texture
22+
23+loadTex : String -> Signal (Response Texture)
24+loadTex = Native.Graphics.WebGL.loadTex
25+
19data Model = Model
26data Model = Model
20
27
21model : Shader attr unif vary -> Shader {} unif vary -> [Triangle attr] -> unif -> Model
28model : Shader attr unif vary -> Shader {} unif vary -> [Triangle attr] -> unif -> Model
libraries/MJS.elm+3−1
@@ -12,7 +12,9 @@ Both vectors and matrices are immutable.
12
12
13import Native.MJS
13import Native.MJS
14
14
15−data V3 = Dummy_V3
15+data V2 = V2
16+data V3 = V3
17+data V4 = V4
16
18
17v3 : Float -> Float -> Float -> V3
19v3 : Float -> Float -> Float -> V3
18v3 = Native.MJS.v3
20v3 = Native.MJS.v3
libraries/Native/Graphics/WebGL.js+60−4
@@ -9,13 +9,35 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
9 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
9 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
10
10
11 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
11 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12−
13− var Signal = Elm.Signal.make(elm);
14 var newElement = Elm.Graphics.Element.make(elm).newElement;
12 var newElement = Elm.Graphics.Element.make(elm).newElement;
13+
14+ var List = Elm.Native.List.make(elm);
15+ var MJS = Elm.Native.MJS.make(elm);
15 var Utils = Elm.Native.Utils.make(elm);
16 var Utils = Elm.Native.Utils.make(elm);
17+ var Signal = Elm.Signal.make(elm);
16 var Tuple2 = Utils.Tuple2;
18 var Tuple2 = Utils.Tuple2;
17− var MJS = Elm.Native.MJS.make(elm);
19+
18− var List = Elm.Native.List.make(elm);
20+ function loadTex(source) {
21+
22+ var response = Signal.constant(elm.Http.values.Waiting);
23+
24+ var img = new Image();
25+
26+ img.onload = function() {
27+ var success = elm.Http.values.Success({img:img});
28+ elm.notify(response.id, success);
29+ }
30+
31+ img.onerror = function(e) {
32+ var failure = A2(elm.Http.values.Failure,0,"Failed");
33+ elm.notify(response.id, failure);
34+ }
35+
36+ img.src = source;
37+
38+ return response;
39+
40+ }
19
41
20 function model(vert, frag, buffer, uniforms) {
42 function model(vert, frag, buffer, uniforms) {
21
43
@@ -28,6 +50,21 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
28
50
29 }
51 }
30
52
53+ function do_texture (gl, img) {
54+
55+ var tex = gl.createTexture();
56+ console.log("Created texture");
57+ gl.bindTexture(gl.TEXTURE_2D, tex);
58+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
59+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
60+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
61+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
62+ gl.generateMipmap(gl.TEXTURE_2D);
63+ //gl.bindTexture(gl.TEXTURE0, null);
64+ return tex;
65+
66+ }
67+
31 function do_compile (gl, src, tipe) {
68 function do_compile (gl, src, tipe) {
32
69
33 var shader = gl.createShader(tipe);
70 var shader = gl.createShader(tipe);
@@ -171,6 +208,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
171 gl.useProgram(program);
208 gl.useProgram(program);
172
209
173 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
210 var numUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
211+ var textureCounter = 0;
174 for (var i = 0; i < numUniforms; i += 1) {
212 for (var i = 0; i < numUniforms; i += 1) {
175 var uniform = gl.getActiveUniform(program, i);
213 var uniform = gl.getActiveUniform(program, i);
176 var uniformLocation = gl.getUniformLocation(program, uniform.name);
214 var uniformLocation = gl.getUniformLocation(program, uniform.name);
@@ -187,6 +225,23 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
187 case gl.FLOAT_MAT4:
225 case gl.FLOAT_MAT4:
188 gl.uniformMatrix4fv(uniformLocation, false, m.uniforms[uniform.name]);
226 gl.uniformMatrix4fv(uniformLocation, false, m.uniforms[uniform.name]);
189 break;
227 break;
228+ case gl.SAMPLER_2D:
229+ var texture = m.uniforms[uniform.name];
230+ var tex = undefined;
231+ if (texture.id) {
232+ tex = model.cache.textures[texture.id];
233+ } else {
234+ texture.id = Utils.guid();
235+ }
236+ if (!tex) {
237+ tex = do_texture(gl, texture.img);
238+ }
239+ var activeName = 'TEXTURE' + textureCounter;
240+ gl.activeTexture(gl[activeName]);
241+ gl.bindTexture(gl.TEXTURE_2D,tex);
242+ gl.uniform1i(uniformLocation, textureCounter);
243+ textureCounter += 1;
244+ break;
190 default:
245 default:
191 console.log("Unsupported uniform type: " + uniform.type);
246 console.log("Unsupported uniform type: " + uniform.type);
192 break;
247 break;
@@ -296,6 +351,7 @@ Elm.Native.Graphics.WebGL.make = function(elm) {
296 }
351 }
297
352
298 return elm.Native.Graphics.WebGL.values = {
353 return elm.Native.Graphics.WebGL.values = {
354+ loadTex:loadTex,
299 model:F4(model),
355 model:F4(model),
300 webgl:F2(webgl)
356 webgl:F2(webgl)
301 };
357 };
tests/test-files/good/Crate.elmnew file+48
@@ -0,0 +1,48 @@
1+
2+module Crate where
3+
4+import Http (..)
5+import MJS (..)
6+import Graphics.WebGL (..)
7+
8+pul = v3 -1 1 0
9+pur = v3 1 1 0
10+pbl = v3 -1 -1 0
11+pbr = v3 1 -1 0
12+
13+mesh : [Triangle { pos : V3 }]
14+mesh = map (mapTriangle (\pos -> {pos=pos})) <|
15+ [(pul,pur,pbl),(pbl,pur,pbr)]
16+
17+vert : Shader { pos : V3 } u { coord : V2 }
18+vert = [glShader|
19+attribute vec3 pos;
20+varying vec2 coord;
21+void main () {
22+ gl_Position = vec4(pos, 1.0);
23+ coord = pos.xy;
24+}
25+|]
26+
27+frag : Shader {} { u | crate : Texture } { coord : V2 }
28+frag = [glShader|
29+precision mediump float;
30+uniform sampler2D crate;
31+varying vec2 coord;
32+void main () {
33+ gl_FragColor = texture2D(crate, coord);
34+}
35+|]
36+
37+crateTex : Signal (Response Texture)
38+crateTex = loadTex "woodCrate.JPG"
39+
40+content : Response Texture -> [Model]
41+content response = case response of
42+ Waiting -> []
43+ Failure i s -> []
44+ Success tex -> [model vert frag mesh { crate = tex }]
45+
46+main = webgl (400,400) <~ (content <~ crateTex)
47+
48+
tests/test-files/good/woodCrate.JPGnew file

Binary file not shown.