glGenVertexArrays和glGenBuffers参数

时间:2017-08-24 11:15:58

标签: c++ opengl vertex-buffer vertex-array-object

在关于OpenGL 3.0+的教程中,我们以这种方式创建了顶点数组对象和顶点缓冲区对象:

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

在这里,VAO是unsigned intGLuint),我们在函数glGenVertexArray中将其地址传递给它{1̶̶̶̶̶̶̶̶̶̶̶̶̶。。。。。。。。。。。。。。。但是,根据文档,函数的第二个参数应该是 unsigned intGLuint*)的数组。 VBO和glGenBuffers也是如此。我不明白为什么上面的代码可以使用这些参数。

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

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

它编译并执行,但是我得到了一个意想不到的行为:我的纹理矩形使用第一个语法呈现,但不使用第二个语法呈现。我不明白为什么会这样。

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

3 个答案:

答案 0 :(得分:2)

第一个索引是0

GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);

答案 1 :(得分:2)

规范中的函数签名是:

void glGenVertexArrays( GLsizei n,
                        GLuint *arrays);

因此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)并且因为{{1}可以保存这么多数据,以这种方式写它是正确的。并且如果每次调用只创建一个id,则更为可取。

正如其他人所说,数组中的第一个元素具有索引VAO。至此,它必须是:

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具有已定义的大小。

答案 2 :(得分:1)

C和C ++中的数组表示为指针。换句话说,指针相当于一个元素的数组。因此,如果要创建单个缓冲区对象,则可以简单地声明单个变量并将指针传递给它,就像在第一个示例中一样(它不是引用,它是指针)并且那里这没什么不对。我自己一直这样做。

为什么你的第二个例子不起作用,请参阅Jonathan Olson的上述答案。