mirror of
https://github.com/photonstorm/phaser
synced 2024-11-24 05:33:35 +00:00
Fixed Multi Texture support in the new batch manager.
This commit is contained in:
parent
2af81bdfba
commit
4c6691863c
3 changed files with 133 additions and 111 deletions
|
@ -20,7 +20,7 @@ Phaser.Renderer.WebGL.GameObjects.Image = {
|
||||||
|
|
||||||
var uvs = frame.uvs;
|
var uvs = frame.uvs;
|
||||||
var verts = src.transform.glVertextData;
|
var verts = src.transform.glVertextData;
|
||||||
var index = src.glTextureIndex;
|
var index = src.frame.source.glTextureIndex;
|
||||||
var tint = src.color._glTint;
|
var tint = src.color._glTint;
|
||||||
var bg = src.color._glBg;
|
var bg = src.color._glBg;
|
||||||
|
|
||||||
|
|
|
@ -85,7 +85,6 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
|
||||||
|
|
||||||
'void main(void) {',
|
'void main(void) {',
|
||||||
' if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
|
' if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
|
||||||
// ' gl_Position = vec4((aVertexPosition / projectionVector) + center, 0.0, 1.0);',
|
|
||||||
' gl_Position = vec4(((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
|
' gl_Position = vec4(((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
|
||||||
' vTextureCoord = aTextureCoord;', // pass the texture coordinate to the fragment shader, the GPU will interpolate the points
|
' vTextureCoord = aTextureCoord;', // pass the texture coordinate to the fragment shader, the GPU will interpolate the points
|
||||||
' vTintColor = vec4(aTintColor.rgb * aTintColor.a, aTintColor.a);',
|
' vTintColor = vec4(aTintColor.rgb * aTintColor.a, aTintColor.a);',
|
||||||
|
@ -109,16 +108,15 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
|
||||||
|
|
||||||
'uniform sampler2D uSampler;', // our texture
|
'uniform sampler2D uSampler;', // our texture
|
||||||
|
|
||||||
'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
|
|
||||||
|
|
||||||
'void main(void) {',
|
'void main(void) {',
|
||||||
' vec4 pixel = texture2D(uSampler, vTextureCoord) * vTintColor;', // get the color from the texture
|
' vec4 pixel = texture2D(uSampler, vTextureCoord) * vTintColor;', // get the color from the texture
|
||||||
' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
|
' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
|
||||||
// ' if (pixel.a > 0.0) pixel = PINK;', // if texture alpha is zero, use the bg color
|
|
||||||
' gl_FragColor = pixel;',
|
' gl_FragColor = pixel;',
|
||||||
'}'
|
'}'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
this.multiTextureFragmentSrc = null;
|
||||||
|
|
||||||
// @type {GLint}
|
// @type {GLint}
|
||||||
this.aVertexPosition;
|
this.aVertexPosition;
|
||||||
|
|
||||||
|
@ -197,11 +195,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
this.indices[i + 5] = j + 3; // Bottom Left
|
this.indices[i + 5] = j + 3; // Bottom Left
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.renderer.enableMultiTextureToggle)
|
|
||||||
{
|
|
||||||
// this.initMultitexShader();
|
|
||||||
}
|
|
||||||
|
|
||||||
var gl = this.gl;
|
var gl = this.gl;
|
||||||
|
|
||||||
// Create indices buffer
|
// Create indices buffer
|
||||||
|
@ -222,8 +215,51 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
// Set the source of the buffer data (this.vertices array)
|
// Set the source of the buffer data (this.vertices array)
|
||||||
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
|
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
|
||||||
|
|
||||||
// initShader
|
var fragmentSrc = this.fragmentSrc;
|
||||||
var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
|
|
||||||
|
if (this.renderer.multiTexture && this.renderer.maxTextures > 1)
|
||||||
|
{
|
||||||
|
var multiFrag = [
|
||||||
|
'precision lowp float;',
|
||||||
|
|
||||||
|
'varying vec2 vTextureCoord;', // the texture coords passed in from the vertex shader
|
||||||
|
'varying vec4 vTintColor;', // the color value passed in from the vertex shader (texture color + alpha + tint)
|
||||||
|
'varying vec4 vBgColor;', // the bg color value passed in from the vertex shader
|
||||||
|
'varying float vTextureIndex;',
|
||||||
|
|
||||||
|
'uniform sampler2D uSamplerArray[' + this.renderer.maxTextures + '];',
|
||||||
|
|
||||||
|
'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
|
||||||
|
|
||||||
|
'void main(void) {',
|
||||||
|
|
||||||
|
' vec4 pixel;',
|
||||||
|
' if (vTextureIndex == 0.0) pixel = texture2D(uSamplerArray[0], vTextureCoord);'
|
||||||
|
];
|
||||||
|
|
||||||
|
for (i = 1; i < this.renderer.maxTextures; i++)
|
||||||
|
{
|
||||||
|
multiFrag.push(' else if (vTextureIndex == ' + i + '.0) pixel = texture2D(uSamplerArray[' + i + '], vTextureCoord);');
|
||||||
|
}
|
||||||
|
|
||||||
|
multiFrag = multiFrag.concat([
|
||||||
|
// ' else pixel = PINK;',
|
||||||
|
' pixel *= vTintColor;',
|
||||||
|
// ' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
|
||||||
|
' gl_FragColor = pixel;',
|
||||||
|
// ' gl_FragColor = PINK;',
|
||||||
|
'}'
|
||||||
|
]);
|
||||||
|
|
||||||
|
this.multiTextureFragmentSrc = multiFrag;
|
||||||
|
|
||||||
|
fragmentSrc = this.multiTextureFragmentSrc;
|
||||||
|
|
||||||
|
console.dir(this.multiTextureFragmentSrc);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compile the Shaders
|
||||||
|
var program = this.renderer.compileProgram(this.vertexSrc, fragmentSrc);
|
||||||
|
|
||||||
// Set Shader
|
// Set Shader
|
||||||
gl.useProgram(program);
|
gl.useProgram(program);
|
||||||
|
@ -248,7 +284,32 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
|
|
||||||
// Get and store the uniforms for the shader
|
// Get and store the uniforms for the shader
|
||||||
// this part is different for multi-textures
|
// this part is different for multi-textures
|
||||||
|
if (this.renderer.multiTexture)
|
||||||
|
{
|
||||||
|
// Bind empty multi-textures to avoid WebGL spam
|
||||||
|
var indices = [];
|
||||||
|
|
||||||
|
var tempTexture = this.renderer.createEmptyTexture(1, 1, 0);
|
||||||
|
|
||||||
|
for (i = 0; i < this.maxTextures; i++)
|
||||||
|
{
|
||||||
|
gl.activeTexture(gl.TEXTURE0 + i);
|
||||||
|
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, tempTexture);
|
||||||
|
|
||||||
|
indices.push(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.uSampler = gl.getUniformLocation(program, 'uSamplerArray[0]');
|
||||||
|
|
||||||
|
gl.activeTexture(gl.TEXTURE0);
|
||||||
|
|
||||||
|
gl.uniform1iv(this.uSamplerArray, indices);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
this.uSampler = gl.getUniformLocation(program, 'uSampler');
|
this.uSampler = gl.getUniformLocation(program, 'uSampler');
|
||||||
|
}
|
||||||
|
|
||||||
// The projection vector (middle of the game world)
|
// The projection vector (middle of the game world)
|
||||||
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
|
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
|
||||||
|
@ -259,64 +320,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
this.program = program;
|
this.program = program;
|
||||||
},
|
},
|
||||||
|
|
||||||
initMultiTextureShader: function ()
|
|
||||||
{
|
|
||||||
this.gl = this.renderer.gl;
|
|
||||||
|
|
||||||
// var gl = this.gl;
|
|
||||||
|
|
||||||
// New Fragment Source ...
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 ()
|
begin: function ()
|
||||||
{
|
{
|
||||||
this._i = 0;
|
this._i = 0;
|
||||||
|
@ -349,27 +352,47 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
|
|
||||||
setCurrentTexture: function (textureSource)
|
setCurrentTexture: function (textureSource)
|
||||||
{
|
{
|
||||||
if (this.currentTextureSource === textureSource)
|
var gl = this.gl;
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (this.renderer.textureArray[source.glTextureIndex] !== source)
|
if (this.renderer.multiTexture)
|
||||||
|
{
|
||||||
|
if (this.renderer.textureArray[textureSource.glTextureIndex] !== textureSource)
|
||||||
|
{
|
||||||
|
console.log('setCurrentTexture', this.currentBatchSize);
|
||||||
|
console.log(textureSource);
|
||||||
|
|
||||||
if (this.currentBatchSize > 0)
|
if (this.currentBatchSize > 0)
|
||||||
{
|
{
|
||||||
this.flush();
|
this.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
var gl = this.gl;
|
gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
|
||||||
|
|
||||||
|
console.log('activeTexture', gl.TEXTURE0 + textureSource.glTextureIndex);
|
||||||
|
|
||||||
|
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
|
||||||
|
|
||||||
|
this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (this.currentTextureSource === textureSource)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentBatchSize > 0)
|
||||||
|
{
|
||||||
|
this.flush();
|
||||||
|
}
|
||||||
|
|
||||||
// gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
|
|
||||||
gl.activeTexture(gl.TEXTURE0);
|
gl.activeTexture(gl.TEXTURE0);
|
||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
|
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
|
||||||
|
|
||||||
this.currentTextureSource = textureSource;
|
this.currentTextureSource = textureSource;
|
||||||
|
}
|
||||||
// this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Call 'addVert' x4 after calling this
|
// Call 'addVert' x4 after calling this
|
||||||
|
@ -424,10 +447,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set texture
|
// Set texture
|
||||||
if (this.currentTextureSource !== gameObject.frame.source)
|
|
||||||
{
|
|
||||||
this.setCurrentTexture(gameObject.frame.source);
|
this.setCurrentTexture(gameObject.frame.source);
|
||||||
}
|
|
||||||
|
|
||||||
// These are TypedArray Views into the vertices ArrayBuffer
|
// These are TypedArray Views into the vertices ArrayBuffer
|
||||||
var colors = this.colors;
|
var colors = this.colors;
|
||||||
|
@ -476,7 +496,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
this.list[this.currentBatchSize++] = gameObject;
|
this.list[this.currentBatchSize++] = gameObject;
|
||||||
},
|
},
|
||||||
|
|
||||||
prepShader: function ()
|
initShader: function ()
|
||||||
{
|
{
|
||||||
var gl = this.gl;
|
var gl = this.gl;
|
||||||
|
|
||||||
|
@ -525,7 +545,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
// Always dirty the first pass through but subsequent calls may be clean
|
// Always dirty the first pass through but subsequent calls may be clean
|
||||||
if (this.dirty)
|
if (this.dirty)
|
||||||
{
|
{
|
||||||
this.prepShader();
|
this.initShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
var gl = this.gl;
|
var gl = this.gl;
|
||||||
|
@ -559,7 +579,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
|
||||||
this.renderer.setBlendMode(sprite.blendMode);
|
this.renderer.setBlendMode(sprite.blendMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.currentTextureSource !== sprite.frame.source)
|
if (!this.renderer.multiTexture && this.currentTextureSource !== sprite.frame.source)
|
||||||
{
|
{
|
||||||
if (currentSize > 0)
|
if (currentSize > 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -86,9 +86,7 @@ Phaser.Renderer.WebGL = function (game)
|
||||||
*/
|
*/
|
||||||
this.stencilBufferLimit = 6;
|
this.stencilBufferLimit = 6;
|
||||||
|
|
||||||
// WebGL specific from here
|
this.multiTexture = true;
|
||||||
|
|
||||||
this.enableMultiTextureToggle = false;
|
|
||||||
|
|
||||||
this.extensions = {};
|
this.extensions = {};
|
||||||
|
|
||||||
|
@ -155,10 +153,10 @@ Phaser.Renderer.WebGL = function (game)
|
||||||
|
|
||||||
this.gl = null;
|
this.gl = null;
|
||||||
|
|
||||||
// Add a null entry to avoid an array look-up miss
|
this.textureArray = [];
|
||||||
this.textureArray = [ null, null ];
|
|
||||||
|
|
||||||
this.currentBlendMode = 0;
|
this.currentBlendMode = 0;
|
||||||
|
this.currentTextureSource = null;
|
||||||
|
|
||||||
this.blendModes = [];
|
this.blendModes = [];
|
||||||
|
|
||||||
|
@ -215,6 +213,13 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
|
|
||||||
this.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
this.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
||||||
|
|
||||||
|
console.log('maxTextures', this.maxTextures);
|
||||||
|
|
||||||
|
if (this.maxTextures === 1)
|
||||||
|
{
|
||||||
|
this.multiTexture = false;
|
||||||
|
}
|
||||||
|
|
||||||
gl.disable(gl.DEPTH_TEST);
|
gl.disable(gl.DEPTH_TEST);
|
||||||
gl.disable(gl.CULL_FACE);
|
gl.disable(gl.CULL_FACE);
|
||||||
gl.enable(gl.BLEND);
|
gl.enable(gl.BLEND);
|
||||||
|
@ -318,12 +323,6 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
*/
|
*/
|
||||||
setTexturePriority: function (textureNameCollection)
|
setTexturePriority: function (textureNameCollection)
|
||||||
{
|
{
|
||||||
if (!this.enableMultiTextureToggle)
|
|
||||||
{
|
|
||||||
console.warn('setTexturePriority error: Multi Texture support hasn\'t been enabled in the Phaser Game Config.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var maxTextures = this.maxTextures;
|
var maxTextures = this.maxTextures;
|
||||||
var imageCache = this.game.cache._cache.image;
|
var imageCache = this.game.cache._cache.image;
|
||||||
var imageName = null;
|
var imageName = null;
|
||||||
|
@ -409,8 +408,7 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
// gl.clearColor(0, 0, 0, 1);
|
// gl.clearColor(0, 0, 0, 1);
|
||||||
// gl.clear(gl.COLOR_BUFFER_BIT);
|
// gl.clear(gl.COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
// Normal Blend Mode
|
this.setBlendMode(this.blendModes.NORMAL);
|
||||||
this.setBlendMode(0);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (this.clearBeforeRender)
|
if (this.clearBeforeRender)
|
||||||
|
@ -476,6 +474,8 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
// Takes a TextureSource object
|
// Takes a TextureSource object
|
||||||
updateTexture: function (source)
|
updateTexture: function (source)
|
||||||
{
|
{
|
||||||
|
console.log('updateTexture', source);
|
||||||
|
|
||||||
if (source.compressionAlgorithm)
|
if (source.compressionAlgorithm)
|
||||||
{
|
{
|
||||||
return this.updateCompressedTexture(source);
|
return this.updateCompressedTexture(source);
|
||||||
|
@ -488,9 +488,7 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
source.glTexture = gl.createTexture();
|
source.glTexture = gl.createTexture();
|
||||||
}
|
}
|
||||||
|
|
||||||
// gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
|
gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
|
||||||
|
|
||||||
gl.activeTexture(gl.TEXTURE0);
|
|
||||||
|
|
||||||
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
|
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
|
||||||
|
|
||||||
|
@ -699,11 +697,15 @@ Phaser.Renderer.WebGL.prototype = {
|
||||||
|
|
||||||
createEmptyTexture: function (width, height, scaleMode)
|
createEmptyTexture: function (width, height, scaleMode)
|
||||||
{
|
{
|
||||||
|
console.log('createEmptyTexture');
|
||||||
|
|
||||||
var gl = this.gl;
|
var gl = this.gl;
|
||||||
var texture = gl.createTexture();
|
var texture = gl.createTexture();
|
||||||
var glScaleMode = (scaleMode === Phaser.scaleModes.LINEAR) ? gl.LINEAR : gl.NEAREST;
|
var glScaleMode = (scaleMode === Phaser.scaleModes.LINEAR) ? gl.LINEAR : gl.NEAREST;
|
||||||
|
|
||||||
|
gl.activeTexture(gl.TEXTURE0);
|
||||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||||
|
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
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);
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
||||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glScaleMode);
|
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glScaleMode);
|
||||||
|
|
Loading…
Reference in a new issue