Skip to content

Commit dd1757a

Browse files
committed
Shaders will now automatically get all active uniforms and populate the uniforms object
1 parent e29626a commit dd1757a

4 files changed

Lines changed: 81 additions & 38 deletions

File tree

src/renderer/webgl/WebGLPipeline.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -571,12 +571,10 @@ var WebGLPipeline = new Class({
571571

572572
var vName = 'vertShader';
573573
var fName = 'fragShader';
574-
var uName = 'uniforms';
575574
var aName = 'attributes';
576575

577576
var defaultVertShader = GetFastValue(config, vName, null);
578577
var defaultFragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(config, fName, null), renderer.maxTextures);
579-
var defaultUniforms = GetFastValue(config, uName, null);
580578
var defaultAttribs = GetFastValue(config, aName, null);
581579

582580
var configShaders = GetFastValue(config, 'shaders', []);
@@ -587,7 +585,7 @@ var WebGLPipeline = new Class({
587585
{
588586
if (defaultVertShader && defaultFragShader)
589587
{
590-
this.shaders = [ new WebGLShader(this, 'default', defaultVertShader, defaultFragShader, DeepCopy(defaultAttribs), DeepCopy(defaultUniforms)) ];
588+
this.shaders = [ new WebGLShader(this, 'default', defaultVertShader, defaultFragShader, DeepCopy(defaultAttribs)) ];
591589
}
592590
}
593591
else
@@ -603,11 +601,10 @@ var WebGLPipeline = new Class({
603601
var vertShader = GetFastValue(shaderEntry, vName, defaultVertShader);
604602
var fragShader = Utils.parseFragmentShaderMaxTextures(GetFastValue(shaderEntry, fName, defaultFragShader), renderer.maxTextures);
605603
var attributes = GetFastValue(shaderEntry, aName, defaultAttribs);
606-
var uniforms = GetFastValue(shaderEntry, uName, defaultUniforms);
607604

608605
if (vertShader && fragShader)
609606
{
610-
newShaders.push(new WebGLShader(this, name, vertShader, fragShader, DeepCopy(attributes), DeepCopy(uniforms)));
607+
newShaders.push(new WebGLShader(this, name, vertShader, fragShader, DeepCopy(attributes)));
611608
}
612609
}
613610

@@ -948,6 +945,9 @@ var WebGLPipeline = new Class({
948945
* This hook is called _after_ the quad (or tri) has been added to the batch, so you can safely
949946
* call 'flush' from within this.
950947
*
948+
* Note that Game Objects may call `batchQuad` or `batchTri` multiple times for a single draw,
949+
* for example the Graphics Game Object.
950+
*
951951
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBatch
952952
* @since 3.50.0
953953
*
@@ -989,7 +989,7 @@ var WebGLPipeline = new Class({
989989
* By default this is an empty method hook that you can override and use in your own custom pipelines.
990990
*
991991
* This method is called once per frame, right before anything has been rendered, but after the canvas
992-
* has been cleared. If this pipeline has a render target, it will be cleared.
992+
* has been cleared. If this pipeline has a render target, it will also have been cleared by this point.
993993
*
994994
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPreRender
995995
* @since 3.50.0
@@ -1003,6 +1003,8 @@ var WebGLPipeline = new Class({
10031003
*
10041004
* This method is called _once per frame_, by every Camera in a Scene that wants to render.
10051005
*
1006+
* It is called at the start of the rendering process, before anything has been drawn to the Camera.
1007+
*
10061008
* @method Phaser.Renderer.WebGL.WebGLPipeline#onRender
10071009
* @since 3.50.0
10081010
*
@@ -1018,6 +1020,9 @@ var WebGLPipeline = new Class({
10181020
*
10191021
* This method is called _once per frame_, after all rendering has happened and snapshots have been taken.
10201022
*
1023+
* It is called at the very end of the rendering process, once all Cameras, for all Scenes, have
1024+
* been rendered.
1025+
*
10211026
* @method Phaser.Renderer.WebGL.WebGLPipeline#onPostRender
10221027
* @since 3.50.0
10231028
*/
@@ -1031,7 +1036,7 @@ var WebGLPipeline = new Class({
10311036
* This method is called every time this pipeline is asked to flush its batch.
10321037
*
10331038
* It is called immediately before the `gl.bufferData` and `gl.drawArray` calls are made, so you can
1034-
* perform any final pre-render modifications. To apply changes post-render, see `onPostBatch`.
1039+
* perform any final pre-render modifications. To apply changes post-render, see `onAfterFlush`.
10351040
*
10361041
* @method Phaser.Renderer.WebGL.WebGLPipeline#onBeforeFlush
10371042
* @since 3.50.0

src/renderer/webgl/WebGLShader.js

Lines changed: 67 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,12 @@ var WEBGL_CONST = require('./const');
2222
* @param {string} vertexShader - The vertex shader source code as a single string.
2323
* @param {string} fragmentShader - The fragment shader source code as a single string.
2424
* @param {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributesConfig[]} attributes - An array of attributes.
25-
* @param {string[]} [uniforms] - An array of shader uniform names that will be looked-up to get the locations for.
2625
*/
2726
var WebGLShader = new Class({
2827

2928
initialize:
3029

31-
function WebGLShader (pipeline, name, vertexShader, fragmentShader, attributes, uniforms)
30+
function WebGLShader (pipeline, name, vertexShader, fragmentShader, attributes)
3231
{
3332
/**
3433
* A reference to the WebGLPipeline that owns this Shader.
@@ -120,11 +119,11 @@ var WebGLShader = new Class({
120119
this.vertexSize = 0;
121120

122121
/**
123-
* The uniforms that this shader requires, as set via the configuration object.
122+
* The active uniforms that this shader has.
124123
*
125-
* This is an object that maps the uniform names to their WebGL location.
124+
* This is an object that maps the uniform names to their WebGL location and cached values.
126125
*
127-
* It is populated with their locations via the `setUniformLocations` method.
126+
* It is populated automatically via the `createUniforms` method.
128127
*
129128
* @name Phaser.Renderer.WebGL.WebGLShader#uniforms
130129
* @type {Phaser.Types.Renderer.WebGL.WebGLPipelineUniformsConfig}
@@ -133,11 +132,7 @@ var WebGLShader = new Class({
133132
this.uniforms = {};
134133

135134
this.createAttributes(attributes);
136-
137-
if (uniforms)
138-
{
139-
this.setUniformLocations(uniforms);
140-
}
135+
this.createUniforms();
141136
},
142137

143138
/**
@@ -325,38 +320,83 @@ var WebGLShader = new Class({
325320
* Sets up the `WebGLShader.uniforms` object, populating it with the names
326321
* and locations of the shader uniforms this shader requires.
327322
*
323+
* It works by first calling `gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS)` to
324+
* find out how many active uniforms this shader has. It then iterates through them,
325+
* calling `gl.getActiveUniform` to get the WebGL Active Info from each one. Finally,
326+
* the name and location are stored in the local array.
327+
*
328328
* This method is called automatically when this class is created.
329329
*
330-
* @method Phaser.Renderer.WebGL.WebGLShader#setUniformLocations
330+
* @method Phaser.Renderer.WebGL.WebGLShader#createUniforms
331331
* @since 3.50.0
332332
*
333-
* @param {string[]} uniformNames - An array of the uniform names to get the locations for.
334-
*
335333
* @return {this} This WebGLShader instance.
336334
*/
337-
setUniformLocations: function (uniformNames)
335+
createUniforms: function ()
338336
{
339337
var gl = this.gl;
340338
var program = this.program;
341339
var uniforms = this.uniforms;
342340

343-
for (var i = 0; i < uniformNames.length; i++)
344-
{
345-
var name = uniformNames[i];
341+
var i;
342+
var name;
343+
var location;
344+
345+
// Look-up all active uniforms
346346

347-
var location = gl.getUniformLocation(program, name);
347+
var totalUniforms = gl.getProgramParameter(program, gl.ACTIVE_UNIFORMS);
348+
349+
for (i = 0; i < totalUniforms; i++)
350+
{
351+
var info = gl.getActiveUniform(program, i);
348352

349-
if (location !== null)
353+
if (info)
350354
{
351-
uniforms[name] =
355+
name = info.name;
356+
357+
location = gl.getUniformLocation(program, name);
358+
359+
if (location !== null)
360+
{
361+
uniforms[name] =
362+
{
363+
name: name,
364+
location: location,
365+
value1: null,
366+
value2: null,
367+
value3: null,
368+
value4: null
369+
};
370+
}
371+
372+
// If the uniform name contains [] for an array struct,
373+
// we'll add an entry for the non-struct name as well.
374+
// Such as uMainSampler[12] = uMainSampler
375+
376+
var struct = name.indexOf('[');
377+
378+
if (struct > 0)
352379
{
353-
name: name,
354-
location: location,
355-
value1: null,
356-
value2: null,
357-
value3: null,
358-
value4: null
359-
};
380+
name = name.substr(0, struct);
381+
382+
if (!uniforms.hasOwnProperty(name))
383+
{
384+
location = gl.getUniformLocation(program, name);
385+
386+
if (location !== null)
387+
{
388+
uniforms[name] =
389+
{
390+
name: name,
391+
location: location,
392+
value1: null,
393+
value2: null,
394+
value3: null,
395+
value4: null
396+
};
397+
}
398+
}
399+
}
360400
}
361401
}
362402

src/renderer/webgl/typedefs/WebGLPipelineConfig.js

Lines changed: 1 addition & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/renderer/webgl/typedefs/WebGLPipelineShaderConfig.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,5 @@
55
* @property {string} [name] - The name of the shader. Doesn't have to be unique, but makes shader look-up easier if it is.
66
* @property {string} [vertShader] - The source code, as a string, for the vertex shader. If not given, uses the `Phaser.Types.Renderer.WebGL.WebGLPipelineConfig.vertShader` property instead.
77
* @property {string} [fragShader] - The source code, as a string, for the fragment shader. Can include `%count%` and `%forloop%` declarations for multi-texture support. If not given, uses the `Phaser.Types.Renderer.WebGL.WebGLPipelineConfig.fragShader` property instead.
8-
* @property {string[]} [uniforms] - An array of shader uniform names that will be looked-up to get the locations for. If not given, uses the `Phaser.Types.Renderer.WebGL.WebGLPipelineConfig.uniforms` property instead.
9-
* @property {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributesConfig} [attributes] - An array of shader attribute data. All shaders bound to this pipeline must use the same attributes.
8+
* @property {Phaser.Types.Renderer.WebGL.WebGLPipelineAttributesConfig} [attributes] - An array of shader attribute data. All shaders bound to this pipeline must use the same attributes.
109
*/

0 commit comments

Comments
 (0)