texture.js | |
---|---|
Provides a simple wrapper around WebGL textures that supports render-to-texture. | |
new GL.Texture(width, height[, options])The arguments Texture parameters can be passed in via the | function Texture(width, height, options) {
options = options || {};
this.id = gl.createTexture();
this.width = width;
this.height = height;
this.format = options.format || gl.RGBA;
this.type = options.type || gl.UNSIGNED_BYTE;
var magFilter = options.filter || options.magFilter || gl.LINEAR;
var minFilter = options.filter || options.minFilter || gl.LINEAR;
if (this.type === gl.FLOAT) {
if (!Texture.canUseFloatingPointTextures()) {
throw new Error('OES_texture_float is required but not supported');
}
if ((minFilter !== gl.NEAREST || magFilter !== gl.NEAREST) &&
!Texture.canUseFloatingPointLinearFiltering()) {
throw new Error('OES_texture_float_linear is required but not supported');
}
} else if (this.type === gl.HALF_FLOAT_OES) {
if (!Texture.canUseHalfFloatingPointTextures()) {
throw new Error('OES_texture_half_float is required but not supported');
}
if ((minFilter !== gl.NEAREST || magFilter !== gl.NEAREST) &&
!Texture.canUseHalfFloatingPointLinearFiltering()) {
throw new Error('OES_texture_half_float_linear is required but not supported');
}
}
gl.bindTexture(gl.TEXTURE_2D, this.id);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, options.wrap || options.wrapS || gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, options.wrap || options.wrapT || gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D, 0, this.format, width, height, 0, this.format, this.type, null);
}
var framebuffer;
var renderbuffer;
var checkerboardCanvas;
Texture.prototype = { |
.bind([unit])Bind this texture to the given texture unit (0-7, defaults to 0). | bind: function(unit) {
gl.activeTexture(gl.TEXTURE0 + (unit || 0));
gl.bindTexture(gl.TEXTURE_2D, this.id);
}, |
.unbind([unit])Clear the given texture unit (0-7, defaults to 0). | unbind: function(unit) {
gl.activeTexture(gl.TEXTURE0 + (unit || 0));
gl.bindTexture(gl.TEXTURE_2D, null);
}, |
.canDrawTo()Check if rendering to this texture is supported. It may not be supported for floating-point textures on some configurations. | canDrawTo: function() {
framebuffer = framebuffer || gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.id, 0);
var result = gl.checkFramebufferStatus(gl.FRAMEBUFFER) == gl.FRAMEBUFFER_COMPLETE;
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
return result;
}, |
.drawTo(callback)Render all draw calls in Example usage: | drawTo: function(callback) {
var v = gl.getParameter(gl.VIEWPORT);
framebuffer = framebuffer || gl.createFramebuffer();
renderbuffer = renderbuffer || gl.createRenderbuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer);
if (this.width != renderbuffer.width || this.height != renderbuffer.height) {
renderbuffer.width = this.width;
renderbuffer.height = this.height;
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, this.width, this.height);
}
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.id, 0);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuffer);
if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE) {
throw new Error('Rendering to this texture is not supported (incomplete framebuffer)');
}
gl.viewport(0, 0, this.width, this.height);
callback();
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.viewport(v[0], v[1], v[2], v[3]);
}, |
.swapWith(other)Switch this texture with | swapWith: function(other) {
var temp;
temp = other.id; other.id = this.id; this.id = temp;
temp = other.width; other.width = this.width; this.width = temp;
temp = other.height; other.height = this.height; this.height = temp;
}
}; |
GL.Texture.fromImage(image[, options])Return a new image created from | Texture.fromImage = function(image, options) {
options = options || {};
var texture = new Texture(image.width, image.height, options);
try {
gl.texImage2D(gl.TEXTURE_2D, 0, texture.format, texture.format, texture.type, image);
} catch (e) {
if (location.protocol == 'file:') {
throw new Error('image not loaded for security reasons (serve this page over "http://" instead)');
} else {
throw new Error('image not loaded for security reasons (image must originate from the same ' +
'domain as this page or use Cross-Origin Resource Sharing)');
}
}
if (options.minFilter && options.minFilter != gl.NEAREST && options.minFilter != gl.LINEAR) {
gl.generateMipmap(gl.TEXTURE_2D);
}
return texture;
}; |
GL.Texture.fromURL(url[, options])Returns a checkerboard texture that will switch to the correct texture when it loads. | Texture.fromURL = function(url, options) {
checkerboardCanvas = checkerboardCanvas || (function() {
var c = document.createElement('canvas').getContext('2d');
c.canvas.width = c.canvas.height = 128;
for (var y = 0; y < c.canvas.height; y += 16) {
for (var x = 0; x < c.canvas.width; x += 16) {
c.fillStyle = (x ^ y) & 16 ? '#FFF' : '#DDD';
c.fillRect(x, y, 16, 16);
}
}
return c.canvas;
})();
var texture = Texture.fromImage(checkerboardCanvas, options);
var image = new Image();
var context = gl;
image.onload = function() {
context.makeCurrent();
Texture.fromImage(image, options).swapWith(texture);
};
image.src = url;
return texture;
}; |
GL.Texture.canUseFloatingPointTextures()Returns false if | Texture.canUseFloatingPointTextures = function() {
return !!gl.getExtension('OES_texture_float');
}; |
GL.Texture.canUseFloatingPointLinearFiltering()Returns false if | Texture.canUseFloatingPointLinearFiltering = function() {
return !!gl.getExtension('OES_texture_float_linear');
}; |
GL.Texture.canUseFloatingPointTextures()Returns false if | Texture.canUseHalfFloatingPointTextures = function() {
return !!gl.getExtension('OES_texture_half_float');
}; |
GL.Texture.canUseFloatingPointLinearFiltering()Returns false if | Texture.canUseHalfFloatingPointLinearFiltering = function() {
return !!gl.getExtension('OES_texture_half_float_linear');
};
|