WebGL - 等待纹理加载

Rem*_*aud 14 html5 textures webgl

如何测试WebGLTexture对象是否"完整"?

目前我收到此消息: [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'

我得到这个警告,因为渲染循环试图在其图像加载完成之前使用纹理,那么如何解决这个问题呢?

gma*_*man 21

解决这个问题的最简单方法是在创建时制作1x1纹理.

var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE,
              new Uint8Array([255, 0, 0, 255])); // red
Run Code Online (Sandbox Code Playgroud)

然后,当图像加载时,您可以用图像替换1x1像素纹理.无需标记,您的场景将使用您选择的颜色进行渲染,直到图像加载完毕.

var img = new Image();
img.src = "http://someplace/someimage.jpg";
img.onload = function() {
   gl.bindTexture(gl.TEXTURE_2D, tex);
   gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);

   // then either generate mips if the image uses power-of-2 dimensions or 
   // set the filtering correctly for non-power-of-2 images.
   setupTextureFilteringAndMips(img.width, img.height);
}
Run Code Online (Sandbox Code Playgroud)

只是为了节省人们遇到他们最有可能遇到的下一个问题的麻烦,WebGL需要mips或者它需要不需要mips的过滤.最重要的是,它需要使用尺寸为2的幂(即1,2,4,8,...,256,512等)的纹理来使用mips.因此,在加载图像时,您很可能希望设置过滤以正确处理此问题.

function isPowerOf2(value) {
  return (value & (value - 1)) == 0;
};

function setupTextureFilteringAndMips(width, height) {
  if (isPowerOf2(width) && isPowerOf2(height) {
    // the dimensions are power of 2 so generate mips and turn on 
    // tri-linear filtering.
    gl.generateMipmap(gl.TEXTURE_2D);
    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
  } else {
    // at least one of the dimensions is not a power of 2 so set the filtering
    // so WebGL will render it.
    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);
  }
}
Run Code Online (Sandbox Code Playgroud)