mirror of
https://github.com/photonstorm/phaser
synced 2024-12-17 08:33:40 +00:00
Cleaning up WebGLRenderer
This commit is contained in:
parent
a41681c21a
commit
cfe07706e6
58 changed files with 1133 additions and 1453 deletions
|
@ -1,284 +0,0 @@
|
|||
var Class = require('../../utils/Class');
|
||||
var GameObject = require('../GameObject');
|
||||
var Components = require('../components');
|
||||
var Render = require('./EffectLayerRender');
|
||||
var TexturedAndNormalizedTintedShader = require('../../renderer/webgl/shaders/TexturedAndNormalizedTintedShader');
|
||||
|
||||
// EffectLayer renders all elements on the layer to an offscreen render target
|
||||
// and then when rendering the color buffer of that render target to the main screen
|
||||
// it applies the effect layer shader.
|
||||
|
||||
var EffectLayer = new Class({
|
||||
|
||||
Extends: GameObject,
|
||||
|
||||
Mixins: [
|
||||
Components.Alpha,
|
||||
Components.BlendMode,
|
||||
Components.Flip,
|
||||
Components.GetBounds,
|
||||
Components.Origin,
|
||||
Components.RenderTarget,
|
||||
Components.ScaleMode,
|
||||
Components.Size,
|
||||
Components.Transform,
|
||||
Components.Visible,
|
||||
Components.ScrollFactor,
|
||||
Render
|
||||
],
|
||||
|
||||
initialize:
|
||||
|
||||
function EffectLayer (scene, x, y, width, height, effectName, fragmentShader)
|
||||
{
|
||||
GameObject.call(this, scene, 'EffectLayer');
|
||||
|
||||
var pot = ((width & (width - 1)) == 0 && (height & (height - 1)) == 0);
|
||||
var resourceManager = scene.sys.game.renderer.resourceManager;
|
||||
var wrap;
|
||||
var gl;
|
||||
|
||||
this.dstRenderTarget = null;
|
||||
this.renderTexture = null;
|
||||
this.dstShader = null;
|
||||
this.uniforms = {};
|
||||
|
||||
if (resourceManager !== undefined)
|
||||
{
|
||||
gl = scene.sys.game.renderer.gl;
|
||||
wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
this.dstShader = resourceManager.createShader(effectName, {
|
||||
vert: TexturedAndNormalizedTintedShader.vert,
|
||||
frag: fragmentShader
|
||||
});
|
||||
|
||||
this.renderTexture = resourceManager.createTexture(
|
||||
0,
|
||||
gl.LINEAR, gl.LINEAR,
|
||||
wrap, wrap,
|
||||
gl.RGBA,
|
||||
null, width, height
|
||||
);
|
||||
|
||||
this.dstRenderTarget = resourceManager.createRenderTarget(width, height, this.renderTexture, null);
|
||||
scene.sys.game.renderer.currentTexture[0] = null; // force rebinding of prev texture
|
||||
}
|
||||
|
||||
this.flipY = true;
|
||||
this.setPosition(x, y);
|
||||
this.setSize(width, height);
|
||||
this.setOrigin(0, 0);
|
||||
|
||||
var _this = this;
|
||||
scene.sys.game.renderer.addContextRestoredCallback(function (renderer) {
|
||||
var resourceManager = renderer.resourceManager;
|
||||
var gl = renderer.gl;
|
||||
var wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
_this.dstShader = resourceManager.createShader(effectName, {
|
||||
vert: TexturedAndNormalizedTintedShader.vert,
|
||||
frag: fragmentShader
|
||||
});
|
||||
|
||||
_this.renderTexture = resourceManager.createTexture(
|
||||
0,
|
||||
gl.LINEAR, gl.LINEAR,
|
||||
wrap, wrap,
|
||||
gl.RGBA,
|
||||
null, _this.width, _this.height
|
||||
);
|
||||
|
||||
_this.dstRenderTarget = resourceManager.createRenderTarget(_this.width, _this.height, _this.renderTexture, null);
|
||||
_this.uniforms = {};
|
||||
scene.sys.game.renderer.currentTexture[0] = null; // force rebinding of prev texture
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
setClearAlpha: function (alpha)
|
||||
{
|
||||
if (this.dstRenderTarget)
|
||||
{
|
||||
this.dstRenderTarget.clearAlpha = alpha;
|
||||
}
|
||||
},
|
||||
|
||||
renderOffScreen: function ()
|
||||
{
|
||||
this.renderTarget = this.dstRenderTarget;
|
||||
},
|
||||
|
||||
renderOnScreen: function ()
|
||||
{
|
||||
this.renderTarget = null;
|
||||
},
|
||||
|
||||
add: function (gameObject)
|
||||
{
|
||||
if (gameObject.renderTarget !== undefined)
|
||||
{
|
||||
gameObject.renderTarget = this.dstRenderTarget;
|
||||
}
|
||||
},
|
||||
|
||||
remove: function (gameObject)
|
||||
{
|
||||
if (gameObject.renderTarget !== undefined)
|
||||
{
|
||||
gameObject.renderTarget = null;
|
||||
}
|
||||
},
|
||||
|
||||
getUniformLocation: function (uniformName)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
var uniforms = this.uniforms;
|
||||
var location;
|
||||
|
||||
if (uniformName in uniforms)
|
||||
{
|
||||
location = uniforms[uniformName];
|
||||
}
|
||||
else
|
||||
{
|
||||
location = dstShader.getUniformLocation(uniformName);
|
||||
uniforms[uniformName] = location;
|
||||
}
|
||||
|
||||
return location;
|
||||
},
|
||||
|
||||
setFloat: function (uniformName, x)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantFloat1(this.getUniformLocation(uniformName), x);
|
||||
},
|
||||
|
||||
setFloat2: function (uniformName, x, y)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantFloat2(this.getUniformLocation(uniformName), x, y);
|
||||
},
|
||||
|
||||
setFloat3: function (uniformName, x, y, z)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantFloat3(this.getUniformLocation(uniformName), x, y, z);
|
||||
},
|
||||
|
||||
setFloat4: function (uniformName, x, y, z, w)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantFloat4(this.getUniformLocation(uniformName), x, y, z, w);
|
||||
},
|
||||
|
||||
setInt: function (uniformName, x)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantInt1(this.getUniformLocation(uniformName), x);
|
||||
},
|
||||
|
||||
setInt2: function (uniformName, x, y)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantInt2(this.getUniformLocation(uniformName), x, y);
|
||||
},
|
||||
|
||||
setInt3: function (uniformName, x, y, z)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantInt3(this.getUniformLocation(uniformName), x, y, z);
|
||||
},
|
||||
|
||||
setInt4: function (uniformName, x, y, z, w)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantInt4(this.getUniformLocation(uniformName), x, y, z, w);
|
||||
},
|
||||
|
||||
setMatrix2x2: function (uniformName, matrix)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantMatrix2x2(this.getUniformLocation(uniformName), matrix);
|
||||
},
|
||||
|
||||
setMatrix3x3: function (uniformName, matrix)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantMatrix3x3(this.getUniformLocation(uniformName), matrix);
|
||||
},
|
||||
|
||||
setMatrix4x4: function (uniformName, matrix)
|
||||
{
|
||||
var dstShader = this.dstShader;
|
||||
|
||||
if (dstShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
dstShader.setConstantMatrix4x4(this.getUniformLocation(uniformName), matrix);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = EffectLayer;
|
|
@ -1,7 +0,0 @@
|
|||
var EffectLayerCanvasRenderer = function (renderer, src, interpolationPercentage, camera)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
module.exports = EffectLayerCanvasRenderer;
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
var BuildGameObject = require('../BuildGameObject');
|
||||
var EffectLayer = require('./EffectLayer');
|
||||
var GameObjectCreator = require('../../scene/plugins/GameObjectCreator');
|
||||
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectCreator context.
|
||||
|
||||
GameObjectCreator.register('effectLayer', function (config)
|
||||
{
|
||||
var x = GetAdvancedValue(config, 'x', 0);
|
||||
var y = GetAdvancedValue(config, 'y', 0);
|
||||
var width = GetAdvancedValue(config, 'width', 512);
|
||||
var height = GetAdvancedValue(config, 'height', 512);
|
||||
var key = GetAdvancedValue(config, 'key', null);
|
||||
var fragmentShader = GetAdvancedValue(config, 'fragmentShader', '');
|
||||
|
||||
var layer = new EffectLayer(this.scene, x, y, width, height, effectName, fragmentShader);
|
||||
|
||||
BuildGameObject(this.scene, layer, config);
|
||||
|
||||
return layer;
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
var EffectLayer = require('./EffectLayer');
|
||||
var GameObjectFactory = require('../../scene/plugins/GameObjectFactory');
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectFactory context.
|
||||
//
|
||||
// There are several properties available to use:
|
||||
//
|
||||
// this.scene - a reference to the Scene that owns the GameObjectFactory
|
||||
// this.displayList - a reference to the Display List the Scene owns
|
||||
// this.updateList - a reference to the Update List the Scene owns
|
||||
|
||||
if (WEBGL_RENDERER)
|
||||
{
|
||||
GameObjectFactory.register('effectLayer', function (x, y, width, height, effectName, fragmentShader)
|
||||
{
|
||||
return this.displayList.add(new EffectLayer(this.scene, x, y, width, height, effectName, fragmentShader));
|
||||
});
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
var renderWebGL = require('../../utils/NOOP');
|
||||
var renderCanvas = require('../../utils/NOOP');
|
||||
|
||||
if (WEBGL_RENDERER)
|
||||
{
|
||||
renderWebGL = require('./EffectLayerWebGLRenderer');
|
||||
}
|
||||
|
||||
if (CANVAS_RENDERER)
|
||||
{
|
||||
renderCanvas = require('./EffectLayerCanvasRenderer');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
renderWebGL: renderWebGL,
|
||||
renderCanvas: renderCanvas
|
||||
|
||||
};
|
|
@ -1,13 +0,0 @@
|
|||
var GameObject = require('../GameObject');
|
||||
|
||||
var EffectLayerWebGLRenderer = function (renderer, src, interpolationPercentage, camera)
|
||||
{
|
||||
if (GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter > 0 && (src.cameraFilter & camera._id)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderer.effectRenderer.renderEffect(src, camera, src.renderTexture, src.width, src.height);
|
||||
};
|
||||
|
||||
module.exports = EffectLayerWebGLRenderer;
|
|
@ -1,354 +0,0 @@
|
|||
// RenderPass Will only work with Sprite and Image GameObjects.
|
||||
|
||||
var Class = require('../../utils/Class');
|
||||
var GameObject = require('../GameObject');
|
||||
var Components = require('../components');
|
||||
var Render = require('./RenderPassRender');
|
||||
var TexturedAndNormalizedTintedShader = require('../../renderer/webgl/shaders/TexturedAndNormalizedTintedShader');
|
||||
var UntexturedAndNormalizedTintedShader = require('../../renderer/webgl/shaders/UntexturedAndNormalizedTintedShader');
|
||||
|
||||
// RenderPass - the user has a higher control on the rendering since you explicitly
|
||||
// indicate what is rendered. RenderPass also has a render target but the difference
|
||||
// is that when explicitly rendering an object to the render pass the shader from that
|
||||
// render pass is applied. This is useful for additive passes and specific object effects.
|
||||
|
||||
var RenderPass = new Class({
|
||||
|
||||
Extends: GameObject,
|
||||
|
||||
Mixins: [
|
||||
Components.Alpha,
|
||||
Components.BlendMode,
|
||||
Components.Flip,
|
||||
Components.GetBounds,
|
||||
Components.Origin,
|
||||
Components.RenderTarget,
|
||||
Components.ScaleMode,
|
||||
Components.ScrollFactor,
|
||||
Components.Size,
|
||||
Components.Tint,
|
||||
Components.Transform,
|
||||
Components.Visible,
|
||||
Render
|
||||
],
|
||||
|
||||
initialize:
|
||||
|
||||
function RenderPass (scene, x, y, width, height, shaderName, fragmentShader, untextured)
|
||||
{
|
||||
GameObject.call(this, scene, 'RenderPass');
|
||||
|
||||
var _this = this;
|
||||
var resourceManager = scene.sys.game.renderer.resourceManager;
|
||||
var pot = ((width & (width - 1)) == 0 && (height & (height - 1)) == 0);
|
||||
var gl;
|
||||
var wrap;
|
||||
|
||||
this.renderer = scene.sys.game.renderer;
|
||||
this.passRenderTarget = null;
|
||||
this.renderTexture = null;
|
||||
this.passShader = null;
|
||||
this.uniforms = {};
|
||||
this.textures = {};
|
||||
|
||||
this.setFlipY(true);
|
||||
this.setPosition(x, y);
|
||||
this.setSize(width, height);
|
||||
this.setOrigin(0, 0);
|
||||
|
||||
if (resourceManager !== undefined)
|
||||
{
|
||||
gl = scene.sys.game.renderer.gl;
|
||||
wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
if (!untextured)
|
||||
{
|
||||
this.passShader = resourceManager.createShader(shaderName, {vert: TexturedAndNormalizedTintedShader.vert, frag: fragmentShader});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.passShader = resourceManager.createShader(shaderName, {vert: UntexturedAndNormalizedTintedShader.vert, frag: fragmentShader});
|
||||
}
|
||||
this.renderTexture = resourceManager.createTexture(0, gl.LINEAR, gl.LINEAR, wrap, wrap, gl.RGBA, null, width, height);
|
||||
this.passRenderTarget = resourceManager.createRenderTarget(width, height, this.renderTexture, null);
|
||||
scene.sys.game.renderer.currentTexture[0] = null; // force rebinding of prev texture
|
||||
this.passShader.bind();
|
||||
this.passShader.setConstantFloat2(this.passShader.getUniformLocation('u_resolution'), width, height);
|
||||
}
|
||||
|
||||
scene.sys.game.renderer.addContextRestoredCallback(function (renderer) {
|
||||
var gl = renderer.gl;
|
||||
var wrap = pot ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
_this.passShader = resourceManager.createShader(shaderName, {vert: TexturedAndNormalizedTintedShader.vert, frag: fragmentShader});
|
||||
_this.renderTexture = resourceManager.createTexture(0, gl.LINEAR, gl.LINEAR, wrap, wrap, gl.RGBA, null, _this.width, _this.height);
|
||||
_this.passRenderTarget = resourceManager.createRenderTarget(_this.width, _this.height, _this.renderTexture, null);
|
||||
_this.uniforms = {};
|
||||
_this.textures = {};
|
||||
_this.passShader.bind();
|
||||
_this.passShader.setConstantFloat2(_this.passShader.getUniformLocation('u_resolution'), _this.width, _this.height);
|
||||
scene.sys.game.renderer.currentTexture[0] = null; // force rebinding of prev texture
|
||||
});
|
||||
},
|
||||
|
||||
clearColorBuffer: function (r, g, b, a)
|
||||
{
|
||||
var gl = this.renderer.gl;
|
||||
|
||||
if (gl)
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.passRenderTarget.framebufferObject);
|
||||
gl.clearColor(r, g, b, a);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
},
|
||||
|
||||
clearDepthStencilBuffers: function (depth, stencil)
|
||||
{
|
||||
var gl = this.renderer.gl;
|
||||
|
||||
if (gl)
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.passRenderTarget.framebufferObject);
|
||||
gl.clearDepth(depth);
|
||||
gl.clearStencil(stencil);
|
||||
gl.clear(gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
},
|
||||
|
||||
clearAllBuffers: function (r, g, b, a, depth, stencil)
|
||||
{
|
||||
var gl = this.renderer.gl;
|
||||
|
||||
if (gl)
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, this.passRenderTarget.framebufferObject);
|
||||
gl.clearColor(r, g, b, a);
|
||||
gl.clearDepth(depth);
|
||||
gl.clearStencil(stencil);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
}
|
||||
},
|
||||
|
||||
render: function (gameObject, camera)
|
||||
{
|
||||
var renderer = this.renderer;
|
||||
var gl = renderer.gl;
|
||||
|
||||
if (gl && !renderer.contextLost)
|
||||
{
|
||||
//gameObject.setShader(this.passShader);
|
||||
gameObject.setRenderTarget(this.passRenderTarget);
|
||||
gameObject.renderWebGL(renderer, gameObject, 0.0, camera);
|
||||
|
||||
for (var key in this.textures)
|
||||
{
|
||||
var textureData = this.textures[key];
|
||||
this.setInt(key, textureData.unit);
|
||||
gl.activeTexture(gl.TEXTURE0 + textureData.unit);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureData.texture);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
}
|
||||
renderer.currentRenderer.flush(this.passShader, this.passRenderTarget);
|
||||
gameObject.setRenderTarget(null);
|
||||
//gameObject.setShader(null);
|
||||
}
|
||||
},
|
||||
|
||||
renderRect: function (x, y, width, height, camera)
|
||||
{
|
||||
var renderer = this.renderer;
|
||||
var gl = renderer.gl;
|
||||
|
||||
if (gl && !renderer.contextLost)
|
||||
{
|
||||
renderer.setRenderer(this.renderer.spriteBatch, null, null);
|
||||
renderer.spriteBatch.addTileTextureRect(
|
||||
null, x, y, width, height, 1.0, 0xFFFFFFFF, this.scrollFactorX, this.scrollFactorY,
|
||||
this.width, this.height, 0, 0, width, height, camera, null, false, true
|
||||
);
|
||||
for (var key in this.textures)
|
||||
{
|
||||
var textureData = this.textures[key];
|
||||
this.setInt(key, textureData.unit);
|
||||
gl.activeTexture(gl.TEXTURE0 + textureData.unit);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureData.texture);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
}
|
||||
//renderer.spriteBatch.addRenderPassRect(x, y, width, height, this.scrollFactorX, this.scrollFactorY, camera, this.passShader, this.passRenderTarget);
|
||||
renderer.spriteBatch.flush(this.passShader, this.passRenderTarget);
|
||||
}
|
||||
},
|
||||
|
||||
setRenderTextureAt: function (renderTexture, samplerName, unit)
|
||||
{
|
||||
var renderer = this.renderer;
|
||||
var gl = renderer.gl;
|
||||
|
||||
if (gl && !renderer.contextLost)
|
||||
{
|
||||
/* Texture 1 is reserved for Phasers Main Renderer */
|
||||
unit = (unit > 0) ? unit : 1;
|
||||
this.textures[samplerName] = { texture: renderTexture.texture, unit: unit };
|
||||
//this.setInt(samplerName, unit);
|
||||
//gl.activeTexture(gl.TEXTURE0 + unit);
|
||||
//gl.bindTexture(gl.TEXTURE_2D, renderTexture.texture);
|
||||
//gl.activeTexture(gl.TEXTURE0);
|
||||
}
|
||||
},
|
||||
|
||||
getUniformLocation: function (uniformName)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
var uniforms = this.uniforms;
|
||||
var location;
|
||||
|
||||
if (uniformName in uniforms)
|
||||
{
|
||||
location = uniforms[uniformName];
|
||||
}
|
||||
else
|
||||
{
|
||||
location = passShader.getUniformLocation(uniformName);
|
||||
uniforms[uniformName] = location;
|
||||
}
|
||||
|
||||
return location;
|
||||
},
|
||||
|
||||
setFloat: function (uniformName, x)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantFloat1(this.getUniformLocation(uniformName), x);
|
||||
},
|
||||
|
||||
setFloat2: function (uniformName, x, y)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantFloat2(this.getUniformLocation(uniformName), x, y);
|
||||
},
|
||||
|
||||
setFloat3: function (uniformName, x, y, z)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantFloat3(this.getUniformLocation(uniformName), x, y, z);
|
||||
},
|
||||
|
||||
setFloat4: function (uniformName, x, y, z, w)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantFloat4(this.getUniformLocation(uniformName), x, y, z, w);
|
||||
},
|
||||
|
||||
setInt: function (uniformName, x)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantInt1(this.getUniformLocation(uniformName), x);
|
||||
},
|
||||
|
||||
setInt2: function (uniformName, x, y)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantInt2(this.getUniformLocation(uniformName), x, y);
|
||||
},
|
||||
|
||||
setInt3: function (uniformName, x, y, z)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantInt3(this.getUniformLocation(uniformName), x, y, z);
|
||||
},
|
||||
|
||||
setInt4: function (uniformName, x, y, z, w)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantInt4(this.getUniformLocation(uniformName), x, y, z, w);
|
||||
},
|
||||
|
||||
setMatrix2x2: function (uniformName, matrix)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantMatrix2x2(this.getUniformLocation(uniformName), matrix);
|
||||
},
|
||||
|
||||
setMatrix3x3: function (uniformName, matrix)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantMatrix3x3(this.getUniformLocation(uniformName), matrix);
|
||||
},
|
||||
|
||||
setMatrix4x4: function (uniformName, matrix)
|
||||
{
|
||||
var passShader = this.passShader;
|
||||
|
||||
if (passShader === null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
passShader.setConstantMatrix4x4(this.getUniformLocation(uniformName), matrix);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = RenderPass;
|
|
@ -1,7 +0,0 @@
|
|||
var RenderPassCanvasRenderer = function (renderer, src, interpolationPercentage, camera)
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
module.exports = RenderPassCanvasRenderer;
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
var BuildGameObject = require('../BuildGameObject');
|
||||
var GameObjectCreator = require('../../scene/plugins/GameObjectCreator');
|
||||
var GetAdvancedValue = require('../../utils/object/GetAdvancedValue');
|
||||
var RenderPass = require('./RenderPass');
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectCreator context.
|
||||
|
||||
GameObjectCreator.register('renderPass', function (config)
|
||||
{
|
||||
var x = GetAdvancedValue(config, 'x', 0);
|
||||
var y = GetAdvancedValue(config, 'y', 0);
|
||||
var width = GetAdvancedValue(config, 'width', 512);
|
||||
var height = GetAdvancedValue(config, 'height', 512);
|
||||
var shaderName = GetAdvancedValue(config, 'shaderName', '');
|
||||
var fragmentShader = GetAdvancedValue(config, 'fragmentShader', '');
|
||||
var untextured = GetAdvancedValue(config, 'untextured', false);
|
||||
|
||||
var pass = new RenderPass(this.scene, x, y, width, height, shaderName, fragmentShader, untextured);
|
||||
|
||||
BuildGameObject(this.scene, pass, config);
|
||||
|
||||
pass.setPosition(x, y);
|
||||
pass.setSize(width, height);
|
||||
pass.setOrigin(0, 0);
|
||||
|
||||
return pass;
|
||||
});
|
|
@ -1,18 +0,0 @@
|
|||
var RenderPass = require('./RenderPass');
|
||||
var GameObjectFactory = require('../../scene/plugins/GameObjectFactory');
|
||||
|
||||
// When registering a factory function 'this' refers to the GameObjectFactory context.
|
||||
//
|
||||
// There are several properties available to use:
|
||||
//
|
||||
// this.scene - a reference to the Scene that owns the GameObjectFactory
|
||||
// this.displayList - a reference to the Display List the Scene owns
|
||||
// this.updateList - a reference to the Update List the Scene owns
|
||||
|
||||
if (WEBGL_RENDERER)
|
||||
{
|
||||
GameObjectFactory.register('renderPass', function (x, y, width, height, shaderName, fragmentShader, untextured)
|
||||
{
|
||||
return this.displayList.add(new RenderPass(this.scene, x, y, width, height, shaderName, fragmentShader, untextured));
|
||||
});
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
var renderWebGL = require('../../utils/NOOP');
|
||||
var renderCanvas = require('../../utils/NOOP');
|
||||
|
||||
if (WEBGL_RENDERER)
|
||||
{
|
||||
renderWebGL = require('./RenderPassWebGLRenderer');
|
||||
}
|
||||
|
||||
if (CANVAS_RENDERER)
|
||||
{
|
||||
renderCanvas = require('./RenderPassCanvasRenderer');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
renderWebGL: renderWebGL,
|
||||
renderCanvas: renderCanvas
|
||||
|
||||
};
|
|
@ -1,13 +0,0 @@
|
|||
var GameObject = require('../GameObject');
|
||||
|
||||
var RenderPassWebGLRenderer = function (renderer, src, interpolationPercentage, camera)
|
||||
{
|
||||
if (GameObject.RENDER_MASK !== src.renderFlags || (src.cameraFilter > 0 && (src.cameraFilter & camera._id)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
renderer.spriteBatch.addSpriteTexture(src, camera, src.renderTexture, src.width, src.height);
|
||||
};
|
||||
|
||||
module.exports = RenderPassWebGLRenderer;
|
178
src/renderer/webgl/WebGLPipeline.js
Normal file
178
src/renderer/webgl/WebGLPipeline.js
Normal file
|
@ -0,0 +1,178 @@
|
|||
var Class = require('../../utils/Class');
|
||||
|
||||
var WebGLPipeline = new Class({
|
||||
|
||||
initialize:
|
||||
|
||||
function WebGLPipeline(config)
|
||||
{
|
||||
this.name = config.name;
|
||||
this.game = config.game;
|
||||
this.view = config.game.canvas;
|
||||
this.resolution = config.game.config.resolution;
|
||||
this.width = config.game.config.width * this.resolution;
|
||||
this.height = config.game.config.height * this.resolution;
|
||||
this.gl = config.gl;
|
||||
this.vertexCount = 0;
|
||||
this.vertexCapacity = config.vertexCapacity;
|
||||
this.manager = config.manager;
|
||||
this.resources = config.manager.resourceManager;
|
||||
this.vertexData = new ArrayBuffer(config.vertexCapacity * config.vertexSize);
|
||||
this.vertexBuffer = null;
|
||||
this.program = null;
|
||||
this.vertexLayout = config.vertexLayout;
|
||||
this.vertexSize = config.vertexSize;
|
||||
this.topology = config.topology;
|
||||
|
||||
// Initialize Shaders and Buffers
|
||||
{
|
||||
var gl = this.gl;
|
||||
var resources = this.resources;
|
||||
var vertexSize = this.vertexSize;
|
||||
var vertexLayout = this.vertexLayout;
|
||||
var program = resources.createShader(this.name, config.shader);
|
||||
var vertexBuffer = resources.createBuffer(gl.ARRAY_BUFFER, this.vertexData.byteLength, gl.STREAM_DRAW);
|
||||
|
||||
for (var key in vertexLayout)
|
||||
{
|
||||
var element = vertexLayout[key];
|
||||
|
||||
vertexBuffer.addAttribute(
|
||||
program.getAttribLocation(key),
|
||||
element.size,
|
||||
element.type,
|
||||
element.normalize,
|
||||
vertexSize,
|
||||
element.offset
|
||||
);
|
||||
}
|
||||
|
||||
this.vertexBuffer = vertexBuffer;
|
||||
this.program = program;
|
||||
}
|
||||
},
|
||||
|
||||
shouldFlush: function ()
|
||||
{
|
||||
return this.vertexCount >= this.vertexCapacity;
|
||||
},
|
||||
|
||||
resize: function (width, height, resolution)
|
||||
{
|
||||
this.width = width * resolution;
|
||||
this.height = height * resolution;
|
||||
return this;
|
||||
},
|
||||
|
||||
bind: function (overrideProgram)
|
||||
{
|
||||
// Check if we're using a custom program or
|
||||
// the default one from the pipeline.
|
||||
if (!overrideProgram) this.program.bind();
|
||||
else overrideProgram.bind();
|
||||
|
||||
this.vertexBuffer.bind();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
flush: function ()
|
||||
{
|
||||
var gl = this.gl;
|
||||
var vertexCount = this.vertexCount;
|
||||
var vertexBuffer = this.vertexBuffer;
|
||||
var vertexData = this.vertexData;
|
||||
var topology = this.topology;
|
||||
|
||||
if (vertexCount === 0) return;
|
||||
|
||||
vertexBuffer.updateResource(vertexData, 0);
|
||||
gl.drawArrays(topology, 0, vertexCount);
|
||||
|
||||
this.vertexCount = 0;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
destroy: function ()
|
||||
{
|
||||
var resources = this.resources;
|
||||
|
||||
resources.deleteShader(this.program);
|
||||
resources.deleteBuffer(this.vertexBuffer);
|
||||
|
||||
this.program = null;
|
||||
this.vertexBuffer = null;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1f(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2f(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3f(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4f(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1i(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2i(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3i(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4i(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix2: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix3: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix4: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = WebGLPipeline;
|
|
@ -1,680 +1,288 @@
|
|||
/**
|
||||
* @author Richard Davey (@photonstorm)
|
||||
* @author Felipe Alfonso (@bitnenfer)
|
||||
* @copyright 2017 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var BlendModes = require('../BlendModes');
|
||||
var BlitterBatch = require('./pipelines/blitterbatch/BlitterBatch');
|
||||
var Class = require('../../utils/Class');
|
||||
var CONST = require('../../const');
|
||||
var EffectRenderer = require('./pipelines/effectrenderer/EffectRenderer');
|
||||
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
|
||||
var MaskRenderer = require('./pipelines/maskrenderer/MaskRenderer');
|
||||
var QuadBatch = require('./pipelines/quadbatch/QuadBatch');
|
||||
var ParticleRenderer = require('./pipelines/particlerenderer/ParticleRenderer');
|
||||
var ResourceManager = require('./ResourceManager');
|
||||
var Resources = require('./resources');
|
||||
var ScaleModes = require('../ScaleModes');
|
||||
var ShapeBatch = require('./pipelines/shapebatch/ShapeBatch');
|
||||
var SpriteRenderer = require('./pipelines/spriterenderer/SpriteRenderer');
|
||||
var TileBatch = require('./pipelines/tilebatch/TileBatch');
|
||||
var TilemapRenderer = require('./pipelines/tilemaprenderer/TilemapRenderer');
|
||||
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
|
||||
|
||||
var WebGLpipeline = new Class({
|
||||
var WebGLRenderer = new Class({
|
||||
|
||||
initialize:
|
||||
|
||||
function WebGLpipeline (game)
|
||||
function WebGLRenderer (game)
|
||||
{
|
||||
var _this = this;
|
||||
this.game = game;
|
||||
this.onContextLostCallbacks = [];
|
||||
this.onContextRestoredCallbacks = [];
|
||||
this.type = CONST.WEBGL;
|
||||
this.width = game.config.width * game.config.resolution;
|
||||
this.height = game.config.height * game.config.resolution;
|
||||
this.resolution = game.config.resolution;
|
||||
this.view = game.canvas;
|
||||
this.view.addEventListener('webglcontextlost', function (evt) {
|
||||
var callbacks = _this.onContextLostCallbacks;
|
||||
var pipelines = _this.pipelines;
|
||||
for (var index = 0; index < pipelines.length; ++index)
|
||||
{
|
||||
pipelines[index].destroy();
|
||||
}
|
||||
_this.contextLost = true;
|
||||
for (var index = 0; index < callbacks.length; ++index)
|
||||
{
|
||||
callbacks[index](_this);
|
||||
}
|
||||
evt.preventDefault();
|
||||
}, false);
|
||||
|
||||
this.view.addEventListener('webglcontextrestored', function (evt) {
|
||||
var callbacks = _this.onContextRestoredCallbacks;
|
||||
_this.pipelines.length = 0;
|
||||
_this.resourceManager.shaderCache = {};
|
||||
_this.resourceManager.shaderCount = 0;
|
||||
_this.contextLost = false;
|
||||
_this.init();
|
||||
_this.game.textures.each(function (texture) {
|
||||
for (var i = 0; i < texture.source.length; ++i)
|
||||
{
|
||||
texture.source[i].init(_this.game);
|
||||
}
|
||||
}, null);
|
||||
for (var index = 0; index < callbacks.length; ++index)
|
||||
{
|
||||
callbacks[index](_this);
|
||||
}
|
||||
}, false);
|
||||
|
||||
// All of these settings will be able to be controlled via the Game Config
|
||||
this.config = {
|
||||
clearBeforeRender: true,
|
||||
transparent: false,
|
||||
autoResize: false,
|
||||
preserveDrawingBuffer: false,
|
||||
|
||||
WebGLContextOptions: {
|
||||
alpha: true,
|
||||
var renderer = this;
|
||||
var config = {
|
||||
backgroundColor: game.config.backgroundColor,
|
||||
contextCreation: {
|
||||
alpha: false,
|
||||
depth: false, // enable when 3D is added in the future
|
||||
antialias: true,
|
||||
premultipliedAlpha: true,
|
||||
stencil: true,
|
||||
preserveDrawingBuffer: false
|
||||
preserveDrawingBuffer: false,
|
||||
failIfMajorPerformanceCaveat: false
|
||||
}
|
||||
};
|
||||
|
||||
this.contextLost = false;
|
||||
this.maxTextures = 1;
|
||||
this.multiTexture = false;
|
||||
this.game = game;
|
||||
this.type = CONST.WEBGL;
|
||||
this.width = game.config.width * game.config.resolution;
|
||||
this.height = game.config.height * game.config.resolution;
|
||||
this.canvas = game.canvas;
|
||||
this.blendModes = [];
|
||||
this.gl = null;
|
||||
this.extensions = null;
|
||||
this.extensionList = {};
|
||||
this.pipelines = [];
|
||||
this.blitterBatch = null;
|
||||
this.aaQuadBatch = null;
|
||||
this.spriteBatch = null;
|
||||
this.shapeBatch = null;
|
||||
this.EffectRenderer = null;
|
||||
this.MaskRenderer = null;
|
||||
this.contextLost = false;
|
||||
this.autoResize = false;
|
||||
this.pipelines = null;
|
||||
|
||||
for (var i = 0; i <= 16; i++)
|
||||
{
|
||||
this.blendModes.push({ func: [ WebGLRenderingContext.ONE, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA ], equation: WebGLRenderingContext.FUNC_ADD });
|
||||
}
|
||||
|
||||
this.blendModes[1].func = [ WebGLRenderingContext.ONE, WebGLRenderingContext.DST_ALPHA ];
|
||||
this.blendModes[2].func = [ WebGLRenderingContext.DST_COLOR, WebGLRenderingContext.ONE_MINUS_SRC_ALPHA ];
|
||||
this.blendModes[3].func = [ WebGLRenderingContext.ONE, WebGLRenderingContext.ONE_MINUS_SRC_COLOR ];
|
||||
|
||||
// Intenal Renderer State (Textures, Framebuffers, Pipelines, Buffers, etc)
|
||||
this.currentTextures = new Array(16);
|
||||
this.currentFramebuffer = null;
|
||||
this.currentPipeline = null;
|
||||
this.currentTexture = [];
|
||||
this.shaderCache = {};
|
||||
this.currentShader = null;
|
||||
this.resourceManager = null;
|
||||
this.currentRenderTarget = null;
|
||||
this.snapshotCallback = null;
|
||||
this.snapshotType = null;
|
||||
this.snapshotEncoder = null;
|
||||
this.currentVertexBuffer = null;
|
||||
this.currentIndexBuffer = null;
|
||||
this.currentBlendMode = CONST.BlendModes.NORMAL;
|
||||
this.currentScissorState = { enabled: false, x: 0, y: 0, w: 0, h: 0 };
|
||||
|
||||
this.scissor = {
|
||||
enabled: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
};
|
||||
// Setup context lost and restore event listeners
|
||||
this.canvas.addEventListener('webglcontextlost', function (event) {
|
||||
renderer.contextLost = true;
|
||||
event.preventDefault();
|
||||
}, false);
|
||||
|
||||
this.init();
|
||||
this.canvas.addEventListener('webglcontextrestored', function (event) {
|
||||
renderer.contextLost = false;
|
||||
renderer.init(config);
|
||||
}, false);
|
||||
|
||||
// This are initialized post context creation
|
||||
this.gl = null;
|
||||
this.supportedExtensions = null;
|
||||
this.extensions = {};
|
||||
|
||||
this.init(config);
|
||||
},
|
||||
|
||||
init: function ()
|
||||
init: function (config)
|
||||
{
|
||||
this.gl = this.view.getContext('webgl', this.config.WebGLContextOptions) || this.view.getContext('experimental-webgl', this.config.WebGLContextOptions);
|
||||
|
||||
if (!this.gl)
|
||||
var canvas = this.canvas;
|
||||
var clearColor = config.backgroundColor;
|
||||
var gl = canvas.getContext('webgl', config.contextCreation) || canvas.getContext('experimental-webgl', config.contextCreation);
|
||||
|
||||
if (!gl)
|
||||
{
|
||||
this.contextLost = true;
|
||||
throw new Error('This browser does not support WebGL. Try using the Canvas pipeline.');
|
||||
}
|
||||
var gl = this.gl;
|
||||
|
||||
this.lostContext = this.getExtension('WEBGL_lose_context');
|
||||
// Load supported extensions
|
||||
this.supportedExtensions = gl.getSupportedExtensions();
|
||||
|
||||
var color = this.game.config.backgroundColor;
|
||||
|
||||
this.resourceManager = new ResourceManager(gl);
|
||||
|
||||
// Setup initial WebGL state
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.CULL_FACE);
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
gl.enable(gl.BLEND);
|
||||
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
|
||||
|
||||
// Map Blend Modes
|
||||
this.blendModes = [];
|
||||
gl.clearColor(clearColor.redGL, clearColor.greenGL, clearColor.blueGL, 1.0);
|
||||
|
||||
for (var i = 0; i <= 16; i++)
|
||||
// Initialize all textures to null
|
||||
for (var index = 0; index < this.currentTextures.length; ++index)
|
||||
{
|
||||
this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD });
|
||||
this.currentTextures[index] = null;
|
||||
}
|
||||
|
||||
// Add
|
||||
this.blendModes[1].func = [ gl.ONE, gl.DST_ALPHA ];
|
||||
|
||||
// Multiply
|
||||
this.blendModes[2].func = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ];
|
||||
|
||||
// Screen
|
||||
this.blendModes[3].func = [ gl.ONE, gl.ONE_MINUS_SRC_COLOR ];
|
||||
|
||||
this.blendMode = -1;
|
||||
this.extensions = gl.getSupportedExtensions();
|
||||
this.blitterBatch = this.addPipeline(new BlitterBatch(this.game, gl, this));
|
||||
//this.quadBatch = this.addPipeline(new QuadBatch(this.game, gl, this));
|
||||
this.spriteRenderer = this.addPipeline(new SpriteRenderer(this.game, gl, this));
|
||||
//this.shapeBatch = this.addPipeline(new ShapeBatch(this.game, gl, this));
|
||||
//this.EffectRenderer = this.addPipeline(new EffectRenderer(this.game, gl, this));
|
||||
//this.tileBatch = this.addPipeline(new TileBatch(this.game, gl, this));
|
||||
//this.TilemapRenderer = this.addPipeline(new TilemapRenderer(this.game, gl, this));
|
||||
//this.ParticleRenderer = this.addPipeline(new ParticleRenderer(this.game, gl, this));
|
||||
//this.MaskRenderer = this.addPipeline(new MaskRenderer(this.game, gl, this));
|
||||
this.currentPipeline = this.spriteRenderer;
|
||||
this.currentVertexBuffer = null;
|
||||
this.setBlendMode(0);
|
||||
this.resize(this.width, this.height);
|
||||
},
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFunc
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFuncSeparate
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendEquation
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendEquationSeparate
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendColor
|
||||
addBlendMode: function (func, equation)
|
||||
{
|
||||
var index = this.blendModes.push({ func: func, equation: equation });
|
||||
|
||||
return index - 1;
|
||||
},
|
||||
|
||||
updateBlendMode: function (index, func, equation)
|
||||
{
|
||||
if (this.blendModes[index])
|
||||
{
|
||||
this.blendModes[index].func = func;
|
||||
|
||||
if (equation)
|
||||
{
|
||||
this.blendModes[index].equation = equation;
|
||||
}
|
||||
}
|
||||
// Clear previous pipelines and reload default ones
|
||||
this.pipelines = {};
|
||||
|
||||
this.setBlendMode(CONST.BlendModes.NORMAL);
|
||||
this.resize(this.width, this.height, this.game.config.resolution);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeBlendMode: function (index)
|
||||
{
|
||||
if (index > 16 && this.blendModes[index])
|
||||
{
|
||||
this.blendModes.splice(index, 1);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
getExtension: function (name)
|
||||
{
|
||||
if (!(name in this.extensionList))
|
||||
{
|
||||
this.extensionList[name] = this.gl.getExtension(name);
|
||||
}
|
||||
return this.extensionList[name];
|
||||
},
|
||||
|
||||
addContextLostCallback: function (callback)
|
||||
{
|
||||
if (this.onContextLostCallbacks.indexOf(callback) === -1)
|
||||
{
|
||||
this.onContextLostCallbacks.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
addContextRestoredCallback: function (callback)
|
||||
{
|
||||
if (this.onContextRestoredCallbacks.indexOf(callback) === -1)
|
||||
{
|
||||
this.onContextRestoredCallbacks.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
createTexture: function (source, width, height)
|
||||
{
|
||||
width = source ? source.width : width;
|
||||
height = source ? source.height : height;
|
||||
|
||||
var gl = this.gl;
|
||||
var filter = gl.NEAREST;
|
||||
var wrap = IsSizePowerOfTwo(width, height) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
|
||||
if (!source.glTexture)
|
||||
{
|
||||
if (source.scaleMode === ScaleModes.LINEAR)
|
||||
{
|
||||
filter = gl.LINEAR;
|
||||
}
|
||||
else if (source.scaleMode === ScaleModes.NEAREST || this.game.config.pixelArt)
|
||||
{
|
||||
filter = gl.NEAREST;
|
||||
}
|
||||
|
||||
if (!source && typeof width === 'number' && typeof height === 'number')
|
||||
{
|
||||
source.glTexture = this.resourceManager.createTexture(
|
||||
0,
|
||||
filter,
|
||||
filter,
|
||||
wrap,
|
||||
wrap,
|
||||
gl.RGBA,
|
||||
null,
|
||||
width, height
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
source.glTexture = this.resourceManager.createTexture(
|
||||
0,
|
||||
filter,
|
||||
filter,
|
||||
wrap,
|
||||
wrap,
|
||||
gl.RGBA,
|
||||
source.image
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.currentTexture[0] = null;
|
||||
},
|
||||
|
||||
setTexture: function (texture, unit)
|
||||
{
|
||||
unit = unit || 0;
|
||||
if (this.currentTexture[unit] !== texture)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + unit);
|
||||
|
||||
if (texture !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
this.currentTexture[unit] = texture;
|
||||
}
|
||||
},
|
||||
|
||||
setPipeline: function (pipeline)
|
||||
{
|
||||
if (this.currentPipeline !== pipeline ||
|
||||
this.currentPipeline.shouldFlush())
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
this.currentPipeline.endPass();
|
||||
this.currentPipeline = pipeline;
|
||||
}
|
||||
},
|
||||
|
||||
setRenderTarget: function (renderTarget)
|
||||
resize: function (width, height, resolution)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (this.currentRenderTarget !== renderTarget)
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (renderTarget !== null)
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTarget.framebufferObject);
|
||||
|
||||
if (renderTarget.shouldClear)
|
||||
{
|
||||
gl.clearColor(0, 0, 0, renderTarget.clearAlpha);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
renderTarget.shouldClear = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
}
|
||||
|
||||
this.currentRenderTarget = renderTarget;
|
||||
}
|
||||
},
|
||||
|
||||
resize: function (width, height)
|
||||
{
|
||||
var resolution = this.game.config.resolution;
|
||||
|
||||
this.width = width * resolution;
|
||||
this.height = height * resolution;
|
||||
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
|
||||
this.canvas.width = this.width;
|
||||
this.canvas.height = this.height;
|
||||
|
||||
if (this.autoResize)
|
||||
{
|
||||
this.view.style.width = (this.width / resolution) + 'px';
|
||||
this.view.style.height = (this.height / resolution) + 'px';
|
||||
this.canvas.style.width = (this.width / resolution) + 'px';
|
||||
this.canvas.style.height = (this.height / resolution) + 'px';
|
||||
}
|
||||
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
for (var i = 0, l = this.pipelines.length; i < l; ++i)
|
||||
{
|
||||
//this.pipelines[i].bind();
|
||||
//this.pipelines[i].resize(width, height, resolution);
|
||||
}
|
||||
// Update all registered pipelines
|
||||
|
||||
//this.currentPipeline.bind();
|
||||
return this;
|
||||
},
|
||||
|
||||
// Call at the start of the render loop
|
||||
preRender: function ()
|
||||
hasExtension: function (extensionName)
|
||||
{
|
||||
// No point rendering if our context has been blown up!
|
||||
if (this.contextLost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.setRenderTarget(null);
|
||||
// Add Pre-render hook
|
||||
|
||||
var gl = this.gl;
|
||||
var color = this.game.config.backgroundColor;
|
||||
|
||||
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
|
||||
|
||||
// Some drivers require to call glClear
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
this.setBlendMode(BlendModes.NORMAL);
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
return this.supportedExtensions ? this.supportedExtensions.indexOf(extensionName) : false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders a single Scene.
|
||||
*
|
||||
* @method render
|
||||
* @param {Phaser.Scene} scene - The Scene to be rendered.
|
||||
* @param {number} interpolationPercentage - The cumulative amount of time that hasn't been simulated yet, divided
|
||||
* by the amount of time that will be simulated the next time update()
|
||||
* runs. Useful for interpolating frames.
|
||||
*/
|
||||
render: function (scene, children, interpolationPercentage, camera)
|
||||
getExtension: function (extensionName)
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
var gl = this.gl;
|
||||
var quadBatch = this.quadBatch;
|
||||
if (!this.hasExtension(extensionName)) return null;
|
||||
|
||||
this.scissor.enabled = (camera.x !== 0 || camera.y !== 0 || camera.width !== gl.canvas.width || camera.height !== gl.canvas.height);
|
||||
|
||||
this.setRenderTarget(null);
|
||||
|
||||
if (this.scissor.enabled)
|
||||
if (!(extensionName in this.extensions))
|
||||
{
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
this.scissor.x = camera.x;
|
||||
this.scissor.y = gl.drawingBufferHeight - camera.y - camera.height;
|
||||
this.scissor.width = camera.width;
|
||||
this.scissor.height = camera.height;
|
||||
|
||||
gl.scissor(this.scissor.x, this.scissor.y, this.scissor.width, this.scissor.height);
|
||||
this.extensions[extensionName] = this.gl.getExtension(extensionName);
|
||||
}
|
||||
|
||||
if (camera.backgroundColor.alphaGL > 0)
|
||||
{
|
||||
var color = camera.backgroundColor;
|
||||
|
||||
//quadBatch.bind();
|
||||
//quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// color.redGL, color.greenGL, color.blueGL, color.alphaGL
|
||||
//);
|
||||
//quadBatch.flush();
|
||||
//this.currentPipeline.bind();
|
||||
}
|
||||
|
||||
var list = children.list;
|
||||
var length = list.length;
|
||||
var pipeline;
|
||||
|
||||
for (var index = 0; index < length; ++index)
|
||||
{
|
||||
var child = list[index];
|
||||
|
||||
if (!child.willRender())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.blendMode !== this.blendMode)
|
||||
{
|
||||
this.setBlendMode(child.blendMode);
|
||||
}
|
||||
|
||||
if (child.mask)
|
||||
{
|
||||
child.mask.preRenderWebGL(this, child, camera);
|
||||
}
|
||||
|
||||
// drawing child
|
||||
child.renderWebGL(this, child, interpolationPercentage, camera);
|
||||
|
||||
if (child.mask)
|
||||
{
|
||||
child.mask.postRenderWebGL(this, child);
|
||||
}
|
||||
|
||||
pipeline = this.currentPipeline;
|
||||
|
||||
if (pipeline.shouldFlush())
|
||||
{
|
||||
pipeline.flush();
|
||||
}
|
||||
}
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (camera._fadeAlpha > 0 || camera._flashAlpha > 0)
|
||||
{
|
||||
this.setRenderTarget(null);
|
||||
this.setBlendMode(BlendModes.NORMAL);
|
||||
|
||||
// // fade rendering
|
||||
// quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// camera._fadeRed,
|
||||
// camera._fadeGreen,
|
||||
// camera._fadeBlue,
|
||||
// camera._fadeAlpha
|
||||
// );
|
||||
// // flash rendering
|
||||
// quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// camera._flashRed,
|
||||
// camera._flashGreen,
|
||||
// camera._flashBlue,
|
||||
// camera._flashAlpha
|
||||
// );
|
||||
// quadBatch.flush();
|
||||
// this.currentPipeline.bind();
|
||||
}
|
||||
|
||||
if (this.scissor.enabled)
|
||||
{
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
}
|
||||
return this.extensions[extensionName];
|
||||
},
|
||||
|
||||
// Called at the end of the render loop (tidy things up, etc)
|
||||
postRender: function ()
|
||||
/* Renderer State Manipulation Functions */
|
||||
|
||||
hasPipeline: function (pipelineName)
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (this.snapshotCallback)
|
||||
{
|
||||
this.snapshotCallback(WebGLSnapshot(this.view, this.snapshotType, this.snapshotEncoder));
|
||||
this.snapshotCallback = null;
|
||||
}
|
||||
|
||||
// Add Post-render hook
|
||||
|
||||
// console.log('%c render end ', 'color: #ffffff; background: #ff0000;');
|
||||
return (pipelineName in this.pipelines);
|
||||
},
|
||||
|
||||
snapshot: function (callback, type, encoderOptions)
|
||||
getPipeline: function (pipelineName)
|
||||
{
|
||||
this.snapshotCallback = callback;
|
||||
this.snapshotType = type;
|
||||
this.snapshotEncoder = encoderOptions;
|
||||
},
|
||||
|
||||
createFBO: function () {},
|
||||
|
||||
setBlendMode: function (newBlendMode)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (newBlendMode === BlendModes.SKIP_CHECK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pipeline = this.currentPipeline;
|
||||
|
||||
if (this.blendMode !== newBlendMode)
|
||||
{
|
||||
if (pipeline)
|
||||
{
|
||||
pipeline.flush();
|
||||
}
|
||||
|
||||
var blend = this.blendModes[newBlendMode].func;
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendEquation(this.blendModes[newBlendMode].equation);
|
||||
|
||||
if (blend.length > 2)
|
||||
{
|
||||
gl.blendFuncSeparate(blend[0], blend[1], blend[2], blend[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.blendFunc(blend[0], blend[1]);
|
||||
}
|
||||
|
||||
this.blendMode = newBlendMode;
|
||||
}
|
||||
},
|
||||
|
||||
addPipeline: function (pipelineInstance)
|
||||
{
|
||||
var index = this.pipelines.indexOf(pipelineInstance);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
this.pipelines.push(pipelineInstance);
|
||||
return pipelineInstance;
|
||||
}
|
||||
|
||||
if (this.hasPipeline(pipelineName)) return this.pipelines[pipelineName];
|
||||
return null;
|
||||
},
|
||||
|
||||
setTextureFilterMode: function (texture, filterMode)
|
||||
removePipeline: function (pipelineName)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var glFilter = [ gl.LINEAR, gl.NEAREST ][filterMode];
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
|
||||
|
||||
if (this.currentTexture[0] !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentTexture[0].texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
return texture;
|
||||
delete this.pipelines[pipelineName];
|
||||
return this;
|
||||
},
|
||||
|
||||
uploadCanvasToGPU: function (srcCanvas, dstTexture, shouldReallocate)
|
||||
addPipeline: function (pipelineName, pipelineInstance)
|
||||
{
|
||||
if (!this.hasPipeline(pipelineName)) this.pipelines[pipelineName] = pipelineInstance;
|
||||
else console.warn('Pipeline', pipelineName, ' already exists.');
|
||||
|
||||
this.pipelines[pipelineName].resize(this.width, this.height, this.game.config.resolution);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setBlendMode: function (blendModeId)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var pipeline = this.currentPipeline;
|
||||
var blendMode = this.blendModes[blendModeId];
|
||||
|
||||
if (blendModeId === CONST.BlendModes.SKIP_CHECK || !pipeline)
|
||||
return;
|
||||
|
||||
if (this.currentBlendMode !== blendModeId)
|
||||
{
|
||||
pipeline.flush();
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendEquation(blendMode.equation);
|
||||
|
||||
if (blendMode.func.length > 2)
|
||||
{
|
||||
gl.blendFuncSeparate(blendMode.func[0], blendMode.func[1], blendMode.func[2], blendMode.func[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.blendFunc(blendMode.func[0], blendMode.func[1]);
|
||||
}
|
||||
|
||||
this.currentBlendMode = blendModeId;
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setTexture2D: function (texture, textureUnit)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (!dstTexture)
|
||||
if (texture !== this.currentTextures[textureUnit])
|
||||
{
|
||||
dstTexture = new Resources.Texture(null, 0, 0);
|
||||
gl.activeTexture(gl.TEXTURE0 + textureUnit);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
// Only call this once
|
||||
dstTexture.texture = gl.createTexture();
|
||||
this.currentTextures[textureUnit] = texture;
|
||||
}
|
||||
|
||||
if (dstTexture != this.currentTexture[0])
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
}
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
if (!shouldReallocate)
|
||||
{
|
||||
// Update resource
|
||||
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate or Reallocate resource
|
||||
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
dstTexture.width = srcCanvas.width;
|
||||
dstTexture.height = srcCanvas.height;
|
||||
}
|
||||
|
||||
// We must rebind old texture
|
||||
if (this.currentTexture.length > 0 && dstTexture != this.currentTexture[0] && this.currentTexture[0] !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentTexture[0].texture);
|
||||
}
|
||||
|
||||
return dstTexture;
|
||||
return this;
|
||||
},
|
||||
|
||||
destroy: function ()
|
||||
setFramebuffer: function (framebuffer)
|
||||
{
|
||||
if (this.lostContext)
|
||||
var gl = this.gl;
|
||||
|
||||
if (framebuffer !== this.currentFramebuffer)
|
||||
{
|
||||
this.lostContext.loseContext();
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
|
||||
}
|
||||
this.gl = null;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setVertexBuffer: function (vertexBuffer)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (vertexBuffer !== this.currentVertexBuffer)
|
||||
{
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setIndexBuffer: function (indexBuffer)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (indexBuffer !== this.currentIndexBuffer)
|
||||
{
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/* Renderer Resource Creation Functions */
|
||||
|
||||
createTexture2D: function ()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
createFramebuffer: function ()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
createProgram: function ()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
createVertexBuffer: function ()
|
||||
{
|
||||
|
||||
},
|
||||
|
||||
createIndexBuffer: function ()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = WebGLpipeline;
|
||||
module.exports = WebGLRenderer;
|
||||
|
|
|
@ -22,19 +22,7 @@ var Pipeline = new Class({
|
|||
this.program = null;
|
||||
this.vertexLayout = config.vertexLayout;
|
||||
this.vertexSize = config.vertexSize;
|
||||
this.currentRenderTarget = null;
|
||||
this.currentProgram = null;
|
||||
this.topology = config.topology;
|
||||
this.onBeginPassTarget = config.onBeginPassTarget || null;
|
||||
this.onEndPassTarget = config.onBeginPassTarget || null;
|
||||
this.onFlushTarget = config.onFlushTarget || null;
|
||||
this.onBindTarget = config.onBindTarget || null;
|
||||
this.onResizeTarget = config.onResizeTarget || null;
|
||||
this.onBeginPass = config.onBeginPass || function onBeginPassStub(pipeline) {};
|
||||
this.onEndPass = config.onEndPass || function onEndPassStub(pipeline) {};
|
||||
this.onFlush = config.onFlush || function onFlushStub(pipeline) {};
|
||||
this.onBind = config.onBind || function onBindStub(pipeline) {};
|
||||
this.onResize = config.onResize || function onResize(width, height, resolution) {};
|
||||
|
||||
// Initialize Shaders and Buffers
|
||||
{
|
||||
|
@ -69,43 +57,22 @@ var Pipeline = new Class({
|
|||
return this.vertexCount >= this.vertexCapacity;
|
||||
},
|
||||
|
||||
bind: function ()
|
||||
{
|
||||
this.onBind.call(this.onBindTarget, this);
|
||||
return this;
|
||||
},
|
||||
|
||||
resize: function (width, height, resolution)
|
||||
{
|
||||
this.onResize.call(this.onResizeTarget, width, height, resolution);
|
||||
this.width = width * resolution;
|
||||
this.height = height * resolution;
|
||||
return this;
|
||||
},
|
||||
|
||||
beginPass: function (renderTarget, program)
|
||||
bind: function (overrideProgram)
|
||||
{
|
||||
if (this.currentRenderTarget !== null ||
|
||||
this.currentProgram !== null)
|
||||
{
|
||||
this.flush();
|
||||
this.endPass();
|
||||
}
|
||||
// Check if we're using a custom program or
|
||||
// the default one from the pipeline.
|
||||
if (!overrideProgram) this.program.bind();
|
||||
else overrideProgram.bind();
|
||||
|
||||
this.currentRenderTarget = (renderTarget || null);
|
||||
this.currentProgram = (program || this.program);
|
||||
this.currentProgram.bind();
|
||||
this.vertexBuffer.bind();
|
||||
|
||||
if (this.currentRenderTarget !== null)
|
||||
{
|
||||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, this.currentRenderTarget.framebufferObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
|
||||
}
|
||||
|
||||
this.onBeginPass.call(this.onBeginPassTarget, this);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -124,24 +91,6 @@ var Pipeline = new Class({
|
|||
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.onFlush.call(this.onFlushTarget, this);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
endPass: function ()
|
||||
{
|
||||
var renderTarget = this.currentRenderTarget;
|
||||
var program = this.currentProgram;
|
||||
|
||||
this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, null);
|
||||
|
||||
this.currentRenderTarget = null;
|
||||
this.currentProgram = null;
|
||||
this.vertexCount = 0;
|
||||
|
||||
this.onEndPass.call(this.onEndPassTarget, this);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -155,6 +104,72 @@ var Pipeline = new Class({
|
|||
this.program = null;
|
||||
this.vertexBuffer = null;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1f(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2f(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3f(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setFloat4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4f(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt1: function (name, x)
|
||||
{
|
||||
this.gl.uniform1i(this.gl.getUniformLocation(this.program.program, name), x);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt2: function (name, x, y)
|
||||
{
|
||||
this.gl.uniform2i(this.gl.getUniformLocation(this.program.program, name), x, y);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt3: function (name, x, y, z)
|
||||
{
|
||||
this.gl.uniform3i(this.gl.getUniformLocation(this.program.program, name), x, y, z);
|
||||
return this;
|
||||
},
|
||||
|
||||
setInt4: function (name, x, y, z, w)
|
||||
{
|
||||
this.gl.uniform4i(this.gl.getUniformLocation(this.program.program, name), x, y, z, w);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix2: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix3: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
},
|
||||
|
||||
setMatrix4: function (name, transpose, matrix)
|
||||
{
|
||||
this.gl.uniformMatrix2fv(this.gl.getUniformLocation(this.program.program, name), transpose, matrix);
|
||||
return this;
|
||||
}
|
||||
|
680
src/renderer/webgl/old/WebGLRenderer.js
Normal file
680
src/renderer/webgl/old/WebGLRenderer.js
Normal file
|
@ -0,0 +1,680 @@
|
|||
/**
|
||||
* @author Richard Davey (@photonstorm)
|
||||
* @author Felipe Alfonso (@bitnenfer)
|
||||
* @copyright 2017 Photon Storm Ltd.
|
||||
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
|
||||
*/
|
||||
|
||||
var BlendModes = require('../BlendModes');
|
||||
var BlitterBatch = require('./pipelines/blitterbatch/BlitterBatch');
|
||||
var Class = require('../../utils/Class');
|
||||
var CONST = require('../../const');
|
||||
var EffectRenderer = require('./pipelines/effectrenderer/EffectRenderer');
|
||||
var IsSizePowerOfTwo = require('../../math/pow2/IsSizePowerOfTwo');
|
||||
var MaskRenderer = require('./pipelines/maskrenderer/MaskRenderer');
|
||||
var QuadBatch = require('./pipelines/quadbatch/QuadBatch');
|
||||
var ParticleRenderer = require('./pipelines/particlerenderer/ParticleRenderer');
|
||||
var ResourceManager = require('./ResourceManager');
|
||||
var Resources = require('./resources');
|
||||
var ScaleModes = require('../ScaleModes');
|
||||
var ShapeBatch = require('./pipelines/shapebatch/ShapeBatch');
|
||||
var SpriteRenderer = require('./pipelines/spriterenderer/SpriteRenderer');
|
||||
var TileBatch = require('./pipelines/tilebatch/TileBatch');
|
||||
var TilemapRenderer = require('./pipelines/tilemaprenderer/TilemapRenderer');
|
||||
var WebGLSnapshot = require('../snapshot/WebGLSnapshot');
|
||||
|
||||
var WebGLpipeline = new Class({
|
||||
|
||||
initialize:
|
||||
|
||||
function WebGLpipeline (game)
|
||||
{
|
||||
var _this = this;
|
||||
this.game = game;
|
||||
this.onContextLostCallbacks = [];
|
||||
this.onContextRestoredCallbacks = [];
|
||||
this.type = CONST.WEBGL;
|
||||
this.width = game.config.width * game.config.resolution;
|
||||
this.height = game.config.height * game.config.resolution;
|
||||
this.resolution = game.config.resolution;
|
||||
this.view = game.canvas;
|
||||
this.view.addEventListener('webglcontextlost', function (evt) {
|
||||
var callbacks = _this.onContextLostCallbacks;
|
||||
var pipelines = _this.pipelines;
|
||||
for (var index = 0; index < pipelines.length; ++index)
|
||||
{
|
||||
pipelines[index].destroy();
|
||||
}
|
||||
_this.contextLost = true;
|
||||
for (var index = 0; index < callbacks.length; ++index)
|
||||
{
|
||||
callbacks[index](_this);
|
||||
}
|
||||
evt.preventDefault();
|
||||
}, false);
|
||||
|
||||
this.view.addEventListener('webglcontextrestored', function (evt) {
|
||||
var callbacks = _this.onContextRestoredCallbacks;
|
||||
_this.pipelines.length = 0;
|
||||
_this.resourceManager.shaderCache = {};
|
||||
_this.resourceManager.shaderCount = 0;
|
||||
_this.contextLost = false;
|
||||
_this.init();
|
||||
_this.game.textures.each(function (texture) {
|
||||
for (var i = 0; i < texture.source.length; ++i)
|
||||
{
|
||||
texture.source[i].init(_this.game);
|
||||
}
|
||||
}, null);
|
||||
for (var index = 0; index < callbacks.length; ++index)
|
||||
{
|
||||
callbacks[index](_this);
|
||||
}
|
||||
}, false);
|
||||
|
||||
// All of these settings will be able to be controlled via the Game Config
|
||||
this.config = {
|
||||
clearBeforeRender: true,
|
||||
transparent: false,
|
||||
autoResize: false,
|
||||
preserveDrawingBuffer: false,
|
||||
|
||||
WebGLContextOptions: {
|
||||
alpha: true,
|
||||
antialias: true,
|
||||
premultipliedAlpha: true,
|
||||
stencil: true,
|
||||
preserveDrawingBuffer: false
|
||||
}
|
||||
};
|
||||
|
||||
this.contextLost = false;
|
||||
this.maxTextures = 1;
|
||||
this.multiTexture = false;
|
||||
this.blendModes = [];
|
||||
this.gl = null;
|
||||
this.extensions = null;
|
||||
this.extensionList = {};
|
||||
this.pipelines = [];
|
||||
this.blitterBatch = null;
|
||||
this.aaQuadBatch = null;
|
||||
this.spriteBatch = null;
|
||||
this.shapeBatch = null;
|
||||
this.EffectRenderer = null;
|
||||
this.MaskRenderer = null;
|
||||
this.currentPipeline = null;
|
||||
this.currentTexture = [];
|
||||
this.shaderCache = {};
|
||||
this.currentShader = null;
|
||||
this.resourceManager = null;
|
||||
this.currentRenderTarget = null;
|
||||
this.snapshotCallback = null;
|
||||
this.snapshotType = null;
|
||||
this.snapshotEncoder = null;
|
||||
|
||||
this.scissor = {
|
||||
enabled: false,
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: 0,
|
||||
height: 0
|
||||
};
|
||||
|
||||
this.init();
|
||||
},
|
||||
|
||||
init: function ()
|
||||
{
|
||||
this.gl = this.view.getContext('webgl', this.config.WebGLContextOptions) || this.view.getContext('experimental-webgl', this.config.WebGLContextOptions);
|
||||
|
||||
if (!this.gl)
|
||||
{
|
||||
this.contextLost = true;
|
||||
throw new Error('This browser does not support WebGL. Try using the Canvas pipeline.');
|
||||
}
|
||||
var gl = this.gl;
|
||||
|
||||
this.lostContext = this.getExtension('WEBGL_lose_context');
|
||||
|
||||
var color = this.game.config.backgroundColor;
|
||||
|
||||
this.resourceManager = new ResourceManager(gl);
|
||||
|
||||
gl.disable(gl.DEPTH_TEST);
|
||||
gl.disable(gl.CULL_FACE);
|
||||
gl.enable(gl.BLEND);
|
||||
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
|
||||
|
||||
// Map Blend Modes
|
||||
this.blendModes = [];
|
||||
|
||||
for (var i = 0; i <= 16; i++)
|
||||
{
|
||||
this.blendModes.push({ func: [ gl.ONE, gl.ONE_MINUS_SRC_ALPHA ], equation: gl.FUNC_ADD });
|
||||
}
|
||||
|
||||
// Add
|
||||
this.blendModes[1].func = [ gl.ONE, gl.DST_ALPHA ];
|
||||
|
||||
// Multiply
|
||||
this.blendModes[2].func = [ gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA ];
|
||||
|
||||
// Screen
|
||||
this.blendModes[3].func = [ gl.ONE, gl.ONE_MINUS_SRC_COLOR ];
|
||||
|
||||
this.blendMode = -1;
|
||||
this.extensions = gl.getSupportedExtensions();
|
||||
this.blitterBatch = this.addPipeline(new BlitterBatch(this.game, gl, this));
|
||||
//this.quadBatch = this.addPipeline(new QuadBatch(this.game, gl, this));
|
||||
this.spriteRenderer = this.addPipeline(new SpriteRenderer(this.game, gl, this));
|
||||
//this.shapeBatch = this.addPipeline(new ShapeBatch(this.game, gl, this));
|
||||
//this.EffectRenderer = this.addPipeline(new EffectRenderer(this.game, gl, this));
|
||||
//this.tileBatch = this.addPipeline(new TileBatch(this.game, gl, this));
|
||||
//this.TilemapRenderer = this.addPipeline(new TilemapRenderer(this.game, gl, this));
|
||||
//this.ParticleRenderer = this.addPipeline(new ParticleRenderer(this.game, gl, this));
|
||||
//this.MaskRenderer = this.addPipeline(new MaskRenderer(this.game, gl, this));
|
||||
this.currentPipeline = this.spriteRenderer;
|
||||
this.currentVertexBuffer = null;
|
||||
this.setBlendMode(0);
|
||||
this.resize(this.width, this.height);
|
||||
},
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFunc
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendFuncSeparate
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendEquation
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendEquationSeparate
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/blendColor
|
||||
addBlendMode: function (func, equation)
|
||||
{
|
||||
var index = this.blendModes.push({ func: func, equation: equation });
|
||||
|
||||
return index - 1;
|
||||
},
|
||||
|
||||
updateBlendMode: function (index, func, equation)
|
||||
{
|
||||
if (this.blendModes[index])
|
||||
{
|
||||
this.blendModes[index].func = func;
|
||||
|
||||
if (equation)
|
||||
{
|
||||
this.blendModes[index].equation = equation;
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
removeBlendMode: function (index)
|
||||
{
|
||||
if (index > 16 && this.blendModes[index])
|
||||
{
|
||||
this.blendModes.splice(index, 1);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
getExtension: function (name)
|
||||
{
|
||||
if (!(name in this.extensionList))
|
||||
{
|
||||
this.extensionList[name] = this.gl.getExtension(name);
|
||||
}
|
||||
return this.extensionList[name];
|
||||
},
|
||||
|
||||
addContextLostCallback: function (callback)
|
||||
{
|
||||
if (this.onContextLostCallbacks.indexOf(callback) === -1)
|
||||
{
|
||||
this.onContextLostCallbacks.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
addContextRestoredCallback: function (callback)
|
||||
{
|
||||
if (this.onContextRestoredCallbacks.indexOf(callback) === -1)
|
||||
{
|
||||
this.onContextRestoredCallbacks.push(callback);
|
||||
}
|
||||
},
|
||||
|
||||
createTexture: function (source, width, height)
|
||||
{
|
||||
width = source ? source.width : width;
|
||||
height = source ? source.height : height;
|
||||
|
||||
var gl = this.gl;
|
||||
var filter = gl.NEAREST;
|
||||
var wrap = IsSizePowerOfTwo(width, height) ? gl.REPEAT : gl.CLAMP_TO_EDGE;
|
||||
|
||||
if (!source.glTexture)
|
||||
{
|
||||
if (source.scaleMode === ScaleModes.LINEAR)
|
||||
{
|
||||
filter = gl.LINEAR;
|
||||
}
|
||||
else if (source.scaleMode === ScaleModes.NEAREST || this.game.config.pixelArt)
|
||||
{
|
||||
filter = gl.NEAREST;
|
||||
}
|
||||
|
||||
if (!source && typeof width === 'number' && typeof height === 'number')
|
||||
{
|
||||
source.glTexture = this.resourceManager.createTexture(
|
||||
0,
|
||||
filter,
|
||||
filter,
|
||||
wrap,
|
||||
wrap,
|
||||
gl.RGBA,
|
||||
null,
|
||||
width, height
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
source.glTexture = this.resourceManager.createTexture(
|
||||
0,
|
||||
filter,
|
||||
filter,
|
||||
wrap,
|
||||
wrap,
|
||||
gl.RGBA,
|
||||
source.image
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.currentTexture[0] = null;
|
||||
},
|
||||
|
||||
setTexture: function (texture, unit)
|
||||
{
|
||||
unit = unit || 0;
|
||||
if (this.currentTexture[unit] !== texture)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + unit);
|
||||
|
||||
if (texture !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
this.currentTexture[unit] = texture;
|
||||
}
|
||||
},
|
||||
|
||||
setPipeline: function (pipeline)
|
||||
{
|
||||
if (this.currentPipeline !== pipeline ||
|
||||
this.currentPipeline.shouldFlush())
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
this.currentPipeline.endPass();
|
||||
this.currentPipeline = pipeline;
|
||||
}
|
||||
},
|
||||
|
||||
setRenderTarget: function (renderTarget)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (this.currentRenderTarget !== renderTarget)
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (renderTarget !== null)
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, renderTarget.framebufferObject);
|
||||
|
||||
if (renderTarget.shouldClear)
|
||||
{
|
||||
gl.clearColor(0, 0, 0, renderTarget.clearAlpha);
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
renderTarget.shouldClear = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
}
|
||||
|
||||
this.currentRenderTarget = renderTarget;
|
||||
}
|
||||
},
|
||||
|
||||
resize: function (width, height)
|
||||
{
|
||||
var resolution = this.game.config.resolution;
|
||||
|
||||
this.width = width * resolution;
|
||||
this.height = height * resolution;
|
||||
|
||||
this.view.width = this.width;
|
||||
this.view.height = this.height;
|
||||
|
||||
if (this.autoResize)
|
||||
{
|
||||
this.view.style.width = (this.width / resolution) + 'px';
|
||||
this.view.style.height = (this.height / resolution) + 'px';
|
||||
}
|
||||
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
for (var i = 0, l = this.pipelines.length; i < l; ++i)
|
||||
{
|
||||
//this.pipelines[i].bind();
|
||||
//this.pipelines[i].resize(width, height, resolution);
|
||||
}
|
||||
|
||||
//this.currentPipeline.bind();
|
||||
},
|
||||
|
||||
// Call at the start of the render loop
|
||||
preRender: function ()
|
||||
{
|
||||
// No point rendering if our context has been blown up!
|
||||
if (this.contextLost)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.setRenderTarget(null);
|
||||
// Add Pre-render hook
|
||||
|
||||
var gl = this.gl;
|
||||
var color = this.game.config.backgroundColor;
|
||||
|
||||
gl.clearColor(color.redGL, color.greenGL, color.blueGL, color.alphaGL);
|
||||
|
||||
// Some drivers require to call glClear
|
||||
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
|
||||
|
||||
this.setBlendMode(BlendModes.NORMAL);
|
||||
this.gl.viewport(0, 0, this.width, this.height);
|
||||
},
|
||||
|
||||
/**
|
||||
* Renders a single Scene.
|
||||
*
|
||||
* @method render
|
||||
* @param {Phaser.Scene} scene - The Scene to be rendered.
|
||||
* @param {number} interpolationPercentage - The cumulative amount of time that hasn't been simulated yet, divided
|
||||
* by the amount of time that will be simulated the next time update()
|
||||
* runs. Useful for interpolating frames.
|
||||
*/
|
||||
render: function (scene, children, interpolationPercentage, camera)
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
var gl = this.gl;
|
||||
var quadBatch = this.quadBatch;
|
||||
|
||||
this.scissor.enabled = (camera.x !== 0 || camera.y !== 0 || camera.width !== gl.canvas.width || camera.height !== gl.canvas.height);
|
||||
|
||||
this.setRenderTarget(null);
|
||||
|
||||
if (this.scissor.enabled)
|
||||
{
|
||||
gl.enable(gl.SCISSOR_TEST);
|
||||
|
||||
this.scissor.x = camera.x;
|
||||
this.scissor.y = gl.drawingBufferHeight - camera.y - camera.height;
|
||||
this.scissor.width = camera.width;
|
||||
this.scissor.height = camera.height;
|
||||
|
||||
gl.scissor(this.scissor.x, this.scissor.y, this.scissor.width, this.scissor.height);
|
||||
}
|
||||
|
||||
if (camera.backgroundColor.alphaGL > 0)
|
||||
{
|
||||
var color = camera.backgroundColor;
|
||||
|
||||
//quadBatch.bind();
|
||||
//quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// color.redGL, color.greenGL, color.blueGL, color.alphaGL
|
||||
//);
|
||||
//quadBatch.flush();
|
||||
//this.currentPipeline.bind();
|
||||
}
|
||||
|
||||
var list = children.list;
|
||||
var length = list.length;
|
||||
var pipeline;
|
||||
|
||||
for (var index = 0; index < length; ++index)
|
||||
{
|
||||
var child = list[index];
|
||||
|
||||
if (!child.willRender())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (child.blendMode !== this.blendMode)
|
||||
{
|
||||
this.setBlendMode(child.blendMode);
|
||||
}
|
||||
|
||||
if (child.mask)
|
||||
{
|
||||
child.mask.preRenderWebGL(this, child, camera);
|
||||
}
|
||||
|
||||
// drawing child
|
||||
child.renderWebGL(this, child, interpolationPercentage, camera);
|
||||
|
||||
if (child.mask)
|
||||
{
|
||||
child.mask.postRenderWebGL(this, child);
|
||||
}
|
||||
|
||||
pipeline = this.currentPipeline;
|
||||
|
||||
if (pipeline.shouldFlush())
|
||||
{
|
||||
pipeline.flush();
|
||||
}
|
||||
}
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (camera._fadeAlpha > 0 || camera._flashAlpha > 0)
|
||||
{
|
||||
this.setRenderTarget(null);
|
||||
this.setBlendMode(BlendModes.NORMAL);
|
||||
|
||||
// // fade rendering
|
||||
// quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// camera._fadeRed,
|
||||
// camera._fadeGreen,
|
||||
// camera._fadeBlue,
|
||||
// camera._fadeAlpha
|
||||
// );
|
||||
// // flash rendering
|
||||
// quadBatch.add(
|
||||
// camera.x, camera.y, camera.width, camera.height,
|
||||
// camera._flashRed,
|
||||
// camera._flashGreen,
|
||||
// camera._flashBlue,
|
||||
// camera._flashAlpha
|
||||
// );
|
||||
// quadBatch.flush();
|
||||
// this.currentPipeline.bind();
|
||||
}
|
||||
|
||||
if (this.scissor.enabled)
|
||||
{
|
||||
gl.disable(gl.SCISSOR_TEST);
|
||||
}
|
||||
},
|
||||
|
||||
// Called at the end of the render loop (tidy things up, etc)
|
||||
postRender: function ()
|
||||
{
|
||||
if (this.contextLost) return;
|
||||
|
||||
this.currentPipeline.flush();
|
||||
|
||||
if (this.snapshotCallback)
|
||||
{
|
||||
this.snapshotCallback(WebGLSnapshot(this.view, this.snapshotType, this.snapshotEncoder));
|
||||
this.snapshotCallback = null;
|
||||
}
|
||||
|
||||
// Add Post-render hook
|
||||
|
||||
// console.log('%c render end ', 'color: #ffffff; background: #ff0000;');
|
||||
},
|
||||
|
||||
snapshot: function (callback, type, encoderOptions)
|
||||
{
|
||||
this.snapshotCallback = callback;
|
||||
this.snapshotType = type;
|
||||
this.snapshotEncoder = encoderOptions;
|
||||
},
|
||||
|
||||
createFBO: function () {},
|
||||
|
||||
setBlendMode: function (newBlendMode)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (newBlendMode === BlendModes.SKIP_CHECK)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var pipeline = this.currentPipeline;
|
||||
|
||||
if (this.blendMode !== newBlendMode)
|
||||
{
|
||||
if (pipeline)
|
||||
{
|
||||
pipeline.flush();
|
||||
}
|
||||
|
||||
var blend = this.blendModes[newBlendMode].func;
|
||||
|
||||
gl.enable(gl.BLEND);
|
||||
gl.blendEquation(this.blendModes[newBlendMode].equation);
|
||||
|
||||
if (blend.length > 2)
|
||||
{
|
||||
gl.blendFuncSeparate(blend[0], blend[1], blend[2], blend[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.blendFunc(blend[0], blend[1]);
|
||||
}
|
||||
|
||||
this.blendMode = newBlendMode;
|
||||
}
|
||||
},
|
||||
|
||||
addPipeline: function (pipelineInstance)
|
||||
{
|
||||
var index = this.pipelines.indexOf(pipelineInstance);
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
this.pipelines.push(pipelineInstance);
|
||||
return pipelineInstance;
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
setTextureFilterMode: function (texture, filterMode)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var glFilter = [ gl.LINEAR, gl.NEAREST ][filterMode];
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
|
||||
|
||||
if (this.currentTexture[0] !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentTexture[0].texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, null);
|
||||
}
|
||||
|
||||
return texture;
|
||||
},
|
||||
|
||||
uploadCanvasToGPU: function (srcCanvas, dstTexture, shouldReallocate)
|
||||
{
|
||||
var gl = this.gl;
|
||||
|
||||
if (!dstTexture)
|
||||
{
|
||||
dstTexture = new Resources.Texture(null, 0, 0);
|
||||
|
||||
// Only call this once
|
||||
dstTexture.texture = gl.createTexture();
|
||||
}
|
||||
|
||||
if (dstTexture != this.currentTexture[0])
|
||||
{
|
||||
this.currentPipeline.flush();
|
||||
}
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
if (!shouldReallocate)
|
||||
{
|
||||
// Update resource
|
||||
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
|
||||
gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Allocate or Reallocate resource
|
||||
gl.bindTexture(gl.TEXTURE_2D, dstTexture.texture);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, srcCanvas);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||
dstTexture.width = srcCanvas.width;
|
||||
dstTexture.height = srcCanvas.height;
|
||||
}
|
||||
|
||||
// We must rebind old texture
|
||||
if (this.currentTexture.length > 0 && dstTexture != this.currentTexture[0] && this.currentTexture[0] !== null)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.currentTexture[0].texture);
|
||||
}
|
||||
|
||||
return dstTexture;
|
||||
},
|
||||
|
||||
destroy: function ()
|
||||
{
|
||||
if (this.lostContext)
|
||||
{
|
||||
this.lostContext.loseContext();
|
||||
}
|
||||
this.gl = null;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
module.exports = WebGLpipeline;
|
|
@ -290,7 +290,7 @@ var SpriteRenderer = new Class({
|
|||
orthoViewMatrix[0] = +2.0 / this.width;
|
||||
orthoViewMatrix[5] = -2.0 / this.height;
|
||||
|
||||
shader.setConstantMatrix4x4(shader.getUniformLocation('uOrthoMatrix'), orthoViewMatrix);
|
||||
this.setMatrix4('uOrthoMatrix', orthoViewMatrix);
|
||||
manager.setTexture(texture, 0);
|
||||
|
||||
vertexViewF32[0] = tx0;
|
Loading…
Reference in a new issue