15

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'

イメージの読み込みが完了する前にレンダー ループがテクスチャを使用しようとしているため、この警告が表示されます。それを修正するにはどうすればよいですか?

4

3 に答える 3

26

これを修正する最も簡単な方法は、作成時に 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

次に、画像が読み込まれると、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);
}

次に遭遇する可能性が最も高い問題に遭遇する手間を省くために、WebGL は mips を必要とするか、mips を必要としないフィルタリングを必要とします。さらに、ミップを使用するには、2 のべき乗 (1、2、4、8、...、256、512 など) の寸法のテクスチャが必要です。そのため、画像をロードするときは、これを正しく処理するようにフィルタリングを設定する必要があります。

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);
  }
}
于 2013-11-03T01:29:50.103 に答える
1

この問題を解決するには、ブール値を使用して、画像が読み込まれたかどうかを確認します。

var loaded = false,
    texture,
    img = new Image();

img.onload = function() {
    texture = gl.createTexture();
    // . . . 
    loaded = true;
};
img.src = "path/myimage.jpg";

// render-loop
function render() {
    if(loaded) {
        // use texture
    }
    else {
        // not loaded yet
    }
}
于 2013-11-01T20:43:17.353 に答える
1

Cordova を使用して HTML5/JS アプリを Android フォンにデプロイしようとしたときに、この問題が発生しました。

最初は、スプライトシート/テクスチャ アトラスが大きすぎてモバイル GPU を読み込めないことが問題だと思っていました。そのため、ImageMagick のmogrify( mogrify -resize 256x256 *.png) を使用してすべての画像を一括縮小しましたが、まだ問題がありました。この手順はまだ必要でした (私8000x8000 .pngの携帯電話には多すぎるため)。

その後、ブラウザのバージョンを確認したところ、使用している Chromium がブラウザよりも古いことがわかりました。そこで、 Crosswalk プラグインを再インストールしたところ、すべて正常にレンダリングされました。console.log(navigator.userAgent)

cordova plugin rm cordova-plugin-crosswalk-webview
cordova plugin add cordova-plugin-crosswalk-webview
于 2016-09-11T15:50:49.657 に答える