3

一度に 500 ~ 800 個のパーティクルをレンダリングする必要がある iOS ゲームを開発しています。glDrawArrays(..)フレーム レートを大幅に下げることなく、より多くのスプライトをレンダリングできるようにするには、ゲーム内のすべてのスプライト を呼び出すのではなく、OpenGL ES で多くのスプライトをバッチ レンダリングすることをお勧めします。

私の質問は次のとおりです。アルファ、回転、およびスケールがすべて異なるが、同じテクスチャ アトラスを共有する 500 以上のパーティクルをバッチレンダリングするにはどうすればよいですか? この質問の重点は、各パーティクルの異なる アルファ回転、およびスケールにあります。

この質問は、ゲームの速度を落とさずに iPhone OpenGL ES パーティクル システムで 1000 以上のパーティクル (独自の回転、スケール、およびアルファを使用) を描画するにはどうすればよいですか?と非常によく似ていることに気付きました。、ただし、その質問はバッチ レンダリングには対応していません。頂点バッファー オブジェクトを利用する前に、一意のアルファ、回転、スケール (ただしテクスチャは同じ) を使用した OpenGL ES でのバッチ レンダリングについて理解したいと思います。したがって、最終的には VBO を使用する予定ですが、最初はこのアプローチを採用したいと考えています。

コード例は大歓迎です。いくつかの例のようにインデックス配列を使用する場合は、インデックス配列の構造と目的を説明してください。

EDIT OpenGL ES 1.1を使用しています。

EDIT以下は、シーン内の各パーティクルをレンダリングする方法のコード例です。これらは同じテクスチャを共有しており、このコードが実行される前にテクスチャが OpenGL ES 1.1 で既にバインドされていると仮定します。

- (void) render {

    glPushMatrix();

    glTranslatef(translation.x, translation.y, translation.z);

    glRotatef(rotation.x, 1, 0, 0);
    glRotatef(rotation.y, 0, 1, 0);
    glRotatef(rotation.z, 0, 0, 1);

    glScalef(scale.x, scale.y, scale.z);

    // change alpha
    glColor4f(1.0, 1.0, 1.0, alpha);

    // glBindTexture(GL_TEXTURE_2D, texture[0]);

    glVertexPointer(2, GL_FLOAT, 0, texturedQuad.vertices);
    glEnableClientState(GL_VERTEX_ARRAY);


    glTexCoordPointer(2, GL_FLOAT, 0, texturedQuad.textureCoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glPopMatrix();
}

この方法に代わるコードを提供していただければ幸いです。

4

1 に答える 1

7

1 つの可能性は、これらの値を頂点属性配列に含めることです。これが最良の選択肢だと思います。OpenGL ES 2.0 ではなく 1.1 を使用している場合、この方法は失敗します。頂点属性配列を使用すると、各頂点に値を格納できます。この場合、アルファと回転をそれぞれ独自の属性配列に格納し、 を使用してシェーダーに渡すことができますglVertexAttribArray。その後、シェーダーはアルファを使用して回転変換と色処理を行います。

もう 1 つのオプションは、CPU で回転変換を実行してから、同様のアルファ値を持つパーティクルを複数の描画呼び出しにバッチ処理することです。このバージョンはもう少し作業が必要で、単一の描画呼び出しではありませんが、シェーダーがオプションでない場合でも最適化に役立ちます。

注:リンクした質問は、アレイソリューションも推奨しています

編集:ここでのコードが OpenGL ES 1.0 である場合、次を使用したソリューションを次に示しますglColorPointer

// allocate buffers to store an array of all particle data
verticesBuffer = ... 
texCoordBuffer = ...
colorBuffer = ...

for (particle in allParticles)
{
  // Create matrix from rotation
  rotMatrix = matrix(particle.rotation.x, particle.rotation.y, particle.rotation.z)
  // Transform particle by matrix
  verticesBuffer[i] = particle.vertices * rotMatrix

  // copy other data
  texCoordBuffer[i] = particle.texCoords;
  colorBuffer[i] = color(1.0, 1.0, 1.0, particle.alpha);
}

glVertexPointer(verticesBuffer, ...)
glTexCoordPointer(texCoodBuffer, ...)
glColorPointer(colorBuffer, ...)

glDrawArrays(particleCount * 4, ...);

このソリューションの適切な最適化は、フレームごとにバッファを再割り当てする必要がないように、各レンダリングのバッファを共有することです。

于 2012-08-03T00:52:06.810 に答える