December 9, 2011

karlphillip karlphillip
Lab Rat
5 posts

[Solved] Rendering QImage on QGLWidget of QML plugin

 

I’m trying to write a QML plugin that reads frames from a Video (using a custom widget and NOT QtMultimedia/Phonon), then each frame is converted to a QImage with format RGB888, and then displayed on a QGLWidget. Right now nothing seems to be draw on the screen (the screen stays white).

It’s important to state that I already have all of this working without QGLWidget, so I know the issue is setting up and drawing on QGLWidget.

The plugin is being registered with:

  1. qmlRegisterType<Video>(uri,1,0,"Video");

so Video is the main class of the plugin. On it’s constructor we have:

  1. Video::Video(QDeclarativeItem* parent)
  2. : QDeclarativeItem(parent), d_ptr(new VideoPrivate(this))
  3. {    
  4.     setFlag(QGraphicsItem::ItemHasNoContents, false);            
  5.  
  6.     Q_D(Video);
  7.     QDeclarativeView* view = new QDeclarativeView;
  8.     view->setViewport(&d->canvas()); // canvas() returns a reference to my custom OpenGL Widget
  9. }

Before I jump to the canvas object, let me say that I overloaded Video::paint() so it calls canvas.paint() while passing QImage as parameter, I don’t know if this is the right way to do it so I would like some advice on this:

  1. void Video::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
  2. {
  3.     Q_UNUSED(painter);
  4.     Q_UNUSED(widget);
  5.     Q_UNUSED(option);
  6.  
  7.     Q_D(Video);
  8.     // I know for sure at this point "d->image()" is valid, but I'm hiding the code for clarity
  9.     d->canvas().paint(painter, option, d->image());
  10. }

The canvas object is declared as GLWidget canvas; and the header of this class is defined as:

  1. class GLWidget : public QGLWidget
  2. {
  3.     Q_OBJECT
  4. public:        
  5.     explicit GLWidget(QWidget* parent = NULL);
  6.     ~GLWidget();
  7.  
  8.     void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image);
  9. };

Seems pretty simple. Now, the implementation of QGLWidget is the following:

  1. GLWidget::GLWidget(QWidget* parent)
  2. : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
  3. {
  4.    // Should I do something here?
  5.    // Maybe setAutoFillBackground(false); ???
  6. }
  7.  
  8. GLWidget::~GLWidget()
  9. {
  10. }

And finally:

  1. void GLWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image)
  2. {
  3.    // I ignore painter because it comes from Video, so I create a new one:
  4.    QPainter gl_painter(this);
  5.  
  6.  
  7.    // Perform drawing as Qt::KeepAspectRatio
  8.  
  9.    gl_painter.fillRect(QRectF(QPoint(0, 0), QSize(this->width(), this->height())), Qt::black);
  10.  
  11.    QImage scaled_img = image->scaled(QSize(this->width(), this->height()), _ar, Qt::FastTransformation);
  12.  
  13.    gl_painter.drawImage(qRound(this->width()/2)  - qRound(scaled_img.size().width()/2),
  14.                         qRound(this->height()/2) - qRound(scaled_img.size().height()/2),
  15.                         scaled_img);
  16. }

What am I missing?

2 replies

December 13, 2011

karlphillip karlphillip
Lab Rat
5 posts

The answer for this question is here [stackoverflow.com].

December 13, 2011

koahnig koahnig
Gene Splicer
2904 posts

Welcome to devnet

Thanks for sharing the solution. Please mark the title line with [Solved]. This helps others to see that there is a solution available, if they have a similar question.

 
  ‹‹ Need to know the CPU Power and disk space for a QML UI Application      QTouchEvent::TouchPoint pressure information ››

You must log in to post a reply. Not a member yet? Register here!