【问题标题】:Heavy CPU usage when draw gl scene; origin?绘制 gl 场景时 CPU 使用率高;起源?
【发布时间】:2011-10-26 12:00:30
【问题描述】:

由于只有窗口的大小会发生变化,我的程序需要一个完整的核心来在最大化的窗口上渲染场景是否正常?

我在 Windows 上使用 C++ 语言中的 Qt 4.7 来绘制 150 张这些尺寸的图片(组件是 RGBA,每个都在一个字节上):1754*1240。 我像这样加载我的纹理:

glGenFramebuffers(TDC_NB_IMAGE, _fborefs);
glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
//initialize tex
glGenTextures(TDC_NB_IMAGE, _picrefs);
for (int i = 0 ; i < TDC_NB_IMAGE ; i++)
{
    qDebug() << "loading texture num : " << i;
    _pics[i].scale = 1.f;
    _pics[i].pos.rx() = i % ((int)sqrt((float)TDC_NB_IMAGE));
    _pics[i].pos.ry() = i / ((int)sqrt((float)TDC_NB_IMAGE));
    _pics[i].text.load("imgTest.png");
    glBindTexture(GL_TEXTURE_2D, _picrefs[i]);
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
    glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);//GL_LINEAR_MIPMAP_LINEAR
    glTexImage2D (GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,
        TDC_IMG_WIDTH, TDC_IMG_HEIGHT, 0, GL_BGRA_EXT, GL_UNSIGNED_BYTE,
        _pics[i].text.toImage().bits()
        );
    //glGenerateMipmap(GL_TEXTURE_2D);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _picrefs[i], 0);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);

我这样画我的场景:

glBindFramebuffer(GL_FRAMEBUFFER, _fbo);
glClear( GL_COLOR_BUFFER_BIT);
//for each image
for (int i = 0 ; i < TDC_NB_IMAGE ; i++)
{
    //compute coords
    if (_update)
    {
        //pos on 0,0
        _pics[i].quad.topleft.rx() = 0;
        _pics[i].quad.topleft.ry() = 0;
        _pics[i].quad.topright.rx() = TDC_IMG_WIDTH;
        _pics[i].quad.topright.ry() = 0;
        _pics[i].quad.botright.rx() = TDC_IMG_WIDTH;
        _pics[i].quad.botright.ry() = TDC_IMG_HEIGHT;
        _pics[i].quad.botleft.rx() = 0;
        _pics[i].quad.botleft.ry() = TDC_IMG_HEIGHT;
        //translate
        QPointF dec(0, 0);
        dec.rx() = _pics[i].pos.x() * TDC_IMG_WIDTH + _pics[i].pos.x() * TDC_SPACE_IMG;
        dec.ry() = _pics[i].pos.y() * TDC_IMG_HEIGHT + _pics[i].pos.y() * TDC_SPACE_IMG;
        _pics[i].quad.topleft += dec;
        _pics[i].quad.topright += dec;
        _pics[i].quad.botright += dec;
        _pics[i].quad.botleft += dec;
        //scale
        _pics[i].quad.topleft *= _globalScale;
        _pics[i].quad.topright *= _globalScale;
        _pics[i].quad.botright *= _globalScale;
        _pics[i].quad.botleft *= _globalScale;
        _update = false;
    }
    //prepare tex drawing
    //draw drawing area
    glBindTexture (GL_TEXTURE_2D, 0);
    glBegin (GL_QUADS);
    glTexCoord2f (0.0, 0.0);glVertex3f (_pics[i].quad.topleft.x(), _pics[i].quad.topleft.y(), 0);
    glTexCoord2f (1.0, 0.0);glVertex3f (_pics[i].quad.topright.x(), _pics[i].quad.topright.y(), 0);
    glTexCoord2f (1.0, 1.0);glVertex3f (_pics[i].quad.botright.x(), _pics[i].quad.botright.y(), 0);
    glTexCoord2f (0.0, 1.0);glVertex3f (_pics[i].quad.botleft.x(), _pics[i].quad.botleft.y(), 0);
    glEnd();
    //draw texture
    glBindTexture (GL_TEXTURE_2D, _picrefs[i]);
    glBegin (GL_QUADS);
    glTexCoord2f (0.0, 0.0);glVertex3f (_pics[i].quad.topleft.x(), _pics[i].quad.topleft.y(), 0);
    glTexCoord2f (1.0, 0.0);glVertex3f (_pics[i].quad.topright.x(), _pics[i].quad.topright.y(), 0);
    glTexCoord2f (1.0, 1.0);glVertex3f (_pics[i].quad.botright.x(), _pics[i].quad.botright.y(), 0);
    glTexCoord2f (0.0, 1.0);glVertex3f (_pics[i].quad.botleft.x(), _pics[i].quad.botleft.y(), 0);
    glEnd();
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);

经过一些基准测试,CPU 使用率似乎来自“//绘制纹理”块。实际上,有时需要 0 毫秒,有时需要 400 毫秒。总体来说,paintGL 函数在窗口最大化时渲染场景需要 5 秒,在窗口为 800*600 大小时接近 0。
我在渲染期间更改了比例(仅修改 _globalScale),因此无论窗口大小如何,我都可以看到 150 张图片。图片的比例不会改变 CPU 使用率。

我在 2 周前开始使用 OpenGL,所以我肯定错过了文档和教程中的一些内容。但即使我再次阅读它们,我也找不到任何解释或渲染这 150 张图片的其他方法。
将来可以用绘图板甚至鼠标来修改一张图片(更准确地说是这张图片的一层,这意味着更多的纹理),所以我需要提高速度。

【问题讨论】:

  • 你的 GPU 有多少 RAM?
  • @genpfault 256MB,这是 GeForce 6800
  • 我的错,我尝试使用较少的纹理。我对内存中超过 27 个未压缩纹理(代表 235MB)有这些问题。我正在使用太多内存。我真的不知道如何一次显示这 150 张图片,同时如果增加了比例因子,我能够以全分辨率看到一张。也许每次比例因子改变时我都应该加载足够的分辨率,但不是如果我们想实时查看渲染的变化,渲染速度会很慢吗?

标签: c++ windows opengl cpu-usage qt4.7


【解决方案1】:

加载图像的缩小版本以实现快速渲染和低内存压力。然后,当您放大图像的特定子集时,您可以加载全分辨率图像并显示这些图像而不是低分辨率纹理。

【讨论】:

  • 好的,我开始这样做了。我还有另一个问题,因为我仍然有性能问题:调用 glTexImage2D(x 的 GLuint 级别)时查询较低的 mimap 缩小图像是否更快,或者加载图片的缩小副本(0 的 GLuint 级别)?
  • 您可以使用纹理 LOD 偏差来仅对加载的 mipmap 级别进行采样,但我认为 OpenGL 仍然为具有所有 mip 级别的完整纹理分配内存。因此,将您的低分辨率图像粘贴到它们自己的纹理对象(无论是否经过 mipmap,不会对内存使用产生太大影响)并拥有一个纹理 ID 池(可能是 5-10,mipped 与否),您可以通过glTexSubImage2D() 重新加载您的当您的视图四处移动时,高分辨率图像。通常,您希望避免使用 glTexImage2D() 重新创建纹理,因为它可能比 glTexSubImage2D() 慢。
  • 非常感谢,它按预期工作。每次更改分辨率时,我仍然必须创建纹理,因为 glTexSubImage2D() 仅应用于纹理的一部分(我需要更改整体)。但是使用这种方法,一切都很顺利。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-10
  • 1970-01-01
  • 1970-01-01
  • 2014-03-14
相关资源
最近更新 更多