1

したがって、2つの異なるシェーダーを使用したレンダリングで問題が発生します。現在、サイコロを表す形状をレンダリングしています。ユーザーがサイコロを選択した場合、サイコロを完全に赤く少し拡大して輪郭を描き、その上に適切なサイコロをレンダリングします。現時点では、いくつかのサイコロは、何らかの理由で、アウトラインに対して間違ったサイコロをレンダリングしますが、適切な前景のサイコロに対しては正しいサイコロをレンダリングします。

どういうわけか、頂点データが混同されていないのではないかと思います。このようなことをopenGLで許可されているかどうかはわかりません。

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, numVertices*sizeof(GLfloat), vertices, GL_STATIC_DRAW);

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

私が持っている最初のシェーダーをロードするときに、ここで頂点データを2つの異なるシェーダーにバインドしようとしています:

vertCoord = glGetAttribLocation(TexAndLighting, "position");

他のシェーダーには次のものがあります。

toon_vertCoord = glGetAttribLocation(Toon, "position");

シェーダーを互いに独立して使用すると、正常に機能しますが、両方を重ねてレンダリングしようとすると、モデルが混同されることがあります。これが私の描画関数の外観です。

- (void) draw {
[EAGLContext setCurrentContext:context];

glBindVertexArrayOES(_vertexArray); 

effect->modelViewMatrix = mvm;
effect->numberColour = GLKVector4Make(numbers[colorSelected].r, numbers[colorSelected].g, numbers[colorSelected].b, 1);
effect->faceColour = GLKVector4Make(faceColors[colorSelected].r, faceColors[colorSelected].g, faceColors[colorSelected].b, 1);

if(selected){
    [effect drawOutline]; //this function prepares the shader
    glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
}

[effect prepareToDraw]; //same with this one
glDrawElements(GL_TRIANGLES, numIndices, GL_UNSIGNED_SHORT, 0);
}

ほとんどのアウトラインが間違ったダイスを使用しているか、まったく使用していないことがわかるように、これはどのように見えるかです。 サイコロの写真

完全なコードへのリンク:http://pastebin.com/yDKb3wrDDice.mm//レンダリング関連
http://pastebin.com/eBK0pzrKEffects.mm//シェーダー関連
http://pastebin.com/5LtDAk8J//マイシェーダー、しかしそれらとは何の関係もないはずです

TL; DR:同じ頂点データを使用する2つの異なるシェーダーを使用しようとしていますが、両方を同時に使用してレンダリングするとモデルが混同されます。これは間違っていると思いますが、実際にはかなり困惑しています。

4

1 に答える 1

2

あなたは正しいです、これは許可されていません(またはむしろそれはあなたが思うことをしません):

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

属性には、シェーダーとの特別なリンクはありません。OpenGLに「属性Nはこのシェーダー用であり、属性Mはこの他のシェーダー用である」とは言えません。

属性は単にインデックスにバインドするだけで、そのインデックスに入力があるシェーダーは、その特定のインデックスに最後にバインドされたデータを丸呑みにします。

したがって、2つのシェーダーがある場合は、それらを「トゥーン」と「ノーマル」と呼びます。これらのシェーダーには、次の入力があります(これは架空のものです)。

normal
  input vertCoord (index = 0)
  input texCoord (index = 1)

toon
  input toon_vertCoord (index = 0)
  input toon_somethingElse (index = 1)

次に、このコードを実行すると、次のようになります。

glEnableVertexAttribArray(effect->vertCoord);        
glVertexAttribPointer(effect->vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

glEnableVertexAttribArray(effect->toon_vertCoord);        
glVertexAttribPointer(effect->toon_vertCoord, 3, GL_FLOAT, GL_FALSE, 0, 0);

draw_normal_object();

同じインデックスを持ち、入力ポインタを上書きしたため、あなたeffect->vertCoordはもはや何にもバインドされていません。toon_vertCoordしたがって、ここでは通常のシェーダーがからサンプリングし、toon_vertCoordすべてが台無しになります。

実行したいのは、「通常のシェーダー」のすべての属性を有効化/ポインター化し、通常のオブジェクトを描画してから、トゥーンシェーダーに切り替え、すべてのトゥーン属性を有効化/ポインター化してから、トゥーンオブジェクトを描画することです。

于 2012-09-04T21:37:30.523 に答える