关于glBindBuffer绑定通用缓冲区绑定点不直接影响对应状态的疑问
glBindBuffer绑定GL_SHADER_STORAGE_BUFFER等目标的状态疑问解答 咱们先把文档里的那句话拆解明白,再结合你的测试结果理清其中的逻辑:
同样,可使用GL_UNIFORM_BUFFER、GL_ATOMIC_COUNTER_BUFFER和GL_SHADER_STORAGE_BUFFER缓冲区绑定点,但它们分别不会直接影响uniform buffer、atomic counter buffer或shader storage buffer的状态。
这句话的核心是要区分上下文级的通用缓冲区绑定点和缓冲区对象自身的特定状态,两者是完全不同的概念:
当你调用
glBindBuffer(GL_SHADER_STORAGE_BUFFER, buffer)时,你只是把buffer绑定到了当前OpenGL上下文的通用GL_SHADER_STORAGE_BUFFER绑定点上。这个操作影响的是上下文的全局状态,也就是你查询SHADER_STORAGE_BUFFER_BINDING时得到的结果——这也是为什么你测试时会看到返回之前绑定的缓冲区名称,因为这个查询项对应的就是这个通用绑定点的状态。而文档里说的"不会直接影响shader storage buffer的状态",指的是缓冲区对象作为shader storage buffer的核心绑定状态——也就是它和shader程序中特定绑定索引的关联关系。比如你用
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, index, buffer)或者glBindBufferRange时,才是把buffer绑定到了shader对应的索引点上,这部分状态才是真正让shader能访问到该缓冲区的关键,而glBindBuffer到通用绑定点的操作并不会修改这部分状态。
举个直观的例子帮你理解:
- 先执行
glBindBuffer(GL_SHADER_STORAGE_BUFFER, bufferA),此时查询SHADER_STORAGE_BUFFER_BINDING会返回bufferA; - 接着执行
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, bufferB),这时候查询SHADER_STORAGE_BUFFER_BINDING仍然是bufferA,但shader中绑定索引0对应的存储缓冲区已经变成了bufferB。
这就说明:通用绑定点的状态和shader关联的索引绑定状态是相互独立的。你的测试结果和文档表述其实并不矛盾——你观察到的是通用绑定点的状态变化,而文档强调的是这个操作不会影响shader storage buffer与shader绑定的核心状态。
内容的提问来源于stack exchange,提问作者user42768

