on aacd30a help sign in
193 lines 6.0 kB history raw
1Elm.Native.Graphics.WebGL = {};
2Elm.Native.Graphics.WebGL.make = function(elm) {
4 elm.Native = elm.Native || {};
5 elm.Native.Graphics = elm.Native.Graphics || {};
6 elm.Native.Graphics.WebGL = elm.Native.Graphics.WebGL || {};
7 if (elm.Native.Graphics.WebGL.values) return elm.Native.Graphics.WebGL.values;
9 //var Render = ElmRuntime.use(ElmRuntime.Render.Element);
10 var newNode = ElmRuntime.use(ElmRuntime.Render.Utils).newElement;
12 var Signal = Elm.Signal.make(elm);
13 var newElement = Elm.Graphics.Element.make(elm).newElement;
14 //var JS = Elm.Native.JavaScript.make(elm);
15 var Utils = Elm.Native.Utils.make(elm);
16 var Tuple2 = Utils.Tuple2;
17 var MJS = Elm.Native.MJS.make(elm);
19 function createShader(gl, str, type) {
20 var shader = gl.createShader(type);
21 gl.shaderSource(shader, str);
22 gl.compileShader(shader);
24 if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
25 throw gl.getShaderInfoLog(shader);
26 }
28 return shader;
29 };
31 function linkProgram(gl, program) {
32 var vshader = createShader(gl, program.vshaderSource, gl.VERTEX_SHADER);
33 var fshader = createShader(gl, program.fshaderSource, gl.FRAGMENT_SHADER);
34 gl.attachShader(program, vshader);
35 gl.attachShader(program, fshader);
36 gl.linkProgram(program);
37 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
38 throw gl.getProgramInfoLog(program);
39 }
40 }
42 function createProgram(gl, vstr, fstr) {
43 var program = gl.createProgram();
44 var vshader = createShader(gl, vstr, gl.VERTEX_SHADER);
45 var fshader = createShader(gl, fstr, gl.FRAGMENT_SHADER);
46 gl.attachShader(program, vshader);
47 gl.attachShader(program, fshader);
48 gl.linkProgram(program);
50 if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
51 throw gl.getProgramInfoLog(program);
52 }
54 return program;
55 };
57 var geoVert = "attribute vec3 aVertexPosition;\
58 attribute vec4 aVertexColor;\
59 \
60 uniform mat4 uMMatrix;\
61 uniform mat4 uPMatrix;\
62 uniform mat4 uVMatrix;\
63 \
64 varying vec4 vVertexColor;\
65 \
66 void main() {\
67 gl_Position = uPMatrix * uVMatrix * uMMatrix * vec4(aVertexPosition, 1.0);\
68 vVertexColor = aVertexColor;\
69 }"
71 var geoFrag = "precision mediump float;\
72 \
73 varying vec4 vVertexColor;\
74 \
75 void main() {\
76 gl_FragColor = vVertexColor;\
77 }"
79 function drawGL(model) {
80 var aspect = model.aspect;
82 var projectionMatrix = MJS.M4x4.makePerspective(45, aspect, 0.01, 100);
84 var eye = MJS.V3.$(0,0,1);
85 var center = MJS.V3.$(0,0,0);
86 var up = MJS.V3.$(0,1,0);
88 var viewMatrix = MJS.M4x4.makeLookAt(eye,center,up);
90 var modelMatrixStack = [MJS.M4x4.identity];
92 var gl = model.gl;
93 gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
95 var scene = model.scene;
96 console.log(scene);
98 }
100 /*
101 * Called for new node, caches lots of stuff
102 */
103 function render(model) {
104 drawGL(model);
105 return model.node;
106 }
108 /*
109 * Called at existing node
110 */
111 function update(canvasNode, oldModel, newModel) {
112 drawGL(newModel)
113 }
115 function glContext(w,h) {
116 var node = newNode('canvas');
117 var gl = node.getContext('webgl');
118 var program = createProgram(gl, geoVert, geoFrag);
119 return Signal.constant({w:w,h:h,gl:gl,node:node,program:program});
120 }
122 function makeMesh(triangles, context) {
123 var indices = [];
124 var positions = [];
125 var colors = [];
127 function pushTriangle(n, node) {
128 if (node.ctor === "[]") return;
129 var tri = node._0;
130 var names = ['a','b','c'];
131 for (var i = 0; i < 3; i+= 1) {
132 indices.push(3 * n + i);
133 var vertex = tri[names[i]];
134 for (var j = 0; j < 3; j += 1) {
135 positions.push(vertex.pos[j]);
136 }
137 colors.push(vertex.color._0);
138 colors.push(vertex.color._1);
139 colors.push(vertex.color._2);
140 colors.push(vertex.color._3);
141 }
142 pushTriangle(n+1,node._1);
143 }
145 pushTriangle(0,triangles);
147 var gl = context.gl;
149 var indexBuffer = gl.createBuffer();
150 gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
151 gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
153 var vertexPosBuffer = gl.createBuffer();
154 gl.bindBuffer(gl.ARRAY_BUFFER, vertexPosBuffer);
155 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW);
157 var vertexColors = gl.createBuffer();
158 gl.bindBuffer(gl.ARRAY_BUFFER, vertexColors);
159 gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
161 return {
162 indexBuffer:indexBuffer,
163 vertexPosBuffer: vertexPosBuffer,
164 vertexColors: vertexColors
165 };
167 }
169 function renderGL(context, scene) {
171 return A3(newElement, context.w, context.h, {
172 ctor: 'Custom',
173 type: 'WebGL',
174 render: render,
175 update: update,
176 model: {
177 aspect: context.w/context.h,
178 node: context.node,
179 gl: context.gl,
180 program: context.program,
181 scene: scene,
182 },
183 });
185 }
187 return elm.Native.Graphics.WebGL.values = {
188 glContext:F2(glContext),
189 makeMesh:F2(makeMesh),
190 renderGL:F2(renderGL),
191 };
193};