Dart: web_gl:渲染警告:绑定到纹理单元0的纹理不可渲染。

13

当我在dartium中运行Web应用程序时,出现错误[.WebGLRenderingContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'。我已经尝试了两天来解决这个问题,包括完全重写代码,但我无法确定问题所在。

我认为问题出现在这段代码中。

  void main() {
  ...
    var texture = gl.createTexture();
    var image = new ImageElement();
    image.onLoad.listen((e) {
      gl.bindTexture(webGL.TEXTURE_2D, texture);
      gl.texImage2DImage(webGL.TEXTURE_2D, 0, webGL.RGBA, webGL.RGBA, 
                       webGL.UNSIGNED_BYTE, image);
      gl.texParameteri(webGL.TEXTURE_2D, webGL.TEXTURE_MAG_FILTER, webGL.NEAREST);
      gl.texParameteri(webGL.TEXTURE_2D, webGL.TEXTURE_MIN_FILTER, webGL.NEAREST);
      gl.bindTexture(webGL.TEXTURE_2D, null);
    });
    image.src = "tex.png";
  ...
  }

tex.png 的尺寸为 32x32。

对于问题有任何想法吗?


gl.generateMipmap(gl.TEXTURE_2D); 对你有帮助吗? - Fox32
1
@Fox32 不需要。只有在设置mipmap参数时才需要,不是吗? - lightandlight
2个回答

13

在我问题中的代码后面,我绑定了纹理并发送采样器统一变量。这是错误的,因为它在图像加载之前执行。为了修复这个问题,我把绑定纹理和绘制元素的调用放在 onload 函数中:

  image.onLoad.listen((e) {
    gl.bindTexture(webGL.TEXTURE_2D, texture);
    gl.texImage2DImage(webGL.TEXTURE_2D, 0, webGL.RGBA, webGL.RGBA, 
                       webGL.UNSIGNED_BYTE, image);
    gl.texParameteri(webGL.TEXTURE_2D, webGL.TEXTURE_MAG_FILTER, webGL.NEAREST);
    gl.texParameteri(webGL.TEXTURE_2D, webGL.TEXTURE_MIN_FILTER, webGL.NEAREST);
    gl.bindTexture(webGL.TEXTURE_2D, null);

    gl.activeTexture(webGL.TEXTURE0);
    gl.bindTexture(webGL.TEXTURE_2D, texture);
    gl.uniform1i(gl.getUniformLocation(shader.program, "uSampler"), 0);

    gl.drawElements(webGL.TRIANGLES, 6, webGL.UNSIGNED_SHORT, 0); 

  });

这确保了图片已经加载完毕。

之前,它只是分配了onload回调函数并执行下一组命令 - 包括绑定纹理 - 但因为计算机非常快,它在图片加载完成之前就已经绑定了纹理并尝试绘制它。


11
另一种处理方法是在纹理创建时创建一个1x1像素的纹理,并在图像加载完成后用图像替换它。这样可以立即开始绘制,无需进行特殊检查。请参见https://dev59.com/yGIj5IYBdhLWcg3w95cc#19748905。 - gman

2

我曾经遇到过同样的错误。但是在我的情况下,我忘记设置

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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);

在我的initTexture()方法中。该代码有助于正确渲染纹理,无论视频的大小如何。
也许对某些人有帮助 :)

或者,如果不想使用mipmapping,则应将两个FILTER选项都设置为gl.NEAREST,这样只会获取最接近的texel,而不是线性混合靠近UV采样位置的texel。某些纹理类型(例如浮点格式)无法进行过滤,因此需要禁用线性过滤。 - brita_

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接