在有关OpenGL 3.0+的教程中,我们通过以下方式创建“顶点数组对象”和“顶点缓冲区对象”:

GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

在这里,VAO是一个unsigned int(GLuint),我们在函数glGenVertexArray中将其地址传递给它。Vr̶e̶f̶e̶r̶e̶n̶c̶e̶但是,根据文档,该函数的第二个参数应为unsigned int(GLuint*)的数组。 VBO和glGenBuffers也是如此。我不明白为什么上面的代码使用这样的参数。

我试图用此代码替换上面的代码(并在代码的其他位置进行必要的修改):
GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[1]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[1]);

它编译并执行,但是出现了意外的行为:我的纹理矩形使用第一种语法而不是第二种语法渲染。我不明白为什么也会发生这种情况。

编辑:谢谢。如前所述,第二个代码中有一个索引错误。

最佳答案

规格中的功能签名为:



因此,arrays需要一个GLuint指针,在其中可以将n * sizeof(GLuint)字节数据写入其中。

编写以下代码是完全正确和有效的:

GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);

因为glGenVertexArrays想要有一个指向GLuint的指针,在该指针上可以将n * sizeof(GLuint)字节的数据写入其中(在您的情况下为1),并且因为VAO可以容纳此数据量,所以以这种方式写入是正确的。并且,如果您每个 call 仅创建一个ID,则是更可取的。

正如其他人已经指出的那样,数组中的第一个元素的索引为0。因此,它必须是:
GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);

如果要在一个调用中创建更多元素,则要使用std::array而不是[]
std::array<GLuint,3> VAOs;
std::array<GLuint,3> VBOs;

glGenVertexArrays(VAOs.size(), &VAOs[0]);
glGenBuffers(VBOs.size(), &VBOs[0]);

注意unsigned intGLuint不一定是相同的类型或大小,因此unsigned int的最小保证数字范围是一定的,但是大小在不同的平台上仍可能有所不同。另一方面,GLuint具有定义的大小。

08-16 11:36