1

OpenGL と GLSL を使用して単純なグラフィック エンジンを作成しました。ここまでは、新しいメッシュ シーン ノードを作成する必要があるときに、メッシュごとに VAO、VBO、および IBO を作成していました。この方法で各メッシュの頂点属性をロードしました。

glBufferData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(VERTEX_POSITION)
        + this->GetVerticesByteSize(VERTEX_TEXTURE) + this->GetVerticesByteSize(VERTEX_NORMAL), NULL, this->m_Usage);
    glBufferSubData(GL_ARRAY_BUFFER, 0, this->GetVerticesByteSize(VERTEX_POSITION), &this->m_VertexBuffer[VERTEX_POSITION][0]);
    if (!this->m_VertexBuffer[VERTEX_TEXTURE].empty())
        glBufferSubData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(VERTEX_POSITION),
            this->GetVerticesByteSize(VERTEX_TEXTURE), &this->m_VertexBuffer[VERTEX_TEXTURE][0]);
    if (!this->m_VertexBuffer[VERTEX_NORMAL].empty())
        glBufferSubData(GL_ARRAY_BUFFER, this->GetVerticesByteSize(
            VERTEX_POSITION) + this->GetVerticesByteSize(VERTEX_TEXTURE),
                this->GetVerticesByteSize(VERTEX_NORMAL), &this->m_VertexBuffer[VERTEX_NORMAL][0]);

しかし、シーンが多数のメッシュで構成されている場合、パフォーマンスが正しくありません (状態の変化が多すぎます)。そこで、シーンのすべてのジオメトリに対して一意の VAO、VBO、および IBO (シングルトン クラス) を作成することにしました。

これを行う方法は次のとおりです。

各メッシュの特定のクラス (「VertexAttributes」と呼びましょう) にすべての頂点属性をロードします。すべてのメッシュがロードされた後、大きな頂点バッファーを一意の VBO に割り当てることができます。上記のように、最初に関数 'glBufferData' を呼び出してシーン内のすべての頂点属性のサイズでメモリ全体を割り当て、その後ループ内の頂点属性の種類ごとに関数 'glBufferSubData' を呼び出します。

しかし、(メッシュごとに) glBufferData を数回呼び出して、シーンの読み込み中に VBO を埋めることは可能ですか (メッシュごとに段階的に)。したがって、再割り当てのように見えます。OpenGLでこれを行うことは可能ですか、それとも私の最初の方法は良い方法ですか?

4

1 に答える 1

3

しかし、(メッシュごとに) glBufferData を数回呼び出して、シーンの読み込み中に VBO を埋めることは可能ですか (メッシュごとに段階的に)。したがって、再割り当てのように見えます。OpenGLでこれを行うことは可能ですか、それとも私の最初の方法は良い方法ですか?

いいえ。 を呼び出すたびglBufferDataに、新しいデータ ストレージ (新しいサイズを使用) が作成され、以前の内容は失われます。

ただし、同じ VBO で複数のオブジェクトを結合することは、多くの場合、特にそれらのオブジェクトの多くが一緒に描画される可能性が高い場合に有効な戦略です。

バッファ オブジェクトのサイズを動的に変更することはできません。できることは、より大きなバッファーを事前に割り当て、その一部を更新することです。適切なサイズのバッファーを多数用意し、動的に満たすことは、実行可能な戦略になる可能性があります。GL_ARB_copy_buffer (GL 3.1 以降のコアで、広く利用可能)もあることに注意してください。これにより、非常に効率的なサーバー側のコピーが可能になりrealloc、新しいバッファーを割り当てて古い内容をコピーすることで、" " の動作をエミュレートすることもできます。

どの戦略が最適かは、常に状況によって異なります。オブジェクトを動的にロードまたは破棄することが多い場合は、いくつかの複雑なバッファー割り当ておよび管理戦略を使用すると効果がある場合があります。

于 2014-05-18T16:39:46.533 に答える