PDA

View Full Version : graphics view slow



dognzhe
1st May 2009, 08:35
hi guys

I have this problem that i try to resolve it for few days, but no progress. i don't even know is that possible to resolve.

i am writting a Tank game. i have a main timer move all the items in the scene. QObject::startTimer(20);

I have a tank move in the scene, and i use graphicsView.ensureVisible to keep it around center of viewport.

so the scene is big (5000,5000) viewport is about 1000,1000, viewport will move when tank moves out of center rect.

i set tank move 10 pixels very timer trigger.

the problem is
when tank moves, it become fuzzy.
when i change it to 3 pixels, it is not fuzzy, but it was very slow, i need to make it move fast. It is tank, not the ant.
So I change the timer to startTimer(3). It works good if the Tank move inside of center rect(viewport is not move).
1. but when viewport moves, tank is slow down!!!!!!!

2. when i resize the viewport, make it smaller, the speed of tank is move more fast than it in bigger viewport.

i think it may has something to do with the speed of paint. the bigger view port takes longer to paint, so 3 millisecond is not enough for it to paint.

i don't know. any ideas? thank advance

fullmetalcoder
1st May 2009, 11:02
Have you tried playing with Graphics view caching strategies?


QGraphicsView::setCacheMode()
QGraphicsItem::setCacheMode()
QGraphicsScene::setItemIndexMethod() (http://doc.trolltech.com/4.5/qgraphicsscene.html#itemIndexMethod-prop)
QGraphicsScene::setSortCacheEnabled() (http://doc.trolltech.com/4.5/qgraphicsscene.html#sortCacheEnabled-prop)

Using a proper combination of these could result in a dramatic increase of performance (there's no warranty though as the efficiency of these optimizations depends on the scene).

There is probably room for improvement in your design as well but the description you gave is not clear enough for me to give you any hints on this. The only thing I can tell without more konwledge of your code is that a proper use of item transformations could help.

If you need smotth animations you may consider exploring Qt labs (http://labs.trolltech.com/blogs/) and giving a try to Qt kinetic (http://labs.trolltech.com/page/Projects/Graphics/Kinetic).

dognzhe
4th May 2009, 03:12
graphicsView.setBackgroundBrush(QBrush(backGroundC olor));
graphicsView.setCacheMode(QGraphicsView::CacheBack ground);
graphicsView.setRenderHint(QPainter::Antialiasing) ;
graphicsView.setViewportUpdateMode(QGraphicsView:: SmartViewportUpdate);//QGraphicsView::FullViewportUpdate);////BoundingRectViewportUpdate);
graphicsView.setDragMode(QGraphicsView::NoDrag);

scene.setItemIndexMethod(QGraphicsScene::NoIndex);

this is my current settings

this game is simple, tank move controlled by keyboard.
there are some rectangles to be shoot at.
the tank is the picture.
there are four pictures for up down left and right, they are preloaded.
"
tankUp = new QImage(":/CannonBattle/Resources/tank up.jpg");
tankDown= new QImage(":/CannonBattle/Resources/tank down.jpg");
tankRight =new QImage(":/CannonBattle/Resources/tank right.jpg");
tankLeft = new QImage(":/CannonBattle/Resources/tank left.jpg");
"
so i did not use any rotation and transformations.

all the paint and collision check happened in one timer.

the way i make the tank move is to setpos(), then call centeron();

is transformation fast than setpos?

wysota
4th May 2009, 13:30
First get rid of "ensure visible" functionality as the view has to recalculate the frustum all the time which is pointless because at each moment you know exactly if your tank is visible on the viewport or not.

Second of all firing a timer every 3 miliseconds doesn't make much sense. Having 333 frames per second differs from having 25 frames per second only in one thing - that you strain your machine almost 15 times more. If you set the period of the timer to 40ms (which gives you 25fps) your performance will improve (you can compensate for the distance to have a similar impression of "speed").

Third of all think if you really need GraphicsView for this use case, maybe it only slows you down.

Fourth of all don't allocate QImage objects on the heap, it doesn't make sense to do so.

dognzhe
5th May 2009, 02:12
Hi man, thanks very much for your reply. I still have some questions.

1. "First get rid of "ensure visible" functionality ", I need it to keep it in viewport, sence is much big than viewport. any other way?

2."If you set the period of the timer to 40ms (which gives you 25fps) your performance will improve (you can compensate for the distance to have a similar impression of "speed").
"
I tried, in order to get same speed i have to move tank 15 pixels very timer which makes tank move serious blurry

3 ." if you really need GraphicsView for this use case, maybe it only slows you down."
any they other way?

4. "don't allocate QImage objects on the heap, it doesn't make sense to do so. "
what should i use? bitmap?

wysota
5th May 2009, 09:38
1. "First get rid of "ensure visible" functionality ", I need it to keep it in viewport, sence is much big than viewport. any other way?
Scroll the viewport yourself. QGraphicsView is derived from QAbstractScrollArea.


2."If you set the period of the timer to 40ms (which gives you 25fps) your performance will improve (you can compensate for the distance to have a similar impression of "speed").
"
I tried, in order to get same speed i have to move tank 15 pixels very timer which makes tank move serious blurry
So find something in between.


3 ." if you really need GraphicsView for this use case, maybe it only slows you down."
any they other way?
Yes, QWidget :)


4. "don't allocate QImage objects on the heap, it doesn't make sense to do so. "
what should i use? bitmap?

No. You should learn reading the docs and at least a bit of C++. Now go google for "heap" and read QImage docs.

dognzhe
6th May 2009, 04:18
this is funny reply.



find something in between. will not achieve the desired speed!

scroll by user is nonsense, have you play any game with scroll bar? unbelievable

wysota
6th May 2009, 09:34
scroll by user is nonsense, have you play any game with scroll bar? unbelievable

Who said anything about the user? I meant you as a programmer.

The fact that you don't understand what I said doesn't mean it is funny. If you design your application correctly you will achieve everything you want without problems. If you misdesign, you'll be running into problems on every step like it is happening now.

dognzhe
7th May 2009, 02:09
my logic is very simple, there is timer, when time out do all the drawing


any one can help??????

wysota
7th May 2009, 10:30
You're not listening. The problem is very unlikely to be drawing. If you have doubts about it, take a profiler and find the bottleneck.

dognzhe
8th May 2009, 03:13
#include "Tank.h"

Tank::Tank(QObject *parent,QGraphicsScene *scene)
: QObject(parent), QGraphicsItem(0,scene)
{
tankDirection=dRight;
tankUp = new QPixmap(":/CannonBattle/Resources/tank up.jpg");
tankDown= new QPixmap(":/CannonBattle/Resources/tank down.jpg");
tankRight =new QPixmap(":/CannonBattle/Resources/tank right.jpg");
tankLeft = new QPixmap(":/CannonBattle/Resources/tank left.jpg");
if(tankUp->isNull() && tankDown->isNull() && tankRight->isNull()){
emit error(QString("tank image load fails"));
}
/*

label.setText("dongzhe adfasd fasdfsdafsadfasdfasd");
//label.setMovie(movie);
mo=this->scene()->addWidget(&label);
mo->setPos(50,50);
*/

this->setCacheMode(QGraphicsItem::DeviceCoordinateCache) ;

}

Tank::~Tank()
{

}

QPixmap* Tank::getImage() const{

if(tankDirection==dRight){
return tankRight;
}else if(tankDirection== dLeft){
return tankLeft;
}else if(tankDirection== dUp){
return tankUp;
}else{
return tankDown;
}

}

QRectF Tank::boundingRect() const{

//increase the boudingRect to get rid of marks
return QRectF(getImage()->rect().x(),getImage()->rect().y(),getImage()->rect().width(),getImage()->rect().height()+2);
//return getImage()->rect();
}

void Tank::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){

painter->drawPixmap(QPoint(0,0),*getImage());
//painter->drawImage(QPoint(0,0),QImage(":/CannonBattle/Resources/explose.gif"));



}


int Tank::type() const {

return TANK_TYPE;
}

[/QTCLASS]


here is move tank

[QTCLASS]
void CannonField::tankMove(){
#if _DEBUG
int a;
int b;
timeTemp.start();
//timeTemp =QTime::currentTime();

#endif

QPointF oldPoint(mainTank->pos());
tankCurrentY = mainTank->pos().y();
tankCurrentX= mainTank->pos().x();
if(mainTank->tankDirection==mainTank->dUp){
mainTank->setPos(tankCurrentX, tankCurrentY-tankSpeed);
}

if(mainTank->tankDirection==mainTank->dDown){
mainTank->setPos(tankCurrentX, tankCurrentY+tankSpeed);
}

if(mainTank->tankDirection==mainTank->dLeft){
mainTank->setPos(tankCurrentX-tankSpeed,tankCurrentY);
}

if(mainTank->tankDirection==mainTank->dRight){
mainTank->setPos(tankCurrentX+tankSpeed,tankCurrentY);
}

tankCurrentY = mainTank->pos().y();
tankCurrentX= mainTank->pos().x();


if (tankCurrentX <0 || tankCurrentY<0 || tankCurrentX > (scene.width()-mainTank->boundingRect().width()) || tankCurrentY > (scene.height()-mainTank->boundingRect().height())) {
mainTank->setPos(oldPoint);
}

QList<QGraphicsItem *> collisions = mainTank->collidingItems(Qt::IntersectsItemBoundingRect);
if(!collisions.isEmpty()){
QGraphicsItem *temp;

QListIterator<QGraphicsItem *> it(collisions);
while(it.hasNext()){
temp= it.next();
if(temp->type()==TARGET_TYPE){
mainTank->setPos(oldPoint);
}
}

}


//graphicsView.centerOn(mainTank);
graphicsView.ensureVisible(mainTank,graphicsView.r ect().width()/3,graphicsView.rect().height()/3);
#if _DEBUG
//for(int i=0;i<1000000;i++)
//{i++;}
//b=QTime::currentTime().msecsTo(timeTemp);
a= timeTemp.elapsed();
qDebug("%d\n",a);
#endif
}




I don;'t know what to do ...

wysota
8th May 2009, 07:40
Please take a profiler and find the bottle neck in your application. Now you're just shooting blind.

dognzhe
8th May 2009, 08:59
Please take a profiler and find the bottle neck in your application. Now you're just shooting blind.

where can i get profiler? is that free? can you give me a link????

wysota
8th May 2009, 09:31
http://www.google.com/search?q=profiling+applications

dognzhe
11th May 2009, 02:26
man, i can 't find the free one... i am using VS2005 with qt.

do you know any free one for downlaod?

jano_alex_es
11th May 2009, 11:06
I think you have one in Visual Studio 2005 (http://msdn.microsoft.com/en-us/library/ms182398(VS.80).aspx)

wysota
11th May 2009, 18:36
man, i can 't find the free one... i am using VS2005 with qt.

Consider switching to a Free compiler then.