in seriously.js [3586:3802]
TargetNode = function (hook, target, options) {
var opts,
flip,
width,
height,
that = this,
matchedType = false,
i, element, elements, context,
debugContext,
frameBuffer,
targetList,
triedWebGl = false,
key;
function targetPlugin(hook, target, options, force) {
var plugin = seriousTargets[hook];
if (plugin.definition) {
plugin = plugin.definition.call(that, target, options, force);
if (!plugin) {
return null;
}
plugin = extend(extend({}, seriousTargets[hook]), plugin);
that.hook = key;
matchedType = true;
that.plugin = plugin;
that.compare = plugin.compare;
if (plugin.target) {
target = plugin.target;
}
if (plugin.gl && !that.gl) {
that.gl = plugin.gl;
if (!gl) {
attachContext(plugin.gl);
}
}
if (that.gl === gl) {
that.model = rectangleModel;
that.shader = baseShader;
}
}
return plugin;
}
function compareTarget(target) {
return that.target === target;
}
Node.call(this);
if (hook && typeof hook !== 'string' || !target && target !== 0) {
if (!options || typeof options !== 'object') {
options = target;
}
target = hook;
}
opts = options || {};
flip = opts.flip === undefined ? true : opts.flip
width = parseInt(opts.width, 10);
height = parseInt(opts.height, 10);
debugContext = opts.debugContext;
// forced target type?
if (typeof hook === 'string' && seriousTargets[hook]) {
targetPlugin(hook, target, opts, true);
}
this.renderToTexture = opts.renderToTexture;
if (target instanceof WebGLFramebuffer) {
frameBuffer = target;
if (opts instanceof HTMLCanvasElement) {
target = opts;
} else if (opts instanceof WebGLRenderingContext) {
target = opts.canvas;
} else if (opts.canvas instanceof HTMLCanvasElement) {
target = opts.canvas;
} else if (opts.context instanceof WebGLRenderingContext) {
target = opts.context.canvas;
} else {
//todo: search all canvases for matching contexts?
throw new Error('Must provide a canvas with WebGLFramebuffer target');
}
}
if (target instanceof HTMLElement && target.tagName === 'CANVAS') {
width = target.width;
height = target.height;
//try to get a webgl context.
if (!gl || gl.canvas !== target && opts.allowSecondaryWebGL) {
triedWebGl = true;
context = getWebGlContext(target, {
alpha: true,
premultipliedAlpha: false,
preserveDrawingBuffer: true,
stencil: true,
debugContext: debugContext
});
}
if (!context) {
if (!opts.allowSecondaryWebGL && gl && gl.canvas !== target) {
throw new Error('Only one WebGL target canvas allowed. Set allowSecondaryWebGL option to create secondary context.');
}
this.render = nop;
Seriously.logger.log('Unable to create WebGL context.');
//throw new Error('Unable to create WebGL context.');
} else if (!gl || gl === context) {
//this is our main WebGL canvas
if (!primaryTarget) {
primaryTarget = this;
}
if (!gl) {
attachContext(context);
}
this.render = this.renderWebGL;
/*
Don't remember what this is for. Maybe we should remove it
*/
if (opts.renderToTexture) {
if (gl) {
this.frameBuffer = new FrameBuffer(gl, width, height, false);
}
} else {
this.frameBuffer = {
frameBuffer: frameBuffer || null
};
}
} else {
//set up alternative drawing method using ArrayBufferView
this.gl = context;
//this.pixels = new Uint8Array(width * height * 4);
//todo: probably need another framebuffer for renderToTexture?
//todo: handle lost context on secondary webgl
this.frameBuffer = {
frameBuffer: frameBuffer || null
};
this.shader = new ShaderProgram(this.gl, baseVertexShader, baseFragmentShader);
this.model = buildRectangleModel.call(this, this.gl);
this.pixels = null;
this.texture = this.gl.createTexture();
this.gl.bindTexture(gl.TEXTURE_2D, this.texture);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
this.gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
this.render = this.renderSecondaryWebGL;
}
matchedType = true;
}
if (!matchedType) {
for (key in seriousTargets) {
if (seriousTargets.hasOwnProperty(key) && seriousTargets[key]) {
if (targetPlugin(key, target, opts, false)) {
break;
}
}
}
}
if (!matchedType) {
throw new Error('Unknown target type');
}
if (allTargets) {
targetList = allTargets.get(target);
if (targetList) {
Seriously.logger.warn(
'Target already in use by another instance',
target,
Object.keys(targetList).map(function (key) {
return targetList[key];
})
);
} else {
targetList = {};
allTargets.set(target, targetList);
}
targetList[seriously.id] = seriously;
}
this.target = target;
this.transform = null;
this.transformDirty = true;
this.flip = flip;
if (width) {
this.width = width;
}
if (height) {
this.height = height;
}
this.uniforms.resolution[0] = this.width;
this.uniforms.resolution[1] = this.height;
if (opts.auto !== undefined) {
this.auto = opts.auto;
} else {
this.auto = auto;
}
this.frames = 0;
this.pub = new Target(this);
nodes.push(this);
nodesById[this.id] = this;
targets.push(this);
};