c++ - 为什么 OpenGL 缓冲区解除绑定顺序很重要?
问题描述
我正在使用 C++ 学习 OpenGL (3.3),我可以使用顶点缓冲区对象、顶点数组对象和索引缓冲区绘制简单的多边形,但我编码它们的方式仍然感觉有点像魔术,所以我会喜欢了解幕后发生的事情。
我对 OpenGL 使用的绑定系统有基本的了解。我也知道 VAO 本身包含绑定的索引缓冲区(如此处所指定),如果我没记错的话,绑定的顶点缓冲区也是如此。
按照这个逻辑,我首先绑定 VAO,然后创建我的 VBO(在幕后绑定在 VAO 的“内部”?),我可以在 VBO 上执行操作,并且一切正常。但是当我在完成设置后解绑我使用的缓冲区时,似乎我必须先解绑 VAO,然后是顶点和索引缓冲区,所以解绑的顺序与绑定相同,并且不是相反的顺序。
这是非常反直觉的。所以我的问题是,为什么解除绑定的顺序很重要?
(澄清一下,无论如何我都会在调用之前重新绑定 VAO glDrawElements
,所以我认为我什至不需要解绑任何东西。这主要是为了学习目的)
以下是相关代码:
GLuint VAO, VBO, IBO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO);
glGenBuffers(1, &VBO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
glGenBuffers(1, &IBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
glBindVertexArray(0); //unbinding VAO here is fine
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
glBindBuffer(GL_ARRAY_BUFFER, 0);
//if I unbind VAO here instead, it won't render the shape anymore
while (!glfwWindowShouldClose(window)) {
glfwPollEvents();
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 9, GL_UNSIGNED_INT, 0);
glfwSwapBuffers(window);
}
解决方案
我相信我可能已经想通了。
看着这个解除约束的命令
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO
glBindVertexArray(0); //unbinding VAO
显然“破坏”了我的多边形,因为在我的 VAO 仍然绑定时解除绑定 VBO 意味着应该“包含”对其使用的缓冲区的引用的 VBO 现在不再绑定到顶点缓冲区。它不知道缓冲区。
首先解除绑定 VAO 允许我在不影响缓冲区的情况下解除绑定。这将是正确的顺序。
glBindVertexArray(0); //unbinding VAO
glBindBuffer(GL_ARRAY_BUFFER, 0); //unbinding VBO
OpenGL的绑定系统有点难以掌握,尤其是当不同的事物相互依赖时,但我认为我的解释是正确的。希望这可以帮助将来的其他学习者。
推荐阅读
- python-3.x - 使用 bash 脚本在子目录中运行机器人框架测试
- scipy - 使用单个 GPU 时的内存分配
- java - selenium java 为 xlink:href 属性加载图像
- elasticsearch - 什么时候在 Lucene 中应用删除
- python - 允许用户管理电子邮件的频率?- Python 批量邮件程序
- python - 模块“时间”没有属性“时钟”
- r - R循环遍历子文件夹
- python - 即使满足条件,如果语句未评估为 True
- node.js - 如何即时获取模型参考nestjs mongoose
- angular - 无法加载 npm\ng,因为在此系统上禁用了运行脚本