| 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; |