I can successfully render a plane with a texture but when I draw multiple objects with different textures then they "randomly" start to mix textures between each other.
My goal is to render sprites. I have one vbo that is just a flat surface that changes texture for each rendering.
This is my rendering function: "spritePlan" is the vbo of a plane vertices texture coord etc.
gl.uniform2fv(shaderProgram.texScalerUniform, [subImageWidth/object.objectTypeMetaData.sprite.mergedImages.width, 1]);
gl.uniform2fv(shaderProgram.texOffsetUniform, [object.objectTypeMetaData.sprite.mergedImagesPositions[object.spriteIndex]/object.objectTypeMetaData.sprite.mergedImages.width, 0]);
gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.vertBuffer);
gl.vertexAttribPointer(vertexAttribLocation, spritePlan.vertBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.texCoordBuffer);
gl.vertexAttribPointer(textureCoordAttribute, spritePlan.texCoordBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, spritePlan.colorBuffer);
gl.vertexAttribPointer(colorAttribLocation, spritePlan.colorBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, object.objectTypeMetaData.sprite.textureSprite);
gl.uniform1i(shaderProgram.sampler2DUniform, 0);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, spritePlan.indexBuffer);
setMatrixUniforms();
var xPos = Math.round(object.x-object.objectTypeMetaData.sprite.originX - viewXP)/rooms[gameVariables.currentRoom].roomWidth,
yPos = Math.round(object.y-object.objectTypeMetaData.sprite.originY - viewYP)/rooms[gameVariables.currentRoom].roomHeight;
var scaleX = (object.objectTypeMetaData.sprite.width/2)/rooms[gameVariables.currentRoom].roomWidth;
var scaleY = (object.objectTypeMetaData.sprite.height/2)/rooms[gameVariables.currentRoom].roomHeight;
mat4.identity(mvMatrix);
mat4.scale(mvMatrix, mvMatrix, [scaleX, scaleY, 1]);
mat4.translate(mvMatrix, mvMatrix, [(xPos/scaleX), (1/scaleY)-(yPos/scaleY), 0.0]);
gl.drawElements(gl.TRIANGLES, spritePlan.indexBuffer.numItems, gl.UNSIGNED_SHORT, 0);
gl.bindTexture(gl.TEXTURE_2D, null);
This is my fragment shader:
precision mediump float;
varying vec3 fragColor;
varying highp vec2 vTextureCoord;
uniform sampler2D uSampler;
void main()
{
vec4 tex = texture2D(uSampler, vTextureCoord);
gl_FragColor = vec4(fragColor, 1.0) * vec4(tex.rgb, tex.a);
};
This is my fragment shader:
precision mediump float;
attribute vec3 vertPosition;
attribute vec3 vertColor;
attribute vec2 aTextureCoord;
varying vec3 fragColor;
varying highp vec2 vTextureCoord;
uniform mat4 uPMatrix;
uniform mat4 uMVMatrix;
uniform vec2 uvOffset;
uniform vec2 uvScale;
void main()
{
fragColor = vertColor;
gl_Position = uPMatrix * uMVMatrix * vec4(vertPosition.x, vertPosition.y, vertPosition.z, 1.0);
vTextureCoord = (vec4(aTextureCoord, 0, 1)).xy * uvScale + uvOffset;
};
I don't really know what may cause this. Every sprite texture is associated with an object and a "new Image" and I looked and every texture is associated with the right object.
Am I not binding the textures correctly? What might be the problem?
Edit1:
I have noticed a pattern in how the textures are replaced.They just switch one step to the sprite that executes after it, so instead of rendering "1 2 3" it renders "3 1 2" which tells me this might be a really easy problem which makes much more frustrating :S
Each sprite is an object with their own Image. My canvas renderer tells me that each sprite has their correct image accosiated with them, so it's probably where I convert their image to a texture where something wrong happens. However I can't see any problems with my image to texture converter:
for(var i=0; i<spritesCompiled.length; i++){
spritesCompiled[i].textureSprite = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, spritesCompiled[i].textureSprite);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, spritesCompiled[i].mergedImages);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER,gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.bindTexture(gl.TEXTURE_2D,null);
}