glGenVertexArrays 和 glGenBuffers 参数

Des*_*ura 4 c++ opengl vertex-buffer vertex-array-object

在有关 OpenGL 3.0+ 的教程中,我们这样创建顶点数组对象和顶点缓冲区对象:

\n\n
GLuint VAO, VBO; \nglGenVertexArrays(1, &VAO);\nglGenBuffers(1, &VBO);\nglBindVertexArray(VAO);\nglBindBuffer(GL_ARRAY_BUFFER, VBO);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这里,VAO 是一个unsigned int( GLuint),我们传递 a\xcc\xb6 \xcc\xb6r\xcc\xb6e\xcc\xb6f\xcc\xb6e\xcc\xb6r\xcc\xb6e\xcc\xb6n\xcc\xb6c\xcc\ xb6e\xcc\xb6 是它在函数中的地址glGenVertexArray。但是,根据文档,函数的第二个参数应该是( )数组 。VBO 和. 我不明白为什么上面的代码适用于这样的参数。unsigned intGLuint*glGenBuffers

\n\n

我尝试用此代码替换上面的代码(并在代码中的其他地方进行必要的修改):

\n\n
GLuint VAO[1];\nGLuint VBO[1];\nglGenVertexArrays(1, VAO);\nglGenBuffers(1, VBO);\nglBindVertexArray(VAO[1]);\nglBindBuffer(GL_ARRAY_BUFFER, VBO[1]);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

编辑:谢谢。如上所述,第二个代码中存在索引错误。

\n

t.n*_*ese 5

规范中的函数签名是:

void glGenVertexArrays( GLsizei n,
                        GLuint *arrays);
Run Code Online (Sandbox Code Playgroud)

因此arrays需要一个可以有效写入数据字节的GLuint 指针。n * sizeof(GLuint)

这样写是完全正确且有效的:

GLuint VAO, VBO; 
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
Run Code Online (Sandbox Code Playgroud)

因为glGenVertexArrays想要有一个指针,指向GLuint有效写入n * sizeof(GLuint)数据字节的位置(在您的情况下1),并且因为VAO可以保存这么多数据,所以以这种方式写入是正确的。如果每次调用只创建一个 id,并且 和 是更好的选择。

正如其他人已经指出的,数组中的第一个元素具有索引0。从那时起它必须是:

GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
Run Code Online (Sandbox Code Playgroud)

如果您想在一次调用中创建更多元素,则需要使用std::arrayover []。

std::array<GLuint,3> VAOs;
std::array<GLuint,3> VBOs;

glGenVertexArrays(VAOs.size(), &VAOs[0]);
glGenBuffers(VBOs.size(), &VBOs[0]);
Run Code Online (Sandbox Code Playgroud)

请注意unsigned int,GLuint不一定是相同的类型或尺寸,unsigned int有最小保证数量范围,但尺寸在不同平台上仍可能有所不同。GLuint另一方面有明确的尺寸。