OpenGL优化

1 c++ windows opengl

我正在尝试使用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;
}
Run Code Online (Sandbox Code Playgroud)

我在控制台中得到以下结果:

-- 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
Run Code Online (Sandbox Code Playgroud)

如您所见,第二个四边形的绘图需要很长时间(164ms).我不知道为什么会这样,因为他们都是四边形.我还检查了纹理(如果相关),但它比bg(第一个四边形)小很多.如果它有任何相关性,我认为第一个四边形应该画得更长,而不是第二个.

我对OpenGL相当陌生(过去我做了很多opengl,但只是初学者)所以我对我正在做的事情有所了解.我只是不确定如何进一步优化它以删除164ms进程.

如何删除或最小化164ms进程?

我必须注意到我使用Intel Atom和intel GMA 450机器.

Nic*_*las 5

让我们假设这个神秘的ELAPSED_MS宏是一个周期精确的CPU计数器.我很怀疑它是,因为它似乎以大毫秒的增量跳跃,但让我们假装是这种情况.

您分析OpenGL的方法是完全错误的.您没有测量渲染四边形所需的时间.您正在测量glFinish完成所需的时间.无法保证glFinish在四边形完成渲染时返回.实际上,它可能会等待很长一段时间,可能是一个线程任务切换或其他东西.谁知道.

关键是您的分析方法不可靠.请停止使用它们.获取OpenGL中实际渲染操作的分析数据的唯一准确方法是使用定时器查询(专门用于测试GPU完成操作所需的时间)或使用专有扩展.

微观剖析(如描绘绘制四边形所需的时间)很难做到正确.特别是四画图通常对于打扰剖析一文不值.

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

那没有用.因为即使你的方法是好的,clock不是做任何形式的时机的可靠方法.您必须使用特定平台的调用,或者使用平台中立库,如C++ 11的计时器(或等效的Boost).