OpenGL 帧缓冲函数在单独 class 中不能完全工作
OpenGL frame-buffer functions not fully working in separate class
我的问题:
当尝试在处理我的渲染循环的主循环之外的单独 class 中执行帧缓冲区操作时,代码会执行并且一些函数会注册,但最终操作的结果不会呈现。
绝对清楚,如果我从单独的 class (GBuffer) 中复制我预期的渲染操作并将其合并到我的主渲染中 class,一切正常。
如果这恰好是错误的问题,另一个问题是 "how do I perform rendering operations outside of the QOpenGLWidget class?"
详情:
在我的渲染循环中,我可以执行以下操作并将场景渲染到我的屏幕上:
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TARGET_FBO);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glClear(GL_COLOR_BUFFER_BIT);
RenderPass();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, TARGET_FBO);
glReadBuffer(GL_COLOR_ATTACHMENT4);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
但是,如果我将渲染通道之前和之后的行移动到单独的 class,例如 GBuffer,代码将 运行 ,但不会呈现任何内容:
GBuffer.StartFrame();
RenderPass();
GBuffer.FinalPass();
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
我的渲染 class 扩展了我的一个名为 DFuncShader 的 class,它包含一个着色器程序并扩展了 QOpenGLFunctions_4_3_Core。我已经为其他几个 classes 这样做了,但没有发现任何问题,但是 none 他们中的一些人以前对帧缓冲区做过任何事情,他们主要只是处理着色器操作。
唯一的区别是我的渲染 class 也继承自 QOpenGLWidget。
我能想到的唯一解决方案是在我的 GBuffer class 中添加一个指向我的主渲染 class 的指针,并使用该指针附加所有 OpenGL 调用,几乎使 class 没有实际意义...
你描述的重构不应该影响结果,因为 OpenGL 只是一个 C API 并且不关心你在它上面做的任何 C++ 包装,只要函数顺序是一样的,参数也是一样的。您确定 TARGET_FBO 在两个版本中相同吗?您可以使用 Apitrace 捕获两个版本的跟踪并进行比较。我怀疑会出现一些可以解释失败的差异。
我缩小了从所提供的 "QOpenGLWidget" class 外部使用时哪些功能不起作用的范围,似乎只要我在主 QOpenGLWidget [=20] 中绑定默认帧缓冲区=],那么一切都很好。
那一行
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
或使用“0”之类的任何变体显然不会在我的任何其他 classes 中发生,除了处理我的渲染循环的那个。
这很容易处理。
我的问题:
当尝试在处理我的渲染循环的主循环之外的单独 class 中执行帧缓冲区操作时,代码会执行并且一些函数会注册,但最终操作的结果不会呈现。
绝对清楚,如果我从单独的 class (GBuffer) 中复制我预期的渲染操作并将其合并到我的主渲染中 class,一切正常。
如果这恰好是错误的问题,另一个问题是 "how do I perform rendering operations outside of the QOpenGLWidget class?"
详情:
在我的渲染循环中,我可以执行以下操作并将场景渲染到我的屏幕上:
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, TARGET_FBO);
glDrawBuffer(GL_COLOR_ATTACHMENT4);
glClear(GL_COLOR_BUFFER_BIT);
RenderPass();
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
glBindFramebuffer(GL_READ_FRAMEBUFFER, TARGET_FBO);
glReadBuffer(GL_COLOR_ATTACHMENT4);
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
但是,如果我将渲染通道之前和之后的行移动到单独的 class,例如 GBuffer,代码将 运行 ,但不会呈现任何内容:
GBuffer.StartFrame();
RenderPass();
GBuffer.FinalPass();
glBlitFramebuffer(0, 0, width, height, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_LINEAR);
我的渲染 class 扩展了我的一个名为 DFuncShader 的 class,它包含一个着色器程序并扩展了 QOpenGLFunctions_4_3_Core。我已经为其他几个 classes 这样做了,但没有发现任何问题,但是 none 他们中的一些人以前对帧缓冲区做过任何事情,他们主要只是处理着色器操作。
唯一的区别是我的渲染 class 也继承自 QOpenGLWidget。
我能想到的唯一解决方案是在我的 GBuffer class 中添加一个指向我的主渲染 class 的指针,并使用该指针附加所有 OpenGL 调用,几乎使 class 没有实际意义...
你描述的重构不应该影响结果,因为 OpenGL 只是一个 C API 并且不关心你在它上面做的任何 C++ 包装,只要函数顺序是一样的,参数也是一样的。您确定 TARGET_FBO 在两个版本中相同吗?您可以使用 Apitrace 捕获两个版本的跟踪并进行比较。我怀疑会出现一些可以解释失败的差异。
我缩小了从所提供的 "QOpenGLWidget" class 外部使用时哪些功能不起作用的范围,似乎只要我在主 QOpenGLWidget [=20] 中绑定默认帧缓冲区=],那么一切都很好。
那一行
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject());
或使用“0”之类的任何变体显然不会在我的任何其他 classes 中发生,除了处理我的渲染循环的那个。
这很容易处理。