phaser-ce
phaser-ce copied to clipboard
WebGL: INVALID_VALUE: vertexAttribPointer: index out of range (Ubuntu)
A bug in the API:
I am getting WebGL: INVALID_VALUE: vertexAttribPointer: index out of range spam on Firefox as well as on Chromium, running Ubuntu.
There is no condition for it to happen. It just happens always. A "code example" therefore simply is the empty example codepen: https://codepen.io/pen?template=vyKJvw
There is nothing obvious wrong, except those errors being spammed.
Here is the stacktrace from chromium, referencing lines in phaser-arcade-physics.js of 2.7.7:
PIXI.WebGLSpriteBatch.flush @ phaser.js:5153 PIXI.WebGLSpriteBatch.end @ phaser.js:4806 PIXI.WebGLRenderer.renderDisplayObject @ phaser.js:3742 PIXI.WebGLRenderer.render @ phaser.js:3705 updateRender @ phaser.js:21403 update @ phaser.js:21325 updateRAF @ phaser.js:49064 _onLoop @ phaser.js:49047
It happens due to shader.aTextureIndex in the line gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20); being -1
It is -1 because the getAttributeLocation earlier does indeed seem to return -1 I have no idea why that is however. It reminds me of an issue I had in other WebGL code that was due to some attributes being optimized away since they were not used, but the shader code of the respective shader here does seem to at least superficially use the attribute.
The minimal code to create the issue is to have Phaser in your namespace and start it with:
new Phaser.Game({width: 10, height: 10, renderer: Phaser.AUTO, resolution: 1})
From that point on it spams the warning.
I tested 2.7.7 and 2.7.3, both show the error. 2.6.2 is unaffected
new Phaser.Game({width: 10, height: 10, renderer: Phaser.AUTO, resolution: 1})
I don't see the warning in my Firefox (https://codepen.io/samme/pen/eWWWdz) so it may be platform-specific.
v2.7.7/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js#L58
Can you try
new Phaser.Game({enableDebug: false});
?
I get the same error here too
phaser.js:18791 WebGL: INVALID_VALUE: vertexAttribPointer: index out of range
I use chrome debug console tool , ubuntu 16.4 LTS
@softmixt Which platform/OS?
Ubuntu 16.4 LTS
My problem system also runs Ubuntu 16.4 LTS, with a Nvidia GTX 960.
The same machine on Windows 7 does not show the error, neither in Chrome nor in Firefox.
I can try new Phaser.Game({enableDebug: false}); later, as in within 24h.
Here is enableDebug: false
: https://codepen.io/samme/pen/EmmwGo
I get back to version v2.6.2 for now I'm going to check it later v2.7.7 using {enableDebug: false} and my g. card is GeForce GTX 1060 6GB/PCIe/SSE2 and I tried all available versions after 2.6.2 and all gave me same error .
Running https://codepen.io/samme/pen/EmmwGo does not show any errors anywhere, whatever enableDebug does, setting it to false makes the errors go away.
Error show when I bind a new state like this :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Hello Phaser</title>
<script src="phaser.min.js"></script>
<script>
window.onload = function() {
var StateExample = function ( game ){};
/**
* @type {{init: Boot.init, preload: Boot.preload, create: Boot.create}}
*/
StateExample.prototype = {
/**
* Set Game initialization settings
*/
init: function ()
{
//this.input.maxPointers = 1;
//this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;
},
preload: function ()
{
// Example Assets
this.game.load.image( 'phaser_logo', 'img.png' );
},
create: function ()
{
// Set background for our game
this.phaser_logo = this.game.add.sprite( 100, 150, 'phaser_logo' );
}
};
var game = new Phaser.Game( {
enableDebug: false,
width: 800,
height: 600,
renderer: Phaser.AUTO,
parent: "game",
transparent: true,
antialias: true,
} );
game.state.add( "StateExample", StateExample );
game.state.start( "StateExample" );
};
</script>
</head>
<body>
<div id="game"></div>
</body>
</html>
this use v2.7.7 if I use v2.6.2 error doesn't show up anymore :(
the result of that code in chrome is this :
and result same code in firefox is this :
The debug canvas is drawn each frame unless it's disabled (via enableDebug: false
) so that's probably what's causing it in an "empty" game.
If you set a breakpoint on the line that's emitting the warning (INVALID_VALUE…) you should be able to see which render object it's linked to.
I have the same issue under Arch Linux in chrome and i get errors in firefox aswell
Even with enableDebug: false still shows the error, so checking a bit what line comes that i doscover it comming from this part :
PIXI.WebGLSpriteBatch.prototype.flush = function () {
// If the batch is length 0 then return as there is nothing to draw
if (this.currentBatchSize === 0) {
return;
}
var gl = this.gl;
var shader;
if (this.dirty) {
this.dirty = false;
shader = this.defaultShader.shaders[gl.id];
// bind the main texture
gl.activeTexture(gl.TEXTURE0);
// bind the buffers
gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// this is the same for each shader?
var stride = this.vertexSize; //this.vertSize * 4;
gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, stride, 8);
// color attributes will be interpreted as unsigned bytes and normalized
gl.vertexAttribPointer(shader.colorAttribute, 4, gl.UNSIGNED_BYTE, true, stride, 16);
// Texture index
gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20);
}
for this function : gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20);
parametet value for shader.aTextureIndex
it is -1 so what i did is that i add a conditional check for shader.aTextureIndex hope solve that console info annoying alert
Same issue on Ubuntu, on FF and Chrome. Both using phaser 2.7.7 and 2.7.10
Getting same issue. Chrome, Ubuntu GNOME.
Ubuntu 17.04, Chrome 59.0.3071.115. Still having this issue. Using phaser 2.8.5. Do exist a workaround to make it work properly?
Ultimately someone needs to figure out why the aTextureIndex
attribute value is missing.
If you just want to silence the error, you can overwrite PIXI.WebGLSpriteBatch#flush: https://gist.github.com/samme/c4d0928c94a345976ee022884b2bce58
found something. assuming this is the latest non ce version of phaser: https://github.com/photonstorm/phaser/blob/master/v2/src/pixi/renderers/webgl/shaders/PixiShader.js#L102-L118
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
// Begin worst hack eva //
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
// maybe its something to do with the current state of the gl context.
// I'm convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
// If theres any webGL people that know why could happen please help :)
if(this.colorAttribute === -1)
{
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute];
there is a comment about "line above returns -1", and in that repo the direct line above the comment is:
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
comparing with current ce master: https://github.com/photonstorm/phaser-ce/blob/master/src/pixi/renderers/webgl/shaders/PixiShader.js#L191-L209
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
// Begin worst hack eva //
// WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
// maybe its something to do with the current state of the gl context.
// I'm convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
// If theres any webGL people that know why could happen please help :)
if(this.colorAttribute === -1)
{
this.colorAttribute = 2;
}
this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];
the direct line above would be:
this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
but thats probably irrelevant, but interestingly on my linux chromium 61.0.3163.100 this.colorAttribute is always 2 (before the if), but this.aTextureIndex is always -1, hmmm...
after some trial and error, this seems to work for me:
diff --git a/src/pixi/renderers/webgl/shaders/PixiShader.js b/src/pixi/renderers/webgl/shaders/PixiShader.js
index 92197a766..7161ce7d3 100644
--- a/src/pixi/renderers/webgl/shaders/PixiShader.js
+++ b/src/pixi/renderers/webgl/shaders/PixiShader.js
@@ -206,10 +206,16 @@ PIXI.PixiShader.prototype.initDefaultShader = function () {
this.colorAttribute = 2;
}
- this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];
-
// End worst hack eva //
+ // this might be related to above `this.colorAttribute === -1` bug?
+ if(this.aTextureIndex === -1)
+ {
+ this.aTextureIndex = 3;
+ }
+
+ this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute, this.aTextureIndex];
+
// add those custom shaders!
for (var key in this.uniforms)
{
I found discussion about same issue https://www.gamedev.net/forums/topic/524172-glgetattriblocation-and-a--1-return-value/ Looks like compiler optimizes shader code, and removes unused variable. If you look at shader code that used for NON-multi-textured case Vertex shader:
PIXI.PixiShader.defaultVertexSrc = [
'// PixiShader Vertex Shader',
'// With multi-texture rendering',
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'attribute vec4 aColor;',
'attribute float aTextureIndex;',
'uniform vec2 projectionVector;',
'uniform vec2 offsetVector;',
'varying vec2 vTextureCoord;',
'varying vec4 vColor;',
'varying float vTextureIndex;',
'const vec2 center = vec2(-1.0, 1.0);',
'void main(void) {',
' if (aTextureIndex > 0.0) gl_Position = vec4(0.0);',
' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);',
' vTextureCoord = aTextureCoord;',
' vColor = vec4(aColor.rgb * aColor.a, aColor.a);',
' vTextureIndex = aTextureIndex;',
'}'
];
aTextureIndex
attribute used only to assigns value to vTextureIndex
and vTextureIndex
is not used in fragment shader
this.fragmentSrc = [
'precision lowp float;',
'varying vec2 vTextureCoord;',
'varying vec4 vColor;',
'varying float vTextureIndex;',
'uniform sampler2D uSampler;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
'}'
];
This variable used only in multi-textured shader, and in non-multi-textured shader compiler just removes vTextureIndex
and aTextureIndex
to optimize code. Thats why
this.aTextureIndex = gl.getAttribLocation(program, 'aTextureIndex');
returns -1
We should make check as it already done for aColor
attribute:
if(this.colorAttribute === -1)
{
this.colorAttribute = 2;
}
right after that I suggest to add a check, same as patch in previous comment
if(this.aTextureIndex === -1)
{
this.aTextureIndex = 3;
}
So, this is not "worst hack eva", this is workaround for compiler optimizations :D
this.aTextureIndex = 3;
Why 3?
shader has 4 attributes
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'attribute vec4 aColor;',
'attribute float aTextureIndex;',
aVertexPosition
- index 0
aTextureCoord
- index 1
aColor
- index 2
aTextureIndex
- index 3
atrtributes should have this indexes usually
actually we dont know what indexes compiler will set to attributes
may be it would be cleaner way to check if attribute exists in flush
method of WebGLSpriteBatch
https://github.com/photonstorm/phaser-ce/blob/9192c3d085bd3a412cd40633fcdda5da59a2864a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js#L584
gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20);
change to
if (shader.aTextureIndex !== -1) {
gl.vertexAttribPointer(shader.aTextureIndex, 1, gl.FLOAT, false, stride, 20);
}
and may be it should be same for colorAttribute https://github.com/photonstorm/phaser-ce/blob/9192c3d085bd3a412cd40633fcdda5da59a2864a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js#L581
aTextureIndex
used also in WebGLFastSpriteBatch.start
https://github.com/photonstorm/phaser-ce/blob/9192c3d085bd3a412cd40633fcdda5da59a2864a/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js#L442
but i dont know is it affected by this issue