PDA

View Full Version : OpenGl 2d



Lele
5th May 2006, 11:41
Hi all,
I'm developing a simple library that enable users to display raw buffers(RGB mainly) and overlays (text, squares ...). I already developed the "Qpainter" version, basically a derived QWidget that uses a Qpainter inside, for the overlays I had to save all the overlays painting requests by the client in temporary arrays and then paint over the buffer image in the paintEvent.




void DisplayPainter3::paintEvent(QPaintEvent *e)
{

QPainter painter(this);
painter.drawImage(QPoint(0, 0), newImage);

for (int i = 0; i < m_pxmps_list.size(); i++)
{
painter.drawPixmap(m_pxmps_list.at(i).p ,m_pxmps_list.at(i).px);
}

for (i = 0; i < m_sq_list.size(); i++)
{
m_pen.setColor(m_sq_list.at(i).co);
painter.setPen(m_pen);
painter.drawRect(m_sq_list.at(i).xs, m_sq_list.at(i).ys, m_sq_list.at(i).w, m_sq_list.at(i).h);
}
....


Now I'd like to do the same taking advantage of the OpenGl hardware acceleration, so my questions:

1. Is there some good tutorial on how using OpenGl for 2d painting in a QGLWidget (or some sample, the examples in Qt are all 3d )?
2. Should I use QGLPixelBuffer?
3. Would it be better to load the buffer in a QImage or Qpixmap before QGLWidget::renderPixmap()?

Ok, hoping not too be too off topic I thank you for any tips.

Bye

e8johan
5th May 2006, 12:19
The Independent Qt Tutorial (http://digitalfanatics.org/projects/qt_tutorial/chapter14.html) has an OpenGL chapter that is based on NeHe's OpenGL tutorials (http://nehe.gamedev.net/) which contains a 2D chapter (http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=21).

Lele
5th May 2006, 14:54
Hi,
thanks for the tip, another thing I'd like to know from people who use OpenGl+Qt is if can really improve my drawing process decreasing cpu time or doing in 2d is just overkill.
thanks again

bye

AlexKiriukha
5th May 2006, 15:57
It depends. Once we did such test (QPainter vs QGLWidget). QGLWidget was faster from 100% to 500%, but it depends of hardware.

Lele
5th May 2006, 17:13
Hi, thanks for the info, right now I'm trying to set up a simple test to compare the two methods.
Actually I don't know how to conduct the test, could you give me some advice or some sample code over the internet?

thanks

Glitch
5th May 2006, 17:38
Are you using Qt 4? If so you might not have to do much to support OpenGL. Aurthur the new painting system for Qt now supports pluggable QPaintEngines. One of these is the QOpenGLPaintEngine.

If in your DisplayPainter3 you reimplement paintEngine() to return a QOpenGLPaintEngine all your QPainter calls should be mapped to GL equivilents instead of XLib or GDI+ equivilents.

I have never swapped paintEngines like this before, but it was a big feature of 4.0 that Trolltech raves about ;). Check out the docs.

--Justin Noel
justin@ics.com

firas
7th May 2006, 02:03
hello,


AlexKiriukha wrote:
It depends. Once we did such test (QPainter vs QGLWidget). QGLWidget was faster from 100% to 500%, but it depends of hardware.

well I tried some test myself and found the following:

1. rendering image data (RGBa) using drawPixmap is the fastest.
class MyPixmapDrawer : public QFrame
...
void MyPixmapDrawer::drawContents( QPainter* p)
{
data=QPixmap::fromMimeSource("dummy.bmp");
p->drawPixmap(0,0,data);
}

it takes roughly 1.0% processor time on P4 2Ghz box: (FC4 OS) with OpenGL enabled (nVidia drivers) GeForce 5200, using QT 3.3.4 and KDevelop 3.3.2.

however the issue that you can not manipulate the pixmap bits (RGB data)!

2. using QGLWindget and paintGL() or drawImage is the same, since you need to convert the QImage to OpenGL texture (however openGL rendering alone is faster about 11.0%)

class MyGLDrawer : public QGLWidget
...
void MyGLDrawer::paintGL()
{
glDrawPixels(data.width(), data.height(), GL_RGBA, GL_UNSIGNED_BYTE, gldata.bits());
}


class MyPixmapDrawer : public QFrame
...
void MyPixmapDrawer::drawContents( QPainter* p)
{
data=QImage::fromMimeSource("dummy.bmp");
p->drawImage(0,0,data);
}

to conclude:
I found that if there is a fast way to convert QImage to QPixmap then the choice is obvious, however I couldn't find such a thing!

otherwise I think drawImage is the best choice.

firas

Lele
8th May 2006, 08:38
Thanks for all your posts,
things are more clear to me now, but I see there's no one specific way to use OpenGL for 2d.

Glitch suggestions sound really good to me but checking the docs I couldn't find that much about it (see at the end of this post)

If I got it right that means I can take advantage of OpenGl without using it directly, has someone already tried that?

thanks again

QPainter and QGLWidget
It is now possible to open a QPainter on a QGLWidget as if it were a normal QWidget. One huge benefit from this is that we utilize the high performance of OpenGL for most drawing operations, such as transformations and pixmap drawing.

Extensive Use of Native Graphics Operations
In the Qt 4 Paint System we make more use of native graphics operations. The benefit we gain from this is that these operations can potentially be performed in hardware, giving significant speed improvements over many pure-software implementations.
Among these are native transformations (Mac OS X and OpenGL), making painting with a world matrix much faster. Some pixmap operations have also been moved closer to the underlying hardware implementations.

firas
8th May 2006, 17:34
Glitch suggestions sound really good to me but checking the docs I couldn't find that much about it (see at the end of this post)
I couldn't agree more, we should alwasy provide the code.
I attached my test KDevelop application. (I couldn't include the screenshot.png due to size limit by the forum policy!) so just take a screenshot of your desktop and save it in src folder.

Note: if you are not using kdevelop, just go to /src then type qmake followed by make.

Lele
9th May 2006, 09:13
Thanks for the sample code,
I think that for having a good comparision with real system it would be necessary to load a different buffer everytime, I mean not from a file but from a sample buffer just like camera acquisition, so we could also check the memory transfer rate from RAM to the board.

Anyway, I'm also looking at qpaintengine_opengl.cpp like Glitch suggested (Arthur painting system) and there the drawImage is implemented using textures and not glDrawPixels.

In conclusion, Arthur painting system could be the solution for who wants to take advantage of using harware acceleration without learning OpenGL directly, unfortunately I can't find good examples for that and the documentations is not helpful.

firas
9th May 2006, 21:37
I'm trying to understand the best way to do such a 2d display,
your use of glDrawPixels is interesting and very fast, and most of all doesn't need to have width and heigh power of 2.
But unfortunately it seems to work differently than other OpenGL rendering, so it's not possible to zoom or resize like when using Texture.
actually it is possible to use the zoom capability. check the QT documentation:

void QGLWidget::resizeGL ( int width, int height ) [virtual protected]
This virtual function is called whenever the widget has been resized. The new size is passed in width and height. Reimplement it in a subclass.
There is no need to call makeCurrent() because this has already been done when this function is called.



So now I'm using
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, width, height,
GL_RGB, GL_UNSIGNED_BYTE, data );

and it's ok even because it automatically resize the width and heigh to be power of 2, but it's very slow if you do that at every frame

re-implement resizeGL(newWidth,newHeight), and it should be ok.


So I just wanted to know if you're using drawpixel for showing a buffer without working on it (zoom, resize, overlays) or it was just a test.

thanks
there are different ways to do (zoom, resize, overlays), like some stuff could be easily done as QImage then you convert that to openGL and do some other stuff and so on..

my inetntion of the test was to find the fastest way of rendering video frames (image sequences) after processing them, e.i. to find the fastest way of displaying the images.