2009-08-12 9 views
1

iPhone上に2Dのタイル張りの背景システムを作りたいと思います。タイルマップとタイルセットイメージを取り込んで画面上のフルマップに変換するもの。OpenGL ESを使用してiPhone上にタイル張りの背景

私の最初のアプローチは、各タイルのポリゴンを作成することでした。これは400ポリゴンでテストを開始するまでうまくいき、非常に遅く動作し始めました。私はちょうど不思議に思っています - いくつかのポリゴンのこの方法は、行く方法ではありませんか?それとも私は何か間違っているのですか?後でコードを投稿するつもりですが、私の主な質問は「400個の小さなポリゴンがiPhone上でゆっくりと動くのか、それとも間違っているのか」ということです。

は、私はまた、初期化時に、タイルマップ/タイルセットのうちのコードでマップテクスチャを作成し、一つの大きなポリゴンにそれを固執することだった別の方法を検討しました。そうですね...このようなことについてどうすればいいのですか?

私は誰かがこれを言及することを知っています - 私はcocos2dを試して考慮しましたが、私はそのルートに行かない理由があります。

+0

問題を特定するには、さらに詳しい情報が必要です。それぞれの異なるタイルイメージはロードされ、Open GLに1度だけテクスチャとして渡されますか?同様のタイルは同じテクスチャリソースを共有しますか?これらのタイルテクスチャイメージのサイズはどれくらいですか?いくつのタイルテクスチャがありますか?あなたはテクスチャをプリロードしていますか、それとも即座にロードしていますか? –

+0

申し訳ありませんが、明確ではありませんでした。 私がテストしたものが遅かったことについて具体的に説明します: 初期化時には、大規模な(2048x2048)タイルセットイメージをPVRTextureクラス(Apple提供)としてロードします。また、initの間に、すべてのタイル頂点を1つの配列に作成します。その後、ループの最中に、テクスチャをバインドして大きな頂点配列のglDrawArraysを呼び出します。 –

答えて

0

Scott、TexParameter設定はテクスチャごとに1回だけ行う必要があります。しかし、それはあなたの減速の原因ではありません。

インデックスのリストを作成し、タイルのセット全体に対してglDrawArraysを一度呼び出すほうがずっと良いでしょう。頂点配列の目標は、1つのステップでできるだけ多くを描画できるようにすることです。

glDrawTexは、非常に非効率的な1組のマインドセットにあなたを強制するので、避けてください。

+0

ありがとうございました。私は、1回のglDrawArraysコールですべてを完了させる方法がなければならないことを知っていました。いくつかの研究の後、私はGL_QUADSを使用するだけで、別のポリゴンを作成することがわかります。私は私のマックから離れていますが、私は後でこれをテストします。 –

+0

GL_QUADSはESではサポートされていません。三角形のペアを使用する必要があります。この使用例では、FANやSTRIPを試しても構いません。 – Frogblast

+0

あなたはそうです、私は "クワッド"をシミュレートするためのカップルの三角形を書くことになりました。どうもありがとう。私は今それを得て、それはかなり良いと思われる、減速はほとんどなくなっている。 –

0

glDrawTex拡張子を使用することも可能です。

0

Stanford iTune Universityには、OpenGL for iPhoneの最適化に関するポッドキャストがあります。

しかし、基本的な考え方は以下のとおりです。

  1. バッチジオメトリ、単一の大きな頂点配列に様々な頂点配列を組み合わせます。これは、xの数を減らす必要がありますポインタは、単一のglポインタ呼び出しを呼び出します。

  2. テクスチャアトラスは、すべての異なるタイルのための単一のテクスチャを使用して、地域であることの違いは、各タイルに使用します。すべてのタイル描画のテクスチャにバインドするだけです。単一のアレイ内の点の様々な部分(例えば、頂点、テクスチャ座標、色)を組み合わせる

  3. インターリーブアレイ、。これはgl * Pointer呼び出しを1回の呼び出しに減らすはずです。それが小さいほど、あなたが、geometeryについては、短期使用の代わりに、フロート可能な場合はジオメトリ情報

  4. を再利用することができ

  5. インデックス付き三角形、。

これは単なる一般的なOpenGL最適化のガイドラインです。タイルエンジンについては、よく。

  1. OpenGLにデータを送信する前に、独自のカリングを実行してください。あなたが描かないものは、保存します。

私はそれは私がこれまでの考えることができるものだと思います。

1

あなたの問題は、ほぼ400倍のテクスチャをバインドしていることがほぼ確実です。すべてのタイルを1つの大きなテクスチャアトラス/スプライトシートに入れ、テクスチャを再バインドするのではなく、アトラスを一度バインドして小さな部分を描画するだけです。これを行うと、実際に減速することなく何千ものタイルを描画できるはずです。

あなたはこのようなあなたのスプライトを描画することができます使用

//Push the matrix so we can keep it as it was previously. 
glPushMatrix(); 

//Store the coordinates/dimensions from a rectangle. 
float x = CGRectGetMinX(rect); 
float y = CGRectGetMinY(rect); 
float w = CGRectGetWidth(rect); 
float h = CGRectGetHeight(rect); 

float xOffset = x; 
float yOffset = y; 

if (rotation != 0.0f) 
{ 
    //Translate the OpenGL context to the center of the sprite for rotation. 
    glTranslatef(x+w/2, y+h/2, 0.0f); 

    //Apply the rotation over the Z axis. 
    glRotatef(rotation, 0.0f, 0.0f, 1.0f); 

    //Have an offset for the top left corner. 
    xOffset = -w/2; 
    yOffset = -h/2; 
} 

// Set up an array of values to use as the sprite vertices. 
GLfloat vertices[] = 
{ 
    xOffset, yOffset, 
    xOffset, yOffset+h, 
    xOffset+w, yOffset+h, 
    xOffset+w, yOffset, 
}; 

// Set up an array of values for the texture coordinates. 
GLfloat texcoords[] = 
{ 
    CGRectGetMinX(clippingRect), CGRectGetMinY(clippingRect), 
    CGRectGetMinX(clippingRect), CGRectGetHeight(clippingRect), 
    CGRectGetWidth(clippingRect), CGRectGetHeight(clippingRect), 
    CGRectGetWidth(clippingRect), CGRectGetMinY(clippingRect), 
}; 

//If the image is flipped, flip the texture coordinates. 
if (flipped) 
{ 
    texcoords[0] = CGRectGetWidth(clippingRect); 
    texcoords[2] = CGRectGetWidth(clippingRect); 
    texcoords[4] = CGRectGetMinX(clippingRect); 
    texcoords[6] = CGRectGetMinX(clippingRect); 
} 

//Render the vertices by pointing to the arrays. 
glVertexPointer(2, GL_FLOAT, 0, vertices); 
glTexCoordPointer(2, GL_FLOAT, 0, texcoords); 

// Set the texture parameters to use a linear filter when minifying. 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

//Allow transparency and blending. 
glEnable(GL_BLEND); 
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 

//Enable 2D textures. 
glEnable(GL_TEXTURE_2D); 

//Bind this texture. 
if ([Globals getLastTextureBound] != texture) 
{ 
    glBindTexture(GL_TEXTURE_2D, texture); 
} 

//Finally draw the arrays. 
glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 

//Restore the model view matrix to prevent contamination. 
glPopMatrix(); 

2 CGRectの私は簡単のためだけです。画像を描画するためのX、Y、幅、高さを指定することができます。また、clippingRectを使用して、描画する画像の位置を指定することもできます。クリッピング矩形では、(0、0、1、1)は画像全体ですが(0、0、0.25、0.25)は左上隅を描画するだけです。クリッピング矩形を変更することで、さまざまな種類のタイルを同じテクスチャにまとめることができます。一度バインドするだけで済みます。道は安い。

0

私のアプリをスピードアップするために何をしましたか?私のレベルをロードした後だった。私はマップ上のタイルのアトラスを作成しました。そして、フレームごとに、カメラが動いたかどうかを確認します。それがしたら、私はglTranslatefを渡し、マップ全体を一度に移動します。動的オブジェクトだけがマップ上を移動する場合は、そのオブジェクトを頂点配列アトラスで更新します。このシステムは非常に効率的です。私はフレームレートの低下なしでたくさんのタイルを描くことができます。

0

クライアントの状態は、初期化時にのみ有効にする必要があります。また、テクスチャオブジェクトの作成時にglTexParameteri関数を呼び出す必要があります。 すべてのglEnable関数はキャッシュされません。つまり、すでにその値に設定されていても状態を設定します。 これらの小さなものはどれも足を伸ばして遅くすることがあります。

BR

関連する問題