在有关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 int
和GLuint
不一定是相同的类型或大小,因此unsigned int
的最小保证数字范围是一定的,但是大小在不同的平台上仍可能有所不同。另一方面,GLuint
具有定义的大小。