blob: ed9c1e7b877fbb24807499409326f2b394916e70 [file] [log] [blame]
function WebGLBaseElement(){
}
WebGLBaseElement.prototype = {
createElements: function(){},
initRendererElement: function(){
this.localTransform = new Matrix();
this.framebuffersData = [];
},
createContainerElements: function(){
this.renderableEffectsManager = new WEffects(this);
if(this.renderableEffectsManager.filters.length) {
this.createFramebuffers(this.glContext);
}
},
createContent: function(){
},
setBlendMode: function(){
var globalData = this.globalData;
if(globalData.blendMode !== this.data.bm) {
globalData.blendMode = this.data.bm;
var blendModeValue = getBlendMode(this.data.bm);
globalData.glContext.globalCompositeOperation = blendModeValue;
}
},
hideElement: function(){
if (!this.hidden && (!this.isInRange || this.isTransparent)) {
this.hidden = true;
}
},
showElement: function(){
if (this.isInRange && !this.isTransparent){
this.hidden = false;
this._isFirstFrame = true;
this.maskManager._isFirstFrame = true;
}
},
renderFrame: function() {
// console.log('RENDER FRAME')
if (this.hidden || this.data.hd) {
return;
}
this.renderTransform();
this.renderRenderable();
this.setBlendMode();
this.renderInnerContent();
this.renderLayer();
if (this._isFirstFrame) {
this._isFirstFrame = false;
}
},
renderEffects: function() {
var glContext = this.glContext;
//rendering effects
var filters = this.renderableEffectsManager.filters;
if(filters.length) {
var size = this.getSize();
var i, len = filters.length;
glContext.viewport(0, 0, size.w, size.h);
this._finalTexture = this.texture;
for (i = 0; i < len; i++) {
// Setup to draw into one of the framebuffers.
glContext.bindFramebuffer(glContext.FRAMEBUFFER, this.framebuffersData[i % 2].framebuffer);
this.currentBuffer = this.framebuffersData[i % 2].framebuffer;
glContext.clearColor(0, 0, 0, 0);
glContext.clear(glContext.COLOR_BUFFER_BIT | glContext.DEPTH_BUFFER_BIT);
filters[i].renderFrame();
// for the next draw, use the texture we just rendered to.
//glContext.activeTexture(glContext.TEXTURE0);
glContext.bindTexture(glContext.TEXTURE_2D, this.framebuffersData[i % 2].texture);
this._finalTexture = this.framebuffersData[i % 2].texture;
}
//TODO: if filters didn't change, skip processing them and bind directly the last binded texture in previous iteration.
}
},
renderMasks: function() {
if(this.maskManager.hasMasks) {
this.maskManager.renderFrame();
}
},
calculateTransform: function() {
if(this.finalTransform._matMdf) {
//Parent comp transform + localTransform
var tr = this.comp.getTransform();
var newTransform = this.localTransform;
this.finalTransform.mat.clone(newTransform);
var p = tr.props;
newTransform.transform(p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],p[8],p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
//TODO: only update the uniform if needed. This is costly.
// console.log(this.localTransform.props)
this.glContext.uniformMatrix4fv(this.mat4UniformLoc, false, this.localTransform.props);
}
},
renderLayer: function() {
// copy to comp's frame buffer
// TODO: check if needed since WebGLCompElement is also changing buffers
this.comp.switchBuffer();
var glContext = this.glContext;
glContext.useProgram(this.program);
this.calculateTransform();
// glContext.vertexAttribPointer(this.positionAttributeLocation, 2, glContext.FLOAT, false, 0, 0);
// glContext.vertexAttribPointer(this.texcoordLocation, 2, glContext.FLOAT, false, 0, 0);
glContext.drawArrays(glContext.TRIANGLES, 0, 6);
},
destroy: function(){
this.glContext = null;
this.data = null;
this.globalData = null;
this.maskManager.destroy();
},
createFramebuffers: function(glContext){
if(this.framebuffersData.length) {
return;
}
var layerSize = this.getSize();
// Frame buffer objects fof effects
for (var ii = 0; ii < 2; ++ii) {
var bufferWithTexture = this.createFrameBufferWithTexture(glContext, layerSize.w, layerSize.h);
this.framebuffersData.push(bufferWithTexture)
}
},
createFrameBufferWithTexture: function(glContext, width, height) {
// Create a framebuffer
var framebuffer = glContext.createFramebuffer();
glContext.bindFramebuffer(glContext.FRAMEBUFFER, framebuffer);
// Attach a texture to it.
var texture = textureFactory(glContext);
// make the texture the same size as the image
glContext.texImage2D(
glContext.TEXTURE_2D, 0, glContext.RGBA, width, height, 0,
glContext.RGBA, glContext.UNSIGNED_BYTE, null);
glContext.framebufferTexture2D(glContext.FRAMEBUFFER, glContext.COLOR_ATTACHMENT0, glContext.TEXTURE_2D, texture, 0);
this.comp.switchBuffer();
return {
texture: texture,
framebuffer: framebuffer
}
},
createRenderableComponents: function() {
this.maskManager = new WMaskElement(this.data, this);
if(this.maskManager.hasMasks || this.data.tt) {
this.createFramebuffers(this.glContext);
}
},
//
mHelper: new Matrix()
};
WebGLBaseElement.prototype.hide = CVBaseElement.prototype.hideElement;
WebGLBaseElement.prototype.show = CVBaseElement.prototype.showElement;