Рендеринг QImage на QGLWidget плагина QML - PullRequest
4 голосов
/ 09 декабря 2011

Я пытаюсь написать QML-плагин , который читает кадры из видео (используя пользовательский виджет для выполнения этой задачи, а не QtMultimedia / Phonon), и каждый кадр преобразуется в QImage RGB888, а затем отображается на QGLWidget (по соображениям производительности). В данный момент на экране ничего не отображается, и экран постоянно остается белым.

Важно отметить, что у меня уже все это работает без QGLWidget, поэтому я знаю, что проблема заключается в настройке и рисовании на QGLWidget.

Плагин регистрируется с:

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

так Video является основным классом плагина. По конструктору имеем:

Video::Video(QDeclarativeItem* parent)
: QDeclarativeItem(parent), d_ptr(new VideoPrivate(this))
{    
    setFlag(QGraphicsItem::ItemHasNoContents, false);            

    Q_D(Video);
    QDeclarativeView* view = new QDeclarativeView;
    view->setViewport(&d->canvas()); // canvas() returns a reference to my custom OpenGL Widget
}

Прежде чем перейти к объекту canvas, позвольте мне сказать, что я перегружен Video::paint(), поэтому он вызывает canvas.paint() при передаче QImage в качестве параметра, я не знаю, является ли это правильным способом сделать это поэтому я хотел бы получить несколько советов по этому поводу:

void Video::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
{
    Q_UNUSED(painter);
    Q_UNUSED(widget);
    Q_UNUSED(option);

    Q_D(Video);
    // I know for sure at this point "d->image()" is valid, but I'm hiding the code for clarity
    d->canvas().paint(painter, option, d->image());
}

Объект canvas объявлен как GLWidget canvas;, а заголовок этого класса определен как:

class GLWidget : public QGLWidget
{
    Q_OBJECT
public:        
    explicit GLWidget(QWidget* parent = NULL);
    ~GLWidget();

    void paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image);
};

Кажется, довольно просто. Теперь реализация QGLWidget выглядит следующим образом:

GLWidget::GLWidget(QWidget* parent)
: QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
{
   // Should I do something here?
   // Maybe setAutoFillBackground(false); ???
}

GLWidget::~GLWidget()
{
}

И наконец:

void GLWidget::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QImage* image)
{
   // I ignore painter because it comes from Video, so I create a new one:
   QPainter gl_painter(this);


   // Perform drawing as Qt::KeepAspectRatio

   gl_painter.fillRect(QRectF(QPoint(0, 0), QSize(this->width(), this->height())), Qt::black);

   QImage scaled_img = image->scaled(QSize(this->width(), this->height()), _ar, Qt::FastTransformation);

   gl_painter.drawImage(qRound(this->width()/2)  - qRound(scaled_img.size().width()/2),
                        qRound(this->height()/2) - qRound(scaled_img.size().height()/2),
                        scaled_img); 
}

Чего мне не хватает?

Первоначально я задавал этот вопрос на Qt Forum , но не получил ответов.

Ответы [ 2 ]

5 голосов
/ 13 декабря 2011

решаемые . Проблема заключалась в том, что я пытался создать новый контекст GL в своем плагине, когда мне нужно было извлечь контекст GL из приложения, которое его загрузило.

Этот код был очень полезен , чтобы понять, как этого добиться.

Кстати, я обнаружил, что вещи рисуются внутри view. Просто мне нужно было выполнить view->show(), но это создало другое окно, которое было не тем, что я искал. Ссылка, которой я поделился выше, содержит ответ.

0 голосов
/ 09 декабря 2011

Я думаю, что вы должны рисовать на своем glwidget, используя функции opengl.

Один из возможных способов - переопределить ваш метод paintGL () в GLWidget. а затем нарисуйте свое изображение с помощью glDrawPixels ().

glClear(GL_COLOR_BUFFER_BIT);
glDrawPixels(buffer.width(), buffer.height(), GL_RGBA, GL_UNSIGNED_BYTE, buffer.bits());

Где буфер - это объект QImage, который необходимо преобразовать с помощью статического метода QGLWidget :: converrtToGLFormat ().

Посмотрите на этот источник для справки: https://github.com/nayyden/ZVector/blob/master/src/GLDebugBufferWidget.cpp

...