1

OpenGLを使用して3つのクワッド(1 bg、2つのスプライト)をレンダリングしようとしています。私は次のコードを持っています:

void GLRenderer::onDrawObjects(long p_dt)
{
    float _log_last_time = ELAPSED_MS;
    fprintf(stdout, "-- starting draw: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time);

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    for(std::vector<queuedRenderable*>::iterator itr = m_displayList.begin();
        itr != m_displayList.end();
        itr++)
    {
        Sprite* spriteToRender = (*itr)->m_sprite;

        float _log_last_time1 = ELAPSED_MS;
        fprintf(stdout, "---- profiling object: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time1);

        glMatrixMode( GL_MODELVIEW );
        glLoadIdentity();

        // glTranslate, glRotate, glScale goes here

        fprintf(stdout, "---- transform done: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time1);
        _log_last_time1 = ELAPSED_MS;

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, (*itr)->m_material->m_glId);

        fprintf(stdout, "---- set material done: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time1);
        _log_last_time1 = ELAPSED_MS;

        unsigned listIds[] = {
            (*itr)->m_mesh->m_glId
        };
        glCallLists(1, GL_UNSIGNED_INT, listIds);

        fprintf(stdout, "---- draw mesh done: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time1);
        _log_last_time1 = ELAPSED_MS;
    }

    fprintf(stdout, "-- flushing to card: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time);
    _log_last_time = ELAPSED_MS;

    glFlush();
    glFinish();

    fprintf(stdout, "-- flush done: %.4f, dTime: %.4f\n", ELAPSED_MS, ELAPSED_MS - _log_last_time);
    _log_last_time = ELAPSED_MS;
}

そして、コンソールで次の結果が得られます。

-- starting draw: 24000.0000, dTime: 0.0000
---- profiling object: 24014.0000, dTime: 0.0000
---- transform done: 24033.0000, dTime: 19.0000
---- set material done: 24046.0000, dTime: 0.0000
---- draw mesh done: 24066.0000, dTime: 1.0000
---- profiling object: 24084.0000, dTime: 0.0000
---- transform done: 24102.0000, dTime: 18.0000
---- set material done: 24120.0000, dTime: 0.0000
---- draw mesh done: 24305.0000, dTime: 164.0000
---- profiling object: 24319.0000, dTime: 0.0000
---- transform done: 24338.0000, dTime: 19.0000
---- set material done: 24356.0000, dTime: 0.0000
---- draw mesh done: 24375.0000, dTime: 2.0000
-- flushing to card: 24389.0000, dTime: 389.0000
-- flush done: 24424.0000, dTime: 18.0000

ご覧のとおり、2番目のクワッドの描画には非常に長い時間がかかります(164ms)。それらはすべてクワッドであるため、なぜだかわかりません。テクスチャもチェックしましたが(関連する場合)、bg(第1クワッド)よりもはるかに小さいです。関連性がある場合は、最初のクワッドは2番目のクワッドではなく、より長く描画する必要があると思います。

私はOpenGLにかなり慣れていないので(過去に多くのopenglを実行しましたが、初心者向けのものです)、自分が何をしているのかについてある程度理解しています。164msのプロセスを削除するために、これをさらに最適化する方法がわかりません。

その164msプロセスを削除または最小化するにはどうすればよいですか?

IntelGMA450マシンでIntelAtomを使用していることに注意する必要があります。

4

1 に答える 1

5

ELAPSED_MSこの不思議なマクロがサイクル精度のCPUカウンターだったとしましょう。ミリ秒単位で大きくジャンプしているように見えるので、疑わしいですが、そうだとしましょう。

OpenGLをプロファイリングするための方法論は完全に間違っています。クワッドのレンダリングにかかる​​時間を測定していません。完了するまでにかかる時間を測定していますglFinishglFinishクワッドがレンダリングを終了した瞬間に戻るという保証はありません。確かに、おそらくスレッドタスクの切り替えなどのために、かなり長い間待っている可能性があります。知るか。

重要なのは、プロファイリングの方法が信頼できないということです。使用を中止してください。OpenGLで実際のレンダリング操作のプロファイリングデータを取得する唯一の正確な方法は、タイマークエリ(GPUでの操作が完了するまでにかかる時間をテストするように特別に設計されています)を使用するか、独自の拡張機能を使用することです。

マイクロプロファイリング(クワッドの描画にかかる時間のプロファイリングなど)を正しく行うことは非常に困難です。特にクワッド描画は、一般的にプロファイリングを行う価値がありません。

ELAPSED_MSは((((float)clock())/ CLOCKS_PER_SEC)* 1000.0f)

それはあまり役に立たない。あなたの方法が良かったとしても、どんな形のタイミングでも行うための信頼できる方法でclockないからです。プラットフォーム固有の 呼び出し、またはC ++ 11のクロノ(または同等のBoost)のようなプラットフォームニュートラルライブラリのいずれかを使用する必要があります。

于 2012-10-26T04:14:04.893 に答える