UNPKG

@quartic/bokehjs

Version:

Interactive, novel data visualization

887 lines (837 loc) 40.2 kB
/* Do not edit, autogenerated by flexx.pyscript */ (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define([], factory); } else if (typeof exports !== 'undefined') { // Node or CommonJS module.exports = factory(); if (typeof window === 'undefined') { root.gloo2 = module.exports; // also create global module in Node } } else { // Browser globals (root is window) root.gloo2 = factory(); } }(this, function () { var _pyfunc_add = function (a, b) { // nargs: 2 if (Array.isArray(a) && Array.isArray(b)) { return a.concat(b); } return a + b; }; var _pyfunc_all = function (x) { // nargs: 1 for (var i=0; i<x.length; i++) { if (!_pyfunc_truthy(x[i])){return false;} } return true; }; var _pyfunc_contains = function contains (a, b) { // nargs: 2 if (b == null) { } else if (Array.isArray(b)) { for (var i=0; i<b.length; i++) {if (_pyfunc_equals(a, b[i])) return true;} return false; } else if (b.constructor === Object) { for (var k in b) {if (a == k) return true;} return false; } else if (b.constructor == String) { return b.indexOf(a) >= 0; } var e = Error('Not a container: ' + b); e.name='TypeError'; throw e; }; var _pyfunc_equals = function equals (a, b) { // nargs: 2 if (a == null || b == null) { } else if (Array.isArray(a) && Array.isArray(b)) { var i = 0, iseq = a.length == b.length; while (iseq && i < a.length) {iseq = equals(a[i], b[i]); i+=1;} return iseq; } else if (a.constructor === Object && b.constructor === Object) { var akeys = Object.keys(a), bkeys = Object.keys(b); akeys.sort(); bkeys.sort(); var i=0, k, iseq = equals(akeys, bkeys); while (iseq && i < akeys.length) {k=akeys[i]; iseq = equals(a[k], b[k]); i+=1;} return iseq; } return a == b; }; var _pyfunc_instantiate = function (ob, args) { // nargs: 2 if ((typeof ob === "undefined") || (typeof window !== "undefined" && window === ob) || (typeof global !== "undefined" && global === ob)) {throw "Class constructor is called as a function.";} for (var name in ob) { if (Object[name] === undefined && typeof ob[name] === 'function' && !ob[name].nobind) { ob[name] = ob[name].bind(ob); } } if (ob.__init__) { ob.__init__.apply(ob, args); } }; var _pyfunc_mult = function (a, b) { // nargs: 2 if ((typeof a === 'number') + (typeof b === 'number') === 1) { if (a.constructor === String) return _pymeth_repeat.call(a, b); if (b.constructor === String) return _pymeth_repeat.call(b, a); if (Array.isArray(b)) {var t=a; a=b; b=t;} if (Array.isArray(a)) { var res = []; for (var i=0; i<b; i++) res = res.concat(a); return res; } } return a * b; }; var _pyfunc_range = function (start, end, step) { var i, res = []; var val = start; var n = (end - start) / step; for (i=0; i<n; i++) { res.push(val); val += step; } return res; }; var _pyfunc_truthy = function (v) { if (v === null || typeof v !== "object") {return v;} else if (v.length !== undefined) {return v.length ? v : false;} else if (v.byteLength !== undefined) {return v.byteLength ? v : false;} else if (v.constructor !== Object) {return true;} else {return Object.getOwnPropertyNames(v).length ? v : false;} }; var _pymeth_append = function (x) { // nargs: 1 if (!Array.isArray(this)) return this.append.apply(this, arguments); this.push(x); }; var _pymeth_get = function (key, d) { // nargs: 1 2 if (this.constructor !== Object) return this.get.apply(this, arguments); if (this[key] !== undefined) {return this[key];} else if (d !== undefined) {return d;} else {return null;} }; var _pymeth_keys = function () { // nargs: 0 if (typeof this['keys'] === 'function') return this.keys.apply(this, arguments); return Object.keys(this); }; var _pymeth_lstrip = function (chars) { // nargs: 0 1 if (this.constructor !== String) return this.lstrip.apply(this, arguments); chars = (chars === undefined) ? ' \t\r\n' : chars; for (var i=0; i<this.length; i++) { if (chars.indexOf(this[i]) < 0) return this.slice(i); } return ''; }; var _pymeth_remove = function (x) { // nargs: 1 if (!Array.isArray(this)) return this.remove.apply(this, arguments); for (var i=0; i<this.length; i++) { if (_pyfunc_equals(this[i], x)) {this.splice(i, 1); return;} } var e = Error(x); e.name='ValueError'; throw e; }; var _pymeth_repeat = function(count) { // nargs: 0 if (this.repeat) return this.repeat(count); if (count < 1) return ''; var result = '', pattern = this.valueOf(); while (count > 1) { if (count & 1) result += pattern; count >>= 1, pattern += pattern; } return result + pattern; }; var _pymeth_startswith = function (x) { // nargs: 1 if (this.constructor !== String) return this.startswith.apply(this, arguments); return this.indexOf(x) == 0; }; var Buffer, GlooObject, IndexBuffer, Program, Texture2D, Texture3DLike, VertexBuffer, __version__, check_error, console; // PyScript module for gloo2.js - lightweight object oriented GL. { /* if this_is_js() */ console = window.console; } __version__ = "0.3"; check_error = function (gl, when) { var e, err, err_3, errors, msg, stub1_seq, stub2_itr; when = (when === undefined) ? "periodic check": when; // Check this from time to time to detect GL errors. // // Parameters // ---------- // when : str // Shown in the exception to help the developer determine when // this check was done. errors = []; while (true) { err = gl.getError(); if ((_pyfunc_equals(err, gl.NO_ERROR) || (_pyfunc_truthy(errors) && _pyfunc_equals(err, errors[errors.length -1])))) { break; } _pymeth_append.call(errors, err); } if (errors.length) { msg = ""; stub1_seq = errors; if ((typeof stub1_seq === "object") && (!Array.isArray(stub1_seq))) { stub1_seq = Object.keys(stub1_seq); } for (stub2_itr = 0; stub2_itr < stub1_seq.length; stub2_itr += 1) { e = stub1_seq[stub2_itr]; msg=_pyfunc_add(msg, e) } err_3 = new Error('RuntimeError:' + ("OpenGL got errors (" + when + "): " + msg + "")); err_3.name = "RuntimeError"; throw err_3; } return null; }; GlooObject = function () { // Abstract base class for all Gloo classes. _pyfunc_instantiate(this, arguments); } GlooObject.prototype._base_class = Object; GlooObject.prototype._class_name = "GlooObject"; GlooObject.prototype.__init__ = function (gl) { // Init by passing the webgl context object. this._gl = gl; this.handle = null; this._create(); if (!(this.handle !== null)) {throw "AssertionError: " + "this.handle !== null";} return null; }; GlooObject.prototype._create = function () { var err_2; err_2 = new Error('NotImplementedError:' + ""); err_2.name = "NotImplementedError"; throw err_2; return null; }; Program = function () { // The program is the central component to connect gloo objects and shaders. _pyfunc_instantiate(this, arguments); } Program.prototype = Object.create(GlooObject.prototype); Program.prototype._base_class = GlooObject.prototype; Program.prototype._class_name = "Program"; Program.prototype.UTYPEMAP = {"float": "uniform1fv", "vec2": "uniform2fv", "vec3": "uniform3fv", "vec4": "uniform4fv", "int": "uniform1iv", "ivec2": "uniform2iv", "ivec3": "uniform3iv", "ivec4": "uniform4iv", "bool": "uniform1iv", "bvec2": "uniform2iv", "bvec3": "uniform3iv", "bvec4": "uniform4iv", "mat2": "uniformMatrix2fv", "mat3": "uniformMatrix3fv", "mat4": "uniformMatrix4fv", "sampler1D": "uniform1i", "sampler2D": "uniform1i", "sampler3D": "uniform1i"}; Program.prototype.ATYPEMAP = {"float": "vertexAttrib1f", "vec2": "vertexAttrib2f", "vec3": "vertexAttrib3f", "vec4": "vertexAttrib4f"}; Program.prototype.ATYPEINFO = {"float": [1, 5126], "vec2": [2, 5126], "vec3": [3, 5126], "vec4": [4, 5126]}; Program.prototype._create = function () { this.handle = this._gl.createProgram(); this.locations = {}; this._unset_variables = []; this._validated = false; this._samplers = {}; this._attributes = {}; this._known_invalid = []; return null; }; Program.prototype.delete = function () { // Delete the program. this._gl.deleteProgram(this.handle); return null; }; Program.prototype.activate = function () { // Activate the program. this._gl.useProgram(this.handle); return null; }; Program.prototype.deactivate = function () { // Disable the program. this._gl.useProgram(0); return null; }; Program.prototype.set_shaders = function (vert, frag) { var code, err_3, err_4, errors, frag_handle, gl, handle, i, status, stub3_, tmp, type_, vert_handle; // Set GLSL code for the vertex and fragment shader. // // This function takes care of setting the shading code and // compiling+linking it into a working program object that is ready // to use. // // Parameters // ---------- // vert : str // GLSL code for the vertex shader. // frag : str // GLSL code for the fragment shader. gl = this._gl; this._linked = false; vert_handle = gl.createShader(gl.VERTEX_SHADER); frag_handle = gl.createShader(gl.FRAGMENT_SHADER); tmp = [[vert, vert_handle, "vertex"], [frag, frag_handle, "fragment"]]; for (i = 0; i < 2; i += 1) { stub3_ = tmp[i]; code = stub3_[0];handle = stub3_[1];type_ = stub3_[2]; gl.shaderSource(handle, code); gl.compileShader(handle); status = gl.getShaderParameter(handle, gl.COMPILE_STATUS); if ((!_pyfunc_truthy(status))) { errors = gl.getShaderInfoLog(handle); err_4 = new Error('RuntimeError:' + (_pyfunc_add((("errors in " + type_) + " shader:\n"), errors))); err_4.name = "RuntimeError"; throw err_4; } } gl.attachShader(this.handle, vert_handle); gl.attachShader(this.handle, frag_handle); gl.linkProgram(this.handle); if ((!_pyfunc_truthy(gl.getProgramParameter(this.handle, gl.LINK_STATUS)))) { err_3 = new Error('RuntimeError:' + ("Program link error:\n" + gl.getProgramInfoLog(this.handle))); err_3.name = "RuntimeError"; throw err_3; } this._unset_variables = this._get_active_attributes_and_uniforms(); gl.detachShader(this.handle, vert_handle); gl.detachShader(this.handle, frag_handle); gl.deleteShader(vert_handle); gl.deleteShader(frag_handle); this._known_invalid = []; this._linked = true; return null; }; Program.prototype._get_active_attributes_and_uniforms = function () { var attributes, ca, container, count, cu, getActive, getLocation, gl, i, info, j, m, name, regex, stub4_, stub5_seq, stub6_itr, uniforms, x; // Retrieve active attributes and uniforms to be able to check that // all uniforms/attributes are set by the user. gl = this._gl; this.locations = {}; regex = new window.RegExp("(\\w+)\\s*(\\[(\\d+)\\])\\s*"); cu = gl.getProgramParameter(this.handle, gl.ACTIVE_UNIFORMS); ca = gl.getProgramParameter(this.handle, gl.ACTIVE_ATTRIBUTES); attributes = []; uniforms = []; stub5_seq = [[attributes, ca, gl.getActiveAttrib, gl.getAttribLocation], [uniforms, cu, gl.getActiveUniform, gl.getUniformLocation]]; if ((typeof stub5_seq === "object") && (!Array.isArray(stub5_seq))) { stub5_seq = Object.keys(stub5_seq); } for (stub6_itr = 0; stub6_itr < stub5_seq.length; stub6_itr += 1) { x = stub5_seq[stub6_itr]; stub4_ = x; container = stub4_[0];count = stub4_[1];getActive = stub4_[2];getLocation = stub4_[3]; for (i = 0; i < count; i += 1) { info = getActive.call(gl, this.handle, i); name = info.name; m = name.match(regex); if (_pyfunc_truthy(m)) { name = m[1]; for (j = 0; j < info.size; j += 1) { _pymeth_append.call(container, (["" + name + "[" + j + "]", info.type])); } } else { _pymeth_append.call(container, [name, info.type]); } this.locations[name] = getLocation.call(gl, this.handle, name); } } return _pyfunc_add(((function list_comprehenson () {var res = [];var v, iter0, i0;iter0 = attributes;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {v = iter0[i0];{res.push(v[0]);}}return res;}).apply(this)), ((function list_comprehenson () {var res = [];var v, iter0, i0;iter0 = uniforms;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {v = iter0[i0];{res.push(v[0]);}}return res;}).apply(this))); }; Program.prototype.set_texture = function (name, value) { var err_3, handle, unit; // Set a texture sampler. // // A texture is a 2 dimensional grid of colors/intensities that // can be applied to a face (or used for other means by providing // a regular grid of data). // // Parameters // ---------- // name : str // The name by which the texture is known in the GLSL code. // value : Texture2D // The gloo Texture2D object to bind. if ((!_pyfunc_truthy(this._linked))) { err_3 = new Error('RuntimeError:' + "Cannot set uniform when program has no code"); err_3.name = "RuntimeError"; throw err_3; } handle = _pymeth_get.call(this.locations, name, (-1)); if (_pyfunc_truthy(handle < 0)) { if ((!_pyfunc_contains(name, this._known_invalid))) { _pymeth_append.call(this._known_invalid, name); console.log("Variable " + name + " is not an active texture"); } return null; } if (_pyfunc_contains(name, this._unset_variables)) { _pymeth_remove.call(this._unset_variables, name); } this.activate(); if (true) { unit = _pymeth_keys.call(this._samplers).length; if (_pyfunc_contains(name, this._samplers)) { unit = this._samplers[name][this._samplers[name].length -1]; } this._samplers[name] = [value._target, value.handle, unit]; this._gl.uniform1i(handle, unit); } return null; }; Program.prototype.set_uniform = function (name, type_, value) { var a_type, count, err_3, funcname, handle, j, name_; // Set a uniform value. // // A uniform is a value that is global to both the vertex and // fragment shader. // // Parameters // ---------- // name : str // The name by which the uniform is known in the GLSL code. // type_ : str // The type of the uniform, e.g. 'float', 'vec2', etc. // value : list of scalars // The value for the uniform. Should be a list even for type float. if ((!_pyfunc_truthy(this._linked))) { err_3 = new Error('RuntimeError:' + "Cannot set uniform when program has no code"); err_3.name = "RuntimeError"; throw err_3; } handle = _pymeth_get.call(this.locations, name, (-1)); if (_pyfunc_truthy(handle < 0)) { if ((!_pyfunc_contains(name, this._known_invalid))) { _pymeth_append.call(this._known_invalid, name); console.log("Variable " + name + " is not an active uniform"); } return null; } if (_pyfunc_contains(name, this._unset_variables)) { _pymeth_remove.call(this._unset_variables, name); } count = 1; if ((!_pymeth_startswith.call(type_, "mat"))) { a_type = _pymeth_get.call({"int": "float", "bool": "float"}, type_, _pymeth_lstrip.call(type_, "ib")); count = Math.floor(value.length/(this.ATYPEINFO[a_type][0])); } if (_pyfunc_truthy(count > 1)) { for (j = 0; j < count; j += 1) { if ((_pyfunc_contains(("" + name + "[" + j + "]"), this._unset_variables))) { name_ = "" + name + "[" + j + "]"; if (_pyfunc_contains(name_, this._unset_variables)) { _pymeth_remove.call(this._unset_variables, name_); } } } } funcname = this.UTYPEMAP[type_]; this.activate(); if (_pymeth_startswith.call(type_, "mat")) { this._gl[funcname](handle, false, value); } else { this._gl[funcname](handle, value); } return null; }; Program.prototype.set_attribute = function (name, type_, value, stride, offset) { var args, err_3, funcname, gtype, handle, is_vbo, size, stub7_; stride = (stride === undefined) ? 0: stride; offset = (offset === undefined) ? 0: offset; // Set an attribute value. // // An attribute represents per-vertex data and can only be used // in the vertex shader. // // Parameters // ---------- // name : str // The name by which the attribute is known in the GLSL code. // type_ : str // The type of the attribute, e.g. 'float', 'vec2', etc. // value : VertexBuffer, array // If value is a VertexBuffer, it is used (with stride and offset) // for the vertex data. If value is an array, its used to set // the value of all vertices (similar to a uniform). // stide : int, default 0 // The stride to "sample" the vertex data inside the buffer. Unless // multiple vertex data are packed into a single buffer, this should // be zero. // offset : int, default 0 // The offset to "sample" the vertex data inside the buffer. Unless // multiple vertex data are packed into a single buffer, or only // a part of the data must be used, this should probably be zero. if ((!_pyfunc_truthy(this._linked))) { err_3 = new Error('RuntimeError:' + "Cannot set attribute when program has no code"); err_3.name = "RuntimeError"; throw err_3; } is_vbo = value instanceof VertexBuffer; handle = _pymeth_get.call(this.locations, name, (-1)); if (_pyfunc_truthy(handle < 0)) { if ((!_pyfunc_contains(name, this._known_invalid))) { _pymeth_append.call(this._known_invalid, name); if ((_pyfunc_truthy(is_vbo) && _pyfunc_truthy(offset > 0))) { } else { console.log("Variable " + name + " is not an active attribute"); } } return null; } if (_pyfunc_contains(name, this._unset_variables)) { _pymeth_remove.call(this._unset_variables, name); } this.activate(); if ((!_pyfunc_truthy(is_vbo))) { funcname = this.ATYPEMAP[type_]; this._attributes[name] = [0, handle, funcname, value]; } else { stub7_ = this.ATYPEINFO[type_]; size = stub7_[0];gtype = stub7_[1]; funcname = "vertexAttribPointer"; args = [size, gtype, this._gl.FALSE, stride, offset]; this._attributes[name] = [value.handle, handle, funcname, args]; } return null; }; Program.prototype._pre_draw = function () { var args, attr_handle, funcname, stub10_, stub11_seq, stub8_, stub9_seq, tex_handle, tex_target, unit, vbo_handle, x; // Prepare for drawing. this.activate(); stub9_seq = this._samplers; for (x in stub9_seq) { if (!stub9_seq.hasOwnProperty(x)){ continue; } x = stub9_seq[x]; stub8_ = x; tex_target = stub8_[0];tex_handle = stub8_[1];unit = stub8_[2]; this._gl.activeTexture(_pyfunc_add(this._gl.TEXTURE0, unit)); this._gl.bindTexture(tex_target, tex_handle); } stub11_seq = this._attributes; for (x in stub11_seq) { if (!stub11_seq.hasOwnProperty(x)){ continue; } x = stub11_seq[x]; stub10_ = x; vbo_handle = stub10_[0];attr_handle = stub10_[1];funcname = stub10_[2];args = stub10_[3]; if (_pyfunc_truthy(vbo_handle)) { this._gl.bindBuffer(this._gl.ARRAY_BUFFER, vbo_handle); this._gl.enableVertexAttribArray(attr_handle); this._gl[funcname].apply(this._gl, [].concat([attr_handle], args)); } else { this._gl.bindBuffer(this._gl.ARRAY_BUFFER, null); this._gl.disableVertexAttribArray(attr_handle); this._gl[funcname].apply(this._gl, [].concat([attr_handle], args)); } } if ((!_pyfunc_truthy(this._validated))) { this._validated = true; this._validate(); } return null; }; Program.prototype._validate = function () { var err_3; if (this._unset_variables.length) { console.log("Program has unset variables: " + this._unset_variables + ""); } this._gl.validateProgram(this.handle); if ((!_pyfunc_truthy(this._gl.getProgramParameter(this.handle, this._gl.VALIDATE_STATUS)))) { console.log(this._gl.getProgramInfoLog(this.handle)); err_3 = new Error('RuntimeError:' + "Program validation error"); err_3.name = "RuntimeError"; throw err_3; } return null; }; Program.prototype.draw = function (mode, selection) { var count, err_3, first, gtype, stub12_; // Draw the current visualization defined by the program. // // Parameters // ---------- // mode : GL enum // Can be POINTS, LINES, LINE_LOOP, LINE_STRIP, LINE_FAN, TRIANGLES // selection : 2-element tuple or IndexBuffer // The selection to draw, specified either as (first, count) or an // IndexBuffer object. if ((!_pyfunc_truthy(this._linked))) { err_3 = new Error('RuntimeError:' + "Cannot draw program if code has not been set"); err_3.name = "RuntimeError"; throw err_3; } check_error(this._gl, "before draw"); if (_pyfunc_truthy(selection instanceof IndexBuffer)) { this._pre_draw(); selection.activate(); count = selection._buffer_size / 2; gtype = this._gl.UNSIGNED_SHORT; this._gl.drawElements(mode, count, gtype, 0); selection.deactivate(); } else { stub12_ = selection; first = stub12_[0];count = stub12_[1]; if (_pyfunc_truthy(count)) { this._pre_draw(); this._gl.drawArrays(mode, first, count); } } check_error(this._gl, "after draw"); return null; }; Buffer = function () { // Base buffer class for vertex data or index data. _pyfunc_instantiate(this, arguments); } Buffer.prototype = Object.create(GlooObject.prototype); Buffer.prototype._base_class = GlooObject.prototype; Buffer.prototype._class_name = "Buffer"; Buffer.prototype._target = null; Buffer.prototype._usage = 35048; Buffer.prototype._create = function () { this.handle = this._gl.createBuffer(); this._buffer_size = 0; return null; }; Buffer.prototype.delete = function () { // Delete the buffer. this._gl.deleteBuffer(this.handle); return null; }; Buffer.prototype.activate = function () { // Activete the buffer. this._gl.bindBuffer(this._target, this.handle); return null; }; Buffer.prototype.deactivate = function () { // Disable the buffer. this._gl.bindBuffer(this._target, null); return null; }; Buffer.prototype.set_size = function (nbytes) { // Set the size of the buffer in bytes. // // Parameters // ---------- // nbytes : int // The number of bytes that the buffer needs to hold. if ((!_pyfunc_equals(nbytes, this._buffer_size))) { this.activate(); this._gl.bufferData(this._target, nbytes, this._usage); this._buffer_size = nbytes; } return null; }; Buffer.prototype.set_data = function (offset, data) { // Set the buffer data. // // Parameters // ---------- // offset : int // The offset in bytes for the new data. // data : typed array // The data to upload. this.activate(); this._gl.bufferSubData(this._target, offset, data); return null; }; VertexBuffer = function () { // A buffer for vertex data. _pyfunc_instantiate(this, arguments); } VertexBuffer.prototype = Object.create(Buffer.prototype); VertexBuffer.prototype._base_class = Buffer.prototype; VertexBuffer.prototype._class_name = "VertexBuffer"; VertexBuffer.prototype._target = 34962; IndexBuffer = function () { // A buffer for index data. _pyfunc_instantiate(this, arguments); } IndexBuffer.prototype = Object.create(Buffer.prototype); IndexBuffer.prototype._base_class = Buffer.prototype; IndexBuffer.prototype._class_name = "IndexBuffer"; IndexBuffer.prototype._target = 34963; Texture2D = function () { // A 2 dimensional regular grid. _pyfunc_instantiate(this, arguments); } Texture2D.prototype = Object.create(GlooObject.prototype); Texture2D.prototype._base_class = GlooObject.prototype; Texture2D.prototype._class_name = "Texture2D"; Texture2D.prototype._target = 3553; Texture2D.prototype._types = {"Int8Array": 5120, "Uint8Array": 5121, "Int16Array": 5122, "Uint16Array": 5123, "Int32Array": 5124, "Uint32Array": 5125, "Float32Array": 5126}; Texture2D.prototype._create = function () { this.handle = this._gl.createTexture(); this._shape_format = null; return null; }; Texture2D.prototype.delete = function () { // Delete the texture. this._gl.deleteTexture(this.handle); return null; }; Texture2D.prototype.activate = function () { // Activate the texture. this._gl.bindTexture(this._target, this.handle); return null; }; Texture2D.prototype.deactivate = function () { // Disable the texture. this._gl.bindTexture(this._target, 0); return null; }; Texture2D.prototype._get_alignment = function (width) { var alignment, alignments, stub13_seq, stub14_itr; // Determines a textures byte alignment. If the width isn't a // power of 2 we need to adjust the byte alignment of the image. // The image height is unimportant. // // www.opengl.org/wiki/Common_Mistakes#Texture_upload_and_pixel_reads alignments = [4, 8, 2, 1]; stub13_seq = alignments; if ((typeof stub13_seq === "object") && (!Array.isArray(stub13_seq))) { stub13_seq = Object.keys(stub13_seq); } for (stub14_itr = 0; stub14_itr < stub13_seq.length; stub14_itr += 1) { alignment = stub13_seq[stub14_itr]; if ((_pyfunc_equals((width % alignment), 0))) { return alignment; } } return null; }; Texture2D.prototype.set_wrapping = function (wrap_s, wrap_t) { // Set the texture wrapping mode. // // Parameters // ---------- // wrap_s : GL enum // The mode to wrap the x dimension. Valid values are REPEAT // CLAMP_TO_EDGE MIRRORED_REPEAT // wrap_t : GL enum // The mode to wrap the y dimension. Same options as for wrap_s. this.activate(); this._gl.texParameterf(this._target, this._gl.TEXTURE_WRAP_S, wrap_s); this._gl.texParameterf(this._target, this._gl.TEXTURE_WRAP_T, wrap_t); return null; }; Texture2D.prototype.set_interpolation = function (min, mag) { // Set the texture interpolation mode // // Parameters // ---------- // min : GL enum // The interpolation mode when minifying (i.e. zoomed out). Valid // values are LINEAR and NEAREST. // max : GL enum // The interpolation mode when magnifying (i.e. zoomed in). Valid // values are LINEAR, NEAREST, NEAREST_MIPMAP_NEAREST, // LINEAR_MIPMAP_NEAREST, NEAREST_MIPMAP_LINEAR, LINEAR_MIPMAP_LINEAR. this.activate(); this._gl.texParameterf(this._target, this._gl.TEXTURE_MIN_FILTER, min); this._gl.texParameterf(this._target, this._gl.TEXTURE_MAG_FILTER, mag); return null; }; Texture2D.prototype.set_size = function (shape, format) { var height, stub15_, width; // Set the size of the 2D texture. // // Parameters // ---------- // shape : tuple of ints // The shape of the data to upload // format : GL enum // The format of the texture data. Can be LUMINANCE, LUMINANCE_ALPHA, // RGB, and RGBA. stub15_ = shape; height = stub15_[0];width = stub15_[1]; if ((!_pyfunc_equals([height, width, format], this._shape_format))) { this._shape_format = [height, width, format]; this.activate(); this._gl.texImage2D(this._target, 0, format, width, height, 0, format, this._gl.UNSIGNED_BYTE, null); } this.u_shape = [height, width]; return null; }; Texture2D.prototype.set_data = function (offset, shape, data) { var _, alignment, err_3, format, gtype, height, stub16_, stub17_, width, x, y; // Set the 2D texture data. // // Parameters // ---------- // offset : tuple of ints // Offset in pixels for each dimension. // shape : tuple of ints // The shape of the data to upload // data : typed array // The actual pixel data. Can be of any type, but on the GPU the // dat is stored in 8 bit precision. if (_pyfunc_equals(shape.length, 2)) { shape = [shape[0], shape[1], 1]; } this.activate(); format = this._shape_format[2]; stub16_ = shape; height = stub16_[0];width = stub16_[1];_ = stub16_[2]; stub17_ = offset; y = stub17_[0];x = stub17_[1]; gtype = _pymeth_get.call(this._types, data.constructor.name, null); if ((gtype === null)) { err_3 = new Error('ValueError:' + ("Type " + data.constructor.name + " not allowed for texture")); err_3.name = "ValueError"; throw err_3; } alignment = this._get_alignment(_pyfunc_mult(shape[shape.length -2], shape[shape.length -1])); if ((!_pyfunc_equals(alignment, 4))) { this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, alignment); } this._gl.texSubImage2D(this._target, 0, x, y, width, height, format, gtype, data); if ((!_pyfunc_equals(alignment, 4))) { this._gl.pixelStorei(this._gl.UNPACK_ALIGNMENT, 4); } return null; }; Texture3DLike = function () { // A 2D texture with support to simulate a 3D texture. // // To use this class, use set_size() and set_data() as if it was a 3D // texture. Add the GLSL_SAMPLE_NEAREST or GLSL_SAMPLE_LINEAR to the // shader to add the sample3D() function that can be used instead of // texture2D(). This function needs ``shape`` and ``tiles`` arguments // which can be set via uniforms, using the ``u_shape`` and ``u_tiles`` // attributes of this object. _pyfunc_instantiate(this, arguments); } Texture3DLike.prototype = Object.create(Texture2D.prototype); Texture3DLike.prototype._base_class = Texture2D.prototype; Texture3DLike.prototype._class_name = "Texture3DLike"; Texture3DLike.prototype.GLSL_SAMPLE_NEAREST = "\n vec4 sample3D(sampler2D tex, vec3 texcoord, vec3 shape, vec2 tiles) {\n shape.xyz = shape.zyx; // silly row-major convention\n float nrows = tiles.y, ncols = tiles.x;\n // Don't let adjacent frames be interpolated into this one\n texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5);\n texcoord.x = max(0.5, texcoord.x) / shape.x;\n texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5);\n texcoord.y = max(0.5, texcoord.y) / shape.y;\n\n float zindex = floor(texcoord.z * shape.z);\n\n // Do a lookup in the 2D texture\n float u = (mod(zindex, ncols) + texcoord.x) / ncols;\n float v = (floor(zindex / ncols) + texcoord.y) / nrows;\n\n return texture2D(tex, vec2(u,v));\n }\n "; Texture3DLike.prototype.GLSL_SAMPLE_LINEAR = "\n vec4 sample3D(sampler2D tex, vec3 texcoord, vec3 shape, vec2 tiles) {\n shape.xyz = shape.zyx; // silly row-major convention\n float nrows = tiles.y, ncols = tiles.x;\n // Don't let adjacent frames be interpolated into this one\n texcoord.x = min(texcoord.x * shape.x, shape.x - 0.5);\n texcoord.x = max(0.5, texcoord.x) / shape.x;\n texcoord.y = min(texcoord.y * shape.y, shape.y - 0.5);\n texcoord.y = max(0.5, texcoord.y) / shape.y;\n\n float z = texcoord.z * shape.z;\n float zindex1 = floor(z);\n float u1 = (mod(zindex1, ncols) + texcoord.x) / ncols;\n float v1 = (floor(zindex1 / ncols) + texcoord.y) / nrows;\n\n float zindex2 = zindex1 + 1.0;\n float u2 = (mod(zindex2, ncols) + texcoord.x) / ncols;\n float v2 = (floor(zindex2 / ncols) + texcoord.y) / nrows;\n\n vec4 s1 = texture2D(tex, vec2(u1, v1));\n vec4 s2 = texture2D(tex, vec2(u2, v2));\n\n return s1 * (zindex2 - z) + s2 * (z - zindex1);\n }\n "; Texture3DLike.prototype._get_tile_info = function (shape) { var err_3, max_size, ncols, nrows; max_size = this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE); nrows = Math.floor(max_size/shape[1]); nrows = Math.min(nrows, shape[0]); ncols = window.Math.ceil(shape[0] / nrows); if (_pyfunc_truthy(_pyfunc_mult(ncols, shape[2]) > max_size)) { err_3 = new Error('RuntimeError:' + ("Cannot fit 3D data with shape " + shape + " onto simulated 2D texture.")); err_3.name = "RuntimeError"; throw err_3; } return [nrows, ncols]; }; Texture3DLike.prototype.set_size = function (shape, format) { var ncols, nrows, sim_shape, stub18_; // Set the size of the 3D texture. // // Parameters // ---------- // shape : tuple of ints // The shape of the data to upload // format : GL enum // The format of the texture data. Can be LUMINANCE, LUMINANCE_ALPHA, // RGB, and RGBA. stub18_ = this._get_tile_info(shape); nrows = stub18_[0];ncols = stub18_[1]; sim_shape = [_pyfunc_mult(shape[1], nrows), _pyfunc_mult(shape[2], ncols)]; Texture3DLike.prototype._base_class.set_size.call(this, sim_shape, format); this.u_shape = [shape[0], shape[1], shape[2]]; this.u_tiles = [ncols, nrows]; return null; }; Texture3DLike.prototype.set_data = function (offset, shape, data) { var Type, col, elements_per_tile, err_3, ncols, nrows, row, sim_shape, stub19_, stub20_, tile, z, zeros; // Set the 3D texture data. // // Parameters // ---------- // offset : tuple of ints // Offset in pixels for each dimension. // shape : tuple of ints // The shape of the data to upload // data : typed array // The actual pixel data. Can be of any type, but on the GPU the // dat is stored in 8 bit precision. if (_pyfunc_equals(shape.length, 3)) { shape = [shape[0], shape[1], shape[2], 1]; } if ((!(_pyfunc_all(((function list_comprehenson () {var res = [];var i, iter0, i0;iter0 = offset;if ((typeof iter0 === "object") && (!Array.isArray(iter0))) {iter0 = Object.keys(iter0);}for (i0=0; i0<iter0.length; i0++) {i = iter0[i0];{res.push(_pyfunc_equals(i, 0));}}return res;}).apply(this)))))) { err_3 = new Error('ValueError:' + "Texture3DLike does not support nonzero offset (for now)"); err_3.name = "ValueError"; throw err_3; } stub19_ = this._get_tile_info(shape); nrows = stub19_[0];ncols = stub19_[1]; sim_shape = [_pyfunc_mult(shape[1], nrows), _pyfunc_mult(shape[2], ncols), shape[3]]; if (_pyfunc_equals(ncols, 1)) { Texture3DLike.prototype._base_class.set_data.call(this, [0, 0], sim_shape, data); } else { Type = data.constructor; zeros = new Type(_pyfunc_mult(_pyfunc_mult(sim_shape[0], sim_shape[1]), sim_shape[2])); Texture3DLike.prototype._base_class.set_data.call(this, [0, 0], sim_shape, zeros); for (z = 0; z < shape[0]; z += 1) { stub20_ = [Math.floor(z/ncols), z % ncols]; row = stub20_[0];col = stub20_[1]; elements_per_tile = Math.floor(data.length/shape[0]); tile = data.slice(_pyfunc_mult(z, elements_per_tile),_pyfunc_mult((z + 1), elements_per_tile)); Texture3DLike.prototype._base_class.set_data.call(this, [_pyfunc_mult(row, shape[1]), _pyfunc_mult(col, shape[2])], shape.slice(1), tile); } } return null; }; return {"Buffer": Buffer, "GlooObject": GlooObject, "IndexBuffer": IndexBuffer, "Program": Program, "Texture2D": Texture2D, "Texture3DLike": Texture3DLike, "VertexBuffer": VertexBuffer, "check_error": check_error, "console": console}; }));