Skip to content

Commit 4c66918

Browse files
committed
Fixed Multi Texture support in the new batch manager.
1 parent 2af81bd commit 4c66918

3 files changed

Lines changed: 126 additions & 104 deletions

File tree

src/gameobjects/image/ImageWebGLRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Phaser.Renderer.WebGL.GameObjects.Image = {
2020

2121
var uvs = frame.uvs;
2222
var verts = src.transform.glVertextData;
23-
var index = src.glTextureIndex;
23+
var index = src.frame.source.glTextureIndex;
2424
var tint = src.color._glTint;
2525
var bg = src.color._glBg;
2626

src/renderer/webgl/BatchManager.js

Lines changed: 107 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,6 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
8585

8686
'void main(void) {',
8787
' if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
88-
// ' gl_Position = vec4((aVertexPosition / projectionVector) + center, 0.0, 1.0);',
8988
' gl_Position = vec4(((aVertexPosition + offsetVector) / projectionVector) + center, 0.0, 1.0);',
9089
' vTextureCoord = aTextureCoord;', // pass the texture coordinate to the fragment shader, the GPU will interpolate the points
9190
' vTintColor = vec4(aTintColor.rgb * aTintColor.a, aTintColor.a);',
@@ -109,16 +108,15 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
109108

110109
'uniform sampler2D uSampler;', // our texture
111110

112-
'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
113-
114111
'void main(void) {',
115112
' vec4 pixel = texture2D(uSampler, vTextureCoord) * vTintColor;', // get the color from the texture
116113
' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
117-
// ' if (pixel.a > 0.0) pixel = PINK;', // if texture alpha is zero, use the bg color
118114
' gl_FragColor = pixel;',
119115
'}'
120116
];
121117

118+
this.multiTextureFragmentSrc = null;
119+
122120
// @type {GLint}
123121
this.aVertexPosition;
124122

@@ -197,11 +195,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
197195
this.indices[i + 5] = j + 3; // Bottom Left
198196
}
199197

200-
if (this.renderer.enableMultiTextureToggle)
201-
{
202-
// this.initMultitexShader();
203-
}
204-
205198
var gl = this.gl;
206199

207200
// Create indices buffer
@@ -222,8 +215,51 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
222215
// Set the source of the buffer data (this.vertices array)
223216
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
224217

225-
// initShader
226-
var program = this.renderer.compileProgram(this.vertexSrc, this.fragmentSrc);
218+
var fragmentSrc = this.fragmentSrc;
219+
220+
if (this.renderer.multiTexture && this.renderer.maxTextures > 1)
221+
{
222+
var multiFrag = [
223+
'precision lowp float;',
224+
225+
'varying vec2 vTextureCoord;', // the texture coords passed in from the vertex shader
226+
'varying vec4 vTintColor;', // the color value passed in from the vertex shader (texture color + alpha + tint)
227+
'varying vec4 vBgColor;', // the bg color value passed in from the vertex shader
228+
'varying float vTextureIndex;',
229+
230+
'uniform sampler2D uSamplerArray[' + this.renderer.maxTextures + '];',
231+
232+
'const vec4 PINK = vec4(1.0, 0.0, 1.0, 1.0);',
233+
234+
'void main(void) {',
235+
236+
' vec4 pixel;',
237+
' if (vTextureIndex == 0.0) pixel = texture2D(uSamplerArray[0], vTextureCoord);'
238+
];
239+
240+
for (i = 1; i < this.renderer.maxTextures; i++)
241+
{
242+
multiFrag.push(' else if (vTextureIndex == ' + i + '.0) pixel = texture2D(uSamplerArray[' + i + '], vTextureCoord);');
243+
}
244+
245+
multiFrag = multiFrag.concat([
246+
// ' else pixel = PINK;',
247+
' pixel *= vTintColor;',
248+
// ' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
249+
' gl_FragColor = pixel;',
250+
// ' gl_FragColor = PINK;',
251+
'}'
252+
]);
253+
254+
this.multiTextureFragmentSrc = multiFrag;
255+
256+
fragmentSrc = this.multiTextureFragmentSrc;
257+
258+
console.dir(this.multiTextureFragmentSrc);
259+
}
260+
261+
// Compile the Shaders
262+
var program = this.renderer.compileProgram(this.vertexSrc, fragmentSrc);
227263

228264
// Set Shader
229265
gl.useProgram(program);
@@ -248,73 +284,40 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
248284

249285
// Get and store the uniforms for the shader
250286
// this part is different for multi-textures
251-
this.uSampler = gl.getUniformLocation(program, 'uSampler');
252-
253-
// The projection vector (middle of the game world)
254-
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
255-
256-
// The offset vector
257-
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
287+
if (this.renderer.multiTexture)
288+
{
289+
// Bind empty multi-textures to avoid WebGL spam
290+
var indices = [];
258291

259-
this.program = program;
260-
},
292+
var tempTexture = this.renderer.createEmptyTexture(1, 1, 0);
261293

262-
initMultiTextureShader: function ()
263-
{
264-
this.gl = this.renderer.gl;
294+
for (i = 0; i < this.maxTextures; i++)
295+
{
296+
gl.activeTexture(gl.TEXTURE0 + i);
265297

266-
// var gl = this.gl;
298+
gl.bindTexture(gl.TEXTURE_2D, tempTexture);
267299

268-
// New Fragment Source ...
300+
indices.push(i);
301+
}
269302

270-
/*
271-
if (this.renderer.enableMultiTextureToggle)
272-
{
273-
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n';
303+
this.uSampler = gl.getUniformLocation(program, 'uSamplerArray[0]');
274304

275-
for (var index = 1; index < this.MAX_TEXTURES; ++index)
276-
{
277-
dynamicIfs += '\telse if (vTextureIndex == ' +
278-
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
279-
index + '], vTextureCoord) * vColor;\n';
280-
}
305+
gl.activeTexture(gl.TEXTURE0);
281306

282-
// Does this need the vTextureIndex varying? Doesn't look like it
283-
284-
this.defaultShader = new Phaser.Filter(
285-
this.renderer.game,
286-
undefined,
287-
[
288-
'precision lowp float;',
289-
'varying vec2 vTextureCoord;',
290-
'varying vec4 vColor;',
291-
'varying float vTextureIndex;',
292-
'uniform sampler2D uSamplerArray[' + this.MAX_TEXTURES + '];',
293-
'void main(void) {',
294-
dynamicIfs,
295-
'\telse gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;',
296-
'}'
297-
]);
307+
gl.uniform1iv(this.uSamplerArray, indices);
298308
}
299309
else
300310
{
301-
// Does this need the vTextureIndex varying? Doesn't look like it
302-
303-
this.defaultShader = new Phaser.Filter(
304-
this.renderer.game,
305-
undefined,
306-
[
307-
'precision lowp float;',
308-
'varying vec2 vTextureCoord;',
309-
'varying vec4 vColor;',
310-
'varying float vTextureIndex;',
311-
'uniform sampler2D uSampler;',
312-
'void main(void) {',
313-
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
314-
'}'
315-
]);
311+
this.uSampler = gl.getUniformLocation(program, 'uSampler');
316312
}
317-
*/
313+
314+
// The projection vector (middle of the game world)
315+
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
316+
317+
// The offset vector
318+
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
319+
320+
this.program = program;
318321
},
319322

320323
begin: function ()
@@ -349,27 +352,47 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
349352

350353
setCurrentTexture: function (textureSource)
351354
{
352-
if (this.currentTextureSource === textureSource)
355+
var gl = this.gl;
356+
357+
if (this.renderer.multiTexture)
353358
{
354-
return;
355-
}
359+
if (this.renderer.textureArray[textureSource.glTextureIndex] !== textureSource)
360+
{
361+
console.log('setCurrentTexture', this.currentBatchSize);
362+
console.log(textureSource);
356363

357-
// if (this.renderer.textureArray[source.glTextureIndex] !== source)
364+
if (this.currentBatchSize > 0)
365+
{
366+
this.flush();
367+
}
358368

359-
if (this.currentBatchSize > 0)
360-
{
361-
this.flush();
369+
gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
370+
371+
console.log('activeTexture', gl.TEXTURE0 + textureSource.glTextureIndex);
372+
373+
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
374+
375+
this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
376+
}
362377
}
378+
else
379+
{
380+
if (this.currentTextureSource === textureSource)
381+
{
382+
return;
383+
}
363384

364-
var gl = this.gl;
385+
if (this.currentBatchSize > 0)
386+
{
387+
this.flush();
388+
}
365389

366-
// gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
367-
gl.activeTexture(gl.TEXTURE0);
368-
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
390+
gl.activeTexture(gl.TEXTURE0);
369391

370-
this.currentTextureSource = textureSource;
392+
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
371393

372-
// this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
394+
this.currentTextureSource = textureSource;
395+
}
373396
},
374397

375398
// Call 'addVert' x4 after calling this
@@ -424,10 +447,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
424447
}
425448

426449
// Set texture
427-
if (this.currentTextureSource !== gameObject.frame.source)
428-
{
429-
this.setCurrentTexture(gameObject.frame.source);
430-
}
450+
this.setCurrentTexture(gameObject.frame.source);
431451

432452
// These are TypedArray Views into the vertices ArrayBuffer
433453
var colors = this.colors;
@@ -476,7 +496,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
476496
this.list[this.currentBatchSize++] = gameObject;
477497
},
478498

479-
prepShader: function ()
499+
initShader: function ()
480500
{
481501
var gl = this.gl;
482502

@@ -525,7 +545,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
525545
// Always dirty the first pass through but subsequent calls may be clean
526546
if (this.dirty)
527547
{
528-
this.prepShader();
548+
this.initShader();
529549
}
530550

531551
var gl = this.gl;
@@ -559,7 +579,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
559579
this.renderer.setBlendMode(sprite.blendMode);
560580
}
561581

562-
if (this.currentTextureSource !== sprite.frame.source)
582+
if (!this.renderer.multiTexture && this.currentTextureSource !== sprite.frame.source)
563583
{
564584
if (currentSize > 0)
565585
{

src/renderer/webgl/WebGLRenderer.js

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,7 @@ Phaser.Renderer.WebGL = function (game)
8686
*/
8787
this.stencilBufferLimit = 6;
8888

89-
// WebGL specific from here
90-
91-
this.enableMultiTextureToggle = false;
89+
this.multiTexture = true;
9290

9391
this.extensions = {};
9492

@@ -155,10 +153,10 @@ Phaser.Renderer.WebGL = function (game)
155153

156154
this.gl = null;
157155

158-
// Add a null entry to avoid an array look-up miss
159-
this.textureArray = [ null, null ];
156+
this.textureArray = [];
160157

161158
this.currentBlendMode = 0;
159+
this.currentTextureSource = null;
162160

163161
this.blendModes = [];
164162

@@ -215,6 +213,13 @@ Phaser.Renderer.WebGL.prototype = {
215213

216214
this.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
217215

216+
console.log('maxTextures', this.maxTextures);
217+
218+
if (this.maxTextures === 1)
219+
{
220+
this.multiTexture = false;
221+
}
222+
218223
gl.disable(gl.DEPTH_TEST);
219224
gl.disable(gl.CULL_FACE);
220225
gl.enable(gl.BLEND);
@@ -318,12 +323,6 @@ Phaser.Renderer.WebGL.prototype = {
318323
*/
319324
setTexturePriority: function (textureNameCollection)
320325
{
321-
if (!this.enableMultiTextureToggle)
322-
{
323-
console.warn('setTexturePriority error: Multi Texture support hasn\'t been enabled in the Phaser Game Config.');
324-
return;
325-
}
326-
327326
var maxTextures = this.maxTextures;
328327
var imageCache = this.game.cache._cache.image;
329328
var imageName = null;
@@ -409,8 +408,7 @@ Phaser.Renderer.WebGL.prototype = {
409408
// gl.clearColor(0, 0, 0, 1);
410409
// gl.clear(gl.COLOR_BUFFER_BIT);
411410

412-
// Normal Blend Mode
413-
this.setBlendMode(0);
411+
this.setBlendMode(this.blendModes.NORMAL);
414412

415413
/*
416414
if (this.clearBeforeRender)
@@ -476,6 +474,8 @@ Phaser.Renderer.WebGL.prototype = {
476474
// Takes a TextureSource object
477475
updateTexture: function (source)
478476
{
477+
console.log('updateTexture', source);
478+
479479
if (source.compressionAlgorithm)
480480
{
481481
return this.updateCompressedTexture(source);
@@ -488,9 +488,7 @@ Phaser.Renderer.WebGL.prototype = {
488488
source.glTexture = gl.createTexture();
489489
}
490490

491-
// gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
492-
493-
gl.activeTexture(gl.TEXTURE0);
491+
gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
494492

495493
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
496494

@@ -699,11 +697,15 @@ Phaser.Renderer.WebGL.prototype = {
699697

700698
createEmptyTexture: function (width, height, scaleMode)
701699
{
700+
console.log('createEmptyTexture');
701+
702702
var gl = this.gl;
703703
var texture = gl.createTexture();
704704
var glScaleMode = (scaleMode === Phaser.scaleModes.LINEAR) ? gl.LINEAR : gl.NEAREST;
705705

706+
gl.activeTexture(gl.TEXTURE0);
706707
gl.bindTexture(gl.TEXTURE_2D, texture);
708+
707709
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
708710
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
709711
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glScaleMode);

0 commit comments

Comments
 (0)