6

OpenGLESの学習中にiPhoneSDKのGLSpriteの例を少し変更しましたが、かなり遅いことがわかりました。シミュレーターでも(最悪の場合)、テクスチャーのある三角形が400個しかないので、何か間違ったことをしているに違いありません。

const GLfloat spriteVertices[] = {
  0.0f, 0.0f, 
  100.0f, 0.0f,  
  0.0f, 100.0f,
  100.0f, 100.0f
};

const GLshort spriteTexcoords[] = {
  0,0,
  1,0,
  0,1,
  1,1
};

- (void)setupView {
    glViewport(0, 0, backingWidth, backingHeight);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    glOrthof(0.0f, backingWidth, backingHeight,0.0f, -10.0f, 10.0f);
    glMatrixMode(GL_MODELVIEW);

    glClearColor(0.3f, 0.0f, 0.0f, 1.0f);

    glVertexPointer(2, GL_FLOAT, 0, spriteVertices);
    glEnableClientState(GL_VERTEX_ARRAY);
    glTexCoordPointer(2, GL_SHORT, 0, spriteTexcoords);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);

    // sprite data is preloaded. 512x512 rgba8888   
    glGenTextures(1, &spriteTexture);
    glBindTexture(GL_TEXTURE_2D, spriteTexture);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, spriteData);
    free(spriteData);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glEnable(GL_TEXTURE_2D);
    glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
} 

- (void)drawView {
  ..
    glClear(GL_COLOR_BUFFER_BIT);
    glLoadIdentity();
    glTranslatef(tx-100, ty-100,10);
    for (int i=0; i<200; i++) { 
        glTranslatef(1, 1, 0);
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
    }
  ..
}

drawViewは、画面がタッチされるか、画面上の指が動かされ、tx、tyがそのタッチが発生したx、y座標に設定されるたびに呼び出されます。

また、翻訳が事前に生成され、DrawArrayが1つしかないが、同じパフォーマンス(〜4 FPS)が得られたときに、GLBufferを使用してみました。

===編集===

一方、これを変更して、はるかに小さいクワッド(サイズ:34x20)が使用され、オーバーラップがはるかに少なくなるようにしました。画面全体に最大400個のクワッド->800個の三角形が広がっています。テクスチャサイズは512x512アトラスとRGBA_8888で、テクスチャ座標はフロートです。このコードは、APIの効率の点で非常に醜いです。2つのMatrixModeの変更と、2つのロードと2つの変換、そして三角ストリップ(クワッド)のdrawarrayがあります。現在、これにより最大45FPSが生成されます。

4

5 に答える 5

19

(これは非常に遅いことは知っていますが、抵抗できませんでした。他の人がアドバイスを求めてここに来る場合に備えて、とにかく投稿します。)

これはテクスチャサイズとは何の関係もありません。なぜ人々がニルスを評価したのか分かりません。彼はOpenGLパイプラインについて根本的な誤解を持っているようです。彼は、特定の三角形について、テクスチャ全体がロードされ、その三角形にマッピングされると考えているようです。反対のことが当てはまります。

三角形がビューポートにマッピングされると、ラスタライズされます。三角形がカバーする画面上のピクセルごとに、フラグメントシェーダーが呼び出されます。デフォルトのフラグメントシェーダー(使用しているOpenGL ES 1.1)は、描画しているピクセルに最も近い(GL_NEAREST)マッピングを行うテクセルを検索します。最高のテクセルを平均化するために高品質のGL_LINEARメソッドを使用しているため、4つのテクセルを検索する可能性があります。それでも、三角形のピクセル数がたとえば100の場合、読み取る必要のあるテクスチャバイトのほとんどは4(ルックアップ)* 100(ピクセル)* 4(色あたりのバイト数です。ニルスが言っていたものよりはるかに少ないです。彼が実際に彼が話していることを知っているように聞こえさせることができるのは驚くべきことです。

タイルアーキテクチャのWRT。これは、参照の局所性を維持するために、組み込みのOpenGLデバイスで一般的です。各タイルは各描画操作にさらされ、ほとんどのタイルをすばやくカリングすると思います。次に、タイルはそれ自体に何を描画するかを決定します。ブレンディングをオンにすると、これははるかに遅くなります。他のタイルと重なって混ざり合う可能性のある大きな三角形を使用しているため、GPUは多くの追加作業を行う必要があります。アルファエッジのある正方形の例をレンダリングする代わりに、(形状の正方形の画像の代わりに)実際の形状をレンダリングする場合は、シーンのこの部分のブレンドをオフにできます。これにより、処理が高速化されると思います。ものすごい。

試してみたい場合は、ブレンドをオフにして、見栄えが悪くても、どれだけスピードアップするかを確認してください。glDisable(GL_BLEND);

于 2010-03-28T07:31:20.643 に答える
3

テクスチャは 512*512*4 バイト/ピクセルです。それはメガバイトのデータです。フレームごとに 200 回レンダリングすると、フレームごとに 200 メガバイトの帯域幅負荷が発生します。

約 4 fps の場合、テクスチャの読み取りだけで 800 mb/秒を消費します。フレームと Zbuffer の書き込みにも帯域幅が必要です。次に、CPU があります。ディスプレイの帯域幅要件も過小評価しないでください。

組み込みシステム (iPhone など) の RAM は、デスクトップ PC ほど高速ではありません。ここに見られるのは、帯域幅不足の影響です。RAM は単にデータをより速く処理することはできません。

この問題を解決する方法:

  • 適切なテクスチャサイズを選択してください。平均して、1 ピクセルあたり 1 テクセルが必要です。これにより、鮮明なテクスチャが得られます。私は知っています-それは常に可能であるとは限りません。常識を働かせてください。

  • ミップマップを使用します。これは余分なスペースの 33% を占有しますが、可能であればグラフィック チップがより低い解像度のミップマップを選択できるようにします。

  • 小さいテクスチャ形式を試してください。おそらく、ARGB4444 形式を使用できます。これにより、レンダリング速度が 2 倍になります。圧縮されたテクスチャ形式も見てください。解凍はハードウェアで行われるため、パフォーマンスが低下することはありません。実際にはその逆です。メモリのサイズが小さいため、グラフィック チップはテクスチャ データをより速く読み取ることができます。

于 2009-01-16T11:04:53.377 に答える
2

私の最初の試みは、悪い(または非常に良い)テストだったと思います。iPhone には、タイル ベースのグラフィック プロセッサを搭載した PowerVR MBX Lite が搭載されています。画面を小さなタイルに分割し、それらを平行にレンダリングします。上記の最初のケースでは、オーバーラップが非常に高いため、サブディビジョンが少し使い果たされた可能性があります。さらに、距離が同じであるためクリップできず、すべてのテクスチャ座標を計算する必要がありました (これは、ループ内の移動を変更することで簡単にテストできます)。また、オーバーラップが原因で、並列処理を利用できず、一部のタイルは何もせずに座っていて、残り (1/3) は多くの作業を行っていました。

したがって、メモリ帯域幅がボトルネックになる可能性はありますが、この例ではそうではありませんでした。グラフィックス ハードウェアの動作とテストのセットアップが原因で、問題はさらに大きくなります。

于 2009-02-03T10:39:47.310 に答える
0

私は iPhone に詳しくありませんが、浮動小数点数を処理するための専用ハードウェアがない場合 (そうではないのではないかと思います)、可能な限り整数を使用する方が高速です。

現在、Android (OpenGL ES も使用) 用に開発しています。たとえば、頂点配列は float ではなく int です。どれだけ違うかはなんとも言えませんが、試してみる価値はあると思います。

于 2009-02-03T01:10:36.210 に答える
0

Apple は iPhone の特定のハードウェア仕様について非常に固く口を閉ざしているが、これはコンソールのバックグラウンドを持つ私たちにとって非常に奇妙に思える。しかし、人々は、CPU が 32 ビット RISC ARM1176JZFであると判断できました。良いニュースは、完全な浮動小数点ユニットを備えているため、ほとんどのプラットフォームで行っている方法で数学と物理のコードを書き続けることができることです。

http://gamesfromwithin.com/?p=239

于 2009-02-03T06:23:35.953 に答える