0

OpenGLで動的に動くオブジェクトを描画するための最良のアプローチは何ですか?

現在、私は次のようにやっています: 私は class を持っておりActor、そのコンストラクターでバッファーを生成します:

Actor::Actor(float x, float y): xpos(x),
                                ypos(y),
                                width(1),
                                height(1) {
    glGenBuffers(1, &buffer);
}

他のすべての処理はすべてのフレームで行われます。

for(auto const &a: actors) {

    float x =  (a.xpos / tiles_x) * 2 - 1.0f + (1 / tiles_x);
    float y = -((a.ypos / tiles_y) * 2 - 1.0f + (1 / tiles_y));
    float w = a.width / (tiles_x);
    float h = a.height / (tiles_y);

    const GLfloat vertex[] {
        x - w, y - h, 1.0f,
        x - w, y + h, 1.0f,
        x + w, y + h, 1.0f,
        x - w, y - h, 1.0f,
        x + w, y - h, 1.0f,
        x + w, y + h, 1.0f,

    };

    glBindBuffer(GL_ARRAY_BUFFER, a.buffer);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertex), vertex, GL_STATIC_DRAW);

    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0,
                          3,
                          GL_FLOAT,
                          GL_FALSE,
                          0,
                          (void*)0);

    glDrawArrays(GL_TRIANGLES, 0, 6);
    glDisableVertexAttribArray(0);
}

私は OpenGL の専門家ではありませんが、かなり効率が悪いように思えます。これには、別のより効率的な方法はありませんか?

4

2 に答える 2

4

非推奨の方法は、glTransform を使用することです。より良い方法は、シェーダーを使用することです。

フレームごとにすべての頂点を GPU に送信する必要はありません。非効率的であるというあなたの仮定は正しいです。アクターを作成するときは、メッシュを 1 回作成し、すべての頂点をグラフィックス カードに送信します。その後、描画フレームごとに、バッファをバインドして glDrawArrays を呼び出すだけです。このようなもの。

変換を適用するには、x、y、z オフセットを頂点シェーダーに送信し、頂点に対して乗算します。このサイトでは、廃止されていない opengl 機能を使用してこれを行う方法について、いくつかの優れたチュートリアルを提供しています。

于 2013-06-12T19:56:31.247 に答える
2

頂点をすべて同じ方法で変換する場合、フレームごとに再計算される 4x4 変換マトリックスの均一変数のみを渡します。

頂点を個別に変更する必要がある場合は、属性配列を変更してフレームごとにアップロードする必要がありますが、オプションの使用を検討する必要がありますGL_DYNAMIC_DRAW。もう少し明確にするために、bufferData - 使用パラメーターの違いを参照してください。

お役に立てれば。

于 2013-06-12T19:46:17.870 に答える