PDA

View Full Version : Binding multiple qgraphicsRectItem to a single QGLFrameBufferObject



sp
26th August 2013, 10:32
Is it possible to bind multiple QGraphicsRectItems to a single QGLFrameBufferObject??? If yes, plz tell the method...

wysota
26th August 2013, 10:42
What would you like to acomplish by doing that?

sp
26th August 2013, 10:48
i have a seven-layered map on the background which is occasionally updated. Each layer is a QGraphicsRectItem.
Will above approach help?

my seniors suggessted this. They said maybe this will result in faster rendering.

wysota
26th August 2013, 10:51
I still don't understand what QGLFrameBufferObject has to do with this.

Will above approach help with what? What is the problem?

sp
26th August 2013, 11:02
there is a scan on top which is a qgraphicsItem. it is updated every 10ms but rendering is not smooth bcoz of many other items that are visible and repainted.
I need smooth rendering of scan.

They suggested me that binding entire map to a qglframebufferobject can cause faster rendering as GPU will take care of it. Its their suggestion. I just thought of trying. so plz tell me will it help in anyway??

wagmare
26th August 2013, 11:05
its my small suggestion
make the qglframbuffer or other opengl on drawbackground of QGraphicsView and add the seven layer of GraphicsItem with required transparency with correct z-order .
use this link to make it render faster
http://thesmithfam.org/blog/2007/02/03/qt-improving-qgraphicsview-performance/

use these flags in QGraphicsVIew

setCacheMode(QGraphicsView::CacheBackground);
setViewportUpdateMode(QGraphicsView::FullViewportU pdate);
setDragMode(QGraphicsView::ScrollHandDrag);
setOptimizationFlag(DontAdjustForAntialiasing);

set viewport to opengl in QGraphicsView

sp
26th August 2013, 11:10
thanks for suggestion but i have already used these flags except for 4th one. they have optimized scan to some extent but still not smooth.

wagmare
26th August 2013, 11:11
fine..
and the link ..? did u set the viewport to opengl ..?

sp
26th August 2013, 11:14
yes i set the viewport to opengl.
i couldnt open link in office. Its blocked. Will try at home and reply tommorow

wagmare
26th August 2013, 11:18
Clipping

No, this isn’t the kind of clipping you hear when you turn up the volume on your wimpy headphones. This clipping refers to pixel painting. Imagine if you had to draw a full-page picture on a p piece of paper, but when you get done, you realize that you made a mistake on a small section in the center. It would be foolish to throw away the whole picture just to redraw this small part. So instead, you apply judicious use of your pencil’s eraser and redraw just that little part. Aren’t you proud of yourself?

When it comes to pixel painting, it’s usually a lot less code to just redraw the whole picture, rather than worry about which parts actually need to be redrawn. In QGraphicsView The problem is that when a QGraphicsItem moves over the top of another, and just slightly covers it, and then moves off again, you need to repaint just the part that was covered, and is now exposed. This is where clipping comes in.

In your custom QGraphicsItem-derived class, there is a paint() method that you are probably already familiar with, that looks like this:
void QGraphicsItem::paint(
QPainter*,
const QStyleOptionGraphicsItem*,
QWidget* );

A much-neglected parameter, the QStyleOptionGraphicsItem (what a mouthful) is very valuable in determining how much of your QGraphicsItem actually needs to be repainted. Check out the exposedRect member (yes, it’s a public member variable), and it will tell you what part of your item needs to be repainted.

This is where clipping comes in. By telling the QPainter object to clip the exposed rectangle of your item, it will ignore all pixel painting that happens outside of that rectangle. This saves lots of wasted painting, and will drastically speed up QGraphicsView operations like animations and drags. Here’s how you do it:
void
MyGraphicsItem::paint( QPainter *painter,
const QStyleOptionGraphicsItem *option,
QWidget* )
{
// Here comes the magic:
painter->setClipRect( option->exposedRect );

// All your custom painting code goes here.
// ...
}

You will see the biggest speed up for objects that frequently have small exposed rectangles. Without setClipRect(), you would needlessly repaint the entire object, rather than just the affected region.

Mind your bounding boxes

This is a simpler one. When you place a custom QGraphicsItem on a QGraphicsView, you have to provide a boundingRect() function. This tells the QGraphicsView how big your item is, and lets it figure out when to repaint your item (like when it comes on screen, or is temporarily obscured by another item). However, if you make a mistake and make your boundingRect() return a QRectF that is too big, you’re going to take a performance penalty. The reason is that QGraphicsView will repaint your item when it may not be necessary.

Also bare in mind that diagonal and curved lines have much larger bounding boxes than vertical and horizontal lines. For example, when you make an S-shaped line that passes near, but not directly over, other QGraphicsItems, it is possible that they will get repainted too often, simply because they collide with the line’s bounding rectangle. Remember that all bounding boxes in QGraphicsView are axis-aligned, and painting is based solely on these rectangles. It’s easy to confuse this with the QGraphicsItem::shape() function, which actually traces an outline of the item, but which is not used for painting (it’s used for mouse clicks, collisions and such).

Don’t overuse anti-aliasing

Anti-aliased lines look good, but horizontal and vertical lines don’t normally need to be anti-aliased. In fact, they usually look worse that way. The same is true for text. Apply anti-aliasing judiciously, because performance wise, it costs a lot more to render lines and text anti-aliased.

the link says..

wysota
26th August 2013, 11:36
there is a scan on top which is a qgraphicsItem. it is updated every 10ms but rendering is not smooth bcoz of many other items that are visible and repainted.
I need smooth rendering of scan.

They suggested me that binding entire map to a qglframebufferobject can cause faster rendering as GPU will take care of it. Its their suggestion. I just thought of trying. so plz tell me will it help in anyway??

Using an FBO will not help much. Rendering every 10ms does not make sense anyway since you probably have a 60Hz display so you're out of sync with your display. The human eye is not capable of noticing such changes anyway. I suggest you try increasing the interval to 1000/30 (to get 30 FPS) and possibly enabling OpenGL viewport for your view.

By the way, for a GL viewport graphics view always works in FullViewportUpdate mode so you can forget about "optimizing bounding rect" and clipping.