├── .gitignore ├── LICENSE ├── README.md ├── docs ├── examples │ ├── ex1.html │ ├── ex1.js │ ├── ex2.html │ ├── ex2.js │ ├── ex3.html │ ├── ex3.js │ ├── ex4.html │ └── ex4.js ├── index.html ├── webgl.html └── webgl │ ├── consts.html │ └── enums.html ├── examples ├── ex1.nim ├── ex2.nim ├── ex3.nim └── ex4.nim ├── oldwrapper ├── webgl.nim └── webglconsts.nim ├── src ├── webgl.nim └── webgl │ ├── consts.nim │ └── enums.nim ├── templates ├── templ_entry.html ├── templ_index.html └── templ_li.html └── webgl.nimble /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | nimcache/ 3 | examples/nimcache 4 | examples/*.js 5 | examples/*.html -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Silvio 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WebGL in Nim 2 | ========= 3 | Experimental wrapper to webgl for Nim (JS backend). 4 | Mostly taken from [mozilla webgl api](https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API) 5 | 6 | __NOTE: it is still incomplete and there are probably bugs__ 7 | 8 | A couple of examples are provided in `/examples` 9 | They are mostly translations of js code taken from mozilla tutorials and [webgl-lessons](https://github.com/tparisi/webgl-lessons), so 10 | don't expect idiomatic nim code. I'll work on improving them ( PRs welcome! ). 11 | 12 | Documentation 13 | ------------- 14 | Some examples and autogenerated docs are avaliable in `/docs` and online at 15 | [my site](http://stisa.space/webgl/) 16 | 17 | To build the docs and examples, `clone` this repo and then run: 18 | ``` 19 | nimble builddocs 20 | ``` 21 | The docs are then available in `/docs` 22 | 23 | Compiling to JS 24 | --------------- 25 | 26 | ``` 27 | nim js [-o:] 28 | ``` 29 | 30 | Note that the part between `[]` is optional, but it's useful as otherwise the `.js` file built by `nim` 31 | would be in `nimcache`. 32 | 33 | TODO 34 | ---- 35 | 36 | - move consts to enums? 37 | - move function out of the `WebglRenderingContext` object, to have autodocs? 38 | - Some utilites: others? ~~setting up a context~~, ~~reading errors~~, ~~emitting to console~~ 39 | - Have a module for `Webgl2` 40 | - Show the code side-by-side with the examples 41 | 42 | 43 | -------------------------------------------------------------------------------- /docs/examples/ex1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Example: ex1 18 | 23 | 24 | 34 | 35 | 36 | 49 |
50 |
51 | 52 |

Example: ex1

53 | 54 | Your browser doesn't appear to support the 55 | <canvas> element. 56 | 57 | 58 |
59 |
60 |

Code

61 |
import dom, ../src/webgl
 62 | 
 63 | var vertexPositionAttribute : uint 
 64 | 
 65 | proc getShader(gl:WebGLRenderingContext, id:string, kind:char):WebGLShader =
 66 |     var shaderScript = dom.document.getElementById(id)
 67 |     if (shaderScript==nil): return
 68 |     var theSource : string = ""
 69 |     var currentChild = shaderScript.firstChild
 70 |     while(currentChild!=nil):
 71 |         if (currentChild.nodeType == dom.TextNode):
 72 |             theSource &= currentChild.nodeValue
 73 |         currentChild = currentChild.nextSibling
 74 |     
 75 |     if(kind == 'f'): result = gl.createShader(seFRAGMENT_SHADER)
 76 |     elif(kind == 'v'): result = gl.createShader(seVERTEX_SHADER)
 77 |     else: return #unknown shader type
 78 | 
 79 |     gl.shaderSource(result, theSource)
 80 | 
 81 |     # Compile shader
 82 |     gl.compileShader(result)
 83 | 
 84 |     # See if it compiled successfully
 85 |     {. emit: "if (!`gl`.getShaderParameter(`result`, `gl`.COMPILE_STATUS)) {alert('An error occurred compiling the shaders: ' + `gl`.getShaderInfoLog(`result`));return null;}; ".}  
 86 | 
 87 | var shaderProgram : WebGLProgram
 88 | proc initShaders(gl:WebGLRenderingContext) =
 89 |     var fragmentShader = getShader(gl, "shader-fs",'f')
 90 |     var vertexShader = getShader(gl, "shader-vs",'v');
 91 | 
 92 |     #Create shader programs
 93 |     shaderProgram = gl.createProgram()
 94 |     gl.attachShader(shaderProgram,vertexShader)
 95 |     gl.attachShader(shaderProgram,fragmentShader)
 96 |     gl.linkProgram(shaderProgram)
 97 | 
 98 |     # If creating the shader program failed, alert
 99 |     # I'm lazy so I'll just emit this directly
100 |     #  {.emit : "if (!`gl`.getProgramParameter(`shaderProgram`, `gl`.LINK_STATUS)) { alert('Unable to initialize the shader program: ' + `gl`.getProgramInfoLog(`shader`)); };" .}
101 | 
102 |     gl.useProgram(shaderProgram)
103 | 
104 |     
105 |     vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
106 |     gl.enableVertexAttribArray(vertexPositionAttribute);
107 | 
108 | var squareVerticesBuffer : WebGLBuffer
109 | 
110 | proc initBuffers(gl:WebGLRenderingContext) =
111 |     squareVerticesBuffer = gl.createBuffer()
112 | 
113 |     gl.bindBuffer(beARRAY_BUFFER, squareVerticesBuffer)
114 | 
115 |     var vertices :seq[float32]= @[
116 |         1.0'f32,  1.0,  0.0,
117 |         -1.0, 1.0,  0.0,
118 |         1.0,  -1.0, 0.0,
119 |         -1.0, -1.0, 0.0
120 |     ];
121 |     
122 |     gl.bufferData(beARRAY_BUFFER, vertices, beSTATIC_DRAW);
123 | 
124 | 
125 | proc setMatrixUniforms(gl:WebGLRenderingContext,pm, mv: seq[float]) =
126 |     var pUniform = gl.getUniformLocation(shaderProgram,"uPMatrix")
127 |     gl.uniformMatrix4fv(pUniform,false, pm)
128 | 
129 |     var mvUniform = gl.getUniformLocation(shaderProgram,"uMVMatrix")
130 |     gl.uniformMatrix4fv(mvUniform,false, mv)
131 | 
132 | proc drawScene(gl:WebGLRenderingContext) =
133 |     gl.clear(bbCOLOR.uint or bbDEPTH.uint);
134 |     
135 |     var perspectiveMatrix = newSeq[float](16)
136 |     perspective4(45, 640.0/480.0, 0.1, 100.0, perspectiveMatrix);
137 |     
138 | 
139 |     var mv = newSeq[float](16)
140 |     mv.identity4();
141 |     mv.traslate4([-0.0, 0.0, -6.0],mv);
142 |     
143 |     gl.bindBuffer(beARRAY_BUFFER, squareVerticesBuffer);
144 |     gl.vertexAttribPointer(vertexPositionAttribute, 3, dtFLOAT, false, 0, 0);
145 |     setMatrixUniforms(gl,perspectiveMatrix,mv);
146 |     gl.drawArrays(pmTRIANGLE_STRIP, 0, 4);
147 | 
148 | 
149 | dom.window.onload = proc (e: dom.Event) =
150 |     echo sizeof(int)
151 |     echo sizeof(uint)
152 |     echo sizeof(float)
153 |     var canvas = dom.document.getElementById("glcanvas").Canvas;
154 |     var gl = canvas.getContext("webgl")
155 |     if gl.isNil: gl = canvas.getContext("experimental-webgl")
156 | 
157 |     gl.clearColor(0.0, 0.0, 0.0, 1.0);  # Clear to black, fully opaque 
158 |     gl.clearDepth(1.0);                 # Clear everything 
159 |     
160 |     # Initialize the shaders; this is where all the lighting for the 
161 |     # vertices and so forth is established.  
162 | 
163 |     initShaders(gl); 
164 | 
165 |     # Here's where we call the routine that builds all the objects 
166 |     # we'll be drawing. 
167 |     initBuffers(gl); 
168 | 
169 |     # Set up to draw the scene periodically. 
170 |     #setInterval(drawScene, 15); 
171 |     drawScene(gl)
172 | 
173 | 
174 |
175 |
176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /docs/examples/ex1.js: -------------------------------------------------------------------------------- 1 | /* Generated by the Nim Compiler v0.16.1 */ 2 | /* (c) 2017 Andreas Rumpf */ 3 | 4 | var framePtr = null; 5 | var excHandler = 0; 6 | var lastJSError = null; 7 | if (typeof Int8Array === 'undefined') Int8Array = Array; 8 | if (typeof Int16Array === 'undefined') Int16Array = Array; 9 | if (typeof Int32Array === 'undefined') Int32Array = Array; 10 | if (typeof Uint8Array === 'undefined') Uint8Array = Array; 11 | if (typeof Uint16Array === 'undefined') Uint16Array = Array; 12 | if (typeof Uint32Array === 'undefined') Uint32Array = Array; 13 | if (typeof Float32Array === 'undefined') Float32Array = Array; 14 | if (typeof Float64Array === 'undefined') Float64Array = Array; 15 | var NTI126 = {size: 0,kind: 37,base: null,node: null,finalizer: null}; 16 | var NTI30099 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; 17 | var NTI3426 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 18 | var NTI3428 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 19 | var NTI3440 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 20 | var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; 21 | var NTI13009 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; 22 | var NTI3408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 23 | var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; 24 | var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; 25 | var NTI3487 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; 26 | var NTI3424 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 27 | var NTI3438 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 28 | var NTI3442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 29 | var NNI3442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 30 | NTI3442.node = NNI3442; 31 | var NNI3438 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 32 | NTI3438.node = NNI3438; 33 | NTI3487.base = NTI3424; 34 | var NNI3424 = {kind: 2, len: 4, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3487, name: "parent", sons: null}, 35 | {kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, 36 | {kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, 37 | {kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}]}; 38 | NTI3424.node = NNI3424; 39 | var NNI3408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 40 | NTI3408.node = NNI3408; 41 | NTI3424.base = NTI3408; 42 | NTI3438.base = NTI3424; 43 | NTI3442.base = NTI3438; 44 | var NNI13009 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, 45 | {kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; 46 | NTI13009.node = NNI13009; 47 | var NNI3440 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 48 | NTI3440.node = NNI3440; 49 | NTI3440.base = NTI3438; 50 | var NNI3428 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 51 | NTI3428.node = NNI3428; 52 | var NNI3426 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 53 | NTI3426.node = NNI3426; 54 | NTI3426.base = NTI3424; 55 | NTI3428.base = NTI3426; 56 | NTI30099.base = NTI126; 57 | function makeNimstrLit(c_14003) { 58 | 59 | var ln = c_14003.length; 60 | var result = new Array(ln + 1); 61 | var i = 0; 62 | for (; i < ln; ++i) { 63 | result[i] = c_14003.charCodeAt(i); 64 | } 65 | result[i] = 0; // terminating zero 66 | return result; 67 | } 68 | function SetConstr() { 69 | 70 | var result = {}; 71 | for (var i = 0; i < arguments.length; ++i) { 72 | var x = arguments[i]; 73 | if (typeof(x) == "object") { 74 | for (var j = x[0]; j <= x[1]; ++j) { 75 | result[j] = true; 76 | } 77 | } else { 78 | result[x] = true; 79 | } 80 | } 81 | return result; 82 | } 83 | function nimCopy(dest_19217, src_19218, ti_19219) { 84 | 85 | var result_19629 = null; 86 | switch (ti_19219.kind) { 87 | case 21: case 22: case 23: case 5: if (!(isFatPointer_19201(ti_19219))) { 88 | result_19629 = src_19218; 89 | } 90 | else { 91 | result_19629 = [src_19218[0], src_19218[1]];} 92 | 93 | 94 | break; 95 | case 19: if (dest_19217 === null || dest_19217 === undefined) { 96 | dest_19217 = {}; 97 | } 98 | else { 99 | for (var key in dest_19217) { delete dest_19217[key]; } 100 | } 101 | for (var key in src_19218) { dest_19217[key] = src_19218[key]; } 102 | result_19629 = dest_19217; 103 | 104 | break; 105 | case 18: case 17: if (!((ti_19219.base == null))) { 106 | result_19629 = nimCopy(dest_19217, src_19218, ti_19219.base); 107 | } 108 | else { 109 | if ((ti_19219.kind == 17)) { 110 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {m_type: ti_19219} : dest_19217;} 111 | else { 112 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {} : dest_19217;} 113 | } 114 | nimCopyAux(result_19629, src_19218, ti_19219.node); 115 | 116 | break; 117 | case 24: case 4: case 27: case 16: if (src_19218 === null) { 118 | result_19629 = null; 119 | } 120 | else { 121 | if (dest_19217 === null || dest_19217 === undefined) { 122 | dest_19217 = new Array(src_19218.length); 123 | } 124 | else { 125 | dest_19217.length = src_19218.length; 126 | } 127 | result_19629 = dest_19217; 128 | for (var i = 0; i < src_19218.length; ++i) { 129 | result_19629[i] = nimCopy(result_19629[i], src_19218[i], ti_19219.base); 130 | } 131 | } 132 | 133 | break; 134 | case 28: if (src_19218 !== null) { 135 | result_19629 = src_19218.slice(0); 136 | } 137 | 138 | break; 139 | default: 140 | result_19629 = src_19218; 141 | break; 142 | } 143 | return result_19629; 144 | } 145 | function eqStrings(a_16603, b_16604) { 146 | 147 | if (a_16603 == b_16604) return true; 148 | if ((!a_16603) || (!b_16604)) return false; 149 | var alen = a_16603.length; 150 | if (alen != b_16604.length) return false; 151 | for (var i = 0; i < alen; ++i) 152 | if (a_16603[i] != b_16604[i]) return false; 153 | return true; 154 | } 155 | function arrayConstr(len_19664, value_19665, typ_19666) { 156 | 157 | var result = new Array(len_19664); 158 | for (var i = 0; i < len_19664; ++i) result[i] = nimCopy(null, value_19665, typ_19666); 159 | return result; 160 | } 161 | function cstrToNimstr(c_14203) { 162 | 163 | var ln = c_14203.length; 164 | var result = new Array(ln); 165 | var r = 0; 166 | for (var i = 0; i < ln; ++i) { 167 | var ch = c_14203.charCodeAt(i); 168 | 169 | if (ch < 128) { 170 | result[r] = ch; 171 | } 172 | else if((ch > 127) && (ch < 2048)) { 173 | result[r] = (ch >> 6) | 192; 174 | ++r; 175 | result[r] = (ch & 63) | 128; 176 | } 177 | else { 178 | result[r] = (ch >> 12) | 224; 179 | ++r; 180 | result[r] = ((ch >> 6) & 63) | 128; 181 | ++r; 182 | result[r] = (ch & 63) | 128; 183 | } 184 | ++r; 185 | } 186 | result[r] = 0; // terminating zero 187 | return result; 188 | } 189 | function toJSStr(s_14403) { 190 | 191 | var len = s_14403.length-1; 192 | var asciiPart = new Array(len); 193 | var fcc = String.fromCharCode; 194 | var nonAsciiPart = null; 195 | var nonAsciiOffset = 0; 196 | for (var i = 0; i < len; ++i) { 197 | if (nonAsciiPart !== null) { 198 | var offset = (i - nonAsciiOffset) * 2; 199 | var code = s_14403[i].toString(16); 200 | if (code.length == 1) { 201 | code = "0"+code; 202 | } 203 | nonAsciiPart[offset] = "%"; 204 | nonAsciiPart[offset + 1] = code; 205 | } 206 | else if (s_14403[i] < 128) 207 | asciiPart[i] = fcc(s_14403[i]); 208 | else { 209 | asciiPart.length = i; 210 | nonAsciiOffset = i; 211 | nonAsciiPart = new Array((len - i) * 2); 212 | --i; 213 | } 214 | } 215 | asciiPart = asciiPart.join(""); 216 | return (nonAsciiPart === null) ? 217 | asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); 218 | } 219 | function raiseException(e_13406, ename_13407) { 220 | 221 | e_13406.name = ename_13407; 222 | if ((excHandler == 0)) { 223 | unhandledException(e_13406); 224 | } 225 | 226 | e_13406.trace = nimCopy(null, rawWriteStackTrace_13228(), NTI138); 227 | throw e_13406;} 228 | function rawEcho() { 229 | 230 | var node_16636 = null; 231 | node_16636 = document.getElementsByTagName('body')[0];if ((node_16636 === null)) { 232 | var e_16650 = null; 233 | e_16650 = {m_type: NTI3428, parent: null, name: null, message: null, trace: null}; 234 | e_16650.message = nimCopy(null, makeNimstrLit(" element does not exist yet!"), NTI138); 235 | e_16650.parent = null; 236 | raiseException(e_16650, "IOError"); 237 | } 238 | 239 | for (var i = 0; i < arguments.length; ++i) { 240 | var x = toJSStr(arguments[i]); 241 | node_16636.appendChild(document.createTextNode(x)); 242 | } 243 | node_16636.appendChild(document.createElement("br")); 244 | } 245 | var nimvm_5887 = false; 246 | var nim_program_result = 0; 247 | var globalRaiseHook_11005 = [null]; 248 | var localRaiseHook_11010 = [null]; 249 | var outOfMemHook_11013 = [null]; 250 | function isFatPointer_19201(ti_19203) { 251 | 252 | var result_19204 = false; 253 | BeforeRet: do { 254 | result_19204 = !((SetConstr(17, 16, 4, 18, 27, 19, 23, 22, 21)[ti_19203.base.kind] != undefined)); 255 | break BeforeRet; 256 | } while (false); 257 | return result_19204; 258 | } 259 | function nimCopyAux(dest_19222, src_19223, n_19225) { 260 | 261 | switch (n_19225.kind) { 262 | case 0: 263 | break; 264 | case 1: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 265 | 266 | break; 267 | case 2: L1: do { 268 | var i_19615 = 0; 269 | var colontmp__19617 = 0; 270 | colontmp__19617 = (n_19225.len - 1); 271 | var res_19620 = 0; 272 | L2: do { 273 | L3: while (true) { 274 | if (!(res_19620 <= colontmp__19617)) break L3; 275 | i_19615 = res_19620; 276 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i_19615]); 277 | res_19620 += 1; 278 | } 279 | } while(false); 280 | } while(false); 281 | 282 | break; 283 | case 3: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 284 | for (var i = 0; i < n_19225.sons.length; ++i) { 285 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i][1]); 286 | } 287 | 288 | break; 289 | } 290 | } 291 | function add_11029(x_11032, x_11032_Idx, y_11033) { 292 | 293 | var len = x_11032[0].length-1; 294 | for (var i = 0; i < y_11033.length; ++i) { 295 | x_11032[0][len] = y_11033.charCodeAt(i); 296 | ++len; 297 | } 298 | x_11032[0][len] = 0 299 | } 300 | function auxWriteStackTrace_13004(f_13006) { 301 | 302 | var Tmp3; 303 | var result_13007 = [null]; 304 | var it_13015 = f_13006; 305 | var i_13016 = 0; 306 | var total_13017 = 0; 307 | var tempFrames_13021 = arrayConstr(64, {Field0: null, Field1: 0}, NTI13009); 308 | L1: do { 309 | L2: while (true) { 310 | if (!!((it_13015 == null))) Tmp3 = false; else {Tmp3 = (i_13016 <= 63); }if (!Tmp3) break L2; 311 | tempFrames_13021[i_13016].Field0 = it_13015.procname; 312 | tempFrames_13021[i_13016].Field1 = it_13015.line; 313 | i_13016 += 1; 314 | total_13017 += 1; 315 | it_13015 = it_13015.prev; 316 | } 317 | } while(false); 318 | L4: do { 319 | L5: while (true) { 320 | if (!!((it_13015 == null))) break L5; 321 | total_13017 += 1; 322 | it_13015 = it_13015.prev; 323 | } 324 | } while(false); 325 | result_13007[0] = nimCopy(null, makeNimstrLit(""), NTI138); 326 | if (!((total_13017 == i_13016))) { 327 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("(")); } else { result_13007[0] = makeNimstrLit("(");}; 328 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr(((total_13017 - i_13016))+"")); } else { result_13007[0] = cstrToNimstr(((total_13017 - i_13016))+"");}; 329 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_13007[0] = makeNimstrLit(" calls omitted) ...\x0A");}; 330 | } 331 | 332 | L6: do { 333 | var j_13215 = 0; 334 | var colontmp__13221 = 0; 335 | colontmp__13221 = (i_13016 - 1); 336 | var res_13224 = colontmp__13221; 337 | L7: do { 338 | L8: while (true) { 339 | if (!(0 <= res_13224)) break L8; 340 | j_13215 = res_13224; 341 | add_11029(result_13007, 0, tempFrames_13021[j_13215].Field0); 342 | if ((0 < tempFrames_13021[j_13215].Field1)) { 343 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(", line: ")); } else { result_13007[0] = makeNimstrLit(", line: ");}; 344 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr((tempFrames_13021[j_13215].Field1)+"")); } else { result_13007[0] = cstrToNimstr((tempFrames_13021[j_13215].Field1)+"");}; 345 | } 346 | 347 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("\x0A")); } else { result_13007[0] = makeNimstrLit("\x0A");}; 348 | res_13224 -= 1; 349 | } 350 | } while(false); 351 | } while(false); 352 | return result_13007[0]; 353 | } 354 | function rawWriteStackTrace_13228() { 355 | 356 | var result_13230 = null; 357 | if (!((framePtr == null))) { 358 | result_13230 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A").slice(0,-1)).concat(auxWriteStackTrace_13004(framePtr)), NTI138); 359 | } 360 | else { 361 | result_13230 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); 362 | } 363 | 364 | return result_13230; 365 | } 366 | function unhandledException(e_13253) { 367 | 368 | var Tmp1; 369 | var buf_13254 = /**/[makeNimstrLit("")]; 370 | if (!!(eqStrings(e_13253.message, null))) Tmp1 = false; else {Tmp1 = !((e_13253.message[0] == 0)); }if (Tmp1) { 371 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception: ");}; 372 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(e_13253.message); } else { buf_13254[0] = e_13253.message;}; 373 | } 374 | else { 375 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception");}; 376 | } 377 | 378 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit(" [")); } else { buf_13254[0] = makeNimstrLit(" [");}; 379 | add_11029(buf_13254, 0, e_13253.name); 380 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("]\x0A")); } else { buf_13254[0] = makeNimstrLit("]\x0A");}; 381 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(rawWriteStackTrace_13228()); } else { buf_13254[0] = rawWriteStackTrace_13228();}; 382 | var cbuf_13401 = toJSStr(buf_13254[0]); 383 | framePtr = null; 384 | if (typeof(Error) !== "undefined") { 385 | throw new Error(cbuf_13401); 386 | } 387 | else { 388 | throw cbuf_13401; 389 | } 390 | } 391 | function raiseOverflow() { 392 | 393 | var e_13840 = null; 394 | e_13840 = {m_type: NTI3442, parent: null, name: null, message: null, trace: null}; 395 | e_13840.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI138); 396 | e_13840.parent = null; 397 | raiseException(e_13840, "OverflowError"); 398 | } 399 | function raiseDivByZero() { 400 | 401 | var e_13858 = null; 402 | e_13858 = {m_type: NTI3440, parent: null, name: null, message: null, trace: null}; 403 | e_13858.message = nimCopy(null, makeNimstrLit("division by zero"), NTI138); 404 | e_13858.parent = null; 405 | raiseException(e_13858, "DivByZeroError"); 406 | } 407 | var vertexPositionAttribute_30001 = [0]; 408 | var shaderProgram_30061 = [null]; 409 | var squareVerticesBuffer_30068 = [null]; 410 | function getShader_30003(gl_30005, id_30006, kind_30007) { 411 | 412 | var result_30008 = null; 413 | var F={procname:"ex1.getShader",prev:framePtr,filename:"ex1.nim",line:0}; 414 | framePtr = F; 415 | BeforeRet: do { 416 | F.line = 6; 417 | var shaderScript_30009 = document.getElementById(toJSStr(id_30006)); 418 | if ((shaderScript_30009 == null)) { 419 | F.line = 7; 420 | break BeforeRet; 421 | } 422 | 423 | F.line = 8; 424 | var theSource_30021 = /**/[makeNimstrLit("")]; 425 | F.line = 9; 426 | var currentChild_30022 = shaderScript_30009.firstChild; 427 | L1: do { 428 | F.line = 10; 429 | L2: while (true) { 430 | if (!!((currentChild_30022 == null))) break L2; 431 | if ((currentChild_30022.nodeType == 3)) { 432 | add_11029(theSource_30021, 0, currentChild_30022.nodeValue); 433 | } 434 | 435 | F.line = 13; 436 | currentChild_30022 = currentChild_30022.nextSibling; 437 | } 438 | } while(false); 439 | if ((kind_30007 == 102)) { 440 | F.line = 15; 441 | result_30008 = gl_30005.createShader(35632); 442 | } 443 | else { 444 | if ((kind_30007 == 118)) { 445 | F.line = 16; 446 | result_30008 = gl_30005.createShader(35633); 447 | } 448 | else { 449 | F.line = 17; 450 | break BeforeRet; 451 | } 452 | } 453 | gl_30005.shaderSource(result_30008, toJSStr(theSource_30021[0])); 454 | gl_30005.compileShader(result_30008); 455 | F.line = 25; 456 | if (!gl_30005.getShaderParameter(result_30008, gl_30005.COMPILE_STATUS)) {alert('An error occurred compiling the shaders: ' + gl_30005.getShaderInfoLog(result_30008));return null;}; } while (false); 457 | framePtr = F.prev; 458 | return result_30008; 459 | } 460 | function initShaders_30063(gl_30065) { 461 | 462 | var F={procname:"ex1.initShaders",prev:framePtr,filename:"ex1.nim",line:0}; 463 | framePtr = F; 464 | F.line = 29; 465 | var fragmentShader_30066 = getShader_30003(gl_30065, makeNimstrLit("shader-fs"), 102); 466 | F.line = 30; 467 | var vertexShader_30067 = getShader_30003(gl_30065, makeNimstrLit("shader-vs"), 118); 468 | F.line = 33; 469 | shaderProgram_30061[0] = gl_30065.createProgram(); 470 | gl_30065.attachShader(shaderProgram_30061[0], vertexShader_30067); 471 | gl_30065.attachShader(shaderProgram_30061[0], fragmentShader_30066); 472 | gl_30065.linkProgram(shaderProgram_30061[0]); 473 | gl_30065.useProgram(shaderProgram_30061[0]); 474 | F.line = 45; 475 | vertexPositionAttribute_30001[0] = gl_30065.getAttribLocation(shaderProgram_30061[0], "aVertexPosition"); 476 | gl_30065.enableVertexAttribArray(vertexPositionAttribute_30001[0]); 477 | framePtr = F.prev; 478 | } 479 | function initBuffers_30070(gl_30072) { 480 | 481 | var F={procname:"ex1.initBuffers",prev:framePtr,filename:"ex1.nim",line:0}; 482 | framePtr = F; 483 | F.line = 51; 484 | squareVerticesBuffer_30068[0] = gl_30072.createBuffer(); 485 | gl_30072.bindBuffer(34962, squareVerticesBuffer_30068[0]); 486 | F.line = 55; 487 | var vertices_30100 = nimCopy(null, [1.0000000000000000e+000, 1.0000000000000000e+000, 0.0, -1.0000000000000000e+000, 1.0000000000000000e+000, 0.0, 1.0000000000000000e+000, -1.0000000000000000e+000, 0.0, -1.0000000000000000e+000, -1.0000000000000000e+000, 0.0], NTI30099); 488 | gl_30072.bufferData(34962, new Float32Array(vertices_30100), 35044); 489 | framePtr = F.prev; 490 | } 491 | function newSeq_30156(len_30160) { 492 | 493 | var result_30162 = null; 494 | var F={procname:"newSeq.newSeq",prev:framePtr,filename:"lib\\system.nim",line:0}; 495 | framePtr = F; 496 | result_30162 = new Array(len_30160); for (var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Example: ex2 18 | 23 | 24 | 34 | 35 | 36 | 49 |
50 |
51 | 52 |

Example: ex2

53 | 54 | Your browser doesn't appear to support the 55 | <canvas> element. 56 | 57 | 58 |
59 |
60 |

Code

61 |
import ../src/webgl, dom
 62 | 
 63 | var gl: WebGLRenderingContext;
 64 | var viewportWidth:int
 65 | var viewportHeight:int
 66 | 
 67 | #########
 68 | proc identity4 (a:auto):auto =
 69 |     {. emit: "`a`[0]=1;`a`[1]=0;`a`[2]=0;`a`[3]=0;`a`[4]=0;`a`[5]=1;`a`[6]=0;`a`[7]=0;`a`[8]=0;`a`[9]=0;`a`[10]=1;`a`[11]=0;`a`[12]=0;`a`[13]=0;`a`[14]=0;`a`[15]=1;`result`=`a`" .}
 70 | 
 71 | proc translate4 (a,b,c:auto):auto =
 72 |     {. emit: "var d=`b`[0],e=`b`[1];`b`=`b`[2];if(!`c`||`a`==`c`){`a`[12]=`a`[0]*d+`a`[4]*e+`a`[8]*`b`+`a`[12];`a`[13]=`a`[1]*d+`a`[5]*e+`a`[9]*`b`+`a`[13];`a`[14]=`a`[2]*d+`a`[6]*e+`a`[10]*`b`+`a`[14];`a`[15]=`a`[3]*d+`a`[7]*e+`a`[11]*`b`+`a`[15];return `a`}var g=`a`[0],f=`a`[1],h=`a`[2],i=`a`[3],j=`a`[4],k=`a`[5],l=`a`[6],o=`a`[7],m=`a`[8],n=`a`[9],p=`a`[10],r=`a`[11];`c`[0]=g;`c`[1]=f;`c`[2]=h;`c`[3]=i;`c`[4]=j;`c`[5]=k;`c`[6]=l;`c`[7]=o;`c`[8]=m;`c`[9]=n;`c`[10]=p;`c`[11]=r;`c`[12]=g*d+j*e+m*`b`+`a`[12];`c`[13]=f*d+k*e+n*`b`+`a`[13];`c`[14]=h*d+l*e+p*`b`+`a`[14];`c`[15]=i*d+o*e+r*`b`+`a`[15];`result` = `c`;" .}
 73 | proc perspective4 (a,b,c,d,e:auto):auto =
 74 |     {. emit : "function frustum(a,b,c,d,e,g,f){var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f;};`a`=`c`*Math.tan(`a`*Math.PI/360);`b`=`a`*`b`;`result` = frustum(-`b`,`b`,-`a`,`a`,`c`,`d`,`e`);" .}
 75 | 
 76 | #######
 77 | 
 78 | proc initGL(canvas:Canvas) = 
 79 |     
 80 |     gl = canvas.getContext("webgl")
 81 |     if gl.isNil: gl = canvas.getContext("experimental-webgl")
 82 |     viewportWidth = canvas.width;
 83 |     viewportHeight = canvas.height;
 84 |     
 85 |     #if (gl==nil): 
 86 |         #alert("Could not initialise WebGL, sorry :-(");
 87 |     
 88 | proc getShader(gl:WebGLRenderingContext, id:cstring,stype:cstring):WebGLShader =
 89 |     var shaderScript = document.getElementById(id);
 90 |     if (shaderScript==nil) :
 91 |         return
 92 |     
 93 |     var str : cstring = shaderScript.firstChild.nodeValue;
 94 |     #[while (k!=nil) :
 95 |         if (k.nodeType == TextNode) :
 96 |             str &= k.nodeValue.cstring;
 97 |             {. emit : "console.log(`stype`+`k`);" .}
 98 |         k = k.nextSibling;
 99 |     {. emit : "console.log(`stype`+`str`);" .}]#
100 | 
101 |     if (stype == "x-shader/x-fragment") :
102 |         result = gl.createShader(seFRAGMENT_SHADER)
103 |     elif (stype == "x-shader/x-vertex"): 
104 |         result = gl.createShader(seVERTEX_SHADER);
105 |     else :
106 |         return;
107 | 
108 |     gl.shaderSource(result, str);
109 |     gl.compileShader(result);
110 | 
111 |     {. emit: "if (!`gl`.getShaderParameter(`result`, `gl`.COMPILE_STATUS)){alert(`stype`+' '+`gl`.getShaderInfoLog(`result`));return null;};" .}
112 | 
113 | var shaderProgram: WebGLProgram
114 | var vertexPositionAttribute:uint
115 | var pMatrixUniform:WebGLUniformLocation
116 | var mvMatrixUniform:WebGLUniformLocation
117 | 
118 | proc initShaders() =
119 |     var fragmentShader = getShader(gl, "shader-fs","x-shader/x-fragment");
120 |     var vertexShader = getShader(gl, "shader-vs","x-shader/x-vertex");
121 | 
122 |     shaderProgram = gl.createProgram();
123 |     gl.attachShader(shaderProgram, vertexShader);
124 |     gl.attachShader(shaderProgram, fragmentShader);
125 |     gl.linkProgram(shaderProgram);
126 | 
127 |     gl.useProgram(shaderProgram);
128 | 
129 |     vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
130 |     gl.enableVertexAttribArray(vertexPositionAttribute);
131 |     pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix");
132 |     mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
133 | 
134 | 
135 | 
136 | var mvMatrix = newSeq[float](16) # 4x4, so 16 elements
137 | var pMatrix = newSeq[float](16)
138 | 
139 | proc setMatrixUniforms() =
140 |     gl.uniformMatrix4fv(pMatrixUniform, false, pMatrix);
141 |     gl.uniformMatrix4fv(mvMatrixUniform, false, mvMatrix);
142 | 
143 | var triangleVertexPositionBuffer:WebGLBuffer
144 | var squareVertexPositionBuffer:WebGLBuffer
145 | var tin : tuple[itemSize,numItems:int]
146 | var vin : tuple[itemSize,numItems:int]
147 | 
148 | proc initBuffers() =
149 |     triangleVertexPositionBuffer = gl.createBuffer();
150 |     gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer);
151 |     var vertices = @[
152 |             0.0,  1.0,  0.0,
153 |         -1.0, -1.0,  0.0,
154 |             1.0, -1.0,  0.0
155 |     ];
156 |     gl.bufferData(beARRAY_BUFFER, vertices, beSTATIC_DRAW);
157 |     tin.itemSize = 3;
158 |     tin.numItems = 3;
159 | 
160 |     squareVertexPositionBuffer = gl.createBuffer();
161 |     gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer);
162 |     var vertices2 = @[
163 |             1.0,  1.0,  0.0,
164 |         -1.0,  1.0,  0.0,
165 |             1.0, -1.0,  0.0,
166 |         -1.0, -1.0,  0.0
167 |     ];
168 |     gl.bufferData(beARRAY_BUFFER, vertices2, beSTATIC_DRAW);
169 |     vin.itemSize = 3;
170 |     vin.numItems = 4;
171 | 
172 | 
173 | 
174 | proc drawScene() =
175 |     gl.viewport(0, 0, viewportWidth, viewportHeight);
176 |     gl.clear(bbCOLOR.uint or bbDEPTH.uint);
177 | 
178 |     perspective4(45, viewportWidth / viewportHeight, 0.1, 100.0, pMatrix);
179 |         
180 |     identity4(mvMatrix);
181 | 
182 |     traslate4(mvMatrix, @[-1.5, 0.0, -7.0], mvMatrix);
183 | 
184 |     gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer);
185 |     gl.vertexAttribPointer(vertexPositionAttribute, tin.itemSize, dtFLOAT, false, 0, 0);
186 |     setMatrixUniforms();
187 |     gl.drawArrays(pmTRIANGLES, 0, tin.numItems);
188 | 
189 | 
190 |     traslate4(mvMatrix, @[3.0, 0.0, 0.0], mvMatrix);
191 |     gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer);
192 |     gl.vertexAttribPointer(vertexPositionAttribute, vin.itemSize, dtFLOAT, false, 0, 0);
193 |     setMatrixUniforms();
194 |     gl.drawArrays(pmTRIANGLE_STRIP, 0, vin.numItems);
195 | 
196 | 
197 | 
198 | 
199 | dom.window.onload = proc (e: dom.Event) =
200 |     var canvas = dom.document.getElementById("glcanvas").Canvas;
201 |     initGL(canvas);
202 |     initShaders();
203 |     initBuffers();
204 | 
205 |     gl.clearColor(0.0, 0.0, 0.0, 1.0);
206 | 
207 |     drawScene();
208 | 
209 | 
210 | 
211 |
212 |
213 | 214 | 215 | 216 | -------------------------------------------------------------------------------- /docs/examples/ex2.js: -------------------------------------------------------------------------------- 1 | /* Generated by the Nim Compiler v0.16.1 */ 2 | /* (c) 2017 Andreas Rumpf */ 3 | 4 | var framePtr = null; 5 | var excHandler = 0; 6 | var lastJSError = null; 7 | if (typeof Int8Array === 'undefined') Int8Array = Array; 8 | if (typeof Int16Array === 'undefined') Int16Array = Array; 9 | if (typeof Int32Array === 'undefined') Int32Array = Array; 10 | if (typeof Uint8Array === 'undefined') Uint8Array = Array; 11 | if (typeof Uint16Array === 'undefined') Uint16Array = Array; 12 | if (typeof Uint32Array === 'undefined') Uint32Array = Array; 13 | if (typeof Float32Array === 'undefined') Float32Array = Array; 14 | if (typeof Float64Array === 'undefined') Float64Array = Array; 15 | var NTI30252 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; 16 | var NTI128 = {size: 0,kind: 36,base: null,node: null,finalizer: null}; 17 | var NTI30211 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; 18 | var NTI3440 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 19 | var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; 20 | var NTI13009 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; 21 | var NTI3408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 22 | var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; 23 | var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; 24 | var NTI3487 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; 25 | var NTI3424 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 26 | var NTI3438 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 27 | var NTI3442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 28 | var NNI3442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 29 | NTI3442.node = NNI3442; 30 | var NNI3438 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 31 | NTI3438.node = NNI3438; 32 | NTI3487.base = NTI3424; 33 | var NNI3424 = {kind: 2, len: 4, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3487, name: "parent", sons: null}, 34 | {kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, 35 | {kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, 36 | {kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}]}; 37 | NTI3424.node = NNI3424; 38 | var NNI3408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 39 | NTI3408.node = NNI3408; 40 | NTI3424.base = NTI3408; 41 | NTI3438.base = NTI3424; 42 | NTI3442.base = NTI3438; 43 | var NNI13009 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, 44 | {kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; 45 | NTI13009.node = NNI13009; 46 | var NNI3440 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 47 | NTI3440.node = NNI3440; 48 | NTI3440.base = NTI3438; 49 | NTI30211.base = NTI128; 50 | NTI30252.base = NTI128; 51 | function makeNimstrLit(c_14003) { 52 | 53 | var ln = c_14003.length; 54 | var result = new Array(ln + 1); 55 | var i = 0; 56 | for (; i < ln; ++i) { 57 | result[i] = c_14003.charCodeAt(i); 58 | } 59 | result[i] = 0; // terminating zero 60 | return result; 61 | } 62 | function SetConstr() { 63 | 64 | var result = {}; 65 | for (var i = 0; i < arguments.length; ++i) { 66 | var x = arguments[i]; 67 | if (typeof(x) == "object") { 68 | for (var j = x[0]; j <= x[1]; ++j) { 69 | result[j] = true; 70 | } 71 | } else { 72 | result[x] = true; 73 | } 74 | } 75 | return result; 76 | } 77 | function nimCopy(dest_19217, src_19218, ti_19219) { 78 | 79 | var result_19629 = null; 80 | switch (ti_19219.kind) { 81 | case 21: case 22: case 23: case 5: if (!(isFatPointer_19201(ti_19219))) { 82 | result_19629 = src_19218; 83 | } 84 | else { 85 | result_19629 = [src_19218[0], src_19218[1]];} 86 | 87 | 88 | break; 89 | case 19: if (dest_19217 === null || dest_19217 === undefined) { 90 | dest_19217 = {}; 91 | } 92 | else { 93 | for (var key in dest_19217) { delete dest_19217[key]; } 94 | } 95 | for (var key in src_19218) { dest_19217[key] = src_19218[key]; } 96 | result_19629 = dest_19217; 97 | 98 | break; 99 | case 18: case 17: if (!((ti_19219.base == null))) { 100 | result_19629 = nimCopy(dest_19217, src_19218, ti_19219.base); 101 | } 102 | else { 103 | if ((ti_19219.kind == 17)) { 104 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {m_type: ti_19219} : dest_19217;} 105 | else { 106 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {} : dest_19217;} 107 | } 108 | nimCopyAux(result_19629, src_19218, ti_19219.node); 109 | 110 | break; 111 | case 24: case 4: case 27: case 16: if (src_19218 === null) { 112 | result_19629 = null; 113 | } 114 | else { 115 | if (dest_19217 === null || dest_19217 === undefined) { 116 | dest_19217 = new Array(src_19218.length); 117 | } 118 | else { 119 | dest_19217.length = src_19218.length; 120 | } 121 | result_19629 = dest_19217; 122 | for (var i = 0; i < src_19218.length; ++i) { 123 | result_19629[i] = nimCopy(result_19629[i], src_19218[i], ti_19219.base); 124 | } 125 | } 126 | 127 | break; 128 | case 28: if (src_19218 !== null) { 129 | result_19629 = src_19218.slice(0); 130 | } 131 | 132 | break; 133 | default: 134 | result_19629 = src_19218; 135 | break; 136 | } 137 | return result_19629; 138 | } 139 | function eqStrings(a_16603, b_16604) { 140 | 141 | if (a_16603 == b_16604) return true; 142 | if ((!a_16603) || (!b_16604)) return false; 143 | var alen = a_16603.length; 144 | if (alen != b_16604.length) return false; 145 | for (var i = 0; i < alen; ++i) 146 | if (a_16603[i] != b_16604[i]) return false; 147 | return true; 148 | } 149 | function arrayConstr(len_19664, value_19665, typ_19666) { 150 | 151 | var result = new Array(len_19664); 152 | for (var i = 0; i < len_19664; ++i) result[i] = nimCopy(null, value_19665, typ_19666); 153 | return result; 154 | } 155 | function cstrToNimstr(c_14203) { 156 | 157 | var ln = c_14203.length; 158 | var result = new Array(ln); 159 | var r = 0; 160 | for (var i = 0; i < ln; ++i) { 161 | var ch = c_14203.charCodeAt(i); 162 | 163 | if (ch < 128) { 164 | result[r] = ch; 165 | } 166 | else if((ch > 127) && (ch < 2048)) { 167 | result[r] = (ch >> 6) | 192; 168 | ++r; 169 | result[r] = (ch & 63) | 128; 170 | } 171 | else { 172 | result[r] = (ch >> 12) | 224; 173 | ++r; 174 | result[r] = ((ch >> 6) & 63) | 128; 175 | ++r; 176 | result[r] = (ch & 63) | 128; 177 | } 178 | ++r; 179 | } 180 | result[r] = 0; // terminating zero 181 | return result; 182 | } 183 | function toJSStr(s_14403) { 184 | 185 | var len = s_14403.length-1; 186 | var asciiPart = new Array(len); 187 | var fcc = String.fromCharCode; 188 | var nonAsciiPart = null; 189 | var nonAsciiOffset = 0; 190 | for (var i = 0; i < len; ++i) { 191 | if (nonAsciiPart !== null) { 192 | var offset = (i - nonAsciiOffset) * 2; 193 | var code = s_14403[i].toString(16); 194 | if (code.length == 1) { 195 | code = "0"+code; 196 | } 197 | nonAsciiPart[offset] = "%"; 198 | nonAsciiPart[offset + 1] = code; 199 | } 200 | else if (s_14403[i] < 128) 201 | asciiPart[i] = fcc(s_14403[i]); 202 | else { 203 | asciiPart.length = i; 204 | nonAsciiOffset = i; 205 | nonAsciiPart = new Array((len - i) * 2); 206 | --i; 207 | } 208 | } 209 | asciiPart = asciiPart.join(""); 210 | return (nonAsciiPart === null) ? 211 | asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); 212 | } 213 | function raiseException(e_13406, ename_13407) { 214 | 215 | e_13406.name = ename_13407; 216 | if ((excHandler == 0)) { 217 | unhandledException(e_13406); 218 | } 219 | 220 | e_13406.trace = nimCopy(null, rawWriteStackTrace_13228(), NTI138); 221 | throw e_13406;} 222 | var nimvm_5887 = false; 223 | var nim_program_result = 0; 224 | var globalRaiseHook_11005 = [null]; 225 | var localRaiseHook_11010 = [null]; 226 | var outOfMemHook_11013 = [null]; 227 | function isFatPointer_19201(ti_19203) { 228 | 229 | var result_19204 = false; 230 | BeforeRet: do { 231 | result_19204 = !((SetConstr(17, 16, 4, 18, 27, 19, 23, 22, 21)[ti_19203.base.kind] != undefined)); 232 | break BeforeRet; 233 | } while (false); 234 | return result_19204; 235 | } 236 | function nimCopyAux(dest_19222, src_19223, n_19225) { 237 | 238 | switch (n_19225.kind) { 239 | case 0: 240 | break; 241 | case 1: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 242 | 243 | break; 244 | case 2: L1: do { 245 | var i_19615 = 0; 246 | var colontmp__19617 = 0; 247 | colontmp__19617 = (n_19225.len - 1); 248 | var res_19620 = 0; 249 | L2: do { 250 | L3: while (true) { 251 | if (!(res_19620 <= colontmp__19617)) break L3; 252 | i_19615 = res_19620; 253 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i_19615]); 254 | res_19620 += 1; 255 | } 256 | } while(false); 257 | } while(false); 258 | 259 | break; 260 | case 3: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 261 | for (var i = 0; i < n_19225.sons.length; ++i) { 262 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i][1]); 263 | } 264 | 265 | break; 266 | } 267 | } 268 | function add_11029(x_11032, x_11032_Idx, y_11033) { 269 | 270 | var len = x_11032[0].length-1; 271 | for (var i = 0; i < y_11033.length; ++i) { 272 | x_11032[0][len] = y_11033.charCodeAt(i); 273 | ++len; 274 | } 275 | x_11032[0][len] = 0 276 | } 277 | function auxWriteStackTrace_13004(f_13006) { 278 | 279 | var Tmp3; 280 | var result_13007 = [null]; 281 | var it_13015 = f_13006; 282 | var i_13016 = 0; 283 | var total_13017 = 0; 284 | var tempFrames_13021 = arrayConstr(64, {Field0: null, Field1: 0}, NTI13009); 285 | L1: do { 286 | L2: while (true) { 287 | if (!!((it_13015 == null))) Tmp3 = false; else {Tmp3 = (i_13016 <= 63); }if (!Tmp3) break L2; 288 | tempFrames_13021[i_13016].Field0 = it_13015.procname; 289 | tempFrames_13021[i_13016].Field1 = it_13015.line; 290 | i_13016 += 1; 291 | total_13017 += 1; 292 | it_13015 = it_13015.prev; 293 | } 294 | } while(false); 295 | L4: do { 296 | L5: while (true) { 297 | if (!!((it_13015 == null))) break L5; 298 | total_13017 += 1; 299 | it_13015 = it_13015.prev; 300 | } 301 | } while(false); 302 | result_13007[0] = nimCopy(null, makeNimstrLit(""), NTI138); 303 | if (!((total_13017 == i_13016))) { 304 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("(")); } else { result_13007[0] = makeNimstrLit("(");}; 305 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr(((total_13017 - i_13016))+"")); } else { result_13007[0] = cstrToNimstr(((total_13017 - i_13016))+"");}; 306 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_13007[0] = makeNimstrLit(" calls omitted) ...\x0A");}; 307 | } 308 | 309 | L6: do { 310 | var j_13215 = 0; 311 | var colontmp__13221 = 0; 312 | colontmp__13221 = (i_13016 - 1); 313 | var res_13224 = colontmp__13221; 314 | L7: do { 315 | L8: while (true) { 316 | if (!(0 <= res_13224)) break L8; 317 | j_13215 = res_13224; 318 | add_11029(result_13007, 0, tempFrames_13021[j_13215].Field0); 319 | if ((0 < tempFrames_13021[j_13215].Field1)) { 320 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(", line: ")); } else { result_13007[0] = makeNimstrLit(", line: ");}; 321 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr((tempFrames_13021[j_13215].Field1)+"")); } else { result_13007[0] = cstrToNimstr((tempFrames_13021[j_13215].Field1)+"");}; 322 | } 323 | 324 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("\x0A")); } else { result_13007[0] = makeNimstrLit("\x0A");}; 325 | res_13224 -= 1; 326 | } 327 | } while(false); 328 | } while(false); 329 | return result_13007[0]; 330 | } 331 | function rawWriteStackTrace_13228() { 332 | 333 | var result_13230 = null; 334 | if (!((framePtr == null))) { 335 | result_13230 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A").slice(0,-1)).concat(auxWriteStackTrace_13004(framePtr)), NTI138); 336 | } 337 | else { 338 | result_13230 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); 339 | } 340 | 341 | return result_13230; 342 | } 343 | function unhandledException(e_13253) { 344 | 345 | var Tmp1; 346 | var buf_13254 = /**/[makeNimstrLit("")]; 347 | if (!!(eqStrings(e_13253.message, null))) Tmp1 = false; else {Tmp1 = !((e_13253.message[0] == 0)); }if (Tmp1) { 348 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception: ");}; 349 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(e_13253.message); } else { buf_13254[0] = e_13253.message;}; 350 | } 351 | else { 352 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception");}; 353 | } 354 | 355 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit(" [")); } else { buf_13254[0] = makeNimstrLit(" [");}; 356 | add_11029(buf_13254, 0, e_13253.name); 357 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("]\x0A")); } else { buf_13254[0] = makeNimstrLit("]\x0A");}; 358 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(rawWriteStackTrace_13228()); } else { buf_13254[0] = rawWriteStackTrace_13228();}; 359 | var cbuf_13401 = toJSStr(buf_13254[0]); 360 | framePtr = null; 361 | if (typeof(Error) !== "undefined") { 362 | throw new Error(cbuf_13401); 363 | } 364 | else { 365 | throw cbuf_13401; 366 | } 367 | } 368 | function raiseOverflow() { 369 | 370 | var e_13840 = null; 371 | e_13840 = {m_type: NTI3442, parent: null, name: null, message: null, trace: null}; 372 | e_13840.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI138); 373 | e_13840.parent = null; 374 | raiseException(e_13840, "OverflowError"); 375 | } 376 | function raiseDivByZero() { 377 | 378 | var e_13858 = null; 379 | e_13858 = {m_type: NTI3440, parent: null, name: null, message: null, trace: null}; 380 | e_13858.message = nimCopy(null, makeNimstrLit("division by zero"), NTI138); 381 | e_13858.parent = null; 382 | raiseException(e_13858, "DivByZeroError"); 383 | } 384 | var gl_30001 = [null]; 385 | var viewportWidth_30003 = [0]; 386 | var viewportHeight_30005 = [0]; 387 | var shaderProgram_30092 = [null]; 388 | var vertexPositionAttribute_30094 = [0]; 389 | var pMatrixUniform_30096 = [null]; 390 | var mvMatrixUniform_30098 = [null]; 391 | function newSeq_30117(len_30121) { 392 | 393 | var result_30123 = null; 394 | var F={procname:"newSeq.newSeq",prev:framePtr,filename:"lib\\system.nim",line:0}; 395 | framePtr = F; 396 | result_30123 = new Array(len_30121); for (var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Example: ex3 18 | 23 | 24 | 34 | 35 | 36 | 49 |
50 |
51 | 52 |

Example: ex3

53 | 54 | Your browser doesn't appear to support the 55 | <canvas> element. 56 | 57 | 58 |
59 |
60 |

Code

61 |
import dom,../src/webgl,math
 62 | 
 63 | #utils
 64 | 
 65 | proc initWebGL(canvas:webgl.Canvas): WebGLRenderingContext {.inline.} = 
 66 |   result = canvas.getContext("webgl")
 67 |   if result.isNil: result = canvas.getContext("experimental-webgl")
 68 | 
 69 | proc checkShader(gl:WebGLRenderingContext,shader:WebGLShader) = 
 70 |   if not gl.getStatus(shader): log gl.getShaderInfoLog(shader)
 71 | proc checkProgram(gl:WebGLRenderingContext,prog:WebGLProgram) =
 72 |   if not gl.getStatus(prog): log gl.getProgramInfoLog(prog)  
 73 | 
 74 | let x = [1,2,3]
 75 | var y = x
 76 | var z = x
 77 | y[0] = 10
 78 | 
 79 | const
 80 |   startX = [-0.75,  0.75, -0.75,  0.75]
 81 |   startY = [-0.75, -0.75,  0.75,  0.75]
 82 |   freqs =  [1.0, math.pow(2.0, 1.0/4.0), math.pow(2.0, 1.0/3.0), math.pow(2.0, 1.0/2.0)]
 83 | 
 84 | var
 85 |   modelX = startX
 86 |   modelY = startY
 87 | 
 88 | # Form an X out of the four points described above
 89 | proc makeModel() : seq[float] =
 90 |   return @[
 91 |     modelX[0], modelY[0], modelX[1], modelY[1],
 92 |     modelX[0], modelY[0], modelX[2], modelY[2],
 93 |     modelX[0], modelY[0], modelX[3], modelY[3],
 94 |     modelX[1], modelY[1], modelX[3], modelY[3],
 95 |     modelX[2], modelY[2], modelX[1], modelY[1],
 96 |     modelX[2], modelY[2], modelX[3], modelY[3]
 97 |   ]
 98 | 
 99 | # Shaders
100 | 
101 | let vertexShaderCode = """
102 | attribute vec2 position;
103 | void main(void) {
104 |     gl_Position = vec4(position, 0.0, 1.0);
105 | }
106 | """
107 | 
108 | let fragmentShaderCode = """
109 | void main(void) {
110 |     gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
111 | }
112 | """
113 | 
114 | # Create context
115 | var canv = dom.document.getElementById("glcanvas").Canvas
116 | var gl = initWebGL(canv)
117 | 
118 | # Create a model
119 | var packedModel = newSeq[float](makeModel().len)# newFloat32Array(makeModel().len.float)
120 | var vertices = gl.createBuffer()
121 | 
122 | # Create vertex shader
123 | var vertexShader = gl.createShader(seVERTEX_SHADER)
124 | gl.shaderSource(vertexShader, vertexShaderCode)
125 | gl.compileShader(vertexShader)
126 | gl.checkShader(vertexShader)
127 | 
128 | # Create fragment shader
129 | var fragmentShader = gl.createShader(seFRAGMENT_SHADER)
130 | gl.shaderSource(fragmentShader, fragmentShaderCode)
131 | gl.compileShader(fragmentShader)
132 | gl.checkShader(fragmentShader)
133 | 
134 | # Link program
135 | var program = gl.createProgram()
136 | gl.attachShader(program, vertexShader)
137 | gl.attachShader(program, fragmentShader)
138 | gl.linkProgram(program)
139 | gl.checkProgram(program)
140 | 
141 | var positionAttrib = gl.getAttribLocation(program, "position")
142 | 
143 | var theta:float = 0.0
144 | 
145 | proc draw(gl:WebGLRenderingContext)=
146 |     let bg = (cos(theta)+1.0)/2.0 # Pulsate background on timer
147 | 
148 |     # Upload values for model
149 |     let model = makeModel()
150 |     packedModel = model
151 |     #for i in 0.. 0: # Start each anchor wobbling at a different time (one every three base wobbles)
179 |             modelX[i] = startX[i] + sin(at * freqs[i])/8.0
180 | 
181 | proc animLoop() =
182 |    draw(gl)
183 |    {.emit: "window.requestAnimationFrame(`animLoop`);" .}
184 | 
185 | # Init
186 | if gl != nil:
187 |   draw(gl)
188 |   animLoop()
189 | 
190 | 
191 |
192 |
193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /docs/examples/ex3.js: -------------------------------------------------------------------------------- 1 | /* Generated by the Nim Compiler v0.16.1 */ 2 | /* (c) 2017 Andreas Rumpf */ 3 | 4 | var framePtr = null; 5 | var excHandler = 0; 6 | var lastJSError = null; 7 | if (typeof Int8Array === 'undefined') Int8Array = Array; 8 | if (typeof Int16Array === 'undefined') Int16Array = Array; 9 | if (typeof Int32Array === 'undefined') Int32Array = Array; 10 | if (typeof Uint8Array === 'undefined') Uint8Array = Array; 11 | if (typeof Uint16Array === 'undefined') Uint16Array = Array; 12 | if (typeof Uint32Array === 'undefined') Uint32Array = Array; 13 | if (typeof Float32Array === 'undefined') Float32Array = Array; 14 | if (typeof Float64Array === 'undefined') Float64Array = Array; 15 | var NTI128 = {size: 0,kind: 36,base: null,node: null,finalizer: null}; 16 | var NTI34043 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 17 | var NTI3454 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 18 | var NTI34052 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; 19 | var NTI34065 = {size: 0,kind: 24,base: null,node: null,finalizer: null}; 20 | var NTI34038 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 21 | var NTI124 = {size: 0,kind: 36,base: null,node: null,finalizer: null}; 22 | var NTI34033 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 23 | var NTI34027 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 24 | var NTI3440 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 25 | var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; 26 | var NTI13009 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; 27 | var NTI3408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 28 | var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; 29 | var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; 30 | var NTI3487 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; 31 | var NTI3424 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 32 | var NTI3438 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 33 | var NTI3442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 34 | var NNI3442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 35 | NTI3442.node = NNI3442; 36 | var NNI3438 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 37 | NTI3438.node = NNI3438; 38 | NTI3487.base = NTI3424; 39 | var NNI3424 = {kind: 2, len: 4, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3487, name: "parent", sons: null}, 40 | {kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, 41 | {kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, 42 | {kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}]}; 43 | NTI3424.node = NNI3424; 44 | var NNI3408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 45 | NTI3408.node = NNI3408; 46 | NTI3424.base = NTI3408; 47 | NTI3438.base = NTI3424; 48 | NTI3442.base = NTI3438; 49 | var NNI13009 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, 50 | {kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; 51 | NTI13009.node = NNI13009; 52 | var NNI3440 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 53 | NTI3440.node = NNI3440; 54 | NTI3440.base = NTI3438; 55 | NTI34027.base = NTI104; 56 | NTI34033.base = NTI124; 57 | NTI34038.base = NTI124; 58 | NTI34065.base = NTI124; 59 | NTI34052.base = NTI124; 60 | var NNI3454 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 61 | NTI3454.node = NNI3454; 62 | NTI3454.base = NTI3424; 63 | NTI34043.base = NTI128; 64 | function makeNimstrLit(c_14003) { 65 | 66 | var ln = c_14003.length; 67 | var result = new Array(ln + 1); 68 | var i = 0; 69 | for (; i < ln; ++i) { 70 | result[i] = c_14003.charCodeAt(i); 71 | } 72 | result[i] = 0; // terminating zero 73 | return result; 74 | } 75 | function SetConstr() { 76 | 77 | var result = {}; 78 | for (var i = 0; i < arguments.length; ++i) { 79 | var x = arguments[i]; 80 | if (typeof(x) == "object") { 81 | for (var j = x[0]; j <= x[1]; ++j) { 82 | result[j] = true; 83 | } 84 | } else { 85 | result[x] = true; 86 | } 87 | } 88 | return result; 89 | } 90 | function nimCopy(dest_19217, src_19218, ti_19219) { 91 | 92 | var result_19629 = null; 93 | switch (ti_19219.kind) { 94 | case 21: case 22: case 23: case 5: if (!(isFatPointer_19201(ti_19219))) { 95 | result_19629 = src_19218; 96 | } 97 | else { 98 | result_19629 = [src_19218[0], src_19218[1]];} 99 | 100 | 101 | break; 102 | case 19: if (dest_19217 === null || dest_19217 === undefined) { 103 | dest_19217 = {}; 104 | } 105 | else { 106 | for (var key in dest_19217) { delete dest_19217[key]; } 107 | } 108 | for (var key in src_19218) { dest_19217[key] = src_19218[key]; } 109 | result_19629 = dest_19217; 110 | 111 | break; 112 | case 18: case 17: if (!((ti_19219.base == null))) { 113 | result_19629 = nimCopy(dest_19217, src_19218, ti_19219.base); 114 | } 115 | else { 116 | if ((ti_19219.kind == 17)) { 117 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {m_type: ti_19219} : dest_19217;} 118 | else { 119 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {} : dest_19217;} 120 | } 121 | nimCopyAux(result_19629, src_19218, ti_19219.node); 122 | 123 | break; 124 | case 24: case 4: case 27: case 16: if (src_19218 === null) { 125 | result_19629 = null; 126 | } 127 | else { 128 | if (dest_19217 === null || dest_19217 === undefined) { 129 | dest_19217 = new Array(src_19218.length); 130 | } 131 | else { 132 | dest_19217.length = src_19218.length; 133 | } 134 | result_19629 = dest_19217; 135 | for (var i = 0; i < src_19218.length; ++i) { 136 | result_19629[i] = nimCopy(result_19629[i], src_19218[i], ti_19219.base); 137 | } 138 | } 139 | 140 | break; 141 | case 28: if (src_19218 !== null) { 142 | result_19629 = src_19218.slice(0); 143 | } 144 | 145 | break; 146 | default: 147 | result_19629 = src_19218; 148 | break; 149 | } 150 | return result_19629; 151 | } 152 | function eqStrings(a_16603, b_16604) { 153 | 154 | if (a_16603 == b_16604) return true; 155 | if ((!a_16603) || (!b_16604)) return false; 156 | var alen = a_16603.length; 157 | if (alen != b_16604.length) return false; 158 | for (var i = 0; i < alen; ++i) 159 | if (a_16603[i] != b_16604[i]) return false; 160 | return true; 161 | } 162 | function arrayConstr(len_19664, value_19665, typ_19666) { 163 | 164 | var result = new Array(len_19664); 165 | for (var i = 0; i < len_19664; ++i) result[i] = nimCopy(null, value_19665, typ_19666); 166 | return result; 167 | } 168 | function cstrToNimstr(c_14203) { 169 | 170 | var ln = c_14203.length; 171 | var result = new Array(ln); 172 | var r = 0; 173 | for (var i = 0; i < ln; ++i) { 174 | var ch = c_14203.charCodeAt(i); 175 | 176 | if (ch < 128) { 177 | result[r] = ch; 178 | } 179 | else if((ch > 127) && (ch < 2048)) { 180 | result[r] = (ch >> 6) | 192; 181 | ++r; 182 | result[r] = (ch & 63) | 128; 183 | } 184 | else { 185 | result[r] = (ch >> 12) | 224; 186 | ++r; 187 | result[r] = ((ch >> 6) & 63) | 128; 188 | ++r; 189 | result[r] = (ch & 63) | 128; 190 | } 191 | ++r; 192 | } 193 | result[r] = 0; // terminating zero 194 | return result; 195 | } 196 | function toJSStr(s_14403) { 197 | 198 | var len = s_14403.length-1; 199 | var asciiPart = new Array(len); 200 | var fcc = String.fromCharCode; 201 | var nonAsciiPart = null; 202 | var nonAsciiOffset = 0; 203 | for (var i = 0; i < len; ++i) { 204 | if (nonAsciiPart !== null) { 205 | var offset = (i - nonAsciiOffset) * 2; 206 | var code = s_14403[i].toString(16); 207 | if (code.length == 1) { 208 | code = "0"+code; 209 | } 210 | nonAsciiPart[offset] = "%"; 211 | nonAsciiPart[offset + 1] = code; 212 | } 213 | else if (s_14403[i] < 128) 214 | asciiPart[i] = fcc(s_14403[i]); 215 | else { 216 | asciiPart.length = i; 217 | nonAsciiOffset = i; 218 | nonAsciiPart = new Array((len - i) * 2); 219 | --i; 220 | } 221 | } 222 | asciiPart = asciiPart.join(""); 223 | return (nonAsciiPart === null) ? 224 | asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); 225 | } 226 | function raiseException(e_13406, ename_13407) { 227 | 228 | e_13406.name = ename_13407; 229 | if ((excHandler == 0)) { 230 | unhandledException(e_13406); 231 | } 232 | 233 | e_13406.trace = nimCopy(null, rawWriteStackTrace_13228(), NTI138); 234 | throw e_13406;} 235 | var startX_34032 = nimCopy(null, [-7.5000000000000000e-001, 7.5000000000000000e-001, -7.5000000000000000e-001, 7.5000000000000000e-001], NTI34033); 236 | var startY_34037 = nimCopy(null, [-7.5000000000000000e-001, -7.5000000000000000e-001, 7.5000000000000000e-001, 7.5000000000000000e-001], NTI34038); 237 | function divInt(a_17403, b_17404) { 238 | 239 | if (b_17404 == 0) raiseDivByZero(); 240 | if (b_17404 == -1 && a_17403 == 2147483647) raiseOverflow(); 241 | return Math.floor(a_17403 / b_17404); 242 | } 243 | function addInt(a_16803, b_16804) { 244 | 245 | var result = a_16803 + b_16804; 246 | if (result > 2147483647 || result < -2147483648) raiseOverflow(); 247 | return result; 248 | } 249 | function mulInt(a_17203, b_17204) { 250 | 251 | var result = a_17203 * b_17204; 252 | if (result > 2147483647 || result < -2147483648) raiseOverflow(); 253 | return result; 254 | } 255 | function chckIndx(i_19803, a_19804, b_19805) { 256 | 257 | var Tmp1; 258 | var result_19806 = 0; 259 | BeforeRet: do { 260 | if (!(a_19804 <= i_19803)) Tmp1 = false; else {Tmp1 = (i_19803 <= b_19805); }if (Tmp1) { 261 | result_19806 = i_19803; 262 | break BeforeRet; 263 | } 264 | else { 265 | raiseIndexError(); 266 | } 267 | 268 | } while (false); 269 | return result_19806; 270 | } 271 | var freqs_34042 = nimCopy(null, [1.0000000000000000e+000, 1.1892071150027210e+000, 1.2599210498948732e+000, 1.4142135623730951e+000], NTI34043); 272 | var nimvm_5887 = false; 273 | var nim_program_result = 0; 274 | var globalRaiseHook_11005 = [null]; 275 | var localRaiseHook_11010 = [null]; 276 | var outOfMemHook_11013 = [null]; 277 | function isFatPointer_19201(ti_19203) { 278 | 279 | var result_19204 = false; 280 | BeforeRet: do { 281 | result_19204 = !((SetConstr(17, 16, 4, 18, 27, 19, 23, 22, 21)[ti_19203.base.kind] != undefined)); 282 | break BeforeRet; 283 | } while (false); 284 | return result_19204; 285 | } 286 | function nimCopyAux(dest_19222, src_19223, n_19225) { 287 | 288 | switch (n_19225.kind) { 289 | case 0: 290 | break; 291 | case 1: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 292 | 293 | break; 294 | case 2: L1: do { 295 | var i_19615 = 0; 296 | var colontmp__19617 = 0; 297 | colontmp__19617 = (n_19225.len - 1); 298 | var res_19620 = 0; 299 | L2: do { 300 | L3: while (true) { 301 | if (!(res_19620 <= colontmp__19617)) break L3; 302 | i_19615 = res_19620; 303 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i_19615]); 304 | res_19620 += 1; 305 | } 306 | } while(false); 307 | } while(false); 308 | 309 | break; 310 | case 3: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 311 | for (var i = 0; i < n_19225.sons.length; ++i) { 312 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i][1]); 313 | } 314 | 315 | break; 316 | } 317 | } 318 | function add_11029(x_11032, x_11032_Idx, y_11033) { 319 | 320 | var len = x_11032[0].length-1; 321 | for (var i = 0; i < y_11033.length; ++i) { 322 | x_11032[0][len] = y_11033.charCodeAt(i); 323 | ++len; 324 | } 325 | x_11032[0][len] = 0 326 | } 327 | function auxWriteStackTrace_13004(f_13006) { 328 | 329 | var Tmp3; 330 | var result_13007 = [null]; 331 | var it_13015 = f_13006; 332 | var i_13016 = 0; 333 | var total_13017 = 0; 334 | var tempFrames_13021 = arrayConstr(64, {Field0: null, Field1: 0}, NTI13009); 335 | L1: do { 336 | L2: while (true) { 337 | if (!!((it_13015 == null))) Tmp3 = false; else {Tmp3 = (i_13016 <= 63); }if (!Tmp3) break L2; 338 | tempFrames_13021[i_13016].Field0 = it_13015.procname; 339 | tempFrames_13021[i_13016].Field1 = it_13015.line; 340 | i_13016 += 1; 341 | total_13017 += 1; 342 | it_13015 = it_13015.prev; 343 | } 344 | } while(false); 345 | L4: do { 346 | L5: while (true) { 347 | if (!!((it_13015 == null))) break L5; 348 | total_13017 += 1; 349 | it_13015 = it_13015.prev; 350 | } 351 | } while(false); 352 | result_13007[0] = nimCopy(null, makeNimstrLit(""), NTI138); 353 | if (!((total_13017 == i_13016))) { 354 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("(")); } else { result_13007[0] = makeNimstrLit("(");}; 355 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr(((total_13017 - i_13016))+"")); } else { result_13007[0] = cstrToNimstr(((total_13017 - i_13016))+"");}; 356 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_13007[0] = makeNimstrLit(" calls omitted) ...\x0A");}; 357 | } 358 | 359 | L6: do { 360 | var j_13215 = 0; 361 | var colontmp__13221 = 0; 362 | colontmp__13221 = (i_13016 - 1); 363 | var res_13224 = colontmp__13221; 364 | L7: do { 365 | L8: while (true) { 366 | if (!(0 <= res_13224)) break L8; 367 | j_13215 = res_13224; 368 | add_11029(result_13007, 0, tempFrames_13021[j_13215].Field0); 369 | if ((0 < tempFrames_13021[j_13215].Field1)) { 370 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(", line: ")); } else { result_13007[0] = makeNimstrLit(", line: ");}; 371 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr((tempFrames_13021[j_13215].Field1)+"")); } else { result_13007[0] = cstrToNimstr((tempFrames_13021[j_13215].Field1)+"");}; 372 | } 373 | 374 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("\x0A")); } else { result_13007[0] = makeNimstrLit("\x0A");}; 375 | res_13224 -= 1; 376 | } 377 | } while(false); 378 | } while(false); 379 | return result_13007[0]; 380 | } 381 | function rawWriteStackTrace_13228() { 382 | 383 | var result_13230 = null; 384 | if (!((framePtr == null))) { 385 | result_13230 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A").slice(0,-1)).concat(auxWriteStackTrace_13004(framePtr)), NTI138); 386 | } 387 | else { 388 | result_13230 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); 389 | } 390 | 391 | return result_13230; 392 | } 393 | function unhandledException(e_13253) { 394 | 395 | var Tmp1; 396 | var buf_13254 = /**/[makeNimstrLit("")]; 397 | if (!!(eqStrings(e_13253.message, null))) Tmp1 = false; else {Tmp1 = !((e_13253.message[0] == 0)); }if (Tmp1) { 398 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception: ");}; 399 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(e_13253.message); } else { buf_13254[0] = e_13253.message;}; 400 | } 401 | else { 402 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception");}; 403 | } 404 | 405 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit(" [")); } else { buf_13254[0] = makeNimstrLit(" [");}; 406 | add_11029(buf_13254, 0, e_13253.name); 407 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("]\x0A")); } else { buf_13254[0] = makeNimstrLit("]\x0A");}; 408 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(rawWriteStackTrace_13228()); } else { buf_13254[0] = rawWriteStackTrace_13228();}; 409 | var cbuf_13401 = toJSStr(buf_13254[0]); 410 | framePtr = null; 411 | if (typeof(Error) !== "undefined") { 412 | throw new Error(cbuf_13401); 413 | } 414 | else { 415 | throw cbuf_13401; 416 | } 417 | } 418 | function raiseOverflow() { 419 | 420 | var e_13840 = null; 421 | e_13840 = {m_type: NTI3442, parent: null, name: null, message: null, trace: null}; 422 | e_13840.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI138); 423 | e_13840.parent = null; 424 | raiseException(e_13840, "OverflowError"); 425 | } 426 | function raiseDivByZero() { 427 | 428 | var e_13858 = null; 429 | e_13858 = {m_type: NTI3440, parent: null, name: null, message: null, trace: null}; 430 | e_13858.message = nimCopy(null, makeNimstrLit("division by zero"), NTI138); 431 | e_13858.parent = null; 432 | raiseException(e_13858, "DivByZeroError"); 433 | } 434 | var x_34029 = nimCopy(null, [1, 2, 3], NTI34027); 435 | var y_34030 = /**/[nimCopy(null, x_34029, NTI34027)]; 436 | var z_34031 = /**/[nimCopy(null, x_34029, NTI34027)]; 437 | y_34030[0][0] = 10; 438 | var modelX_34048 = /**/[nimCopy(null, startX_34032, NTI34033)]; 439 | var modelY_34049 = /**/[nimCopy(null, startY_34037, NTI34038)]; 440 | var vertexShaderCode_34066 = makeNimstrLit("attribute vec2 position;\x0Avoid main(void) {\x0A gl_Position = vec4(position, 0.0, 1.0);\x0A}\x0A"); 441 | var fragmentShaderCode_34067 = makeNimstrLit("void main(void) {\x0A gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);\x0A}\x0A"); 442 | var canv_34068 = /**/[document.getElementById("glcanvas")]; 443 | function initWebGL_34001(canvas_34004) { 444 | 445 | var result_34005 = null; 446 | var F={procname:"ex3.initWebGL",prev:framePtr,filename:"ex3.nim",line:0}; 447 | framePtr = F; 448 | F.line = 6; 449 | result_34005 = canvas_34004.getContext("webgl"); 450 | if ((result_34005 === null)) { 451 | F.line = 7; 452 | result_34005 = canvas_34004.getContext("experimental-webgl"); 453 | } 454 | 455 | framePtr = F.prev; 456 | return result_34005; 457 | } 458 | var gl_34069 = /**/[initWebGL_34001(canv_34068[0])]; 459 | function newSeq_34083(len_34087) { 460 | 461 | var result_34089 = null; 462 | var F={procname:"newSeq.newSeq",prev:framePtr,filename:"lib\\system.nim",line:0}; 463 | framePtr = F; 464 | result_34089 = new Array(len_34087); for (var i=0;i 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Example: ex4 18 | 23 | 24 | 34 | 35 | 36 | 49 |
50 |
51 | 52 |

Example: ex4

53 | 54 | Your browser doesn't appear to support the 55 | <canvas> element. 56 | 57 | 58 |
59 |
60 |

Code

61 |
import ../src/webgl, dom
 62 | 
 63 | converter toUI(i:int):uint = i.uint
 64 | 
 65 | #============== Creating a canvas ====================*/
 66 | var canvas = dom.document.getElementById("glcanvas").Canvas;
 67 | var gl = canvas.getContextWebgl()
 68 | #======== Defining and storing the geometry ===========*/
 69 | 
 70 | var vertices = [
 71 |   -0.5'f32,0.5,0.0,
 72 |   -0.5,-0.5,0.0,
 73 |   0.5,-0.5,0.0, 
 74 | ];
 75 | 
 76 | var indices = [0'u16,1,2];
 77 | 
 78 | # Create an empty buffer object to store vertex buffer
 79 | var vertex_buffer = gl.createBuffer();
 80 | 
 81 | # Bind appropriate array buffer to it
 82 | gl.bindBuffer(beArrayBuffer, vertex_buffer);
 83 | 
 84 | # Pass the vertex data to the buffer
 85 | gl.bufferData(beArrayBuffer, vertices, beStaticDraw);
 86 | 
 87 | # Unbind the buffer
 88 | gl.bindBuffer(beArrayBuffer, nil);
 89 | 
 90 | # Create an empty buffer object to store Index buffer
 91 | var Index_Buffer = gl.createBuffer();
 92 | 
 93 | # Bind appropriate array buffer to it
 94 | gl.bindBuffer(beElementArrayBuffer, Index_Buffer);
 95 | 
 96 | # Pass the vertex data to the buffer
 97 | gl.bufferData(beElementArrayBuffer, indices, beStaticDraw);
 98 | 
 99 | # Unbind the buffer
100 | gl.bindBuffer(beElementArrayBuffer, nil);
101 | 
102 | #================ Shaders ====================*/
103 | 
104 | # Vertex shader source code
105 | var vertCode = "attribute vec3 coordinates;"&
106 |   "void main(void) {" &
107 |   " gl_Position = vec4(coordinates, 1.0);" &
108 |   "}"
109 |   
110 | # Create a vertex shader object
111 | var vertShader = gl.createShader(seVertexShader);
112 | 
113 | # Attach vertex shader source code
114 | gl.shaderSource(vertShader, vertCode);
115 | 
116 | # Compile the vertex shader
117 | gl.compileShader(vertShader);
118 | if not gl.getStatus(vertShader): log("error vs")
119 | #fragment shader source code
120 | var fragCode ="void main(void){" &
121 |   "gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);" &
122 |   "}"
123 |   
124 | # Create fragment shader object
125 | var fragShader = gl.createShader(seFragmentShader);
126 | 
127 | # Attach fragment shader source code
128 | gl.shaderSource(fragShader, fragCode); 
129 | 
130 | # Compile the fragmentt shader
131 | gl.compileShader(fragShader);
132 | if not gl.getStatus(fragShader): log("error fg")
133 | # Create a shader program object to store
134 | # the combined shader program
135 | var shaderProgram = gl.createProgram();
136 | 
137 | # Attach a vertex shader
138 | gl.attachShader(shaderProgram, vertShader);
139 | 
140 | # Attach a fragment shader
141 | gl.attachShader(shaderProgram, fragShader);
142 | 
143 | # Link both the programs
144 | gl.linkProgram(shaderProgram);
145 | if not gl.getStatus(shaderProgram): log("error p")
146 | # Use the combined shader program object
147 | gl.useProgram(shaderProgram);
148 | 
149 | #======= Associating shaders to buffer objects =======*/
150 | 
151 | # Bind vertex buffer object
152 | gl.bindBuffer(beArrayBuffer, vertex_buffer);
153 | 
154 | # Bind index buffer object
155 | gl.bindBuffer(beElementArrayBuffer, Index_Buffer);
156 | 
157 | # Get the attribute location
158 | var coord = gl.getAttribLocation(shaderProgram, "coordinates");
159 | 
160 | # Point an attribute to the currently bound VBO
161 | gl.vertexAttribPointer(coord, 3, dtFloat, false, 0, 0); 
162 | 
163 | # Enable the attribute
164 | gl.enableVertexAttribArray(coord);
165 | 
166 | #=========Drawing the triangle===========*/
167 | 
168 | # Clear the canvas
169 | gl.clearColor(0.5, 0.5, 0.5, 0.9);
170 | 
171 | # Enable the depth test
172 | gl.enable(0x0B71);
173 | 
174 | # Clear the color buffer bit
175 | gl.clear(bbColor);
176 | 
177 | # Set the view port
178 | gl.viewport(0,0,canvas.width,canvas.height);
179 | 
180 | # Draw the triangle
181 | gl.drawElements(pmTriangles, indices.len, dtUnsignedShort,0) #0x1403 ??
182 | 
183 |
184 |
185 | 186 | 187 | 188 | -------------------------------------------------------------------------------- /docs/examples/ex4.js: -------------------------------------------------------------------------------- 1 | /* Generated by the Nim Compiler v0.16.1 */ 2 | /* (c) 2017 Andreas Rumpf */ 3 | 4 | var framePtr = null; 5 | var excHandler = 0; 6 | var lastJSError = null; 7 | if (typeof Int8Array === 'undefined') Int8Array = Array; 8 | if (typeof Int16Array === 'undefined') Int16Array = Array; 9 | if (typeof Int32Array === 'undefined') Int32Array = Array; 10 | if (typeof Uint8Array === 'undefined') Uint8Array = Array; 11 | if (typeof Uint16Array === 'undefined') Uint16Array = Array; 12 | if (typeof Uint32Array === 'undefined') Uint32Array = Array; 13 | if (typeof Float32Array === 'undefined') Float32Array = Array; 14 | if (typeof Float64Array === 'undefined') Float64Array = Array; 15 | var NTI118 = {size: 0,kind: 42,base: null,node: null,finalizer: null}; 16 | var NTI30014 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 17 | var NTI126 = {size: 0,kind: 37,base: null,node: null,finalizer: null}; 18 | var NTI30008 = {size: 0,kind: 16,base: null,node: null,finalizer: null}; 19 | var NTI3446 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 20 | var NTI3440 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 21 | var NTI104 = {size: 0,kind: 31,base: null,node: null,finalizer: null}; 22 | var NTI13009 = {size: 0, kind: 18, base: null, node: null, finalizer: null}; 23 | var NTI3408 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 24 | var NTI138 = {size: 0,kind: 28,base: null,node: null,finalizer: null}; 25 | var NTI140 = {size: 0,kind: 29,base: null,node: null,finalizer: null}; 26 | var NTI3487 = {size: 0,kind: 22,base: null,node: null,finalizer: null}; 27 | var NTI3424 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 28 | var NTI3438 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 29 | var NTI3442 = {size: 0, kind: 17, base: null, node: null, finalizer: null}; 30 | var NNI3442 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 31 | NTI3442.node = NNI3442; 32 | var NNI3438 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 33 | NTI3438.node = NNI3438; 34 | NTI3487.base = NTI3424; 35 | var NNI3424 = {kind: 2, len: 4, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "parent", len: 0, typ: NTI3487, name: "parent", sons: null}, 36 | {kind: 1, offset: "name", len: 0, typ: NTI140, name: "name", sons: null}, 37 | {kind: 1, offset: "message", len: 0, typ: NTI138, name: "msg", sons: null}, 38 | {kind: 1, offset: "trace", len: 0, typ: NTI138, name: "trace", sons: null}]}; 39 | NTI3424.node = NNI3424; 40 | var NNI3408 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 41 | NTI3408.node = NNI3408; 42 | NTI3424.base = NTI3408; 43 | NTI3438.base = NTI3424; 44 | NTI3442.base = NTI3438; 45 | var NNI13009 = {kind: 2, len: 2, offset: 0, typ: null, name: null, sons: [{kind: 1, offset: "Field0", len: 0, typ: NTI140, name: "Field0", sons: null}, 46 | {kind: 1, offset: "Field1", len: 0, typ: NTI104, name: "Field1", sons: null}]}; 47 | NTI13009.node = NNI13009; 48 | var NNI3440 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 49 | NTI3440.node = NNI3440; 50 | NTI3440.base = NTI3438; 51 | var NNI3446 = {kind: 2, len: 0, offset: 0, typ: null, name: null, sons: []}; 52 | NTI3446.node = NNI3446; 53 | NTI3446.base = NTI3424; 54 | NTI30008.base = NTI126; 55 | NTI30014.base = NTI118; 56 | function makeNimstrLit(c_14003) { 57 | 58 | var ln = c_14003.length; 59 | var result = new Array(ln + 1); 60 | var i = 0; 61 | for (; i < ln; ++i) { 62 | result[i] = c_14003.charCodeAt(i); 63 | } 64 | result[i] = 0; // terminating zero 65 | return result; 66 | } 67 | function SetConstr() { 68 | 69 | var result = {}; 70 | for (var i = 0; i < arguments.length; ++i) { 71 | var x = arguments[i]; 72 | if (typeof(x) == "object") { 73 | for (var j = x[0]; j <= x[1]; ++j) { 74 | result[j] = true; 75 | } 76 | } else { 77 | result[x] = true; 78 | } 79 | } 80 | return result; 81 | } 82 | function nimCopy(dest_19217, src_19218, ti_19219) { 83 | 84 | var result_19629 = null; 85 | switch (ti_19219.kind) { 86 | case 21: case 22: case 23: case 5: if (!(isFatPointer_19201(ti_19219))) { 87 | result_19629 = src_19218; 88 | } 89 | else { 90 | result_19629 = [src_19218[0], src_19218[1]];} 91 | 92 | 93 | break; 94 | case 19: if (dest_19217 === null || dest_19217 === undefined) { 95 | dest_19217 = {}; 96 | } 97 | else { 98 | for (var key in dest_19217) { delete dest_19217[key]; } 99 | } 100 | for (var key in src_19218) { dest_19217[key] = src_19218[key]; } 101 | result_19629 = dest_19217; 102 | 103 | break; 104 | case 18: case 17: if (!((ti_19219.base == null))) { 105 | result_19629 = nimCopy(dest_19217, src_19218, ti_19219.base); 106 | } 107 | else { 108 | if ((ti_19219.kind == 17)) { 109 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {m_type: ti_19219} : dest_19217;} 110 | else { 111 | result_19629 = (dest_19217 === null || dest_19217 === undefined) ? {} : dest_19217;} 112 | } 113 | nimCopyAux(result_19629, src_19218, ti_19219.node); 114 | 115 | break; 116 | case 24: case 4: case 27: case 16: if (src_19218 === null) { 117 | result_19629 = null; 118 | } 119 | else { 120 | if (dest_19217 === null || dest_19217 === undefined) { 121 | dest_19217 = new Array(src_19218.length); 122 | } 123 | else { 124 | dest_19217.length = src_19218.length; 125 | } 126 | result_19629 = dest_19217; 127 | for (var i = 0; i < src_19218.length; ++i) { 128 | result_19629[i] = nimCopy(result_19629[i], src_19218[i], ti_19219.base); 129 | } 130 | } 131 | 132 | break; 133 | case 28: if (src_19218 !== null) { 134 | result_19629 = src_19218.slice(0); 135 | } 136 | 137 | break; 138 | default: 139 | result_19629 = src_19218; 140 | break; 141 | } 142 | return result_19629; 143 | } 144 | function eqStrings(a_16603, b_16604) { 145 | 146 | if (a_16603 == b_16604) return true; 147 | if ((!a_16603) || (!b_16604)) return false; 148 | var alen = a_16603.length; 149 | if (alen != b_16604.length) return false; 150 | for (var i = 0; i < alen; ++i) 151 | if (a_16603[i] != b_16604[i]) return false; 152 | return true; 153 | } 154 | function arrayConstr(len_19664, value_19665, typ_19666) { 155 | 156 | var result = new Array(len_19664); 157 | for (var i = 0; i < len_19664; ++i) result[i] = nimCopy(null, value_19665, typ_19666); 158 | return result; 159 | } 160 | function cstrToNimstr(c_14203) { 161 | 162 | var ln = c_14203.length; 163 | var result = new Array(ln); 164 | var r = 0; 165 | for (var i = 0; i < ln; ++i) { 166 | var ch = c_14203.charCodeAt(i); 167 | 168 | if (ch < 128) { 169 | result[r] = ch; 170 | } 171 | else if((ch > 127) && (ch < 2048)) { 172 | result[r] = (ch >> 6) | 192; 173 | ++r; 174 | result[r] = (ch & 63) | 128; 175 | } 176 | else { 177 | result[r] = (ch >> 12) | 224; 178 | ++r; 179 | result[r] = ((ch >> 6) & 63) | 128; 180 | ++r; 181 | result[r] = (ch & 63) | 128; 182 | } 183 | ++r; 184 | } 185 | result[r] = 0; // terminating zero 186 | return result; 187 | } 188 | function toJSStr(s_14403) { 189 | 190 | var len = s_14403.length-1; 191 | var asciiPart = new Array(len); 192 | var fcc = String.fromCharCode; 193 | var nonAsciiPart = null; 194 | var nonAsciiOffset = 0; 195 | for (var i = 0; i < len; ++i) { 196 | if (nonAsciiPart !== null) { 197 | var offset = (i - nonAsciiOffset) * 2; 198 | var code = s_14403[i].toString(16); 199 | if (code.length == 1) { 200 | code = "0"+code; 201 | } 202 | nonAsciiPart[offset] = "%"; 203 | nonAsciiPart[offset + 1] = code; 204 | } 205 | else if (s_14403[i] < 128) 206 | asciiPart[i] = fcc(s_14403[i]); 207 | else { 208 | asciiPart.length = i; 209 | nonAsciiOffset = i; 210 | nonAsciiPart = new Array((len - i) * 2); 211 | --i; 212 | } 213 | } 214 | asciiPart = asciiPart.join(""); 215 | return (nonAsciiPart === null) ? 216 | asciiPart : asciiPart + decodeURIComponent(nonAsciiPart.join("")); 217 | } 218 | function raiseException(e_13406, ename_13407) { 219 | 220 | e_13406.name = ename_13407; 221 | if ((excHandler == 0)) { 222 | unhandledException(e_13406); 223 | } 224 | 225 | e_13406.trace = nimCopy(null, rawWriteStackTrace_13228(), NTI138); 226 | throw e_13406;} 227 | var nimvm_5887 = false; 228 | var nim_program_result = 0; 229 | var globalRaiseHook_11005 = [null]; 230 | var localRaiseHook_11010 = [null]; 231 | var outOfMemHook_11013 = [null]; 232 | function isFatPointer_19201(ti_19203) { 233 | 234 | var result_19204 = false; 235 | BeforeRet: do { 236 | result_19204 = !((SetConstr(17, 16, 4, 18, 27, 19, 23, 22, 21)[ti_19203.base.kind] != undefined)); 237 | break BeforeRet; 238 | } while (false); 239 | return result_19204; 240 | } 241 | function nimCopyAux(dest_19222, src_19223, n_19225) { 242 | 243 | switch (n_19225.kind) { 244 | case 0: 245 | break; 246 | case 1: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 247 | 248 | break; 249 | case 2: L1: do { 250 | var i_19615 = 0; 251 | var colontmp__19617 = 0; 252 | colontmp__19617 = (n_19225.len - 1); 253 | var res_19620 = 0; 254 | L2: do { 255 | L3: while (true) { 256 | if (!(res_19620 <= colontmp__19617)) break L3; 257 | i_19615 = res_19620; 258 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i_19615]); 259 | res_19620 += 1; 260 | } 261 | } while(false); 262 | } while(false); 263 | 264 | break; 265 | case 3: dest_19222[n_19225.offset] = nimCopy(dest_19222[n_19225.offset], src_19223[n_19225.offset], n_19225.typ); 266 | for (var i = 0; i < n_19225.sons.length; ++i) { 267 | nimCopyAux(dest_19222, src_19223, n_19225.sons[i][1]); 268 | } 269 | 270 | break; 271 | } 272 | } 273 | function add_11029(x_11032, x_11032_Idx, y_11033) { 274 | 275 | var len = x_11032[0].length-1; 276 | for (var i = 0; i < y_11033.length; ++i) { 277 | x_11032[0][len] = y_11033.charCodeAt(i); 278 | ++len; 279 | } 280 | x_11032[0][len] = 0 281 | } 282 | function auxWriteStackTrace_13004(f_13006) { 283 | 284 | var Tmp3; 285 | var result_13007 = [null]; 286 | var it_13015 = f_13006; 287 | var i_13016 = 0; 288 | var total_13017 = 0; 289 | var tempFrames_13021 = arrayConstr(64, {Field0: null, Field1: 0}, NTI13009); 290 | L1: do { 291 | L2: while (true) { 292 | if (!!((it_13015 == null))) Tmp3 = false; else {Tmp3 = (i_13016 <= 63); }if (!Tmp3) break L2; 293 | tempFrames_13021[i_13016].Field0 = it_13015.procname; 294 | tempFrames_13021[i_13016].Field1 = it_13015.line; 295 | i_13016 += 1; 296 | total_13017 += 1; 297 | it_13015 = it_13015.prev; 298 | } 299 | } while(false); 300 | L4: do { 301 | L5: while (true) { 302 | if (!!((it_13015 == null))) break L5; 303 | total_13017 += 1; 304 | it_13015 = it_13015.prev; 305 | } 306 | } while(false); 307 | result_13007[0] = nimCopy(null, makeNimstrLit(""), NTI138); 308 | if (!((total_13017 == i_13016))) { 309 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("(")); } else { result_13007[0] = makeNimstrLit("(");}; 310 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr(((total_13017 - i_13016))+"")); } else { result_13007[0] = cstrToNimstr(((total_13017 - i_13016))+"");}; 311 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(" calls omitted) ...\x0A")); } else { result_13007[0] = makeNimstrLit(" calls omitted) ...\x0A");}; 312 | } 313 | 314 | L6: do { 315 | var j_13215 = 0; 316 | var colontmp__13221 = 0; 317 | colontmp__13221 = (i_13016 - 1); 318 | var res_13224 = colontmp__13221; 319 | L7: do { 320 | L8: while (true) { 321 | if (!(0 <= res_13224)) break L8; 322 | j_13215 = res_13224; 323 | add_11029(result_13007, 0, tempFrames_13021[j_13215].Field0); 324 | if ((0 < tempFrames_13021[j_13215].Field1)) { 325 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit(", line: ")); } else { result_13007[0] = makeNimstrLit(", line: ");}; 326 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(cstrToNimstr((tempFrames_13021[j_13215].Field1)+"")); } else { result_13007[0] = cstrToNimstr((tempFrames_13021[j_13215].Field1)+"");}; 327 | } 328 | 329 | if (result_13007[0] != null) { result_13007[0] = (result_13007[0].slice(0, -1)).concat(makeNimstrLit("\x0A")); } else { result_13007[0] = makeNimstrLit("\x0A");}; 330 | res_13224 -= 1; 331 | } 332 | } while(false); 333 | } while(false); 334 | return result_13007[0]; 335 | } 336 | function rawWriteStackTrace_13228() { 337 | 338 | var result_13230 = null; 339 | if (!((framePtr == null))) { 340 | result_13230 = nimCopy(null, (makeNimstrLit("Traceback (most recent call last)\x0A").slice(0,-1)).concat(auxWriteStackTrace_13004(framePtr)), NTI138); 341 | } 342 | else { 343 | result_13230 = nimCopy(null, makeNimstrLit("No stack traceback available\x0A"), NTI138); 344 | } 345 | 346 | return result_13230; 347 | } 348 | function unhandledException(e_13253) { 349 | 350 | var Tmp1; 351 | var buf_13254 = /**/[makeNimstrLit("")]; 352 | if (!!(eqStrings(e_13253.message, null))) Tmp1 = false; else {Tmp1 = !((e_13253.message[0] == 0)); }if (Tmp1) { 353 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception: ")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception: ");}; 354 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(e_13253.message); } else { buf_13254[0] = e_13253.message;}; 355 | } 356 | else { 357 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("Error: unhandled exception")); } else { buf_13254[0] = makeNimstrLit("Error: unhandled exception");}; 358 | } 359 | 360 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit(" [")); } else { buf_13254[0] = makeNimstrLit(" [");}; 361 | add_11029(buf_13254, 0, e_13253.name); 362 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(makeNimstrLit("]\x0A")); } else { buf_13254[0] = makeNimstrLit("]\x0A");}; 363 | if (buf_13254[0] != null) { buf_13254[0] = (buf_13254[0].slice(0, -1)).concat(rawWriteStackTrace_13228()); } else { buf_13254[0] = rawWriteStackTrace_13228();}; 364 | var cbuf_13401 = toJSStr(buf_13254[0]); 365 | framePtr = null; 366 | if (typeof(Error) !== "undefined") { 367 | throw new Error(cbuf_13401); 368 | } 369 | else { 370 | throw cbuf_13401; 371 | } 372 | } 373 | function raiseOverflow() { 374 | 375 | var e_13840 = null; 376 | e_13840 = {m_type: NTI3442, parent: null, name: null, message: null, trace: null}; 377 | e_13840.message = nimCopy(null, makeNimstrLit("over- or underflow"), NTI138); 378 | e_13840.parent = null; 379 | raiseException(e_13840, "OverflowError"); 380 | } 381 | function raiseDivByZero() { 382 | 383 | var e_13858 = null; 384 | e_13858 = {m_type: NTI3440, parent: null, name: null, message: null, trace: null}; 385 | e_13858.message = nimCopy(null, makeNimstrLit("division by zero"), NTI138); 386 | e_13858.parent = null; 387 | raiseException(e_13858, "DivByZeroError"); 388 | } 389 | var canvas_30006 = /**/[document.getElementById("glcanvas")]; 390 | function sysFatal_21821(message_21827) { 391 | 392 | var F={procname:"sysFatal.sysFatal",prev:framePtr,filename:"lib\\system.nim",line:0}; 393 | framePtr = F; 394 | F.line = 2646; 395 | var e_21829 = null; 396 | e_21829 = {m_type: NTI3446, parent: null, name: null, message: null, trace: null}; 397 | F.line = 2648; 398 | e_21829.message = nimCopy(null, message_21827, NTI138); 399 | F.line = 2649; 400 | raiseException(e_21829, "AssertionError"); 401 | framePtr = F.prev; 402 | } 403 | function raiseAssert_21816(msg_21818) { 404 | 405 | var F={procname:"system.raiseAssert",prev:framePtr,filename:"lib\\system.nim",line:0}; 406 | framePtr = F; 407 | sysFatal_21821(msg_21818); 408 | framePtr = F.prev; 409 | } 410 | function failedAssertImpl_21839(msg_21841) { 411 | 412 | var F={procname:"system.failedAssertImpl",prev:framePtr,filename:"lib\\system.nim",line:0}; 413 | framePtr = F; 414 | raiseAssert_21816(msg_21841); 415 | framePtr = F.prev; 416 | } 417 | function getContextWebgl_28955(c_28957) { 418 | 419 | var result_28958 = null; 420 | var F={procname:"webgl.getContextWebgl",prev:framePtr,filename:"C:\\Users\\stisa\\OneDrive\\Progetti\\webgl\\src\\webgl.nim",line:0}; 421 | framePtr = F; 422 | F.line = 423; 423 | result_28958 = c_28957.getContext("webgl"); 424 | if ((result_28958 === null)) { 425 | F.line = 424; 426 | result_28958 = c_28957.getContext("experimental-webgl"); 427 | } 428 | 429 | if (!(!((result_28958 === null)))) { 430 | failedAssertImpl_21839(makeNimstrLit("not isNil(result) ")); 431 | } 432 | 433 | framePtr = F.prev; 434 | return result_28958; 435 | } 436 | var gl_30007 = /**/[getContextWebgl_28955(canvas_30006[0])]; 437 | var vertices_30013 = /**/[nimCopy(null, [-5.0000000000000000e-001, 5.0000000000000000e-001, 0.0, -5.0000000000000000e-001, -5.0000000000000000e-001, 0.0, 5.0000000000000000e-001, -5.0000000000000000e-001, 0.0], NTI30008)]; 438 | var indices_30016 = /**/[nimCopy(null, [0, 1, 2], NTI30014)]; 439 | var vertex_buffer_30017 = /**/[gl_30007[0].createBuffer()]; 440 | gl_30007[0].bindBuffer(34962, vertex_buffer_30017[0]); 441 | gl_30007[0].bufferData(34962, new Float32Array(vertices_30013[0]), 35044); 442 | gl_30007[0].bindBuffer(34962, null); 443 | var Index_Buffer_30052 = /**/[gl_30007[0].createBuffer()]; 444 | gl_30007[0].bindBuffer(34963, Index_Buffer_30052[0]); 445 | gl_30007[0].bufferData(34963, new Uint16Array(indices_30016[0]), 35044); 446 | gl_30007[0].bindBuffer(34963, null); 447 | var vertCode_30087 = /**/[makeNimstrLit("attribute vec3 coordinates;void main(void) { gl_Position = vec4(coordinates, 1.0);}")]; 448 | var vertShader_30096 = /**/[gl_30007[0].createShader(35633)]; 449 | gl_30007[0].shaderSource(vertShader_30096[0], toJSStr(vertCode_30087[0])); 450 | gl_30007[0].compileShader(vertShader_30096[0]); 451 | function getStatus_29029(gl_29031, what_29032) { 452 | 453 | var result_29033 = false; 454 | var F={procname:"webgl.getStatus",prev:framePtr,filename:"C:\\Users\\stisa\\OneDrive\\Progetti\\webgl\\src\\webgl.nim",line:0}; 455 | framePtr = F; 456 | F.line = 444; 457 | result_29033 = gl_29031.getShaderParameter(what_29032, gl_29031.COMPILE_STATUS);framePtr = F.prev; 458 | return result_29033; 459 | } 460 | if (!(getStatus_29029(gl_30007[0], vertShader_30096[0]))) { 461 | console.log("error vs"); 462 | } 463 | 464 | var fragCode_30100 = /**/[makeNimstrLit("void main(void){gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);}")]; 465 | var fragShader_30109 = /**/[gl_30007[0].createShader(35632)]; 466 | gl_30007[0].shaderSource(fragShader_30109[0], toJSStr(fragCode_30100[0])); 467 | gl_30007[0].compileShader(fragShader_30109[0]); 468 | if (!(getStatus_29029(gl_30007[0], fragShader_30109[0]))) { 469 | console.log("error fg"); 470 | } 471 | 472 | var shaderProgram_30113 = /**/[gl_30007[0].createProgram()]; 473 | gl_30007[0].attachShader(shaderProgram_30113[0], vertShader_30096[0]); 474 | gl_30007[0].attachShader(shaderProgram_30113[0], fragShader_30109[0]); 475 | gl_30007[0].linkProgram(shaderProgram_30113[0]); 476 | function getStatus_29034(gl_29036, what_29037) { 477 | 478 | var result_29038 = false; 479 | var F={procname:"webgl.getStatus",prev:framePtr,filename:"C:\\Users\\stisa\\OneDrive\\Progetti\\webgl\\src\\webgl.nim",line:0}; 480 | framePtr = F; 481 | F.line = 446; 482 | result_29038 = gl_29036.getProgramParameter(what_29037, gl_29036.LINK_STATUS);framePtr = F.prev; 483 | return result_29038; 484 | } 485 | if (!(getStatus_29034(gl_30007[0], shaderProgram_30113[0]))) { 486 | console.log("error p"); 487 | } 488 | 489 | gl_30007[0].useProgram(shaderProgram_30113[0]); 490 | gl_30007[0].bindBuffer(34962, vertex_buffer_30017[0]); 491 | gl_30007[0].bindBuffer(34963, Index_Buffer_30052[0]); 492 | var coord_30137 = /**/[gl_30007[0].getAttribLocation(shaderProgram_30113[0], "coordinates")]; 493 | gl_30007[0].vertexAttribPointer(coord_30137[0], 3, 5126, false, 0, 0); 494 | gl_30007[0].enableVertexAttribArray(coord_30137[0]); 495 | gl_30007[0].clearColor(5.0000000000000000e-001, 5.0000000000000000e-001, 5.0000000000000000e-001, 9.0000000000000002e-001); 496 | gl_30007[0].enable(2929); 497 | gl_30007[0].clear(16384); 498 | gl_30007[0].viewport(0, 0, canvas_30006[0].width, canvas_30006[0].height); 499 | gl_30007[0].drawElements(4, 3, 5123, 0); 500 | -------------------------------------------------------------------------------- /docs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | webgl 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 32 |
33 |

Examples for webgl

34 | 49 |

AutoDocs for webgl

50 |

Mozilla Documentation

51 |
52 | 53 | 54 | -------------------------------------------------------------------------------- /examples/ex1.nim: -------------------------------------------------------------------------------- 1 | import dom, ../src/webgl 2 | 3 | var vertexPositionAttribute : uint 4 | 5 | proc getShader(gl:WebGLRenderingContext, id:string, kind:char):WebGLShader = 6 | var shaderScript = dom.document.getElementById(id) 7 | if (shaderScript==nil): return 8 | var theSource : string = "" 9 | var currentChild = shaderScript.firstChild 10 | while(currentChild!=nil): 11 | if (currentChild.nodeType == dom.TextNode): 12 | theSource &= currentChild.nodeValue 13 | currentChild = currentChild.nextSibling 14 | 15 | if(kind == 'f'): result = gl.createShader(seFRAGMENT_SHADER) 16 | elif(kind == 'v'): result = gl.createShader(seVERTEX_SHADER) 17 | else: return #unknown shader type 18 | 19 | gl.shaderSource(result, theSource) 20 | 21 | # Compile shader 22 | gl.compileShader(result) 23 | 24 | # See if it compiled successfully 25 | {. emit: "if (!`gl`.getShaderParameter(`result`, `gl`.COMPILE_STATUS)) {alert('An error occurred compiling the shaders: ' + `gl`.getShaderInfoLog(`result`));return null;}; ".} 26 | 27 | var shaderProgram : WebGLProgram 28 | proc initShaders(gl:WebGLRenderingContext) = 29 | var fragmentShader = getShader(gl, "shader-fs",'f') 30 | var vertexShader = getShader(gl, "shader-vs",'v'); 31 | 32 | #Create shader programs 33 | shaderProgram = gl.createProgram() 34 | gl.attachShader(shaderProgram,vertexShader) 35 | gl.attachShader(shaderProgram,fragmentShader) 36 | gl.linkProgram(shaderProgram) 37 | 38 | # If creating the shader program failed, alert 39 | # I'm lazy so I'll just emit this directly 40 | # {.emit : "if (!`gl`.getProgramParameter(`shaderProgram`, `gl`.LINK_STATUS)) { alert('Unable to initialize the shader program: ' + `gl`.getProgramInfoLog(`shader`)); };" .} 41 | 42 | gl.useProgram(shaderProgram) 43 | 44 | 45 | vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); 46 | gl.enableVertexAttribArray(vertexPositionAttribute); 47 | 48 | var squareVerticesBuffer : WebGLBuffer 49 | 50 | proc initBuffers(gl:WebGLRenderingContext) = 51 | squareVerticesBuffer = gl.createBuffer() 52 | 53 | gl.bindBuffer(beARRAY_BUFFER, squareVerticesBuffer) 54 | 55 | var vertices :seq[float32]= @[ 56 | 1.0'f32, 1.0, 0.0, 57 | -1.0, 1.0, 0.0, 58 | 1.0, -1.0, 0.0, 59 | -1.0, -1.0, 0.0 60 | ]; 61 | 62 | gl.bufferData(beARRAY_BUFFER, vertices, beSTATIC_DRAW); 63 | 64 | 65 | proc setMatrixUniforms(gl:WebGLRenderingContext,pm, mv: seq[float]) = 66 | var pUniform = gl.getUniformLocation(shaderProgram,"uPMatrix") 67 | gl.uniformMatrix4fv(pUniform,false, pm) 68 | 69 | var mvUniform = gl.getUniformLocation(shaderProgram,"uMVMatrix") 70 | gl.uniformMatrix4fv(mvUniform,false, mv) 71 | 72 | proc drawScene(gl:WebGLRenderingContext) = 73 | gl.clear(bbCOLOR.uint or bbDEPTH.uint); 74 | 75 | var perspectiveMatrix = newSeq[float](16) 76 | perspective4(45, 640.0/480.0, 0.1, 100.0, perspectiveMatrix); 77 | 78 | 79 | var mv = newSeq[float](16) 80 | mv.identity4(); 81 | mv.traslate4([-0.0, 0.0, -6.0],mv); 82 | 83 | gl.bindBuffer(beARRAY_BUFFER, squareVerticesBuffer); 84 | gl.vertexAttribPointer(vertexPositionAttribute, 3, dtFLOAT, false, 0, 0); 85 | setMatrixUniforms(gl,perspectiveMatrix,mv); 86 | gl.drawArrays(pmTRIANGLE_STRIP, 0, 4); 87 | 88 | 89 | dom.window.onload = proc (e: dom.Event) = 90 | echo sizeof(int) 91 | echo sizeof(uint) 92 | echo sizeof(float) 93 | var canvas = dom.document.getElementById("glcanvas").Canvas; 94 | var gl = canvas.getContext("webgl") 95 | if gl.isNil: gl = canvas.getContext("experimental-webgl") 96 | 97 | gl.clearColor(0.0, 0.0, 0.0, 1.0); # Clear to black, fully opaque 98 | gl.clearDepth(1.0); # Clear everything 99 | 100 | # Initialize the shaders; this is where all the lighting for the 101 | # vertices and so forth is established. 102 | 103 | initShaders(gl); 104 | 105 | # Here's where we call the routine that builds all the objects 106 | # we'll be drawing. 107 | initBuffers(gl); 108 | 109 | # Set up to draw the scene periodically. 110 | #setInterval(drawScene, 15); 111 | drawScene(gl) 112 | -------------------------------------------------------------------------------- /examples/ex2.nim: -------------------------------------------------------------------------------- 1 | import ../src/webgl, dom 2 | 3 | var gl: WebGLRenderingContext; 4 | var viewportWidth:int 5 | var viewportHeight:int 6 | 7 | ######### 8 | proc identity4 (a:auto):auto = 9 | {. emit: "`a`[0]=1;`a`[1]=0;`a`[2]=0;`a`[3]=0;`a`[4]=0;`a`[5]=1;`a`[6]=0;`a`[7]=0;`a`[8]=0;`a`[9]=0;`a`[10]=1;`a`[11]=0;`a`[12]=0;`a`[13]=0;`a`[14]=0;`a`[15]=1;`result`=`a`" .} 10 | 11 | proc translate4 (a,b,c:auto):auto = 12 | {. emit: "var d=`b`[0],e=`b`[1];`b`=`b`[2];if(!`c`||`a`==`c`){`a`[12]=`a`[0]*d+`a`[4]*e+`a`[8]*`b`+`a`[12];`a`[13]=`a`[1]*d+`a`[5]*e+`a`[9]*`b`+`a`[13];`a`[14]=`a`[2]*d+`a`[6]*e+`a`[10]*`b`+`a`[14];`a`[15]=`a`[3]*d+`a`[7]*e+`a`[11]*`b`+`a`[15];return `a`}var g=`a`[0],f=`a`[1],h=`a`[2],i=`a`[3],j=`a`[4],k=`a`[5],l=`a`[6],o=`a`[7],m=`a`[8],n=`a`[9],p=`a`[10],r=`a`[11];`c`[0]=g;`c`[1]=f;`c`[2]=h;`c`[3]=i;`c`[4]=j;`c`[5]=k;`c`[6]=l;`c`[7]=o;`c`[8]=m;`c`[9]=n;`c`[10]=p;`c`[11]=r;`c`[12]=g*d+j*e+m*`b`+`a`[12];`c`[13]=f*d+k*e+n*`b`+`a`[13];`c`[14]=h*d+l*e+p*`b`+`a`[14];`c`[15]=i*d+o*e+r*`b`+`a`[15];`result` = `c`;" .} 13 | proc perspective4 (a,b,c,d,e:auto):auto = 14 | {. emit : "function frustum(a,b,c,d,e,g,f){var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f;};`a`=`c`*Math.tan(`a`*Math.PI/360);`b`=`a`*`b`;`result` = frustum(-`b`,`b`,-`a`,`a`,`c`,`d`,`e`);" .} 15 | 16 | ####### 17 | 18 | proc initGL(canvas:Canvas) = 19 | 20 | gl = canvas.getContext("webgl") 21 | if gl.isNil: gl = canvas.getContext("experimental-webgl") 22 | viewportWidth = canvas.width; 23 | viewportHeight = canvas.height; 24 | 25 | #if (gl==nil): 26 | #alert("Could not initialise WebGL, sorry :-("); 27 | 28 | proc getShader(gl:WebGLRenderingContext, id:cstring,stype:cstring):WebGLShader = 29 | var shaderScript = document.getElementById(id); 30 | if (shaderScript==nil) : 31 | return 32 | 33 | var str : cstring = shaderScript.firstChild.nodeValue; 34 | #[while (k!=nil) : 35 | if (k.nodeType == TextNode) : 36 | str &= k.nodeValue.cstring; 37 | {. emit : "console.log(`stype`+`k`);" .} 38 | k = k.nextSibling; 39 | {. emit : "console.log(`stype`+`str`);" .}]# 40 | 41 | if (stype == "x-shader/x-fragment") : 42 | result = gl.createShader(seFRAGMENT_SHADER) 43 | elif (stype == "x-shader/x-vertex"): 44 | result = gl.createShader(seVERTEX_SHADER); 45 | else : 46 | return; 47 | 48 | gl.shaderSource(result, str); 49 | gl.compileShader(result); 50 | 51 | {. emit: "if (!`gl`.getShaderParameter(`result`, `gl`.COMPILE_STATUS)){alert(`stype`+' '+`gl`.getShaderInfoLog(`result`));return null;};" .} 52 | 53 | var shaderProgram: WebGLProgram 54 | var vertexPositionAttribute:uint 55 | var pMatrixUniform:WebGLUniformLocation 56 | var mvMatrixUniform:WebGLUniformLocation 57 | 58 | proc initShaders() = 59 | var fragmentShader = getShader(gl, "shader-fs","x-shader/x-fragment"); 60 | var vertexShader = getShader(gl, "shader-vs","x-shader/x-vertex"); 61 | 62 | shaderProgram = gl.createProgram(); 63 | gl.attachShader(shaderProgram, vertexShader); 64 | gl.attachShader(shaderProgram, fragmentShader); 65 | gl.linkProgram(shaderProgram); 66 | 67 | gl.useProgram(shaderProgram); 68 | 69 | vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition"); 70 | gl.enableVertexAttribArray(vertexPositionAttribute); 71 | pMatrixUniform = gl.getUniformLocation(shaderProgram, "uPMatrix"); 72 | mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix"); 73 | 74 | 75 | 76 | var mvMatrix = newSeq[float](16) # 4x4, so 16 elements 77 | var pMatrix = newSeq[float](16) 78 | 79 | proc setMatrixUniforms() = 80 | gl.uniformMatrix4fv(pMatrixUniform, false, pMatrix); 81 | gl.uniformMatrix4fv(mvMatrixUniform, false, mvMatrix); 82 | 83 | var triangleVertexPositionBuffer:WebGLBuffer 84 | var squareVertexPositionBuffer:WebGLBuffer 85 | var tin : tuple[itemSize,numItems:int] 86 | var vin : tuple[itemSize,numItems:int] 87 | 88 | proc initBuffers() = 89 | triangleVertexPositionBuffer = gl.createBuffer(); 90 | gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer); 91 | var vertices = @[ 92 | 0.0, 1.0, 0.0, 93 | -1.0, -1.0, 0.0, 94 | 1.0, -1.0, 0.0 95 | ]; 96 | gl.bufferData(beARRAY_BUFFER, vertices, beSTATIC_DRAW); 97 | tin.itemSize = 3; 98 | tin.numItems = 3; 99 | 100 | squareVertexPositionBuffer = gl.createBuffer(); 101 | gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer); 102 | var vertices2 = @[ 103 | 1.0, 1.0, 0.0, 104 | -1.0, 1.0, 0.0, 105 | 1.0, -1.0, 0.0, 106 | -1.0, -1.0, 0.0 107 | ]; 108 | gl.bufferData(beARRAY_BUFFER, vertices2, beSTATIC_DRAW); 109 | vin.itemSize = 3; 110 | vin.numItems = 4; 111 | 112 | 113 | 114 | proc drawScene() = 115 | gl.viewport(0, 0, viewportWidth, viewportHeight); 116 | gl.clear(bbCOLOR.uint or bbDEPTH.uint); 117 | 118 | perspective4(45, viewportWidth / viewportHeight, 0.1, 100.0, pMatrix); 119 | 120 | identity4(mvMatrix); 121 | 122 | traslate4(mvMatrix, @[-1.5, 0.0, -7.0], mvMatrix); 123 | 124 | gl.bindBuffer(beARRAY_BUFFER, triangleVertexPositionBuffer); 125 | gl.vertexAttribPointer(vertexPositionAttribute, tin.itemSize, dtFLOAT, false, 0, 0); 126 | setMatrixUniforms(); 127 | gl.drawArrays(pmTRIANGLES, 0, tin.numItems); 128 | 129 | 130 | traslate4(mvMatrix, @[3.0, 0.0, 0.0], mvMatrix); 131 | gl.bindBuffer(beARRAY_BUFFER, squareVertexPositionBuffer); 132 | gl.vertexAttribPointer(vertexPositionAttribute, vin.itemSize, dtFLOAT, false, 0, 0); 133 | setMatrixUniforms(); 134 | gl.drawArrays(pmTRIANGLE_STRIP, 0, vin.numItems); 135 | 136 | 137 | 138 | 139 | dom.window.onload = proc (e: dom.Event) = 140 | var canvas = dom.document.getElementById("glcanvas").Canvas; 141 | initGL(canvas); 142 | initShaders(); 143 | initBuffers(); 144 | 145 | gl.clearColor(0.0, 0.0, 0.0, 1.0); 146 | 147 | drawScene(); 148 | 149 | -------------------------------------------------------------------------------- /examples/ex3.nim: -------------------------------------------------------------------------------- 1 | import dom,../src/webgl,math 2 | 3 | #utils 4 | 5 | proc initWebGL(canvas:webgl.Canvas): WebGLRenderingContext {.inline.} = 6 | result = canvas.getContext("webgl") 7 | if result.isNil: result = canvas.getContext("experimental-webgl") 8 | 9 | proc checkShader(gl:WebGLRenderingContext,shader:WebGLShader) = 10 | if not gl.getStatus(shader): log gl.getShaderInfoLog(shader) 11 | proc checkProgram(gl:WebGLRenderingContext,prog:WebGLProgram) = 12 | if not gl.getStatus(prog): log gl.getProgramInfoLog(prog) 13 | 14 | let x = [1,2,3] 15 | var y = x 16 | var z = x 17 | y[0] = 10 18 | 19 | const 20 | startX = [-0.75, 0.75, -0.75, 0.75] 21 | startY = [-0.75, -0.75, 0.75, 0.75] 22 | freqs = [1.0, math.pow(2.0, 1.0/4.0), math.pow(2.0, 1.0/3.0), math.pow(2.0, 1.0/2.0)] 23 | 24 | var 25 | modelX = startX 26 | modelY = startY 27 | 28 | # Form an X out of the four points described above 29 | proc makeModel() : seq[float] = 30 | return @[ 31 | modelX[0], modelY[0], modelX[1], modelY[1], 32 | modelX[0], modelY[0], modelX[2], modelY[2], 33 | modelX[0], modelY[0], modelX[3], modelY[3], 34 | modelX[1], modelY[1], modelX[3], modelY[3], 35 | modelX[2], modelY[2], modelX[1], modelY[1], 36 | modelX[2], modelY[2], modelX[3], modelY[3] 37 | ] 38 | 39 | # Shaders 40 | 41 | let vertexShaderCode = """ 42 | attribute vec2 position; 43 | void main(void) { 44 | gl_Position = vec4(position, 0.0, 1.0); 45 | } 46 | """ 47 | 48 | let fragmentShaderCode = """ 49 | void main(void) { 50 | gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0); 51 | } 52 | """ 53 | 54 | # Create context 55 | var canv = dom.document.getElementById("glcanvas").Canvas 56 | var gl = initWebGL(canv) 57 | 58 | # Create a model 59 | var packedModel = newSeq[float](makeModel().len)# newFloat32Array(makeModel().len.float) 60 | var vertices = gl.createBuffer() 61 | 62 | # Create vertex shader 63 | var vertexShader = gl.createShader(seVERTEX_SHADER) 64 | gl.shaderSource(vertexShader, vertexShaderCode) 65 | gl.compileShader(vertexShader) 66 | gl.checkShader(vertexShader) 67 | 68 | # Create fragment shader 69 | var fragmentShader = gl.createShader(seFRAGMENT_SHADER) 70 | gl.shaderSource(fragmentShader, fragmentShaderCode) 71 | gl.compileShader(fragmentShader) 72 | gl.checkShader(fragmentShader) 73 | 74 | # Link program 75 | var program = gl.createProgram() 76 | gl.attachShader(program, vertexShader) 77 | gl.attachShader(program, fragmentShader) 78 | gl.linkProgram(program) 79 | gl.checkProgram(program) 80 | 81 | var positionAttrib = gl.getAttribLocation(program, "position") 82 | 83 | var theta:float = 0.0 84 | 85 | proc draw(gl:WebGLRenderingContext)= 86 | let bg = (cos(theta)+1.0)/2.0 # Pulsate background on timer 87 | 88 | # Upload values for model 89 | let model = makeModel() 90 | packedModel = model 91 | #for i in 0.. 0: # Start each anchor wobbling at a different time (one every three base wobbles) 119 | modelX[i] = startX[i] + sin(at * freqs[i])/8.0 120 | 121 | proc animLoop() = 122 | draw(gl) 123 | {.emit: "window.requestAnimationFrame(`animLoop`);" .} 124 | 125 | # Init 126 | if gl != nil: 127 | draw(gl) 128 | animLoop() 129 | -------------------------------------------------------------------------------- /examples/ex4.nim: -------------------------------------------------------------------------------- 1 | import ../src/webgl, dom 2 | 3 | converter toUI(i:int):uint = i.uint 4 | 5 | #============== Creating a canvas ====================*/ 6 | var canvas = dom.document.getElementById("glcanvas").Canvas; 7 | var gl = canvas.getContextWebgl() 8 | #======== Defining and storing the geometry ===========*/ 9 | 10 | var vertices = [ 11 | -0.5'f32,0.5,0.0, 12 | -0.5,-0.5,0.0, 13 | 0.5,-0.5,0.0, 14 | ]; 15 | 16 | var indices = [0'u16,1,2]; 17 | 18 | # Create an empty buffer object to store vertex buffer 19 | var vertex_buffer = gl.createBuffer(); 20 | 21 | # Bind appropriate array buffer to it 22 | gl.bindBuffer(beArrayBuffer, vertex_buffer); 23 | 24 | # Pass the vertex data to the buffer 25 | gl.bufferData(beArrayBuffer, vertices, beStaticDraw); 26 | 27 | # Unbind the buffer 28 | gl.bindBuffer(beArrayBuffer, nil); 29 | 30 | # Create an empty buffer object to store Index buffer 31 | var Index_Buffer = gl.createBuffer(); 32 | 33 | # Bind appropriate array buffer to it 34 | gl.bindBuffer(beElementArrayBuffer, Index_Buffer); 35 | 36 | # Pass the vertex data to the buffer 37 | gl.bufferData(beElementArrayBuffer, indices, beStaticDraw); 38 | 39 | # Unbind the buffer 40 | gl.bindBuffer(beElementArrayBuffer, nil); 41 | 42 | #================ Shaders ====================*/ 43 | 44 | # Vertex shader source code 45 | var vertCode = "attribute vec3 coordinates;"& 46 | "void main(void) {" & 47 | " gl_Position = vec4(coordinates, 1.0);" & 48 | "}" 49 | 50 | # Create a vertex shader object 51 | var vertShader = gl.createShader(seVertexShader); 52 | 53 | # Attach vertex shader source code 54 | gl.shaderSource(vertShader, vertCode); 55 | 56 | # Compile the vertex shader 57 | gl.compileShader(vertShader); 58 | if not gl.getStatus(vertShader): log("error vs") 59 | #fragment shader source code 60 | var fragCode ="void main(void){" & 61 | "gl_FragColor = vec4(0.0, 0.0, 0.0, 0.1);" & 62 | "}" 63 | 64 | # Create fragment shader object 65 | var fragShader = gl.createShader(seFragmentShader); 66 | 67 | # Attach fragment shader source code 68 | gl.shaderSource(fragShader, fragCode); 69 | 70 | # Compile the fragmentt shader 71 | gl.compileShader(fragShader); 72 | if not gl.getStatus(fragShader): log("error fg") 73 | # Create a shader program object to store 74 | # the combined shader program 75 | var shaderProgram = gl.createProgram(); 76 | 77 | # Attach a vertex shader 78 | gl.attachShader(shaderProgram, vertShader); 79 | 80 | # Attach a fragment shader 81 | gl.attachShader(shaderProgram, fragShader); 82 | 83 | # Link both the programs 84 | gl.linkProgram(shaderProgram); 85 | if not gl.getStatus(shaderProgram): log("error p") 86 | # Use the combined shader program object 87 | gl.useProgram(shaderProgram); 88 | 89 | #======= Associating shaders to buffer objects =======*/ 90 | 91 | # Bind vertex buffer object 92 | gl.bindBuffer(beArrayBuffer, vertex_buffer); 93 | 94 | # Bind index buffer object 95 | gl.bindBuffer(beElementArrayBuffer, Index_Buffer); 96 | 97 | # Get the attribute location 98 | var coord = gl.getAttribLocation(shaderProgram, "coordinates"); 99 | 100 | # Point an attribute to the currently bound VBO 101 | gl.vertexAttribPointer(coord, 3, dtFloat, false, 0, 0); 102 | 103 | # Enable the attribute 104 | gl.enableVertexAttribArray(coord); 105 | 106 | #=========Drawing the triangle===========*/ 107 | 108 | # Clear the canvas 109 | gl.clearColor(0.5, 0.5, 0.5, 0.9); 110 | 111 | # Enable the depth test 112 | gl.enable(0x0B71); 113 | 114 | # Clear the color buffer bit 115 | gl.clear(bbColor); 116 | 117 | # Set the view port 118 | gl.viewport(0,0,canvas.width,canvas.height); 119 | 120 | # Draw the triangle 121 | gl.drawElements(pmTriangles, indices.len, dtUnsignedShort,0) #0x1403 ?? -------------------------------------------------------------------------------- /oldwrapper/webgl.nim: -------------------------------------------------------------------------------- 1 | import dom 2 | include webglconsts 3 | 4 | 5 | #TODO: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Types 6 | type 7 | Canvas* = ref CanvasObj 8 | CanvasObj {.importc.} = object of dom.Element 9 | width*: int 10 | height*:int 11 | clientWidth*: int 12 | clientHeight*:int 13 | 14 | ArrayBufferView* = ref ArrayBufferViewObj 15 | ArrayBufferViewObj {. importc .} = object of RootObj 16 | 17 | Int8Array* = ref Int8ArrayObj 18 | Int8ArrayObj {. importc .} = object of ArrayBufferView 19 | 20 | Uint8Array* = ref Uint8ArrayObj 21 | Uint8ArrayObj {. importc .} = object of ArrayBufferView 22 | 23 | Uint8ClampedArray* = ref Uint8ClampedArrayObj 24 | Uint8ClampedArrayObj {. importc .} = object of ArrayBufferView 25 | 26 | Int16Array* = ref Int16ArrayObj 27 | Int16ArrayObj {. importc .} = object of ArrayBufferView 28 | 29 | Uint16Array* = ref Uint16ArrayObj 30 | Uint16ArrayObj {. importc .} = object of ArrayBufferView 31 | 32 | Int32Array* = ref Int32ArrayObj 33 | Int32ArrayObj {. importc .} = object of ArrayBufferView 34 | 35 | Uint32Array* = ref Uint32ArrayObj 36 | Uint32ArrayObj {. importc .} = object of ArrayBufferView 37 | 38 | Float32Array* = ref Float32ArrayObj 39 | Float32ArrayObj {. importc .} = object of ArrayBufferView 40 | 41 | Float64Array* = ref Float64ArrayObj 42 | Float64ArrayObj {. importc .} = object of ArrayBufferView 43 | 44 | DataView* = ref DataViewObj 45 | DataViewObj {. importc .} = object of ArrayBufferView 46 | 47 | WebGLActiveInfoObj* {. importc .} = object 48 | name*: cstring 49 | `type`*: GLenum 50 | size*: GLint 51 | WebGLActiveInfo* = ref WebGLActiveInfoObj 52 | 53 | WebGLUniformLocation* = ref WebGLUniformLocationObj 54 | WebGLUniformLocationObj {. importc .} = object of RootObj 55 | 56 | WebGLShaderPrecisionFormat* = ref WebGLShaderPrecisionFormatObj 57 | WebGLShaderPrecisionFormatObj {. importc .} = object of RootObj 58 | 59 | WebGLContextAttributes* = ref WebGLContextAttributesObj 60 | WebGLContextAttributesObj {. importc .} = object of RootObj 61 | 62 | WebGLBuffer* = ref WebGLBufferObj 63 | WebGLBufferObj {. importc .} = object of RootObj 64 | 65 | WebGLTexture* = ref WebGLTextureObj 66 | WebGLTextureObj {. importc .} = object of RootObj 67 | 68 | WebGLProgram* = ref WebGLProgramObj 69 | WebGLProgramObj {. importc .} = object of RootObj 70 | 71 | WebGLShader* = ref WebGLShaderObj 72 | WebGLShaderObj {. importc .} = object of RootObj 73 | 74 | WebGLRenderbuffer* = ref WebGLRenderbufferObj 75 | WebGLRenderbufferObj {. importc .} = object of RootObj 76 | 77 | WebGLFramebuffer* = ref WebGLFramebufferObj 78 | WebGLFramebufferObj {. importc .} = object of RootObj 79 | 80 | #The WebGL context 81 | WebGLRenderingContext* = ref WebGLRenderingContextObj 82 | WebGLRenderingContextObj {.importc.} = object 83 | #The following properties and methods provide general information and functionality to deal with the WebGL context: 84 | 85 | canvas*: Canvas #A read-only back-reference to the HTMLCanvasElement. Might be null if it is not associated with a element. 86 | drawingBufferWidth*:int #The read-only width of the current drawing buffer. Should match the width of the canvas element associated with this context. 87 | drawingBufferHeight*:int #The read-only height of the current drawing buffer. Should match the height of the canvas element associated with this context. 88 | 89 | commit* : proc() #Pushes frames back to the original HTMLCanvasElement, if the context is not directly fixed to a specific canvas. 90 | getContextAttributes* : proc(): WebGLContextAttributes #Returns a WebGLContextAttributes object that contains the actual context parameters. Might return null, if the context is lost. 91 | isContextLost* : proc():bool #Returns true if the context is lost, otherwise returns false. 92 | 93 | #Viewing and clipping 94 | scissor* : proc(x, y:GLint, width, height: GLsizei) #Defines the scissor box. 95 | viewport* : proc(x, y:GLint, width, height: GLsizei) #Sets the viewport. 96 | 97 | #State information 98 | blendColor* : proc(red, green, blue, alpha:GLclampf) #Sets the source and destination blending factors. 99 | blendEquation* : proc(mode:GLenum) #Sets both the RGB blend equation and alpha blend equation to a single equation. 100 | blendEquationSeparate* : proc(modeRGB, modeAlpha:GLenum) #Sets the RGB blend equation and alpha blend equation separately. 101 | blendFunc* : proc(sfactor, dfactor:GLenum) #Defines which function is used for blending pixel arithmetic. 102 | blendFuncSeparate* : proc(srcRGB, dstRGB, srcAlpha, dstAlpha:GLenum) #Defines which function is used for blending pixel arithmetic for RGB and alpha components separately. 103 | clearColor* : proc(red, green, blue, alpha:GLclampf) #Specifies the color values used when clearing color buffers. 104 | clearDepth* : proc(depth:GLclampf) #Specifies the depth value used when clearing the depth buffer. 105 | clearStencil* : proc(s:GLint) #Specifies the stencil value used when clearing the stencil buffer. 106 | colorMask* : proc(red, green, blue, alpha:GLboolean) #Sets which color components to enable or to disable when drawing or rendering to a WebGLFramebuffer. 107 | cullFace* : proc(mode:GLenum) #Specifies whether or not front- and/or back-facing polygons can be culled. 108 | depthFunc* : proc(fun:GLenum) #Specifies a function that compares incoming pixel depth to the current depth buffer value. 109 | depthMask* : proc(flag:GLboolean) #Sets whether writing into the depth buffer is enabled or disabled. 110 | depthRange* : proc(zNear, zFar:GLclampf) #Specifies the depth range mapping from normalized device coordinates to window or viewport coordinates. 111 | disable* : proc(cap:GLenum) #Disables specific WebGL capabilities for this context. 112 | enable* : proc(cap:GLenum) #Enables specific WebGL capabilities for this context. 113 | frontFace* : proc(mode:GLenum) #Specifies whether polygons are front- or back-facing by setting a winding orientation. 114 | getError* : proc():GLenum #Returns error information. 115 | hint* : proc(target,mode:GLenum) #Specifies hints for certain behaviors. The interpretation of these hints depend on the implementation. 116 | isEnabled* : proc(cap:GLenum):GLboolean #Tests whether a specific WebGL capability is enabled or not for this context. 117 | lineWidth* : proc(width:GLfloat) #Sets the line width of rasterized lines. 118 | pixelStorei* : proc(pname:GLenum, param:GLint) #Specifies the pixel storage modes 119 | polygonOffset* : proc(factor, units:GLfloat) #Specifies the scale factors and units to calculate depth values. 120 | sampleCoverage* : proc(value:GLclampf, invert:GLboolean) #Specifies multi-sample coverage parameters for anti-aliasing effects. 121 | stencilFunc* : proc(fun:GLenum,rf:GLint,mask:GLuint) #Sets the both front and back function and reference value for stencil testing. 122 | stencilFuncSeparate* : proc(face, fun:GLenum, rf:GLint, mask:GLuint) #Sets the front and/or back function and reference value for stencil testing. 123 | stencilMask* : proc(mask:GLuint) #Controls enabling and disabling of both the front and back writing of individual bits in the stencil planes. 124 | stencilMaskSeparate* : proc(face:GLenum,mask:GLuint) #Controls enabling and disabling of front and/or back writing of individual bits in the stencil planes. 125 | stencilOp* : proc(fail, zfail, zpass:GLenum) #Sets both the front and back-facing stencil test actions. 126 | stencilOpSeparate* : proc(face, fail, zfail, zpass:GLenum) #Sets the front and/or back-facing stencil test actions. 127 | 128 | #Buffers 129 | bindBuffer* : proc(target:GLenum,buffer:WebGLBuffer) #Binds a WebGLBuffer object to a given target. 130 | createBuffer* : proc():WebGLBuffer #Creates a WebGLBuffer object. 131 | deleteBuffer* : proc(buffer:WebGLBuffer ) #Deletes a WebGLBuffer object. 132 | isBuffer* : proc(buffer:WEbGLBuffer):GLboolean #Returns a Boolean indicating if the passed buffer is valid. 133 | 134 | #Framebuffers 135 | bindFramebuffer* : proc(target:GLenum, framebuffer:WebGLFramebuffer) #Binds a WebGLFrameBuffer object to a given target. 136 | checkFramebufferStatus* : proc(target:GLenum):GLenum #Returns the status of the framebuffer. 137 | createFramebuffer* : proc():WebGLFramebuffer #Creates a WebGLFrameBuffer object. 138 | deleteFramebuffer* : proc(framebuffer:WebGLFramebuffer) #Deletes a WebGLFrameBuffer object. 139 | framebufferRenderbuffer* : proc(target, attachment, renderbuffertarget:GLenum, renderbuffer:WebGLRenderbuffer) #Attaches a WebGLRenderingBuffer object to a WebGLFrameBuffer object. 140 | framebufferTexture2D* : proc(target, attachment, textarget:GLenum, texture:WebGLTexture, level:Glint) #Attaches a textures image to a WebGLFrameBuffer object. 141 | isFramebuffer* : proc(framebuffer:WebGLFramebuffer):GLboolean #Returns a Boolean indicating if the passed WebGLFrameBuffer object is valid. 142 | readPixels* : proc(x, y:GLint, width, height:GLsizei, format, typ:GLenum, pixels:ArrayBufferView) #Reads a block of pixels from the WebGLFrameBuffer. 143 | 144 | #Renderbuffers 145 | bindRenderbuffer* : proc(target:Glenum, renderbuffer: WebGLRenderbuffer) #Binds a WebGLRenderBuffer object to a given target. 146 | createRenderbuffer* : proc():WebGLRenderbuffer #Creates a WebGLRenderBuffer object. 147 | deleteRenderbuffer* : proc(renderbuffer:WebGLRenderbuffer) #Deletes a WebGLRenderBuffer object. 148 | isRenderbuffer* : proc(renderbuffer:WebGLRenderbuffer): GLboolean #Returns a Boolean indicating if the passed WebGLRenderingBuffer is valid. 149 | renderbufferStorage* : proc(target, internalFormat:GLenum, width, height:GLsizei) #Creates a renderbuffer data store. 150 | 151 | #Textures 152 | bindTexture* : proc(target:GLenum, texture:WebGLTexture) #Binds a WebGLTexture object to a given target. 153 | compressedTexImage2D* : proc(target:GLenum, level:GLint, internalformat:GLenum, width, height:GLsizei, border:GLint, pixels:ArrayBufferView) #Specifies a 2D texture image in a compressed format. 154 | compressedTexSubImage2D* : proc(target:GLenum, level, xoffset,yoffset:GLint, width, height:GLsizei, format:GLint, pixels:ArrayBufferView) #Specifies a 2D texture sub-image in a compressed format. 155 | copyTexImage2D* : proc(target:GLenum, level,internalformat, x, y:GLint, width, height:GLsizei, border:GLint) #Copies a 2D texture image. 156 | copyTexSubImage2D* : proc(target:GLenum, level, xoffset, yoffset, x, y:GLint, width, height:GLsizei) #Copies a 2D texture sub-image. 157 | createTexture* : proc():WebGLTexture #Creates a WebGLTexture object. 158 | deleteTexture* : proc(texture:WebGLTexture) #Deletes a WebGLTexture object. 159 | generateMipmap* : proc(target:GLenum) #Generates a set of mipmaps for a WebGLTexture object. 160 | isTexture* : proc(texture:WebGLTexture):GLboolean #Returns a Boolean indicating if the passed WebGLTexture is valid. 161 | texParameterf* : proc(target:GLenum, pname:GLenum, param:GLfloat ) #Sets texture parameters. 162 | texParameteri* : proc(target:GLenum, pname:GLenum, param:GLenum) #Sets texture parameters. 163 | 164 | #Programs and shaders 165 | attachShader* : proc(program: WebGLProgram, shader: WebGLShader) #Attaches a WebGLShader to a WebGLProgram. 166 | bindAttribLocation* : proc(program:WebGLProgram, index:GLuint, name:cstring) #Binds a generic vertex index to a named attribute variable. 167 | compileShader* : proc(shader:WebGLShader) #Compiles a WebGLShader. 168 | createProgram* : proc():WebGLProgram #Creates a WebGLProgram. 169 | createShader* : proc(typ:GLenum):WebGLShader #Creates a WebGLShader. 170 | deleteProgram* : proc(program:WebGLProgram) #Deletes a WebGLProgram. 171 | deleteShader* : proc(shader:WebGLShader) #Deletes a WebGLShader. 172 | detachShader* : proc(program:WebGLProgram, shader:WebGLShader) #Detaches a WebGLShader. 173 | getAttachedShaders* : proc(program:WebGLProgram): seq[WebGLShader] #Returns a list of WebGLShader objects attached to a WebGLProgram. 174 | getProgramInfoLog* : proc(program:WebGLProgram):cstring #Returns the information log for a WebGLProgram object. 175 | getShaderPrecisionFormat* : proc(shaderType,precisionType: GLenum):WebGLShaderPrecisionFormat #Returns a WebGLShaderPrecisionFormat object describing the precision for the numeric format of the shader. 176 | getShaderInfoLog* : proc(shader:WebGLShader):cstring #Returns the information log for a WebGLShader object. 177 | getShaderSource* : proc(shader:WebGLShader):cstring #Returns the source code of a WebGLShader as a string. 178 | isProgram* : proc(program:WebGLProgram):GLboolean #Returns a Boolean indicating if the passed WebGLProgram is valid. 179 | isShader* : proc(shader:WebGLShader):GLboolean #Returns a Boolean indicating if the passed WebGLShader is valid. 180 | linkProgram* : proc(program:WebGLProgram) #Links the passed WebGLProgram object. 181 | shaderSource* : proc(shader:WebGLShader,source:cstring) #Sets the source code in a WebGLShader. 182 | useProgram* : proc(program:WebGLProgram) #Uses the specified WebGLProgram as part the current rendering state. 183 | validateProgram* : proc(program:WebGLProgram) #Validates a WebGLProgram. 184 | 185 | #Uniforms and attributes 186 | disableVertexAttribArray* : proc(index:GLuint) #Disables a vertex attribute array at a given position. 187 | enableVertexAttribArray* : proc(index:GLuint) #Enables a vertex attribute array at a given position. 188 | getActiveAttrib* : proc(program:WebGLProgram, index:Gluint):WebGLActiveInfo #Returns information about an active attribute variable. 189 | getActiveUniform* : proc(program:WebGLProgram, index:GLuint):WebGLActiveInfo #Returns information about an active uniform variable. 190 | getAttribLocation* : proc(program:WebGLProgram, name:cstring):GLuint #Returns the location of an attribute variable. 191 | getUniformLocation* : proc(program:WebGLProgram, name:cstring):WebGLUniformLocation #Returns the location of a uniform variable. 192 | getVertexAttribOffset* : proc(index:GLuint, pname:GLenum):GLsizeiptr #Returns the address of a given vertex attribute. 193 | uniform1f* : proc(location:WebGLUniformLocation, v0:float) #Specifies a value for a uniform variable. 194 | uniform1fv* : proc(location:WebGLUniformLocation, value:Float32Array) 195 | uniform1i* : proc(location:WebGLUniformLocation, v0:int) 196 | uniform1iv* : proc(location:WebGLUniformLocation, value:Int32Array) 197 | 198 | uniform2f* : proc(location:WebGLUniformLocation, v0, v1:float) 199 | uniform2fv* : proc(location:WebGLUniformLocation, value:FLoat32Array) 200 | uniform2i* : proc(location:WebGLUniformLocation, v0, v1:int) 201 | uniform2iv* : proc(location:WebGLUniformLocation, value:Int32Array) 202 | 203 | uniform3f* : proc(location:WebGLUniformLocation, v0, v1, v2:float) 204 | uniform3fv* : proc(location:WebGLUniformLocation, value:Float32Array) 205 | uniform3i* : proc(location:WebGLUniformLocation, v0, v1, v2:int) 206 | uniform3iv* : proc(location:WebGLUniformLocation, value:Int32Array) 207 | 208 | uniform4f* : proc(location:WebGLUniformLocation, v0, v1, v2, v3:float) 209 | uniform4fv* : proc(location:WebGLUniformLocation, value:Float32Array) 210 | uniform4i* : proc(location:WebGLUniformLocation, v0, v1, v2, v3:int) 211 | uniform4iv* : proc(location:WebGLUniformLocation, value:Int32Array) 212 | 213 | uniformMatrix2fv* : proc(location:WebGLUniformLocation, transpose:GLboolean, value: Float32Array) #Specifies a matrix value for a uniform variable. 214 | uniformMatrix3fv* : proc(location:WebGLUniformLocation, transpose:GLboolean, value: Float32Array) 215 | uniformMatrix4fv* : proc(location:WebGLUniformLocation, transpose:GLboolean, value: Float32Array) 216 | 217 | vertexAttrib1f*: proc(index:GLuint, v0:float) #Specifies a value for a generic vertex attribute. 218 | vertexAttrib2f*: proc(index:GLuint, v0, v1:float) 219 | vertexAttrib3f*: proc(index:GLuint, v0, v1, v2:float) 220 | vertexAttrib4f*: proc(index:GLuint, v0, v1, v2, v3:float) 221 | 222 | vertexAttrib1fv*: proc(index:GLuint, value:Float32Array) 223 | vertexAttrib2fv*: proc(index:GLuint, value:Float32Array) 224 | vertexAttrib3fv*: proc(index:GLuint, value:Float32Array) 225 | vertexAttrib4fv*: proc(index:GLuint, value:Float32Array) 226 | 227 | vertexAttribPointer* : proc(index:GLuint, size:GLint, typ:GLenum, normalized:GLboolean, stride:GLsizei, offset:GLintptr) #Specifies the data formats and locations of vertex attributes in a vertex attributes array. 228 | 229 | #Drawing buffers 230 | clear* : proc(mask:GLbitfield) #Clears specified buffers to preset values. 231 | drawArrays* : proc(mode:GLenum, first:GLint, count:GLsizei) #Renders primitives from array data. 232 | drawElements* : proc(mode:GLenum, count:GLsizei, typ: GLenum, offset:GLintptr) #Renders primitives from element array data. 233 | finish* : proc() #Blocks execution until all previously called commands are finished. 234 | flush* : proc() #Empties different 235 | 236 | proc getBoundingClientRect*(c:Canvas):tuple[top,bottom,left,right:float] = 237 | var 238 | t,b,lf,r:float 239 | {.emit:""" 240 | var _rect = `c`.getBoundingClientRect(); 241 | `t`= _rect.top; 242 | `b`= _rect.bottom; 243 | `l`= _rect.left; 244 | `r`= _rect.right; 245 | """} 246 | result = (t,b,lf,r) 247 | 248 | proc bufferData*(gl:WebGLRenderingContext, target:GLenum, size:GLsizeiptr, usage:GLenum) = #Updates buffer data. 249 | {. emit: "`gl`.bufferData(`target`,`size`,`usage`);" .} 250 | proc bufferData*(gl:WebGLRenderingContext, target:GLenum, data:Float32Array, usage:GLenum) = #Updates buffer data. 251 | {. emit: "`gl`.bufferData(`target`,`data`,`usage`);" .} 252 | 253 | proc bufferSubData*(gl:WebGLRenderingContext,target:GLenum, offset:GLintptr, data:auto) =#Updates buffer data starting at a passed offset. 254 | {. emit: "`gl`.bufferData(`target`,`offset`,`data`);" .} 255 | 256 | proc getParameter* (pname:GLenum):auto {.importc.} #Returns a value for the passed parameter name. 257 | 258 | proc activeTexture* (gl:WebGLRenderingContext, texture:auto) {.importc.} #Selects the active texture unit. 259 | 260 | # FIXME: getParameter does not handle 261 | # gl.DELETE_STATUS: Returns a GLboolean indicating whether or not the program is flagged for deletion. 262 | # gl.LINK_STATUS: Returns a GLboolean indicating whether or not the last link operation was successful. 263 | # gl.VALIDATE_STATUS: Returns a GLboolean indicating whether or not the last validation operation was successful 264 | # Use getStatus(Shader|Program) instead 265 | 266 | proc getProgramParameter* (gl:WebGLRenderingContext,program:WebGLProgram, pname:GLenum):GLint{.importc.} #Returns information about the program. 267 | 268 | proc getBufferParameter* (gl:WebGLRenderingContext,target, pname:GLenum): auto {.importc.} #Returns information about the buffer. 269 | 270 | proc getFramebufferAttachmentParameter* (gl:WebGLRenderingContext,target, attachment, pname:GLenum):auto {.importc.} #Returns information about the framebuffer. 271 | 272 | proc getRenderbufferParameter* (gl:WebGLRenderingContext,target, pname:GLenum):auto {.importc.} #Returns information about the framebuffer. 273 | 274 | proc getTexParameter* (gl:WebGLRenderingContext,target:GLenum,pname:GLenum): auto {.importc.} #Returns information about the texture. 275 | 276 | proc getShaderParameter* (gl:WebGLRenderingContext,shader:WebGLShader, pname:Glenum):GLint {.importc.} #Returns information about the shader. 277 | 278 | proc getUniform* (gl:WebGLRenderingContext,program:WebGLProgram, location:WebGLUniformLocation):auto {.importc.} #Returns the value of a uniform variable at a given location. 279 | 280 | proc getVertexAttrib*(gl:WebGLRenderingContext,index:GLuint, pname:GLenum):WebGLBuffer = #Returns information about a vertex attribute at a given position. 281 | {. emit: "`result`=`gl`.getVertexAttrib(`index`,`pname`);" .} 282 | #proc texImage2D*(gl:WebGLRenderingContext, target: GLenum, level: GLint, internalformat: GLint, format: GLenum, typ: GLenum, pixels:ImageData)= #TODO 283 | #{.emit: "gl.texImage2D(target, level, internalformat, format, type, pixels);".} 284 | 285 | proc texImage2D*(gl:WebGLRenderingContext, target: GLenum, level: GLint, internalformat: GLint, width, height: GLsizei, border: GLint, format: GLenum, typ: GLenum, pixels:ArrayBufferView) {.importc.} 286 | 287 | proc texImage2D*(gl:WebGLRenderingContext, target: GLenum, level: GLint, internalformat: GLenum, format: GLenum, typ: GLenum, pixels:dom.ImageElement) {.importc.} 288 | 289 | proc texImage2D*(gl:WebGLRenderingContext, target: GLenum, level: GLint, internalformat: GLint, format: GLenum, typ: GLenum, pixels:Canvas) {.importc.} 290 | 291 | proc texImage2D*(gl:WebGLRenderingContext, target: GLenum, level: GLint, internalformat: GLint, format: GLenum, typ: GLenum, pixels:dom.EmbedElement) {.importc.} #TODO 292 | 293 | #proc texSubImage2D* (target:GLenum, level, xoffset, yoffset:GLint, format, typ:GLenum, ImageData? pixels) 294 | # {. emit: "`gl`.texSubImage2D(`target`, `level`, `xoffset`, `yoffset`, `format`, `type`, `pixels`);" .} 295 | 296 | proc texSubImage2D* (target:GLenum, level, xoffset, yoffset:GLint, width, height:GLsizei, format, typ:GLenum, pixels:ArrayBufferView) {.importc.} 297 | 298 | proc texSubImage2D* (target:GLenum, level, xoffset, yoffset:GLint, format, typ:GLenum, pixels:ImageElement) {.importc.} 299 | 300 | proc texSubImage2D* (target:GLenum, level, xoffset, yoffset:GLint, format, typ:GLenum, pixels:Canvas) {.importc.} 301 | 302 | proc texSubImage2D* (target:GLenum, level, xoffset, yoffset:GLint, format, typ:GLenum, pixels:EmbedElement) {.importc.} 303 | 304 | #Helpers 305 | proc f32A* (s:openarray[float]):Float32Array = #helper 306 | {.emit: "`result` = new Float32Array(`s`);".} 307 | proc ui16A* (s:openarray[int]):UInt16Array = #helper 308 | {.emit: "`result` = new UInt16Array(`s`);".} 309 | 310 | 311 | proc log*(str:varargs[auto]) = {.emit: "console.log(`str`);".} 312 | 313 | converter toFloat32Array*(a: seq[float32]): Float32Array = {.emit: "`result` = new Float32Array(`a`);".} 314 | 315 | converter toFloat32Array*(a: seq[float]): Float32Array = {.emit: "`result` = new Float32Array(`a`);".} 316 | 317 | converter toUint32Array*(a: seq[uint]): Uint32Array = {.emit: "`result` = new Uint32Array(`a`);".} 318 | 319 | converter toInt32Array*(a: seq[int]): Int32Array = {.emit: "`result` = new Int32Array(`a`);".} 320 | 321 | 322 | proc getContextWebGL*(c: Canvas): WebGLRenderingContext = 323 | ## Get a webgl context on the given canvas. 324 | ## Example: 325 | ## .. code-block:: nim 326 | ## var canvas = dom.document.getElementById("canvas").Canvas 327 | ## var gl = getContextWebGL(canvas) 328 | 329 | {.emit: "`result` = `c`.getContext('webgl') || `c`.getContext('experimental-webgl');".} 330 | 331 | proc requestAnimationFrame*(fn:proc(time:float))= {.emit:"window.requestAnimationFrame(`fn`);".} 332 | 333 | proc getStatus*(gl:WebGLRenderingContext,what:WebglShader): GLboolean = 334 | {. emit:"`result` = `gl`.getShaderParameter(`what`, `gl`.COMPILE_STATUS);" .} 335 | proc getStatus*(gl:WebGLRenderingContext,what:WebglProgram): GLboolean = 336 | {. emit:"`result` = `gl`.getProgramParameter(`what`, `gl`.LINK_STATUS);" .} 337 | 338 | proc resize*(canvas:Canvas) = 339 | if ( 340 | canvas.width != canvas.clientwidth or 341 | canvas.height != canvas.clientheight 342 | ): 343 | canvas.width = canvas.clientwidth 344 | canvas.height = canvas.clientheight 345 | 346 | #[Deprecable?]# 347 | # a: matrix in which to store identity 348 | proc identity4* (a:auto):auto = 349 | {. emit: "`a`[0]=1;`a`[1]=0;`a`[2]=0;`a`[3]=0;`a`[4]=0;`a`[5]=1;`a`[6]=0;`a`[7]=0;`a`[8]=0;`a`[9]=0;`a`[10]=1;`a`[11]=0;`a`[12]=0;`a`[13]=0;`a`[14]=0;`a`[15]=1;`result`=`a`" .} 350 | 351 | # a: matrix to traslate,b: traslation, c: matrix translated 352 | proc traslate4* (a,b,c:auto):auto = 353 | {. emit: "var d=`b`[0],e=`b`[1];`b`=`b`[2];if(!`c`||`a`==`c`){`a`[12]=`a`[0]*d+`a`[4]*e+`a`[8]*`b`+`a`[12];`a`[13]=`a`[1]*d+`a`[5]*e+`a`[9]*`b`+`a`[13];`a`[14]=`a`[2]*d+`a`[6]*e+`a`[10]*`b`+`a`[14];`a`[15]=`a`[3]*d+`a`[7]*e+`a`[11]*`b`+`a`[15];return `a`}var g=`a`[0],f=`a`[1],h=`a`[2],i=`a`[3],j=`a`[4],k=`a`[5],l=`a`[6],o=`a`[7],m=`a`[8],n=`a`[9],p=`a`[10],r=`a`[11];`c`[0]=g;`c`[1]=f;`c`[2]=h;`c`[3]=i;`c`[4]=j;`c`[5]=k;`c`[6]=l;`c`[7]=o;`c`[8]=m;`c`[9]=n;`c`[10]=p;`c`[11]=r;`c`[12]=g*d+j*e+m*`b`+`a`[12];`c`[13]=f*d+k*e+n*`b`+`a`[13];`c`[14]=h*d+l*e+p*`b`+`a`[14];`c`[15]=i*d+o*e+r*`b`+`a`[15];`result` = `c`;" .} 354 | 355 | # a: ?? , b: scale, c: ??, d: ??, e: matrix 356 | proc perspective4* (a,b,c,d,e:auto):auto = 357 | {. emit : "function frustum(a,b,c,d,e,g,f){var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f;};`a`=`c`*Math.tan(`a`*Math.PI/360);`b`=`a`*`b`;`result` = frustum(-`b`,`b`,-`a`,`a`,`c`,`d`,`e`);" .} 358 | 359 | -------------------------------------------------------------------------------- /src/webgl.nim: -------------------------------------------------------------------------------- 1 | import dom 2 | import webgl/enums 3 | import jsffi 4 | export enums 5 | 6 | 7 | #TODO: https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Types 8 | type 9 | Canvas* = ref CanvasObj 10 | CanvasObj {.importc.} = object of dom.Element 11 | width*: int 12 | height*:int 13 | 14 | ArrayBufferView* = ref ArrayBufferViewObj 15 | ArrayBufferViewObj {. importc .} = object of RootObj 16 | 17 | Int8Array* = ref Int8ArrayObj 18 | Int8ArrayObj {. importc .} = object of ArrayBufferView 19 | 20 | Uint8Array* = ref Uint8ArrayObj 21 | Uint8ArrayObj {. importc .} = object of ArrayBufferView 22 | 23 | Uint8ClampedArray* = ref Uint8ClampedArrayObj 24 | Uint8ClampedArrayObj {. importc .} = object of ArrayBufferView 25 | 26 | Int16Array* = ref Int16ArrayObj 27 | Int16ArrayObj {. importc .} = object of ArrayBufferView 28 | 29 | Int32Array* = ref Int32ArrayObj 30 | Int32ArrayObj {. importc .} = object of ArrayBufferView 31 | 32 | Uint16Array* = ref Uint16ArrayObj 33 | Uint16ArrayObj {. importc .} = object of ArrayBufferView 34 | 35 | Float32Array* = ref Float32ArrayObj 36 | Float32ArrayObj {. importc .} = object of ArrayBufferView 37 | 38 | Float64Array* = ref Float64ArrayObj 39 | Float64ArrayObj {. importc .} = object of ArrayBufferView 40 | 41 | DataView* = ref DataViewObj 42 | DataViewObj {. importc .} = object of ArrayBufferView 43 | 44 | WebGLActiveInfoObj* {. importc .} = object 45 | name*: cstring 46 | `type`*: uint 47 | size*: int 48 | WebGLActiveInfo* = ref WebGLActiveInfoObj 49 | 50 | WebGLUniformLocation* = ref WebGLUniformLocationObj 51 | WebGLUniformLocationObj {. importc .} = object of RootObj 52 | 53 | WebGLShaderPrecisionFormat* = ref WebGLShaderPrecisionFormatObj 54 | WebGLShaderPrecisionFormatObj {. importc .} = object of RootObj 55 | 56 | WebGLContextAttributes* = ref WebGLContextAttributesObj 57 | WebGLContextAttributesObj {. importc .} = object of RootObj 58 | 59 | WebGLBuffer* = ref WebGLBufferObj 60 | WebGLBufferObj {. importc .} = object of RootObj 61 | 62 | WebGLTexture* = ref WebGLTextureObj 63 | WebGLTextureObj {. importc .} = object of RootObj 64 | 65 | WebGLProgram* = ref WebGLProgramObj 66 | WebGLProgramObj {. importc .} = object of RootObj 67 | 68 | WebGLShader* = ref WebGLShaderObj 69 | WebGLShaderObj {. importc .} = object of RootObj 70 | 71 | WebGLRenderbuffer* = ref WebGLRenderbufferObj 72 | WebGLRenderbufferObj {. importc .} = object of RootObj 73 | 74 | WebGLFramebuffer* = ref WebGLFramebufferObj 75 | WebGLFramebufferObj {. importc .} = object of RootObj 76 | 77 | #The WebGL context 78 | WebGLRenderingContext* = ref WebGLRenderingContextObj 79 | WebGLRenderingContextObj {.importc.} = object 80 | # The following properties and methods provide general information and functionality to deal with the WebGL context: 81 | 82 | canvas*: Canvas #A read-only back-reference to the HTMLCanvasElement. Might be null if it is not associated with a element. 83 | drawingBufferWidth*:int #The read-only width of the current drawing buffer. Should match the width of the canvas element associated with this context. 84 | drawingBufferHeight*:int #The read-only height of the current drawing buffer. Should match the height of the canvas element associated with this context. 85 | 86 | {.push importcpp.} 87 | proc commit*(gl:WebGLRenderingContext) 88 | ## Pushes frames back to the original HTMLCanvasElement, if the context is not directly fixed to a specific canvas. 89 | proc getContextAttributes*(gl:WebGLRenderingContext): WebGLContextAttributes 90 | ## Returns a WebGLContextAttributes object that contains the actual context parameters. Might return null, if the context is lost. 91 | proc isContextLost*(gl:WebGLRenderingContext):bool 92 | ## Returns true if the context is lost, otherwise returns false. 93 | 94 | # Viewing and clipping 95 | proc scissor*(gl:WebglRenderingContext, x, y,width, height: int) 96 | ## Defines the scissor box. 97 | proc viewport*(gl:WebglRenderingContext, x, y, width, height: int) 98 | ## Sets the viewport. 99 | 100 | # State information 101 | proc blendColor* (gl:WebglRenderingContext, red, green, blue, alpha:float32) 102 | ## Sets the source and destination blending factors. 103 | proc blendEquation* (gl:WebglRenderingContext, mode:uint) 104 | ## Sets both the RGB blend equation and alpha blend equation to a single equation. 105 | proc blendEquationSeparate* (gl:WebglRenderingContext, modeRGB, modeAlpha:uint) 106 | ## Sets the RGB blend equation and alpha blend equation separately. 107 | proc blendFunc* (gl:WebglRenderingContext, sfactor, dfactor:uint) 108 | ## Defines which function is used for blending pixel arithmetic. 109 | proc blendFuncSeparate* (gl:WebglRenderingContext, srcRGB, dstRGB, srcAlpha, dstAlpha:uint) 110 | ## Defines which function is used for blending pixel arithmetic for RGB and alpha components separately. 111 | proc clearColor* (gl:WebglRenderingContext, red, green, blue, alpha:float32) 112 | ## Specifies the color values used when clearing color buffers. 113 | proc clearDepth* (gl:WebglRenderingContext, depth:float32) 114 | ## Specifies the depth value used when clearing the depth buffer. 115 | proc clearStencil* (gl:WebglRenderingContext, s:int) 116 | ## Specifies the stencil value used when clearing the stencil buffer. 117 | proc colorMask* (gl:WebglRenderingContext, red, green, blue, alpha:bool) 118 | ## Sets which color components to enable or to disable when drawing or rendering to a WebGLFramebuffer. 119 | proc cullFace* (gl:WebglRenderingContext, mode:uint) 120 | ## Specifies whether or not front- and/or back-facing polygons can be culled. 121 | proc depthFunc* (gl:WebglRenderingContext, fun:uint) 122 | ## Specifies a function that compares incoming pixel depth to the current depth buffer value. 123 | proc depthMask* (gl:WebglRenderingContext, flag:bool) 124 | ## Sets whether writing into the depth buffer is enabled or disabled. 125 | proc depthRange* (gl:WebglRenderingContext, zNear, zFar:float) 126 | ## Specifies the depth range mapping from normalized device coordinates to window or viewport coordinates. 127 | proc disable* (gl:WebglRenderingContext, cap:uint) 128 | ## Disables specific WebGL capabilities for this context. 129 | proc enable* (gl:WebglRenderingContext, cap:uint) 130 | ## Enables specific WebGL capabilities for this context. 131 | proc frontFace* (gl:WebglRenderingContext, mode:uint) 132 | ## Specifies whether polygons are front- or back-facing by setting a winding orientation. 133 | proc getError* (gl:WebglRenderingContext):uint 134 | ## Returns error information. 135 | proc hint* (gl:WebglRenderingContext, target,mode:uint) 136 | ## Specifies hints for certain behaviors. The interpretation of these hints depend on the implementation. 137 | proc isEnabled* (gl:WebglRenderingContext, cap:uint):bool 138 | ## Tests whether a specific WebGL capability is enabled or not for this context. 139 | proc lineWidth* (gl:WebglRenderingContext, width:float32) 140 | ## Sets the line width of rasterized lines. 141 | proc pixelStorei* (gl:WebglRenderingContext, pname:uint, param:int) 142 | ## Specifies the pixel storage modes 143 | proc polygonOffset* (gl:WebglRenderingContext, factor, units:float32) 144 | ## Specifies the scale factors and units to calculate depth values. 145 | proc sampleCoverage* (gl:WebglRenderingContext, value:float32, invert:bool) 146 | ## Specifies multi-sample coverage parameters for anti-aliasing effects. 147 | proc stencilFunc* (gl:WebglRenderingContext, fun:uint,rf:int,mask:uint) 148 | ## Sets the both front and back function and reference value for stencil testing. 149 | proc stencilFuncSeparate* (gl:WebglRenderingContext, face, fun:uint, rf:int, mask:uint) 150 | ## Sets the front and/or back function and reference value for stencil testing. 151 | proc stencilMask* (gl:WebglRenderingContext, mask:uint) 152 | ## Controls enabling and disabling of both the front and back writing of individual bits in the stencil planes. 153 | proc stencilMaskSeparate* (gl:WebglRenderingContext, face:uint,mask:uint) 154 | ## Controls enabling and disabling of front and/or back writing of individual bits in the stencil planes. 155 | proc stencilOp* (gl:WebglRenderingContext, fail, zfail, zpass:uint) 156 | ## Sets both the front and back-facing stencil test actions. 157 | proc stencilOpSeparate* (gl:WebglRenderingContext, face, fail, zfail, zpass:uint) 158 | ## Sets the front and/or back-facing stencil test actions. 159 | 160 | # Buffers 161 | proc bindBuffer* (gl:WebglRenderingContext,target:uint|BufferEnum,buffer:WebGLBuffer) 162 | ## Binds a WebGLBuffer object to a given target. 163 | proc createBuffer* (gl:WebglRenderingContext):WebGLBuffer 164 | ## Creates a WebGLBuffer object. 165 | proc deleteBuffer* (gl:WebglRenderingContext,buffer:WebGLBuffer ) 166 | ## Deletes a WebGLBuffer object. 167 | proc isBuffer* (gl:WebglRenderingContext,buffer:WEbGLBuffer):bool 168 | ## Returns a Boolean indicating if the passed buffer is valid. 169 | 170 | # Framebuffers 171 | proc bindFramebuffer* (gl:WebglRenderingContext,target:uint, framebuffer:WebGLFramebuffer) 172 | ## Binds a WebGLFrameBuffer object to a given target. 173 | proc checkFramebufferStatus* (gl:WebglRenderingContext,target:uint):uint 174 | ## Returns the status of the framebuffer. 175 | proc createFramebuffer* (gl:WebglRenderingContext):WebGLFramebuffer 176 | ## Creates a WebGLFrameBuffer object. 177 | proc deleteFramebuffer* (gl:WebglRenderingContext,framebuffer:WebGLFramebuffer) 178 | ## Deletes a WebGLFrameBuffer object. 179 | proc framebufferRenderbuffer* (gl:WebglRenderingContext,target, attachment, renderbuffertarget:uint, renderbuffer:WebGLRenderbuffer) 180 | ## Attaches a WebGLRenderingBuffer object to a WebGLFrameBuffer object. 181 | proc framebufferTexture2D* (gl:WebglRenderingContext,target, attachment, textarget:uint, texture:WebGLTexture, level:int) 182 | ## Attaches a textures image to a WebGLFrameBuffer object. 183 | proc isFramebuffer* (gl:WebglRenderingContext,framebuffer:WebGLFramebuffer):bool 184 | ## Returns a Boolean indicating if the passed WebGLFrameBuffer object is valid. 185 | proc readPixels* (gl:WebglRenderingContext,x, y:int, width, height:int, format, typ:uint, pixels:ArrayBufferView) 186 | ## Reads a block of pixels from the WebGLFrameBuffer. 187 | 188 | #Renderbuffers 189 | proc bindRenderbuffer* (gl:WebglRenderingContext,target:uint, renderbuffer: WebGLRenderbuffer) 190 | ## Binds a WebGLRenderBuffer object to a given target. 191 | proc createRenderbuffer* (gl:WebglRenderingContext):WebGLRenderbuffer 192 | ## Creates a WebGLRenderBuffer object. 193 | proc deleteRenderbuffer* (gl:WebglRenderingContext,renderbuffer:WebGLRenderbuffer) 194 | ## Deletes a WebGLRenderBuffer object. 195 | proc isRenderbuffer* (gl:WebglRenderingContext,renderbuffer:WebGLRenderbuffer): bool 196 | ## Returns a Boolean indicating if the passed WebGLRenderingBuffer is valid. 197 | proc renderbufferStorage* (gl:WebglRenderingContext,target, internalFormat:uint, width, height:int) 198 | ## Creates a renderbuffer data store. 199 | 200 | #Textures 201 | proc bindTexture* (gl:WebglRenderingContext,target:uint, texture:WebGLTexture) 202 | ## Binds a WebGLTexture object to a given target. 203 | proc compressedTexImage2D* (gl:WebglRenderingContext,target:uint, level:int, internalformat:uint, width, height:int, border:int, pixels:ArrayBufferView) 204 | ## Specifies a 2D texture image in a compressed format. 205 | proc compressedTexSubImage2D* (gl:WebglRenderingContext,target:uint, level, xoffset,yoffset:int, width, height:int, format:int, pixels:ArrayBufferView) 206 | ## Specifies a 2D texture sub-image in a compressed format. 207 | proc copyTexImage2D* (gl:WebglRenderingContext,target:uint, level,internalformat, x, y:int, width, height:int, border:int) 208 | ## Copies a 2D texture image. 209 | proc copyTexSubImage2D* (gl:WebglRenderingContext,target:uint, level, xoffset, yoffset, x, y:int, width, height:int) 210 | ## Copies a 2D texture sub-image. 211 | proc createTexture* (gl:WebglRenderingContext):WebGLTexture 212 | ## Creates a WebGLTexture object. 213 | proc deleteTexture* (gl:WebglRenderingContext,texture:WebGLTexture) 214 | ## Deletes a WebGLTexture object. 215 | proc generateMipmap* (gl:WebglRenderingContext,target:uint) 216 | ## Generates a set of mipmaps for a WebGLTexture object. 217 | proc isTexture* (gl:WebglRenderingContext,texture:WebGLTexture):bool 218 | ## Returns a Boolean indicating if the passed WebGLTexture is valid. 219 | proc texParameterf* (gl:WebglRenderingContext,target:uint, pname:uint, param:float32 ) 220 | ## Sets texture parameters. 221 | proc texParameteri* (gl:WebglRenderingContext,target:uint, pname:uint, param:uint) 222 | ## Sets texture parameters. 223 | 224 | #Programs and shaders 225 | proc attachShader* (gl:WebglRenderingContext,program: WebGLProgram, shader: WebGLShader) 226 | ## Attaches a WebGLShader to a WebGLProgram. 227 | proc bindAttribLocation* (gl:WebglRenderingContext,program:WebGLProgram, index:uint, name:cstring) 228 | ## Binds a generic vertex index to a named attribute variable. 229 | proc compileShader* (gl:WebglRenderingContext,shader:WebGLShader) 230 | ## Compiles a WebGLShader. 231 | proc createProgram* (gl:WebglRenderingContext):WebGLProgram 232 | ## Creates a WebGLProgram. 233 | proc createShader* (gl:WebglRenderingContext,typ:uint|ShaderEnum):WebGLShader 234 | ## Creates a WebGLShader. 235 | proc deleteProgram* (gl:WebglRenderingContext,program:WebGLProgram) 236 | ## Deletes a WebGLProgram. 237 | proc deleteShader* (gl:WebglRenderingContext,shader:WebGLShader) 238 | ## Deletes a WebGLShader. 239 | proc detachShader* (gl:WebglRenderingContext,program:WebGLProgram, shader:WebGLShader) 240 | ## Detaches a WebGLShader. 241 | proc getAttachedShaders* (gl:WebglRenderingContext,program:WebGLProgram): seq[WebGLShader] 242 | ## Returns a list of WebGLShader objects attached to a WebGLProgram. 243 | proc getProgramInfoLog* (gl:WebglRenderingContext,program:WebGLProgram):cstring 244 | ## Returns the information log for a WebGLProgram object. 245 | proc getShaderPrecisionFormat* (gl:WebglRenderingContext,shaderType,precisionType: uint):WebGLShaderPrecisionFormat 246 | ## Returns a WebGLShaderPrecisionFormat object describing the precision for the numeric format of the shader. 247 | proc getShaderInfoLog* (gl:WebglRenderingContext,shader:WebGLShader):cstring 248 | ## Returns the information log for a WebGLShader object. 249 | proc getShaderSource* (gl:WebglRenderingContext,shader:WebGLShader):cstring 250 | ## Returns the source code of a WebGLShader as a string. 251 | proc isProgram* (gl:WebglRenderingContext,program:WebGLProgram):bool 252 | ## Returns a Boolean indicating if the passed WebGLProgram is valid. 253 | proc isShader* (gl:WebglRenderingContext,shader:WebGLShader):bool 254 | ## Returns a Boolean indicating if the passed WebGLShader is valid. 255 | proc linkProgram* (gl:WebglRenderingContext,program:WebGLProgram) 256 | ## Links the passed WebGLProgram object. 257 | proc shaderSource* (gl:WebglRenderingContext,shader:WebGLShader,source:cstring) 258 | ## Sets the source code in a WebGLShader. 259 | proc useProgram* (gl:WebglRenderingContext,program:WebGLProgram) 260 | ## Uses the specified WebGLProgram as part the current rendering state. 261 | proc validateProgram* (gl:WebglRenderingContext,program:WebGLProgram) 262 | ## Validates a WebGLProgram. 263 | 264 | # Uniforms and attributes 265 | proc disableVertexAttribArray* (gl:WebglRenderingContext,index:uint) 266 | ## Disables a vertex attribute array at a given position. 267 | proc enableVertexAttribArray* (gl:WebglRenderingContext,index:uint) 268 | ## Enables a vertex attribute array at a given position. 269 | proc getActiveAttrib* (gl:WebglRenderingContext,program:WebGLProgram, index:uint):WebGLActiveInfo 270 | ## Returns information about an active attribute variable. 271 | proc getActiveUniform* (gl:WebglRenderingContext,program:WebGLProgram, index:uint):WebGLActiveInfo 272 | ## Returns information about an active uniform variable. 273 | proc getAttribLocationUnchecked* (gl:WebglRenderingContext,program:WebGLProgram, name:cstring):int {. importcpp: "#.getAttribLocation(@)".} 274 | proc getAttribLocation* (gl:WebglRenderingContext,program:WebGLProgram, name:cstring):uint {. importcpp: "#.getAttribLocationChecked(@)".}= 275 | let unchckresult = gl.getAttribLocationUnchecked(program,name) 276 | doassert(unchckresult>=0, "getAttribLocation:" & $name & "not found") 277 | result = unchckresult.uint 278 | 279 | ## Returns the location of an attribute variable. 280 | proc getUniformLocation* (gl:WebglRenderingContext,program:WebGLProgram, name:cstring):WebGLUniformLocation 281 | ## Returns the location of a uniform variable. 282 | proc getVertexAttribOffset* (gl:WebglRenderingContext,index:uint, pname:uint):int64 283 | ## Returns the address of a given vertex attribute. 284 | proc uniform1f* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0:float32) 285 | ## Specifies a value for a uniform variable. 286 | proc uniform1fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Float32Array) 287 | proc uniform1i* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0:int) 288 | proc uniform1iv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Int32Array) 289 | 290 | proc uniform2f* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1:float32) 291 | proc uniform2fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Float32Array) 292 | proc uniform2i* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1:int) 293 | proc uniform2iv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Int32Array) 294 | 295 | proc uniform3f* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1, v2:float32) 296 | proc uniform3fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Float32Array) 297 | proc uniform3i* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1, v2:int) 298 | proc uniform3iv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Int32Array) 299 | 300 | proc uniform4f* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1, v2, v3:float32) 301 | proc uniform4fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Float32Array) 302 | proc uniform4i* (gl:WebglRenderingContext,location:WebGLUniformLocation, v0, v1, v2, v3:int) 303 | proc uniform4iv* (gl:WebglRenderingContext,location:WebGLUniformLocation, value:Int32Array) 304 | 305 | proc uniformMatrix2fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, transpose:bool, value: Float32Array) 306 | ## Specifies a matrix value for a uniform variable. 307 | proc uniformMatrix3fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, transpose:bool, value: Float32Array) 308 | proc uniformMatrix4fv* (gl:WebglRenderingContext,location:WebGLUniformLocation, transpose:bool, value: Float32Array) 309 | 310 | proc vertexAttrib1f*(gl:WebglRenderingContext,index:uint, v0:float32) 311 | ##Specifies a value for a generic vertex attribute. 312 | proc vertexAttrib2f*(gl:WebglRenderingContext,index:uint, v0, v1:float32) 313 | proc vertexAttrib3f*(gl:WebglRenderingContext,index:uint, v0, v1, v2:float32) 314 | proc vertexAttrib4f*(gl:WebglRenderingContext,index:uint, v0, v1, v2, v3:float32) 315 | 316 | proc vertexAttrib1fv*(gl:WebglRenderingContext,index:uint, value:Float32Array) 317 | proc vertexAttrib2fv*(gl:WebglRenderingContext,index:uint, value:Float32Array) 318 | proc vertexAttrib3fv*(gl:WebglRenderingContext,index:uint, value:Float32Array) 319 | proc vertexAttrib4fv*(gl:WebglRenderingContext,index:uint, value:Float32Array) 320 | 321 | proc vertexAttribPointer* (gl:WebglRenderingContext,index:uint, size:int, typ:uint|DataType, 322 | normalized:bool, stride:int, offset:int64) 323 | ## Specifies the data formats and locations of vertex attributes in a vertex attributes array. 324 | 325 | #Drawing buffers 326 | proc clear* (gl:WebglRenderingContext,mask:uint|BufferBit) 327 | ## Clears specified buffers to preset values. 328 | proc drawArrays* (gl:WebglRenderingContext,mode:uint|PrimitiveMode, first:int, count:int) 329 | ## Renders primitives from array data. 330 | proc drawElements* (gl:WebglRenderingContext,mode:uint|PrimitiveMode, count:int, typ: uint|DataType, offset:int64) 331 | ## Renders primitives from element array data. 332 | proc finish* (gl:WebglRenderingContext) 333 | ## Blocks execution until all previously called commands are finished. 334 | proc flush* (gl:WebglRenderingContext) 335 | ## Empties different 336 | 337 | proc bufferData*(gl:WebGLRenderingContext, target:uint|BufferEnum, size:int64, usage:uint|BufferEnum) 338 | ## Updates buffer data. 339 | 340 | proc bufferData*(gl:WebGLRenderingContext, target:uint|BufferEnum, data:Int32Array|Uint16Array|Float32Array, usage:uint|BufferEnum) 341 | ## Updates buffer data. 342 | 343 | proc bufferSubData*(gl:WebGLRenderingContext,target:uint, offset:int64, data:auto) 344 | ## Updates buffer data starting at a passed offset. 345 | 346 | proc getParameter* (gl:WebGLRenderingContext,pname:uint):auto 347 | ## Returns a value for the passed parameter name. 348 | 349 | proc activeTexture* (gl:WebGLRenderingContext, texture:auto) 350 | ## Selects the active texture unit. 351 | 352 | # FIXME: getParameter does not handle 353 | # gl.DELETE_STATUS: Returns a bool indicating whether or not the program is flagged for deletion. 354 | # gl.LINK_STATUS: Returns a bool indicating whether or not the last link operation was successful. 355 | # gl.VALIDATE_STATUS: Returns a bool indicating whether or not the last validation operation was successful 356 | # Use getStatus(Shader|Program) instead 357 | 358 | proc getProgramParameter* (gl:WebGLRenderingContext,program:WebGLProgram, pname:uint):int 359 | ## Returns information about the program. 360 | 361 | proc getBufferParameter* (gl:WebGLRenderingContext,target, pname:uint): auto 362 | ## Returns information about the buffer. 363 | 364 | proc getFramebufferAttachmentParameter* (gl:WebGLRenderingContext,target, attachment, pname:uint):auto 365 | ## Returns information about the framebuffer. 366 | 367 | proc getRenderbufferParameter* (gl:WebGLRenderingContext,target, pname:uint):auto 368 | ## Returns information about the framebuffer. 369 | 370 | proc getTexParameter* (gl:WebGLRenderingContext,target:uint,pname:uint): auto 371 | ## Returns information about the texture. 372 | 373 | proc getShaderParameter* (gl:WebGLRenderingContext,shader:WebGLShader, pname:uint):int 374 | ## Returns information about the shader. 375 | 376 | proc getUniform* (gl:WebGLRenderingContext,program:WebGLProgram, location:WebGLUniformLocation):auto 377 | ## Returns the value of a uniform variable at a given location. 378 | 379 | proc getVertexAttrib*(gl:WebGLRenderingContext,index:uint, pname:uint):WebGLBuffer 380 | ## Returns information about a vertex attribute at a given position. 381 | 382 | #proc texImage2D*(gl:WebGLRenderingContext, target: uint, level: int, internalformat: int, format: uint, typ: uint, pixels:ImageData)= #TODO 383 | #{.emit: "gl.texImage2D(target, level, internalformat, format, type, pixels);".} 384 | 385 | proc texImage2D*(gl:WebGLRenderingContext, target: uint, level: int, internalformat: int, width, height: int, border: int, format: uint, typ: uint, pixels:ArrayBufferView) 386 | 387 | proc texImage2D*(gl:WebGLRenderingContext, target: uint, level: int, internalformat: uint, format: uint, typ: uint, pixels:dom.ImageElement) 388 | 389 | proc texImage2D*(gl:WebGLRenderingContext, target: uint, level: int, internalformat: int, format: uint, typ: uint, pixels:Canvas) 390 | 391 | proc texImage2D*(gl:WebGLRenderingContext, target: uint, level: int, internalformat: int, format: uint, typ: uint, pixels:dom.EmbedElement) #TODO 392 | 393 | #proc texSubImage2D* (target:uint, level, xoffset, yoffset:int, format, typ:uint, ImageData? pixels) 394 | # {. emit: "`gl`.texSubImage2D(`target`, `level`, `xoffset`, `yoffset`, `format`, `type`, `pixels`);" .} 395 | 396 | proc texSubImage2D* (target:uint, level, xoffset, yoffset:int, width, height:int, format, typ:uint, pixels:ArrayBufferView) 397 | 398 | proc texSubImage2D* (target:uint, level, xoffset, yoffset:int, format, typ:uint, pixels:ImageElement) 399 | 400 | proc texSubImage2D* (target:uint, level, xoffset, yoffset:int, format, typ:uint, pixels:Canvas) 401 | 402 | proc texSubImage2D* (target:uint, level, xoffset, yoffset:int, format, typ:uint, pixels:EmbedElement) 403 | 404 | proc getContext*(c: Canvas,kind:cstring): WebGLRenderingContext 405 | ## Get the specified context on the given canvas. 406 | ## Does NOT account for eg. ``experimental-webgl`` vs ``webgl`` etc. 407 | ## See ``getContextWebgl`` for that 408 | ## Example: 409 | ## .. code-block:: nim 410 | ## var canvas = dom.document.getElementById("canvas").Canvas 411 | ## var gl = canvas.getContext("webgl") 412 | ## 413 | 414 | {. pop .} 415 | 416 | proc getContextWebgl*(c:Canvas) : WebGLRenderingContext = 417 | ## Get a webgl context on the given canvas. 418 | ## Tries ``webgl`` first, then ``experimental-webgl`` 419 | ## Example: 420 | ## .. code-block:: nim 421 | ## var canvas = dom.document.getElementById("canvas").Canvas 422 | ## var gl = canvas.getContextWebgl() 423 | ## 424 | result = c.getContext("webgl") 425 | if result.isNil: result = c.getContext("experimental-webgl") 426 | assert(not result.isNil) 427 | 428 | proc getBoundingClientRect*(c:Canvas):tuple[top,bottom,left,right:float] = 429 | var 430 | t,b,lf,r:float 431 | {.emit:""" 432 | var _rect = `c`.getBoundingClientRect(); 433 | `t`= _rect.top; 434 | `b`= _rect.bottom; 435 | `l`= _rect.left; 436 | `r`= _rect.right; 437 | """} 438 | result = (t,b,lf,r) 439 | 440 | template log*(str:varargs[untyped]) {.deprecated.} = console.log(str) 441 | 442 | proc requestAnimationFrame*(fn:proc(time:float))= {.emit:"window.requestAnimationFrame(`fn`);".} 443 | 444 | proc getStatus*(gl:WebGLRenderingContext,what:WebglShader): bool = 445 | {. emit:"`result` = `gl`.getShaderParameter(`what`, `gl`.COMPILE_STATUS);" .} 446 | proc getStatus*(gl:WebGLRenderingContext,what:WebglProgram): bool = 447 | {. emit:"`result` = `gl`.getProgramParameter(`what`, `gl`.LINK_STATUS);" .} 448 | 449 | proc resize*(canvas:Canvas) = 450 | if ( 451 | canvas.width != canvas.clientwidth or 452 | canvas.height != canvas.clientheight 453 | ): 454 | canvas.width = canvas.clientwidth 455 | canvas.height = canvas.clientheight 456 | 457 | converter toF32*(v:float):float32 = v.float32 458 | converter toF32A*[N:int](v:array[N,float32]) :Float32Array {.importcpp: "new Float32Array(#)".} # might be a lie 459 | converter toF32A*(v:seq[float32]) :Float32Array {.importcpp: "new Float32Array(#)".} # might be a lie 460 | converter toF32A*[N:int](v:array[N,float]) :Float32Array {.importcpp: "new Float32Array(#)".} # might be a lie 461 | converter toF32A*(v:seq[float]) :Float32Array {.importcpp: "new Float32Array(#)".} # might be a lie 462 | 463 | converter toUI16*(v:int):uint16 = v.uint16 464 | converter toUI16A*[N:int](v:array[N,uint16]) :Uint16Array {.importcpp: "new Uint16Array(#)".} # might be a lie 465 | converter toUI16A*(v:seq[uint16]) :Uint16Array {.importcpp: "new Uint16Array(#)".} # might be a lie 466 | 467 | converter toI32A*[N:int](v:array[N,int]) :Int32Array {.importcpp: "new Int32Array(#)".} # might be a lie 468 | converter toI32A*(v:seq[int]) :Int32Array {.importcpp: "new Int32Array(#)".} # might be a lie 469 | 470 | 471 | #[Deprecable?]# 472 | # a: matrix in which to store identity 473 | proc identity4* (a:auto):auto = 474 | {. emit: "`a`[0]=1;`a`[1]=0;`a`[2]=0;`a`[3]=0;`a`[4]=0;`a`[5]=1;`a`[6]=0;`a`[7]=0;`a`[8]=0;`a`[9]=0;`a`[10]=1;`a`[11]=0;`a`[12]=0;`a`[13]=0;`a`[14]=0;`a`[15]=1;`result`=`a`" .} 475 | 476 | # a: matrix to traslate,b: traslation, c: matrix translated 477 | proc traslate4* (a,b,c:auto):auto = 478 | {. emit: "var d=`b`[0],e=`b`[1];`b`=`b`[2];if(!`c`||`a`==`c`){`a`[12]=`a`[0]*d+`a`[4]*e+`a`[8]*`b`+`a`[12];`a`[13]=`a`[1]*d+`a`[5]*e+`a`[9]*`b`+`a`[13];`a`[14]=`a`[2]*d+`a`[6]*e+`a`[10]*`b`+`a`[14];`a`[15]=`a`[3]*d+`a`[7]*e+`a`[11]*`b`+`a`[15];return `a`}var g=`a`[0],f=`a`[1],h=`a`[2],i=`a`[3],j=`a`[4],k=`a`[5],l=`a`[6],o=`a`[7],m=`a`[8],n=`a`[9],p=`a`[10],r=`a`[11];`c`[0]=g;`c`[1]=f;`c`[2]=h;`c`[3]=i;`c`[4]=j;`c`[5]=k;`c`[6]=l;`c`[7]=o;`c`[8]=m;`c`[9]=n;`c`[10]=p;`c`[11]=r;`c`[12]=g*d+j*e+m*`b`+`a`[12];`c`[13]=f*d+k*e+n*`b`+`a`[13];`c`[14]=h*d+l*e+p*`b`+`a`[14];`c`[15]=i*d+o*e+r*`b`+`a`[15];`result` = `c`;" .} 479 | 480 | # a: ?? , b: scale, c: ??, d: ??, e: matrix 481 | proc perspective4* (a,b,c,d,e:auto):auto = 482 | {. emit : "function frustum(a,b,c,d,e,g,f){var h=b-a,i=d-c,j=g-e;f[0]=e*2/h;f[1]=0;f[2]=0;f[3]=0;f[4]=0;f[5]=e*2/i;f[6]=0;f[7]=0;f[8]=(b+a)/h;f[9]=(d+c)/i;f[10]=-(g+e)/j;f[11]=-1;f[12]=0;f[13]=0;f[14]=-(g*e*2)/j;f[15]=0;return f;};`a`=`c`*Math.tan(`a`*Math.PI/360);`b`=`a`*`b`;`result` = frustum(-`b`,`b`,-`a`,`a`,`c`,`d`,`e`);" .} 483 | 484 | -------------------------------------------------------------------------------- /src/webgl/enums.nim: -------------------------------------------------------------------------------- 1 | type BufferBit* = enum 2 | bbDepth = 0x00000100 # Passed to clear to clear the current depth buffer. 3 | bbStencil = 0x00000400 # Passed to clear to clear the current stencil buffer. 4 | bbColor = 0x00004000 # Passed to clear to clear the current color buffer. 5 | 6 | type PrimitiveMode* = enum 7 | ## Constants passed to WebGLRenderingContext.drawElements() or 8 | ## WebGLRenderingContext.drawArrays() to specify what kind of primitive to render. 9 | pmPoints = 0x0000 # Passed to drawElements or drawArrays to draw single points. 10 | pmLines = 0x0001 # Passed to drawElements or drawArrays to draw lines. Each vertex connects to the one after it. 11 | pmLineLoop = 0x0002 # Passed to drawElements or drawArrays to draw lines. Each set of two vertices is treated as a separate line segment. 12 | pmLineStrip = 0x0003 # Passed to drawElements or drawArrays to draw a connected group of line segments from the first vertex to the last. 13 | pmTriangles = 0x0004 # Passed to drawElements or drawArrays to draw triangles. Each set of three vertices creates a separate triangle. 14 | pmTriangleStrip = 0x0005 # Passed to drawElements or drawArrays to draw a connected group of triangles. 15 | pmTriangleFan = 0x0006 # Passed to drawElements or drawArrays to draw a connected group of triangles. Each vertex connects to the previous and the first vertex in the fan. 16 | 17 | type BlendingMode* = enum 18 | #Constants passed to WebGLRenderingContext.blendFunc() or WebGLRenderingContext.blendFuncSeparate() to specify the blending mode (for both, RBG and alpha, or separately). 19 | bmZERO = 0 # Passed to blendFunc or blendFuncSeparate to turn off a component. 20 | bmONE = 1 # Passed to blendFunc or blendFuncSeparate to turn on a component. 21 | bmSRC_COLOR = 0x0300 # Passed to blendFunc or blendFuncSeparate to multiply a component by the source elements color. 22 | bmONE_MINUS_SRC_COLOR = 0x0301 # Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source elements color. 23 | bmSRC_ALPHA = 0x0302 # Passed to blendFunc or blendFuncSeparate to multiply a component by the source's alpha. 24 | bmONE_MINUS_SRC_ALPHA = 0x0303 # Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the source's alpha. 25 | bmDST_ALPHA = 0x0304 # Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's alpha. 26 | bmONE_MINUS_DST_ALPHA = 0x0305 # Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's alpha. 27 | bmDST_COLOR = 0x0306 # Passed to blendFunc or blendFuncSeparate to multiply a component by the destination's color. 28 | bmONE_MINUS_DST_COLOR = 0x0307 # Passed to blendFunc or blendFuncSeparate to multiply a component by one minus the destination's color. 29 | bmSRC_ALPHA_SATURATE = 0x0308 # Passed to blendFunc or blendFuncSeparate to multiply a component by the minimum of source's alpha or one minus the destination's alpha. 30 | bmCONSTANT_COLOR = 0x8001 # Passed to blendFunc or blendFuncSeparate to specify a constant color blend function. 31 | bmONE_MINUS_CONSTANT_COLOR = 0x8002 # Passed to blendFunc or blendFuncSeparate to specify one minus a constant color blend function. 32 | bmCONSTANT_ALPHA = 0x8003 # Passed to blendFunc or blendFuncSeparate to specify a constant alpha blend function. 33 | bmONE_MINUS_CONSTANT_ALPHA = 0x8004 # Passed to blendFunc or blendFuncSeparate to specify one minus a constant alpha blend function. 34 | 35 | type BlendingEq* = enum 36 | #Constants passed to WebGLRenderingContext.blendEquation() or WebGLRenderingContext.blendEquationSeparate() to control how the blending is calculated (for both, RBG and alpha, or separately). 37 | beFUNC_ADD = 0x8006 # Passed to blendEquation or blendEquationSeparate to set an addition blend function. 38 | beFUNC_SUBSTRACT = 0x800A # Passed to blendEquation or blendEquationSeparate to specify a subtraction blend function (source - destination). 39 | beFUNC_REVERSE_SUBTRACT = 0x800B # Passed to blendEquation or blendEquationSeparate to specify a reverse subtraction blend function (destination - source). 40 | 41 | type BufferEnum* = enum 42 | #Constants passed to WebGLRenderingContext.bufferData(), WebGLRenderingContext.bufferSubData(), WebGLRenderingContext.bindBuffer(), or WebGLRenderingContext.getBufferParameter(). 43 | beBUFFER_SIZE = 0x8764 # Passed to getBufferParameter to get a buffer's size. 44 | beBUFFER_USAGE = 0x8765 # Passed to getBufferParameter to get the hint for the buffer passed in when it was created. 45 | beARRAY_BUFFER = 0x8892 # Passed to bindBuffer or bufferData to specify the type of buffer being used. 46 | beELEMENT_ARRAY_BUFFER = 0x8893 # Passed to bindBuffer or bufferData to specify the type of buffer being used. 47 | beSTREAM_DRAW = 0x88E0 # Passed to bufferData as a hint about whether the contents of the buffer are likely to not be used often. 48 | beSTATIC_DRAW = 0x88E4 # Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and not change often. 49 | beDYNAMIC_DRAW = 0x88E8 # Passed to bufferData as a hint about whether the contents of the buffer are likely to be used often and change often. 50 | 51 | type DataType* = enum 52 | dtBYTE = 0x1400 # 53 | dtUNSIGNED_BYTE = 0x1401 # 54 | dtSHORT = 0x1402 # 55 | dtUNSIGNED_SHORT = 0x1403 # 56 | dtINT = 0x1404 # 57 | dtUNSIGNED_INT = 0x1405 # 58 | dtFLOAT = 0x1406 # 59 | 60 | type ShaderEnum* = enum 61 | #Constants passed to WebGLRenderingContext.createShader() or WebGLRenderingContext.getShaderParameter() 62 | seMAX_VERTEX_ATTRIBS = 0x8869 # 63 | seMAX_TEXTURE_IMAGE_UNITS = 0x8872 # Implementation dependent number of maximum texture units. At least 8. 64 | seFRAGMENT_SHADER = 0x8B30 # Passed to createShader to define a fragment shader. 65 | seVERTEX_SHADER = 0x8B31 # Passed to createShader to define a vertex shader 66 | seMAX_VERTEX_TEXTURE_IMAGE_UNITS = 0x8B4C # 67 | seMAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D # 68 | seSHADER_TYPE = 0x8B4F # 69 | seDELETE_STATUS = 0x8B80 # Passed to getShaderParamter to determine if a shader was deleted via deleteShader. Returns true if it was, false otherwise. 70 | seCOMPILE_STATUS = 0x8B81 # Passed to getShaderParamter to get the status of the compilation. Returns false if the shader was not compiled. You can then query getShaderInfoLog to find the exact error 71 | seLINK_STATUS = 0x8B82 # Passed to getProgramParameter after calling linkProgram to determine if a program was linked correctly. Returns false if there were errors. Use getProgramInfoLog to find the exact error. 72 | seVALIDATE_STATUS = 0x8B83 # Passed to getProgramParameter after calling validateProgram to determine if it is valid. Returns false if errors were found. 73 | seATTACHED_SHADERS = 0x8B85 # Passed to getProgramParameter after calling attachShader to determine if the shader was attached correctly. Returns false if errors occurred. 74 | seACTIVE_UNIFORMS = 0x8B86 # Passed to getProgramParamter to get the number of uniforms active in a program. 75 | seACTIVE_ATTRIBUTES = 0x8B89 # Passed to getProgramParameter to get the number of attributes active in a program. 76 | seSHADING_LANGUAGE_VERSION = 0x8B8C # 77 | seCURRENT_PROGRAM = 0x8B8D # 78 | seMAX_VERTEX_UNIFORM_VECTORS = 0x8DFB # 79 | seMAX_VARYING_VECTORS = 0x8DFC # 80 | seMAX_FRAGMENT_UNIFORM_VECTORS = 0x8DFD # 81 | -------------------------------------------------------------------------------- /templates/templ_entry.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Example: $title 18 | 23 | 24 | 34 | 35 | 36 | 49 |
50 |
51 | 52 |

Example: $title

53 | 54 | Your browser doesn't appear to support the 55 | <canvas> element. 56 | 57 | 58 |
59 |
60 |

Code

61 |
$code
62 | 
63 |
64 |
65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /templates/templ_index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | $project 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 32 |
33 |

Examples for $project

34 |
    35 | $li 36 |
37 |

AutoDocs for $project

38 |

Mozilla Documentation

39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /templates/templ_li.html: -------------------------------------------------------------------------------- 1 |
  • 2 | Example: $title 3 |
  • -------------------------------------------------------------------------------- /webgl.nimble: -------------------------------------------------------------------------------- 1 | # Package 2 | version = "0.2.2" 3 | author = "stisa" 4 | description = "Basic wrapper for WebGL." 5 | license = "MIT" 6 | 7 | srcDir = "src" 8 | 9 | skipDirs = @["oldwrapper","templates"] 10 | 11 | # Deps 12 | requires: "nim >= 0.16.1" 13 | 14 | import ospaths 15 | 16 | task docs, "Build docs folder - examples and documentation": 17 | #exec("nim js -o:docs/ex1.js examples/ex1.nim") 18 | #exec("nim js -o:docs/ex2.js examples/ex2.nim") 19 | #exec("nim js -o:docs/ex3.js examples/ex3.nim") 20 | mkdir "docs"/"webgl" 21 | mkdir "docs"/"examples" 22 | exec("exampler") # custom utility to generate example pages 23 | exec("nim doc2 -o:" & "docs"/"webgl.html " & "src"/"webgl.nim") 24 | exec("nim doc2 -o:" & "docs"/"webgl"/"enums.html " & "src"/"webgl"/"enums.nim") 25 | exec("nim doc2 -o:" & "docs"/"webgl"/"consts.html " & "src"/"webgl"/"consts.nim") 26 | withdir "examples": 27 | for file in listfiles("."): 28 | if splitfile(file).ext == ".nim": 29 | exec "nim js -o:" & ".."/"docs"/"examples"/file.changefileext("js") & " " & file 30 | --------------------------------------------------------------------------------