要在OpenGL中创建统一的缓冲区对象,为什么必须同时调用glBindBuffer
和glBindBufferRange
?根据{{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时,您会认真考虑要使用该缓冲区,而不仅仅是修改它。
这似乎使我感到困惑,但我不理解这种解释。它说它可以解除绑定到目标的绑定,这似乎强化了我的(错误的)想法,即事先不需要将缓冲区绑定到目标。
答案 0 :(得分:4)
glBufferData
不仅会初始化缓冲区,还会创建具有指定大小的缓冲区对象的数据存储。您可以像使用c ++中的内存分配一样思考它。
glBufferData
为当前绑定到指定目标的缓冲区对象创建数据存储。在这种情况下,它为命名缓冲区对象g_GlobalMatricesUBO
创建了一个数据存储,因为它已绑定到指定的目标GL_UNIFORM_BUFFER
。
glBindBufferRange
不会创建任何数据存储,它使用必须存在的数据存储。具有数据存储区的缓冲区对象由第三个参数指定。