2012-03-14 8 views
3

私のWebGLプログラムでピッキング(色とreadPixelsを使用)を実装しようとしています。プログラムを始めると、shaderProgramを別に作成します。 1つはフォンシェーディング用で、もう1つはどのシェイプがクリックされたかを検出するための色をシェイプに与えます。異なる数の属性を持つ2つ以上のシェーダーを使用すると競合します

phongシェーダには2つの属性があります。頂点の位置と頂点の法線。ピッキングする人は単にポジションを持っています。

今私は、これらのシェーダが同じプログラムに存在し、ピッキングのものを使用しているという奇妙な理由から、drawArrayコールが失敗するとわかりました。最後に、gl.vertexAttribPointerコールが発生します。私は混乱していると私はアクティブな属性の配列を使用してチェックするときにそれを発見: gl.getVertexAttrib(インデックス、gl.VERTEX_ATTRIB_ARRAY_ENABLED);

真0,1リターンの両方が(ピッキングシェーダがgl.useProgram(ピッキング)とアクティブである場合、これは)

今はgl.disableVertexAttribArray(1)と1を無効にした場合。すべてが再び動作します。もう一つの修正点は、まずphongシェーダで描画し、ピッキングシェーダを使用して、何とか魔法のようにOKにすることです。その場合、phongシェーダを使用して頂点法線バッファを接続すると、ピッキングシェーダとdrawArrayコールが切り替わるときにどういうことかと思います。

私はgl.enableAttribArrayを間違って使用しているかどうかを知りたいので、シェーダなどの切り替え時に無効にする必要があります。

また、私はShaderプログラムを別の順序で作成しようとしましたが、成功しませんでした。

答えて

3

おそらく分かったように、useProgramは、次の描画呼び出しで実行するプログラム(シェーダコード)以外のものには影響しません。現在のプログラムで使用されている属性のみが有効になっていることを確認する必要があります。

何らかの方法でWebGLコードをラップした場合は、ラッパーのどこかに保存されている各プログラムの使用可能な属性番号の最大値を維持し、最新の使用プログラムと比較し、

+0

これは、私がソートを行うことを決めたことです。シェーダごとにどの頂点属性が存在し、どのシェーダがどのシェーダに存在するのか知っています私はgl.useProgram呼び出しをラップしていますので、最初にクリーンアップを行うことができます。 – nkassis

+0

実際にuseProgramは制服に影響を与えます。 GL_ARB_uniform_buffer_objectは、同じプログラムの複数のコピーを作成するだけでシミュレートできます。実際には、ドライバはGL_ARB_uniform_buffer_objectのフードの下でこれを実行します。 – gman

+0

ユニフォームにはどのような影響がありますか?私が理解する限り、セキュリティ上の理由から、あるプログラムの制服は別のプログラムの中で使用することはできませんが、GL.useProgramの影響を受けてはいけません。 – MikaelEmtinger

1

OpenGLは状態マシンです。ピッキングシェーダを選択することで、OpenGLをフォンシェーダの追加属性がなくなった状態に置くことができます。

多くの人が間違った悪いハビットに陥って、OpenGLで「一度の初期化」のようなものがあると想定しています。これはそうではありません。描画操作の直前に、描画操作の直前に必要なすべての状態を設定し、完了したら設定を元に戻すのが理想的です。これは、シェーダをバインドした後、頂点属性と呼ばれる必要なシェーダ入力を有効にしてバインドすることも想定しています。

+0

gl.useProgramの直後に私の頂点属性配列を有効にしますが、修正しません。私はまだglで2番目の属性配列を明示的に無効にする必要があります。disableAttributeArray(1) – nkassis

+0

@nkassis:次に無効にしてください。とにかくそれはあなたがやるべきことです。 – datenwolf

+0

@nkassisちょっと明確にすると、呼び出される関数はgl.disableVertexAttribArray –

1

あなたのコードを見ることなく告げるのは難しいですが... WebGLでは、アクセスされるすべての属性に描画呼び出しを満たすのに十分なデータが必要です。したがって、データの3つの頂点を持つ2つのアトリビュートをそれぞれ設定し、3つの頂点を描画した場合、シェーダを切り替えて1つのアトリビュートを6つの頂点で設定し、2つ目のアトリビュートを3つの頂点だけ残してから6つの頂点で描画しようとすると、現在、両方の属性にアクセスして描画していれば、WebGLは描画呼び出しに失敗します。

Chrome 19を実行している場合は、これが問題であるかどうかをJavaScriptコンソールで教えてください。

+0

ええクロム19は "INVALID_OPERATION:drawArrays:attribs not set corrrectly"と文句を言っています他のシェーダでgl.useProgramを実行すると、有効な頂点属性がリセットされるという印象を与えます。今私は、この特定のシェーダのために1つの頂点属性を持つ必要があるときに、2つの頂点属性を有効にしました。 p – nkassis