diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 7ec96b9..7952fb3 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -115,11 +115,19 @@ this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); } - this.MAX_TEXTURES = 1; - + glCore._testingContext = gl; const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); - // create a couple of buffers + const sampleValues = new Int32Array(this.MAX_TEXTURES); + + for (let i = 0; i < this.MAX_TEXTURES; i++) + { + sampleValues[i] = i; + } + + shader.uniformGroup.add('default', {uSamplers:sampleValues}, true);//this.renderer.globalUniforms; + shader.uniforms.globals = this.renderer.globalUniforms; + this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); // we use the second shader as the first one depending on your browser may omit aTextureId @@ -132,16 +140,17 @@ this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[i], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[i], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[i], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); - if (shader.attributes.aTextureId) + if (attributeData.aTextureId) { - this.vaos[i].addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + this.vaos[i].addAttribute(this.vertexBuffers[i], attributeData.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); } /* eslint-enable max-len */ @@ -384,12 +393,14 @@ /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; + // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); if (this.shader.attributes.aTextureId) { @@ -452,7 +463,9 @@ */ start() { - this.renderer._bindGLShader(this.shader); + // this.renderer._bindGLShader(this.shader); + this.renderer.shader.bindShader(this.shader, true); + this.renderer.shader.syncUniformGroup(this.shader.uniformGroup); if (settings.CAN_UPLOAD_SAME_BUFFER) { diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 7ec96b9..7952fb3 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -115,11 +115,19 @@ this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); } - this.MAX_TEXTURES = 1; - + glCore._testingContext = gl; const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); - // create a couple of buffers + const sampleValues = new Int32Array(this.MAX_TEXTURES); + + for (let i = 0; i < this.MAX_TEXTURES; i++) + { + sampleValues[i] = i; + } + + shader.uniformGroup.add('default', {uSamplers:sampleValues}, true);//this.renderer.globalUniforms; + shader.uniforms.globals = this.renderer.globalUniforms; + this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); // we use the second shader as the first one depending on your browser may omit aTextureId @@ -132,16 +140,17 @@ this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[i], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[i], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[i], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); - if (shader.attributes.aTextureId) + if (attributeData.aTextureId) { - this.vaos[i].addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + this.vaos[i].addAttribute(this.vertexBuffers[i], attributeData.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); } /* eslint-enable max-len */ @@ -384,12 +393,14 @@ /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; + // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); if (this.shader.attributes.aTextureId) { @@ -452,7 +463,9 @@ */ start() { - this.renderer._bindGLShader(this.shader); + // this.renderer._bindGLShader(this.shader); + this.renderer.shader.bindShader(this.shader, true); + this.renderer.shader.syncUniformGroup(this.shader.uniformGroup); if (settings.CAN_UPLOAD_SAME_BUFFER) { diff --git a/src/core/sprites/webgl/generateMultiTextureShader.js b/src/core/sprites/webgl/generateMultiTextureShader.js index bf4e506..1dabb7a 100644 --- a/src/core/sprites/webgl/generateMultiTextureShader.js +++ b/src/core/sprites/webgl/generateMultiTextureShader.js @@ -1,4 +1,5 @@ import { GLShader } from 'pixi-gl-core'; +import Shader from '../../shader/Shader'; import { PRECISION } from '../../const'; import { readFileSync } from 'fs'; import { join } from 'path'; @@ -25,7 +26,8 @@ fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures); fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures)); - const shader = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shaderold = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shader = Shader.from(vertexSrc, fragmentSrc);//, PRECISION.DEFAULT); const sampleValues = []; @@ -34,8 +36,9 @@ sampleValues[i] = i; } - shader.bind(); - shader.uniforms.uSamplers = sampleValues; + // shader.bind(); + // shader.uniforms.uSamplers = new Int32Array(sampleValues); + // shader.uniformGroup.static = true; return shader; } diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 7ec96b9..7952fb3 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -115,11 +115,19 @@ this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); } - this.MAX_TEXTURES = 1; - + glCore._testingContext = gl; const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); - // create a couple of buffers + const sampleValues = new Int32Array(this.MAX_TEXTURES); + + for (let i = 0; i < this.MAX_TEXTURES; i++) + { + sampleValues[i] = i; + } + + shader.uniformGroup.add('default', {uSamplers:sampleValues}, true);//this.renderer.globalUniforms; + shader.uniforms.globals = this.renderer.globalUniforms; + this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); // we use the second shader as the first one depending on your browser may omit aTextureId @@ -132,16 +140,17 @@ this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[i], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[i], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[i], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); - if (shader.attributes.aTextureId) + if (attributeData.aTextureId) { - this.vaos[i].addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + this.vaos[i].addAttribute(this.vertexBuffers[i], attributeData.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); } /* eslint-enable max-len */ @@ -384,12 +393,14 @@ /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; + // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); if (this.shader.attributes.aTextureId) { @@ -452,7 +463,9 @@ */ start() { - this.renderer._bindGLShader(this.shader); + // this.renderer._bindGLShader(this.shader); + this.renderer.shader.bindShader(this.shader, true); + this.renderer.shader.syncUniformGroup(this.shader.uniformGroup); if (settings.CAN_UPLOAD_SAME_BUFFER) { diff --git a/src/core/sprites/webgl/generateMultiTextureShader.js b/src/core/sprites/webgl/generateMultiTextureShader.js index bf4e506..1dabb7a 100644 --- a/src/core/sprites/webgl/generateMultiTextureShader.js +++ b/src/core/sprites/webgl/generateMultiTextureShader.js @@ -1,4 +1,5 @@ import { GLShader } from 'pixi-gl-core'; +import Shader from '../../shader/Shader'; import { PRECISION } from '../../const'; import { readFileSync } from 'fs'; import { join } from 'path'; @@ -25,7 +26,8 @@ fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures); fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures)); - const shader = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shaderold = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shader = Shader.from(vertexSrc, fragmentSrc);//, PRECISION.DEFAULT); const sampleValues = []; @@ -34,8 +36,9 @@ sampleValues[i] = i; } - shader.bind(); - shader.uniforms.uSamplers = sampleValues; + // shader.bind(); + // shader.uniforms.uSamplers = new Int32Array(sampleValues); + // shader.uniformGroup.static = true; return shader; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index f227ae0..87838f3 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,4 +1,5 @@ import BaseTexture from './BaseTexture'; +import FrameBuffer from './FrameBuffer'; import settings from '../settings'; /** @@ -60,7 +61,7 @@ * @private * @member {object} */ - this._glRenderTargets = {}; +// this._glRenderTargets = {}; /** * A reference to the canvas render target (we only need one as this can be shared across renderers) @@ -70,12 +71,10 @@ */ this._canvasRenderTarget = null; - /** - * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. - * - * @member {boolean} - */ - this.valid = false; + this.clearColor = [0,0,0,0]; + + this.frameBuffer = new FrameBuffer(width, height) + .addColorTexture(0, this); } /** @@ -86,22 +85,8 @@ */ resize(width, height) { - if (width === this.width && height === this.height) - { - return; - } - - this.valid = (width > 0 && height > 0); - - this.width = width; - this.height = height; - - if (!this.valid) - { - return; - } - - this.emit('update', this); + super.resize(width, height); + this.frameBuffer.resize(width, height); } /** diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 7ec96b9..7952fb3 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -115,11 +115,19 @@ this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); } - this.MAX_TEXTURES = 1; - + glCore._testingContext = gl; const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); - // create a couple of buffers + const sampleValues = new Int32Array(this.MAX_TEXTURES); + + for (let i = 0; i < this.MAX_TEXTURES; i++) + { + sampleValues[i] = i; + } + + shader.uniformGroup.add('default', {uSamplers:sampleValues}, true);//this.renderer.globalUniforms; + shader.uniforms.globals = this.renderer.globalUniforms; + this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); // we use the second shader as the first one depending on your browser may omit aTextureId @@ -132,16 +140,17 @@ this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[i], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[i], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[i], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); - if (shader.attributes.aTextureId) + if (attributeData.aTextureId) { - this.vaos[i].addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + this.vaos[i].addAttribute(this.vertexBuffers[i], attributeData.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); } /* eslint-enable max-len */ @@ -384,12 +393,14 @@ /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; + // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); if (this.shader.attributes.aTextureId) { @@ -452,7 +463,9 @@ */ start() { - this.renderer._bindGLShader(this.shader); + // this.renderer._bindGLShader(this.shader); + this.renderer.shader.bindShader(this.shader, true); + this.renderer.shader.syncUniformGroup(this.shader.uniformGroup); if (settings.CAN_UPLOAD_SAME_BUFFER) { diff --git a/src/core/sprites/webgl/generateMultiTextureShader.js b/src/core/sprites/webgl/generateMultiTextureShader.js index bf4e506..1dabb7a 100644 --- a/src/core/sprites/webgl/generateMultiTextureShader.js +++ b/src/core/sprites/webgl/generateMultiTextureShader.js @@ -1,4 +1,5 @@ import { GLShader } from 'pixi-gl-core'; +import Shader from '../../shader/Shader'; import { PRECISION } from '../../const'; import { readFileSync } from 'fs'; import { join } from 'path'; @@ -25,7 +26,8 @@ fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures); fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures)); - const shader = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shaderold = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shader = Shader.from(vertexSrc, fragmentSrc);//, PRECISION.DEFAULT); const sampleValues = []; @@ -34,8 +36,9 @@ sampleValues[i] = i; } - shader.bind(); - shader.uniforms.uSamplers = sampleValues; + // shader.bind(); + // shader.uniforms.uSamplers = new Int32Array(sampleValues); + // shader.uniformGroup.static = true; return shader; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index f227ae0..87838f3 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,4 +1,5 @@ import BaseTexture from './BaseTexture'; +import FrameBuffer from './FrameBuffer'; import settings from '../settings'; /** @@ -60,7 +61,7 @@ * @private * @member {object} */ - this._glRenderTargets = {}; +// this._glRenderTargets = {}; /** * A reference to the canvas render target (we only need one as this can be shared across renderers) @@ -70,12 +71,10 @@ */ this._canvasRenderTarget = null; - /** - * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. - * - * @member {boolean} - */ - this.valid = false; + this.clearColor = [0,0,0,0]; + + this.frameBuffer = new FrameBuffer(width, height) + .addColorTexture(0, this); } /** @@ -86,22 +85,8 @@ */ resize(width, height) { - if (width === this.width && height === this.height) - { - return; - } - - this.valid = (width > 0 && height > 0); - - this.width = width; - this.height = height; - - if (!this.valid) - { - return; - } - - this.emit('update', this); + super.resize(width, height); + this.frameBuffer.resize(width, height); } /** diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 1fd0ee3..1d30d8f 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -6,7 +6,7 @@ import EventEmitter from 'eventemitter3'; import settings from '../settings'; import { Rectangle } from '../math'; -import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; +import { TextureCache, BaseTextureCache, getResolutionOfUrl, uid } from '../utils'; /** * A texture stores the information that represents an image or part of an image. It cannot be added @@ -470,6 +470,7 @@ Texture.fromImage = Texture.from; Texture.fromSVG = Texture.from; Texture.fromCanvas = Texture.from; +Texture.fromVideo = Texture.from; Texture.fromFrame = Texture.from; function createWhiteTexture() diff --git a/src/core/renderers/webgl/ShaderManager.js b/src/core/renderers/webgl/ShaderManager.js index 290d4ba..cf7b433 100644 --- a/src/core/renderers/webgl/ShaderManager.js +++ b/src/core/renderers/webgl/ShaderManager.js @@ -51,9 +51,11 @@ // TODO - some current pixi plugins bypass this.. so it not safe to use yet.. // if (this.shader !== shader) // { - this.shader = shader; - this.renderer._bindGLShader(glShader); - // } + if (this.shader !== shader) + { + this.shader = shader; + glShader.bind(); + } if (!dontSync) { @@ -84,7 +86,7 @@ const group = uniformGroups[0]; const syncFunc = group.syncUniforms[this.shader.program.id] || this.createSynGroups(group); - syncFunc(glShader.uniformD1ata, group.uniforms, this.renderer); + syncFunc(glShader.uniformData, group.uniforms, this.renderer); } @@ -116,7 +118,14 @@ */ getGLShader() { - return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + if(this.shader) + { + return this.shader.program.glShaders[this.renderer.CONTEXT_UID]; + } + else + { + return null; + } } /** diff --git a/src/core/renderers/webgl/WebGLRenderer.js b/src/core/renderers/webgl/WebGLRenderer.js index 12bcbee..6cfb52f 100644 --- a/src/core/renderers/webgl/WebGLRenderer.js +++ b/src/core/renderers/webgl/WebGLRenderer.js @@ -3,10 +3,12 @@ import StencilManager from './managers/StencilManager'; import FilterManager from './managers/FilterManager'; import FramebufferManager from './managers/FramebufferManager'; +import RenderTextureManager from './managers/RenderTextureManager'; import NewTextureManager from './managers/NewTextureManager'; import RenderTarget from './utils/RenderTarget'; import ObjectRenderer from './utils/ObjectRenderer'; import TextureManager from './TextureManager'; +import ProjectionManager from './managers/ProjectionManager'; import StateManager from './managers/StateManager'; import ShaderManager from './ShaderManager'; import BaseTexture from '../../textures/BaseTexture'; @@ -16,6 +18,9 @@ import { pluginTarget } from '../../utils'; import glCore from 'pixi-gl-core'; import { RENDERER_TYPE } from '../../const'; +import UniformGroup from '../../shader/UniformGroup'; +import { Rectangle, Matrix } from '../../math'; + let CONTEXT_UID = 0; @@ -119,6 +124,12 @@ this.framebuffer = new FramebufferManager(this); this.texture = new NewTextureManager(this); + this.renderTexture = new RenderTextureManager(this); + this.projection = new ProjectionManager(this); + + this.globalUniforms = new UniformGroup({ + projectionMatrix:new Matrix() + }, true) /** * The currently active ObjectRenderer. @@ -152,6 +163,8 @@ */ // this.state = new WebGLState(this.gl); this.state = new StateManager(this.gl); + this.state.setBlendMode(0); + this.renderingToScreen = true; @@ -190,7 +203,8 @@ this._nextTextureLocation = 0; - this.setBlendMode(0); + + } /** @@ -217,15 +231,10 @@ this.textureManager = new TextureManager(this); this.textureGC = new TextureGarbageCollector(this); - this.shaderManager = new ShaderManager(this); + this.shader = new ShaderManager(this); this.state.resetToDefault(); - this.rootRenderTarget = new RenderTarget(gl, this.width, this.height, null, this.resolution, true); - this.rootRenderTarget.clearColor = this._backgroundColorRgba; - - this.bindRenderTarget(this.rootRenderTarget); - // now lets fill up the textures with empty ones! const emptyGLTexture = new glCore.GLTexture.fromData(gl, null, 1, 1); @@ -293,13 +302,13 @@ // displayObject.hitArea = //TODO add a temp hit area } - this.bindRenderTexture(renderTexture, transform); + this.renderTexture.bind(renderTexture); this.currentRenderer.start(); if (clear !== undefined ? clear : this.clearBeforeRender) { - this._activeRenderTarget.clear(); + this.renderTexture.clear(); } displayObject.renderWebGL(this); @@ -357,37 +366,7 @@ SystemRenderer.prototype.resize.call(this, screenWidth, screenHeight); - this.rootRenderTarget.resize(screenWidth, screenHeight); - - if (this._activeRenderTarget === this.rootRenderTarget) - { - this.rootRenderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = this.rootRenderTarget.projectionMatrix.toArray(true); - } - } - } - - /** - * Resizes the webGL view to the specified width and height. - * - * @param {number} blendMode - the desired blend mode - */ - setBlendMode(blendMode) - { - this.state.setBlendMode(blendMode); - } - - /** - * Erases the active render target and fills the drawing area with a colour - * - * @param {number} [clearColor] - The colour - */ - clear(clearColor) - { - this._activeRenderTarget.clear(clearColor); + this.renderTexture.resize(screenWidth, screenHeight); } /** @@ -401,129 +380,6 @@ } /** - * Erases the render texture and fills the drawing area with a colour - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to clear - * @param {number} [clearColor] - The colour - * @return {PIXI.WebGLRenderer} Returns itself. - */ - clearRenderTexture(renderTexture, clearColor) - { - const baseTexture = renderTexture.baseTexture; - const renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - - if (renderTarget) - { - renderTarget.clear(clearColor); - } - - return this; - } - - /** - * Binds a render texture for rendering - * - * @param {PIXI.RenderTexture} renderTexture - The render texture to render - * @param {PIXI.Transform} transform - The transform to be applied to the render texture - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTexture(renderTexture, transform) - { - let renderTarget; - - if (renderTexture) - { - const baseTexture = renderTexture.baseTexture; - - if (!baseTexture._glRenderTargets[this.CONTEXT_UID]) - { - // bind the current texture - this.textureManager.updateTexture(baseTexture, 0); - } - - this.unbindTexture(baseTexture); - - renderTarget = baseTexture._glRenderTargets[this.CONTEXT_UID]; - renderTarget.setFrame(renderTexture.frame); - } - else - { - renderTarget = this.rootRenderTarget; - } - - renderTarget.transform = transform; - this.bindRenderTarget(renderTarget); - - return this; - } - - /** - * Changes the current render target to the one given in parameter - * - * @param {PIXI.RenderTarget} renderTarget - the new render target - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindRenderTarget(renderTarget) - { - if (renderTarget !== this._activeRenderTarget) - { - this._activeRenderTarget = renderTarget; - renderTarget.activate(); - - if (this._activeShader) - { - this._activeShader.uniforms.projectionMatrix = renderTarget.projectionMatrix.toArray(true); - } - - this.stencilManager.setMaskStack(renderTarget.stencilMaskStack); - } - - return this; - } - - /** - * Changes the current shader to the one given in parameter - * - * @param {PIXI.Shader} shader - the new shader - * @param {boolean} dontSync - false if the shader should automatically sync its uniforms. - * @return {PIXI.WebGLRenderer} Returns itself. - */ - bindShader(shader, dontSync) - { - this.shaderManager.bindShader(shader, dontSync); - - return this; - } - - /** - * Changes the current GLShader to the one given in parameter - * - * @param {PIXI.glCore.Shader} shader - the new glShader - * @param {boolean} [autoProject=true] - Whether automatically set the projection matrix - * @return {PIXI.WebGLRenderer} Returns itself. - */ - _bindGLShader(shader, autoProject) - { - // TODO cache - if (this._activeShader !== shader) - { - this._activeShader = shader; - shader.bind(); - - // `autoProject` normally would be a default parameter set to true - // but because of how Babel transpiles default parameters - // it hinders the performance of this method. - if (autoProject !== false) - { - // automatically set the projection matrix - shader.uniforms.projectionMatrix = this._activeRenderTarget.projectionMatrix.toArray(true); - } - } - - return this; - } - - /** * Binds the texture. This will return the location of the bound texture. * It may not be the same as the one you pass in. This is due to optimisation that prevents * needless binding of textures. For example if the texture is already bound it will return the diff --git a/src/core/renderers/webgl/managers/FramebufferManager.js b/src/core/renderers/webgl/managers/FramebufferManager.js index a6b2e19..645fdc9 100644 --- a/src/core/renderers/webgl/managers/FramebufferManager.js +++ b/src/core/renderers/webgl/managers/FramebufferManager.js @@ -76,14 +76,14 @@ this.renderer.texture.unbind(framebuffer.depthTexture); } - gl.viewport(0,0,framebuffer.width, framebuffer.height); +// gl.viewport(0,0,framebuffer.width, framebuffer.height); } else { gl.bindFramebuffer(gl.FRAMEBUFFER, null); - gl.viewport(0,0,this.renderer.width, this.renderer.height); + // gl.viewport(0,0,this.renderer.width, this.renderer.height); } } diff --git a/src/core/renderers/webgl/managers/NewTextureManager.js b/src/core/renderers/webgl/managers/NewTextureManager.js index ef7e2da..02aee2c 100644 --- a/src/core/renderers/webgl/managers/NewTextureManager.js +++ b/src/core/renderers/webgl/managers/NewTextureManager.js @@ -61,6 +61,8 @@ const gl = this.gl; + texture = texture.baseTexture || texture; + location = location || 0; if(this.currentLocation !== location) diff --git a/src/core/renderers/webgl/managers/ProjectionManager.js b/src/core/renderers/webgl/managers/ProjectionManager.js new file mode 100644 index 0000000..a9bea4b --- /dev/null +++ b/src/core/renderers/webgl/managers/ProjectionManager.js @@ -0,0 +1,92 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class ProjectionManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.projectionMatrix = new Matrix(); + } + + update(destinationFrame, sourceFrame, root) + { + this.destinationFrame = destinationFrame || this.destinationFrame || this.defaultFrame; + this.sourceFrame = sourceFrame || this.sourceFrame || destinationFrame; + + this.calculateProjection(this.destinationFrame, this.sourceFrame, root); + + this.renderer.globalUniforms.uniforms.projectionMatrix = this.projectionMatrix; + this.renderer.globalUniforms.update(); + + const gl = this.renderer.gl; + + // TODO this is bot needed here? + const resolution = 1; + + // TODO add a check as them may be the same! + if (this.destinationFrame !== this.sourceFrame) + { +// gl.enable(gl.SCISSOR_TEST); + gl.scissor( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + else + { + // gl.disable(gl.SCISSOR_TEST); + } + + // TODO - does not need to be updated all the time?? + gl.viewport( + this.destinationFrame.x | 0, + this.destinationFrame.y | 0, + (this.destinationFrame.width * resolution) | 0, + (this.destinationFrame.height * resolution) | 0 + ); + } + + /** + * Updates the projection matrix based on a projection frame (which is a rectangle) + * + * @param {Rectangle} destinationFrame - The destination frame. + * @param {Rectangle} sourceFrame - The source frame. + */ + calculateProjection(destinationFrame, sourceFrame, root) + { + const pm = this.projectionMatrix; + + pm.identity(); + + // TODO: make dest scale source + if (!root) + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = 1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = -1 - (sourceFrame.y * pm.d); + } + else + { + pm.a = 1 / destinationFrame.width * 2; + pm.d = -1 / destinationFrame.height * 2; + + pm.tx = -1 - (sourceFrame.x * pm.a); + pm.ty = 1 - (sourceFrame.y * pm.d); + } + } +} diff --git a/src/core/renderers/webgl/managers/RenderTextureManager.js b/src/core/renderers/webgl/managers/RenderTextureManager.js new file mode 100644 index 0000000..e88b421 --- /dev/null +++ b/src/core/renderers/webgl/managers/RenderTextureManager.js @@ -0,0 +1,79 @@ +import WebGLManager from './WebGLManager'; +import { Rectangle, Matrix } from '../../../math'; + +const tempRect = new Rectangle(); + +/** + * @class + * @extends PIXI.WebGLManager + * @memberof PIXI + */ + +export default class RenderTextureManager extends WebGLManager +{ + /** + * @param {PIXI.WebGLRenderer} renderer - The renderer this manager works for. + */ + constructor(renderer) + { + super(renderer); + + this.clearColor = renderer._backgroundColorRgba; + } + + bind(renderTexture) + { + // TODO - do we want this?? + if(this.renderTexture === renderTexture)return; + + this.renderTexture = renderTexture; + + if(renderTexture) + { + this.renderer.framebuffer.bind(renderTexture.baseTexture.frameBuffer); + this.renderer.projection.update(renderTexture.frame, renderTexture.frame, false); + } + else + { + this.renderer.framebuffer.bind(null); + + tempRect.width = this.renderer.width; + tempRect.height = this.renderer.height; + // TODO store this.. + this.renderer.projection.update(tempRect, tempRect, true); + } + + const glShader = this.renderer.shader.getGLShader() + + if (glShader) + { + // glShader.uniforms.projectionMatrix = this.renderer.projection.projectionMatrix.toArray(true); + } + } + + /** + * Erases the render texture and fills the drawing area with a colour + * + * @param {number} [clearColor] - The colour + * @return {PIXI.WebGLRenderer} Returns itself. + */ + clear(clearColor) + { + if(this.renderTexture) + { + clearColor = clearColor || this.renderTexture.baseTexture.clearColor; + } + else + { + clearColor = clearColor || this.clearColor; + } + + this.renderer.framebuffer.clear(clearColor[0], clearColor[1], clearColor[2], clearColor[3]); + } + + resize(screenWidth, screenHeight) + { + // resize the root only! + this.bind(null) + } +} diff --git a/src/core/settings.js b/src/core/settings.js index 7de1975..18c5877 100644 --- a/src/core/settings.js +++ b/src/core/settings.js @@ -172,7 +172,7 @@ * @type {PIXI.SCALE_MODES} * @default PIXI.SCALE_MODES.LINEAR */ - SCALE_MODE: 0, + SCALE_MODE: 1, /** * Default specify float precision in vertex shader. diff --git a/src/core/shader/Program.js b/src/core/shader/Program.js index 46cd06e..bf93ef5 100644 --- a/src/core/shader/Program.js +++ b/src/core/shader/Program.js @@ -38,7 +38,7 @@ // this is where we store shader references.. this.glShaders = {}; - this.syncUniforms = generateUniformsSync(this.uniformData); + this.syncUniforms = null;//generateUniformsSync(this.uniformData); this.id = UID++; } @@ -53,7 +53,8 @@ */ extractData(vertexSrc, fragmentSrc) { - const gl = glCore._testingContext || Program.getTestingContext; + console.log(glCore._testingContext) + const gl = glCore._testingContext || Program.getTestingContext(); if (!gl) { @@ -71,7 +72,7 @@ this.attributeData = this.getAttributeData(program, gl); this.uniformData = this.getUniformData(program, gl); - gl.deleteProgram(program); + //gl.deleteProgram(program); } } @@ -135,6 +136,7 @@ const totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS); // TODO expose this as a prop? + // const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); const maskRegex = new RegExp('^(projectionMatrix|uSampler|translationMatrix)$'); for (let i = 0; i < totalUniforms; i++) @@ -143,7 +145,7 @@ const name = uniformData.name.replace(/\[.*?\]/, ''); const type = glCore.shader.mapType(gl, uniformData.type); - if (!name.match(maskRegex)) + // if (!name.match(maskRegex)) { /*eslint-disable */ uniforms[name] = { diff --git a/src/core/shader/Shader.js b/src/core/shader/Shader.js index b05379a..ad4fcfc 100644 --- a/src/core/shader/Shader.js +++ b/src/core/shader/Shader.js @@ -44,7 +44,7 @@ if (!uniform) // bad as we need check wher ethe uniforms are.. { - //this.uniforms.uniforms[i] = program.uniformData[i].value; + //this.uniformGroup.uniforms[i] = program.uniformData[i].value; } else if (uniform instanceof Array) { diff --git a/src/core/shader/UniformGroup.js b/src/core/shader/UniformGroup.js index 5de1a7a..8768226 100644 --- a/src/core/shader/UniformGroup.js +++ b/src/core/shader/UniformGroup.js @@ -32,6 +32,11 @@ this.dirtyId++; } + add(name, uniforms, _static) + { + this.uniforms[name] = new UniformGroup(uniforms, _static); + } + static from(uniforms, _static) { return new UniformGroup(uniforms, _static); diff --git a/src/core/shader/generateUniformsSync.js b/src/core/shader/generateUniformsSync.js index 5885d7d..8dc3adb 100644 --- a/src/core/shader/generateUniformsSync.js +++ b/src/core/shader/generateUniformsSync.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)' }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)' + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)' }; export default function generateUniformsSync(uniformData) { @@ -147,7 +147,7 @@ } //console.log(' --------------- ') - //console.log(func); + console.log(func); return new Function('uniformData', 'uniformValues', 'renderer', func); // eslint-disable-line no-new-func } diff --git a/src/core/shader/generateUniformsSync2.js b/src/core/shader/generateUniformsSync2.js index d6eb86b..c0322b1 100644 --- a/src/core/shader/generateUniformsSync2.js +++ b/src/core/shader/generateUniformsSync2.js @@ -36,8 +36,8 @@ mat3: 'gl.uniformMatrix3fv(location, false, value)', mat4: 'gl.uniformMatrix4fv(location, false, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1i(location, value)', + samplerCube: 'gl.uniform1i(location, value)', }; const GLSL_TO_ARRAY_SETTERS = { @@ -58,8 +58,8 @@ bvec3: 'gl.uniform3iv(location, value)', bvec4: 'gl.uniform4iv(location, value)', - sampler2D: 'uniform1i(location, value)', - samplerCube: 'uniform1i(location, value)', + sampler2D: 'gl.uniform1iv(location, value)', + samplerCube: 'gl.uniform1iv(location, value)', }; export default function generateUniformsSync2(group, uniformData) @@ -80,7 +80,7 @@ if(group.uniforms[i].group) { func += ` - renderer.shaderManager.syncUniformGroup(uniformValues.${i}); + renderer.shader.syncUniformGroup(uniformValues.${i}); ` } @@ -100,16 +100,26 @@ { func += `\nif (uniformValues.${i}.baseTexture) { + + renderer.texture.bind(uniformValues.${i}, ${textureCount}) + if(uniformData.${i}.value !== ${textureCount}) + { + uniformData.${i}.value = ${textureCount}; + gl.uniform1i(uniformData.${i}.location, ${textureCount});\n; // eslint-disable-line max-len + } + + /* var location = renderer.bindTexture(uniformValues.${i}.baseTexture, ${textureCount}, false); if(uniformData.${i}.value !== location) { uniformData.${i}.value = location; gl.uniform1i(uniformData.${i}.location, location);\n; // eslint-disable-line max-len - } + }*/ } else if(uniformValues.${i}._new) { + renderer.texture.bind(uniformValues.${i}, ${textureCount}) if(uniformData.${i}.value !== ${textureCount}) { @@ -119,6 +129,7 @@ } else { + console.log("binding..") uniformData.${i}.value = ${textureCount}; renderer.boundTextures[${textureCount}] = renderer.emptyTextures[${textureCount}]; gl.activeTexture(gl.TEXTURE0 + ${textureCount}); diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 7ec96b9..7952fb3 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -115,11 +115,19 @@ this.MAX_TEXTURES = checkMaxIfStatmentsInShader(this.MAX_TEXTURES, gl); } - this.MAX_TEXTURES = 1; - + glCore._testingContext = gl; const shader = this.shader = generateMultiTextureShader(gl, this.MAX_TEXTURES); - // create a couple of buffers + const sampleValues = new Int32Array(this.MAX_TEXTURES); + + for (let i = 0; i < this.MAX_TEXTURES; i++) + { + sampleValues[i] = i; + } + + shader.uniformGroup.add('default', {uSamplers:sampleValues}, true);//this.renderer.globalUniforms; + shader.uniforms.globals = this.renderer.globalUniforms; + this.indexBuffer = glCore.GLBuffer.createIndexBuffer(gl, this.indices, gl.STATIC_DRAW); // we use the second shader as the first one depending on your browser may omit aTextureId @@ -132,16 +140,17 @@ this.vertexBuffers[i] = glCore.GLBuffer.createVertexBuffer(gl, null, gl.STREAM_DRAW); /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; // build the vao object that will render.. this.vaos[i] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[i], shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[i], shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[i], shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[i], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[i], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[i], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); - if (shader.attributes.aTextureId) + if (attributeData.aTextureId) { - this.vaos[i].addAttribute(this.vertexBuffers[i], shader.attributes.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); + this.vaos[i].addAttribute(this.vertexBuffers[i], attributeData.aTextureId, gl.FLOAT, false, this.vertByteSize, 4 * 4); } /* eslint-enable max-len */ @@ -384,12 +393,14 @@ /* eslint-disable max-len */ + var attributeData = shader.program.attributeData; + // build the vao object that will render.. this.vaos[this.vertexCount] = this.renderer.createVao() .addIndex(this.indexBuffer) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) - .addAttribute(this.vertexBuffers[this.vertexCount], this.shader.attributes.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aVertexPosition, gl.FLOAT, false, this.vertByteSize, 0) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aTextureCoord, gl.UNSIGNED_SHORT, true, this.vertByteSize, 2 * 4) + .addAttribute(this.vertexBuffers[this.vertexCount], attributeData.aColor, gl.UNSIGNED_BYTE, true, this.vertByteSize, 3 * 4); if (this.shader.attributes.aTextureId) { @@ -452,7 +463,9 @@ */ start() { - this.renderer._bindGLShader(this.shader); + // this.renderer._bindGLShader(this.shader); + this.renderer.shader.bindShader(this.shader, true); + this.renderer.shader.syncUniformGroup(this.shader.uniformGroup); if (settings.CAN_UPLOAD_SAME_BUFFER) { diff --git a/src/core/sprites/webgl/generateMultiTextureShader.js b/src/core/sprites/webgl/generateMultiTextureShader.js index bf4e506..1dabb7a 100644 --- a/src/core/sprites/webgl/generateMultiTextureShader.js +++ b/src/core/sprites/webgl/generateMultiTextureShader.js @@ -1,4 +1,5 @@ import { GLShader } from 'pixi-gl-core'; +import Shader from '../../shader/Shader'; import { PRECISION } from '../../const'; import { readFileSync } from 'fs'; import { join } from 'path'; @@ -25,7 +26,8 @@ fragmentSrc = fragmentSrc.replace(/%count%/gi, maxTextures); fragmentSrc = fragmentSrc.replace(/%forloop%/gi, generateSampleSrc(maxTextures)); - const shader = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shaderold = new GLShader(gl, vertexSrc, fragmentSrc, PRECISION.DEFAULT); + const shader = Shader.from(vertexSrc, fragmentSrc);//, PRECISION.DEFAULT); const sampleValues = []; @@ -34,8 +36,9 @@ sampleValues[i] = i; } - shader.bind(); - shader.uniforms.uSamplers = sampleValues; + // shader.bind(); + // shader.uniforms.uSamplers = new Int32Array(sampleValues); + // shader.uniformGroup.static = true; return shader; } diff --git a/src/core/textures/BaseRenderTexture.js b/src/core/textures/BaseRenderTexture.js index f227ae0..87838f3 100644 --- a/src/core/textures/BaseRenderTexture.js +++ b/src/core/textures/BaseRenderTexture.js @@ -1,4 +1,5 @@ import BaseTexture from './BaseTexture'; +import FrameBuffer from './FrameBuffer'; import settings from '../settings'; /** @@ -60,7 +61,7 @@ * @private * @member {object} */ - this._glRenderTargets = {}; +// this._glRenderTargets = {}; /** * A reference to the canvas render target (we only need one as this can be shared across renderers) @@ -70,12 +71,10 @@ */ this._canvasRenderTarget = null; - /** - * This will let the renderer know if the texture is valid. If it's not then it cannot be rendered. - * - * @member {boolean} - */ - this.valid = false; + this.clearColor = [0,0,0,0]; + + this.frameBuffer = new FrameBuffer(width, height) + .addColorTexture(0, this); } /** @@ -86,22 +85,8 @@ */ resize(width, height) { - if (width === this.width && height === this.height) - { - return; - } - - this.valid = (width > 0 && height > 0); - - this.width = width; - this.height = height; - - if (!this.valid) - { - return; - } - - this.emit('update', this); + super.resize(width, height); + this.frameBuffer.resize(width, height); } /** diff --git a/src/core/textures/Texture.js b/src/core/textures/Texture.js index 1fd0ee3..1d30d8f 100644 --- a/src/core/textures/Texture.js +++ b/src/core/textures/Texture.js @@ -6,7 +6,7 @@ import EventEmitter from 'eventemitter3'; import settings from '../settings'; import { Rectangle } from '../math'; -import { TextureCache, BaseTextureCache, getResolutionOfUrl } from '../utils'; +import { TextureCache, BaseTextureCache, getResolutionOfUrl, uid } from '../utils'; /** * A texture stores the information that represents an image or part of an image. It cannot be added @@ -470,6 +470,7 @@ Texture.fromImage = Texture.from; Texture.fromSVG = Texture.from; Texture.fromCanvas = Texture.from; +Texture.fromVideo = Texture.from; Texture.fromFrame = Texture.from; function createWhiteTexture() diff --git a/src/mesh/webgl/MeshRenderer.js b/src/mesh/webgl/MeshRenderer.js index 53be712..3d33be7 100644 --- a/src/mesh/webgl/MeshRenderer.js +++ b/src/mesh/webgl/MeshRenderer.js @@ -44,7 +44,7 @@ render(mesh) { // bind the shader.. - const glShader = this.renderer.shaderManager.bindShader(mesh.shader, true); + const glShader = this.renderer.shader.bind(mesh.shader, true); // set the shader props.. if (glShader.uniformData.translationMatrix)