mirror of
https://github.com/photonstorm/phaser
synced 2024-11-27 15:12:18 +00:00
Huge amount of work getting the WebGL renderer sorted out, tidied up and merged with the latest Texture and Transform components.
This commit is contained in:
parent
c39c97f9d8
commit
18b12dfc3e
12 changed files with 687 additions and 320 deletions
|
@ -32,8 +32,8 @@
|
|||
* @param {object} [uniforms] - Uniform mappings object. The uniforms are added on the default uniforms, or replace them if the keys are the same.
|
||||
* @param {Array|string} [fragmentSrc] - The fragment shader code. Either an array, one element per line of code, or a string.
|
||||
*/
|
||||
Phaser.Filter = function (game, uniforms, fragmentSrc) {
|
||||
|
||||
Phaser.Filter = function (game, uniforms, fragmentSrc)
|
||||
{
|
||||
/**
|
||||
* @property {Phaser.Game} game - A reference to the currently running game.
|
||||
*/
|
||||
|
@ -90,7 +90,7 @@ Phaser.Filter = function (game, uniforms, fragmentSrc) {
|
|||
resolution: { type: '2f', value: { x: 256, y: 256 }},
|
||||
time: { type: '1f', value: 0 },
|
||||
mouse: { type: '2f', value: { x: 0.0, y: 0.0 } },
|
||||
date: { type: '4fv', value: [ d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() *60 * 60 + d.getMinutes() * 60 + d.getSeconds() ] },
|
||||
date: { type: '4fv', value: [ d.getFullYear(), d.getMonth(), d.getDate(), d.getHours() * 60 * 60 + d.getMinutes() * 60 + d.getSeconds() ] },
|
||||
sampleRate: { type: '1f', value: 44100.0 },
|
||||
iChannel0: { type: 'sampler2D', value: null, textureData: { repeat: true } },
|
||||
iChannel1: { type: 'sampler2D', value: null, textureData: { repeat: true } },
|
||||
|
@ -125,10 +125,11 @@ Phaser.Filter.prototype = {
|
|||
|
||||
/**
|
||||
* This should be over-ridden. Will receive a variable number of arguments.
|
||||
*
|
||||
*
|
||||
* @method Phaser.Filter#init
|
||||
*/
|
||||
init: function () {
|
||||
init: function ()
|
||||
{
|
||||
|
||||
// This should be over-ridden. Will receive a variable number of arguments.
|
||||
|
||||
|
@ -141,21 +142,20 @@ Phaser.Filter.prototype = {
|
|||
* @param {number} width - The width of the display.
|
||||
* @param {number} height - The height of the display.
|
||||
*/
|
||||
setResolution: function (width, height) {
|
||||
|
||||
setResolution: function (width, height)
|
||||
{
|
||||
this.uniforms.resolution.value.x = width;
|
||||
this.uniforms.resolution.value.y = height;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the filter.
|
||||
*
|
||||
*
|
||||
* @method Phaser.Filter#update
|
||||
* @param {Phaser.Pointer} [pointer] - A Pointer object to use for the filter. The coordinates are mapped to the mouse uniform.
|
||||
*/
|
||||
update: function (pointer) {
|
||||
|
||||
update: function (pointer)
|
||||
{
|
||||
if (pointer)
|
||||
{
|
||||
var x = pointer.x / this.game.width;
|
||||
|
@ -170,11 +170,10 @@ Phaser.Filter.prototype = {
|
|||
}
|
||||
|
||||
this.uniforms.time.value = this.game.time.totalElapsedSeconds();
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new Phaser.Image object using a blank texture and assigns
|
||||
* Creates a new Phaser.Image object using a blank texture and assigns
|
||||
* this Filter to it. The image is then added to the world.
|
||||
*
|
||||
* If you don't provide width and height values then Filter.width and Filter.height are used.
|
||||
|
@ -191,8 +190,8 @@ Phaser.Filter.prototype = {
|
|||
* @param {number} [anchorY=0] - Set the y anchor point of the Image. A value between 0 and 1, where 0 is the top-left and 1 is bottom-right.
|
||||
* @return {Phaser.Image} The newly added Image object.
|
||||
*/
|
||||
addToWorld: function (x, y, width, height, anchorX, anchorY) {
|
||||
|
||||
addToWorld: function (x, y, width, height, anchorX, anchorY)
|
||||
{
|
||||
if (anchorX === undefined) { anchorX = 0; }
|
||||
if (anchorY === undefined) { anchorY = 0; }
|
||||
|
||||
|
@ -232,22 +231,21 @@ Phaser.Filter.prototype = {
|
|||
*
|
||||
* @method Phaser.Filter#syncUniforms
|
||||
*/
|
||||
syncUniforms: function () {
|
||||
|
||||
syncUniforms: function ()
|
||||
{
|
||||
for (var i = 0; i < this.shaders.length; i++)
|
||||
{
|
||||
this.shaders[i].dirty = true;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear down this Filter and null out references to game.
|
||||
*
|
||||
*
|
||||
* @method Phaser.Filter#destroy
|
||||
*/
|
||||
destroy: function () {
|
||||
|
||||
destroy: function ()
|
||||
{
|
||||
this.passes.length = 0;
|
||||
this.shaders.length = 0;
|
||||
this.fragmentSrc.length = 0;
|
||||
|
@ -255,7 +253,6 @@ Phaser.Filter.prototype = {
|
|||
this.game = null;
|
||||
this.uniforms = null;
|
||||
this.prevPoint = null;
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -6,14 +6,15 @@ Phaser.Renderer.WebGL.GameObjects.Image = {
|
|||
|
||||
render: function (renderer, src)
|
||||
{
|
||||
// If the sprite is not visible or the alpha is 0 then no need to render this element
|
||||
if (!src.visible || src.alpha === 0 || !src.renderable)
|
||||
var frame = src.frame;
|
||||
|
||||
// Skip rendering?
|
||||
|
||||
if (src.skipRender || !src.visible || src.worldAlpha <= 0 || !frame.cutWidth || !frame.cutHeight)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Add back in: || src.texture.crop.width <= 0 || src.texture.crop.height <= 0
|
||||
|
||||
renderer.spriteBatch.render(src);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,11 +11,19 @@ Phaser.Renderer.WebGL.GameObjects.Stage = {
|
|||
|
||||
render: function (renderer, src)
|
||||
{
|
||||
if (src.visible === false || src.alpha === 0 || src.children.length === 0)
|
||||
if (!src.visible || src.alpha === 0 || src.children.list.length === 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < src.children.list.length; i++)
|
||||
{
|
||||
var child = src.children.list[i];
|
||||
|
||||
child.render(renderer, child);
|
||||
}
|
||||
|
||||
/*
|
||||
var i;
|
||||
|
||||
if (src._mask || src._filters)
|
||||
|
@ -64,6 +72,7 @@ Phaser.Renderer.WebGL.GameObjects.Stage = {
|
|||
child.render(renderer, child);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -329,7 +329,7 @@ Phaser.Cache.prototype = {
|
|||
|
||||
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgAQMAAABJtOi3AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABVJREFUeF7NwIEAAAAAgKD9qdeocAMAoAABm3DkcAAAAABJRU5ErkJggg==';
|
||||
|
||||
this.game.textures.addImage('__DEFAULT', img);
|
||||
// this.game.textures.addImage('__DEFAULT', img);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -347,7 +347,7 @@ Phaser.Cache.prototype = {
|
|||
|
||||
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAIAAAD8GO2jAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAJ9JREFUeNq01ssOwyAMRFG46v//Mt1ESmgh+DFmE2GPOBARKb2NVjo+17PXLD8a1+pl5+A+wSgFygymWYHBb0FtsKhJDdZlncG2IzJ4ayoMDv20wTmSMzClEgbWYNTAkQ0Z+OJ+A/eWnAaR9+oxCF4Os0H8htsMUp+pwcgBBiMNnAwF8GqIgL2hAzaGFFgZauDPKABmowZ4GL369/0rwACp2yA/ttmvsQAAAABJRU5ErkJggg==';
|
||||
|
||||
this.game.textures.addImage('__MISSING', img);
|
||||
// this.game.textures.addImage('__MISSING', img);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -59,18 +59,144 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer)
|
|||
this.indices[i + 5] = j + 3;
|
||||
}
|
||||
|
||||
this.drawing = false;
|
||||
this.currentTextureSource = null;
|
||||
|
||||
// this.drawing = false;
|
||||
this.currentBatchSize = 0;
|
||||
this.currentBaseTexture = null;
|
||||
this.dirty = true;
|
||||
this.textures = [];
|
||||
this.blendModes = [];
|
||||
this.shaders = [];
|
||||
this.sprites = [];
|
||||
this.defaultShader = null;
|
||||
// this.defaultShader = null;
|
||||
|
||||
this.MAX_TEXTURES = 0;
|
||||
|
||||
// Let's Merge Sprite in here
|
||||
|
||||
/**
|
||||
* The WebGL program.
|
||||
* @property program
|
||||
* @type Any
|
||||
*/
|
||||
this.program = null;
|
||||
|
||||
/**
|
||||
* The Default Vertex shader source.
|
||||
*
|
||||
* @property defaultVertexSrc
|
||||
* @type String
|
||||
*/
|
||||
this.multivertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute vec4 aColor;',
|
||||
'attribute float aTextureIndex;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
|
||||
'const vec2 center = vec2(-1.0, 1.0);',
|
||||
|
||||
'void main(void) {',
|
||||
' if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
|
||||
' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
' vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
|
||||
' vTextureIndex = aTextureIndex;',
|
||||
'}'
|
||||
];
|
||||
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute vec4 aColor;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
|
||||
'const vec2 center = vec2(-1.0, 1.0);',
|
||||
|
||||
'void main(void) {',
|
||||
' gl_Position = vec4((aVertexPosition / projectionVector) + center, 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
' vec3 color = mod(vec3(aColor.y / 65536.0, aColor.y / 256.0, aColor.y), 256.0) / 256.0;',
|
||||
' vColor = vec4(color * aColor.x, aColor.x);',
|
||||
'}'
|
||||
];
|
||||
|
||||
/**
|
||||
* The fragment shader.
|
||||
* @property fragmentSrc
|
||||
* @type Array
|
||||
*/
|
||||
this.multifragmentSrc = [
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
];
|
||||
|
||||
this.fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
];
|
||||
|
||||
/**
|
||||
* Uniform attributes cache.
|
||||
* @property attributes
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
this.attributes = [];
|
||||
|
||||
/**
|
||||
* A local texture counter for multi-texture shaders.
|
||||
* @property textureCount
|
||||
* @type Number
|
||||
*/
|
||||
this.textureCount = 0;
|
||||
|
||||
// @type {WebGLUniformLocation }
|
||||
this.uSampler;
|
||||
|
||||
// @type {WebGLUniformLocation }
|
||||
this.projectionVector;
|
||||
|
||||
// @type {WebGLUniformLocation }
|
||||
this.offsetVector;
|
||||
|
||||
// @type {GLint}
|
||||
this.colorAttribute;
|
||||
|
||||
// @type {GLint}
|
||||
this.aTextureIndex;
|
||||
|
||||
// @type {GLint}
|
||||
this.aVertexPosition;
|
||||
|
||||
// @type {GLint}
|
||||
this.aTextureCoord;
|
||||
|
||||
// @type {WebGLUniformLocation }
|
||||
this.translationMatrix;
|
||||
|
||||
// @type {WebGLUniformLocation }
|
||||
this.alpha;
|
||||
};
|
||||
|
||||
Phaser.Renderer.WebGL.BatchManager.prototype.constructor = Phaser.Renderer.WebGL.BatchManager;
|
||||
|
@ -81,55 +207,56 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
{
|
||||
this.gl = this.renderer.gl;
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
this.MAX_TEXTURES = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
||||
|
||||
if (this.renderer.enableMultiTextureToggle)
|
||||
{
|
||||
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n'
|
||||
|
||||
for (var index = 1; index < this.MAX_TEXTURES; ++index)
|
||||
{
|
||||
dynamicIfs += '\telse if (vTextureIndex == ' +
|
||||
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
|
||||
index + '], vTextureCoord) * vColor;\n'
|
||||
}
|
||||
|
||||
this.defaultShader = new Phaser.Filter(
|
||||
this.renderer.game,
|
||||
undefined,
|
||||
[
|
||||
'//WebGLBatchManager Fragment Shader.',
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSamplerArray[' + this.MAX_TEXTURES + '];',
|
||||
'void main(void) {',
|
||||
dynamicIfs,
|
||||
'\telse gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;',
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.defaultShader = new Phaser.Filter(
|
||||
this.renderer.game,
|
||||
undefined,
|
||||
[
|
||||
'//WebGLBatchManager Fragment Shader.',
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
]);
|
||||
this.initMultitexShader();
|
||||
}
|
||||
|
||||
console.log('Compiled BatchManager Shader');
|
||||
|
||||
// console.log(this.vertexSrc.join('\n'));
|
||||
// console.log(this.fragmentSrc.join('\n'));
|
||||
// console.log('compiling ...');
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
// Set Shader
|
||||
gl.useProgram(program);
|
||||
|
||||
// Get and store the attributes
|
||||
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
|
||||
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
// this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
|
||||
|
||||
// Get and store the uniforms for the shader
|
||||
// this part is different for multi-textures
|
||||
this.uSampler = gl.getUniformLocation(program, 'uSampler');
|
||||
|
||||
// vertex position
|
||||
gl.enableVertexAttribArray(0);
|
||||
|
||||
// texture coordinate
|
||||
gl.enableVertexAttribArray(1);
|
||||
|
||||
// color attribute
|
||||
gl.enableVertexAttribArray(2);
|
||||
|
||||
// texture index
|
||||
// gl.enableVertexAttribArray(3);
|
||||
|
||||
// The projection vector (middle of the game world)
|
||||
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
|
||||
// this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
|
||||
|
||||
this.program = program;
|
||||
|
||||
// setAttribs can also call this (which handles the enable array calls above)
|
||||
// this.attributes = [ this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex ];
|
||||
this.attributes = [ this.aVertexPosition, this.aTextureCoord, this.colorAttribute ];
|
||||
|
||||
// Create a couple of buffers
|
||||
this.vertexBuffer = gl.createBuffer();
|
||||
this.indexBuffer = gl.createBuffer();
|
||||
|
@ -142,25 +269,73 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
|
||||
},
|
||||
|
||||
this.currentBlendMode = 99999;
|
||||
initMultiTextureShader: function ()
|
||||
{
|
||||
this.gl = this.renderer.gl;
|
||||
|
||||
var shader = new Phaser.Renderer.WebGL.Shaders.Sprite(this.renderer);
|
||||
// var gl = this.gl;
|
||||
|
||||
shader.fragmentSrc = this.defaultShader.fragmentSrc;
|
||||
shader.uniforms = {};
|
||||
shader.init();
|
||||
// New Fragment Source ...
|
||||
|
||||
this.defaultShader.shaders = shader;
|
||||
/*
|
||||
if (this.renderer.enableMultiTextureToggle)
|
||||
{
|
||||
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n';
|
||||
|
||||
for (var index = 1; index < this.MAX_TEXTURES; ++index)
|
||||
{
|
||||
dynamicIfs += '\telse if (vTextureIndex == ' +
|
||||
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
|
||||
index + '], vTextureCoord) * vColor;\n';
|
||||
}
|
||||
|
||||
// Does this need the vTextureIndex varying? Doesn't look like it
|
||||
|
||||
this.defaultShader = new Phaser.Filter(
|
||||
this.renderer.game,
|
||||
undefined,
|
||||
[
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSamplerArray[' + this.MAX_TEXTURES + '];',
|
||||
'void main(void) {',
|
||||
dynamicIfs,
|
||||
'\telse gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;',
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Does this need the vTextureIndex varying? Doesn't look like it
|
||||
|
||||
this.defaultShader = new Phaser.Filter(
|
||||
this.renderer.game,
|
||||
undefined,
|
||||
[
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
]);
|
||||
}
|
||||
*/
|
||||
},
|
||||
|
||||
begin: function ()
|
||||
{
|
||||
this.shader = this.renderer.shaderManager.defaultShader;
|
||||
this.start();
|
||||
},
|
||||
|
||||
start: function () {
|
||||
start: function ()
|
||||
{
|
||||
this.dirty = true;
|
||||
},
|
||||
|
||||
|
@ -169,55 +344,63 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
this.flush();
|
||||
},
|
||||
|
||||
stop: function () {
|
||||
stop: function ()
|
||||
{
|
||||
this.flush();
|
||||
this.dirty = true;
|
||||
},
|
||||
|
||||
render: function (sprite)
|
||||
render: function (src)
|
||||
{
|
||||
var texture = sprite.texture;
|
||||
var baseTexture = texture.baseTexture;
|
||||
var gl = this.gl;
|
||||
var frame = src.frame;
|
||||
var source = frame.source;
|
||||
|
||||
if (this.renderer.textureArray[baseTexture.textureIndex] !== baseTexture)
|
||||
// Check TextureSource
|
||||
if (this.currentTextureSource !== source)
|
||||
// if (this.renderer.textureArray[source.glTextureIndex] !== source)
|
||||
{
|
||||
this.flush();
|
||||
gl.activeTexture(gl.TEXTURE0 + baseTexture.textureIndex);
|
||||
gl.bindTexture(gl.TEXTURE_2D, baseTexture._glTextures);
|
||||
this.renderer.textureArray[baseTexture.textureIndex] = baseTexture;
|
||||
if (this.currentBatchSize > 0)
|
||||
{
|
||||
this.flush();
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
// gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
|
||||
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
|
||||
|
||||
// this.renderer.textureArray[source.glTextureIndex] = source;
|
||||
this.currentTextureSource = source;
|
||||
}
|
||||
|
||||
// check texture..
|
||||
// Check Batch Size
|
||||
if (this.currentBatchSize >= this.size)
|
||||
{
|
||||
this.flush();
|
||||
this.currentBaseTexture = texture.baseTexture;
|
||||
this.currentTextureSource = source;
|
||||
}
|
||||
|
||||
// get the uvs for the texture
|
||||
var uvs = texture._uvs;
|
||||
// MOVE ALL OF THIS INTO THE SPRITE / IMAGE WEBGL CLASSES? and just expose 'addVerts' here instead
|
||||
|
||||
// if the uvs have not updated then no point rendering just yet!
|
||||
if (!uvs)
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Get the Texture UVs
|
||||
var uvs = frame.uvs;
|
||||
|
||||
var aX = sprite.anchor.x;
|
||||
var aY = sprite.anchor.y;
|
||||
var aX = src.anchorX;
|
||||
var aY = src.anchorY;
|
||||
|
||||
var w0, w1, h0, h1;
|
||||
|
||||
/*
|
||||
if (texture.trim)
|
||||
{
|
||||
// if the sprite is trimmed then we need to add the extra space before transforming the sprite coords.
|
||||
// If the sprite is trimmed, add the extra space before transforming
|
||||
var trim = texture.trim;
|
||||
|
||||
w1 = trim.x - aX * trim.width;
|
||||
w1 = trim.x - (aX * trim.width);
|
||||
w0 = w1 + texture.crop.width;
|
||||
|
||||
h1 = trim.y - aY * trim.height;
|
||||
h1 = trim.y - (aY * trim.height);
|
||||
h0 = h1 + texture.crop.height;
|
||||
}
|
||||
else
|
||||
|
@ -228,13 +411,20 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
h0 = texture.frame.height * (1 - aY);
|
||||
h1 = texture.frame.height * -aY;
|
||||
}
|
||||
*/
|
||||
|
||||
var i = this.currentBatchSize * this.vertexSize; //4 * this.vertSize;
|
||||
var tiOffset = this.currentBatchSize * 4;
|
||||
var resolution = texture.baseTexture.resolution;
|
||||
var textureIndex = texture.baseTexture.textureIndex;
|
||||
w0 = (frame.width) * (1 - aX);
|
||||
w1 = (frame.width) * -aX;
|
||||
|
||||
var wt = sprite.worldTransform;
|
||||
h0 = frame.height * (1 - aY);
|
||||
h1 = frame.height * -aY;
|
||||
|
||||
var i = this.currentBatchSize * this.vertexSize;
|
||||
|
||||
var resolution = source.resolution;
|
||||
var textureIndex = source.textureIndex;
|
||||
|
||||
var wt = src.transform.world;
|
||||
|
||||
var a = wt.a / resolution;
|
||||
var b = wt.b / resolution;
|
||||
|
@ -243,9 +433,10 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
var tx = wt.tx;
|
||||
var ty = wt.ty;
|
||||
|
||||
var cw = texture.crop.width;
|
||||
var ch = texture.crop.height;
|
||||
// var cw = frame.cutWidth;
|
||||
// var ch = frame.cutHeight;
|
||||
|
||||
/*
|
||||
if (texture.rotated)
|
||||
{
|
||||
var a0 = wt.a;
|
||||
|
@ -273,13 +464,17 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
w0 = h0;
|
||||
w1 = h1;
|
||||
h0 = _w0;
|
||||
h1 = _w1;
|
||||
h1 = _w1;
|
||||
}
|
||||
*/
|
||||
|
||||
// These are just views into the same typed array
|
||||
var colors = this.colors;
|
||||
var positions = this.positions;
|
||||
var tint = sprite.tint;
|
||||
var color = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (sprite.worldAlpha * 255 << 24);
|
||||
|
||||
// var tint = sprite.tint;
|
||||
var tint = 0xffffff;
|
||||
var color = (tint >> 16) + (tint & 0xff00) + ((tint & 0xff) << 16) + (src.worldAlpha * 255 << 24);
|
||||
|
||||
if (this.renderer.roundPixels)
|
||||
{
|
||||
|
@ -287,6 +482,11 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
ty |= 0;
|
||||
}
|
||||
|
||||
// Interleaved vert and color data
|
||||
// The color passed here includes an applied tint *see bitwise ops above *
|
||||
// Better to calculate that in the shader?
|
||||
|
||||
// Top Left vert (xy, uv, color)
|
||||
positions[i++] = a * w1 + c * h1 + tx;
|
||||
positions[i++] = d * h1 + b * w1 + ty;
|
||||
positions[i++] = uvs.x0;
|
||||
|
@ -294,6 +494,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
colors[i++] = color;
|
||||
positions[i++] = textureIndex;
|
||||
|
||||
// Top Right vert (xy, uv, color)
|
||||
positions[i++] = a * w0 + c * h1 + tx;
|
||||
positions[i++] = d * h1 + b * w0 + ty;
|
||||
positions[i++] = uvs.x1;
|
||||
|
@ -301,6 +502,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
colors[i++] = color;
|
||||
positions[i++] = textureIndex;
|
||||
|
||||
// Bottom Right vert (xy, uv, color)
|
||||
positions[i++] = a * w0 + c * h0 + tx;
|
||||
positions[i++] = d * h0 + b * w0 + ty;
|
||||
positions[i++] = uvs.x2;
|
||||
|
@ -308,6 +510,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
colors[i++] = color;
|
||||
positions[i++] = textureIndex;
|
||||
|
||||
// Bottom Left vert (xy, uv, color)
|
||||
positions[i++] = a * w1 + c * h0 + tx;
|
||||
positions[i++] = d * h0 + b * w1 + ty;
|
||||
positions[i++] = uvs.x3;
|
||||
|
@ -315,10 +518,56 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
colors[i++] = color;
|
||||
positions[i++] = textureIndex;
|
||||
|
||||
// increment the batchsize
|
||||
this.sprites[this.currentBatchSize++] = sprite;
|
||||
this.sprites[this.currentBatchSize++] = src;
|
||||
},
|
||||
|
||||
/*
|
||||
addVerts: function (uvs, wt, w0, h0, w1, h1, alpha, tint)
|
||||
{
|
||||
var a = wt.a;
|
||||
var b = wt.b;
|
||||
var c = wt.c;
|
||||
var d = wt.d;
|
||||
var tx = wt.tx;
|
||||
var ty = wt.ty;
|
||||
|
||||
var verts = this.vertices;
|
||||
var i = this._size * 4 * this.vertSize;
|
||||
|
||||
// Top Left vert (xy, uv, color)
|
||||
verts[i++] = a * w1 + c * h1 + tx;
|
||||
verts[i++] = d * h1 + b * w1 + ty;
|
||||
verts[i++] = uvs.x0;
|
||||
verts[i++] = uvs.y0;
|
||||
verts[i++] = alpha;
|
||||
verts[i++] = tint[0];
|
||||
|
||||
// Top Right vert (xy, uv, color)
|
||||
verts[i++] = a * w0 + c * h1 + tx;
|
||||
verts[i++] = d * h1 + b * w0 + ty;
|
||||
verts[i++] = uvs.x1;
|
||||
verts[i++] = uvs.y1;
|
||||
verts[i++] = alpha;
|
||||
verts[i++] = tint[1];
|
||||
|
||||
// Bottom Right vert (xy, uv, color)
|
||||
verts[i++] = a * w0 + c * h0 + tx;
|
||||
verts[i++] = d * h0 + b * w0 + ty;
|
||||
verts[i++] = uvs.x2;
|
||||
verts[i++] = uvs.y2;
|
||||
verts[i++] = alpha;
|
||||
verts[i++] = tint[2];
|
||||
|
||||
// Bottom Left vert (xy, uv, color)
|
||||
verts[i++] = a * w1 + c * h0 + tx;
|
||||
verts[i++] = d * h0 + b * w1 + ty;
|
||||
verts[i++] = uvs.x3;
|
||||
verts[i++] = uvs.y3;
|
||||
verts[i++] = alpha;
|
||||
verts[i++] = tint[3];
|
||||
},
|
||||
*/
|
||||
|
||||
flush: function ()
|
||||
{
|
||||
// If the batch is length 0 then return as there is nothing to draw
|
||||
|
@ -328,33 +577,37 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
}
|
||||
|
||||
var gl = this.gl;
|
||||
var shader;
|
||||
|
||||
if (this.dirty)
|
||||
{
|
||||
// Always dirty the first pass through
|
||||
// but subsequent calls may be clean
|
||||
this.dirty = false;
|
||||
|
||||
shader = this.defaultShader.shaders;
|
||||
|
||||
// bind the main texture
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
// bind the buffers
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
|
||||
// this is the same for each shader?
|
||||
var stride = this.vertexSize; //this.vertSize * 4;
|
||||
gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
|
||||
gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, stride, 8);
|
||||
|
||||
// color attributes will be interpreted as unsigned bytes and normalized
|
||||
gl.vertexAttribPointer(shader.colorAttribute, 4, gl.UNSIGNED_BYTE, true, stride, 16);
|
||||
// set the projection vector (defaults to middle of game world on negative y)
|
||||
gl.uniform2f(this.projectionVector, this.renderer.projection.x, this.renderer.projection.y);
|
||||
|
||||
// Texture index
|
||||
gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20);
|
||||
// vertex position
|
||||
gl.vertexAttribPointer(this.aVertexPosition, 2, gl.FLOAT, false, this.stride, 0);
|
||||
|
||||
// texture coordinate
|
||||
gl.vertexAttribPointer(this.aTextureCoord, 2, gl.FLOAT, false, this.stride, 8);
|
||||
|
||||
// color attribute
|
||||
gl.vertexAttribPointer(this.colorAttribute, 2, gl.FLOAT, false, this.stride, 16);
|
||||
|
||||
// texture index
|
||||
// gl.vertexAttribPointer(this.aTextureIndex, 2, gl.FLOAT, false, this.stride, 20);
|
||||
}
|
||||
|
||||
// upload the verts to the buffer
|
||||
// Upload verts to the buffer
|
||||
if (this.currentBatchSize > (this.size * 0.5))
|
||||
{
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
|
||||
|
@ -362,109 +615,79 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
else
|
||||
{
|
||||
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
|
||||
|
||||
var view = this.positions.subarray(0, this.currentBatchSize * this.vertexSize);
|
||||
|
||||
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
|
||||
}
|
||||
|
||||
var nextTexture, nextBlendMode, nextShader;
|
||||
var batchSize = 0;
|
||||
var start = 0;
|
||||
|
||||
var currentBaseTexture = null;
|
||||
var currentBlendMode = this.renderer.currentBlendMode;
|
||||
var currentShader = null;
|
||||
|
||||
var blendSwap = false;
|
||||
var shaderSwap = false;
|
||||
var sprite;
|
||||
var textureIndex = 0;
|
||||
|
||||
for (var i = 0, j = this.currentBatchSize; i < j; i++)
|
||||
var start = 0;
|
||||
var currentSize = 0;
|
||||
|
||||
var nextSource = null;
|
||||
|
||||
var blend = 0;
|
||||
var nextBlend = null;
|
||||
|
||||
for (var i = 0; i < this.currentBatchSize; i++)
|
||||
{
|
||||
sprite = this.sprites[i];
|
||||
|
||||
if (sprite.tilingTexture)
|
||||
nextBlend = sprite.blendMode;
|
||||
|
||||
if (blend !== nextBlend)
|
||||
{
|
||||
nextTexture = sprite.tilingTexture.baseTexture;
|
||||
}
|
||||
else
|
||||
{
|
||||
nextTexture = sprite.texture.baseTexture;
|
||||
|
||||
// Unrolled for speed
|
||||
/*
|
||||
if (nextBlend === this.renderer.blendModes.NORMAL)
|
||||
{
|
||||
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else if (nextBlend === BlendModes.ADD)
|
||||
{
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
|
||||
}
|
||||
else if (nextBlend === BlendModes.MULTIPLY)
|
||||
{
|
||||
gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else if (nextBlend === BlendModes.SCREEN)
|
||||
{
|
||||
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
nextBlendMode = sprite.blendMode;
|
||||
nextShader = sprite.shader || this.defaultShader;
|
||||
nextSource = sprite.frame.source;
|
||||
|
||||
blendSwap = currentBlendMode !== nextBlendMode;
|
||||
shaderSwap = currentShader !== nextShader;
|
||||
|
||||
var skip = nextTexture.skipRender;
|
||||
|
||||
if (skip && sprite.children.length > 0)
|
||||
if (nextSource !== this.currentTextureSource)
|
||||
{
|
||||
skip = false;
|
||||
}
|
||||
|
||||
if (blendSwap || shaderSwap)
|
||||
{
|
||||
this.renderBatch(currentBaseTexture, batchSize, start);
|
||||
if (currentSize > 0)
|
||||
{
|
||||
this.renderBatch(this.currentTextureSource, currentSize, start);
|
||||
}
|
||||
|
||||
start = i;
|
||||
batchSize = 0;
|
||||
currentBaseTexture = nextTexture;
|
||||
|
||||
if (blendSwap)
|
||||
{
|
||||
currentBlendMode = nextBlendMode;
|
||||
this.renderer.setBlendMode(currentBlendMode);
|
||||
}
|
||||
|
||||
if (shaderSwap)
|
||||
{
|
||||
currentShader = nextShader;
|
||||
|
||||
shader = currentShader.shaders;
|
||||
|
||||
if (!shader)
|
||||
{
|
||||
shader = new PIXI.PixiShader(gl);
|
||||
|
||||
shader.fragmentSrc = currentShader.fragmentSrc;
|
||||
shader.uniforms = currentShader.uniforms;
|
||||
shader.init();
|
||||
|
||||
currentShader.shaders = shader;
|
||||
}
|
||||
|
||||
this.renderer.shaderManager.setShader(shader);
|
||||
|
||||
if (shader.dirty)
|
||||
{
|
||||
shader.syncUniforms();
|
||||
}
|
||||
|
||||
// both these only need to be set if they are changing..
|
||||
// set the projection
|
||||
var projection = this.renderer.projection;
|
||||
|
||||
gl.uniform2f(shader.projectionVector, projection.x, projection.y);
|
||||
|
||||
var offsetVector = this.renderer.offset;
|
||||
|
||||
gl.uniform2f(shader.offsetVector, offsetVector.x, offsetVector.y);
|
||||
}
|
||||
currentSize = 0;
|
||||
this.currentTextureSource = nextSource;
|
||||
}
|
||||
|
||||
batchSize++;
|
||||
currentSize++;
|
||||
}
|
||||
|
||||
this.renderBatch(currentBaseTexture, batchSize, start);
|
||||
if (currentSize > 0)
|
||||
{
|
||||
this.renderBatch(this.currentTextureSource, currentSize, start);
|
||||
}
|
||||
|
||||
// then reset the batch!
|
||||
// Reset the batch
|
||||
this.currentBatchSize = 0;
|
||||
},
|
||||
|
||||
renderBatch: function (texture, size, startIndex)
|
||||
renderBatch: function (source, size, startIndex)
|
||||
{
|
||||
if (size === 0)
|
||||
{
|
||||
|
@ -473,10 +696,9 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
|
||||
var gl = this.gl;
|
||||
|
||||
// check if a texture is dirty..
|
||||
if (texture._dirty)
|
||||
if (source.glDirty)
|
||||
{
|
||||
if (!this.renderer.updateTexture(texture))
|
||||
if (!this.renderer.updateTexture(source))
|
||||
{
|
||||
// If updateTexture returns false then we cannot render it, so bail out now
|
||||
return;
|
||||
|
@ -485,7 +707,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
|||
|
||||
gl.drawElements(gl.TRIANGLES, size * 6, gl.UNSIGNED_SHORT, startIndex * 6 * 2);
|
||||
|
||||
// increment the draw count
|
||||
this.renderer.drawCount++;
|
||||
},
|
||||
|
||||
|
|
|
@ -48,21 +48,23 @@ Phaser.Renderer.WebGL.ShaderManager.prototype = {
|
|||
|
||||
init: function ()
|
||||
{
|
||||
return;
|
||||
|
||||
this.gl = this.renderer.gl;
|
||||
|
||||
// this shader is used for the default sprite rendering
|
||||
// This shader is used for the batched rendering of Images and Sprites
|
||||
this.defaultShader = new Phaser.Renderer.WebGL.Shaders.Sprite(this.renderer);
|
||||
|
||||
// this shader is used for the fast sprite rendering
|
||||
// This shader is used for SpriteBatch Game Object rendering
|
||||
this.fastShader = new Phaser.Renderer.WebGL.Shaders.SpriteBatch(this.renderer);
|
||||
|
||||
// the next one is used for rendering triangle strips
|
||||
// Tiling Sprites / Strips
|
||||
this.stripShader = new Phaser.Renderer.WebGL.Shaders.Strip(this.renderer);
|
||||
|
||||
// the next one is used for rendering primitives
|
||||
// Simple Graphics (when vertices count is low)
|
||||
this.primitiveShader = new Phaser.Renderer.WebGL.Shaders.PrimitiveGraphics(this.renderer);
|
||||
|
||||
// the next one is used by the stencil buffer manager when Graphics.mode = 1
|
||||
// The next one is used by the stencil buffer manager when Graphics.mode = 1
|
||||
this.complexPrimitiveShader = new Phaser.Renderer.WebGL.Shaders.ComplexPrimitiveGraphics(this.renderer);
|
||||
|
||||
this.setShader(this.defaultShader);
|
||||
|
|
|
@ -155,13 +155,16 @@ Phaser.Renderer.WebGL = function (game)
|
|||
|
||||
this.gl = null;
|
||||
|
||||
this.textureArray = [];
|
||||
// Add a null entry to avoid an array look-up miss
|
||||
this.textureArray = [ null, null ];
|
||||
|
||||
this.blendModes = [];
|
||||
|
||||
this.drawCount = 0;
|
||||
this.flipY = 1;
|
||||
|
||||
this.contextLost = false;
|
||||
|
||||
this._fbErrors = {
|
||||
36054: 'Incomplete attachment',
|
||||
36055: 'Missing attachment',
|
||||
|
@ -186,6 +189,7 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
|
||||
if (!this.gl)
|
||||
{
|
||||
this.contextLost = true;
|
||||
throw new Error('This browser does not support WebGL. Try using the Canvas renderer.');
|
||||
}
|
||||
|
||||
|
@ -378,7 +382,7 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
*/
|
||||
render: function (stage)
|
||||
{
|
||||
// no point rendering if our context has been blown up!
|
||||
// No point rendering if our context has been blown up!
|
||||
if (this.contextLost)
|
||||
{
|
||||
return;
|
||||
|
@ -390,20 +394,39 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
|
||||
gl.viewport(0, 0, this.width, this.height);
|
||||
|
||||
// make sure we are bound to the main frame buffer
|
||||
// Make sure we are bound to the main frame buffer
|
||||
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
||||
|
||||
if (this.game.clearBeforeRender)
|
||||
// Transparent
|
||||
gl.clearColor(0, 0, 0, 0);
|
||||
|
||||
// Black
|
||||
// gl.clearColor(0, 0, 0, 1);
|
||||
// gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
|
||||
// Normal Blend Mode
|
||||
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
/*
|
||||
if (this.clearBeforeRender)
|
||||
{
|
||||
gl.clearColor(stage._bgColor.r, stage._bgColor.g, stage._bgColor.b, stage._bgColor.a);
|
||||
// gl.clearColor(stage._bgColor.r, stage._bgColor.g, stage._bgColor.b, stage._bgColor.a);
|
||||
gl.clearColor(0, 0.5, 0, 0);
|
||||
|
||||
gl.clear(gl.COLOR_BUFFER_BIT);
|
||||
}
|
||||
|
||||
this.offset.x = this.game.camera._shake.x;
|
||||
this.offset.y = this.game.camera._shake.y;
|
||||
// this.offset.x = this.game.camera._shake.x;
|
||||
// this.offset.y = this.game.camera._shake.y;
|
||||
|
||||
this.offset.x = 0;
|
||||
this.offset.y = 0;
|
||||
|
||||
this.setBlendMode(this.blendModes.NORMAL);
|
||||
*/
|
||||
|
||||
this.offset.x = 0;
|
||||
this.offset.y = 0;
|
||||
|
||||
// Reset draw count
|
||||
this.drawCount = 0;
|
||||
|
@ -443,57 +466,55 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
texture._dirty = false;
|
||||
},
|
||||
|
||||
updateTexture: function (texture)
|
||||
// Takes a TextureSource object
|
||||
updateTexture: function (source)
|
||||
{
|
||||
if (!texture.hasLoaded)
|
||||
if (source.compressionAlgorithm)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (texture.source.compressionAlgorithm)
|
||||
{
|
||||
return this.updateCompressedTexture(texture);
|
||||
return this.updateCompressedTexture(source);
|
||||
}
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
if (!texture._glTextures)
|
||||
if (!source.glTexture)
|
||||
{
|
||||
texture._glTextures = gl.createTexture();
|
||||
source.glTexture = gl.createTexture();
|
||||
}
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + texture.textureIndex);
|
||||
gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture._glTextures);
|
||||
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultipliedAlpha);
|
||||
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, source.premultipliedAlpha);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source);
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, source.image);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, source.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
|
||||
if (texture.mipmap && Phaser.Math.isPowerOfTwo(texture.width, texture.height))
|
||||
if (source.mipmap && source.isPowerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, source.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR_MIPMAP_LINEAR : gl.NEAREST_MIPMAP_NEAREST);
|
||||
gl.generateMipmap(gl.TEXTURE_2D);
|
||||
}
|
||||
else
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, source.scaleMode === Phaser.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
|
||||
}
|
||||
|
||||
if (!texture._powerOf2)
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
if (source.isPowerOf2)
|
||||
{
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
texture._dirty = false;
|
||||
source.glDirty = false;
|
||||
|
||||
console.log('updateTexture', source.glTexture);
|
||||
|
||||
return true;
|
||||
},
|
||||
|
@ -657,7 +678,9 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS))
|
||||
{
|
||||
console.log(gl.getProgramInfoLog(shaderProgram));
|
||||
console.log('Could not initialize shaders');
|
||||
console.log('Could not initialize shaders: Vertex & Fragment');
|
||||
console.log(vertexSrc.join('\n'));
|
||||
console.log(fragmentSrc.join('\n'));
|
||||
}
|
||||
|
||||
return shaderProgram;
|
||||
|
@ -685,7 +708,7 @@ Phaser.Renderer.WebGL.prototype = {
|
|||
var gl = this.gl;
|
||||
var framebuffer = gl.createFramebuffer();
|
||||
var depthStencilBuffer = gl.createRenderbuffer();
|
||||
var colorBuffer = null;
|
||||
var colorBuffer = null;
|
||||
var fbStatus = 0;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + textureUnit);
|
||||
|
|
|
@ -128,28 +128,66 @@ Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {
|
|||
else
|
||||
{
|
||||
this.initDefaultShader();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
initDefaultShader: function ()
|
||||
{
|
||||
if (this.fragmentSrc === null)
|
||||
{
|
||||
this.fragmentSrc = [
|
||||
'precision lowp float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
|
||||
'}'
|
||||
];
|
||||
// this.fragmentSrc = [
|
||||
// 'precision lowp float;',
|
||||
// 'varying vec2 vTextureCoord;',
|
||||
// 'varying vec4 vColor;',
|
||||
// 'varying float vTextureIndex;',
|
||||
// 'uniform sampler2D uSampler;',
|
||||
// 'void main(void) {',
|
||||
// ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
|
||||
// '}'
|
||||
// ];
|
||||
}
|
||||
|
||||
var fragmentSrc = [
|
||||
'precision mediump float;',
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'uniform sampler2D uSampler;',
|
||||
'void main(void) {',
|
||||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
];
|
||||
|
||||
var vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute vec4 aColor;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
|
||||
'const vec2 center = vec2(-1.0, 1.0);',
|
||||
|
||||
'void main(void) {',
|
||||
' gl_Position = vec4((aVertexPosition / projectionVector) + center, 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
' vec3 color = mod(vec3(aColor.y / 65536.0, aColor.y / 256.0, aColor.y), 256.0) / 256.0;',
|
||||
' vColor = vec4(color * aColor.x, aColor.x);',
|
||||
'}'
|
||||
];
|
||||
|
||||
|
||||
console.log('initDefaultShader');
|
||||
console.log(vertexSrc.join('\n'));
|
||||
console.log(fragmentSrc.join('\n'));
|
||||
console.log('compiling ...');
|
||||
|
||||
var gl = this.gl;
|
||||
|
||||
var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
var program = this.renderer.compileProgram(vertexSrc, fragmentSrc);
|
||||
|
||||
// var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
gl.useProgram(program);
|
||||
|
||||
|
@ -163,16 +201,20 @@ Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {
|
|||
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
|
||||
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
|
||||
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
|
||||
this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
|
||||
// this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
|
||||
|
||||
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];
|
||||
// this.attributes = [ this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex ];
|
||||
this.attributes = [ this.aVertexPosition, this.aTextureCoord, this.colorAttribute ];
|
||||
|
||||
// add those custom shaders!
|
||||
// Add those custom shaders!
|
||||
|
||||
/*
|
||||
for (var key in this.uniforms)
|
||||
{
|
||||
// get the uniform locations..
|
||||
this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
|
||||
}
|
||||
*/
|
||||
|
||||
this.initUniforms();
|
||||
|
||||
|
@ -256,6 +298,8 @@ Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {
|
|||
|
||||
initUniforms: function ()
|
||||
{
|
||||
console.log('initUniforms', this.uniforms);
|
||||
|
||||
this.textureCount = 1;
|
||||
var gl = this.gl;
|
||||
var uniform;
|
||||
|
@ -331,6 +375,8 @@ Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {
|
|||
*/
|
||||
initSampler2D: function (uniform)
|
||||
{
|
||||
console.log('initSampler2D');
|
||||
|
||||
if (!uniform.value || !uniform.value.baseTexture || !uniform.value.baseTexture.hasLoaded)
|
||||
{
|
||||
return;
|
||||
|
@ -406,6 +452,8 @@ Phaser.Renderer.WebGL.Shaders.Sprite.prototype = {
|
|||
*/
|
||||
syncUniforms: function ()
|
||||
{
|
||||
console.log('syncUniforms');
|
||||
|
||||
this.textureCount = 1;
|
||||
|
||||
var uniform;
|
||||
|
|
|
@ -91,13 +91,13 @@ Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype = {
|
|||
{
|
||||
if (this.renderer.enableMultiTextureToggle)
|
||||
{
|
||||
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n'
|
||||
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n';
|
||||
|
||||
for (var index = 1; index < this.renderer.getMaxTextureUnits(); ++index)
|
||||
{
|
||||
dynamicIfs += '\telse if (vTextureIndex == ' +
|
||||
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
|
||||
index + '], vTextureCoord) * vColor;\n'
|
||||
dynamicIfs += '\telse if (vTextureIndex == ' +
|
||||
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
|
||||
index + '], vTextureCoord) * vColor;\n';
|
||||
}
|
||||
|
||||
this.fragmentSrc = [
|
||||
|
@ -110,7 +110,7 @@ Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype = {
|
|||
'const vec4 GREEN = vec4(0.0, 1.0, 0.0, 1.0);',
|
||||
'void main(void) {',
|
||||
dynamicIfs,
|
||||
'else gl_FragColor = PINK;',
|
||||
'else gl_FragColor = PINK;',
|
||||
'}'
|
||||
];
|
||||
}
|
||||
|
@ -126,9 +126,37 @@ Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype = {
|
|||
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
|
||||
'}'
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
this.vertexSrc = [
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aTextureCoord;',
|
||||
'attribute vec4 aColor;',
|
||||
'attribute float aTextureIndex;',
|
||||
|
||||
'uniform vec2 projectionVector;',
|
||||
'uniform vec2 offsetVector;',
|
||||
|
||||
'varying vec2 vTextureCoord;',
|
||||
'varying vec4 vColor;',
|
||||
'varying float vTextureIndex;',
|
||||
|
||||
'const vec2 center = vec2(-1.0, 1.0);',
|
||||
|
||||
'void main(void) {',
|
||||
' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
' vTextureIndex = aTextureIndex;',
|
||||
' vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
|
||||
'}'
|
||||
];
|
||||
|
||||
// ' vec3 color = mod(vec3(aColor.y / 65536.0, aColor.y / 256.0, aColor.y), 256.0) / 256.0;',
|
||||
// ' vColor = vec4(color * aColor.x, aColor.x);',
|
||||
|
||||
|
||||
/*
|
||||
this.vertexSrc = [
|
||||
'attribute vec2 aVertexPosition;',
|
||||
'attribute vec2 aPositionCoord;',
|
||||
'attribute vec2 aScale;',
|
||||
|
@ -152,13 +180,14 @@ Phaser.Renderer.WebGL.Shaders.SpriteBatch.prototype = {
|
|||
' vec2 sv = aVertexPosition * aScale;',
|
||||
' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
|
||||
' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
|
||||
' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
|
||||
' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
|
||||
' v = (uMatrix * vec3(v + aPositionCoord , 1.0)).xy ;',
|
||||
' gl_Position = vec4((v / projectionVector) + center , 0.0, 1.0);',
|
||||
' vTextureCoord = aTextureCoord;',
|
||||
' vTextureIndex = aTextureIndex;',
|
||||
' vColor = aColor;',
|
||||
'}'
|
||||
];
|
||||
*/
|
||||
|
||||
var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
|
||||
|
||||
|
|
|
@ -142,6 +142,7 @@ Phaser.TextureFrame = function (texture, name, sourceIndex, x, y, width, height)
|
|||
}
|
||||
};
|
||||
|
||||
this.updateUVs();
|
||||
};
|
||||
|
||||
Phaser.TextureFrame.prototype.constructor = Phaser.TextureFrame;
|
||||
|
@ -171,6 +172,8 @@ Phaser.TextureFrame.prototype = {
|
|||
this.cutHeight = Phaser.Math.clamp(height, 0, this.data.cut.h - this.cutY);
|
||||
}
|
||||
|
||||
this.updateUVs();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -203,6 +206,8 @@ Phaser.TextureFrame.prototype = {
|
|||
this.width = destWidth;
|
||||
this.height = destHeight;
|
||||
|
||||
this.updateUVs();
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
|
@ -214,21 +219,21 @@ Phaser.TextureFrame.prototype = {
|
|||
*/
|
||||
updateUVs: function ()
|
||||
{
|
||||
var tw = this.texture.width;
|
||||
var th = this.texture.height;
|
||||
var tw = this.source.width;
|
||||
var th = this.source.height;
|
||||
var uvs = this.data.uvs;
|
||||
|
||||
uvs.x0 = this.x / tw;
|
||||
uvs.y0 = this.y / th;
|
||||
uvs.x0 = this.cutX / tw;
|
||||
uvs.y0 = this.cutY / th;
|
||||
|
||||
uvs.x1 = (this.x + this.width) / tw;
|
||||
uvs.y1 = this.y / th;
|
||||
uvs.x1 = (this.cutX + this.cutWidth) / tw;
|
||||
uvs.y1 = this.cutY / th;
|
||||
|
||||
uvs.x2 = (this.x + this.width) / tw;
|
||||
uvs.y2 = (this.y + this.height) / th;
|
||||
uvs.x2 = (this.cutX + this.cutWidth) / tw;
|
||||
uvs.y2 = (this.cutY + this.cutHeight) / th;
|
||||
|
||||
uvs.x3 = this.x / tw;
|
||||
uvs.y3 = (this.y + this.height) / th;
|
||||
uvs.x3 = this.cutX / tw;
|
||||
uvs.y3 = (this.cutY + this.cutHeight) / th;
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -241,8 +246,8 @@ Phaser.TextureFrame.prototype = {
|
|||
*/
|
||||
updateUVsInverted: function ()
|
||||
{
|
||||
var tw = this.texture.width;
|
||||
var th = this.texture.height;
|
||||
var tw = this.source.width;
|
||||
var th = this.source.height;
|
||||
var uvs = this.data.uvs;
|
||||
|
||||
uvs.x0 = this.x / tw;
|
||||
|
@ -328,6 +333,23 @@ Object.defineProperties(Phaser.TextureFrame.prototype, {
|
|||
return this.data.sourceSize.h;
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* UVs
|
||||
*
|
||||
* @name Phaser.TextureFrame#uvs
|
||||
* @property {Object} uvs
|
||||
*/
|
||||
uvs: {
|
||||
|
||||
enumerable: true,
|
||||
|
||||
get: function ()
|
||||
{
|
||||
return this.data.uvs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
|
|
@ -47,21 +47,11 @@ Phaser.Texture = function (manager, key, source)
|
|||
|
||||
this.frameTotal = 0;
|
||||
|
||||
this.dirty = true;
|
||||
|
||||
/**
|
||||
* @property _glTextures
|
||||
* @type Array
|
||||
* @private
|
||||
*/
|
||||
this.glTextures = null;
|
||||
|
||||
// Load the Sources
|
||||
for (var i = 0; i < source.length; i++)
|
||||
{
|
||||
this.source.push(new Phaser.TextureSource(this, source[i]));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
Phaser.Texture.prototype.constructor = Phaser.Texture;
|
||||
|
@ -81,10 +71,21 @@ Phaser.Texture.prototype = {
|
|||
|
||||
get: function (name)
|
||||
{
|
||||
if (name === undefined || name === null) { name = '__BASE'; }
|
||||
if (name === undefined || name === null || this.frameTotal === 1)
|
||||
{
|
||||
name = '__BASE';
|
||||
}
|
||||
|
||||
return this.frames[name];
|
||||
var frame = this.frames[name];
|
||||
|
||||
if (!frame)
|
||||
{
|
||||
console.warn('No Texture.frame found with name ' + name);
|
||||
}
|
||||
else
|
||||
{
|
||||
return frame;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -94,16 +95,18 @@ Phaser.Texture.prototype = {
|
|||
*/
|
||||
destroy: function ()
|
||||
{
|
||||
|
||||
// Need to iterate though the TextureSources, and unload each one
|
||||
// then clear out the frames
|
||||
|
||||
/*
|
||||
if (this.source)
|
||||
{
|
||||
Phaser.CanvasPool.removeByCanvas(this.source);
|
||||
}
|
||||
|
||||
this.source = null;
|
||||
|
||||
this.unloadFromGPU();
|
||||
|
||||
// TODO: Clear out the Frames
|
||||
*/
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -17,6 +17,8 @@ Phaser.TextureSource = function (texture, source)
|
|||
|
||||
this.image = source;
|
||||
|
||||
this.compressionAlgorithm = null;
|
||||
|
||||
/**
|
||||
* The Resolution of the texture.
|
||||
*
|
||||
|
@ -45,7 +47,7 @@ Phaser.TextureSource = function (texture, source)
|
|||
|
||||
/**
|
||||
* The scale mode to apply when scaling this texture
|
||||
*
|
||||
*
|
||||
* @property scaleMode
|
||||
* @type {Number}
|
||||
* @default Phaser.scaleModes.DEFAULT;
|
||||
|
@ -64,33 +66,43 @@ Phaser.TextureSource = function (texture, source)
|
|||
/**
|
||||
* Set this to true if a mipmap of this texture needs to be generated. This value needs to be set before the texture is used
|
||||
* Also the texture must be a power of two size to work
|
||||
*
|
||||
*
|
||||
* @property mipmap
|
||||
* @type {Boolean}
|
||||
*/
|
||||
this.mipmap = false;
|
||||
|
||||
/**
|
||||
* The multi texture batching index number.
|
||||
* @property textureIndex
|
||||
* @type Number
|
||||
*/
|
||||
this.textureIndex = 0;
|
||||
|
||||
/**
|
||||
* A BaseTexture can be set to skip the rendering phase in the WebGL Sprite Batch.
|
||||
*
|
||||
*
|
||||
* You may want to do this if you have a parent Sprite with no visible texture (i.e. uses the internal `__default` texture)
|
||||
* that has children that you do want to render, without causing a batch flush in the process.
|
||||
*
|
||||
*
|
||||
* @property renderable
|
||||
* @type Boolean
|
||||
*/
|
||||
this.renderable = false;
|
||||
this.renderable = true;
|
||||
|
||||
/**
|
||||
* @property isPowerOf2
|
||||
* @type boolean
|
||||
*/
|
||||
this.isPowerOf2 = Phaser.Math.isPowerOfTwo(this.width, this.height);
|
||||
|
||||
/**
|
||||
* @property glTexture
|
||||
*/
|
||||
this.glTexture = null;
|
||||
|
||||
/**
|
||||
* The multi texture batching index number.
|
||||
* @property glTextureIndex
|
||||
* @type Number
|
||||
*/
|
||||
this.glTextureIndex = 0;
|
||||
|
||||
/**
|
||||
* @property glDirty
|
||||
*/
|
||||
this.glDirty = true;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue