目标
我想为 Qt3D 实现一个实际的小部件,因为QWidget::createWindowContainer
它不适合我。
问题描述
我让新类子类化的第一种方法QWidget
并QSurface
没有成功,因为 Qt3D 代码在多个地方QWindow
都需要 a或 a ,我不想重新编译整个 Qt3D 基础。QOffscreenSurface
我的第二个想法是将 Qt3D 内容渲染到屏幕外表面,然后在QOpenGLWidget
. 当我使用QRenderCapture
framegraph 节点将渲染到屏幕外纹理的图像保存,然后将图像加载到 a并在's函数QOpenGLTexture
中绘制它时,我可以看到渲染的图像 -即在 Qt3D 和 OpenGL 小部件中的渲染工作正常。与直接从 Qt3D 渲染内容相比,这非常慢。QOpenGLWidget
paintGL
现在,当我在 的渲染期间使用 的GLuint
返回来绑定纹理时,一切都保持黑色。QTexutre2D
QOpenGLWidget
当然,如果QOpenGLWidget
和 QT3D 的上下文完全分开,这将是有道理的。但是通过从中检索,AbstractRenderer
我QRenderAspectPrivate
能够获得 Qt3D 使用的上下文。在我的main.cpp
我设置
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
Qt3D的QOpenGLWidget
和 的上下文都引用了相同的共享上下文 - 我通过使用打印两者来验证这一点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
附加到Qt3D 将场景渲染到屏幕外的QRenderTargetOutput
/的那个。QRenderTarget
我有一个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 项目中找到。