Create and use wrappers for WebGLUniformLocation and WebGLAttribLocation.

This commit is contained in:
Ben Richards 2024-01-30 22:13:51 +13:00
parent 0f9fb3177d
commit e920b1a961
5 changed files with 277 additions and 24 deletions

View file

@ -625,7 +625,6 @@ var Shader = new Class({
*/
initUniforms: function ()
{
var gl = this.gl;
var map = this.renderer.glFuncMap;
var program = this.program;
@ -638,7 +637,7 @@ var Shader = new Class({
var type = uniform.type;
var data = map[type];
uniform.uniformLocation = gl.getUniformLocation(program.webGLProgram, key);
uniform.uniformLocation = this.renderer.createUniformLocation(program, key);
if (type !== 'sampler2D')
{
@ -959,7 +958,7 @@ var Shader = new Class({
this.renderer.setProgram(this.program);
gl.uniform1i(uniform.uniformLocation, this._textureCount);
gl.uniform1i(uniform.uniformLocation.webGLUniformLocation, this._textureCount);
this._textureCount++;
},
@ -1002,24 +1001,24 @@ var Shader = new Class({
{
if (uniform.glMatrix)
{
glFunc.call(gl, location, uniform.transpose, value);
glFunc.call(gl, location.webGLUniformLocation, uniform.transpose, value);
}
else
{
glFunc.call(gl, location, value);
glFunc.call(gl, location.webGLUniformLocation, value);
}
}
else if (length === 2)
{
glFunc.call(gl, location, value.x, value.y);
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y);
}
else if (length === 3)
{
glFunc.call(gl, location, value.x, value.y, value.z);
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y, value.z);
}
else if (length === 4)
{
glFunc.call(gl, location, value.x, value.y, value.z, value.w);
glFunc.call(gl, location.webGLUniformLocation, value.x, value.y, value.z, value.w);
}
else if (uniform.type === 'sampler2D')
{
@ -1027,7 +1026,7 @@ var Shader = new Class({
gl.bindTexture(gl.TEXTURE_2D, value.webGLTexture);
gl.uniform1i(location, textureCount);
gl.uniform1i(location.webGLUniformLocation, textureCount);
textureCount++;
}

View file

@ -24,6 +24,8 @@ var WebGLBufferWrapper = require('./wrappers/WebGLBufferWrapper');
var WebGLProgramWrapper = require('./wrappers/WebGLProgramWrapper');
var WebGLTextureWrapper = require('./wrappers/WebGLTextureWrapper');
var WebGLFramebufferWrapper = require('./wrappers/WebGLFramebufferWrapper');
var WebGLAttribLocationWrapper = require('./wrappers/WebGLAttribLocationWrapper');
var WebGLUniformLocationWrapper = require('./wrappers/WebGLUniformLocationWrapper');
var DEBUG = false;
@ -268,6 +270,24 @@ var WebGLRenderer = new Class({
*/
this.glFramebufferWrappers = [];
/**
* A list of all WebGLAttribLocationWrappers that have been created by this renderer.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#glAttribLocationWrappers
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper[]}
* @since 3.80.0
*/
this.glAttribLocationWrappers = [];
/**
* A list of all WebGLUniformLocationWrappers that have been created by this renderer.
*
* @name Phaser.Renderer.WebGL.WebGLRenderer#glUniformLocationWrappers
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper[]}
* @since 3.80.0
*/
this.glUniformLocationWrappers = [];
/**
* The currently bound framebuffer in use.
*
@ -2144,6 +2164,38 @@ var WebGLRenderer = new Class({
return vertexBuffer;
},
/**
* Creates a WebGLAttribLocationWrapper instance based on the given WebGLProgramWrapper and attribute name.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createAttribLocation
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgramWrapper instance.
* @param {string} name - The name of the attribute.
*/
createAttribLocation: function (program, name)
{
var attrib = new WebGLAttribLocationWrapper(this.gl, program, name);
this.glAttribLocationWrappers.push(attrib);
return attrib;
},
/**
* Creates a WebGLUniformLocationWrapper instance based on the given WebGLProgramWrapper and uniform name.
*
* @method Phaser.Renderer.WebGL.WebGLRenderer#createUniformLocation
* @since 3.80.0
*
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgramWrapper instance.
* @param {string} name - The name of the uniform.
*/
createUniformLocation: function (program, name)
{
var uniform = new WebGLUniformLocationWrapper(this.gl, program, name);
this.glUniformLocationWrappers.push(uniform);
return uniform;
},
/**
* Wrapper for creating a vertex buffer.
*

View file

@ -313,29 +313,29 @@ var WebGLShader = new Class({
if (reset)
{
var attribLocation = gl.getAttribLocation(program.webGLProgram, element.name);
var attribLocation = this.renderer.createAttribLocation(program, element.name);
if (attribLocation >= 0)
if (attribLocation.webGLAttribLocation >= 0)
{
gl.enableVertexAttribArray(attribLocation);
gl.enableVertexAttribArray(attribLocation.webGLAttribLocation);
gl.vertexAttribPointer(attribLocation, size, type, normalized, vertexSize, offset);
gl.vertexAttribPointer(attribLocation.webGLAttribLocation, size, type, normalized, vertexSize, offset);
element.enabled = true;
element.location = attribLocation;
}
else if (attribLocation !== -1)
else if (attribLocation.webGLAttribLocation !== -1)
{
gl.disableVertexAttribArray(attribLocation);
gl.disableVertexAttribArray(attribLocation.webGLAttribLocation);
}
}
else if (enabled)
{
gl.vertexAttribPointer(location, size, type, normalized, vertexSize, offset);
gl.vertexAttribPointer(location.webGLAttribLocation, size, type, normalized, vertexSize, offset);
}
else if (!enabled && location > -1)
else if (!enabled && location !== -1 && location.webGLAttribLocation > -1)
{
gl.disableVertexAttribArray(location);
gl.disableVertexAttribArray(location.webGLAttribLocation);
element.location = -1;
}
@ -382,7 +382,7 @@ var WebGLShader = new Class({
{
name = info.name;
location = gl.getUniformLocation(program.webGLProgram, name);
location = this.renderer.createUniformLocation(program, name);
if (location !== null)
{
@ -409,7 +409,7 @@ var WebGLShader = new Class({
if (!uniforms.hasOwnProperty(name))
{
location = gl.getUniformLocation(program.webGLProgram, name);
location = this.renderer.createUniformLocation(program, name);
if (location !== null)
{
@ -507,7 +507,7 @@ var WebGLShader = new Class({
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location, value1);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1);
this.pipeline.currentShader = this;
}
@ -553,7 +553,7 @@ var WebGLShader = new Class({
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location, value1, value2);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2);
this.pipeline.currentShader = this;
}
@ -601,7 +601,7 @@ var WebGLShader = new Class({
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location, value1, value2, value3);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2, value3);
this.pipeline.currentShader = this;
}
@ -651,7 +651,7 @@ var WebGLShader = new Class({
this.renderer.setProgram(this.program);
setter.call(this.gl, uniform.location, value1, value2, value3, value4);
setter.call(this.gl, uniform.location.webGLUniformLocation, value1, value2, value3, value4);
this.pipeline.currentShader = this;
}

View file

@ -0,0 +1,101 @@
var Class = require('../../../utils/Class');
/**
* @classdesc
* Wrapper for a WebGL attribute location, containing all the information that was used to create it.
*
* A WebGLAttribLocation should never be exposed outside the WebGLRenderer,
* so the WebGLRenderer can handle context loss and other events without other systems having to be aware of it.
* Always use WebGLAttribLocationWrapper instead.
*
* @class WebGLAttribLocationWrapper
* @memberof Phaser.Renderer.WebGL.Wrappers
* @constructor
* @since 3.80.0
*
* @param {WebGLRenderingContext} gl - The WebGLRenderingContext to create the WebGLAttribLocation for.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgram that this location refers to. This must be created first.
* @param {string} name - The name of this location, as defined in the shader source code.
*/
var WebGLAttribLocationWrapper = new Class({
initialize:
function WebGLAttribLocationWrapper (gl, program, name)
{
/**
* The WebGLAttribLocation being wrapped by this class.
*
* This property could change at any time.
* Therefore, you should never store a reference to this value.
* It should only be passed directly to the WebGL API for drawing.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#webGLAttribLocation
* @type {WebGLAttribLocation}
* @default -1
* @since 3.80.0
*/
this.webGLAttribLocation = -1;
/**
* The WebGLRenderingContext that owns this location.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper#gl
* @type {WebGLRenderingContext}
* @since 3.80.0
*/
this.gl = gl;
/**
* The WebGLProgram that this location refers to.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#program
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper}
* @since 3.80.0
*/
this.program = program;
/**
* The name of this location, as defined in the shader source code.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#name
* @type {string}
* @since 3.80.0
*/
this.name = name;
this.createResource();
},
/**
* Creates the WebGLAttribLocation.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#createResource
* @since 3.80.0
*/
createResource: function ()
{
if (this.program.webGLProgram === null)
{
this.webGLAttribLocation = -1;
return;
}
this.webGLAttribLocation = this.gl.getAttribLocation(this.program.webGLProgram, this.name);
},
/**
* Destroys this WebGLAttribLocationWrapper.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLAttribLocationWrapper#destroy
* @since 3.80.0
*/
destroy: function ()
{
this.gl = null;
this.program = null;
this.name = null;
this.webGLAttribLocation = -1;
}
});
module.exports = WebGLAttribLocationWrapper;

View file

@ -0,0 +1,101 @@
var Class = require('../../../utils/Class');
/**
* @classdesc
* Wrapper for a WebGL uniform location, containing all the information that was used to create it.
*
* A WebGLUniformLocation should never be exposed outside the WebGLRenderer,
* so the WebGLRenderer can handle context loss and other events without other systems having to be aware of it.
* Always use WebGLUniformLocationWrapper instead.
*
* @class WebGLUniformLocationWrapper
* @memberof Phaser.Renderer.WebGL.Wrappers
* @constructor
* @since 3.80.0
*
* @param {WebGLRenderingContext} gl - The WebGLRenderingContext to create the WebGLUniformLocation for.
* @param {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper} program - The WebGLProgram that this location refers to. This must be created first.
* @param {string} name - The name of this location, as defined in the shader source code.
*/
var WebGLUniformLocationWrapper = new Class({
initialize:
function WebGLUniformLocationWrapper (gl, program, name)
{
/**
* The WebGLUniformLocation being wrapped by this class.
*
* This property could change at any time.
* Therefore, you should never store a reference to this value.
* It should only be passed directly to the WebGL API for drawing.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#webGLUniformLocation
* @type {?WebGLUniformLocation}
* @default null
* @since 3.80.0
*/
this.webGLUniformLocation = null;
/**
* The WebGLRenderingContext that owns this location.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper#gl
* @type {WebGLRenderingContext}
* @since 3.80.0
*/
this.gl = gl;
/**
* The WebGLProgram that this location refers to.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#program
* @type {Phaser.Renderer.WebGL.Wrappers.WebGLProgramWrapper}
* @since 3.80.0
*/
this.program = program;
/**
* The name of this location, as defined in the shader source code.
*
* @name Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#name
* @type {string}
* @since 3.80.0
*/
this.name = name;
this.createResource();
},
/**
* Creates the WebGLUniformLocation.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#createResource
* @since 3.80.0
*/
createResource: function ()
{
if (this.program.webGLProgram === null)
{
this.webGLUniformLocation = null;
return;
}
this.webGLUniformLocation = this.gl.getUniformLocation(this.program.webGLProgram, this.name);
},
/**
* Destroys this WebGLUniformLocationWrapper.
*
* @method Phaser.Renderer.WebGL.Wrappers.WebGLUniformLocationWrapper#destroy
* @since 3.80.0
*/
destroy: function ()
{
this.gl = null;
this.program = null;
this.name = null;
this.webGLUniformLocation = null;
}
});
module.exports = WebGLUniformLocationWrapper;