Skip to content

Commit 2f41d9c

Browse files
committed
Sampler Array working correctly for WebGLSpriteBatch + PixiShader
1 parent 9aa71e5 commit 2f41d9c

2 files changed

Lines changed: 74 additions & 22 deletions

File tree

src/pixi/renderers/webgl/shaders/PixiShader.js

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,7 @@ PIXI.PixiShader = function(gl)
3535
* @property fragmentSrc
3636
* @type Array
3737
*/
38-
this.fragmentSrc = [
39-
'// PixiShader Fragment Shader.',
40-
'precision lowp float;',
41-
'varying vec2 vTextureCoord;',
42-
'varying vec4 vColor;',
43-
'varying float vTextureIndex;',
44-
'uniform sampler2D uSamplerArray[16];',
45-
'void main(void) {',
46-
' gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor ;',
47-
'}'
48-
];
38+
this.fragmentSrc = null;
4939

5040
/**
5141
* A local texture counter for multi-texture shaders.
@@ -90,13 +80,34 @@ PIXI.PixiShader.prototype.constructor = PIXI.PixiShader;
9080
PIXI.PixiShader.prototype.init = function()
9181
{
9282
var gl = this.gl;
83+
var MAX_TEXTURES = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
84+
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n'
85+
for (var index = 1; index < MAX_TEXTURES; ++index)
86+
{
87+
dynamicIfs += '\telse if (vTextureIndex == ' +
88+
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
89+
index + '], vTextureCoord) * vColor;\n'
90+
}
91+
this.fragmentSrc = [
92+
'// PixiShader Fragment Shader.',
93+
'precision lowp float;',
94+
'varying vec2 vTextureCoord;',
95+
'varying vec4 vColor;',
96+
'varying float vTextureIndex;',
97+
'uniform sampler2D uSamplerArray[' + MAX_TEXTURES + '];',
98+
'void main(void) {',
99+
dynamicIfs,
100+
'\telse gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;',
101+
'}'
102+
];
93103

94104
var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc);
95105

96106
gl.useProgram(program);
97107

98108
// get and store the uniforms for the shader
99-
this.uSampler = gl.getUniformLocation(program, 'uSampler');
109+
//this.uSampler = gl.getUniformLocation(program, 'uSampler');
110+
this.uSamplerArray = gl.getUniformLocation(program, 'uSamplerArray[0]');
100111
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
101112
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
102113
this.dimensions = gl.getUniformLocation(program, 'dimensions');
@@ -105,6 +116,18 @@ PIXI.PixiShader.prototype.init = function()
105116
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
106117
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
107118
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
119+
this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
120+
121+
var indices = [];
122+
for (var i = 0; i < MAX_TEXTURES; ++i) {
123+
indices.push(i);
124+
}
125+
// NOTE:!!!
126+
// If textures are not bound
127+
// then we'll get a bunch of warnings like:
128+
// "WARNING: there is no texture bound to the unit X"
129+
// Don't be scared, everything will be alright.
130+
gl.uniform1iv(this.uSamplerArray, indices);
108131

109132
// Begin worst hack eva //
110133

@@ -155,6 +178,7 @@ PIXI.PixiShader.prototype.initUniforms = function()
155178

156179
if (type === 'sampler2D')
157180
{
181+
debugger;
158182
uniform._init = false;
159183

160184
if (uniform.value !== null)

src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,14 @@ PIXI.WebGLSpriteBatch = function()
6666
* @type Uint16Array
6767
*/
6868
this.indices = new PIXI.Uint16Array(numIndices);
69+
70+
/**
71+
* Holds the texture indices
72+
*
73+
* @property textureIndices
74+
* @type Float32Array
75+
*/
76+
this.textureIndices = new PIXI.Float32Array(numIndices);
6977

7078
/**
7179
* @property lastIndexCount
@@ -135,16 +143,7 @@ PIXI.WebGLSpriteBatch = function()
135143
* @property defaultShader
136144
* @type AbstractFilter
137145
*/
138-
this.defaultShader = new PIXI.AbstractFilter([
139-
'//WebGLSpriteBatch Fragment Shader.',
140-
'precision lowp float;',
141-
'varying vec2 vTextureCoord;',
142-
'varying vec4 vColor;',
143-
'uniform sampler2D uSampler;',
144-
'void main(void) {',
145-
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
146-
'}'
147-
]);
146+
this.defaultShader = null;
148147
};
149148

150149
/**
@@ -153,11 +152,32 @@ PIXI.WebGLSpriteBatch = function()
153152
*/
154153
PIXI.WebGLSpriteBatch.prototype.setContext = function(gl)
155154
{
155+
var MAX_TEXTURES = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS);
156+
var dynamicIfs = '\tif (vTextureIndex == 0.0) gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;\n'
157+
for (var index = 1; index < MAX_TEXTURES; ++index)
158+
{
159+
dynamicIfs += '\telse if (vTextureIndex == ' +
160+
index + '.0) gl_FragColor = texture2D(uSamplerArray[' +
161+
index + '], vTextureCoord) * vColor;\n'
162+
}
156163
this.gl = gl;
164+
this.defaultShader = new PIXI.AbstractFilter([
165+
'//WebGLSpriteBatch Fragment Shader.',
166+
'precision lowp float;',
167+
'varying vec2 vTextureCoord;',
168+
'varying vec4 vColor;',
169+
'varying float vTextureIndex;',
170+
'uniform sampler2D uSamplerArray[' + MAX_TEXTURES + '];',
171+
'void main(void) {',
172+
dynamicIfs,
173+
'\telse gl_FragColor = texture2D(uSamplerArray[0], vTextureCoord) * vColor;',
174+
'}'
175+
]);
157176

158177
// create a couple of buffers
159178
this.vertexBuffer = gl.createBuffer();
160179
this.indexBuffer = gl.createBuffer();
180+
this.texIndexBuffer = gl.createBuffer();
161181

162182
// 65535 is max index, so 65535 / 6 = 10922.
163183

@@ -168,6 +188,9 @@ PIXI.WebGLSpriteBatch.prototype.setContext = function(gl)
168188
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
169189
gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
170190

191+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texIndexBuffer);
192+
gl.bufferData(gl.ARRAY_BUFFER, this.textureIndices, gl.DYNAMIC_DRAW);
193+
171194
this.currentBlendMode = 99999;
172195

173196
var shader = new PIXI.PixiShader(gl);
@@ -496,6 +519,10 @@ PIXI.WebGLSpriteBatch.prototype.flush = function()
496519

497520
// color attributes will be interpreted as unsigned bytes and normalized
498521
gl.vertexAttribPointer(shader.colorAttribute, 4, gl.UNSIGNED_BYTE, true, stride, 4 * 4);
522+
523+
gl.bindBuffer(gl.ARRAY_BUFFER, this.texIndexBuffer);
524+
gl.enableVertexAttribArray(shader.aTextureIndex);
525+
gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, gl.FALSE, 0, 0);
499526
}
500527

501528
// upload the verts to the buffer
@@ -674,6 +701,7 @@ PIXI.WebGLSpriteBatch.prototype.destroy = function()
674701

675702
this.gl.deleteBuffer(this.vertexBuffer);
676703
this.gl.deleteBuffer(this.indexBuffer);
704+
this.gl.deleteBuffer(this.texIndexBuffer);
677705

678706
this.currentBaseTexture = null;
679707

0 commit comments

Comments
 (0)