Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: spbtellurian от Март 31, 2010, 14:15



Название: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 14:15
Есть класс окна (унаследован от QWidget ) занимающийся отрисовкой различной 2D графикой в том числе текста.
При наследовании окна отрисовки от QWidget загрузка CPU 3-5%

Посмотрев пример "2D Painting Example" ради эсперемента попробывал унаследоваться от QGLWidget.
Загрузка CPU сильно возросла !!. вместо 3-5% получил 35-37%

Почему у меня такие тормоза ???


Qt 4.3.3\WinXP\NVidia7900


Название: Re: Тормоза в QGLWidget
Отправлено: GreatSnake от Март 31, 2010, 14:19
Для начала не мешало бы обновить Qt.


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 14:32
Обновлять Qt по каждому чиху можно когда пишешь для себя
а когда есть целый вагон приложений разбросанных по всей стране то вопрос совместимости стоит более остро чем "свежеть" версии Qt

Однако хотелось бы по существу вопроса ::) Почему в отрисовка через QGLWidget оказалась значительно медленнее ???


Название: Re: Тормоза в QGLWidget
Отправлено: alexman от Март 31, 2010, 14:42
Если код (кроме наследования) не изменился, то скорее всего из-за взаимодействия Qt и OpenGL.


Название: Re: Тормоза в QGLWidget
Отправлено: GreatSnake от Март 31, 2010, 14:45
Цитировать
Обновлять Qt по каждому чиху можно когда пишешь для себя
а когда есть целый вагон приложений разбросанных по всей стране то вопрос совместимости стоит более остро чем "свежеть" версии Qt
Почитайте тогда это (http://doc.trolltech.com/qq/qq26-openglcanvas.html), может измените свое мнение.


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 14:48
Код один в один. Просто изменил название класса от котрого у наследвался.

посмотрел примерчик из QT SDK "2D Painting Example" вдохновился опсание мол QGLWidget ускоряет отрисовку 2D. А на практике то получается совесм наоборот.

Маленький примерчк "2D Painting Example" рисует одинаково что в QWidget что в QGLWidget а вот на релаьном дел у меня полный ахтунг получилось.


Название: Re: Тормоза в QGLWidget
Отправлено: alexman от Март 31, 2010, 14:52
Код один в один. Просто изменил название класса от котрого у наследвался.
А кто тогда будет функции
Код:
virtual void	initializeGL ()
virtual void paintGL ()
virtual void resizeGL ( int width, int height )
переопределять?


Название: Re: Тормоза в QGLWidget
Отправлено: alexman от Март 31, 2010, 14:54
посмотрел примерчик из QT SDK "2D Painting Example" вдохновился опсание мол QGLWidget ускоряет отрисовку 2D. А на практике то получается совесм наоборот.
Не может быть! Скорее всего что-то не очень хорошо спроектировано! :(


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 15:03
Цитата: alexman link=topic=13015.msg84014#msg84014
А кто тогда будет функции
[code
virtual void   initializeGL ()
virtual void   paintGL ()
virtual void   resizeGL ( int width, int height )
[/code]
переопределять?
Будет плесать от печки т.е. от QT SDK там есть примерчик "2D Painting Example". И там нет переопределений выше озвученных методов.


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 15:07
Не может быть! Скорее всего что-то не очень хорошо спроектировано! :(
Всё возможно. Вероятно мой код заточен под QWidget и для QGLWidget его надо модефицировать. Тогда возникает другой вопрос что и как ?

to ALL:
Кто сталкивался с подобным переносом отрисовки может подскажет какие есть грабли ?


Название: Re: Тормоза в QGLWidget
Отправлено: ieroglif от Март 31, 2010, 15:52
граблей много, почти все индивидуальны и проходятся исключительно на собственном опыте.


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 15:57
ну то что граблей млжет быть много это опнятно.
Вопрос в другом:
Кто сталкивается с проблемами производительности при переходе от QWidget к QGLWidget ?


Название: Re: Тормоза в QGLWidget
Отправлено: alexman от Март 31, 2010, 16:00
Трудный вопрос (сугубо индивидуально);)


Название: Re: Тормоза в QGLWidget
Отправлено: spbtellurian от Март 31, 2010, 16:04
Чегото я вас не понимаю привожу конкретный пример спрашиваю конкретный вопрос а вы всё какими то общими фразами...

Вот конкретно вы alexman и ieroglif сталкивались с описанной мной проблемой и если да то как решили ?


Название: Re: Тормоза в QGLWidget
Отправлено: ieroglif от Март 31, 2010, 18:33
Вот, конкретно, мы - иероглиф, писали (да и до сих пор под настроение пишем) 3д игру под огл при юзании qt.
итогом стало что что один и тот же код под линухом давал 25фпс, а под вендой = 60.
а уж сколько я там граблей то перекопал что бы убыстрить - и не вспомнишь.
понимаешь, несколько месяцев ковырялся в огле пытаясь соптимизировать код - так что граблей много, они индивидуальны, и рассказать про них можно только двумя фактами:
1. кури маны, читай книги по оглу, ковыряйся, пропуй писать примеры и т.д.
2. повторить п.1. пока всё на заработает на устраивающем тебя уровне.


Название: Re: Тормоза в QGLWidget
Отправлено: ieroglif от Март 31, 2010, 18:36
(ах да.. а на маке под 110фпс - вот и ковыряйся сколько влезет =) )


Название: Re: Тормоза в QGLWidget
Отправлено: break от Март 31, 2010, 22:16
Я ст олкнулся с такой задачей

потребовалось сделать так чтобы куча написанных окошек стали пропорционально ресайзится - то есть куча готовых форм, переводить их все на лайауты где их не было и следить за политикой ресайза - тоже вариант но он более трудоемок. Мне подсказали (http://www.prog.org.ru/topic_11996_0.html), что если использовать QGraphicScene и QGraphicView - то в эту сцену можно затолкать любой виджет и при этом уже там можно делать scale.

Все это заработало, появились артефакты (в Qt ошибку признали и даже однажды может исправят http://bugreports.qt.nokia.com/browse/QTBUG-7296) и жуткие тормоза. Я тоже решил это дело ускорить через OpenGL. И все ускорилось в разы, но при этом наткнулся на такую хрень: - часть моих окошек использовала QPixmap, часть QImage - все QPixmap перестали выводиться! А QImage в методе paint работает ( painter.drawImage ), если указывать картинку как фон заданием стайл-шита - тоже не работает...

вот мой код для вывода этих ресайзных виджетов...


ResizeGView.h
Код
C++ (Qt)
#ifndef __RESIZEGVIEW_H__
#define __RESIZEGVIEW_H__
 
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsProxyWidget>
#include <QTimer>
 
class CResizeGView : public QGraphicsView
{
Q_OBJECT;
QWidget * m_pWidget;
QTimer    m_tmDoResize;
 
public:
CResizeGView( QWidget * parent = 0 ) : QGraphicsView( parent )
{
m_pWidget = 0;
m_tmDoResize.setSingleShot( true );
m_tmDoResize.setInterval( 500 );
QObject::connect( &m_tmDoResize, SIGNAL(timeout()), this, SLOT(doResize()) );
}
virtual ~CResizeGView() {}
 
void setWidget( QWidget * pWidget )
{
m_pWidget = pWidget;
}
 
private:
virtual void resizeEvent ( QResizeEvent * pEvent )
{
m_tmDoResize.start();
}
 
private slots:
void doResize()
{
double fdW = (double)( size().width()-10 ) / (double)(m_pWidget->size().width());
double fdH = (double)( size().height()-10 ) / (double)(m_pWidget->size().height());
resetTransform();
scale( fdW, fdH );
}
};
 
#endif // __RESIZEGVIEW_H__
 

Код
C++ (Qt)
void showScaledWidget( QWidget * pWidget,
  bool bFullScreen,
  bool bScaled,
  int nScreenNum,
  QGraphicsScene * & pGScene,
  QGraphicsView * & pGView )
{
QWidget * pParentSCR = QApplication::desktop()->screen( nScreenNum );
 
if ( bScaled )
{
pGScene = new QGraphicsScene();
pGScene->addWidget( pWidget );
 
CResizeGView * pResizeGView = new CResizeGView( pParentSCR );
pResizeGView->setScene( pGScene );
pGView = pResizeGView; // возвращаем указатель на созданный объект для удаления в вызывающем коде
 
//**************************** код ускорения через OpenGL *****************************************
// QGLWidget удалять отдельно не нужно - удалится сам при удалении pGView
//pGView->setViewport( new QGLWidget(QGLFormat(QGL::SampleBuffers)) );
//**************************** код ускорения через OpenGL *****************************************
 
pResizeGView->setGeometry( pWidget->geometry() );
pResizeGView->setWidget( pWidget ); // View-у нужен доступ к геометрии виджета для правильного ресайза
pResizeGView->setWindowTitle( pWidget->windowTitle() );
 
if ( bFullScreen )
pGView->showFullScreen();
else
pGView->show();
}
else
{
pWidget->setParent( pParentSCR );
if ( bFullScreen )
pWidget->showFullScreen();
else
pWidget->show();
};
}
 


Название: Re: Тормоза в QGLWidget
Отправлено: ieroglif от Март 31, 2010, 23:07
...потребовалось сделать так чтобы куча написанных окошек стали пропорционально ресайзится - то есть куча готовых форм, переводить их все на лайауты где их не было и следить за политикой ресайза - тоже вариант но он более трудоемок. ...

простите за любопытство, а почему более трудоёмок?


Название: Re: Тормоза в QGLWidget
Отправлено: break от Апрель 01, 2010, 02:05
Цитировать
простите за любопытство, а почему более трудоёмок?

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


Название: Re: Тормоза в QGLWidget
Отправлено: mozgofil от Апрель 18, 2010, 18:36
ну то что граблей млжет быть много это опнятно.
Вопрос в другом:
Кто сталкивается с проблемами производительности при переходе от QWidget к QGLWidget ?
уточни что конкретно тормозит: GL -евская отрисовка или сам по себе виджет:
убери весь код отрисовки и сравни скорость
если скорость примерно одинаковая, закуривай маны по OpenGL


Название: Re: Тормоза в QGLWidget
Отправлено: serg_admin от Май 21, 2010, 15:18
Столкнулся с этой проблемой на видеокарте GeForce4 MX 4000. К тому же не было поддержки pBuffer.
После обновления драйвера для видеокарты все прекрасно заработало


Название: Re: Тормоза в QGLWidget
Отправлено: navrocky от Июнь 23, 2010, 15:13
Тормоза возникают, потому что не всё хорошо отрисовывать через OpenGL, слишком толстая прослойка получается. OpenGL хорошо справляется с рисованием масштабированных полупрозрачных картинок, намного лучше чем это делать программно, но при рисовании интерфейса, текста, OpenGL будет только тормозом, т.к. не заточено оно под это, особенно под текст.

Так что OpenGL не панацея. Плюс ко всему визуальное качество картинки при использовании OpenGL хуже чем при софтварьном рендеринге, видно на сглаженных линиях, шрифте.


Название: Re: Тормоза в QGLWidget
Отправлено: break от Июнь 23, 2010, 17:18
 navrocky - ерунду говоришь! - посмотри на GUI в программе Blender - там все работает через openGL ( по крайней мере Linux версия ) - если грамотно пользоваться он отлично подойдет для рисования текста и т.д. хотя изначально разрабатывался для 3D. QGLWidget очень тонкая прослойка которая ничего не тормозит. Но вот механизм QGLPainter - в Qt с производительностью не дружит - когда это касается QProxyWidget (ситуацию я описал выше!)


Название: Re: Тормоза в QGLWidget
Отправлено: navrocky от Июнь 23, 2010, 23:04
Почему тогда кутэшные примеры не ускоряются в разы при использовании opengl ? А местами даже работают тормознее от этого?

Потом может и QGLWidget и тонкая прослойка, на сам OpenGL достаточно толст. Плюс к этому видеокарты затачиваются под рисование текстурированных полигонов, но никак не под текст и линии. Я много раз наблюдал картину когда wireframe модель работала намного тормознее, чем текстурированная.



Название: Re: Тормоза в QGLWidget
Отправлено: xop от Июнь 24, 2010, 08:51
Потому что методы рисования на CPU и GPU - сильно разные. А Qt этого практически не учитывает.

По поводу рисования текста. Если кэшировать шрифты в текстурах и выводить квадами через динамический VBO - то это будет очень быстро. Намного быстрее тормознутого Qtшного drawText, на который тут уже в нескольких темах ругались. Потери качества - не будет.

По поводу рисования линий. Видюхи как правило с ними справляются плохо. Кстати, именно из-за этого и происходит сильная просадка производительности при использовании wireframe. Обходится обычно это так - вместо линий опять же рисуют длинные тонкие квады. Причем если квады делать толщиной в 2-3 пиксела, рисовать с альфа-блендом и при этом хитро текстурить (или использовать шейдер), то можно добиться линий с антиалиасингом без использования аппаратного MSAA. И будет это работать тоже очень резво.


Название: Re: Тормоза в QGLWidget
Отправлено: kamre от Июнь 24, 2010, 20:47
Потому что методы рисования на CPU и GPU - сильно разные. А Qt этого практически не учитывает.
Почему это не учитывает? При включении OpenGL отрисовка делается в несколько раз быстрее: http://trac-hg.assembla.com/jgears/wiki/ResultsHome

По поводу рисования текста. Если кэшировать шрифты в текстурах и выводить квадами через динамический VBO - то это будет очень быстро. Намного быстрее тормознутого Qtшного drawText, на который тут уже в нескольких темах ругались. Потери качества - не будет.
Не все так просто. Если для QPainter будет разное масштабирование, то при отрисовке нужно же новую текстуру со шрифтом делать, иначе будет потеря в качестве.

Обходится обычно это так - вместо линий опять же рисуют длинные тонкие квады. Причем если квады делать толщиной в 2-3 пиксела, рисовать с альфа-блендом и при этом хитро текстурить (или использовать шейдер), то можно добиться линий с антиалиасингом без использования аппаратного MSAA. И будет это работать тоже очень резво.
В Qt при отрисовке через opengl вроде так и делается, и через шейдеры сглаживание. На нормальных видеокартах с нормальными драйверами получается заметно быстрее.


Название: Re: Тормоза в QGLWidget
Отправлено: xop от Июнь 25, 2010, 12:37
Почему это не учитывает? При включении OpenGL отрисовка делается в несколько раз быстрее: http://trac-hg.assembla.com/jgears/wiki/ResultsHome
Это радует. Значит я отстал от жизни :)

Не все так просто. Если для QPainter будет разное масштабирование, то при отрисовке нужно же новую текстуру со шрифтом делать, иначе будет потеря в качестве.
Согласен, про масштабирование не подумал.