2

私は、プレイステーション ネットワークのゲーム「Greed Corp」に触発された、初めての openGL ゲームに取り組んでいます。ヘックス グリッドに基づくターン ベースの戦略ゲームです。各六角形タイルには独自の高さとテクスチャがあります。

現在、読んだいくつかの例とチュートリアルに基づいて六角形を描いています。これが私のヘクタイルクラスです:

public class HexTile
{
    private float height;

    private int[] textures = new int[1];

    private float vertices[] = {     0.0f,   0.0f, 0.0f,    //center
                                     0.0f,   1.0f, 0.0f,    // top
                                    -1.0f,   0.5f, 0.0f,    // left top
                                    -1.0f,  -0.5f, 0.0f,    // left bottom
                                     0.0f,  -1.0f, 0.0f,    // bottom
                                     1.0f,  -0.5f, 0.0f,    // right bottom
                                     1.0f,  0.5f, 0.0f,     // right top
    };

    private short[] indices = {      0, 1, 2, 3, 4, 5, 6, 1};

    //private float texture[] = { };

    private FloatBuffer vertexBuffer;
    private ShortBuffer indexBuffer;
    //private FloatBuffer textureBuffer;    

    public HexTile()
    {
        ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
        vbb.order(ByteOrder.nativeOrder());
        vertexBuffer = vbb.asFloatBuffer();
        vertexBuffer.put(vertices);
        vertexBuffer.position(0);

        ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
        ibb.order(ByteOrder.nativeOrder());
        indexBuffer = ibb.asShortBuffer();
        indexBuffer.put(indices);
        indexBuffer.position(0);

        /*ByteBuffer tbb = ByteBuffer.allocateDirect(texture.length * 4);
        tbb.order(ByteOrder.nativeOrder());
        textureBuffer = tbb.asFloatBuffer();
        textureBuffer.put(texture);
        textureBuffer.position(0);*/
    }

    public void setHeight(float h)
    {
        height = h;
    }
    public float getHeight()
    {
        return height;
    }

    public void draw(GL10 gl)
    {
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        //gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);

        gl.glDrawElements(GL10.GL_TRIANGLE_FAN, indices.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
    }

    public void loadGLTexture(GL10 gl, Context context)
    {
        textures[0] = -1;
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.hex);

        while(textures[0] <= 0)
            gl.glGenTextures(1, textures, 0); 

        gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);

        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);

        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
    }
}

フレームごとに、表示されているすべてのタイルをループして描画します。これは、最大 11 * 9 タイルになります。ただし、これによりフレームレートが 38 に低下します。これは、テクスチャを描画することさえせず、平らな六角形だけです。

現在、どうすればパフォーマンスを向上させることができるかを考えています。グリッド全体を一度に描画する方が高速であると考えましたが、各タイルの高さが異なる可能性があり、隣接するタイルとはテクスチャが異なる可能性が高いため、その方法がわかりません。

実際のゲームを始めたいので、これについて何か助けていただければ幸いです ^.^

4

2 に答える 2

1

16 進グリッドが静的であると仮定すると、すべての六角形を 1 回スピンし、それらのジオメトリを生成し、一度に描画できる 1 つ (または 2^16 を超える頂点がある場合は複数) の大きな VBO にすべてを追加できます。

テクスチャに関する限り、テクスチャ アトラスを使用できる場合があります。

于 2011-06-06T19:09:57.797 に答える
0

私は現在 OpenGL も学習しています。「Cloud Stream」と呼ばれる 1 つの Android OpenGL アプリケーションを作成しましたが、パフォーマンスに関して同様の問題が見つかりました。

パフォーマンスの問題に対する一般的な回答として、役立つことがいくつかあります。ハードウェア レベルでのグラフィックスの Vertex パイプラインは、一度に大量の頂点を渡すと明らかに効率的になります。Hex タイルごとに glVertexPointer を呼び出すのは、すべてのタイルの頂点で 1 回呼び出すほど効率的ではありません。

これにより、基本的にすべてのタイルを一度に描画するため、コーディングが難しくなりますが、少しスピードアップするようです. 私のアプリケーションでは、すべての雲が 1 回の呼び出しで描画されます。

Vertice の位置を VBO に保存する方法もありますが、少なくとも 2.1 ユーザーに対応しようとしたときは非常に難しいことがわかりました。最近はもっと簡単かもしれませんが、よくわかりません。これにより、タイルの Vertice 配列をビデオ メモリに保存し、テクスチャの場合と同様にポインターを取得することができます。ご想像のとおり、Vertice Array Buffer を各フレームに送信しないと、各タイル描画の速度が少し速くなります。物事が静的でなくても、フレームごとに変化しているとは思えないので、良いアプローチです。

私がオンラインで見つけたもう 1 つの提案は、Vertices に Float の代わりに Short を使用することでした。次に、完成したレンダリングのスケールを変更して、目的のサイズにします。これにより、頂点のサイズが小さくなり、速度が少し上がります...大量ではありませんが、試してみる価値はあります。

最後に追加したいのは、透明度を使用することになった場合...それが機能するには、パフォーマンスに影響を与えるために背面から前面にペイントする必要があることに注意してください。前から後ろに描画すると、レンダリング エンジンは、座標が表示されていないときに描画しないことを自動的に認識します...後ろから前に描画すると、すべてが描画されます。このことを念頭に置いて、可能な限り前から後ろに描くようにしてください。

あなたのゲームで頑張ってください。あなたがどのようにうまくいったか知りたいです... 私はゲームを始めたばかりで、始めるのがとても楽しみです。まだこれに出くわしていない場合は... 一読の価値があると思います。 http://www.codeproject.com/KB/graphics/hexagonal_part1.aspx

于 2011-12-29T21:18:03.423 に答える