PDA

View Full Version : OpenGL rendering problem



spud
25th February 2007, 19:17
I have a project where I render a recorded gps path on an aereal photo. I do this using a QGraphicsScene with a QGraphicsPathItem on a QGraphicsPixmapItem. Simple enough. When I use OpenGL to render the scene, i.e.


QGraphicsView::setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));

i notice that the path loses accuracy, as if it is restricted by a lower resolution. See the attached snapshots. Does anybody have an idea why this is, or how i can fix it?

wysota
26th February 2007, 08:54
Is the scene size the same in both cases? Could you prepare a minimal compilable example reproducing the problem?

minimoog
26th February 2007, 21:44
I think that the problem is using the antialiasing (multisample buffers).

spud
27th February 2007, 13:22
OK, now I've gotten around to preparing a minimal example. You can see the problem by turning on gl rendering and zooming in with the wheel mouse. Look at the top and bottom of the circle to see the effect.

Explanation:
I have a georeferenced image with the accompanying data:

0.250000
0.000000
0.000000
-0.250000
400000.000000
6000000.000000

which means the image origin is at (400000, 6000000) (central europe) and the pixel size is 0.25 x 0.25 meter (y axis flipped).
My problem stems from deriving the scene rect from the data. It's pretty handy to know that one unit in the scene corresponds to one meter in the real world.
so I add the image as a QGraphicsPixmapItem



QGraphicsPixmapItem*item = new QGraphicsPixmapItem(QPixmap::fromImage(img), 0, &scene);
QMatrix matrix;
matrix.translate(400000.0, 6000000.0);
matrix.scale( 0.25, -0.25);
item->setMatrix(matrix);

// set sceneRect to image size
scene.setSceneRect(matrix.dx(), matrix.dy(), img.width()*matrix.m11(), img.height()*matrix.m22());


I then want to display a recorded gps path. I have two ways of doing this. One which shows up ok and one which displays the aforementioned problem.



// doesn't work with opengl
QPainterPath path;
path.lineTo(p1);
path.lineTo(p2);
...
QGraphicsPathItem*pathItem = new QGraphicsPathItem(path, 0, &scene);



// works with opengl
QPainterPath path;
QPointF origin(400000.0, 6000000.0);
path.lineTo(p1-origin);
path.lineTo(p2-origin);
...
QGraphicsPathItem*pathItem = new QGraphicsPathItem(path, 0, &scene);
pathItem->moveBy(origin.x(), origin.y());

Obviously there is some kind of a rounding error at work here. The problem is worse along the y-axis, which makes sense, since the offset in that direction is larger by a factor of 20.

I now know how to work around this problem, but I am curious as to why it shows up in one case and not the other and if it is a necessary evil dictated by technical limitations or a bug in the Qt implementation.

minimoog
27th February 2007, 19:45
I was looking at the QT source code to find where is the problem when there is a rendering in OpenGL. Before rendering the path, QT tesselates the "path" into the triangles, then renders the triangles into to OpenGL. Maybe the tesselator is the problem? Qt uses GLU tesselator, maybe GLU tess losses accuracy?

wysota
27th February 2007, 20:44
If you're zooming, then it might be a problem with floating point calculations accuracy. Does the same thing happen with smaller zoom factors?