Высокая загрузка ЦП при отрисовке сцены gl; источник?

Поскольку меняется только размер окна, нормально ли, что моей программе требуется одно полное ядро ​​для рендеринга сцены в развернутом окне?

Я использую Qt 4.7 на языке C++ в окнах для рисования 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);

После некоторого бенчмаркинга кажется, что высокая загрузка ЦП связана с блоком «//draw texture». На самом деле, иногда это занимает 0 мс, а иногда и 400 мс. В целом, функция paintGL занимает 5 секунд для рендеринга сцены, когда окно развернуто, и близко к 0, когда окно имеет размер 800*600.
Я изменяю масштаб во время рендеринга (изменяя только _globalScale), чтобы я мог увидеть 150 изображений независимо от размера окна. Масштаб изображений никак не влияет на загрузку процессора.

Я начал использовать OpenGL 2 недели назад, поэтому наверняка что-то пропустил в документации и туториалах... но даже если я перечитал их снова , я не нахожу ни объяснения, ни другого способа отрендерить эти 150 картинок.
В будущем можно будет модифицировать картинку (точнее слой этой картинки, что подразумевает больше текстур) с графическим планшет или даже мышь, поэтому мне нужно улучшение скорости.


person Aigrefin    schedule 26.10.2011    source источник
comment
Сколько оперативной памяти у вашего графического процессора?   -  person genpfault    schedule 26.10.2011
comment
@genpfault 256 МБ, это GeForce 6800   -  person Aigrefin    schedule 26.10.2011
comment
Мой плохой, я пробовал с меньшим количеством текстур. У меня такие проблемы с более чем 27 несжатыми текстурами в памяти, что составляет 235 МБ. Я использую слишком много памяти. Я действительно не знаю, как отобразить эти 150 изображений одновременно, и в то же время иметь возможность видеть одно в полном разрешении, если коэффициент масштабирования был увеличен. медленный рендеринг, если мы хотим видеть изменения, отображаемые в реальном времени?   -  person Aigrefin    schedule 26.10.2011


Ответы (1)


Загружайте уменьшенные версии изображений для быстрого рендеринга и уменьшения нагрузки на память. Затем, когда вы увеличиваете масштаб определенного подмножества изображений, вы можете загрузить изображения с полным разрешением и отобразить их вместо текстур с низким разрешением.

person genpfault    schedule 26.10.2011
comment
Хорошо, я начал делать это. У меня есть еще один вопрос, потому что у меня все еще есть проблемы с производительностью: быстрее ли запрашивать изображение с более низким уменьшением mimap при вызове glTexImage2D (уровень GLuint в x) или загружать уменьшенную копию изображения (уровень GLuint в 0)? - person Aigrefin; 26.10.2011
comment
Вы можете использовать смещение LOD текстуры только для выборки загруженных уровней MIP, но я думаю, что OpenGL по-прежнему выделяет память для полной текстуры со всеми уровнями MIP. Так что прикрепляйте изображения с низким разрешением к своим собственным объектам текстуры (с мип-маппингом или без, это не сильно повлияет на использование памяти) и имейте пул идентификаторов текстур (может быть, 5-10, с мип-мэппингом или без), которые вы можете перезагрузить через glTexSubImage2D() с вашим высоким разрешением. res изображения, когда ваш взгляд перемещается. Как правило, вы хотите избежать повторного создания текстур с помощью glTexImage2D(), так как это может быть медленнее, чем glTexSubImage2D(). - person genpfault; 26.10.2011
comment
Большое спасибо, все работает, как и ожидалось. Мне по-прежнему приходится создавать текстуры каждый раз, когда я меняю их разрешение, так как glTexSubImage2D() применяется только к части текстуры (и мне нужно изменить все). Но с этим методом все работает достаточно гладко. - person Aigrefin; 01.11.2011