具有自定义帧缓冲区和多个渲染目标的 QOpenGLWidget

2023-12-27

相关我的另一个问题 https://stackoverflow.com/questions/50943629/add-render-target-to-default-framebuffer-of-qopenglwidget,我正在尝试渲染分段蒙版以启用对象拾取。但我无法达到预期的结果。

选项1根本不起作用。我无法检索颜色附件 1 的内容,也无法检查它是否存在(我仅使用本机 OpenGL 调用创建了附件)。

Using this https://forum.qt.io/topic/67640/multiple-render-targets-with-qopenglframebufferobject帖子,我能够重现green.png and red.png通过创建带有第二个颜色附件的自定义帧缓冲区来图像,然后将其绑定并绘制到(全部在paintGL()).

不知何故,我必须使用该人的帧缓冲区创建代码,因为当我自己创建帧缓冲区时,总是有一个警告说toImage called for missing color attachment,虽然我附上了颜色附件并且textures()对帧缓冲区的调用返回了两个对象。然后我尝试在之后插入渲染代码

GLfloat red[4] = { 1.0f, 0.0f, 0.0f, 1.0f };
f->glClearBufferfv(GL_COLOR, 0, red);

GLfloat green[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
f->glClearBufferfv(GL_COLOR, 1, green);

但这仍然产生了红色和绿色的图像。但是当使用普通的默认帧缓冲区时,代码渲染得很好。我将着色器调整为(用于测试目的的简短版本):

void main() {
       gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
       gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);
}

由于我能够生成红色和绿色图像,我假设必须有一种方法可以使用此自定义帧缓冲区检索碎片数据。我现在拥有的解决方案是程序的完整(!)副本和另一个专用片段着色器,其唯一目的是渲染分段,并再次执行所有 OpenGL 绘制调用。正如你所猜测的,这是一个有点丑陋的解决方案,尽管场景不是那么大并且我的计算机能够轻松处理它。有人有想法/链接吗?


如果您想在一个中写入多个渲染目标片段着色器 https://www.khronos.org/opengl/wiki/Fragment_Shader,那么你必须声明多个output https://www.khronos.org/opengl/wiki/Fragment_Shader#Outputs变量:

#version 330

layout(location = 0) out vec4 fragData0;
layout(location = 1) out vec4 fragData1;

void main() 
{
    fragData0 = vec4(1.0, 1.0, 1.0, 1.0);
    fragData1 = vec4(0.0, 0.0, 0.0, 1.0);
}

从 GLSL 版本 1.1 开始(#version 110, OpenGL 2.0) 到 GLSL 版本 1.5 (#version 150,OpenGL 3.2),通过写入内置片段着色器输出变量可以实现相同的效果gl_FragData.

void main() 
{
    gl_FragData[0] = vec4(1.0, 1.0, 1.0, 1.0);
    gl_FragData[1] = vec4(0.0, 0.0, 0.0, 1.0);
}

也可以看看片段着色器输出 - 历代以来 https://io7m.com/documents/fso-tta/


要在 Qt 中使用多个渲染目标,必须将第二个颜色附件添加到帧缓冲区,并且必须通过以下方式指定颜色缓冲区列表glDrawBuffers https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glDrawBuffers.xhtml:

QOpenGLShaderProgram *program;
QOpenGLFramebufferObject *fb; 
int fb_width;
int fb_height,
fb = new QOpenGLFramebufferObject( fb_width, fb_height );
fb->addColorAttachment( fb_width, fb_height );
glViewport(0, 0, fb_width, fb_height);
fb->bind();
glClearColor(0, 0, 0, 1);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );

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

program->bind();
// ..... do the drawing    

program->release();
fb->release();

可以访问附加到帧缓冲区的 OpenGL 纹理对象:

QVector<GLuint> fb_textrues = fb->textures();
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

具有自定义帧缓冲区和多个渲染目标的 QOpenGLWidget 的相关文章

随机推荐