I am working in a web viewer that has many shader programs rendering to the same page. I'm adding another program that renders a quad with a texture. The quad renders just fine. The texture is what's giving me an issue.
Mesh.prototype.initTexture = function(ctx) {
this.texture = this.ctx.createTexture();
this.texture.image = new Image();
// ctx.bindTexture(this.ctx.TEXTURE_2D, this.texture);
// ctx.texImage2D(this.ctx.TEXTURE_2D, 0, this.ctx.RGBA, 1, 1, 0, this.ctx.RGBA, this.ctx.UNSIGNED_BYTE, new Uint8Array([255, 0, 0, 255])); // red
mesh.texture.image.onload = function () {
//Upon callback, 'this' is different, so we use the global variable for now
mesh.handleLoadedTexture(mesh.texture,mesh.texture.image);
}
this.texture.image.src = "/path/to/images/nehe.gif";
}
That's my initTexture function. I can uncomment the two lines that load the red square (a la WebGL - wait for texture to load), then the texture renders as red and no errors pop up anymore, but my texture never loads. The texture itself is a renderable texture that I downloaded from LearningWebGL. I have a demo downloaded form that site that runs well on my localhost that's in parallel to this project.
Here's the handleLoadedTexture function
Mesh.prototype.handleLoadedTexture = function(texture, image) {
mesh.ctx.bindTexture(mesh.ctx.TEXTURE_2D, texture);
mesh.ctx.pixelStorei(mesh.ctx.UNPACK_FLIP_Y_WEBGL, true);
mesh.ctx.texImage2D(mesh.ctx.TEXTURE_2D, 0, mesh.ctx.RGBA, this.ctx.RGBA, mesh.ctx.UNSIGNED_BYTE, image);
mesh.ctx.texParameteri(mesh.ctx.TEXTURE_2D, mesh.ctx.TEXTURE_MAG_FILTER, mesh.ctx.NEAREST);
mesh.ctx.texParameteri(mesh.ctx.TEXTURE_2D, mesh.ctx.TEXTURE_MIN_FILTER, mesh.ctx.NEAREST);
mesh.ctx.generateMipmap(mesh.ctx.TEXTURE_2D);
mesh.ctx.bindTexture(mesh.ctx.TEXTURE_2D, null);
}
Then we have the chunk that calls render of this in the overall render pipeline:
if (mesh != null) {
mesh = new Mesh();
ctx.useProgram(meshShader);
// I set the camera and projection matrices here
glCheck();
if(!mesh.vbo) {
mesh.loadGL(ctx);
}
if(!mesh.texture){
mesh.initTexture(ctx);
}
mesh.render(meshShader);
glCheck();
}
Nothing too revolutionary there.
Render function:
Mesh.prototype.render = function(program) {
assert(this.vbo != null, "VBO is null");
assert(this.tcbo != null, "TCBO is null");
// Arguments here are (index, size, type, normalized(bool), stride, offset)
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.vbo);
this.ctx.vertexAttribPointer(program.a.vertex, this.sizevertices, this.ctx.FLOAT, false, 0, 0);
this.ctx.bindBuffer(this.ctx.ARRAY_BUFFER, this.tcbo);
this.ctx.vertexAttribPointer(program.a.textureCoordinate, this.sizetexco, this.ctx.FLOAT, false, 0, 0);
this.ctx.activeTexture(this.ctx.TEXTURE0);
this.ctx.bindTexture(this.ctx.TEXTURE_2D, this.texture);
this.ctx.uniform1i(program.uSampler, 0);
this.ctx.drawArrays(this.ctx.TRIANGLE_STRIP, 0, this.numvertices);
render.glCheck();
}
Vertex Shader:
varying vec2 vTextureCoord;
attribute vec3 vertex;
attribute vec2 textureCoordinate;
//other unrelated uniforms
void main(void) {
//position settings omitted
vTextureCoord = textureCoordinate;
}
Fragment Shader:
precision mediump float;
varying vec2 vTextureCoord;
uniform sampler2D uSampler;
void main(void) {
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t));
}