首页 > 解决方案 > 在实现 OIT 的同时,不同窗口的缓冲区和纹理能否在 OpenGL 中共享同一个绑定点?

问题描述

首先我想说我已经实现了PPLL(Per-Pixel Linked Lists) 可以透明地绘制,一切看起来都很正常。问题发生在我尝试在多个窗口中使用 PPLL 的时候。

我在我的程序中使用 OpenGL 4.5 + QT。用户界面草图如下所示: 在此处输入图像描述

界面分为窗口 0 和窗口 1 两部分,它们从不同的角度渲染相同的东西。窗口 2 将偶尔打开和关闭以显示其他内容。

所有三个窗口都可以正常以透明模式渲染。但是,当窗口 2 关闭时,窗口 0 会变成闪烁无色(而窗口 2 仍然正常),如下图所示。

在此处输入图像描述

以下是每个窗口中 PPLL 的一些实现细节。

三个窗口使用相同的着色器。值得注意的是,PPLL 的片段着色器中的图像为每个窗口共享相同的绑定点。

layout (binding = 0, r32ui)         uniform uimage2D head_pointer_image;        // save the head pointers for all pixels
layout (binding = 1, rgba32ui)      uniform writeonly uimageBuffer list_buffer; // save every fragment data
layout (binding = 0, offset = 0)    uniform atomic_uint list_counter;           // used to assign a unique index for each fragment

每个窗口都有自己的 PPLL 资源(缓冲区和纹理),这些资源将在窗口初始化时应用,在窗口关闭时删除。

GLuint m_headPointerTexture;
GLuint m_headPointerClearBuffer;
GLuint m_atomicCounterBuffer;
GLuint m_linkedListBuffer;
GLuint m_linkedListTexture;
....
glDeleteTextures(1, &m_headPointerTexture);
glDeleteBuffers(1, &m_headPointerClearBuffer);
glDeleteBuffers(1, &m_atomicCounterBuffer);
glDeleteBuffers(1, &m_linkedListBuffer);
glDeleteTextures(1, &m_linkedListTexture);

对于窗口 0 的错误渲染,我有两个猜想:

  1. 对于 glsl 中定义的图像,不同的窗口应该使用不同的绑定点。

  2. 不同的窗口应该共享资源(缓冲区和纹理)。

我对每个猜想都进行了各种测试,但结果都不尽如人意。

更新:

这是一个复杂的项目。我不完全确定该错误与 PPLL 有关。当对象 A 和 B 都在窗口 0 和 1 上绘制时,会发生错误。但是,当我只在窗口 0 和 1 上绘制对象 A(或 B)时,不会发生错误。这很奇怪。我完全疯了。

标签: c++openglglsl

解决方案


我已经解决了这个问题。

该错误发生在window 2关闭的时候,与window 2申请的资源释放有关。

适当调整window 2的解构顺序即可解决问题。

谢谢大家。


推荐阅读