Цель
Я хотел бы реализовать настоящий виджет для Qt3D, поскольку QWidget::createWindowContainer
просто не подходит для меня.
описание проблемы
Мой первый подход, позволяющий создать новый подкласс класса QWidget
и QSurface
, не увенчался успехом, поскольку код Qt3D либо ожидает QWindow
, либо QOffscreenSurface
в несколько places, и я не хочу перекомпилировать всю базу Qt3D.
Моя вторая идея заключалась в том, чтобы визуализировать содержимое Qt3D на внеэкранной поверхности, а затем нарисовать текстуру на четырехугольнике в QOpenGLWidget
. Когда я использую узел QRenderCapture
framegraph для сохранения изображения, отрендеренного в закадровую текстуру, а затем загружаю изображение в QOpenGLTexture
и рисую его с помощью функции QOpenGLWidget
paintGL
, я вижу визуализированное изображение - т. Е. рендеринг в Qt3D, а также в виджете OpenGL работает правильно. Это просто очень медленно по сравнению с рендерингом содержимого напрямую из Qt3D.
Теперь, когда я использую GLuint
, возвращаемый QTexutre2D
для привязки текстуры во время рендеринга QOpenGLWidget
, все остается черным.
Конечно, это имело бы смысл, если бы контексты QOpenGLWidget
и QT3D были полностью разделены. Но, получив AbstractRenderer
из _ 16_ Мне удалось получить контекст, который Qt3D использует. В моем main.cpp
я поставил
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
Контекст QOpenGLWidget
и Qt3D оба ссылаются на один и тот же общий контекст - я проверил это, распечатав оба с использованием qDebug
, это один и тот же объект.
Разве это не должно позволить мне использовать текстуру из Qt3D?
Или какие-либо другие предложения о том, как реализовать такой виджет? Я просто подумал, что это самый простой способ.
Детали реализации / Что я пробовал до сих пор
Вот как выглядит функция paintGL
в моем QOpenGLWidget
:
glClearColor(1.0, 1.0, 1.0, 1.0);
glDisable(GL_BLEND);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
d->m_shaderProgram->bind();
{
QMatrix4x4 m;
m.ortho(0, 1, 1, 0, 1.0f, 3.0f);
m.translate(0.0f, 0.0f, -2.0f);
QOpenGLVertexArrayObject::Binder vaoBinder(&d->m_vao);
d->m_shaderProgram->setUniformValue("matrix", m);
glBindTexture(GL_TEXTURE_2D, d->m_colorTexture->handle().toUInt());
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
d->m_shaderProgram->release();
m_colorTexture
- это QTexture2D
, который прикреплен к _26 _ / _ 27_, в который Qt3D визуализирует сцену за кадром.
У меня есть QFrameAction
для запуска обновлений розыгрыша на QOpenGLWidget
:
connect(d->m_frameAction, &Qt3DLogic::QFrameAction::triggered, this, &Qt3DWidget::paintGL);
Я убедился, что это действительно вызывает функцию paintGL
. Итак, каждый раз, когда я рисую QOpenGLWidget
, рамка должна быть готова и присутствовать в текстуре.
Я также попытался заменить m_colorTexture
на QSharedGLTexture
. Затем я создал эту текстуру в контексте QOpenGLWidget
, как это
m_texture = new QOpenGLTexture(QOpenGLTexture::Target2D);
m_texture->setFormat(QOpenGLTexture::RGBA8_UNorm);
// w and h are width and height of the widget
m_texture->setSize(w, h);
// m_colorTexture is the QSharedGLTexture
m_colorTexture->setTextureId(m_texture->textureId());
В resizeEvent
функции QOpenGLWdiget
я установил соответствующий размер для этой текстуры, а также для всех закадровых ресурсов Qt3D. Это тоже показывает просто черный экран. Размещение qDebug() << glGetError();
непосредственно после привязки текстуры просто показывает 0
каждый раз, поэтому я предполагаю, что ошибок нет.
Код можно найти здесь, в моем проекте GitHub.
QSurface
(потому чтоQWindow
это делает, аQt3DWindow
является подклассом). Теперь я подумал о создании подклассовQWidget
иQSurface
и передаче поверхностиQRenderSurfaceSelector
Qt3D, но я действительно не знаю, как это реализовать (например, функция, которая возвращаетQPlatformSurface *
), а Qt3D внутренне ожидаетQWindow
илиQOffscreenSurface
, т. Е. Я бы приходится адаптировать много кода Qt3D, что делает невозможным. - person Florian Blume   schedule 04.09.2020QAspectEngine
для обработки кадров и напрямую использую тот же контекст вQOpenGLWidget
и Qt3d, который по крайней мере один раз рисует чистый цвет Qt3D, хотя впоследствии он больше не обновляется. Я до сих пор не понимаю, почему я не могу использовать текстуру из Qt3D с общим контекстом ... - person Florian Blume   schedule 04.09.2020