在关于OpenGL 3.0+的教程中,我们以这种方式创建了顶点数组对象和顶点缓冲区对象:
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER, VBO);
在这里,VAO是unsigned int
(GLuint
),我们在函数glGenVertexArray
中传递̶̶r̶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]);
它编译和执行,但我得到了一个意想不到的行为:我的纹理矩形呈现第一种语法,而不是第二种。我不明白为什么这也会发生。
编辑:谢谢。如前所述,第二个代码中存在索引错误。
发布于 2017-08-24 12:04:08
规范中的函数签名是:
void glGenVertexArrays( GLsizei n,GLuint *数组);
因此,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
可以保存这一数量的数据,所以这样写是正确的。而且,如果每次调用只创建一个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<GLuint,3> VAOs;
std::array<GLuint,3> VBOs;
glGenVertexArrays(VAOs.size(), &VAOs[0]);
glGenBuffers(VBOs.size(), &VBOs[0]);
注意,unsigned int
和GLuint
不一定是相同的类型或大小,unsigned int
有一个最小的保证数量范围,但是在不同的平台上大小仍然可能有所不同。另一方面,GLuint
有一个定义的大小。
发布于 2017-08-24 11:22:44
第一个指数为0
GLuint VAO[1];
GLuint VBO[1];
glGenVertexArrays(1, VAO);
glGenBuffers(1, VBO);
glBindVertexArray(VAO[0]);
glBindBuffer(GL_ARRAY_BUFFER, VBO[0]);
发布于 2017-08-24 11:54:42
C和C++中的数组表示为指针。相反,指针相当于一个元素的数组。因此,如果要创建单个缓冲区对象,可以简单地声明单个变量并传递指向它的指针,就像在第一个示例中所做的那样(它不是引用,而是指针),这没有什么问题。我自己也是这么做的。
关于第二个例子不起作用的原因,请参阅上文的Jonathan的答案。
https://stackoverflow.com/questions/45860198
复制相似问题