3

我想将第二个渲染目标添加到 QOpenGLWidget 的默认帧缓冲区。

原因是我想实现对象拾取并通过将分割掩码渲染到gl_FragData[1]. 不幸的是,您只能GLuint从小部件中检索句柄,并且在句柄中没有构造函数,QOpenGLFramebufferObject也没有其他选项可以检索帧缓冲区。

是否有可能在没有变通方法的情况下将另一个纹理附加到小部件的默认帧缓冲区?

我能想到的唯一两个选择是:

1. 在初始化时使用原生OpenGL调用(我宁愿坚持纯Qt)附加纹理(当然我会存储segmentationTexture以便以后删除它):

glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
QOpenGLTexture *segmentationTexture = new QOpenGLTexture(QOpenGLTexture::BindingTargetBuffer);
// set texture parameters
segmentationTexture.create();
segmentationTexture.bind();
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, segmentationTexture.textureId(), 0);
segmentationTexture.release();

然后在paintGL()

GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1 };
glDrawBuffers(2, buffers);

在 OpenGL 绘制调用之前并用于glReadBuffer(GL_COLOR_ATTACHMENT1);gl_FragData[1]. 或者,如果这不起作用,则仅使用本机 OpenGL 代码来生成纹理。

2. 创建第二个帧缓冲区对象,将其绑定,paintGL()然后使用默认帧缓冲区交换内容glBlitFramebuffer(以考虑多重采样)以显示渲染,但使用第二个帧缓冲区从gl_FragData[1]. 但这感觉有点“讨厌”。

4

2 回答 2

1

我想将第二个渲染目标添加到QOpenGLWidget.

答案很简单,您不能向任何 OpenGL 默认帧缓冲区对象添加第二个颜色附件。

请参阅OpenGL 4.6 API 兼容性配置文件规范;2.1。执行模型;第 9 页

有两类帧缓冲区:当上下文成为当前上下文时,窗口系统提供的帧缓冲区与上下文相关联,以及应用程序创建的帧缓冲区。窗口系统提供的帧缓冲区称为默认帧缓冲区。应用程序创建的帧缓冲区,称为帧缓冲区对象,可以根据需要创建。一个上下文可以与两个帧缓冲区相关联,一个用于读取和绘图操作中的每一个。默认帧缓冲区和帧缓冲区对象主要通过用于配置和管理其状态的接口来区分。

GL 命令对默认帧缓冲区的影响最终由窗口系统控制,窗口系统分配帧缓冲区资源,确定 GL 在任何给定时间可以访问默认帧缓冲区的哪些部分,并与 GL 沟通这些部分的结构。因此,没有用于初始化 GL 上下文或配置默认帧缓冲区的 GL 命令。
类似地,GL 没有解决在物理显示设备上显示帧缓冲区内容(包括通过伽马校正等技术转换单个帧缓冲区值)的问题。

请参阅OpenGL 4.6 API 兼容性配置文件规范;9.2. 绑定和管理帧缓冲对象;第 340 页

帧缓冲区对象(那些具有非零名称的对象)在一些重要方面与默认帧缓冲区不同。首先,与默认帧缓冲区不同,帧缓冲区对象对帧缓冲区中的每个逻辑缓冲区都有可修改的连接点。

于 2018-06-21T16:53:54.453 回答
0

对于挑选,你可以只渲染到一个单独的QOpenGLFramebufferObject,即:

makeCurrent();
glPushAttrib(GL_VIEWPORT_BIT);
glViewport(0, 0, width(), height());
QOpenGLFramebufferObject fbo(width(), height(), QOpenGLFramebufferObject::CombinedDepthStencil);
fbo.bind();
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
[…] render stuff […]
fbo.release();
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT);
glPopAttrib();
QImage fboImage(fbo.toImage());
QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);

另请参阅toImage 文档解释 2 QImages 的必要性。

于 2018-06-21T21:22:52.990 回答