4

私はこの論文を実装しようとしています。私はそれのほとんどをダウンさせましたが、幾何学的なエッジを決定して表示するためにシェーダーに任意の非幾何学的データを送信することに関する部分が問題を引き起こしています. VBOについて知っていることを使用して、ほとんどのデータを問題なく送信できました。ただし、大量のデータを送信する必要があるため、複数のテクスチャ座標を使用する必要があります。

テクスチャ座標の複数のセットを設定する正しい方法であると思われるいくつかのバリエーションを既に実装し、多くのフォーラム ポスターの指示に従いました。これまでのところ、解決策はありません。

コンテキストとして、プログラムは、モデル内の一意のエッジごとに、4 つの頂点、2 つの法線ベクトル、浮動小数、および整数 (浮動小数として格納) のセットの 4 つのほぼ同一のコピーを送信しています。次のようにデータをレイアウトしました。

v0 is stored in gl_Vertex (vec3)
v1 is stored in gl_Color (vec3)
v2 is stored in gl_MultiTexCoord0 (vec3)
v3 is stored in gl_MultiTexCoord1 (vec3)
n0 is stored in gl_Normal (vec3)
n1 is stored in gl_SecondaryColor (vec3)
r and i are stored in gl_MultiTexCoord2 (vec2)

4 つのコピーの唯一の違いは i 値です。これは、描画可能なエッジが見つかった場合に頂点を編成する方法を決定するのに役立ちます。

ご覧のとおり、少なくとも 3 つのテクスチャ座標が必要です。最初のもの (gl_MultiTexCoord0) は問題なく動作しましたが、グラフィック カード上にある次のテクスチャ座標は制御不能な動作をしているように見え、動作することもありますが、通常は動作しません。

私のレンダリング関数は、次のように使用されていました。

void Mesh::RenderLineEdgesGPU()
{
    // Enable client state
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // Turn on edge shader
    edgeProgram.Activate();

    // Link buffers
    // v0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    // v1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
    glColorPointer(3, GL_FLOAT, 0, 0);

    // v2
    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // v3
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // n0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
    glNormalPointer(GL_FLOAT, 0, 0);

    // n1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0);

    // r and i
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    // Indicies
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);

    // Draw
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // Turn off edge shader
    edgeProgram.Deactivate();

    // Disable client state
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
}

これは私のオリジナルでした。v0、v1、および v2 で確実に機能します。「r and i」で機能するように見えますが、それは錯覚である可能性があります。n0 または n1 をテストする機能はまだありません。v3 は確実に機能しません。ご覧のとおり、ポイントとして描画しているため、(シェーダーを介して) そこにあるかどうかがわかります。v0、v1、および v2 がすべて存在します。v3 で同じことをしようとすると、原点に 1 つのポイントが生成されるか、何も生成されません。

オンラインで提案を見た後、ここに私の新しいセットアップがあります:

void Mesh::RenderLineEdgesGPU()
{
    // Enable client state
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_COLOR_ARRAY);
    glEnableClientState(GL_SECONDARY_COLOR_ARRAY);

    // Turn on edge shader
    edgeProgram.Activate();

    // Link buffers
    // v0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[0]);
    glVertexPointer(3, GL_FLOAT, 0, 0);

    // v1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[1]);
    glColorPointer(3, GL_FLOAT, 0, 0);

    // v2
    glClientActiveTextureARB(GL_TEXTURE0_ARB);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[2]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    // v3
    glClientActiveTextureARB(GL_TEXTURE1_ARB);

    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);

    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[3]);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    // n0
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[4]);
    glNormalPointer(GL_FLOAT, 0, 0);

    // n1
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[5]);
    glSecondaryColorPointer(3, GL_FLOAT, 0, 0);

    // r and i
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, edgeMeshHandles[6]);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    // Indicies
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, edgeMeshHandles[7]);

    // Draw
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // Turn off edge shader
    edgeProgram.Deactivate();

    // Disable client state
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_COLOR_ARRAY);
    glDisableClientState(GL_SECONDARY_COLOR_ARRAY);
}

各テクスチャ座標リストの実際の「読み込み」の周りでglEnableClientState/呼び出しをどのように行ったかに注意してください。glDisableClientStateと も使用glActiveTextureARBglEnable(GL_TEXTURE_2D)ます。ここで が必要な理由は理解できると思いますがglActiveTextureARB、もう 1 つは困惑します。GLSL Common Mistakes pageによると、glEnable(GL_TEXTURE_2D)シェーダーの使用はとにかくこの呼び出しを無視するため、独自のシェーダーを作成するときに使用することは想定されていません。

それだけです。テクスチャ座標で非テクスチャ座標データを送信する方法を具体的に説明しているチュートリアルを見つけることができずに、ここまで来ました。おそらく誰かがそのチュートリアルを知っていれば、私の問題は軽減されるでしょう. 御時間ありがとうございます!

4

1 に答える 1

8

glClientActiveTextureARB呼び出しに続いてどの特定のテクスチャ座標単位を変更しglEnableClientState(GL_TEX_COORD_ARRAY)、変更するかglTexCoordPointerを変更します。

glActiveTextureARBに影響glEnable(GL_TEXTURE_2D)します。これは、前述のように、シェーダーは必要ありません。

コードをよく見て、これらの5つの呼び出し(および同等のDisable)のみを選択すると、次のようになります。

    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE0_ARB);
    glEnable(GL_TEXTURE_2D);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glActiveTextureARB(GL_TEXTURE1_ARB);
    glEnable(GL_TEXTURE_2D);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);
    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

わかりました。すでにglActiveTextureARBとglEnableは役に立たないと言ったので(ちなみに、GL_TEXTURE_2D間に描画せずに有効/無効にするのは役に立ちません)、それらを削除します。

    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

今何が目立ちますか?2つの問題:

  • Drawを実行する前に、クライアントの状態を無効にします
  • TEXTURE2のイネーブルビットを設定しません

あなたは何を書くべきですか?それらの線に沿った何か:(注意してください、各ポインター呼び出しにBindBuffer呼び出しを追加し直す必要があります):

    // texture coord 0
    glClientActiveTextureARB(GL_TEXTURE0_ARB); // program texcoord unit 0
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); // enable array data to shader
    glTexCoordPointer(3, GL_FLOAT, 0, 0); // say what data

    // texture coord 1
    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(3, GL_FLOAT, 0, 0);

    // texture coord 2
    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    glTexCoordPointer(2, GL_FLOAT, 0, 0);

    glDrawElements(GL_POINTS, EdgeVertexQuantity, GL_UNSIGNED_INT, 0);

    // done with those texcoord units, turn them off
    glClientActiveTextureARB(GL_TEXTURE0_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE1_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    glClientActiveTextureARB(GL_TEXTURE2_ARB);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

BindBufferに関するいくつかのコメント:は影響を受けglBindBufferARB(GL_ARRAY_BUFFER_ARB,...)ませが、次の呼び出しglClientActiveTextureARBは影響します。glTexCoordPointer本質的には、に追加の引数を提供するものglClientActiveTextureARBと考えてください。glBindBufferARBglTexCoordPointer

最後に、これらのVBOの一部をより少ないバッファーにグループ化することをお勧めします。別の質問のために何かありますか?(ヒント、2つの引数はglTexCoordPointer0である必要はありません)

于 2009-11-05T08:22:49.337 に答える