Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-jambi-interest Archive, November 2007
Speed up QGraphicsView rendering


Message 1 in thread

Hi,

Like many of the questions asked before this one, I'll start by saying
I'm new to Qt Jambi. I'm somewhat experimenting with QGraphicsScene and
QGraphicsView, which both work like a charm!

I'm trying some animations with a helicopter on screen which moves
toward the mouse. This goes perfectly and fast. When the helicopter is
close to the borders of the view, the view should be altered to ensure
it stays visible. I have tried several methods for this, and
ensureVisible(helicopter, margin, margin) has the appropriate effect.
But when the view is altered, everything slows down so much! Normally
30fps (done with a QTimer) is no problem, but when the view should be
altered everything shakes at a lower frame rate. This happens both with
a background and without a background. I've searched the docs for
anything about this, but didn't find anything. I tried
view.setCacheMode(QGraphicsView.CacheModeFlag.CacheBackground); to speed
up the rendering, but this didn't have any effect.

Is there any way of speeding the process up? The view isn't that big
(1024x765), so rendering it shouldn't take that long, I would presume.
Or am I doing something wrong?

Best regards,

Maarten Decat


Message 2 in thread

Maarten Decat wrote:
> Hi,
> 
> Like many of the questions asked before this one, I'll start by saying
> I'm new to Qt Jambi. I'm somewhat experimenting with QGraphicsScene and
> QGraphicsView, which both work like a charm!
> 
> I'm trying some animations with a helicopter on screen which moves
> toward the mouse. This goes perfectly and fast. When the helicopter is
> close to the borders of the view, the view should be altered to ensure
> it stays visible. I have tried several methods for this, and
> ensureVisible(helicopter, margin, margin) has the appropriate effect.
> But when the view is altered, everything slows down so much! Normally
> 30fps (done with a QTimer) is no problem, but when the view should be
> altered everything shakes at a lower frame rate. This happens both with
> a background and without a background. I've searched the docs for
> anything about this, but didn't find anything. I tried
> view.setCacheMode(QGraphicsView.CacheModeFlag.CacheBackground); to speed
> up the rendering, but this didn't have any effect.
> 
> Is there any way of speeding the process up? The view isn't that big
> (1024x765), so rendering it shouldn't take that long, I would presume.
> Or am I doing something wrong?

Hi Maarten,

While waiting for a compile job yesterday I put together a small sample 
app and I can definitly reproduce this problem. As far as I can see, 
what hits me the most (Windows XP with semi-ok Graphics Card) is the 
native scrolling of the offscreen buffer. The best way to get around 
this so switch to opengl based rendering which eliminates the native 
scrolling. This can be done by setting the QGraphicView's viewport to

view.setViewport(new QGLWidget());

If you want antialiasing etc in there you can acheive that by 
constructing the widget with a more advanced QGLFormat.

Does this solve the problem?

-
Gunnar
package com.trolltech.tests;
package com.trolltech.tests;

import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;

import com.trolltech.qt.opengl.*;

public class GraphicsItem {

    private static class Heli extends QGraphicsItem {

        public Heli() {
            QConicalGradient g = new QConicalGradient();
            g.setColorAt(0, QColor.white);
            g.setColorAt(0.25, QColor.transparent);
            g.setColorAt(0.50, QColor.white);
            g.setColorAt(0.75, QColor.transparent);
            g.setColorAt(1.00, QColor.white);
            blades = new QBrush(g);

            body = new QPainterPath();
            body.moveTo(-5, 0);
            body.cubicTo(-5, -5,
                         10, -5,
                         20, 0);
            body.cubicTo(10, 5,
                         -5, 5,
                         -5, 0);
        }

        public void paint(QPainter p, QStyleOptionGraphicsItem option, QWidget widget) {
            p.setPen(QColor.black);
            p.setBrush(QColor.red);
            p.drawPath(body);

            p.setPen(QColor.white);
            p.setBrush(blades);
            p.rotate(count * 50);
            p.drawEllipse(-10, -10, 20, 20);

            ++count;
            long ctime = System.currentTimeMillis() - time;
            if (ctime > 2000) {
                double ops = count / (double) ctime;
                System.out.println("average over last 2 seconds is: " + (int) (ops * 1000) + "fps");
                time = System.currentTimeMillis();
                count = 0;
            }
        };

        public void moveAndUpdate() {
            rotate(1);
            translate(-5, 2);
            ensureVisible(bounds);
        }

        public QRectF boundingRect() { return bounds; }

        private QRectF bounds = new QRectF(-10, -10, 30, 20);
        private QPainterPath body;
        private QBrush blades;
        private int count;
        private long time;
    }

    public static void main(String args[]) {
        QApplication.initialize(args);

        QGraphicsScene scene = new QGraphicsScene();
        scene.setSceneRect(-1000, -1000, 2000, 2000);

        QPixmap pm = new QPixmap(32, 32);
        pm.fill(new QColor(255, 223, 101));
        QPainter p = new QPainter(pm);
        for (int i=0; i<100; ++i) {
            p.drawPoint((int)(Math.random() * 32), (int) (Math.random() * 32));
        }
        p.end();
        scene.setBackgroundBrush(new QBrush(pm));

        final QGraphicsView view = new QGraphicsView(scene);
        view.setRenderHints(QPainter.RenderHint.Antialiasing);
        view.resize(1024, 768);

        if (args == null || args.length < 1 || args[0].indexOf("-no-opengl") < 0)
            view.setViewport(new QGLWidget());

        view.show();

        Heli h = new Heli();

        QTimer t = new QTimer();
        t.setInterval(10);
        t.timeout.connect(h, "moveAndUpdate()");
        t.start();

        scene.addItem(h);

        QApplication.exec();
    }
}

Message 3 in thread

Gunnar Sletta wrote:
> Maarten Decat wrote:
>> Hi,
>>
>> Like many of the questions asked before this one, I'll start by saying
>> I'm new to Qt Jambi. I'm somewhat experimenting with QGraphicsScene and
>> QGraphicsView, which both work like a charm!
>>
>> I'm trying some animations with a helicopter on screen which moves
>> toward the mouse. This goes perfectly and fast. When the helicopter is
>> close to the borders of the view, the view should be altered to ensure
>> it stays visible. I have tried several methods for this, and
>> ensureVisible(helicopter, margin, margin) has the appropriate effect.
>> But when the view is altered, everything slows down so much! Normally
>> 30fps (done with a QTimer) is no problem, but when the view should be
>> altered everything shakes at a lower frame rate. This happens both with
>> a background and without a background. I've searched the docs for
>> anything about this, but didn't find anything. I tried
>> view.setCacheMode(QGraphicsView.CacheModeFlag.CacheBackground); to speed
>> up the rendering, but this didn't have any effect.
>>
>> Is there any way of speeding the process up? The view isn't that big
>> (1024x765), so rendering it shouldn't take that long, I would presume.
>> Or am I doing something wrong?
> 
> Hi Maarten,
> 
> While waiting for a compile job yesterday I put together a small sample 
> app and I can definitly reproduce this problem. As far as I can see, 
> what hits me the most (Windows XP with semi-ok Graphics Card) is the 
> native scrolling of the offscreen buffer. The best way to get around 
> this so switch to opengl based rendering which eliminates the native 
> scrolling. This can be done by setting the QGraphicView's viewport to
> 
> view.setViewport(new QGLWidget());
> 
> If you want antialiasing etc in there you can acheive that by 
> constructing the widget with a more advanced QGLFormat.
> 
> Does this solve the problem?
> 
> -
> Gunnar
> 

This most definitely solves the problem! Everything goes fast and smooth 
right now! Having some problems on Linux (Xlib:  extension "XFree86-DRI" 
missing on display ":1.0".) but this is just some driver stuff I think, 
will try to fix that later :p In windows, it works like a charm!

Thank you very much Gunnar! I'm starting to like Qt Jambi even more, 
with this kind of responses!

Maarten