WebGL可渲染纹理无法渲染。 RENDER警告:绑定到纹理单元0的纹理不可渲染

时间:2014-02-04 19:17:28

标签: javascript opengl-es textures webgl

我在一个Web浏览器中工作,它有许多着色器程序渲染到同一页面。我正在添加另一个渲染纹理四边形的程序。四边形渲染得很好。纹理是给我一个问题的。

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";

}

这是我的initTexture功能。我可以取消注释加载红色方块的两条线(la WebGL - wait for texture to load),然后纹理渲染为红色,不再弹出错误,但我的纹理永远不会加载。纹理本身是我从LearningWebGL下载的可渲染纹理。我有一个演示下载表单,该站点在我的localhost上运行良好,与该项目并行。

这是handleLoadedTexture函数

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);
}

然后我们在整个渲染管道中有一个调用渲染的块:

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();
}

那里没什么革命性的。

渲染功能:

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();
}

顶点着色器:

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));
}

2 个答案:

答案 0 :(得分:1)

我想知道您在mesh函数中引用了哪个initTexture - 它肯定没有在您提供的代码中的任何位置定义...

也许你想写

this.texture.image.onload = function....

您已经了解到函数内的this与外部不同。但我想你需要使用另一个变量,而不是全局变量,如下所示:

that = this;
this.texture.image.onload = function () {
    that.handleLoadedTexture(mesh.texture,mesh.texture.image);
}

答案 1 :(得分:0)

if(!mesh.texture) {    // isn't it 'undefined'
    mesh.initTexture(ctx);
}

也许最好有适合整个事情的旗帜。

// when creating mesh
mesh.texInit = false;

加载时:

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);
        mesh.texInit = true;
        // note ^ here
    }
    this.texture.image.src = "/path/to/images/nehe.gif";
}

用于渲染:

if(mesh.texInit) { doMagic(); } // aka render