Skip to content

Commit 120b6eb

Browse files
committed
Blend Modes work. More optimisations in the batch manager.
1 parent dae0b2c commit 120b6eb

5 files changed

Lines changed: 74 additions & 131 deletions

File tree

src/gameobjects/image/ImageWebGLRenderer.js

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,6 @@ Phaser.Renderer.WebGL.GameObjects.Image = {
7171
}
7272
*/
7373

74-
// Also works ...
75-
76-
// renderer.spriteBatch.startGameObject(src);
77-
// renderer.spriteBatch.addVert(verts.x0, verts.y0, uvs.x0, uvs.y0, index, tint.topLeft + alpha, bg);
78-
// renderer.spriteBatch.addVert(verts.x1, verts.y1, uvs.x1, uvs.y1, index, tint.topRight + alpha, bg);
79-
// renderer.spriteBatch.addVert(verts.x2, verts.y2, uvs.x2, uvs.y2, index, tint.bottomRight + alpha, bg);
80-
// renderer.spriteBatch.addVert(verts.x3, verts.y3, uvs.x3, uvs.y3, index, tint.bottomLeft + alpha, bg);
8174
}
8275

8376
};

src/renderer/webgl/BatchManager.js

Lines changed: 50 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
4747
// View on the vertices as a Uint32Array
4848
this.colors = new Uint32Array(this.vertices);
4949

50-
this.currentTextureSource = null;
51-
5250
this.currentBatchSize = 0;
51+
5352
this.dirty = true;
53+
5454
this.list = [];
5555

5656
/**
@@ -109,8 +109,9 @@ Phaser.Renderer.WebGL.BatchManager = function (renderer, batchSize)
109109
'uniform sampler2D uSampler;', // our texture
110110

111111
'void main(void) {',
112-
' vec4 pixel = texture2D(uSampler, vTextureCoord) * vTintColor;', // get the color from the texture
113-
' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
112+
' vec4 pixel = texture2D(uSampler, vTextureCoord);', // get the color from the texture
113+
// ' vec4 pixel = texture2D(uSampler, vTextureCoord) * vTintColor;', // get the color from the texture
114+
// ' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
114115
' gl_FragColor = pixel;',
115116
'}'
116117
];
@@ -217,7 +218,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
217218

218219
var fragmentSrc = this.fragmentSrc;
219220

220-
if (this.renderer.multiTexture && this.renderer.maxTextures > 1)
221+
if (this.renderer.multiTexture)
221222
{
222223
var multiFrag = [
223224
'precision lowp float;',
@@ -243,22 +244,20 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
243244
}
244245

245246
multiFrag = multiFrag.concat([
246-
// ' else pixel = PINK;',
247+
' else pixel = PINK;',
248+
247249
' pixel *= vTintColor;',
248-
// ' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
250+
' if (pixel.a == 0.0) pixel = vBgColor;', // if texture alpha is zero, use the bg color
249251
' gl_FragColor = pixel;',
250-
// ' gl_FragColor = PINK;',
251252
'}'
252253
]);
253254

254255
this.multiTextureFragmentSrc = multiFrag;
255256

256257
fragmentSrc = this.multiTextureFragmentSrc;
257-
258-
// console.dir(this.multiTextureFragmentSrc);
259258
}
260259

261-
// Compile the Shaders
260+
// Compile the Shader
262261
var program = this.renderer.compileProgram(this.vertexSrc, fragmentSrc);
263262

264263
// Set Shader
@@ -283,7 +282,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
283282
gl.enableVertexAttribArray(this.aBgColor);
284283

285284
// Get and store the uniforms for the shader
286-
// this part is different for multi-textures
287285
if (this.renderer.multiTexture)
288286
{
289287
// Bind empty multi-textures to avoid WebGL spam
@@ -302,8 +300,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
302300

303301
this.uSampler = gl.getUniformLocation(program, 'uSamplerArray[0]');
304302

305-
gl.activeTexture(gl.TEXTURE0);
306-
307303
gl.uniform1iv(this.uSampler, indices);
308304
}
309305
else
@@ -314,7 +310,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
314310
// The projection vector (middle of the game world)
315311
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
316312

317-
// The offset vector
313+
// The offset vector (camera shake)
318314
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
319315

320316
this.program = program;
@@ -324,7 +320,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
324320
{
325321
this._i = 0;
326322
this.dirty = true;
327-
this.currentTextureSource = null;
328323
this.currentBatchSize = 0;
329324
},
330325

@@ -354,90 +349,21 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
354349

355350
setCurrentTexture: function (textureSource)
356351
{
357-
var gl = this.gl;
358-
359-
if (this.renderer.multiTexture)
360-
{
361-
if (this.renderer.textureArray[textureSource.glTextureIndex] !== textureSource)
362-
{
363-
// console.log('setCurrentTexture - batch size', this.currentBatchSize);
364-
// console.log(textureSource);
365-
366-
if (this.currentBatchSize > 0)
367-
{
368-
this.flush();
369-
}
370-
371-
gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
372-
373-
// console.log('activeTexture', gl.TEXTURE0 + textureSource.glTextureIndex);
374-
375-
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
376-
377-
this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
378-
}
379-
}
380-
else
352+
if (this.renderer.textureArray[textureSource.glTextureIndex] !== textureSource)
381353
{
382-
// console.log('setCurrentTexture');
383-
384-
if (this.currentTextureSource === textureSource)
385-
{
386-
// console.log('skip');
387-
return;
388-
}
389-
390354
if (this.currentBatchSize > 0)
391355
{
392-
// console.log('force flush from insdie setCurrentTexture');
393356
this.flush();
394357
}
395358

396-
// console.log('bind new sprites texture', textureSource.image.currentSrc);
359+
var gl = this.gl;
397360

398-
gl.activeTexture(gl.TEXTURE0);
361+
gl.activeTexture(gl.TEXTURE0 + textureSource.glTextureIndex);
399362

400363
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
401364

402-
this.currentTextureSource = textureSource;
403-
}
404-
},
405-
406-
// Call 'addVert' x4 after calling this
407-
startGameObject: function (gameObject)
408-
{
409-
// Does this Game Objects texture need updating?
410-
if (gameObject.frame.source.glDirty)
411-
{
412-
this.renderer.updateTexture(gameObject.frame.source);
413-
}
414-
415-
// Check Batch Size
416-
if (this.currentBatchSize >= this.maxBatchSize)
417-
{
418-
this.flush();
365+
this.renderer.textureArray[textureSource.glTextureIndex] = textureSource;
419366
}
420-
421-
this.list[this.currentBatchSize++] = gameObject;
422-
},
423-
424-
// Call this 4 times, once for each vert
425-
// Then call addGameObject to complete it (or before it, doesn't matter which order)
426-
427-
addVert: function (x, y, uvx, uvy, textureIndex, tint, bg)
428-
{
429-
var i = this._i;
430-
431-
this.positions[i++] = x;
432-
this.positions[i++] = y;
433-
this.positions[i++] = uvx;
434-
this.positions[i++] = uvy;
435-
this.positions[i++] = textureIndex;
436-
437-
this.colors[i++] = tint;
438-
this.colors[i++] = bg;
439-
440-
this._i = i;
441367
},
442368

443369
addToBatch: function (gameObject, verts, uvs, textureIndex, alpha, tintColors, bgColors)
@@ -447,35 +373,46 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
447373
// Check Batch Size and flush if needed
448374
if (this.currentBatchSize >= this.maxBatchSize)
449375
{
450-
// console.log('force flush because batch limit hit');
451376
this.flush();
452377
}
453378

379+
var source = gameObject.frame.source;
380+
454381
// Does this Game Objects texture need updating?
455-
if (gameObject.frame.source.glDirty)
382+
if (source.glDirty)
456383
{
457384
// Check Batch Size and flush if needed
458385
if (this.currentBatchSize > 0)
459386
{
460-
// console.log('force flush before updateTexture');
461387
this.flush();
462388
}
463389

464-
// console.log('texture dirty');
465-
this.renderer.updateTexture(gameObject.frame.source);
390+
this.renderer.updateTexture(source);
466391
}
467392

468-
// Set texture
469-
this.setCurrentTexture(gameObject.frame.source);
393+
// Set the current texture (not if this sprite has its own shader?)
394+
if (this.renderer.textureArray[source.glTextureIndex] !== source)
395+
{
396+
var gl = this.gl;
397+
398+
if (this.currentBatchSize > 0)
399+
{
400+
this.flush();
401+
}
402+
403+
gl.activeTexture(gl.TEXTURE0 + source.glTextureIndex);
404+
405+
gl.bindTexture(gl.TEXTURE_2D, source.glTexture);
406+
407+
this.renderer.textureArray[source.glTextureIndex] = source;
408+
}
470409

471410
// These are TypedArray Views into the vertices ArrayBuffer
472411
var colors = this.colors;
473412
var positions = this.positions;
474413

475414
var i = this._i;
476415

477-
// console.log('addToBatch i / ci', i, this.currentBatchSize);
478-
479416
// Top Left vert (xy, uv, color)
480417
positions[i++] = verts.x0;
481418
positions[i++] = verts.y0;
@@ -521,9 +458,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
521458
{
522459
var gl = this.gl;
523460

524-
// Bind the main texture
525-
// gl.activeTexture(gl.TEXTURE0);
526-
527461
// Bind the buffers
528462
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
529463
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
@@ -563,8 +497,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
563497

564498
flush: function ()
565499
{
566-
// console.log('flush');
567-
568500
// Always dirty the first pass through but subsequent calls may be clean
569501
if (this.dirty)
570502
{
@@ -573,7 +505,10 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
573505

574506
var gl = this.gl;
575507

576-
// Upload verts to the buffer
508+
// Upload the vertex data to the GPU - is this cheaper (overall) than creating a new TypedArray view?
509+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
510+
511+
/*
577512
if (this.currentBatchSize > this.halfBatchSize)
578513
{
579514
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
@@ -587,6 +522,7 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
587522
588523
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
589524
}
525+
*/
590526

591527
var sprite;
592528

@@ -599,15 +535,24 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
599535

600536
if (sprite.blendMode !== this.renderer.currentBlendMode)
601537
{
538+
if (currentSize > 0)
539+
{
540+
gl.drawElements(gl.TRIANGLES, currentSize * 6, gl.UNSIGNED_SHORT, start * 6 * 2);
541+
this.renderer.drawCount++;
542+
}
543+
602544
this.renderer.setBlendMode(sprite.blendMode);
603545
}
604546

547+
// TODO: Check for shader here
548+
549+
// If either blend or shader set, we need to drawElements and swap
550+
605551
currentSize++;
606552
}
607553

608554
if (currentSize > 0)
609555
{
610-
// console.log('flushed and drew', currentSize);
611556
gl.drawElements(gl.TRIANGLES, currentSize * 6, gl.UNSIGNED_SHORT, start * 6 * 2);
612557
this.renderer.drawCount++;
613558
}
@@ -625,8 +570,6 @@ Phaser.Renderer.WebGL.BatchManager.prototype = {
625570
this.gl.deleteBuffer(this.vertexBuffer);
626571
this.gl.deleteBuffer(this.indexBuffer);
627572

628-
this.currentTextureSource = null;
629-
630573
this.renderer = null;
631574
this.gl = null;
632575
}

0 commit comments

Comments
 (0)