简体   繁体   English

OpenGL:是否支持在一个上下文中渲染为FBO,然后在另一个上下文中使用FBO的纹理?

[英]OpenGL: Is it supported to render into an FBO in one context, then use the FBO's texture in another?

I have the following OpenGL setup for troubleshooting frame buffer issues: 我具有以下OpenGL设置,用于解决帧缓冲区问题:

  1. I render a cube into a frame buffer. 我将多维数据集渲染到帧缓冲区中。
  2. I use the target texture from this frame buffer to draw a textured quad, which displays the cube in my viewport. 我使用该帧缓冲区中的目标纹理绘制一个纹理四边形,该四边形在我的视口中显示该多维数据集。

This works OK when both stages of the process are done in the same context, but breaks if stage 1 is done in a different context to stage 2 (note that these contexts are both shared and both on the same thread). 当过程的两个阶段都在同一上下文中完成时,此方法可以正常工作,但是如果阶段1在与第二阶段不同的上下文中完成,则会中断(请注意,这些上下文都是共享的,并且都在同一线程上)。 In this case, I only ever see the cube displayed when I resize my viewport (which recreates my frame buffer). 在这种情况下,我只能在调整视口大小(重新创建帧缓冲区)时看到显示的多维数据集。 The cube is sometimes corrupted or fragmented, which leads me to believe that all I'm seeing is parts of memory that were used by the texture before it was resized, and that nothing is ever displayed properly. 多维数据集有时会损坏或碎片化,这使我相信,我所看到的只是纹理调整大小之前纹理所使用的内存部分,并且从未正确显示任何内容。

The reason I have to have this setup is that in my actual application I'm using Qt OpenGL widgets, which are forced to use their own individual contexts, so I have to render my scene in its own dedicated context and then copy it to the relevant viewports using shareable OpenGL resources. 我必须进行此设置的原因是,在我的实际应用程序中,我使用的是Qt OpenGL小部件,这些部件必须使用各自的上下文,因此必须在自己的专用上下文中渲染场景,然后将其复制到使用可共享OpenGL资源的相关视口。 If I don't do this, I get errors caused by VAOs being bound/used in other contexts. 如果我不这样做,我会收到由于VAO在其他情况下绑定/使用而导致的错误。

I've tried the following unsuccessful combinations (where the primary context is where I use the texture to draw the quad, and the secondary context where the "offscreen" rendering of the cube into the frame buffer takes place): 我尝试了以下不成功的组合(主要上下文是我使用纹理绘制四边形的位置,而次要上下文是将多维数据集“脱离屏幕”渲染到帧缓冲区中的位置):

  • Creating the frame buffer, its render buffer and its texture all in the secondary context. 在辅助上下文中创建帧缓冲区,其渲染缓冲区及其纹理。
  • Creating the frame buffer and the render buffer in the secondary context, creating the texture in the primary context, and then attaching the texture to the frame buffer in the secondary context. 在辅助上下文中创建帧缓冲区和渲染缓冲区,在主上下文中创建纹理,然后在辅助上下文中将纹理附加到帧缓冲区。
  • Creating the frame buffer, its render buffer and two separate textures in the secondary context. 在辅助上下文中创建帧缓冲区,其渲染缓冲区和两个单独的纹理。 One of these textures is initially attached to the frame buffer for rendering. 这些纹理之一最初附加到帧缓冲区以进行渲染。 Once the rendering to the frame buffer is complete, the first texture is detached and the second one attached. 渲染到帧缓冲区后,将分离第一个纹理,并附加第二个纹理。 The previously attached texture containing the content of the rendering is used with the quad in the primary context. 先前包含的包含渲染内容的纹理在主要上下文中与四边形一起使用。

In addition, I can't use glBlitFramebuffer() as I don't have access to the frame buffer the QOpenGLWidget uses in the application (as far as I've tried, QOpenGLWidget::defaultFramebufferObject() returns 0 which causes glBlitFramebuffer to give me errors). 另外,由于无法访问QOpenGLWidget在应用程序中使用的帧缓冲区,因此我无法使用glBlitFramebuffer() (据我所尝试, QOpenGLWidget::defaultFramebufferObject()返回0导致glBlitFramebuffer给出我的错误)。

The only way I have managed to get the rendering to work is to use a QOpenGLFrameBuffer and call takeTexture() when I want to use the texture with the quad. 我设法使渲染正常工作的唯一方法是使用QOpenGLFrameBuffer并在要与四边形一起使用纹理时调用takeTexture() However, doing it this way means that the QOpenGLFrameBuffer creates itself a new texture and I have to destroy the old one once I've used it, which seems very inefficient. 但是,以这种方式进行操作意味着QOpenGLFrameBuffer会自己创建一个新纹理,使用后我必须销毁旧纹理,这似乎效率很低。

Is there anything I can do to solve this problem? 有什么我可以解决的问题吗?

I've got a project that uses a texture like that. 我有一个使用这种纹理的项目。 You need to call glFinish() after drawing and before using the texture from QOpenGLFramebufferObject::texture() . 在绘制之后和使用QOpenGLFramebufferObject::texture()的纹理之前,需要调用glFinish() QOpenGLFramebufferObject::texture() That was our problem on some of the OSes. 这是某些操作系统上的问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM