@quartic/bokehjs
Version:
Interactive, novel data visualization
887 lines (837 loc) • 40.2 kB
JavaScript
/* 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};
}));