mirror of
https://github.com/photonstorm/phaser
synced 2025-02-17 14:38:30 +00:00
Updated WebGLRenderer to support new texture assignment
* The property `WebGLRenderer.currentActiveTextureUnit` has been renamed to `currentActiveTexture`. * `WebGLRenderer.startActiveTexture` is a new read-only property contains the current starting active texture unit. * `WebGLRenderer.maxTextures` is a new read-only property that contains the maximum number of texture units WebGL can use. * `WebGLRenderer.textureIndexes` is a new read-only array that contains all of the available WebGL texture units. * `WebGLRenderer.tempTextures` is a new read-only array that contains temporary WebGL textures. * The `WebGLRenderer.currentTextures` property has been removed, as it's no longer used. * `WebGLRenderer.currentTextures` has been removed, as it's no longer used internally. * `WebGLRenderer.setBlankTexture` no longer has a `force` parameter, as it's set by default. * `WebGLRenderer.setTextureSource` is a new method, used by pipelines and Game Objects, that will assign a texture unit to the given Texture Source. * The `WebGLRenderer.setTexture2D` method has been updated to use the new texture unit assignment. It no longer takes the `textureUnit` or `flush` parameters and these have been removed from its method signature.
This commit is contained in:
parent
9c76ec0389
commit
216d7cb1fa
1 changed files with 238 additions and 64 deletions
|
@ -7,7 +7,6 @@
|
|||
|
||||
var BaseCamera = require('../../cameras/2d/BaseCamera');
|
||||
var CameraEvents = require('../../cameras/2d/events');
|
||||
var CheckShaderMax = require('./CheckShaderMax');
|
||||
var Class = require('../../utils/Class');
|
||||
var CONST = require('../../const');
|
||||
var GameEvents = require('../../core/events');
|
||||
|
@ -150,7 +149,7 @@ var WebGLRenderer = new Class({
|
|||
this.blendModes = [];
|
||||
|
||||
/**
|
||||
* Keeps track of any WebGLTexture created with the current WebGLRenderingContext
|
||||
* Keeps track of any WebGLTexture created with the current WebGLRenderingContext.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#nativeTextures
|
||||
* @type {array}
|
||||
|
@ -205,22 +204,55 @@ var WebGLRenderer = new Class({
|
|||
// Internal Renderer State (Textures, Framebuffers, Pipelines, Buffers, etc)
|
||||
|
||||
/**
|
||||
* Cached value for the last texture unit that was used
|
||||
* Cached value for the last texture unit that was used.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentActiveTextureUnit
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentActiveTexture
|
||||
* @type {integer}
|
||||
* @since 3.1.0
|
||||
*/
|
||||
this.currentActiveTextureUnit = 0;
|
||||
this.currentActiveTexture = 0;
|
||||
|
||||
/**
|
||||
* An array of the last texture handles that were bound to the WebGLRenderingContext
|
||||
* Contains the current starting active texture unit.
|
||||
* This value is constantly updated and should be treated as read-only by your code.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#currentTextures
|
||||
* @type {array}
|
||||
* @since 3.0.0
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#startActiveTexture
|
||||
* @type {integer}
|
||||
* @since 3.25.0
|
||||
*/
|
||||
this.currentTextures = new Array(16);
|
||||
this.startActiveTexture = 0;
|
||||
|
||||
/**
|
||||
* The maximum number of textures the GPU can handle. The minimum under the WebGL1 spec is 8.
|
||||
* This is set via the Game Config `maxTextures` property and should never be changed after boot.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#maxTextures
|
||||
* @type {integer}
|
||||
* @since 3.25.0
|
||||
*/
|
||||
this.maxTextures = 0;
|
||||
|
||||
/**
|
||||
* An array of the available WebGL texture units, used to populate the uSampler uniforms.
|
||||
*
|
||||
* This array is populated during the init phase and should never be changed after boot.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#textureIndexes
|
||||
* @type {array}
|
||||
* @since 3.25.0
|
||||
*/
|
||||
this.textureIndexes;
|
||||
|
||||
/**
|
||||
* An array of default temporary WebGL Textures.
|
||||
*
|
||||
* This array is populated during the init phase and should never be changed after boot.
|
||||
*
|
||||
* @name Phaser.Renderer.WebGL.WebGLRenderer#tempTextures
|
||||
* @type {array}
|
||||
* @since 3.25.0
|
||||
*/
|
||||
this.tempTextures;
|
||||
|
||||
/**
|
||||
* Current framebuffer in use
|
||||
|
@ -674,16 +706,11 @@ var WebGLRenderer = new Class({
|
|||
// Load supported extensions
|
||||
var exts = gl.getSupportedExtensions();
|
||||
|
||||
if (!config.maxTextures)
|
||||
if (!config.maxTextures || config.maxTextures === -1)
|
||||
{
|
||||
config.maxTextures = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
|
||||
}
|
||||
|
||||
if (!config.maxTextureSize)
|
||||
{
|
||||
config.maxTextureSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
|
||||
}
|
||||
|
||||
var extString = 'WEBGL_compressed_texture_';
|
||||
var wkExtString = 'WEBKIT_' + extString;
|
||||
|
||||
|
@ -704,21 +731,53 @@ var WebGLRenderer = new Class({
|
|||
// Mipmaps
|
||||
this.mipmapFilter = gl[config.mipmapFilter];
|
||||
|
||||
// Initialize all textures to null
|
||||
for (var index = 0; index < this.currentTextures.length; ++index)
|
||||
// Check maximum supported textures
|
||||
this.maxTextures = Utils.checkShaderMax(gl, config.maxTextures);
|
||||
|
||||
this.textureIndexes = [];
|
||||
|
||||
// Create temporary WebGL textures
|
||||
var tempTextures = this.tempTextures;
|
||||
|
||||
if (Array.isArray(tempTextures))
|
||||
{
|
||||
this.currentTextures[index] = null;
|
||||
for (var t = 0; i < this.maxTextures; t++)
|
||||
{
|
||||
gl.deleteTexture(tempTextures[t]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tempTextures = new Array(this.maxTextures);
|
||||
}
|
||||
|
||||
// Check maximum shader if statements
|
||||
var maxGPUTextures = CheckShaderMax(gl, gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS));
|
||||
// Create temp textures to stop WebGL errors on mac os
|
||||
for (var index = 0; index < this.maxTextures; index++)
|
||||
{
|
||||
var tempTexture = gl.createTexture();
|
||||
|
||||
console.log('maxGPUTextures', maxGPUTextures);
|
||||
gl.activeTexture(gl.TEXTURE0 + index);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, tempTexture);
|
||||
|
||||
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([ 0, 0, 255, 255 ]));
|
||||
|
||||
tempTextures[index] = tempTexture;
|
||||
|
||||
this.textureIndexes.push(index);
|
||||
}
|
||||
|
||||
this.tempTextures = tempTextures;
|
||||
|
||||
// Reset to texture 1 (texture zero is reserved for framebuffers)
|
||||
this.currentActiveTexture = 1;
|
||||
this.startActiveTexture++;
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
|
||||
// Clear previous pipelines and reload default ones
|
||||
this.pipelines = {};
|
||||
|
||||
this.addPipeline('TextureTintPipeline', new TextureTintPipeline({ game: game, renderer: this, maxGPUTextures: maxGPUTextures }));
|
||||
this.addPipeline('TextureTintPipeline', new TextureTintPipeline({ game: game, renderer: this }));
|
||||
|
||||
// this.addPipeline('TextureTintStripPipeline', new TextureTintStripPipeline({ game: game, renderer: this }));
|
||||
// this.addPipeline('BitmapMaskPipeline', new BitmapMaskPipeline({ game: game, renderer: this }));
|
||||
|
@ -1060,9 +1119,9 @@ var WebGLRenderer = new Class({
|
|||
*/
|
||||
setPipeline: function (pipelineInstance, gameObject)
|
||||
{
|
||||
if (this.currentPipeline !== pipelineInstance ||
|
||||
this.currentPipeline.vertexBuffer !== this.currentVertexBuffer ||
|
||||
this.currentPipeline.program !== this.currentProgram)
|
||||
var current = this.currentPipeline;
|
||||
|
||||
if (current !== pipelineInstance || current.vertexBuffer !== this.currentVertexBuffer || current.program !== this.currentProgram)
|
||||
{
|
||||
this.flush();
|
||||
this.currentPipeline = pipelineInstance;
|
||||
|
@ -1131,11 +1190,11 @@ var WebGLRenderer = new Class({
|
|||
|
||||
this.setBlendMode(0, true);
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, this.blankTexture.glTexture);
|
||||
|
||||
this.currentActiveTextureUnit = 0;
|
||||
this.currentTextures[0] = this.blankTexture.glTexture;
|
||||
this.currentActiveTexture = 1;
|
||||
this.startActiveTexture++;
|
||||
|
||||
this.currentPipeline = pipelineInstance;
|
||||
this.currentPipeline.bind();
|
||||
|
@ -1283,17 +1342,60 @@ var WebGLRenderer = new Class({
|
|||
* @method Phaser.Renderer.WebGL.WebGLRenderer#setBlankTexture
|
||||
* @private
|
||||
* @since 3.12.0
|
||||
*
|
||||
* @param {boolean} [force=false] - Force a blank texture set, regardless of what's already bound?
|
||||
*/
|
||||
setBlankTexture: function (force)
|
||||
setBlankTexture: function ()
|
||||
{
|
||||
if (force === undefined) { force = false; }
|
||||
this.setTexture2D(this.blankTexture.glTexture);
|
||||
},
|
||||
|
||||
if (force || this.currentActiveTextureUnit !== 0 || !this.currentTextures[0])
|
||||
/**
|
||||
* Activates the Texture Source and assigns it the next available texture unit.
|
||||
* If none are available, it will flush the current pipeline first.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.WebGLRenderer#setTextureSource
|
||||
* @since 3.25.0
|
||||
*
|
||||
* @param {Phaser.Textures.TextureSource} textureSource - The Texture Source to be assigned the texture unit.
|
||||
*
|
||||
* @return {number} The texture unit that was assigned to the Texture Source.
|
||||
*/
|
||||
setTextureSource: function (textureSource)
|
||||
{
|
||||
var gl = this.gl;
|
||||
var currentActiveTexture = this.currentActiveTexture;
|
||||
|
||||
if (textureSource.glIndexCounter < this.startActiveTexture)
|
||||
{
|
||||
this.setTexture2D(this.blankTexture.glTexture, 0);
|
||||
textureSource.glIndexCounter = this.startActiveTexture;
|
||||
|
||||
if (currentActiveTexture < this.maxTextures)
|
||||
{
|
||||
textureSource.glIndex = currentActiveTexture;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + currentActiveTexture);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
|
||||
|
||||
this.currentActiveTexture++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're out of textures, so flush the batch and reset back to 0
|
||||
this.flush();
|
||||
|
||||
this.startActiveTexture++;
|
||||
|
||||
textureSource.glIndexCounter = this.startActiveTexture;
|
||||
|
||||
textureSource.glIndex = 0;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
gl.bindTexture(gl.TEXTURE_2D, textureSource.glTexture);
|
||||
|
||||
this.currentActiveTexture = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return textureSource.glIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1302,39 +1404,49 @@ var WebGLRenderer = new Class({
|
|||
*
|
||||
* @method Phaser.Renderer.WebGL.WebGLRenderer#setTexture2D
|
||||
* @since 3.0.0
|
||||
* @version 2.0 - Updated in 3.25.0 to remove the `textureUnit` and `flush` parameters.
|
||||
*
|
||||
* @param {WebGLTexture} texture - The WebGL texture that needs to be bound.
|
||||
* @param {integer} textureUnit - The texture unit to which the texture will be bound.
|
||||
* @param {boolean} [flush=true] - Will the current pipeline be flushed if this is a new texture, or not?
|
||||
*
|
||||
* @return {this} This WebGLRenderer instance.
|
||||
* @return {number} The texture unit that was assigned to the Texture Source.
|
||||
*/
|
||||
setTexture2D: function (texture, textureUnit, flush)
|
||||
setTexture2D: function (texture)
|
||||
{
|
||||
if (flush === undefined) { flush = true; }
|
||||
|
||||
var gl = this.gl;
|
||||
var currentActiveTexture = this.currentActiveTexture;
|
||||
|
||||
if (texture !== this.currentTextures[textureUnit])
|
||||
if (texture.glIndexCounter < this.startActiveTexture)
|
||||
{
|
||||
if (flush)
|
||||
texture.glIndexCounter = this.startActiveTexture;
|
||||
|
||||
if (currentActiveTexture < this.maxTextures)
|
||||
{
|
||||
texture.glIndex = currentActiveTexture;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE0 + currentActiveTexture);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
this.currentActiveTexture++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We're out of textures, so flush the batch and reset back to 1 (0 is reserved for fbos)
|
||||
this.flush();
|
||||
|
||||
this.startActiveTexture++;
|
||||
|
||||
texture.glIndexCounter = this.startActiveTexture;
|
||||
|
||||
texture.glIndex = 1;
|
||||
|
||||
gl.activeTexture(gl.TEXTURE1);
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
this.currentActiveTexture = 2;
|
||||
}
|
||||
|
||||
if (this.currentActiveTextureUnit !== textureUnit)
|
||||
{
|
||||
gl.activeTexture(gl.TEXTURE0 + textureUnit);
|
||||
|
||||
this.currentActiveTextureUnit = textureUnit;
|
||||
}
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
this.currentTextures[textureUnit] = texture;
|
||||
}
|
||||
|
||||
return this;
|
||||
return texture.glIndex;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1552,7 +1664,11 @@ var WebGLRenderer = new Class({
|
|||
var gl = this.gl;
|
||||
var texture = gl.createTexture();
|
||||
|
||||
this.setTexture2D(texture, 0);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
|
||||
|
@ -1582,12 +1698,17 @@ var WebGLRenderer = new Class({
|
|||
gl.generateMipmap(gl.TEXTURE_2D);
|
||||
}
|
||||
|
||||
this.setTexture2D(null, 0);
|
||||
if (currentTexture)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
|
||||
}
|
||||
|
||||
texture.isAlphaPremultiplied = pma;
|
||||
texture.isRenderTexture = false;
|
||||
texture.width = width;
|
||||
texture.height = height;
|
||||
texture.glIndex = 0;
|
||||
texture.glIndexCounter = -1;
|
||||
|
||||
this.nativeTextures.push(texture);
|
||||
|
||||
|
@ -1764,11 +1885,13 @@ var WebGLRenderer = new Class({
|
|||
|
||||
this.gl.deleteTexture(texture);
|
||||
|
||||
if (this.currentTextures[0] === texture && !this.game.pendingDestroy)
|
||||
/*
|
||||
if (!this.game.pendingDestroy)
|
||||
{
|
||||
// texture we just deleted is in use, so bind a blank texture
|
||||
this.setBlankTexture(true);
|
||||
}
|
||||
*/
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -2435,7 +2558,10 @@ var WebGLRenderer = new Class({
|
|||
|
||||
if (width > 0 && height > 0)
|
||||
{
|
||||
this.setTexture2D(dstTexture, 0);
|
||||
// this.setTexture2D(dstTexture, 0);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
||||
gl.bindTexture(gl.TEXTURE_2D, dstTexture);
|
||||
|
||||
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
|
||||
|
||||
|
@ -2444,7 +2570,11 @@ var WebGLRenderer = new Class({
|
|||
dstTexture.width = width;
|
||||
dstTexture.height = height;
|
||||
|
||||
this.setTexture2D(null, 0);
|
||||
// this.setTexture2D(null, 0);
|
||||
if (currentTexture)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
|
||||
}
|
||||
}
|
||||
|
||||
return dstTexture;
|
||||
|
@ -2546,12 +2676,21 @@ var WebGLRenderer = new Class({
|
|||
var gl = this.gl;
|
||||
var glFilter = [ gl.LINEAR, gl.NEAREST ][filter];
|
||||
|
||||
this.setTexture2D(texture, 0);
|
||||
// this.setTexture2D(texture, 0);
|
||||
gl.activeTexture(gl.TEXTURE0);
|
||||
|
||||
var currentTexture = gl.getParameter(gl.TEXTURE_BINDING_2D);
|
||||
|
||||
gl.bindTexture(gl.TEXTURE_2D, texture);
|
||||
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, glFilter);
|
||||
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, glFilter);
|
||||
|
||||
this.setTexture2D(null, 0);
|
||||
// this.setTexture2D(null, 0);
|
||||
if (currentTexture)
|
||||
{
|
||||
gl.bindTexture(gl.TEXTURE_2D, currentTexture);
|
||||
}
|
||||
|
||||
return this;
|
||||
},
|
||||
|
@ -2747,6 +2886,29 @@ var WebGLRenderer = new Class({
|
|||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a 1iv uniform value on the given shader.
|
||||
*
|
||||
* If the shader is not currently active, it is made active first.
|
||||
*
|
||||
* @method Phaser.Renderer.WebGL.WebGLRenderer#setInt1iv
|
||||
* @since 3.25.0
|
||||
*
|
||||
* @param {WebGLProgram} program - The target WebGLProgram from which the uniform location will be looked-up.
|
||||
* @param {string} name - The name of the uniform to look-up and modify.
|
||||
* @param {Int32List} arr - The 1iv value to set on the named uniform.
|
||||
*
|
||||
* @return {this} This WebGL Renderer instance.
|
||||
*/
|
||||
setInt1iv: function (program, name, arr)
|
||||
{
|
||||
this.setProgram(program);
|
||||
|
||||
this.gl.uniform1iv(this.gl.getUniformLocation(program, name), arr);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a 1i uniform value on the given shader.
|
||||
*
|
||||
|
@ -2955,11 +3117,23 @@ var WebGLRenderer = new Class({
|
|||
{
|
||||
// Clear-up anything that should be cleared :)
|
||||
|
||||
for (var i = 0; i < this.nativeTextures.length; i++)
|
||||
var i;
|
||||
var gl = this.gl;
|
||||
|
||||
var temp = this.tempTextures;
|
||||
var native = this.nativeTextures;
|
||||
|
||||
for (i = 0; i < temp.length; i++)
|
||||
{
|
||||
this.gl.deleteTexture(this.nativeTextures[i]);
|
||||
gl.deleteTexture(temp[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < native.length; i++)
|
||||
{
|
||||
gl.deleteTexture(native[i]);
|
||||
}
|
||||
|
||||
this.textureIndexes = [];
|
||||
this.nativeTextures = [];
|
||||
|
||||
for (var key in this.pipelines)
|
||||
|
|
Loading…
Add table
Reference in a new issue