├── .gitignore ├── README.markdown ├── api.js ├── package.json ├── src ├── arch_wrapper.h ├── v8_typed_array.cc ├── v8_typed_array.h └── webgl.cc ├── webgl.js └── wscript /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | .lock-wscript 3 | npm-debug.log 4 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | More to come, for now see 2 | -------------------------------------------------------------------------------- /api.js: -------------------------------------------------------------------------------- 1 | var gl = require('./build/default/node-webgl.node'); 2 | 3 | var GLenum = "number"; 4 | var GLint = "number"; 5 | var GLuint = "number"; 6 | var GLfloat = "number"; 7 | var GLclampf = "number"; 8 | var GLsizeiptr = "number"; 9 | var GLintptr = "number"; 10 | var GLbitfield = "number"; 11 | var GLboolean = "boolean"; 12 | var GLsizei = "number"; 13 | var DOMString = "string"; 14 | var any = "string"; 15 | function WebGLUniformLocation(_) { this._ = _; } 16 | function WebGLBuffer(_) { this._ = _; } 17 | function WebGLProgram(_) { this._ = _; } 18 | function WebGLShader(_) { this._ = _; } 19 | function WebGLFramebuffer(_) { this._ = _; } 20 | function WebGLRenderbuffer(_) { this._ = _; } 21 | function WebGLTexture(_) { this._ = _; } 22 | function WebGLActiveInfo(_) { this._ = _; } 23 | 24 | 25 | // These needs to be implemented 26 | function ArrayBufferView() {} 27 | function FloatArray() {} 28 | function ImageData() {} 29 | function Int32Array() {} 30 | 31 | console.log("// Generated by " + __filename + "\n"); 32 | process.stdout.write("var gl = module.exports = require('./build/default/node-webgl.node');\n\n"); 33 | 34 | 35 | var funcs = []; 36 | // Wrap raw C++ functions in nice JavaScript type checking and arguments 37 | // Also wrap raw integer's in proper webgl objects 38 | 39 | forEach({ 40 | activeTexture: { args: { texture: GLenum }}, 41 | attachShader: { args: { program: WebGLProgram, shader: WebGLShader }}, 42 | bindAttribLocation: { args: { program: WebGLProgram, index: GLuint, name: DOMString }}, 43 | bindBuffer: { args: { target: GLenum, buffer: WebGLBuffer }}, 44 | bindFramebuffer: { args: { target: GLenum, framebuffer: WebGLFramebuffer }}, 45 | bindRenderbuffer: { args: { target: GLenum, renderbuffer: WebGLRenderbuffer }}, 46 | bindTexture: { args: { target: GLenum, texture: WebGLTexture }}, 47 | blendColor: { args: { red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf }}, 48 | blendEquation: { args: { mode: GLenum }}, 49 | blendEquationSeparate: { args: { modeRGB: GLenum, modeAlpha: GLenum }}, 50 | blendFunc: { args: { sfactor: GLenum, dfactor: GLenum }}, 51 | blendFuncSeparate: { args: { srcRGB: GLenum, dstRGB: GLenum, srcAlpha: GLenum, dstAlpha: GLenum }}, 52 | 53 | // bufferData: { args: { target: GLenum, size: GLsizeiptr, usage: GLenum }}, 54 | // bufferData: { args: { target: GLenum, data: ArrayBufferView, usage: GLenum }}, 55 | bufferData: { args: { target: GLenum, data: ArrayBuffer, usage: GLenum }}, 56 | // bufferSubData: { args: { target: GLenum, offset: GLintptr, data: ArrayBufferView }}, 57 | bufferSubData: { args: { target: GLenum, offset: GLintptr, data: ArrayBuffer }}, 58 | 59 | checkFramebufferStatus: { result: GLenum, args: { target: GLenum }}, 60 | clear: { args: { mask: GLbitfield }}, 61 | clearColor: { args: { red: GLclampf, green: GLclampf, blue: GLclampf, alpha: GLclampf }}, 62 | clearDepth: { args: { depth: GLclampf }}, 63 | clearStencil: { args: { s : GLint }}, 64 | colorMask: { args: { red: GLboolean, green: GLboolean, blue: GLboolean, alpha: GLboolean }}, 65 | compileShader: { args: { shader: WebGLShader }}, 66 | 67 | 68 | copyTexImage2D: { args: { target: GLenum, level: GLint, internalformat: GLenum, 69 | x: GLint, y: GLint, width: GLsizei, height: GLsizei, border: GLint }}, 70 | copyTexSubImage2D: { args: { target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, 71 | x: GLint, y: GLint, width: GLsizei, height: GLsizei }}, 72 | 73 | createBuffer: { result: WebGLBuffer, args: {} }, 74 | createFramebuffer: { result: WebGLFramebuffer, args: {} }, 75 | createProgram: { result: WebGLProgram, args: {} }, 76 | createRenderbuffer: { result: WebGLRenderbuffer, args: {} }, 77 | createShader: { result: WebGLShader, args: { type: GLenum }}, 78 | createTexture: { result: WebGLTexture, args: {} }, 79 | 80 | cullFace: { args: { mode: GLenum }}, 81 | 82 | deleteBuffer: { args: { buffer: WebGLBuffer }}, 83 | deleteFramebuffer: { args: { framebuffer: WebGLFramebuffer }}, 84 | deleteProgram: { args: { program: WebGLProgram }}, 85 | deleteRenderbuffer: { args: { renderbuffer: WebGLRenderbuffer }}, 86 | deleteShader: { args: { shader: WebGLShader }}, 87 | deleteTexture: { args: { texture: WebGLTexture }}, 88 | 89 | depthFunc: { args: { func: GLenum }}, 90 | depthMask: { args: { flag: GLboolean }}, 91 | depthRange: { args: { zNear: GLclampf, zFar: GLclampf }}, 92 | detachShader: { args: { program: WebGLProgram, shader: WebGLShader }}, 93 | disable: { args: { cap: GLenum }}, 94 | disableVertexAttribArray: { args: { index: GLuint }}, 95 | drawArrays: { args: { mode: GLenum, first: GLint, count: GLsizei }}, 96 | drawElements: { args: { mode: GLenum, count: GLsizei, type: GLenum, offset: GLintptr }}, 97 | 98 | enable: { args: { cap: GLenum }}, 99 | enableVertexAttribArray: { args: { index: GLuint }}, 100 | finish: { args: {}}, 101 | flush: { args: {}}, 102 | framebufferRenderbuffer: { args: { target: GLenum, attachment: GLenum, 103 | renderbuffertarget: GLenum, renderbuffer: WebGLRenderbuffer }}, 104 | framebufferTexture2D: { args: { target: GLenum, attachment: GLenum, textarget: GLenum, 105 | texture: WebGLTexture, level: GLint }}, 106 | frontFace: { args: { mode: GLenum }}, 107 | 108 | generateMipmap: { args: { target: GLenum }}, 109 | 110 | getActiveAttrib: { result: WebGLActiveInfo, args: { program: WebGLProgram, index: GLuint }}, 111 | getActiveUniform: { result: WebGLActiveInfo, args: { program: WebGLProgram, index: GLuint }}, 112 | getAttachedShaders: { result: [WebGLShader], args: { program: WebGLProgram }}, 113 | 114 | getAttribLocation: { result: GLint, args: { program: WebGLProgram, name: DOMString }}, 115 | 116 | getParameter: { result: any, args: { pname: GLenum }}, 117 | getBufferParameter: { result: any, args: { target: GLenum, pname: GLenum }}, 118 | 119 | getError: { result: GLenum, args: {}}, 120 | 121 | getFramebufferAttachmentParameter: { result: any, args: { target: GLenum, attachment: GLenum, pname: GLenum }}, 122 | getProgramParameter: { result: any, args: { program: WebGLProgram, pname: GLenum }}, 123 | getProgramInfoLog: { result: DOMString, args: { program: WebGLProgram }}, 124 | getRenderbufferParameter: { result: any, args: { target: GLenum, pname: GLenum }}, 125 | getShaderParameter: { result: any, args: { shader: WebGLShader, pname: GLenum }}, 126 | getShaderInfoLog: { result: DOMString, args: { shader: WebGLShader }}, 127 | 128 | getShaderSource: { result: DOMString, args: { shader: WebGLShader }}, 129 | 130 | getTexParameter: { result: any, args: { target: GLenum, pname: GLenum }}, 131 | 132 | getUniform: { result: any, args: { program: WebGLProgram, location: WebGLUniformLocation }}, 133 | 134 | getUniformLocation: { result: WebGLUniformLocation, args: { program: WebGLProgram, name: DOMString }}, 135 | 136 | getVertexAttrib: { result: any, args: { index: GLuint, pname: GLenum }}, 137 | 138 | getVertexAttribOffset: { result: GLsizeiptr, args: { index: GLuint, pname: GLenum }}, 139 | 140 | hint: { args: { target: GLenum, mode: GLenum }}, 141 | isBuffer: { result: GLboolean, args: { buffer: WebGLBuffer }}, 142 | isEnabled: { result: GLboolean, args: { cap: GLenum }}, 143 | isFramebuffer: { result: GLboolean, args: { framebuffer: WebGLFramebuffer }}, 144 | isProgram: { result: GLboolean, args: { program: WebGLProgram }}, 145 | isRenderbuffer: { result: GLboolean, args: { renderbuffer: WebGLRenderbuffer }}, 146 | isShader: { result: GLboolean, args: { shader: WebGLShader }}, 147 | isTexture: { result: GLboolean, args: { texture: WebGLTexture }}, 148 | lineWidth: { args: { width: GLfloat }}, 149 | linkProgram: { args: { program: WebGLProgram }}, 150 | pixelStorei: { args: { pname: GLenum, param: GLint }}, 151 | polygonOffset: { args: { factor: GLfloat, units: GLfloat }}, 152 | 153 | readPixels: { args: { x: GLint, y: GLint, width: GLsizei, height: GLsizei, 154 | format: GLenum, type: GLenum, pixels: ArrayBufferView }}, 155 | 156 | renderbufferStorage: { args: { target: GLenum, internalformat: GLenum, width: GLsizei, height: GLsizei }}, 157 | sampleCoverage: { args: { value: GLclampf, invert: GLboolean }}, 158 | scissor: { args: { x: GLint, y: GLint, width: GLsizei, height: GLsizei }}, 159 | 160 | shaderSource: { args: { shader: WebGLShader, source: DOMString }}, 161 | 162 | stencilFunc: { args: { func: GLenum, ref: GLint, mask: GLuint }}, 163 | stencilFuncSeparate: { args: { face: GLenum, func: GLenum, ref: GLint, mask: GLuint }}, 164 | stencilMask: { args: { mask: GLuint }}, 165 | stencilMaskSeparate: { args: { face: GLenum, mask: GLuint }}, 166 | stencilOp: { args: { fail: GLenum, zfail: GLenum, zpass: GLenum }}, 167 | stencilOpSeparate: { args: { face: GLenum, fail: GLenum, zfail: GLenum, zpass: GLenum }}, 168 | 169 | 170 | texImage2D: { args: { target: GLenum, level: GLint, internalformat: GLenum, 171 | width: GLsizei, height: GLsizei, border: GLint, format: GLenum, 172 | type: GLenum, pixels: ArrayBufferView }}, 173 | // texImage2D: { args: { target: GLenum, level: GLint, internalformat: GLenum, 174 | // format: GLenum, type: GLenum, pixels: ImageData }}, 175 | 176 | 177 | texParameterf: { args: { target: GLenum, pname: GLenum, param: GLfloat }}, 178 | texParameteri: { args: { target: GLenum, pname: GLenum, param: GLint }}, 179 | 180 | texSubImage2D: { args: { target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, 181 | width: GLsizei, height: GLsizei, format: GLenum, 182 | type: GLenum, pixels: ArrayBufferView }}, 183 | // texSubImage2D: { args: { target: GLenum, level: GLint, xoffset: GLint, yoffset: GLint, 184 | // format: GLenum, type: GLenum, pixels: ImageData }}, 185 | 186 | 187 | uniform1f: { args: { location: WebGLUniformLocation, x: GLfloat }}, 188 | uniform1fv: { args: { location: WebGLUniformLocation, v: FloatArray }}, 189 | uniform1i: { args: { location: WebGLUniformLocation, x: GLint }}, 190 | uniform1iv: { args: { location: WebGLUniformLocation, v: Int32Array }}, 191 | uniform2f: { args: { location: WebGLUniformLocation, x: GLfloat, y: GLfloat }}, 192 | uniform2fv: { args: { location: WebGLUniformLocation, v: FloatArray }}, 193 | uniform2i: { args: { location: WebGLUniformLocation, x: GLint, y: GLint }}, 194 | uniform2iv: { args: { location: WebGLUniformLocation, v: Int32Array }}, 195 | uniform3f: { args: { location: WebGLUniformLocation, x: GLfloat, y: GLfloat, z: GLfloat }}, 196 | uniform3fv: { args: { location: WebGLUniformLocation, v: FloatArray }}, 197 | uniform3i: { args: { location: WebGLUniformLocation, x: GLint, y: GLint, z: GLint }}, 198 | uniform3iv: { args: { location: WebGLUniformLocation, x: Int32Array }}, 199 | uniform4f: { args: { location: WebGLUniformLocation, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat }}, 200 | uniform4fv: { args: { location: WebGLUniformLocation, v: FloatArray }}, 201 | uniform4i: { args: { location: WebGLUniformLocation, x: GLint, y: GLint, z: GLint, w: GLint }}, 202 | uniform4iv: { args: { location: WebGLUniformLocation, x: Int32Array }}, 203 | 204 | uniformMatrix2fv: { args: { location: WebGLUniformLocation, transpose: GLboolean, value: FloatArray }}, 205 | uniformMatrix3fv: { args: { location: WebGLUniformLocation, transpose: GLboolean, value: FloatArray }}, 206 | uniformMatrix4fv: { args: { location: WebGLUniformLocation, transpose: GLboolean, value: FloatArray }}, 207 | 208 | useProgram: { args: { program: WebGLProgram }}, 209 | validateProgram: { args: { program: WebGLProgram }}, 210 | 211 | vertexAttrib1f: { args: { indx: GLuint, x: GLfloat }}, 212 | vertexAttrib1fv: { args: { indx: GLuint, values: FloatArray }}, 213 | vertexAttrib2f: { args: { indx: GLuint, x: GLfloat, y: GLfloat }}, 214 | vertexAttrib2fv: { args: { indx: GLuint, values: FloatArray }}, 215 | vertexAttrib3f: { args: { indx: GLuint, x: GLfloat, y: GLfloat, z: GLfloat }}, 216 | vertexAttrib3fv: { args: { indx: GLuint, values: FloatArray }}, 217 | vertexAttrib4f: { args: { indx: GLuint, x: GLfloat, y: GLfloat, z: GLfloat, w: GLfloat }}, 218 | vertexAttrib4fv: { args: { indx: GLuint, values: FloatArray }}, 219 | vertexAttribPointer: { args: { indx: GLuint, size: GLint, type: GLenum, 220 | normalized: GLboolean, stride: GLsizei, offset: GLintptr }}, 221 | 222 | viewport: { args: { x: GLint, y: GLint, width: GLsizei, height: GLsizei }}, 223 | 224 | }, function (api, name) { 225 | var sig = []; 226 | var args = []; 227 | var cargs = []; 228 | var fullArgs = []; 229 | var check = ["arguments.length === " + Object.keys(api.args).length]; 230 | forEach(api.args, function (type, arg) { 231 | args.push(arg); 232 | if (typeof type === 'string') { 233 | sig.push(type); 234 | check.push('typeof ' + arg + ' === "' + type + '"'); 235 | cargs.push(arg); 236 | fullArgs.push(type + " " + arg); 237 | } else { 238 | sig.push(type.name); 239 | fullArgs.push(type.name + " " + arg); 240 | if (type.name.substr(0, 5) === "WebGL") { 241 | cargs.push(arg + " ? " + arg + "._ : 0"); 242 | check.push("(" + arg + " === null || " + arg + " instanceof " + type.name + ")"); 243 | } else { 244 | cargs.push(arg); 245 | check.push("typeof " + arg + ' === "object"'); 246 | } 247 | if (funcs.indexOf(type) < 0) { funcs.push(type); } 248 | } 249 | }); 250 | args = args.join(", "); 251 | cargs = cargs.join(", "); 252 | fullArgs = fullArgs.join(", "); 253 | sig = sig.join(", "); 254 | check = check.join(" && "); 255 | if ((typeof api.result === 'function') && funcs.indexOf(api.result) < 0) { funcs.push(api.result); } 256 | 257 | process.stdout.write( 258 | "\nvar _" + name + " = gl." + name + ";\n" + 259 | "gl." + name + " = function " + name + "(" + args + ") {\n" + 260 | (check ? " if (!(" + check + ")) {\n" + 261 | " throw new TypeError('Expected " + name + "(" + fullArgs + ")');\n" + 262 | " }\n" : "") + 263 | (typeof api.result === 'function' ? 264 | " return new " + api.result.name + "(_" + name + "(" + cargs + "));\n" : 265 | " return _" + name + "(" + cargs + ");\n") + 266 | "}\n" 267 | ); 268 | 269 | }); 270 | 271 | process.stdout.write("\n////////////////////////////////////////////////////////////////////////////////\n\n"); 272 | 273 | funcs.forEach(function (func) { 274 | if (!func.length) return; 275 | console.log(func.toString()); 276 | }); 277 | 278 | 279 | //////////////////////////////////////////////////////////////////////////////// 280 | 281 | function forEach(object, callback, thisp) { 282 | var keys = Object.keys(object); 283 | for (var i = 0, l = keys.length; i < l; i++) { 284 | var key = keys[i]; 285 | var value = object[key]; 286 | if (arguments.length > 2) callback.call(thisp, value, key, keys); 287 | else callback(value, key, keys); 288 | } 289 | } 290 | 291 | 292 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Tim Caswell (http://creationix.com/)", 3 | "name": "webgl", 4 | "description": "webGL bindings for node", 5 | "version": "0.0.7", 6 | "main": "webgl.js", 7 | "engines": { 8 | "node": ">=0.4.0" 9 | }, 10 | "dependencies": {}, 11 | "devDependencies": {} 12 | } 13 | -------------------------------------------------------------------------------- /src/arch_wrapper.h: -------------------------------------------------------------------------------- 1 | #ifndef _INCLIDE_ARCH_WRAPPER_ 2 | #define _INCLUDE_ARCH_WRAPPER_ 3 | #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED 4 | #include 5 | #include 6 | typedef double GLclampd; 7 | #else 8 | #ifdef __APPLE__ 9 | #include 10 | #include 11 | #define glClearDepthf glClearDepth 12 | #else 13 | #ifdef _WIN32 14 | #include 15 | #else 16 | #include 17 | #endif 18 | #endif 19 | #endif 20 | #endif -------------------------------------------------------------------------------- /src/v8_typed_array.cc: -------------------------------------------------------------------------------- 1 | // V8 Typed Array implementation. 2 | // (c) Dean McNamee , 2011. 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to 6 | // deal in the Software without restriction, including without limitation the 7 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | // sell copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | // IN THE SOFTWARE. 21 | 22 | #include // calloc, etc 23 | #include // memmove 24 | 25 | #include 26 | 27 | #include "v8_typed_array.h" 28 | 29 | namespace { 30 | 31 | v8::Handle ThrowError(const char* msg) { 32 | return v8::ThrowException(v8::Exception::Error(v8::String::New(msg))); 33 | } 34 | 35 | v8::Handle ThrowTypeError(const char* msg) { 36 | return v8::ThrowException(v8::Exception::TypeError(v8::String::New(msg))); 37 | } 38 | 39 | v8::Handle ThrowRangeError(const char* msg) { 40 | return v8::ThrowException(v8::Exception::RangeError(v8::String::New(msg))); 41 | } 42 | 43 | struct BatchedMethods { 44 | const char* name; 45 | v8::Handle (*func)(const v8::Arguments& args); 46 | }; 47 | 48 | class ArrayBuffer { 49 | public: 50 | static v8::Persistent GetTemplate() { 51 | static v8::Persistent ft_cache; 52 | if (!ft_cache.IsEmpty()) 53 | return ft_cache; 54 | 55 | v8::HandleScope scope; 56 | ft_cache = v8::Persistent::New( 57 | v8::FunctionTemplate::New(&ArrayBuffer::V8New)); 58 | ft_cache->SetClassName(v8::String::New("ArrayBuffer")); 59 | v8::Local instance = ft_cache->InstanceTemplate(); 60 | instance->SetInternalFieldCount(1); // Buffer. 61 | 62 | return ft_cache; 63 | } 64 | 65 | static bool HasInstance(v8::Handle value) { 66 | return GetTemplate()->HasInstance(value); 67 | } 68 | 69 | private: 70 | static void WeakCallback(v8::Persistent value, void* data) { 71 | v8::Object* obj = v8::Object::Cast(*value); 72 | 73 | void* ptr = obj->GetIndexedPropertiesExternalArrayData(); 74 | int element_size = v8_typed_array::SizeOfArrayElementForType( 75 | obj->GetIndexedPropertiesExternalArrayDataType()); 76 | int size = 77 | obj->GetIndexedPropertiesExternalArrayDataLength() * element_size; 78 | 79 | v8::V8::AdjustAmountOfExternalAllocatedMemory(-size); 80 | 81 | value.ClearWeak(); 82 | value.Dispose(); 83 | 84 | free(ptr); 85 | } 86 | 87 | static v8::Handle V8New(const v8::Arguments& args) { 88 | if (!args.IsConstructCall()) 89 | return ThrowTypeError("Constructor cannot be called as a function."); 90 | 91 | // To match Chrome, we allow "new ArrayBuffer()". 92 | // if (args.Length() != 1) 93 | // return ThrowError("Wrong number of arguments."); 94 | 95 | if (args[0]->Int32Value() < 0) { 96 | return ThrowRangeError("ArrayBufferView size is not a small enough " 97 | "positive integer."); 98 | } 99 | 100 | size_t num_bytes = args[0]->Uint32Value(); 101 | void* buf = calloc(num_bytes, 1); 102 | if (!buf) 103 | return ThrowError("Unable to allocate ArrayBuffer."); 104 | 105 | args.This()->SetPointerInInternalField(0, buf); 106 | 107 | args.This()->Set(v8::String::New("byteLength"), 108 | v8::Integer::NewFromUnsigned(num_bytes), 109 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 110 | 111 | // NOTE(deanm): This is not in the spec, you shouldn't be able to index 112 | // the ArrayBuffer. However, it currently simplifies some handling in our 113 | // implementation, so we make ArrayView operator[] act like an Uint8Array. 114 | // , This allows DataView to work with both ArrayBuffers and TypedArrays. 115 | args.This()->SetIndexedPropertiesToExternalArrayData( 116 | buf, v8::kExternalUnsignedByteArray, num_bytes); 117 | 118 | v8::V8::AdjustAmountOfExternalAllocatedMemory(num_bytes); 119 | 120 | v8::Persistent persistent = 121 | v8::Persistent::New(args.This()); 122 | persistent.MakeWeak(NULL, &ArrayBuffer::WeakCallback); 123 | 124 | return args.This(); 125 | } 126 | }; 127 | 128 | static bool checkAlignment(unsigned int val, unsigned int bytes) { 129 | return (val & (bytes - 1)) == 0; // Handles bytes == 0. 130 | } 131 | 132 | template 133 | class TypedArray { 134 | public: 135 | static v8::Persistent GetTemplate() { 136 | static v8::Persistent ft_cache; 137 | if (!ft_cache.IsEmpty()) 138 | return ft_cache; 139 | 140 | v8::HandleScope scope; 141 | ft_cache = v8::Persistent::New( 142 | v8::FunctionTemplate::New(&TypedArray::V8New)); 143 | v8::Local instance = ft_cache->InstanceTemplate(); 144 | instance->SetInternalFieldCount(0); 145 | 146 | ft_cache->Set(v8::String::New("BYTES_PER_ELEMENT"), 147 | v8::Uint32::New(TBytes), v8::ReadOnly); 148 | instance->Set(v8::String::New("BYTES_PER_ELEMENT"), 149 | v8::Uint32::New(TBytes), v8::ReadOnly); 150 | 151 | v8::Local default_signature = v8::Signature::New(ft_cache); 152 | 153 | static BatchedMethods methods[] = { 154 | { "set", &TypedArray::set }, 155 | { "subarray", &TypedArray::subarray }, 156 | }; 157 | 158 | for (size_t i = 0; i < sizeof(methods) / sizeof(*methods); ++i) { 159 | instance->Set(v8::String::New(methods[i].name), 160 | v8::FunctionTemplate::New(methods[i].func, 161 | v8::Handle(), 162 | default_signature)); 163 | } 164 | 165 | return ft_cache; 166 | } 167 | 168 | static bool HasInstance(v8::Handle value) { 169 | return GetTemplate()->HasInstance(value); 170 | } 171 | 172 | private: 173 | static v8::Handle V8New(const v8::Arguments& args) { 174 | if (!args.IsConstructCall()) 175 | return ThrowTypeError("Constructor cannot be called as a function."); 176 | 177 | // To match Chrome, we allow "new Float32Array()". 178 | // if (args.Length() != 1) 179 | // return ThrowError("Wrong number of arguments."); 180 | 181 | v8::Local buffer; 182 | unsigned int length = 0; 183 | unsigned int byte_offset = 0; 184 | 185 | if (ArrayBuffer::HasInstance(args[0])) { // ArrayBuffer constructor. 186 | buffer = v8::Local::Cast(args[0]); 187 | unsigned int buflen = 188 | buffer->GetIndexedPropertiesExternalArrayDataLength(); 189 | 190 | if (args[1]->Int32Value() < 0) 191 | return ThrowRangeError("Byte offset out of range."); 192 | byte_offset = args[1]->Uint32Value(); 193 | 194 | if (!checkAlignment(byte_offset, TBytes)) 195 | return ThrowRangeError("Byte offset is not aligned."); 196 | 197 | if (args.Length() > 2) { 198 | if (args[2]->Int32Value() < 0) 199 | return ThrowRangeError("Length out of range."); 200 | length = args[2]->Uint32Value(); 201 | } else { 202 | if (buflen < byte_offset || 203 | !checkAlignment(buflen - byte_offset, TBytes)) { 204 | return ThrowRangeError("Byte offset / length is not aligned."); 205 | } 206 | length = (buflen - byte_offset) / TBytes; 207 | } 208 | 209 | // NOTE(deanm): Sloppy integer overflow checks. 210 | if (byte_offset > buflen || byte_offset + length > buflen || 211 | byte_offset + length * TBytes > buflen) { 212 | return ThrowRangeError("Length is out of range."); 213 | } 214 | 215 | // TODO(deanm): Error check. 216 | void* buf = buffer->GetPointerFromInternalField(0); 217 | args.This()->SetIndexedPropertiesToExternalArrayData( 218 | reinterpret_cast(buf) + byte_offset, TEAType, length); 219 | } else if (args[0]->IsObject()) { // TypedArray / type[] constructor. 220 | v8::Local obj = v8::Local::Cast(args[0]); 221 | length = obj->Get(v8::String::New("length"))->Uint32Value(); 222 | 223 | // TODO(deanm): Handle integer overflow. 224 | v8::Handle argv[1] = { 225 | v8::Integer::NewFromUnsigned(length * TBytes)}; 226 | buffer = ArrayBuffer::GetTemplate()-> 227 | GetFunction()->NewInstance(1, argv); 228 | 229 | void* buf = buffer->GetPointerFromInternalField(0); 230 | args.This()->SetIndexedPropertiesToExternalArrayData( 231 | buf, TEAType, length); 232 | // TODO(deanm): check for failure. 233 | for (uint32_t i = 0; i < length; ++i) { 234 | // Use the v8 setter to deal with typing. Maybe slow? 235 | args.This()->Set(i, obj->Get(i)); 236 | } 237 | } else { // length constructor. 238 | // Try to match Chrome, Float32Array(""), Float32Array(true/false) is 239 | // okay, but Float32Array(null) throws a TypeError and 240 | // Float32Array(undefined) throw a RangeError. 241 | if (args.Length() > 0 && (args[0]->IsUndefined() || args[0]->IsNull())) 242 | return ThrowTypeError("Type error"); 243 | 244 | if (args[0]->Int32Value() < 0) { 245 | return ThrowRangeError("ArrayBufferView size is not a small enough " 246 | "positive integer."); 247 | } 248 | 249 | length = args[0]->Uint32Value(); 250 | // TODO(deanm): Handle integer overflow. 251 | v8::Handle argv[1] = { 252 | v8::Integer::NewFromUnsigned(length * TBytes)}; 253 | 254 | buffer = ArrayBuffer::GetTemplate()-> 255 | GetFunction()->NewInstance(1, argv); 256 | void* buf = buffer->GetPointerFromInternalField(0); 257 | 258 | args.This()->SetIndexedPropertiesToExternalArrayData( 259 | buf, TEAType, length); 260 | // TODO(deanm): check for failure. 261 | } 262 | 263 | args.This()->Set(v8::String::New("buffer"), 264 | buffer, 265 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 266 | args.This()->Set(v8::String::New("length"), 267 | v8::Integer::NewFromUnsigned(length), 268 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 269 | args.This()->Set(v8::String::New("byteOffset"), 270 | v8::Integer::NewFromUnsigned(byte_offset), 271 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 272 | args.This()->Set(v8::String::New("byteLength"), 273 | v8::Integer::NewFromUnsigned(length * TBytes), 274 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 275 | 276 | return args.This(); 277 | } 278 | 279 | static v8::Handle set(const v8::Arguments& args) { 280 | if (args.Length() < 1) 281 | return ThrowError("Wrong number of arguments."); 282 | 283 | if (!args[0]->IsObject()) 284 | return ThrowTypeError("Type error."); 285 | 286 | v8::Handle obj = v8::Handle::Cast(args[0]); 287 | 288 | if (TypedArray::HasInstance(obj)) { // ArrayBufferView. 289 | v8::Handle src_buffer = v8::Handle::Cast( 290 | obj->Get(v8::String::New("buffer"))); 291 | v8::Handle dst_buffer = v8::Handle::Cast( 292 | args.This()->Get(v8::String::New("buffer"))); 293 | 294 | if (args[1]->Int32Value() < 0) 295 | return ThrowRangeError("Offset may not be negative."); 296 | 297 | unsigned int offset = args[1]->Uint32Value(); 298 | unsigned int src_length = 299 | obj->Get(v8::String::New("length"))->Uint32Value(); 300 | unsigned int dst_length = 301 | args.This()->Get(v8::String::New("length"))->Uint32Value(); 302 | if (offset > dst_length) 303 | return ThrowRangeError("Offset out of range."); 304 | 305 | if (src_length > dst_length - offset) 306 | return ThrowRangeError("Offset/length out of range."); 307 | 308 | // We don't want to get the buffer pointer, because that means we'll have 309 | // to just do the calculations for byteOffset / byteLength again. 310 | // Instead just use the pointer on the external array data. 311 | void* src_ptr = obj->GetIndexedPropertiesExternalArrayData(); 312 | void* dst_ptr = args.This()->GetIndexedPropertiesExternalArrayData(); 313 | 314 | // From the spec: 315 | // If the input array is a TypedArray, the two arrays may use the same 316 | // underlying ArrayBuffer. In this situation, setting the values takes 317 | // place as if all the data is first copied into a temporary buffer that 318 | // does not overlap either of the arrays, and then the data from the 319 | // temporary buffer is copied into the current array. 320 | memmove(reinterpret_cast(dst_ptr) + offset * TBytes, 321 | src_ptr, src_length * TBytes); 322 | } else { // type[] 323 | if (args[1]->Int32Value() < 0) 324 | return ThrowRangeError("Offset may not be negative."); 325 | 326 | unsigned int src_length = 327 | obj->Get(v8::String::New("length"))->Uint32Value(); 328 | unsigned int dst_length = 329 | args.This()->Get(v8::String::New("length"))->Uint32Value(); 330 | unsigned int offset = args[1]->Uint32Value(); 331 | 332 | if (offset > dst_length) 333 | return ThrowRangeError("Offset out of range."); 334 | 335 | if (src_length > dst_length - offset) 336 | return ThrowRangeError("Offset/length out of range."); 337 | 338 | for (uint32_t i = 0; i < src_length; ++i) { 339 | // Use the v8 setter to deal with typing. Maybe slow? 340 | args.This()->Set(i + offset, obj->Get(i)); 341 | } 342 | } 343 | 344 | return v8::Undefined(); 345 | } 346 | 347 | static v8::Handle subarray(const v8::Arguments& args) { 348 | // TODO(deanm): The unsigned / signed type mixing makes me super nervous. 349 | 350 | unsigned int length = 351 | args.This()->Get(v8::String::New("length"))->Uint32Value(); 352 | int begin = args[0]->Int32Value(); 353 | int end = length; 354 | if (args.Length() > 1) 355 | end = args[1]->Int32Value(); 356 | 357 | if (begin < 0) begin = length + begin; 358 | if (begin < 0) begin = 0; 359 | if (begin > length) begin = length; 360 | 361 | if (end < 0) end = length + end; 362 | if (end < 0) end = 0; 363 | if (end > length) end = length; 364 | 365 | if (begin > end) begin = end; 366 | 367 | int byte_offset = begin * TBytes + 368 | args.This()->Get(v8::String::New("byteOffset"))->Uint32Value(); 369 | 370 | // Call through to the ArrayBuffer, byteOffset, length constructor. 371 | v8::Handle argv[] = { 372 | args.This()->Get(v8::String::New("buffer")), 373 | v8::Integer::New(byte_offset), 374 | v8::Integer::New(end - begin)}; 375 | return TypedArray::GetTemplate()-> 376 | GetFunction()->NewInstance(3, argv); 377 | } 378 | }; 379 | 380 | class Int8Array : public TypedArray<1, v8::kExternalByteArray> { }; 381 | class Uint8Array : public TypedArray<1, v8::kExternalUnsignedByteArray> { }; 382 | class Int16Array : public TypedArray<2, v8::kExternalShortArray> { }; 383 | class Uint16Array : public TypedArray<2, v8::kExternalUnsignedShortArray> { }; 384 | class Int32Array : public TypedArray<4, v8::kExternalIntArray> { }; 385 | class Uint32Array : public TypedArray<4, v8::kExternalUnsignedIntArray> { }; 386 | class Float32Array : public TypedArray<4, v8::kExternalFloatArray> { }; 387 | 388 | template 389 | v8::Handle cTypeToValue(T) { 390 | return v8::Undefined(); 391 | } 392 | 393 | template <> 394 | v8::Handle cTypeToValue(unsigned char val) { 395 | return v8::Integer::NewFromUnsigned(val); 396 | } 397 | 398 | template <> 399 | v8::Handle cTypeToValue(char val) { 400 | return v8::Integer::New(val); 401 | } 402 | 403 | template <> 404 | v8::Handle cTypeToValue(unsigned short val) { 405 | return v8::Integer::NewFromUnsigned(val); 406 | } 407 | 408 | template <> 409 | v8::Handle cTypeToValue(short val) { 410 | return v8::Integer::New(val); 411 | } 412 | 413 | template <> 414 | v8::Handle cTypeToValue(unsigned int val) { 415 | return v8::Integer::NewFromUnsigned(val); 416 | } 417 | 418 | template <> 419 | v8::Handle cTypeToValue(int val) { 420 | return v8::Integer::New(val); 421 | } 422 | 423 | template <> 424 | v8::Handle cTypeToValue(float val) { 425 | return v8::Number::New(val); 426 | } 427 | 428 | template <> 429 | v8::Handle cTypeToValue(double val) { 430 | return v8::Number::New(val); 431 | } 432 | 433 | 434 | template 435 | T valueToCType(v8::Handle value) { 436 | return 0; 437 | } 438 | 439 | template <> 440 | unsigned char valueToCType(v8::Handle value) { 441 | return value->Uint32Value(); 442 | } 443 | 444 | template <> 445 | char valueToCType(v8::Handle value) { 446 | return value->Int32Value(); 447 | } 448 | 449 | template <> 450 | unsigned short valueToCType(v8::Handle value) { 451 | return value->Uint32Value(); 452 | } 453 | 454 | template <> 455 | short valueToCType(v8::Handle value) { 456 | return value->Int32Value(); 457 | } 458 | 459 | template <> 460 | unsigned int valueToCType(v8::Handle value) { 461 | return value->Uint32Value(); 462 | } 463 | 464 | template <> 465 | int valueToCType(v8::Handle value) { 466 | return value->Int32Value(); 467 | } 468 | 469 | template <> 470 | float valueToCType(v8::Handle value) { 471 | return value->NumberValue(); 472 | } 473 | 474 | template <> 475 | double valueToCType(v8::Handle value) { 476 | return value->NumberValue(); 477 | } 478 | 479 | 480 | class DataView { 481 | public: 482 | static v8::Persistent GetTemplate() { 483 | static v8::Persistent ft_cache; 484 | if (!ft_cache.IsEmpty()) 485 | return ft_cache; 486 | 487 | v8::HandleScope scope; 488 | ft_cache = v8::Persistent::New( 489 | v8::FunctionTemplate::New(&DataView::V8New)); 490 | ft_cache->SetClassName(v8::String::New("DataView")); 491 | v8::Local instance = ft_cache->InstanceTemplate(); 492 | instance->SetInternalFieldCount(0); 493 | 494 | v8::Local default_signature = v8::Signature::New(ft_cache); 495 | 496 | static BatchedMethods methods[] = { 497 | { "getUint8", &DataView::getUint8 }, 498 | { "getInt8", &DataView::getInt8 }, 499 | { "getUint16", &DataView::getUint16 }, 500 | { "getInt16", &DataView::getInt16 }, 501 | { "getUint32", &DataView::getUint32 }, 502 | { "getInt32", &DataView::getInt32 }, 503 | { "getFloat32", &DataView::getFloat32 }, 504 | { "getFloat64", &DataView::getFloat64 }, 505 | { "setUint8", &DataView::setUint8 }, 506 | { "setInt8", &DataView::setInt8 }, 507 | { "setUint16", &DataView::setUint16 }, 508 | { "setInt16", &DataView::setInt16 }, 509 | { "setUint32", &DataView::setUint32 }, 510 | { "setInt32", &DataView::setInt32 }, 511 | { "setFloat32", &DataView::setFloat32 }, 512 | { "setFloat64", &DataView::setFloat64 }, 513 | }; 514 | 515 | for (size_t i = 0; i < sizeof(methods) / sizeof(*methods); ++i) { 516 | instance->Set(v8::String::New(methods[i].name), 517 | v8::FunctionTemplate::New(methods[i].func, 518 | v8::Handle(), 519 | default_signature)); 520 | } 521 | 522 | return ft_cache; 523 | } 524 | 525 | static bool HasInstance(v8::Handle value) { 526 | return GetTemplate()->HasInstance(value); 527 | } 528 | 529 | private: 530 | static v8::Handle V8New(const v8::Arguments& args) { 531 | if (!args.IsConstructCall()) 532 | return ThrowTypeError("Constructor cannot be called as a function."); 533 | 534 | if (args.Length() < 1) 535 | return ThrowError("Wrong number of arguments."); 536 | 537 | if (!args[0]->IsObject()) 538 | return ThrowError("Object must be an ArrayBuffer."); 539 | 540 | v8::Handle buffer = v8::Handle::Cast(args[0]); 541 | if (!buffer->HasIndexedPropertiesInExternalArrayData()) 542 | return ThrowError("Object must be an ArrayBuffer."); 543 | 544 | unsigned int byte_length = 545 | buffer->GetIndexedPropertiesExternalArrayDataLength(); 546 | unsigned int byte_offset = args[1]->Uint32Value(); 547 | 548 | if (args[1]->Int32Value() < 0 || byte_offset >= byte_length) 549 | return ThrowRangeError("byteOffset out of range."); 550 | 551 | if (!args[2]->IsUndefined()) { 552 | if (args[2]->Int32Value() < 0) 553 | return ThrowRangeError("byteLength out of range."); 554 | unsigned int new_byte_length = args[2]->Uint32Value(); 555 | if (new_byte_length > byte_length) 556 | return ThrowRangeError("byteLength out of range."); 557 | if (byte_offset + new_byte_length > byte_length) 558 | return ThrowRangeError("byteOffset/byteLength out of range."); 559 | byte_length = new_byte_length; 560 | } else { 561 | // Adjust the original byte_length from total length to length to end. 562 | byte_length -= byte_offset; 563 | } 564 | 565 | void* buf = buffer->GetIndexedPropertiesExternalArrayData(); 566 | 567 | // Like ArrayBuffer, we violate the spec and add an operator[]. 568 | args.This()->SetIndexedPropertiesToExternalArrayData( 569 | reinterpret_cast(buf) + byte_offset, 570 | v8::kExternalUnsignedByteArray, byte_length); 571 | 572 | args.This()->Set(v8::String::New("buffer"), 573 | buffer, 574 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 575 | args.This()->Set(v8::String::New("byteOffset"), 576 | v8::Integer::NewFromUnsigned(byte_offset), 577 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 578 | args.This()->Set(v8::String::New("byteLength"), 579 | v8::Integer::NewFromUnsigned(byte_length), 580 | (v8::PropertyAttribute)(v8::ReadOnly|v8::DontDelete)); 581 | return args.This(); 582 | } 583 | 584 | // TODO(deanm): This isn't beautiful or optimal. 585 | static void swizzle(char* buf, size_t len) { 586 | for (int i = 0; i < len / 2; ++i) { 587 | char t = buf[i]; 588 | buf[i] = buf[len - i - 1]; 589 | buf[len - i - 1] = t; 590 | } 591 | } 592 | 593 | template 594 | static T getValue(void* ptr, unsigned int index, bool swiz) { 595 | char buf[sizeof(T)]; 596 | memcpy(buf, reinterpret_cast(ptr) + index, sizeof(T)); 597 | if (swiz) 598 | swizzle(buf, sizeof(T)); 599 | T val; 600 | memcpy(&val, buf, sizeof(T)); 601 | return val; 602 | } 603 | 604 | template 605 | static void setValue(void* ptr, unsigned int index, T val, bool swiz) { 606 | char buf[sizeof(T)]; 607 | memcpy(buf, &val, sizeof(T)); 608 | if (swiz) 609 | swizzle(buf, sizeof(T)); 610 | memcpy(reinterpret_cast(ptr) + index, buf, sizeof(T)); 611 | } 612 | 613 | template 614 | static v8::Handle getGeneric(const v8::Arguments& args) { 615 | if (args.Length() < 1) 616 | return ThrowError("Wrong number of arguments."); 617 | 618 | unsigned int index = args[0]->Uint32Value(); 619 | bool little_endian = args[1]->BooleanValue(); 620 | // TODO(deanm): All of these things should be cacheable. 621 | int element_size = v8_typed_array::SizeOfArrayElementForType( 622 | args.This()->GetIndexedPropertiesExternalArrayDataType()); 623 | int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() * 624 | element_size; 625 | 626 | if (index + sizeof(T) > size) // TODO(deanm): integer overflow. 627 | return ThrowError("Index out of range."); 628 | 629 | void* ptr = args.This()->GetIndexedPropertiesExternalArrayData(); 630 | return cTypeToValue(getValue(ptr, index, !little_endian)); 631 | } 632 | 633 | template 634 | static v8::Handle setGeneric(const v8::Arguments& args) { 635 | if (args.Length() < 2) 636 | return ThrowError("Wrong number of arguments."); 637 | 638 | unsigned int index = args[0]->Int32Value(); 639 | bool little_endian = args[2]->BooleanValue(); 640 | // TODO(deanm): All of these things should be cacheable. 641 | int element_size = v8_typed_array::SizeOfArrayElementForType( 642 | args.This()->GetIndexedPropertiesExternalArrayDataType()); 643 | int size = args.This()->GetIndexedPropertiesExternalArrayDataLength() * 644 | element_size; 645 | 646 | if (index + sizeof(T) > size) // TODO(deanm): integer overflow. 647 | return ThrowError("Index out of range."); 648 | 649 | void* ptr = args.This()->GetIndexedPropertiesExternalArrayData(); 650 | setValue(ptr, index, valueToCType(args[1]), !little_endian); 651 | return v8::Undefined(); 652 | } 653 | 654 | static v8::Handle getUint8(const v8::Arguments& args) { 655 | return getGeneric(args); 656 | } 657 | 658 | static v8::Handle getInt8(const v8::Arguments& args) { 659 | return getGeneric(args); 660 | } 661 | 662 | static v8::Handle getUint16(const v8::Arguments& args) { 663 | return getGeneric(args); 664 | } 665 | 666 | static v8::Handle getInt16(const v8::Arguments& args) { 667 | return getGeneric(args); 668 | } 669 | 670 | static v8::Handle getUint32(const v8::Arguments& args) { 671 | return getGeneric(args); 672 | } 673 | 674 | static v8::Handle getInt32(const v8::Arguments& args) { 675 | return getGeneric(args); 676 | } 677 | 678 | static v8::Handle getFloat32(const v8::Arguments& args) { 679 | return getGeneric(args); 680 | } 681 | 682 | static v8::Handle getFloat64(const v8::Arguments& args) { 683 | return getGeneric(args); 684 | } 685 | 686 | static v8::Handle setUint8(const v8::Arguments& args) { 687 | return setGeneric(args); 688 | } 689 | 690 | static v8::Handle setInt8(const v8::Arguments& args) { 691 | return setGeneric(args); 692 | } 693 | 694 | static v8::Handle setUint16(const v8::Arguments& args) { 695 | return setGeneric(args); 696 | } 697 | 698 | static v8::Handle setInt16(const v8::Arguments& args) { 699 | return setGeneric(args); 700 | } 701 | 702 | static v8::Handle setUint32(const v8::Arguments& args) { 703 | return setGeneric(args); 704 | } 705 | 706 | static v8::Handle setInt32(const v8::Arguments& args) { 707 | return setGeneric(args); 708 | } 709 | 710 | static v8::Handle setFloat32(const v8::Arguments& args) { 711 | return setGeneric(args); 712 | } 713 | 714 | static v8::Handle setFloat64(const v8::Arguments& args) { 715 | return setGeneric(args); 716 | } 717 | }; 718 | 719 | 720 | } // namespace 721 | 722 | namespace v8_typed_array { 723 | 724 | void AttachBindings(v8::Handle obj) { 725 | obj->Set(v8::String::New("ArrayBuffer"), 726 | ArrayBuffer::GetTemplate()->GetFunction()); 727 | obj->Set(v8::String::New("Int8Array"), 728 | Int8Array::GetTemplate()->GetFunction()); 729 | obj->Set(v8::String::New("Uint8Array"), 730 | Uint8Array::GetTemplate()->GetFunction()); 731 | obj->Set(v8::String::New("Int16Array"), 732 | Int16Array::GetTemplate()->GetFunction()); 733 | obj->Set(v8::String::New("Uint16Array"), 734 | Uint16Array::GetTemplate()->GetFunction()); 735 | obj->Set(v8::String::New("Int32Array"), 736 | Int32Array::GetTemplate()->GetFunction()); 737 | obj->Set(v8::String::New("Uint32Array"), 738 | Uint32Array::GetTemplate()->GetFunction()); 739 | obj->Set(v8::String::New("Float32Array"), 740 | Float32Array::GetTemplate()->GetFunction()); 741 | obj->Set(v8::String::New("DataView"), 742 | DataView::GetTemplate()->GetFunction()); 743 | } 744 | 745 | int SizeOfArrayElementForType(v8::ExternalArrayType type) { 746 | switch (type) { 747 | case v8::kExternalByteArray: 748 | case v8::kExternalUnsignedByteArray: 749 | return 1; 750 | case v8::kExternalShortArray: 751 | case v8::kExternalUnsignedShortArray: 752 | return 2; 753 | case v8::kExternalIntArray: 754 | case v8::kExternalUnsignedIntArray: 755 | case v8::kExternalFloatArray: 756 | return 4; 757 | default: 758 | return 0; 759 | } 760 | } 761 | 762 | } // namespace v8_typed_array 763 | -------------------------------------------------------------------------------- /src/v8_typed_array.h: -------------------------------------------------------------------------------- 1 | // V8 Typed Array implementation. 2 | // (c) Dean McNamee , 2011. 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to 6 | // deal in the Software without restriction, including without limitation the 7 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8 | // sell copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 20 | // IN THE SOFTWARE. 21 | 22 | #ifndef V8_TYPED_ARRAY_H_ 23 | #define V8_TYPED_ARRAY_H_ 24 | 25 | #include 26 | 27 | namespace v8_typed_array { 28 | 29 | void AttachBindings(v8::Handle obj); 30 | 31 | int SizeOfArrayElementForType(v8::ExternalArrayType type); 32 | 33 | } // namespace v8_typed_array 34 | 35 | #endif // V8_TYPED_ARRAY_H_ 36 | -------------------------------------------------------------------------------- /src/webgl.cc: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "v8_typed_array.h" 5 | 6 | #include "arch_wrapper.h" 7 | 8 | using namespace v8; 9 | 10 | namespace webgl { 11 | 12 | 13 | Handle Uniform1f(const Arguments& args) { 14 | HandleScope scope; 15 | 16 | int location = args[0]->Int32Value(); 17 | double x = args[1]->NumberValue(); 18 | 19 | glUniform1f(location, x); 20 | return Undefined(); 21 | } 22 | 23 | Handle Uniform2f(const Arguments& args) { 24 | HandleScope scope; 25 | 26 | int location = args[0]->Int32Value(); 27 | double x = args[1]->NumberValue(); 28 | double y = args[2]->NumberValue(); 29 | 30 | glUniform2f(location, x, y); 31 | return Undefined(); 32 | } 33 | 34 | Handle Uniform4f(const Arguments& args) { 35 | HandleScope scope; 36 | 37 | int location = args[0]->Int32Value(); 38 | double x = args[1]->NumberValue(); 39 | double y = args[2]->NumberValue(); 40 | double z = args[3]->NumberValue(); 41 | double w = args[4]->NumberValue(); 42 | 43 | glUniform4f(location, x, y, z, w); 44 | return Undefined(); 45 | } 46 | 47 | Handle Uniform1i(const Arguments& args) { 48 | HandleScope scope; 49 | 50 | int location = args[0]->Int32Value(); 51 | int x = args[1]->Int32Value(); 52 | 53 | glUniform1i(location, x); 54 | return Undefined(); 55 | } 56 | 57 | Handle Uniform2i(const Arguments& args) { 58 | HandleScope scope; 59 | 60 | int location = args[0]->Int32Value(); 61 | int x = args[1]->Int32Value(); 62 | int y = args[2]->Int32Value(); 63 | 64 | glUniform2i(location, x, y); 65 | return Undefined(); 66 | } 67 | 68 | Handle Uniform4i(const Arguments& args) { 69 | HandleScope scope; 70 | 71 | int location = args[0]->Int32Value(); 72 | int x = args[1]->Int32Value(); 73 | int y = args[2]->Int32Value(); 74 | int z = args[3]->Int32Value(); 75 | int w = args[4]->Int32Value(); 76 | 77 | glUniform4i(location, x, y, z, w); 78 | return Undefined(); 79 | } 80 | 81 | 82 | Handle PixelStorei(const Arguments& args) { 83 | HandleScope scope; 84 | 85 | int pname = args[0]->Int32Value(); 86 | int param = args[1]->Int32Value(); 87 | 88 | glPixelStorei(pname,param); 89 | 90 | return Undefined(); 91 | } 92 | 93 | Handle BindAttribLocation(const Arguments& args) { 94 | HandleScope scope; 95 | 96 | int program = args[0]->Int32Value(); 97 | int index = args[1]->Int32Value(); 98 | String::Utf8Value name(args[2]); 99 | 100 | glBindAttribLocation(program, index, *name); 101 | 102 | return Undefined(); 103 | } 104 | 105 | 106 | Handle GetError(const Arguments& args) { 107 | HandleScope scope; 108 | 109 | return Number::New(glGetError()); 110 | } 111 | 112 | 113 | Handle DrawArrays(const Arguments& args) { 114 | HandleScope scope; 115 | 116 | int mode = args[0]->Int32Value(); 117 | int first = args[1]->Int32Value(); 118 | int count = args[2]->Int32Value(); 119 | 120 | glDrawArrays(mode, first, count); 121 | 122 | return Undefined(); 123 | } 124 | 125 | Handle UniformMatrix4fv(const Arguments& args) { 126 | HandleScope scope; 127 | 128 | GLint location = args[0]->Int32Value(); 129 | GLboolean transpose = args[1]->BooleanValue(); 130 | Local value = Local::Cast(args[2]); 131 | 132 | 133 | GLsizei count = value->GetIndexedPropertiesExternalArrayDataLength(); 134 | 135 | if (count < 16) { 136 | return ThrowException(Exception::TypeError(String::New("Not enough data for UniformMatrix4fv"))); 137 | } 138 | 139 | const GLfloat* data = (const GLfloat*)value->GetIndexedPropertiesExternalArrayData(); 140 | 141 | // printf("count=%d\n", count); 142 | // printf("[%f, %f, %f, %f,\n", data[0], data[1], data[2], data[3]); 143 | // printf(" %f, %f, %f, %f,\n", data[4], data[5], data[6], data[7]); 144 | // printf(" %f, %f, %f, %f,\n", data[8], data[9], data[10], data[11]); 145 | // printf(" %f, %f, %f, %f]\n", data[12], data[13], data[14], data[15]); 146 | 147 | 148 | glUniformMatrix4fv(location, count / 16, transpose, data); 149 | 150 | return Undefined(); 151 | } 152 | 153 | 154 | 155 | Handle GetAttribLocation(const Arguments& args) { 156 | HandleScope scope; 157 | 158 | int program = args[0]->Int32Value(); 159 | String::Utf8Value name(args[1]); 160 | 161 | return Number::New(glGetAttribLocation(program, *name)); 162 | } 163 | 164 | 165 | Handle DepthFunc(const Arguments& args) { 166 | HandleScope scope; 167 | 168 | glDepthFunc(args[0]->Int32Value()); 169 | 170 | return Undefined(); 171 | } 172 | 173 | 174 | Handle Viewport(const Arguments& args) { 175 | HandleScope scope; 176 | 177 | int x = args[0]->Int32Value(); 178 | int y = args[1]->Int32Value(); 179 | int width = args[2]->Int32Value(); 180 | int height = args[3]->Int32Value(); 181 | 182 | glViewport(x, y, width, height); 183 | 184 | return Undefined(); 185 | 186 | return Number::New(glCreateShader(args[0]->Int32Value())); 187 | } 188 | 189 | Handle CreateShader(const Arguments& args) { 190 | HandleScope scope; 191 | 192 | return Number::New(glCreateShader(args[0]->Int32Value())); 193 | } 194 | 195 | 196 | Handle ShaderSource(const Arguments& args) { 197 | HandleScope scope; 198 | 199 | int id = args[0]->Int32Value(); 200 | String::Utf8Value code(args[1]); 201 | 202 | const char* codes[1]; 203 | codes[0] = *code; 204 | 205 | glShaderSource (id, 1, codes, NULL); 206 | 207 | return Undefined(); 208 | } 209 | 210 | 211 | Handle CompileShader(const Arguments& args) { 212 | HandleScope scope; 213 | 214 | 215 | glCompileShader(args[0]->Int32Value()); 216 | 217 | return Undefined(); 218 | } 219 | 220 | 221 | Handle GetShaderParameter(const Arguments& args) { 222 | HandleScope scope; 223 | 224 | int shader = args[0]->Int32Value(); 225 | int pname = args[1]->Int32Value(); 226 | int value = 0; 227 | switch (pname) { 228 | case GL_DELETE_STATUS: 229 | case GL_COMPILE_STATUS: 230 | glGetShaderiv(shader, pname, &value); 231 | return Boolean::New(static_cast(value)); 232 | case GL_SHADER_TYPE: 233 | glGetShaderiv(shader, pname, &value); 234 | return Number::New(static_cast(value)); 235 | case GL_INFO_LOG_LENGTH: 236 | case GL_SHADER_SOURCE_LENGTH: 237 | glGetShaderiv(shader, pname, &value); 238 | return Number::New(static_cast(value)); 239 | default: 240 | return ThrowException(Exception::TypeError(String::New("GetShaderParameter: Invalid Enum"))); 241 | } 242 | } 243 | 244 | Handle GetShaderInfoLog(const Arguments& args) { 245 | HandleScope scope; 246 | 247 | int id = args[0]->Int32Value(); 248 | int Len = 1024; 249 | char Error[1024]; 250 | glGetShaderInfoLog(id, 1024, &Len, Error); 251 | 252 | return String::New(Error); 253 | } 254 | 255 | 256 | Handle CreateProgram(const Arguments& args) { 257 | HandleScope scope; 258 | 259 | return Number::New(glCreateProgram()); 260 | } 261 | 262 | 263 | Handle AttachShader(const Arguments& args) { 264 | HandleScope scope; 265 | 266 | int program = args[0]->Int32Value(); 267 | int shader = args[1]->Int32Value(); 268 | 269 | glAttachShader(program, shader); 270 | 271 | return Undefined(); 272 | } 273 | 274 | 275 | Handle LinkProgram(const Arguments& args) { 276 | HandleScope scope; 277 | 278 | glLinkProgram(args[0]->Int32Value()); 279 | 280 | return Undefined(); 281 | } 282 | 283 | 284 | Handle GetProgramParameter(const Arguments& args) { 285 | HandleScope scope; 286 | 287 | int program = args[0]->Int32Value(); 288 | int pname = args[1]->Int32Value(); 289 | 290 | int value = 0; 291 | switch (pname) { 292 | case GL_DELETE_STATUS: 293 | case GL_LINK_STATUS: 294 | case GL_VALIDATE_STATUS: 295 | glGetProgramiv(program, pname, &value); 296 | return Boolean::New(static_cast(value)); 297 | case GL_ATTACHED_SHADERS: 298 | case GL_ACTIVE_ATTRIBUTES: 299 | case GL_ACTIVE_UNIFORMS: 300 | glGetProgramiv(program, pname, &value); 301 | return Number::New(static_cast(value)); 302 | default: 303 | return ThrowException(Exception::TypeError(String::New("GetProgramParameter: Invalid Enum"))); 304 | } 305 | } 306 | 307 | 308 | Handle GetUniformLocation(const Arguments& args) { 309 | HandleScope scope; 310 | 311 | int program = args[0]->Int32Value(); 312 | String::Utf8Value name(args[1]); 313 | 314 | return Number::New(glGetUniformLocation(program, *name)); 315 | } 316 | 317 | 318 | Handle ClearColor(const Arguments& args) { 319 | HandleScope scope; 320 | 321 | double red = args[0]->NumberValue(); 322 | double green = args[1]->NumberValue(); 323 | double blue = args[2]->NumberValue(); 324 | double alpha = args[3]->NumberValue(); 325 | 326 | glClearColor(red, green, blue, alpha); 327 | 328 | return Undefined(); 329 | } 330 | 331 | 332 | Handle ClearDepth(const Arguments& args) { 333 | HandleScope scope; 334 | 335 | double depth = args[0]->NumberValue(); 336 | 337 | glClearDepthf(depth); 338 | 339 | return Undefined(); 340 | } 341 | 342 | Handle Disable(const Arguments& args) { 343 | HandleScope scope; 344 | 345 | glDisable(args[0]->Int32Value()); 346 | return Undefined(); 347 | } 348 | 349 | Handle Enable(const Arguments& args) { 350 | HandleScope scope; 351 | 352 | glEnable(args[0]->Int32Value()); 353 | return Undefined(); 354 | } 355 | 356 | 357 | Handle CreateTexture(const Arguments& args) { 358 | HandleScope scope; 359 | 360 | GLuint texture; 361 | glGenTextures(1, &texture); 362 | return Number::New(texture); 363 | } 364 | 365 | 366 | Handle BindTexture(const Arguments& args) { 367 | HandleScope scope; 368 | 369 | int target = args[0]->Int32Value(); 370 | int texture = args[1]->Int32Value(); 371 | 372 | glBindTexture(target, texture); 373 | return Undefined(); 374 | } 375 | 376 | 377 | Handle TexImage2D(const Arguments& args) { 378 | HandleScope scope; 379 | 380 | int target = args[0]->Int32Value(); 381 | int level = args[1]->Int32Value(); 382 | int internalformat = args[2]->Int32Value(); 383 | int width = args[3]->Int32Value(); 384 | int height = args[4]->Int32Value(); 385 | int border = args[5]->Int32Value(); 386 | int format = args[6]->Int32Value(); 387 | int type = args[7]->Int32Value(); 388 | Local obj = Local::Cast(args[8]); 389 | 390 | void* pixels = obj->GetIndexedPropertiesExternalArrayData(); 391 | 392 | glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); 393 | 394 | return Undefined(); 395 | } 396 | 397 | 398 | Handle TexParameteri(const Arguments& args) { 399 | HandleScope scope; 400 | 401 | int target = args[0]->Int32Value(); 402 | int pname = args[1]->Int32Value(); 403 | int param = args[2]->Int32Value(); 404 | 405 | glTexParameteri(target, pname, param); 406 | 407 | return Undefined(); 408 | } 409 | 410 | 411 | Handle Clear(const Arguments& args) { 412 | HandleScope scope; 413 | 414 | glClear(args[0]->Int32Value()); 415 | 416 | return Undefined(); 417 | } 418 | 419 | 420 | Handle UseProgram(const Arguments& args) { 421 | HandleScope scope; 422 | 423 | glUseProgram(args[0]->Int32Value()); 424 | 425 | return Undefined(); 426 | } 427 | 428 | 429 | Handle CreateBuffer(const Arguments& args) { 430 | HandleScope scope; 431 | 432 | GLuint buffer; 433 | glGenBuffers(1, &buffer); 434 | return Number::New(buffer); 435 | } 436 | 437 | 438 | Handle BindBuffer(const Arguments& args) { 439 | HandleScope scope; 440 | 441 | int target = args[0]->Int32Value(); 442 | int buffer = args[1]->Int32Value(); 443 | 444 | glBindBuffer(target, buffer); 445 | 446 | return Undefined(); 447 | } 448 | 449 | 450 | Handle CreateFramebuffer(const Arguments& args) { 451 | HandleScope scope; 452 | 453 | GLuint buffer; 454 | glGenFramebuffers(1, &buffer); 455 | return Number::New(buffer); 456 | } 457 | 458 | 459 | Handle BindFramebuffer(const Arguments& args) { 460 | HandleScope scope; 461 | 462 | int target = args[0]->Int32Value(); 463 | int buffer = args[1]->Int32Value(); 464 | 465 | glBindFramebuffer(target, buffer); 466 | 467 | return Undefined(); 468 | } 469 | 470 | 471 | Handle FramebufferTexture2D(const Arguments& args) { 472 | HandleScope scope; 473 | 474 | int target = args[0]->Int32Value(); 475 | int attachment = args[1]->Int32Value(); 476 | int textarget = args[2]->Int32Value(); 477 | int texture = args[3]->Int32Value(); 478 | int level = args[4]->Int32Value(); 479 | 480 | glFramebufferTexture2D(target, attachment, textarget, texture, level); 481 | 482 | return Undefined(); 483 | } 484 | 485 | 486 | Handle BufferData(const Arguments& args) { 487 | HandleScope scope; 488 | 489 | int target = args[0]->Int32Value(); 490 | Local obj = Local::Cast(args[1]); 491 | int usage = args[2]->Int32Value(); 492 | 493 | int element_size = v8_typed_array::SizeOfArrayElementForType( 494 | obj->GetIndexedPropertiesExternalArrayDataType()); 495 | int size = obj->GetIndexedPropertiesExternalArrayDataLength() * element_size; 496 | void* data = obj->GetIndexedPropertiesExternalArrayData(); 497 | 498 | 499 | // printf("BufferData %d %d %d\n", target, size, usage); 500 | glBufferData(target, size, data, usage); 501 | 502 | return Undefined(); 503 | } 504 | 505 | 506 | Handle BufferSubData(const Arguments& args) { 507 | HandleScope scope; 508 | 509 | int target = args[0]->Int32Value(); 510 | int offset = args[1]->Int32Value(); 511 | Local obj = Local::Cast(args[2]); 512 | 513 | int element_size = v8_typed_array::SizeOfArrayElementForType( 514 | obj->GetIndexedPropertiesExternalArrayDataType()); 515 | int size = obj->GetIndexedPropertiesExternalArrayDataLength() * element_size; 516 | void* data = obj->GetIndexedPropertiesExternalArrayData(); 517 | 518 | glBufferSubData(target, offset, size, data); 519 | 520 | return Undefined(); 521 | } 522 | 523 | 524 | Handle BlendEquation(const Arguments& args) { 525 | HandleScope scope; 526 | 527 | return ThrowException(Exception::Error(String::New("BlendEquation not implemented in node-webgl"))); 528 | } 529 | 530 | 531 | Handle BlendFunc(const Arguments& args) { 532 | HandleScope scope; 533 | 534 | return ThrowException(Exception::Error(String::New("BlendFunc not implemented in node-webgl"))); 535 | } 536 | 537 | 538 | Handle EnableVertexAttribArray(const Arguments& args) { 539 | HandleScope scope; 540 | 541 | glEnableVertexAttribArray(args[0]->Int32Value()); 542 | 543 | return Undefined(); 544 | } 545 | 546 | 547 | Handle VertexAttribPointer(const Arguments& args) { 548 | HandleScope scope; 549 | 550 | int indx = args[0]->Int32Value(); 551 | int size = args[1]->Int32Value(); 552 | int type = args[2]->Int32Value(); 553 | int normalized = args[3]->BooleanValue(); 554 | int stride = args[4]->Int32Value(); 555 | int offset = args[5]->Int32Value(); 556 | 557 | // printf("VertexAttribPointer %d %d %d %d %d %d\n", indx, size, type, normalized, stride, offset); 558 | glVertexAttribPointer(indx, size, type, normalized, stride, (const GLvoid *)offset); 559 | 560 | return Undefined(); 561 | } 562 | 563 | 564 | Handle ActiveTexture(const Arguments& args) { 565 | HandleScope scope; 566 | 567 | glActiveTexture(args[0]->Int32Value()); 568 | return Undefined(); 569 | } 570 | 571 | 572 | Handle DrawElements(const Arguments& args) { 573 | HandleScope scope; 574 | 575 | int mode = args[0]->Int32Value(); 576 | int count = args[1]->Int32Value(); 577 | int type = args[2]->Int32Value(); 578 | int offset = args[3]->Int32Value(); 579 | glDrawElements(mode, count, type, (const GLvoid*)offset); 580 | return Undefined(); 581 | } 582 | 583 | 584 | Handle Flush(const Arguments& args) { 585 | HandleScope scope; 586 | 587 | glFlush(); 588 | return Undefined(); 589 | } 590 | 591 | 592 | } 593 | 594 | extern "C" void 595 | init(Handle target) 596 | { 597 | 598 | NODE_SET_METHOD(target, "uniform1f", webgl::Uniform1f); 599 | NODE_SET_METHOD(target, "uniform2f", webgl::Uniform2f); 600 | NODE_SET_METHOD(target, "uniform4f", webgl::Uniform4f); 601 | NODE_SET_METHOD(target, "uniform1i", webgl::Uniform1i); 602 | NODE_SET_METHOD(target, "uniform2i", webgl::Uniform2i); 603 | NODE_SET_METHOD(target, "uniform4i", webgl::Uniform4i); 604 | NODE_SET_METHOD(target, "pixelStorei", webgl::PixelStorei); 605 | NODE_SET_METHOD(target, "bindAttribLocation", webgl::BindAttribLocation); 606 | NODE_SET_METHOD(target, "getError", webgl::GetError); 607 | NODE_SET_METHOD(target, "drawArrays", webgl::DrawArrays); 608 | NODE_SET_METHOD(target, "uniformMatrix4fv", webgl::UniformMatrix4fv); 609 | 610 | NODE_SET_METHOD(target, "getAttribLocation", webgl::GetAttribLocation); 611 | NODE_SET_METHOD(target, "depthFunc", webgl::DepthFunc); 612 | NODE_SET_METHOD(target, "viewport", webgl::Viewport); 613 | NODE_SET_METHOD(target, "createShader", webgl::CreateShader); 614 | NODE_SET_METHOD(target, "shaderSource", webgl::ShaderSource); 615 | NODE_SET_METHOD(target, "compileShader", webgl::CompileShader); 616 | NODE_SET_METHOD(target, "getShaderParameter", webgl::GetShaderParameter); 617 | NODE_SET_METHOD(target, "getShaderInfoLog", webgl::GetShaderInfoLog); 618 | NODE_SET_METHOD(target, "createProgram", webgl::CreateProgram); 619 | NODE_SET_METHOD(target, "attachShader", webgl::AttachShader); 620 | NODE_SET_METHOD(target, "linkProgram", webgl::LinkProgram); 621 | NODE_SET_METHOD(target, "getProgramParameter", webgl::GetProgramParameter); 622 | NODE_SET_METHOD(target, "getUniformLocation", webgl::GetUniformLocation); 623 | NODE_SET_METHOD(target, "clearColor", webgl::ClearColor); 624 | NODE_SET_METHOD(target, "clearDepth", webgl::ClearDepth); 625 | 626 | NODE_SET_METHOD(target, "disable", webgl::Disable); 627 | NODE_SET_METHOD(target, "createTexture", webgl::CreateTexture); 628 | NODE_SET_METHOD(target, "bindTexture", webgl::BindTexture); 629 | NODE_SET_METHOD(target, "texImage2D", webgl::TexImage2D); 630 | NODE_SET_METHOD(target, "texParameteri", webgl::TexParameteri); 631 | NODE_SET_METHOD(target, "clear", webgl::Clear); 632 | NODE_SET_METHOD(target, "useProgram", webgl::UseProgram); 633 | NODE_SET_METHOD(target, "createFramebuffer", webgl::CreateFramebuffer); 634 | NODE_SET_METHOD(target, "bindFramebuffer", webgl::BindFramebuffer); 635 | NODE_SET_METHOD(target, "framebufferTexture2D", webgl::FramebufferTexture2D); 636 | NODE_SET_METHOD(target, "createBuffer", webgl::CreateBuffer); 637 | NODE_SET_METHOD(target, "bindBuffer", webgl::BindBuffer); 638 | NODE_SET_METHOD(target, "bufferData", webgl::BufferData); 639 | NODE_SET_METHOD(target, "bufferSubData", webgl::BufferSubData); 640 | NODE_SET_METHOD(target, "enable", webgl::Enable); 641 | NODE_SET_METHOD(target, "blendEquation", webgl::BlendEquation); 642 | NODE_SET_METHOD(target, "blendFunc", webgl::BlendFunc); 643 | NODE_SET_METHOD(target, "enableVertexAttribArray", webgl::EnableVertexAttribArray); 644 | NODE_SET_METHOD(target, "vertexAttribPointer", webgl::VertexAttribPointer); 645 | NODE_SET_METHOD(target, "activeTexture", webgl::ActiveTexture); 646 | NODE_SET_METHOD(target, "drawElements", webgl::DrawElements); 647 | NODE_SET_METHOD(target, "flush", webgl::Flush); 648 | 649 | target->Set(String::New("FRAGMENT_SHADER"), Number::New(GL_FRAGMENT_SHADER)); 650 | target->Set(String::New("VERTEX_SHADER"), Number::New(GL_VERTEX_SHADER)); 651 | target->Set(String::New("COMPILE_STATUS"), Number::New(GL_COMPILE_STATUS)); 652 | target->Set(String::New("DELETE_STATUS"), Number::New(GL_DELETE_STATUS)); 653 | target->Set(String::New("LINK_STATUS"), Number::New(GL_LINK_STATUS)); 654 | target->Set(String::New("VALIDATE_STATUS"), Number::New(GL_VALIDATE_STATUS)); 655 | target->Set(String::New("ATTACHED_SHADERS"), Number::New(GL_ATTACHED_SHADERS)); 656 | target->Set(String::New("ACTIVE_ATTRIBUTES"), Number::New(GL_ACTIVE_ATTRIBUTES)); 657 | target->Set(String::New("ACTIVE_UNIFORMS"), Number::New(GL_ACTIVE_UNIFORMS)); 658 | target->Set(String::New("ELEMENT_ARRAY_BUFFER"), Number::New(GL_ELEMENT_ARRAY_BUFFER)); 659 | 660 | 661 | target->Set(String::New("NEVER"), Number::New(GL_NEVER)); 662 | target->Set(String::New("LESS"), Number::New(GL_LESS)); 663 | target->Set(String::New("EQUAL"), Number::New(GL_EQUAL)); 664 | target->Set(String::New("LEQUAL"), Number::New(GL_LEQUAL)); 665 | target->Set(String::New("GREATER"), Number::New(GL_GREATER)); 666 | target->Set(String::New("NOTEQUAL"), Number::New(GL_NOTEQUAL)); 667 | target->Set(String::New("GEQUAL"), Number::New(GL_GEQUAL)); 668 | target->Set(String::New("ALWAYS"), Number::New(GL_ALWAYS)); 669 | 670 | target->Set(String::New("DEPTH_TEST"), Number::New(GL_DEPTH_TEST)); 671 | target->Set(String::New("ARRAY_BUFFER"), Number::New(GL_ARRAY_BUFFER)); 672 | target->Set(String::New("STATIC_DRAW"), Number::New(GL_STATIC_DRAW)); 673 | target->Set(String::New("STREAM_DRAW"), Number::New(GL_STREAM_DRAW)); 674 | target->Set(String::New("DYNAMIC_DRAW"), Number::New(GL_DYNAMIC_DRAW)); 675 | 676 | target->Set(String::New("FLOAT"), Number::New(GL_FLOAT)); 677 | target->Set(String::New("UNSIGNED_BYTE"), Number::New(GL_UNSIGNED_BYTE)); 678 | target->Set(String::New("UNSIGNED_SHORT"), Number::New(GL_UNSIGNED_SHORT)); 679 | target->Set(String::New("FALSE"), Boolean::New(GL_FALSE)); 680 | target->Set(String::New("TRIANGLES"), Number::New(GL_TRIANGLES)); 681 | target->Set(String::New("TRIANGLE_STRIP"), Number::New(GL_TRIANGLE_STRIP)); 682 | target->Set(String::New("COLOR_BUFFER_BIT"), Number::New(GL_COLOR_BUFFER_BIT)); 683 | target->Set(String::New("DEPTH_BUFFER_BIT"), Number::New(GL_DEPTH_BUFFER_BIT)); 684 | 685 | target->Set(String::New("TEXTURE_2D"), Number::New(GL_TEXTURE_2D)); 686 | target->Set(String::New("TEXTURE0"), Number::New(GL_TEXTURE0)); 687 | target->Set(String::New("TEXTURE1"), Number::New(GL_TEXTURE1)); 688 | target->Set(String::New("TEXTURE2"), Number::New(GL_TEXTURE2)); 689 | target->Set(String::New("TEXTURE3"), Number::New(GL_TEXTURE3)); 690 | target->Set(String::New("TEXTURE4"), Number::New(GL_TEXTURE4)); 691 | target->Set(String::New("TEXTURE_MIN_FILTER"), Number::New(GL_TEXTURE_MIN_FILTER)); 692 | target->Set(String::New("TEXTURE_MAG_FILTER"), Number::New(GL_TEXTURE_MAG_FILTER)); 693 | target->Set(String::New("LINEAR"), Number::New(GL_LINEAR)); 694 | target->Set(String::New("NEAREST"), Number::New(GL_NEAREST)); 695 | 696 | target->Set(String::New("FRAMEBUFFER"), Number::New(GL_FRAMEBUFFER)); 697 | target->Set(String::New("COLOR_ATTACHMENT0"), Number::New(GL_COLOR_ATTACHMENT0)); 698 | 699 | target->Set(String::New("INVALID_ENUM"), Number::New(GL_INVALID_ENUM)); 700 | target->Set(String::New("INVALID_VALUE"), Number::New(GL_INVALID_VALUE)); 701 | target->Set(String::New("INVALID_OPERATION"), Number::New(GL_INVALID_OPERATION)); 702 | // target->Set(String::New("STACK_OVERFLOW"), Number::New(GL_STACK_OVERFLOW)); 703 | // target->Set(String::New("STACK_UNDERFLOW"), Number::New(GL_STACK_UNDERFLOW)); 704 | target->Set(String::New("OUT_OF_MEMORY"), Number::New(GL_OUT_OF_MEMORY)); 705 | // target->Set(String::New("TABLE_TOO_LARGE"), Number::New(GL_TABLE_TOO_LARGE)); 706 | 707 | 708 | target->Set(String::New("UNPACK_ALIGNMENT"), Number::New(GL_UNPACK_ALIGNMENT)); 709 | target->Set(String::New("RGBA"), Number::New(GL_RGBA)); 710 | 711 | 712 | 713 | v8_typed_array::AttachBindings(Context::GetCurrent()->Global()); 714 | 715 | 716 | } 717 | 718 | -------------------------------------------------------------------------------- /webgl.js: -------------------------------------------------------------------------------- 1 | // Generated by /home/tim/Code/node-webgl/api.js 2 | 3 | var gl = module.exports = require('./build/default/node-webgl.node'); 4 | 5 | 6 | var _activeTexture = gl.activeTexture; 7 | gl.activeTexture = function activeTexture(texture) { 8 | if (!(arguments.length === 1 && typeof texture === "number")) { 9 | throw new TypeError('Expected activeTexture(number texture)'); 10 | } 11 | return _activeTexture(texture); 12 | } 13 | 14 | var _attachShader = gl.attachShader; 15 | gl.attachShader = function attachShader(program, shader) { 16 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && (shader === null || shader instanceof WebGLShader))) { 17 | throw new TypeError('Expected attachShader(WebGLProgram program, WebGLShader shader)'); 18 | } 19 | return _attachShader(program ? program._ : 0, shader ? shader._ : 0); 20 | } 21 | 22 | var _bindAttribLocation = gl.bindAttribLocation; 23 | gl.bindAttribLocation = function bindAttribLocation(program, index, name) { 24 | if (!(arguments.length === 3 && (program === null || program instanceof WebGLProgram) && typeof index === "number" && typeof name === "string")) { 25 | throw new TypeError('Expected bindAttribLocation(WebGLProgram program, number index, string name)'); 26 | } 27 | return _bindAttribLocation(program ? program._ : 0, index, name); 28 | } 29 | 30 | var _bindBuffer = gl.bindBuffer; 31 | gl.bindBuffer = function bindBuffer(target, buffer) { 32 | if (!(arguments.length === 2 && typeof target === "number" && (buffer === null || buffer instanceof WebGLBuffer))) { 33 | throw new TypeError('Expected bindBuffer(number target, WebGLBuffer buffer)'); 34 | } 35 | return _bindBuffer(target, buffer ? buffer._ : 0); 36 | } 37 | 38 | var _bindFramebuffer = gl.bindFramebuffer; 39 | gl.bindFramebuffer = function bindFramebuffer(target, framebuffer) { 40 | if (!(arguments.length === 2 && typeof target === "number" && (framebuffer === null || framebuffer instanceof WebGLFramebuffer))) { 41 | throw new TypeError('Expected bindFramebuffer(number target, WebGLFramebuffer framebuffer)'); 42 | } 43 | return _bindFramebuffer(target, framebuffer ? framebuffer._ : 0); 44 | } 45 | 46 | var _bindRenderbuffer = gl.bindRenderbuffer; 47 | gl.bindRenderbuffer = function bindRenderbuffer(target, renderbuffer) { 48 | if (!(arguments.length === 2 && typeof target === "number" && (renderbuffer === null || renderbuffer instanceof WebGLRenderbuffer))) { 49 | throw new TypeError('Expected bindRenderbuffer(number target, WebGLRenderbuffer renderbuffer)'); 50 | } 51 | return _bindRenderbuffer(target, renderbuffer ? renderbuffer._ : 0); 52 | } 53 | 54 | var _bindTexture = gl.bindTexture; 55 | gl.bindTexture = function bindTexture(target, texture) { 56 | if (!(arguments.length === 2 && typeof target === "number" && (texture === null || texture instanceof WebGLTexture))) { 57 | throw new TypeError('Expected bindTexture(number target, WebGLTexture texture)'); 58 | } 59 | return _bindTexture(target, texture ? texture._ : 0); 60 | } 61 | 62 | var _blendColor = gl.blendColor; 63 | gl.blendColor = function blendColor(red, green, blue, alpha) { 64 | if (!(arguments.length === 4 && typeof red === "number" && typeof green === "number" && typeof blue === "number" && typeof alpha === "number")) { 65 | throw new TypeError('Expected blendColor(number red, number green, number blue, number alpha)'); 66 | } 67 | return _blendColor(red, green, blue, alpha); 68 | } 69 | 70 | var _blendEquation = gl.blendEquation; 71 | gl.blendEquation = function blendEquation(mode) { 72 | if (!(arguments.length === 1 && typeof mode === "number")) { 73 | throw new TypeError('Expected blendEquation(number mode)'); 74 | } 75 | return _blendEquation(mode); 76 | } 77 | 78 | var _blendEquationSeparate = gl.blendEquationSeparate; 79 | gl.blendEquationSeparate = function blendEquationSeparate(modeRGB, modeAlpha) { 80 | if (!(arguments.length === 2 && typeof modeRGB === "number" && typeof modeAlpha === "number")) { 81 | throw new TypeError('Expected blendEquationSeparate(number modeRGB, number modeAlpha)'); 82 | } 83 | return _blendEquationSeparate(modeRGB, modeAlpha); 84 | } 85 | 86 | var _blendFunc = gl.blendFunc; 87 | gl.blendFunc = function blendFunc(sfactor, dfactor) { 88 | if (!(arguments.length === 2 && typeof sfactor === "number" && typeof dfactor === "number")) { 89 | throw new TypeError('Expected blendFunc(number sfactor, number dfactor)'); 90 | } 91 | return _blendFunc(sfactor, dfactor); 92 | } 93 | 94 | var _blendFuncSeparate = gl.blendFuncSeparate; 95 | gl.blendFuncSeparate = function blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha) { 96 | if (!(arguments.length === 4 && typeof srcRGB === "number" && typeof dstRGB === "number" && typeof srcAlpha === "number" && typeof dstAlpha === "number")) { 97 | throw new TypeError('Expected blendFuncSeparate(number srcRGB, number dstRGB, number srcAlpha, number dstAlpha)'); 98 | } 99 | return _blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha); 100 | } 101 | 102 | var _bufferData = gl.bufferData; 103 | gl.bufferData = function bufferData(target, data, usage) { 104 | if (!(arguments.length === 3 && typeof target === "number" && typeof data === "object" && typeof usage === "number")) { 105 | throw new TypeError('Expected bufferData(number target, ArrayBuffer data, number usage)'); 106 | } 107 | return _bufferData(target, data, usage); 108 | } 109 | 110 | var _bufferSubData = gl.bufferSubData; 111 | gl.bufferSubData = function bufferSubData(target, offset, data) { 112 | if (!(arguments.length === 3 && typeof target === "number" && typeof offset === "number" && typeof data === "object")) { 113 | throw new TypeError('Expected bufferSubData(number target, number offset, ArrayBuffer data)'); 114 | } 115 | return _bufferSubData(target, offset, data); 116 | } 117 | 118 | var _checkFramebufferStatus = gl.checkFramebufferStatus; 119 | gl.checkFramebufferStatus = function checkFramebufferStatus(target) { 120 | if (!(arguments.length === 1 && typeof target === "number")) { 121 | throw new TypeError('Expected checkFramebufferStatus(number target)'); 122 | } 123 | return _checkFramebufferStatus(target); 124 | } 125 | 126 | var _clear = gl.clear; 127 | gl.clear = function clear(mask) { 128 | if (!(arguments.length === 1 && typeof mask === "number")) { 129 | throw new TypeError('Expected clear(number mask)'); 130 | } 131 | return _clear(mask); 132 | } 133 | 134 | var _clearColor = gl.clearColor; 135 | gl.clearColor = function clearColor(red, green, blue, alpha) { 136 | if (!(arguments.length === 4 && typeof red === "number" && typeof green === "number" && typeof blue === "number" && typeof alpha === "number")) { 137 | throw new TypeError('Expected clearColor(number red, number green, number blue, number alpha)'); 138 | } 139 | return _clearColor(red, green, blue, alpha); 140 | } 141 | 142 | var _clearDepth = gl.clearDepth; 143 | gl.clearDepth = function clearDepth(depth) { 144 | if (!(arguments.length === 1 && typeof depth === "number")) { 145 | throw new TypeError('Expected clearDepth(number depth)'); 146 | } 147 | return _clearDepth(depth); 148 | } 149 | 150 | var _clearStencil = gl.clearStencil; 151 | gl.clearStencil = function clearStencil(s) { 152 | if (!(arguments.length === 1 && typeof s === "number")) { 153 | throw new TypeError('Expected clearStencil(number s)'); 154 | } 155 | return _clearStencil(s); 156 | } 157 | 158 | var _colorMask = gl.colorMask; 159 | gl.colorMask = function colorMask(red, green, blue, alpha) { 160 | if (!(arguments.length === 4 && typeof red === "boolean" && typeof green === "boolean" && typeof blue === "boolean" && typeof alpha === "boolean")) { 161 | throw new TypeError('Expected colorMask(boolean red, boolean green, boolean blue, boolean alpha)'); 162 | } 163 | return _colorMask(red, green, blue, alpha); 164 | } 165 | 166 | var _compileShader = gl.compileShader; 167 | gl.compileShader = function compileShader(shader) { 168 | if (!(arguments.length === 1 && (shader === null || shader instanceof WebGLShader))) { 169 | throw new TypeError('Expected compileShader(WebGLShader shader)'); 170 | } 171 | return _compileShader(shader ? shader._ : 0); 172 | } 173 | 174 | var _copyTexImage2D = gl.copyTexImage2D; 175 | gl.copyTexImage2D = function copyTexImage2D(target, level, internalformat, x, y, width, height, border) { 176 | if (!(arguments.length === 8 && typeof target === "number" && typeof level === "number" && typeof internalformat === "number" && typeof x === "number" && typeof y === "number" && typeof width === "number" && typeof height === "number" && typeof border === "number")) { 177 | throw new TypeError('Expected copyTexImage2D(number target, number level, number internalformat, number x, number y, number width, number height, number border)'); 178 | } 179 | return _copyTexImage2D(target, level, internalformat, x, y, width, height, border); 180 | } 181 | 182 | var _copyTexSubImage2D = gl.copyTexSubImage2D; 183 | gl.copyTexSubImage2D = function copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) { 184 | if (!(arguments.length === 8 && typeof target === "number" && typeof level === "number" && typeof xoffset === "number" && typeof yoffset === "number" && typeof x === "number" && typeof y === "number" && typeof width === "number" && typeof height === "number")) { 185 | throw new TypeError('Expected copyTexSubImage2D(number target, number level, number xoffset, number yoffset, number x, number y, number width, number height)'); 186 | } 187 | return _copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); 188 | } 189 | 190 | var _createBuffer = gl.createBuffer; 191 | gl.createBuffer = function createBuffer() { 192 | if (!(arguments.length === 0)) { 193 | throw new TypeError('Expected createBuffer()'); 194 | } 195 | return new WebGLBuffer(_createBuffer()); 196 | } 197 | 198 | var _createFramebuffer = gl.createFramebuffer; 199 | gl.createFramebuffer = function createFramebuffer() { 200 | if (!(arguments.length === 0)) { 201 | throw new TypeError('Expected createFramebuffer()'); 202 | } 203 | return new WebGLFramebuffer(_createFramebuffer()); 204 | } 205 | 206 | var _createProgram = gl.createProgram; 207 | gl.createProgram = function createProgram() { 208 | if (!(arguments.length === 0)) { 209 | throw new TypeError('Expected createProgram()'); 210 | } 211 | return new WebGLProgram(_createProgram()); 212 | } 213 | 214 | var _createRenderbuffer = gl.createRenderbuffer; 215 | gl.createRenderbuffer = function createRenderbuffer() { 216 | if (!(arguments.length === 0)) { 217 | throw new TypeError('Expected createRenderbuffer()'); 218 | } 219 | return new WebGLRenderbuffer(_createRenderbuffer()); 220 | } 221 | 222 | var _createShader = gl.createShader; 223 | gl.createShader = function createShader(type) { 224 | if (!(arguments.length === 1 && typeof type === "number")) { 225 | throw new TypeError('Expected createShader(number type)'); 226 | } 227 | return new WebGLShader(_createShader(type)); 228 | } 229 | 230 | var _createTexture = gl.createTexture; 231 | gl.createTexture = function createTexture() { 232 | if (!(arguments.length === 0)) { 233 | throw new TypeError('Expected createTexture()'); 234 | } 235 | return new WebGLTexture(_createTexture()); 236 | } 237 | 238 | var _cullFace = gl.cullFace; 239 | gl.cullFace = function cullFace(mode) { 240 | if (!(arguments.length === 1 && typeof mode === "number")) { 241 | throw new TypeError('Expected cullFace(number mode)'); 242 | } 243 | return _cullFace(mode); 244 | } 245 | 246 | var _deleteBuffer = gl.deleteBuffer; 247 | gl.deleteBuffer = function deleteBuffer(buffer) { 248 | if (!(arguments.length === 1 && (buffer === null || buffer instanceof WebGLBuffer))) { 249 | throw new TypeError('Expected deleteBuffer(WebGLBuffer buffer)'); 250 | } 251 | return _deleteBuffer(buffer ? buffer._ : 0); 252 | } 253 | 254 | var _deleteFramebuffer = gl.deleteFramebuffer; 255 | gl.deleteFramebuffer = function deleteFramebuffer(framebuffer) { 256 | if (!(arguments.length === 1 && (framebuffer === null || framebuffer instanceof WebGLFramebuffer))) { 257 | throw new TypeError('Expected deleteFramebuffer(WebGLFramebuffer framebuffer)'); 258 | } 259 | return _deleteFramebuffer(framebuffer ? framebuffer._ : 0); 260 | } 261 | 262 | var _deleteProgram = gl.deleteProgram; 263 | gl.deleteProgram = function deleteProgram(program) { 264 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 265 | throw new TypeError('Expected deleteProgram(WebGLProgram program)'); 266 | } 267 | return _deleteProgram(program ? program._ : 0); 268 | } 269 | 270 | var _deleteRenderbuffer = gl.deleteRenderbuffer; 271 | gl.deleteRenderbuffer = function deleteRenderbuffer(renderbuffer) { 272 | if (!(arguments.length === 1 && (renderbuffer === null || renderbuffer instanceof WebGLRenderbuffer))) { 273 | throw new TypeError('Expected deleteRenderbuffer(WebGLRenderbuffer renderbuffer)'); 274 | } 275 | return _deleteRenderbuffer(renderbuffer ? renderbuffer._ : 0); 276 | } 277 | 278 | var _deleteShader = gl.deleteShader; 279 | gl.deleteShader = function deleteShader(shader) { 280 | if (!(arguments.length === 1 && (shader === null || shader instanceof WebGLShader))) { 281 | throw new TypeError('Expected deleteShader(WebGLShader shader)'); 282 | } 283 | return _deleteShader(shader ? shader._ : 0); 284 | } 285 | 286 | var _deleteTexture = gl.deleteTexture; 287 | gl.deleteTexture = function deleteTexture(texture) { 288 | if (!(arguments.length === 1 && (texture === null || texture instanceof WebGLTexture))) { 289 | throw new TypeError('Expected deleteTexture(WebGLTexture texture)'); 290 | } 291 | return _deleteTexture(texture ? texture._ : 0); 292 | } 293 | 294 | var _depthFunc = gl.depthFunc; 295 | gl.depthFunc = function depthFunc(func) { 296 | if (!(arguments.length === 1 && typeof func === "number")) { 297 | throw new TypeError('Expected depthFunc(number func)'); 298 | } 299 | return _depthFunc(func); 300 | } 301 | 302 | var _depthMask = gl.depthMask; 303 | gl.depthMask = function depthMask(flag) { 304 | if (!(arguments.length === 1 && typeof flag === "boolean")) { 305 | throw new TypeError('Expected depthMask(boolean flag)'); 306 | } 307 | return _depthMask(flag); 308 | } 309 | 310 | var _depthRange = gl.depthRange; 311 | gl.depthRange = function depthRange(zNear, zFar) { 312 | if (!(arguments.length === 2 && typeof zNear === "number" && typeof zFar === "number")) { 313 | throw new TypeError('Expected depthRange(number zNear, number zFar)'); 314 | } 315 | return _depthRange(zNear, zFar); 316 | } 317 | 318 | var _detachShader = gl.detachShader; 319 | gl.detachShader = function detachShader(program, shader) { 320 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && (shader === null || shader instanceof WebGLShader))) { 321 | throw new TypeError('Expected detachShader(WebGLProgram program, WebGLShader shader)'); 322 | } 323 | return _detachShader(program ? program._ : 0, shader ? shader._ : 0); 324 | } 325 | 326 | var _disable = gl.disable; 327 | gl.disable = function disable(cap) { 328 | if (!(arguments.length === 1 && typeof cap === "number")) { 329 | throw new TypeError('Expected disable(number cap)'); 330 | } 331 | return _disable(cap); 332 | } 333 | 334 | var _disableVertexAttribArray = gl.disableVertexAttribArray; 335 | gl.disableVertexAttribArray = function disableVertexAttribArray(index) { 336 | if (!(arguments.length === 1 && typeof index === "number")) { 337 | throw new TypeError('Expected disableVertexAttribArray(number index)'); 338 | } 339 | return _disableVertexAttribArray(index); 340 | } 341 | 342 | var _drawArrays = gl.drawArrays; 343 | gl.drawArrays = function drawArrays(mode, first, count) { 344 | if (!(arguments.length === 3 && typeof mode === "number" && typeof first === "number" && typeof count === "number")) { 345 | throw new TypeError('Expected drawArrays(number mode, number first, number count)'); 346 | } 347 | return _drawArrays(mode, first, count); 348 | } 349 | 350 | var _drawElements = gl.drawElements; 351 | gl.drawElements = function drawElements(mode, count, type, offset) { 352 | if (!(arguments.length === 4 && typeof mode === "number" && typeof count === "number" && typeof type === "number" && typeof offset === "number")) { 353 | throw new TypeError('Expected drawElements(number mode, number count, number type, number offset)'); 354 | } 355 | return _drawElements(mode, count, type, offset); 356 | } 357 | 358 | var _enable = gl.enable; 359 | gl.enable = function enable(cap) { 360 | if (!(arguments.length === 1 && typeof cap === "number")) { 361 | throw new TypeError('Expected enable(number cap)'); 362 | } 363 | return _enable(cap); 364 | } 365 | 366 | var _enableVertexAttribArray = gl.enableVertexAttribArray; 367 | gl.enableVertexAttribArray = function enableVertexAttribArray(index) { 368 | if (!(arguments.length === 1 && typeof index === "number")) { 369 | throw new TypeError('Expected enableVertexAttribArray(number index)'); 370 | } 371 | return _enableVertexAttribArray(index); 372 | } 373 | 374 | var _finish = gl.finish; 375 | gl.finish = function finish() { 376 | if (!(arguments.length === 0)) { 377 | throw new TypeError('Expected finish()'); 378 | } 379 | return _finish(); 380 | } 381 | 382 | var _flush = gl.flush; 383 | gl.flush = function flush() { 384 | if (!(arguments.length === 0)) { 385 | throw new TypeError('Expected flush()'); 386 | } 387 | return _flush(); 388 | } 389 | 390 | var _framebufferRenderbuffer = gl.framebufferRenderbuffer; 391 | gl.framebufferRenderbuffer = function framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) { 392 | if (!(arguments.length === 4 && typeof target === "number" && typeof attachment === "number" && typeof renderbuffertarget === "number" && (renderbuffer === null || renderbuffer instanceof WebGLRenderbuffer))) { 393 | throw new TypeError('Expected framebufferRenderbuffer(number target, number attachment, number renderbuffertarget, WebGLRenderbuffer renderbuffer)'); 394 | } 395 | return _framebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer ? renderbuffer._ : 0); 396 | } 397 | 398 | var _framebufferTexture2D = gl.framebufferTexture2D; 399 | gl.framebufferTexture2D = function framebufferTexture2D(target, attachment, textarget, texture, level) { 400 | if (!(arguments.length === 5 && typeof target === "number" && typeof attachment === "number" && typeof textarget === "number" && (texture === null || texture instanceof WebGLTexture) && typeof level === "number")) { 401 | throw new TypeError('Expected framebufferTexture2D(number target, number attachment, number textarget, WebGLTexture texture, number level)'); 402 | } 403 | return _framebufferTexture2D(target, attachment, textarget, texture ? texture._ : 0, level); 404 | } 405 | 406 | var _frontFace = gl.frontFace; 407 | gl.frontFace = function frontFace(mode) { 408 | if (!(arguments.length === 1 && typeof mode === "number")) { 409 | throw new TypeError('Expected frontFace(number mode)'); 410 | } 411 | return _frontFace(mode); 412 | } 413 | 414 | var _generateMipmap = gl.generateMipmap; 415 | gl.generateMipmap = function generateMipmap(target) { 416 | if (!(arguments.length === 1 && typeof target === "number")) { 417 | throw new TypeError('Expected generateMipmap(number target)'); 418 | } 419 | return _generateMipmap(target); 420 | } 421 | 422 | var _getActiveAttrib = gl.getActiveAttrib; 423 | gl.getActiveAttrib = function getActiveAttrib(program, index) { 424 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && typeof index === "number")) { 425 | throw new TypeError('Expected getActiveAttrib(WebGLProgram program, number index)'); 426 | } 427 | return new WebGLActiveInfo(_getActiveAttrib(program ? program._ : 0, index)); 428 | } 429 | 430 | var _getActiveUniform = gl.getActiveUniform; 431 | gl.getActiveUniform = function getActiveUniform(program, index) { 432 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && typeof index === "number")) { 433 | throw new TypeError('Expected getActiveUniform(WebGLProgram program, number index)'); 434 | } 435 | return new WebGLActiveInfo(_getActiveUniform(program ? program._ : 0, index)); 436 | } 437 | 438 | var _getAttachedShaders = gl.getAttachedShaders; 439 | gl.getAttachedShaders = function getAttachedShaders(program) { 440 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 441 | throw new TypeError('Expected getAttachedShaders(WebGLProgram program)'); 442 | } 443 | return _getAttachedShaders(program ? program._ : 0); 444 | } 445 | 446 | var _getAttribLocation = gl.getAttribLocation; 447 | gl.getAttribLocation = function getAttribLocation(program, name) { 448 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && typeof name === "string")) { 449 | throw new TypeError('Expected getAttribLocation(WebGLProgram program, string name)'); 450 | } 451 | return _getAttribLocation(program ? program._ : 0, name); 452 | } 453 | 454 | var _getParameter = gl.getParameter; 455 | gl.getParameter = function getParameter(pname) { 456 | if (!(arguments.length === 1 && typeof pname === "number")) { 457 | throw new TypeError('Expected getParameter(number pname)'); 458 | } 459 | return _getParameter(pname); 460 | } 461 | 462 | var _getBufferParameter = gl.getBufferParameter; 463 | gl.getBufferParameter = function getBufferParameter(target, pname) { 464 | if (!(arguments.length === 2 && typeof target === "number" && typeof pname === "number")) { 465 | throw new TypeError('Expected getBufferParameter(number target, number pname)'); 466 | } 467 | return _getBufferParameter(target, pname); 468 | } 469 | 470 | var _getError = gl.getError; 471 | gl.getError = function getError() { 472 | if (!(arguments.length === 0)) { 473 | throw new TypeError('Expected getError()'); 474 | } 475 | return _getError(); 476 | } 477 | 478 | var _getFramebufferAttachmentParameter = gl.getFramebufferAttachmentParameter; 479 | gl.getFramebufferAttachmentParameter = function getFramebufferAttachmentParameter(target, attachment, pname) { 480 | if (!(arguments.length === 3 && typeof target === "number" && typeof attachment === "number" && typeof pname === "number")) { 481 | throw new TypeError('Expected getFramebufferAttachmentParameter(number target, number attachment, number pname)'); 482 | } 483 | return _getFramebufferAttachmentParameter(target, attachment, pname); 484 | } 485 | 486 | var _getProgramParameter = gl.getProgramParameter; 487 | gl.getProgramParameter = function getProgramParameter(program, pname) { 488 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && typeof pname === "number")) { 489 | throw new TypeError('Expected getProgramParameter(WebGLProgram program, number pname)'); 490 | } 491 | return _getProgramParameter(program ? program._ : 0, pname); 492 | } 493 | 494 | var _getProgramInfoLog = gl.getProgramInfoLog; 495 | gl.getProgramInfoLog = function getProgramInfoLog(program) { 496 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 497 | throw new TypeError('Expected getProgramInfoLog(WebGLProgram program)'); 498 | } 499 | return _getProgramInfoLog(program ? program._ : 0); 500 | } 501 | 502 | var _getRenderbufferParameter = gl.getRenderbufferParameter; 503 | gl.getRenderbufferParameter = function getRenderbufferParameter(target, pname) { 504 | if (!(arguments.length === 2 && typeof target === "number" && typeof pname === "number")) { 505 | throw new TypeError('Expected getRenderbufferParameter(number target, number pname)'); 506 | } 507 | return _getRenderbufferParameter(target, pname); 508 | } 509 | 510 | var _getShaderParameter = gl.getShaderParameter; 511 | gl.getShaderParameter = function getShaderParameter(shader, pname) { 512 | if (!(arguments.length === 2 && (shader === null || shader instanceof WebGLShader) && typeof pname === "number")) { 513 | throw new TypeError('Expected getShaderParameter(WebGLShader shader, number pname)'); 514 | } 515 | return _getShaderParameter(shader ? shader._ : 0, pname); 516 | } 517 | 518 | var _getShaderInfoLog = gl.getShaderInfoLog; 519 | gl.getShaderInfoLog = function getShaderInfoLog(shader) { 520 | if (!(arguments.length === 1 && (shader === null || shader instanceof WebGLShader))) { 521 | throw new TypeError('Expected getShaderInfoLog(WebGLShader shader)'); 522 | } 523 | return _getShaderInfoLog(shader ? shader._ : 0); 524 | } 525 | 526 | var _getShaderSource = gl.getShaderSource; 527 | gl.getShaderSource = function getShaderSource(shader) { 528 | if (!(arguments.length === 1 && (shader === null || shader instanceof WebGLShader))) { 529 | throw new TypeError('Expected getShaderSource(WebGLShader shader)'); 530 | } 531 | return _getShaderSource(shader ? shader._ : 0); 532 | } 533 | 534 | var _getTexParameter = gl.getTexParameter; 535 | gl.getTexParameter = function getTexParameter(target, pname) { 536 | if (!(arguments.length === 2 && typeof target === "number" && typeof pname === "number")) { 537 | throw new TypeError('Expected getTexParameter(number target, number pname)'); 538 | } 539 | return _getTexParameter(target, pname); 540 | } 541 | 542 | var _getUniform = gl.getUniform; 543 | gl.getUniform = function getUniform(program, location) { 544 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && (location === null || location instanceof WebGLUniformLocation))) { 545 | throw new TypeError('Expected getUniform(WebGLProgram program, WebGLUniformLocation location)'); 546 | } 547 | return _getUniform(program ? program._ : 0, location ? location._ : 0); 548 | } 549 | 550 | var _getUniformLocation = gl.getUniformLocation; 551 | gl.getUniformLocation = function getUniformLocation(program, name) { 552 | if (!(arguments.length === 2 && (program === null || program instanceof WebGLProgram) && typeof name === "string")) { 553 | throw new TypeError('Expected getUniformLocation(WebGLProgram program, string name)'); 554 | } 555 | return new WebGLUniformLocation(_getUniformLocation(program ? program._ : 0, name)); 556 | } 557 | 558 | var _getVertexAttrib = gl.getVertexAttrib; 559 | gl.getVertexAttrib = function getVertexAttrib(index, pname) { 560 | if (!(arguments.length === 2 && typeof index === "number" && typeof pname === "number")) { 561 | throw new TypeError('Expected getVertexAttrib(number index, number pname)'); 562 | } 563 | return _getVertexAttrib(index, pname); 564 | } 565 | 566 | var _getVertexAttribOffset = gl.getVertexAttribOffset; 567 | gl.getVertexAttribOffset = function getVertexAttribOffset(index, pname) { 568 | if (!(arguments.length === 2 && typeof index === "number" && typeof pname === "number")) { 569 | throw new TypeError('Expected getVertexAttribOffset(number index, number pname)'); 570 | } 571 | return _getVertexAttribOffset(index, pname); 572 | } 573 | 574 | var _hint = gl.hint; 575 | gl.hint = function hint(target, mode) { 576 | if (!(arguments.length === 2 && typeof target === "number" && typeof mode === "number")) { 577 | throw new TypeError('Expected hint(number target, number mode)'); 578 | } 579 | return _hint(target, mode); 580 | } 581 | 582 | var _isBuffer = gl.isBuffer; 583 | gl.isBuffer = function isBuffer(buffer) { 584 | if (!(arguments.length === 1 && (buffer === null || buffer instanceof WebGLBuffer))) { 585 | throw new TypeError('Expected isBuffer(WebGLBuffer buffer)'); 586 | } 587 | return _isBuffer(buffer ? buffer._ : 0); 588 | } 589 | 590 | var _isEnabled = gl.isEnabled; 591 | gl.isEnabled = function isEnabled(cap) { 592 | if (!(arguments.length === 1 && typeof cap === "number")) { 593 | throw new TypeError('Expected isEnabled(number cap)'); 594 | } 595 | return _isEnabled(cap); 596 | } 597 | 598 | var _isFramebuffer = gl.isFramebuffer; 599 | gl.isFramebuffer = function isFramebuffer(framebuffer) { 600 | if (!(arguments.length === 1 && (framebuffer === null || framebuffer instanceof WebGLFramebuffer))) { 601 | throw new TypeError('Expected isFramebuffer(WebGLFramebuffer framebuffer)'); 602 | } 603 | return _isFramebuffer(framebuffer ? framebuffer._ : 0); 604 | } 605 | 606 | var _isProgram = gl.isProgram; 607 | gl.isProgram = function isProgram(program) { 608 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 609 | throw new TypeError('Expected isProgram(WebGLProgram program)'); 610 | } 611 | return _isProgram(program ? program._ : 0); 612 | } 613 | 614 | var _isRenderbuffer = gl.isRenderbuffer; 615 | gl.isRenderbuffer = function isRenderbuffer(renderbuffer) { 616 | if (!(arguments.length === 1 && (renderbuffer === null || renderbuffer instanceof WebGLRenderbuffer))) { 617 | throw new TypeError('Expected isRenderbuffer(WebGLRenderbuffer renderbuffer)'); 618 | } 619 | return _isRenderbuffer(renderbuffer ? renderbuffer._ : 0); 620 | } 621 | 622 | var _isShader = gl.isShader; 623 | gl.isShader = function isShader(shader) { 624 | if (!(arguments.length === 1 && (shader === null || shader instanceof WebGLShader))) { 625 | throw new TypeError('Expected isShader(WebGLShader shader)'); 626 | } 627 | return _isShader(shader ? shader._ : 0); 628 | } 629 | 630 | var _isTexture = gl.isTexture; 631 | gl.isTexture = function isTexture(texture) { 632 | if (!(arguments.length === 1 && (texture === null || texture instanceof WebGLTexture))) { 633 | throw new TypeError('Expected isTexture(WebGLTexture texture)'); 634 | } 635 | return _isTexture(texture ? texture._ : 0); 636 | } 637 | 638 | var _lineWidth = gl.lineWidth; 639 | gl.lineWidth = function lineWidth(width) { 640 | if (!(arguments.length === 1 && typeof width === "number")) { 641 | throw new TypeError('Expected lineWidth(number width)'); 642 | } 643 | return _lineWidth(width); 644 | } 645 | 646 | var _linkProgram = gl.linkProgram; 647 | gl.linkProgram = function linkProgram(program) { 648 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 649 | throw new TypeError('Expected linkProgram(WebGLProgram program)'); 650 | } 651 | return _linkProgram(program ? program._ : 0); 652 | } 653 | 654 | var _pixelStorei = gl.pixelStorei; 655 | gl.pixelStorei = function pixelStorei(pname, param) { 656 | if (!(arguments.length === 2 && typeof pname === "number" && typeof param === "number")) { 657 | throw new TypeError('Expected pixelStorei(number pname, number param)'); 658 | } 659 | return _pixelStorei(pname, param); 660 | } 661 | 662 | var _polygonOffset = gl.polygonOffset; 663 | gl.polygonOffset = function polygonOffset(factor, units) { 664 | if (!(arguments.length === 2 && typeof factor === "number" && typeof units === "number")) { 665 | throw new TypeError('Expected polygonOffset(number factor, number units)'); 666 | } 667 | return _polygonOffset(factor, units); 668 | } 669 | 670 | var _readPixels = gl.readPixels; 671 | gl.readPixels = function readPixels(x, y, width, height, format, type, pixels) { 672 | if (!(arguments.length === 7 && typeof x === "number" && typeof y === "number" && typeof width === "number" && typeof height === "number" && typeof format === "number" && typeof type === "number" && typeof pixels === "object")) { 673 | throw new TypeError('Expected readPixels(number x, number y, number width, number height, number format, number type, ArrayBufferView pixels)'); 674 | } 675 | return _readPixels(x, y, width, height, format, type, pixels); 676 | } 677 | 678 | var _renderbufferStorage = gl.renderbufferStorage; 679 | gl.renderbufferStorage = function renderbufferStorage(target, internalformat, width, height) { 680 | if (!(arguments.length === 4 && typeof target === "number" && typeof internalformat === "number" && typeof width === "number" && typeof height === "number")) { 681 | throw new TypeError('Expected renderbufferStorage(number target, number internalformat, number width, number height)'); 682 | } 683 | return _renderbufferStorage(target, internalformat, width, height); 684 | } 685 | 686 | var _sampleCoverage = gl.sampleCoverage; 687 | gl.sampleCoverage = function sampleCoverage(value, invert) { 688 | if (!(arguments.length === 2 && typeof value === "number" && typeof invert === "boolean")) { 689 | throw new TypeError('Expected sampleCoverage(number value, boolean invert)'); 690 | } 691 | return _sampleCoverage(value, invert); 692 | } 693 | 694 | var _scissor = gl.scissor; 695 | gl.scissor = function scissor(x, y, width, height) { 696 | if (!(arguments.length === 4 && typeof x === "number" && typeof y === "number" && typeof width === "number" && typeof height === "number")) { 697 | throw new TypeError('Expected scissor(number x, number y, number width, number height)'); 698 | } 699 | return _scissor(x, y, width, height); 700 | } 701 | 702 | var _shaderSource = gl.shaderSource; 703 | gl.shaderSource = function shaderSource(shader, source) { 704 | if (!(arguments.length === 2 && (shader === null || shader instanceof WebGLShader) && typeof source === "string")) { 705 | throw new TypeError('Expected shaderSource(WebGLShader shader, string source)'); 706 | } 707 | return _shaderSource(shader ? shader._ : 0, source); 708 | } 709 | 710 | var _stencilFunc = gl.stencilFunc; 711 | gl.stencilFunc = function stencilFunc(func, ref, mask) { 712 | if (!(arguments.length === 3 && typeof func === "number" && typeof ref === "number" && typeof mask === "number")) { 713 | throw new TypeError('Expected stencilFunc(number func, number ref, number mask)'); 714 | } 715 | return _stencilFunc(func, ref, mask); 716 | } 717 | 718 | var _stencilFuncSeparate = gl.stencilFuncSeparate; 719 | gl.stencilFuncSeparate = function stencilFuncSeparate(face, func, ref, mask) { 720 | if (!(arguments.length === 4 && typeof face === "number" && typeof func === "number" && typeof ref === "number" && typeof mask === "number")) { 721 | throw new TypeError('Expected stencilFuncSeparate(number face, number func, number ref, number mask)'); 722 | } 723 | return _stencilFuncSeparate(face, func, ref, mask); 724 | } 725 | 726 | var _stencilMask = gl.stencilMask; 727 | gl.stencilMask = function stencilMask(mask) { 728 | if (!(arguments.length === 1 && typeof mask === "number")) { 729 | throw new TypeError('Expected stencilMask(number mask)'); 730 | } 731 | return _stencilMask(mask); 732 | } 733 | 734 | var _stencilMaskSeparate = gl.stencilMaskSeparate; 735 | gl.stencilMaskSeparate = function stencilMaskSeparate(face, mask) { 736 | if (!(arguments.length === 2 && typeof face === "number" && typeof mask === "number")) { 737 | throw new TypeError('Expected stencilMaskSeparate(number face, number mask)'); 738 | } 739 | return _stencilMaskSeparate(face, mask); 740 | } 741 | 742 | var _stencilOp = gl.stencilOp; 743 | gl.stencilOp = function stencilOp(fail, zfail, zpass) { 744 | if (!(arguments.length === 3 && typeof fail === "number" && typeof zfail === "number" && typeof zpass === "number")) { 745 | throw new TypeError('Expected stencilOp(number fail, number zfail, number zpass)'); 746 | } 747 | return _stencilOp(fail, zfail, zpass); 748 | } 749 | 750 | var _stencilOpSeparate = gl.stencilOpSeparate; 751 | gl.stencilOpSeparate = function stencilOpSeparate(face, fail, zfail, zpass) { 752 | if (!(arguments.length === 4 && typeof face === "number" && typeof fail === "number" && typeof zfail === "number" && typeof zpass === "number")) { 753 | throw new TypeError('Expected stencilOpSeparate(number face, number fail, number zfail, number zpass)'); 754 | } 755 | return _stencilOpSeparate(face, fail, zfail, zpass); 756 | } 757 | 758 | var _texImage2D = gl.texImage2D; 759 | gl.texImage2D = function texImage2D(target, level, internalformat, width, height, border, format, type, pixels) { 760 | if (!(arguments.length === 9 && typeof target === "number" && typeof level === "number" && typeof internalformat === "number" && typeof width === "number" && typeof height === "number" && typeof border === "number" && typeof format === "number" && typeof type === "number" && typeof pixels === "object")) { 761 | throw new TypeError('Expected texImage2D(number target, number level, number internalformat, number width, number height, number border, number format, number type, ArrayBufferView pixels)'); 762 | } 763 | return _texImage2D(target, level, internalformat, width, height, border, format, type, pixels); 764 | } 765 | 766 | var _texParameterf = gl.texParameterf; 767 | gl.texParameterf = function texParameterf(target, pname, param) { 768 | if (!(arguments.length === 3 && typeof target === "number" && typeof pname === "number" && typeof param === "number")) { 769 | throw new TypeError('Expected texParameterf(number target, number pname, number param)'); 770 | } 771 | return _texParameterf(target, pname, param); 772 | } 773 | 774 | var _texParameteri = gl.texParameteri; 775 | gl.texParameteri = function texParameteri(target, pname, param) { 776 | if (!(arguments.length === 3 && typeof target === "number" && typeof pname === "number" && typeof param === "number")) { 777 | throw new TypeError('Expected texParameteri(number target, number pname, number param)'); 778 | } 779 | return _texParameteri(target, pname, param); 780 | } 781 | 782 | var _texSubImage2D = gl.texSubImage2D; 783 | gl.texSubImage2D = function texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) { 784 | if (!(arguments.length === 9 && typeof target === "number" && typeof level === "number" && typeof xoffset === "number" && typeof yoffset === "number" && typeof width === "number" && typeof height === "number" && typeof format === "number" && typeof type === "number" && typeof pixels === "object")) { 785 | throw new TypeError('Expected texSubImage2D(number target, number level, number xoffset, number yoffset, number width, number height, number format, number type, ArrayBufferView pixels)'); 786 | } 787 | return _texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); 788 | } 789 | 790 | var _uniform1f = gl.uniform1f; 791 | gl.uniform1f = function uniform1f(location, x) { 792 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number")) { 793 | throw new TypeError('Expected uniform1f(WebGLUniformLocation location, number x)'); 794 | } 795 | return _uniform1f(location ? location._ : 0, x); 796 | } 797 | 798 | var _uniform1fv = gl.uniform1fv; 799 | gl.uniform1fv = function uniform1fv(location, v) { 800 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 801 | throw new TypeError('Expected uniform1fv(WebGLUniformLocation location, FloatArray v)'); 802 | } 803 | return _uniform1fv(location ? location._ : 0, v); 804 | } 805 | 806 | var _uniform1i = gl.uniform1i; 807 | gl.uniform1i = function uniform1i(location, x) { 808 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number")) { 809 | throw new TypeError('Expected uniform1i(WebGLUniformLocation location, number x)'); 810 | } 811 | return _uniform1i(location ? location._ : 0, x); 812 | } 813 | 814 | var _uniform1iv = gl.uniform1iv; 815 | gl.uniform1iv = function uniform1iv(location, v) { 816 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 817 | throw new TypeError('Expected uniform1iv(WebGLUniformLocation location, Int32Array v)'); 818 | } 819 | return _uniform1iv(location ? location._ : 0, v); 820 | } 821 | 822 | var _uniform2f = gl.uniform2f; 823 | gl.uniform2f = function uniform2f(location, x, y) { 824 | if (!(arguments.length === 3 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number")) { 825 | throw new TypeError('Expected uniform2f(WebGLUniformLocation location, number x, number y)'); 826 | } 827 | return _uniform2f(location ? location._ : 0, x, y); 828 | } 829 | 830 | var _uniform2fv = gl.uniform2fv; 831 | gl.uniform2fv = function uniform2fv(location, v) { 832 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 833 | throw new TypeError('Expected uniform2fv(WebGLUniformLocation location, FloatArray v)'); 834 | } 835 | return _uniform2fv(location ? location._ : 0, v); 836 | } 837 | 838 | var _uniform2i = gl.uniform2i; 839 | gl.uniform2i = function uniform2i(location, x, y) { 840 | if (!(arguments.length === 3 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number")) { 841 | throw new TypeError('Expected uniform2i(WebGLUniformLocation location, number x, number y)'); 842 | } 843 | return _uniform2i(location ? location._ : 0, x, y); 844 | } 845 | 846 | var _uniform2iv = gl.uniform2iv; 847 | gl.uniform2iv = function uniform2iv(location, v) { 848 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 849 | throw new TypeError('Expected uniform2iv(WebGLUniformLocation location, Int32Array v)'); 850 | } 851 | return _uniform2iv(location ? location._ : 0, v); 852 | } 853 | 854 | var _uniform3f = gl.uniform3f; 855 | gl.uniform3f = function uniform3f(location, x, y, z) { 856 | if (!(arguments.length === 4 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number" && typeof z === "number")) { 857 | throw new TypeError('Expected uniform3f(WebGLUniformLocation location, number x, number y, number z)'); 858 | } 859 | return _uniform3f(location ? location._ : 0, x, y, z); 860 | } 861 | 862 | var _uniform3fv = gl.uniform3fv; 863 | gl.uniform3fv = function uniform3fv(location, v) { 864 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 865 | throw new TypeError('Expected uniform3fv(WebGLUniformLocation location, FloatArray v)'); 866 | } 867 | return _uniform3fv(location ? location._ : 0, v); 868 | } 869 | 870 | var _uniform3i = gl.uniform3i; 871 | gl.uniform3i = function uniform3i(location, x, y, z) { 872 | if (!(arguments.length === 4 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number" && typeof z === "number")) { 873 | throw new TypeError('Expected uniform3i(WebGLUniformLocation location, number x, number y, number z)'); 874 | } 875 | return _uniform3i(location ? location._ : 0, x, y, z); 876 | } 877 | 878 | var _uniform3iv = gl.uniform3iv; 879 | gl.uniform3iv = function uniform3iv(location, x) { 880 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "object")) { 881 | throw new TypeError('Expected uniform3iv(WebGLUniformLocation location, Int32Array x)'); 882 | } 883 | return _uniform3iv(location ? location._ : 0, x); 884 | } 885 | 886 | var _uniform4f = gl.uniform4f; 887 | gl.uniform4f = function uniform4f(location, x, y, z, w) { 888 | if (!(arguments.length === 5 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number" && typeof z === "number" && typeof w === "number")) { 889 | throw new TypeError('Expected uniform4f(WebGLUniformLocation location, number x, number y, number z, number w)'); 890 | } 891 | return _uniform4f(location ? location._ : 0, x, y, z, w); 892 | } 893 | 894 | var _uniform4fv = gl.uniform4fv; 895 | gl.uniform4fv = function uniform4fv(location, v) { 896 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof v === "object")) { 897 | throw new TypeError('Expected uniform4fv(WebGLUniformLocation location, FloatArray v)'); 898 | } 899 | return _uniform4fv(location ? location._ : 0, v); 900 | } 901 | 902 | var _uniform4i = gl.uniform4i; 903 | gl.uniform4i = function uniform4i(location, x, y, z, w) { 904 | if (!(arguments.length === 5 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "number" && typeof y === "number" && typeof z === "number" && typeof w === "number")) { 905 | throw new TypeError('Expected uniform4i(WebGLUniformLocation location, number x, number y, number z, number w)'); 906 | } 907 | return _uniform4i(location ? location._ : 0, x, y, z, w); 908 | } 909 | 910 | var _uniform4iv = gl.uniform4iv; 911 | gl.uniform4iv = function uniform4iv(location, x) { 912 | if (!(arguments.length === 2 && (location === null || location instanceof WebGLUniformLocation) && typeof x === "object")) { 913 | throw new TypeError('Expected uniform4iv(WebGLUniformLocation location, Int32Array x)'); 914 | } 915 | return _uniform4iv(location ? location._ : 0, x); 916 | } 917 | 918 | var _uniformMatrix2fv = gl.uniformMatrix2fv; 919 | gl.uniformMatrix2fv = function uniformMatrix2fv(location, transpose, value) { 920 | if (!(arguments.length === 3 && (location === null || location instanceof WebGLUniformLocation) && typeof transpose === "boolean" && typeof value === "object")) { 921 | throw new TypeError('Expected uniformMatrix2fv(WebGLUniformLocation location, boolean transpose, FloatArray value)'); 922 | } 923 | return _uniformMatrix2fv(location ? location._ : 0, transpose, value); 924 | } 925 | 926 | var _uniformMatrix3fv = gl.uniformMatrix3fv; 927 | gl.uniformMatrix3fv = function uniformMatrix3fv(location, transpose, value) { 928 | if (!(arguments.length === 3 && (location === null || location instanceof WebGLUniformLocation) && typeof transpose === "boolean" && typeof value === "object")) { 929 | throw new TypeError('Expected uniformMatrix3fv(WebGLUniformLocation location, boolean transpose, FloatArray value)'); 930 | } 931 | return _uniformMatrix3fv(location ? location._ : 0, transpose, value); 932 | } 933 | 934 | var _uniformMatrix4fv = gl.uniformMatrix4fv; 935 | gl.uniformMatrix4fv = function uniformMatrix4fv(location, transpose, value) { 936 | if (!(arguments.length === 3 && (location === null || location instanceof WebGLUniformLocation) && typeof transpose === "boolean" && typeof value === "object")) { 937 | throw new TypeError('Expected uniformMatrix4fv(WebGLUniformLocation location, boolean transpose, FloatArray value)'); 938 | } 939 | return _uniformMatrix4fv(location ? location._ : 0, transpose, value); 940 | } 941 | 942 | var _useProgram = gl.useProgram; 943 | gl.useProgram = function useProgram(program) { 944 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 945 | throw new TypeError('Expected useProgram(WebGLProgram program)'); 946 | } 947 | return _useProgram(program ? program._ : 0); 948 | } 949 | 950 | var _validateProgram = gl.validateProgram; 951 | gl.validateProgram = function validateProgram(program) { 952 | if (!(arguments.length === 1 && (program === null || program instanceof WebGLProgram))) { 953 | throw new TypeError('Expected validateProgram(WebGLProgram program)'); 954 | } 955 | return _validateProgram(program ? program._ : 0); 956 | } 957 | 958 | var _vertexAttrib1f = gl.vertexAttrib1f; 959 | gl.vertexAttrib1f = function vertexAttrib1f(indx, x) { 960 | if (!(arguments.length === 2 && typeof indx === "number" && typeof x === "number")) { 961 | throw new TypeError('Expected vertexAttrib1f(number indx, number x)'); 962 | } 963 | return _vertexAttrib1f(indx, x); 964 | } 965 | 966 | var _vertexAttrib1fv = gl.vertexAttrib1fv; 967 | gl.vertexAttrib1fv = function vertexAttrib1fv(indx, values) { 968 | if (!(arguments.length === 2 && typeof indx === "number" && typeof values === "object")) { 969 | throw new TypeError('Expected vertexAttrib1fv(number indx, FloatArray values)'); 970 | } 971 | return _vertexAttrib1fv(indx, values); 972 | } 973 | 974 | var _vertexAttrib2f = gl.vertexAttrib2f; 975 | gl.vertexAttrib2f = function vertexAttrib2f(indx, x, y) { 976 | if (!(arguments.length === 3 && typeof indx === "number" && typeof x === "number" && typeof y === "number")) { 977 | throw new TypeError('Expected vertexAttrib2f(number indx, number x, number y)'); 978 | } 979 | return _vertexAttrib2f(indx, x, y); 980 | } 981 | 982 | var _vertexAttrib2fv = gl.vertexAttrib2fv; 983 | gl.vertexAttrib2fv = function vertexAttrib2fv(indx, values) { 984 | if (!(arguments.length === 2 && typeof indx === "number" && typeof values === "object")) { 985 | throw new TypeError('Expected vertexAttrib2fv(number indx, FloatArray values)'); 986 | } 987 | return _vertexAttrib2fv(indx, values); 988 | } 989 | 990 | var _vertexAttrib3f = gl.vertexAttrib3f; 991 | gl.vertexAttrib3f = function vertexAttrib3f(indx, x, y, z) { 992 | if (!(arguments.length === 4 && typeof indx === "number" && typeof x === "number" && typeof y === "number" && typeof z === "number")) { 993 | throw new TypeError('Expected vertexAttrib3f(number indx, number x, number y, number z)'); 994 | } 995 | return _vertexAttrib3f(indx, x, y, z); 996 | } 997 | 998 | var _vertexAttrib3fv = gl.vertexAttrib3fv; 999 | gl.vertexAttrib3fv = function vertexAttrib3fv(indx, values) { 1000 | if (!(arguments.length === 2 && typeof indx === "number" && typeof values === "object")) { 1001 | throw new TypeError('Expected vertexAttrib3fv(number indx, FloatArray values)'); 1002 | } 1003 | return _vertexAttrib3fv(indx, values); 1004 | } 1005 | 1006 | var _vertexAttrib4f = gl.vertexAttrib4f; 1007 | gl.vertexAttrib4f = function vertexAttrib4f(indx, x, y, z, w) { 1008 | if (!(arguments.length === 5 && typeof indx === "number" && typeof x === "number" && typeof y === "number" && typeof z === "number" && typeof w === "number")) { 1009 | throw new TypeError('Expected vertexAttrib4f(number indx, number x, number y, number z, number w)'); 1010 | } 1011 | return _vertexAttrib4f(indx, x, y, z, w); 1012 | } 1013 | 1014 | var _vertexAttrib4fv = gl.vertexAttrib4fv; 1015 | gl.vertexAttrib4fv = function vertexAttrib4fv(indx, values) { 1016 | if (!(arguments.length === 2 && typeof indx === "number" && typeof values === "object")) { 1017 | throw new TypeError('Expected vertexAttrib4fv(number indx, FloatArray values)'); 1018 | } 1019 | return _vertexAttrib4fv(indx, values); 1020 | } 1021 | 1022 | var _vertexAttribPointer = gl.vertexAttribPointer; 1023 | gl.vertexAttribPointer = function vertexAttribPointer(indx, size, type, normalized, stride, offset) { 1024 | if (!(arguments.length === 6 && typeof indx === "number" && typeof size === "number" && typeof type === "number" && typeof normalized === "boolean" && typeof stride === "number" && typeof offset === "number")) { 1025 | throw new TypeError('Expected vertexAttribPointer(number indx, number size, number type, boolean normalized, number stride, number offset)'); 1026 | } 1027 | return _vertexAttribPointer(indx, size, type, normalized, stride, offset); 1028 | } 1029 | 1030 | var _viewport = gl.viewport; 1031 | gl.viewport = function viewport(x, y, width, height) { 1032 | if (!(arguments.length === 4 && typeof x === "number" && typeof y === "number" && typeof width === "number" && typeof height === "number")) { 1033 | throw new TypeError('Expected viewport(number x, number y, number width, number height)'); 1034 | } 1035 | return _viewport(x, y, width, height); 1036 | } 1037 | 1038 | //////////////////////////////////////////////////////////////////////////////// 1039 | 1040 | function WebGLProgram(_) { this._ = _; } 1041 | function WebGLShader(_) { this._ = _; } 1042 | function WebGLBuffer(_) { this._ = _; } 1043 | function WebGLFramebuffer(_) { this._ = _; } 1044 | function WebGLRenderbuffer(_) { this._ = _; } 1045 | function WebGLTexture(_) { this._ = _; } 1046 | function WebGLActiveInfo(_) { this._ = _; } 1047 | function WebGLUniformLocation(_) { this._ = _; } 1048 | -------------------------------------------------------------------------------- /wscript: -------------------------------------------------------------------------------- 1 | from os import popen 2 | import sys 3 | 4 | srcdir = '.' 5 | blddir = 'build' 6 | VERSION = '0.0.0' 7 | 8 | def set_options(opt): 9 | opt.tool_options('compiler_cxx') 10 | 11 | def configure(conf): 12 | conf.check_tool('compiler_cxx') 13 | conf.check_tool('node_addon') 14 | 15 | 16 | def build(bld): 17 | obj = bld.new_task_gen('cxx', 'shlib', 'node_addon') 18 | obj.target = "node-webgl" 19 | obj.cxxflags = ["-pthread", "-Wall"] 20 | 21 | if sys.platform.startswith('darwin'): 22 | obj.uselib = ["GL", "GLU", "GLUT"] 23 | obj.framework = ['OpenGL','GLUT','Cocoa'] 24 | else: 25 | obj.linkflags = ["-lGLESv2"] 26 | 27 | obj.source = ["src/webgl.cc", "src/v8_typed_array.cc"] 28 | # obj.uselib = "SDL" 29 | --------------------------------------------------------------------------------