Подтвердить что ты не робот

Рендеринг настраиваемого opengl в qt5 qtquick 2.0

Я ищу способ отображения своих пользовательских вызовов opengl внутри элемента qtquick 2.0. Чтобы дать вам некоторый контекст: у меня есть С++ 3d engine, который использует opengl для рендеринга. Цель состоит в том, чтобы сделать рендеринг внутри пользовательского интерфейса qtquick 2.0.

То, что я узнал, это то, что pre qt 5.0 (qtquick 2.0) вы использовали QtGlWidget и вставляете его в QDeclarativeView. Другой способ, который я нашел, - использовать QtDeclarativeItem и переопределить метод void QDeclarativeItem:: paint (QPainter * p, const QStyleOptionGraphicsItem * o, QWidget * w).

Как я понимаю, это невозможно, поскольку QtQuick 2.0 использует новый рендерер, основанный на OpenGl. Поэтому, как представляется, это не так просто, как переопределение метода краски.

Кто-нибудь знает, как я буду реализовывать QQuickItem, который позволяет выполнять мои вызовы opengl?

4b9b3361

Ответ 1

Вы можете сделать одну из двух вещей. Либо сделайте свой контент в текстуре, либо визуализируйте в контексте OpenGL графика сцены, подключив его с помощью сигналов QQuickWindow::beforeRendering или QQuickWindow::afterRendering.

Пример использования FBO и текстуры можно найти здесь: http://doc.qt.io/qt-5/qtquick-scenegraph-textureinsgnode-example.html

Пример того, как визуализировать непосредственно контекст OpenGL графа сцены можно найти здесь: http://doc.qt.io/qt-5/qtquick-scenegraph-openglunderqml-example.html

Ответ 2

В вашем 3D-движке визуализируйте текстуру и в QQuickItem используйте QSGSimpleTextureNode, чтобы показать результаты рендеринга. QtQuick поддерживает его собственное состояние GL, которое вы могли бы испортить, поэтому рекомендуется использовать только классы QSG * для показа пользовательского контента. В принципе, простой QtQuick - это инструмент для рендеринга прямоугольников, а не 3D-контента в целом.

Пример

(Lame):

QScopedPointer<QSGTexture> texture_;

QSGNode* MyItem::updatePaintNode(QSGNode* node, UpdatePaintNodeData*)
{
  if (width() <= 0 || height() <= 0)
  {
    texture_.reset();

    delete node;
    return 0;
  }
  else
  {
    if (!node)
    {
      node = new QSGSimpleTextureNode;

      static_cast<QSGSimpleTextureNode*>(node)
        ->setFiltering(QSGTexture::Nearest);
    }
    // else do nothing

    static_cast<QSGSimpleTextureNode*>(node)->setRect(boundingRect());

    getTheTextureFrom3DEngine(texture_);

    Q_ASSERT(texture_);
    static_cast<QSGSimpleTextureNode*>(node)->setTexture(texture_.data());

    return node;
  }
}

Вам также необходимо создать экземпляр таймера для обновления содержимого. Вы можете сделать это из QQuickItem.