0

立方体の頂点データが主に GL_TRIANGLES で使用するために構築されている場合に、描画モードを GL_LINE、GL_LINE_STRIP、または GL_LINE_LOOP に切り替えようとすると、興味深い結果が得られますが、立方体の適切なワイヤフレーム表現を提供するものはありません。

GL_LINES/GL_LINE_STRIP/GL_LINE_LOOP と GL_TRIANGLES の間で描画モードを切り替えるだけで良い結果が得られるように、立方体の頂点とインデックス データを構築する方法はありますか? それとも、線モードの 1 つで使用するために頂点を再作成するための適切なワイヤフレームを取得する唯一の方法はありますか?

4

1 に答える 1

1

最も実用的な方法は、おそらく最も単純な方法です。線と三角形のレンダリングに個別のインデックス配列を使用します。確かに頂点属性を複製する必要はありませんが、まったく異なるプリミティブ タイプを同じインデックスで描画することは非常に問題に思えます。

GL_ELEMENT_ARRAY_BUFFERこれを実装するには、2 つの異なるインデックス ( ) バッファーを使用できます。または、より洗練された私見では、単一のバッファを使用し、両方のインデックス セットを格納します。三角形のレンダリングと線のレンダリングtriIdxCountにインデックスが必要だとします。lineIdxCount次に、次の方法でインデックス バッファを設定できます。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,
             (triIdxCount + lineIdxCount) * sizeof(GLushort), 0,
             GL_STATIC_DRAW);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                0, triIdxCount * sizeof(GLushort), triIdxArray);
glBufferSubData(GL_ELEMENT_ARRAY_BUFFER,
                triIdxCount * sizeof(GLushort), lineIdxCount * sizeof(GLushort),
                lineIdxArray);

次に、描画の準備ができたら、インデックス バッファー バインディングを含むすべての状態を設定し (理想的には、すべての状態設定に VAO を使用します)、条件付きでレンダリングします。

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuf);
if (renderTri) {
    glDrawElements(GL_TRIANGLES, triIndexCount, GL_UNSIGNED_SHORT, 0);
} else {
    glDrawElements(GL_LINES, lineIdxCount, GL_UNSIGNED_SHORT,
                   triIndexCount * sizeof(GLushort));
}

メモリ使用量の観点からすると、2 セットのインデックスを持つことは、適度な量のオーバーヘッドです。通常、実際の頂点属性データはインデックス データよりもはるかに大きく、ここで重要な点は、属性データが複製されないことです。

線を厳密にレンダリングする必要はなく、ワイヤフレーム タイプのレンダリングが必要な場合は、他のオプションがあります。たとえば、ポリゴンの境界に近いピクセルのみを描画し、ポリゴン エッジまでの距離に基づいてフラグメント シェーダーの内部ピクセルを破棄するエレガントなアプローチ (自分で実装したことはありませんが、巧妙に見えます) があります。この質問 (私が回答を寄稿した場所) では、アプローチについて詳しく説明しています:ワイヤーフレーム シェーダー - 共有頂点を使用する場合の重心座標の問題

于 2014-09-05T05:25:02.557 に答える