How to show fast a color buffer
-
Hi,
I'm working on RayTracer Render project and I want to make some UI for it. In the begining I was using SDL to show the result image, but I chose to exchange SDL with Qt and to make some nice UI.
I keep the result (the rendered image) in two dimensional color buffer. The structure of the color is something like this:
struct Color
{
float red;
float green;
float blue;
}The color chanels are from 0 to 1 and it's not a problem to transform them in [0, 255].
The real problem is how to show this buffer fast.
I have a QMainWindow, and a Render custom widget with the buffer and the other ray-tracing logic. The Render widget is the QMainWIndow's center widget.
I tried with drawing a points with QPainter on the widget and for every point I change the color of the pen, but... it takes 2-3sec to show 640x480 image.
I also tried to draw directly on QImage and to show it with QPixmap, QGraphicsScene and QGraphicsView, but... again 2-3sec
With SDL the showing of the buffer was happening immediately.
The drawing in Qt is just slow or I just can't find out the right way.
I'm new with Qt (from 2 days) and I can't find out the best way to do this. Can someone give me some hints or advises?
Thanks s a lot
P.S. Eventually I will want to can save the image in some file. I can use the buffer for that, but... just to note
-
see the QColor constructors:
QColor( int r, int g, int b, int a = 255 )
QColor ( QRgb color )
QRgb is basically an 32bit int value which bytes-groups contain the color values.
You can then use the QColor object and draw it with an QPainter to an QWidget surface or into a QPixmap and save it to a image file.
-
I'm using my Color class for the buffet because I need some extra color functionality and I want to make the core of the render independent of Qt.
When I'm setting the pen color I transfer my Color to QColor.
@
void Render::paintEvent(QPaintEvent *event)
{
QPainter painter(this);QPen pen(QColor(0, 0, 0));
painter.setPen(pen);
for (int i = 0; i < this->height * this->width; i++)
{
Color* currentColor = &this->buffer[i];pen.setColor(QColor(currentColor->red, currentColor->green, currentColor->blue));
painter.setPen(pen);
painter.drawPoint(i % this->width, i / this->width);
}
}
@
I did a test with QColor buffer but the speed is the same... there is not big difference -
SDL is using OpenGL, so the graphics card is used.
Qt uses by default the CPU.Try painting to an "QGLWidget":http://qt-project.org/doc/qt-4.8/QGLWidget.html#details to make Qt use OpenGL.
-
[quote author="raven-worx" date="1390212761"]SDL is using OpenGL, so the graphics card is used.
Qt uses by default the CPU.Try painting to an "QGLWidget":http://qt-project.org/doc/qt-4.8/QGLWidget.html#details to make Qt use OpenGL.[/quote]
I didn't know that Qt usesthe CPU. (I told you I'm new...)
QGLWidget will be fast enought. Thanks a lot. I will try it :)
-
Even if you do the same technique in GL it will be much slower than it should.
You do not want to issue a drawing command for each pixel in your image!
You want to prepare your image buffer to be rendered and then draw it with 1 command.In Qt this would be:
-create a QImage with your pixels (you can even do that without a copy, look at the QImage constructors)
-call QPainter::drawImageIn GL:
-create a gl texture with your data
-draw some shape (a rectangle?) with that texture.Both should be about the same speed since the bottle neck is the upload of the pixel data to the GPU. Both add up to 2 steps (upload and draw) instead of 640x480=307200 draw points !