qt - 将渲染目标添加到 QOpenGLWidget 的默认帧缓冲区

标签 qt opengl framebuffer rendertarget

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

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

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

我能想到的仅有的两个选项是:

1. 使用 native 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] 中检索内容。或者,如果这不起作用,则仅使用 native OpenGL 代码来生成纹理。

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

最佳答案

I'd like to add a second render target to the default framebuffer of a QOpenGLWidget.

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

参见 OpenGL 4.6 API Compatibility Profile Specification; 2.1. EXECUTION MODEL; page 9

There are two classes of framebuffers: a window system-provided framebuffer associated with a context when the context is made current, and application-created framebuffers. The window system-provided framebuffer is referred to as the default framebuffer. Application-created framebuffers, referred to as framebuffer objects, may be created as desired, A context may be associated with two framebuffers, one for each of reading and drawing operations. The default framebuffer and framebuffer objects are distinguished primarily by the interfaces for configuring and managing their state.

The effects of GL commands on the default framebuffer are ultimately controlled by the window system, which allocates framebuffer resources, determines which portions of the default framebuffer the GL may access at any given time, and communicates to the GL how those portions are structured. Therefore, there are no GL commands to initialize a GL context or configure the default framebuffer.
Similarly, display of framebuffer contents on a physical display device (including the transformation of individual framebuffer values by such techniques as gamma correction) is not addressed by the GL.

参见 OpenGL 4.6 API Compatibility Profile Specification; 9.2. BINDING AND MANAGING FRAMEBUFFER OBJECTS; page 340

Framebuffer objects (those with a non-zero name) differ from the default framebuffer in a few important ways. First and foremost, unlike the default framebuffer, framebuffer objects have modifiable attachment points for each logical buffer in the framebuffer.

关于qt - 将渲染目标添加到 QOpenGLWidget 的默认帧缓冲区,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50943629/

相关文章:

python - PyQt 设置列宽

c++ - 在 Qt 中连接多个信号和槽

c++ - 如何检查当前在 OpenGL 中绑定(bind)了哪个帧缓冲区对象?

c - Linux framebuffer像素位域通用实现

c++ - centos7中的qt版本

c++ - lvlc-qt 缺少编译错误

multithreading - 从另一个线程更新映射的 OpenGL 缓冲区

c - 如何使用 OpenGL 按特定顺序绘制贴花?

c++ - 使用 glm 创建 View 矩阵

opengl - 具有 float 纹理钳位值的帧缓冲区对象