1

フラグメント シェーダーで 2 つのテクスチャを使用しようとしていますが、WebGL でテクスチャを適切に送信するのに問題があります。一度に 1 つずつ送信できますが、両方を同時に送信しようとすると、真っ黒になります。他にもマルチテクスチャリングの例をいくつか見てきましたが、それらはすべて画像の配列の読み込みを扱っています。

ビデオを 1 つのテクスチャにロードし、キャンバスを 2 つ目のテクスチャにロードしたいと考えています。私が書いた c++ opengl プログラムからシェーダーを移動しているだけなので、すべてのシェーダーが正常であることはほぼ確実です。また、動画やキャンバスをそれぞれコメントアウトすることで個別に表示することもできますが、上記のように一緒にするとエラーになるようです。

これは、テクスチャを作成して塗りつぶしているコードのスニペットです。

var texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);

var texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);

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

そして、私の描画ループ内:

gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, video);
var tex1loc = gl.getUniformLocation(program,"u_image");
gl.uniform1i(tex1loc, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture1);

gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, canvas);
var tex2loc = gl.getUniformLocation(program, "u_image2");
gl.uniform1i(tex2loc, 1);
gl.activeTexture(gl.TEXTURE1);
gl.bindTexture(gl.TEXTURE_2D, texture2);

次のような警告メッセージも表示されます。

GL_INVALID_ENUM : glActiveTexture: テクスチャは GL_FALSE でした

GL_INVALID_ENUM : glActiveTexture: テクスチャは GL_LINES でした

また:

WebGL: drawArrays: テクスチャ ユニット 0 にバインドされたテクスチャはレンダリングできません。2 の累乗ではなく、テクスチャ フィルタリングに互換性がないか、「テクスチャが完全」ではありません。または、OES_float_linear または OES_half_float_linear 拡張機能が有効になっていないときに、テクスチャがリニア フィルタリングを使用する Float または Half Float タイプです。

警告をトリガーする行は次のとおりです。

gl.drawArrays(gl.TRIANGLES, 0,6);

助けてくれてありがとう!

4

1 に答える 1

2

gl.activeTextureテクスチャ ユニットを設定し、他のすべてのテクスチャ コマンドの効果を設定します。テクスチャ ユニットごとに 2 つのバインド ポイントがTEXTURE_2Dあり、TEXTURE_CUBE_MAP.

このように考えることができます

gl = {
  activeTextureUnit: 0,
  textureUnits: [
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     { TEXTURE_2D: null: TEXTURE_CUBE_MAP: null, },
     ...
  ],
};

gl.activeTextureこれをするだけ

gl.activeTexture = function(unit) {
 gl.activeTextureUnit = unit - gl.TEXTURE0;
};

gl.bindTextureこれを行います

gl.bindTexture = function(bindPoint, texture) {
  gl.textureUnits[gl.activeTextureUnit][bindPoint] = texture;
};

gl.texImage2Dgl.texParamteriこのように使用するテクスチャを調べます

gl.texImage2D = function(bindPoint, .....) {
  var texture = gl.textureUnits[gl.activeTextureUnit][bindPoint];
  // now do something with texture

したがって、すべてを知っていると、コードの最初の問題は、2 つのテクスチャを作成することですがtexture1texture2テクスチャ パラメータのみを設定することですtexture2。これは、2 番目の呼び出しが、そのバインド ポイントでgl.bindTexture現在のテクスチャにバインドされてからのみ動作するテクスチャを設定するためです。その質感に。activeTextureTEXTURE_2Dgl.texParameteri

texture1バインドする前にパラメータを設定する必要がありますtexture2

同様に、描画コードを呼び出す必要があるgl.activeTextureか、呼び出すgl.bindTexture前に、それ以外の場合は、現在アクティブなテクスチャ ユニットのgl.texImage2Dポイントをバインドするためにバインドされているテクスチャで動作します。TEXTURE_2D

関連する警告についてgl.activeTextureは、テクスチャに関連するすべてのコードを投稿したことは確かですか? gl.activeTextureすべてを投稿した場合、有効に見える唯一の呼び出しであるため、これらの警告はあまり意味がありません。

それ以外の場合、ユニット 0 のテクスチャがレンダリング可能でないという他の警告は、texture1上記で説明したようにパラメータを設定していないためです。

したがって、明確にするために、コードは次のようになります

var texture1 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture1);

// you need to set parameters for texture1
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.NEAREST);
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER, gl.NEAREST);

var texture2 = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture2);

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

// these should be looked up at init time
var tex1loc = gl.getUniformLocation(program,"u_image");
var tex2loc = gl.getUniformLocation(program, "u_image2");

ループを描く:

// call active texture first
gl.activeTexture(gl.TEXTURE0);
// then bind a texture. This now binds texture1 to unit 0
gl.bindTexture(gl.TEXTURE_2D, texture1);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, video);
gl.uniform1i(tex1loc, 0);

// call active texture first
gl.activeTexture(gl.TEXTURE1);
// then bind a texture. This now binds texture2 to unit 1
gl.bindTexture(gl.TEXTURE_2D, texture2);
gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE, canvas);
gl.uniform1i(tex2loc, 1);
于 2014-02-27T07:54:58.333 に答える