为什么必须同时使用glBindBuffer和glBindBufferRange在OpenGL中创建统一缓冲区?

时间:2019-06-11 05:58:34

标签: c++ opengl

要在OpenGL中创建统一的缓冲区对象,为什么必须同时调用glBindBufferglBindBufferRange?根据{{​​3}},

  

将glBindBufferRange视为将缓冲区绑定到两个位置:特定索引和目标。 glBindBuffer仅绑定到目标,而不绑定到索引。

因此,如果您已经使用glBindBuffer将缓冲区绑定到同一目标,那么glBindBufferRange对我来说似乎是多余的。

我正在阅读学习现代3D图形编程,documentation显示了如何制作统一的缓冲区对象。书中使用的代码:

glGenBuffers(1, &g_GlobalMatricesUBO);
glBindBuffer(GL_UNIFORM_BUFFER, g_GlobalMatricesUBO);
glBufferData(GL_UNIFORM_BUFFER, sizeof(glm::mat4) * 2, NULL, GL_STREAM_DRAW);
glBindBuffer(GL_UNIFORM_BUFFER, 0);

glBindBufferRange(GL_UNIFORM_BUFFER, g_iGlobalMatricesBindingIndex, g_GlobalMatricesUBO, 0, sizeof(glm::mat4) * 2);

此代码有效,直到我注释掉对glBufferData的调用为止,在这种情况下,我将得到黑屏。这使我感到惊讶,因为此后无论如何我们都将g_GlobalMatricesUBO绑定到GL_UNIFORM_BUFFER绑定目标。链接到前面的文档还说:

  

请注意,这不会用glBindBuffer替换标准缓冲区绑定。实际上,它确实将缓冲区绑定到目标参数,从而取消绑定到该目标的任何内容。但是通常,当您使用glBindBufferRange时,您会认真考虑要使用该缓冲区,而不仅仅是修改它。

这似乎使我感到困惑,但我不理解这种解释。它说它可以解除绑定到目标的绑定,这似乎强化了我的(错误的)想法,即事先不需要将缓冲区绑定到目标。

1 个答案:

答案 0 :(得分:4)

glBufferData不仅会初始化缓冲区,还会创建具有指定大小的缓冲区对象的数据存储。您可以像使用c ++中的内存分配一样思考它。 glBufferData为当前绑定到指定目标的缓冲区对象创建数据存储。在这种情况下,它为命名缓冲区对象g_GlobalMatricesUBO创建了一个数据存储,因为它已绑定到指定的目标GL_UNIFORM_BUFFER

glBindBufferRange不会创建任何数据存储,它使用必须存在的数据存储。具有数据存储区的缓冲区对象由第三个参数指定。