PDA

View Full Version : QGraphicsView performance problems



MarPan
30th June 2010, 15:12
Hello,

I am trying to write a roundabout simulator. I have a class inheriting QGraphicsView. Here's the initialization from the constructor:

_scene = new QGraphicsScene;
_scene->setSceneRect(-1000, -1000, 2000, 2000);
_scene->setItemIndexMethod(QGraphicsScene::NoIndex);

setScene(_scene);
setCacheMode(QGraphicsView::CacheBackground);
setViewportUpdateMode(QGraphicsView::SmartViewport Update);
setDragMode(QGraphicsView::ScrollHandDrag);
setOptimizationFlag(DontAdjustForAntialiasing); I tried adding some mice from Colliding Mice example. When there are more then twenty (or so) of them, performance drops. I commented out any of my roundabout-drawing code, so now it's just mice on a green background.
I tried simplifying the mouse::paint() and mouse::advance() functions, but that didn't seem to do the trick.

What is the reason behind the slowdown? I wanted to have many more cars moving (and detecting collisions) then twenty :) should I use different approach then GraphicsView?

steno
30th June 2010, 15:44
You can try FullViewportUpdate and set the viewport to use opengl.

tbscope
30th June 2010, 16:25
And maybe turn off indexing if you don't need it

MarPan
30th June 2010, 17:34
Thank you for quick responses. I have already disabled indexing as you can see in the code in my first post.

Switching to OpenGL helped a little: now slowdown is noticible at about 54 mice running around. So it's better, but still not as good as I hoped it would be. Do you have any other suggestions?

If you want to reproduce my problem, the simpliest way is to open the Colliding Mice example and change MouseCount to a higher value.

steno
30th June 2010, 18:58
This is just a guess cause I don't know what qt does under the hood, but if you turn indexing off and try to do collision detection on that many objects with a naive approch, you will see a performance problem.

MarPan
30th June 2010, 21:35
I'm afraid it has nothing to do with collision detection. I commented out code from mouse::advance that was checking for collisions, leaving only basic movement, and the slowdown still occurs the same way.

xray2000
1st July 2010, 07:00
Hi, My suggestion: if there is a problem with the perfomance rendering of graphics objects, try to use QtOpengl in Double Buffering mode.

MarPan
1st July 2010, 21:21
I added:
qglwidget = new QGLWidget;
qglwidget->context()->format().setDoubleBuffer(true);
setViewport(qglwidget); to the initalization code given above, but without any positive outcome.
(I hope I did it correctly)

xray2000
2nd July 2010, 06:46
I added:
qglwidget = new QGLWidget;
qglwidget->context()->format().setDoubleBuffer(true);
setViewport(qglwidget); to the initalization code given above, but without any positive outcome.
(I hope I did it correctly)

I hope, In this case you don't use QGraphicsScene and QGraphicsView for painting object's? you should use
void GLWidget::paintEvent(QPaintEvent *event) for manually painting objects (without QGraphicsScene, QGraphicsView classes).
Rendering with using only QtOpengGl must give more efficiency then using graphics scene.

MarPan
2nd July 2010, 10:03
Firstly, I may have misinformed you. When I wrote
I commented out code from mouse::advance that was checking for collisions I was right, but there was also one line in paint(), that was resposible for color of ears if there was a collision.

So right now, instead of drawing a mouse, I load a pixmap from disk (it's just a 25x50 monocolored rectangle) and store a pointer inside a mouse class. In the paint function I have
painter->setClipRect( option->exposedRect );
pixmap->fill(scene()->collidingItems(this).isEmpty() ? Qt::cyan : Qt::red);
painter->drawPixmap(pixmap->rect(), *pixmap, pixmap->rect()); With code like this, the maximum is about 60 "cars". When I comment the middle line, I can have over 200 without significant slowdown.

So it apperas it's collision after all. But documentation says I can have "millions of items on the scene". Am I doing something wrong?
Of course I set the ItemIndexMethod back to QGraphicsScene::BspTreeIndex. I also left viewport set to opengl with double buffering on, since it helped a little (though I don't know why).

And I don't really want to give up on qgraphicsview. The reason I chose it was because of it's collision tools.


EDIT: I just have read an interesting blog entry: http://labs.trolltech.com/blogs/2009/02/27/braindump-graphics-view-and-the-joys-of-off-screen-rendering/. Andreas also tried improving performance of colliding mice and says
(the bottleneck of the example becomes the collision-detection). Does that mean that I cannot go any further than that?

mdwh
14th August 2010, 21:24
Sorry to bump an oldish thread, but I've noticed similar performance issues with QGraphicsScene and collision detection, particularly when running on my Nokia 5800 (Symbian).

I have written a simple breakout clone. There are around 27 items in the scene. When I call QGraphicsScene::collidingItems once per frame (to check for collisions between ball and blocks), performance is fine.

I then added a bonus where the player could shoot bullets, and for each bullet, there was an additional call to QGraphicsScene::collidingItems. There was a noticable slowdown with each bullet added, with it slowing to a crawl even with only 2-3 bullets!

I fixed the problem by writing my own spatial indexing method, implementing a 2D spatial grid. Now sure, obviously I realise that an indexing method written specifically for my game will do better than a generic indexing method, but I don't understand why it's so slow. The documentation says "One of QGraphicsScene's greatest strengths is its ability to efficiently determine the location of items. Even with millions of items on the scene, the items() functions can determine the location of an item within few milliseconds."

My blocks are static, so I don't think that's a problem for the BSP. Also I note that things seem to run just as slowly with BSP indexing, compared with indexing disabled.

I don't know if this is normal behaviour, or we're doing something wrong?