13

I'm getting the error [.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' when I run my web app in dartium. I've been trying to troubleshoot this issue for two days, including a full rewrite of the code, But I can't isolate the issue.

I think the problem lies in this piece of code, however.

  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 is 32x32

Any ideas about what the problem is?

lightandlight
  • 1,345
  • 3
  • 10
  • 24

2 Answers2

13

Immediately after the code in my question I had bound the texture and send the sampler uniform. This was wrong because it was executed before the image loaded. To fix this, I put the calls to bind the texture and draw elements in the onload function:

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

  });

which makes sure the image has loaded.

Before, it would just assign the onload callback and then execute the next set of commands - which involved binding the texture - but because the computer is very quick it had already bound the texture and tried to draw it before the image had finished loading.

lightandlight
  • 1,345
  • 3
  • 10
  • 24
  • 11
    Another way to handle this is to create a 1x1 pixel texture at texture creation time and replace it with the image after the image has loaded. This lets you start drawing immediately with no special checking. See http://stackoverflow.com/questions/19722247/webgl-wait-for-texture-to-load/19748905#19748905 – gman Feb 23 '14 at 05:19
2

I had the same error. But in my case, I forgot to set

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

in my initTexture()-method. The code helps to render the texture correctly regardless of the size of the video.

Maybe it helps someone :)

wuiwuiwui
  • 499
  • 4
  • 13
  • Alternatively, if the intention is to *not* have mipmapping, both FILTER options should be set to gl.NEAREST which gets just the closest texel instead of linearly blending the texels closer to the UV sample position. Some texture types (e.g. float formats) are not filterable so they'll need the linear filtering disabled. – brita_ Jun 05 '21 at 11:20