sku-pg
Version:
Skulpt is a Javascript implementation of Python 2.x. Python that runs in your browser!
170 lines (144 loc) • 6.27 kB
JavaScript
// most of this file is from/based on 'tdl'
var $builtinmodule = function(name)
{
var mod = {};
var Buffer = function(array, opt_target) {
var target = opt_target || gl.ARRAY_BUFFER;
var buf = gl.createBuffer();
this.target = target;
this.buf = buf;
this.set(array);
this.numComponents_ = array.numComponents;
this.numElements_ = array.numElements;
this.totalComponents_ = this.numComponents_ * this.numElements_;
if (array.buffer instanceof Float32Array) {
this.type_ = gl.FLOAT;
} else if (array.buffer instanceof Uint8Array) {
this.type_ = gl.UNSIGNED_BYTE;
} else if (array.buffer instanceof Int8Array) {
this.type_ = gl._BYTE;
} else if (array.buffer instanceof Uint16Array) {
this.type_ = gl.UNSIGNED_SHORT;
} else if (array.buffer instanceof Int16Array) {
this.type_ = gl.SHORT;
} else {
throw("unhandled type:" + (typeof array.buffer));
}
};
Buffer.prototype.set = function(array) {
gl.bindBuffer(this.target, this.buf);
gl.bufferData(this.target, array.buffer, gl.STATIC_DRAW);
}
Buffer.prototype.type = function() {
return this.type_;
};
Buffer.prototype.numComponents = function() {
return this.numComponents_;
};
Buffer.prototype.numElements = function() {
return this.numElements_;
};
Buffer.prototype.totalComponents = function() {
return this.totalComponents_;
};
Buffer.prototype.buffer = function() {
return this.buf;
};
Buffer.prototype.stride = function() {
return 0;
};
Buffer.prototype.offset = function() {
return 0;
};
mod.Model = Sk.misceval.buildClass(mod, function($gbl, $loc)
{
$loc.__init__ = new Sk.builtin.func(function(self, shader, arrays, textures)
{
self.buffers = {};
var setBuffer = function(name, array)
{
var target = (name == 'indices') ? gl.ELEMENT_ARRAY_BUFFER : gl.ARRAY_BUFFER;
b = self.buffers[name];
if (!b)
b = new Buffer(array, target);
else
b.set(array);
self.buffers[name] = b;
};
for (name in arrays)
setBuffer(name, arrays[name]);
var textureUnits = {};
var unit = 0;
for (var texture in textures)
{
textureUnits[texture] = unit++;
}
self.mode = gl.TRIANGLES;
self.textures = textures.v;
self.textureUnits = textureUnits;
self.shader = shader;
});
/**
* Sets up the shared parts of drawing this model. Uses the
* program, binds the buffers, sets the textures.
*
* @param {!Object.<string, *>} uniforms An object of names to
* values to set on this models uniforms.
*/
$loc.drawPrep = new Sk.builtin.func(function(self, uniforms)
{
var shader = self.shader;
var buffers = self.buffers;
var textures = self.textures;
uniforms = Sk.ffi.remapToJs(uniforms);
Sk.misceval.callsim(shader.use, shader);
for (var buffer in buffers) {
var b = buffers[buffer];
if (buffer == 'indices') {
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, b.buffer());
} else {
var attrib = shader.attrib[buffer];
if (attrib) {
attrib(b);
}
}
}
for (var texture in textures) {
var unit = self.textureUnits[texture];
shader.setUniform$impl(shader, textuer, unit);
textures[texture].bindToUnit(unit);
}
for (var uniform in uniforms) {
shader.setUniform$impl(shader, uniform, uniforms[uniform]);
}
});
/**
* Draws this model.
*
* After calling tdl.models.Model.drawPrep you can call this
* function multiple times to draw this model.
*
* @param {!Object.<string, *>} uniforms An object of names to
* values to set on this models uniforms.
*/
$loc.draw = new Sk.builtin.func(function(self, uniforms, opt_textures)
{
var shader = self.shader;
uniforms = Sk.ffi.remapToJs(uniforms);
for (uniform in uniforms) {
shader.setUniform$impl(shader, uniform, uniforms[uniform]);
}
if (opt_textures) {
for (var texture in opt_textures) {
var unit = self.textureUnits[texture];
shader.setUniform$impl(shader, texture, unit);
opt_textures[texture].bindToUnit(unit);
}
}
var buffers = self.buffers;
gl.drawElements(self.mode, buffers.indices.totalComponents(), gl.UNSIGNED_SHORT, 0);
});
},
'Model', []);
return mod;
};