如何解决在OpenGL中使用Qt3D屏幕外渲染纹理 目标问题描述实施细节/到目前为止我已经尝试过的
目标
我想为Qt3D实现一个实际的小部件,因为QWidget::createWindowContainer
只是不适合我使用。
问题描述
我让第一个新类子类QWidget
和QSurface
的第一种方法没有成功,因为Qt3D代码期望{{3}中有QWindow
或QOffscreenSurface
} multiple,但我不想重新编译整个Qt3D基础。
我的第二个想法是将Qt3D内容渲染到屏幕外的表面,然后在QOpenGLWidget
中的四边形上绘制纹理。当我使用QRenderCapture
框架图节点将渲染的图像保存到屏幕外纹理,然后将图像加载到QOpenGLTexture
并在QOpenGLWidget
的{{1}}函数中绘制时我可以看到渲染的图像-即在Qt3D以及OpenGL小部件中进行渲染均可正常工作。与直接从Qt3D渲染内容相比,这非常慢。
现在,当我使用places返回的paintGL
绑定GLuint
的渲染过程中的纹理时,一切都保持黑色。
如果QOpenGLWidget
和QT3D的上下文是完全分开的,那么这当然是有道理的。但是,通过从QTexutre2D
中检索AbstractRenderer
,我可以获得Qt3D使用的上下文。在我的QOpenGLWidget
中设置
main.cpp
QApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
和Qt3D的上下文都引用相同的共享上下文-我通过使用QOpenGLWidget
进行打印来验证了这一点,它们是同一对象。
这不是让我使用Qt3D中的纹理吗?
或者关于如何实现这种小部件的其他建议?我只是认为这是最简单的方法。
实施细节/到目前为止我已经尝试过的
这就是我的qDebug
中的paintGL
函数的样子:
QOpenGLWidget
glClearColor(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.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,4);
}
d->m_shaderProgram->release();
是m_colorTexture
,它附加到Qt3D将场景渲染到屏幕外的QTexture2D
/ QRenderTargetOutput
上。
我有一个QRenderTarget
来触发QFrameAction
上的绘图更新:
QOpenGLWidget
我已验证这确实调用了connect(d->m_frameAction,&Qt3DLogic::QFrameAction::triggered,this,&Qt3DWidget::paintGL);
函数。因此,每次我绘制paintGL
时,框架都应该准备好并出现在纹理中。
我还尝试将QOpenGLWidget
替换为QRenderAspectPrivate
。然后,我使用m_colorTexture
的上下文创建了这种纹理
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());
的{{1}}函数中,我为此纹理以及所有Qt3D屏幕外资源设置了适当的大小。这也仅显示黑屏。绑定纹理后直接放置resizeEvent
每次都会显示QOpenGLWdiget
,因此我认为没有任何错误。
可以找到代码QSharedGLTexture
。
解决方法
尽管我没有找到确切的解决方案,但自从我成功创建了Qt3D小部件后,我将在此处发布答案。
可以找到代码here。这不是最干净的解决方案,因为我认为应该可以以某种方式使用共享纹理。相反,现在我在Qt3D上设置QOpenGLWidget
的上下文,为此我必须使用Qt3D的私有类。这意味着Qt3D直接绘制到由OpenGL小部件绑定的帧缓冲区上。不幸的是,现在该小部件必须是渲染驱动程序,并通过调用QAspectEngine
在processFrame
上执行手动更新。理想情况下,我希望将所有处理循环都留给Qt3D,但至少现在该小部件可以按原样工作。
编辑:
我在手动测试here中找到了QSharedGLTexture
的示例。它以相反的方式工作,即OpenGL渲染纹理,而Qt3D使用它,因此我认为应该可以反转方向。不幸的是,QSharedGLTexture
似乎有点不稳定,因为调整OpenGL窗口的大小有时会使应用程序崩溃。这就是为什么我现在坚持使用我的解决方案的原因。但是,如果有人有关于此问题的新闻,请随时发布答案!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。