绘制gl场景时CPU使用率高;起源?

发布于 2024-12-12 04:11:29 字数 3965 浏览 0 评论 0原文

由于除了窗口大小之外什么都没有变化,我的程序需要一个完整的核心来在最大化的窗口上渲染场景,这正常吗?

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

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 使用来自“//绘制纹理”块。实际上,有时需要 0ms,有时需要 400ms。总体而言,当窗口最大化时,paintGL函数需要5秒来渲染场景,而当窗口大小为800*600时,该时间接近于0。
我在渲染过程中更改了比例(仅修改 _globalScale),这样无论窗口大小如何,我都可以看到 150 张图片。图片的比例不会改变 CPU 使用率。

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

Since nothing but the size of the window evolve, is it normal my program needs one full core to render the scene on a maximized window ?

I'm using Qt 4.7 in the C++ language on windows to draw 150 pictures (components are RGBA, each on a byte) of those dimensions : 1754*1240.
I load my textures like this :

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);

I draw my scene like this :

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);

After some benchmarking, it seems the heavy CPU usage comes from the "//draw texture" block. Actually, sometimes it takes 0ms and sometimes 400ms. Overall, the paintGL function takes 5seconds to render the scene when the window is maximized, and close to 0 when the window is at 800*600 size.
I change the scale during the rendering (only modifying _globalScale) so i can see the 150 pictures whatever the size of the window. The scale of the pictures doesn't change anything to the CPU usage.

I started using OpenGL 2 weeks ago, so i surely missed something in the documentation and tutorials.. but even if i read them again, i don't find neither the explanation nor another way to render those 150 pictures.
In the future it will be possible to modify a picture (more precisely a layer of this picture, which implies more textures) with a graphic tablet or even the mouse, so i need the speed improvement.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笑着哭最痛 2024-12-19 04:11:30

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

Load scaled down versions of your images for fast rendering and low memory pressure. Then when you're zoomed in on a particular subset of images you can load the full-resolution ones and display those instead of the low-resolution textures.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文