在我的应用程序中,我有一个使用OpenGL管理渲染的模块,并将结果呈现为QOpenGLFrameBufferObjects
。我知道这很有用,因为我可以使用QOpenGLFrameBufferObject::toImage()
保存其内容并查看渲染。
我现在尝试获取从QOpenGLFrameBufferObject::texture()
返回的纹理ID,将其绑定为普通的OpenGL纹理,并使用全屏四边形将其渲染到QOpenGLWidget
视口中。 (我正在使用这个两步法,因为我不知道如何解决QOpenGLWidgets
每个都在他们自己的环境中工作的事实,但这是一个不同的故事。)
这里的问题是glBindTexture()
在我调用它时会返回InvalidOperation
。根据OpenGL文档,这是因为“[The]纹理之前创建的目标与[输入]的目标不匹配。”但是,我通过将GL_TEXTURE_2D
传递给构造函数来创建帧缓冲区对象,并将其作为目标传递给glBindTexture()
,所以我不确定我哪里出错了。网上没有太多关于如何正确使用QOpenGLFrameBufferObject::texture()
的文档。
其他补充信息,如果有帮助:
QOpenGLFrameBufferObject::isValid()
返回true; glIsTexture()
会返回false,但我不知道为什么会给出这是因为Qt为了绑定OpenGL纹理而提供给我的值。 OpenGL文档确实提到“由glGenTextures返回的名称,但通过调用glBindTexture尚未与纹理相关联,不是纹理的名称”,但在这里我无论如何都无法绑定它。QOpenGLWidget
的上下文而不是渲染模块的上下文)。我将提供一些代码,但我所拥有的很多内容都是特定于渲染模块中存在的系统,因此只有少量相关的OpenGL代码。
在渲染模块上下文中:
QOpenGLFrameBufferObject fbo = new QOpenGLFrameBufferObject(QSize(...), GL_TEXTURE_2D);
// Do some rendering in this context later
在QOpenGLWidget
上下文中,在渲染模块中渲染到帧缓冲区之后:
GLuint textureId = fbo->texture();
glBindTexture(GL_TEXTURE_2D, textureId)) // Invalid operation
编辑:事实证明,罪魁祸首是我的上下文实际上并未被共享,因为我误解了Qt::AA_ShareOpenGLContexts
应用程序属性的作用。一旦我正确地分享了它们,问题就解决了。