0

这是一些绘制到屏幕上的简单代码。

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glBindBuffer(GL_ARRAY_BUFFER, vbo);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

这工作正常。但是,我尝试更改一些 GL 调用的顺序,如下所示:

GLuint vbo;

glGenBuffers(1, &vbo);

glUseProgram(myProgram);

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);

//Now comes after the setting of the vertex attributes.
glBindBuffer(GL_ARRAY_BUFFER, vbo);

//Fill up my VBO with vertex data
glBufferData(GL_ARRAY_BUFFER, sizeof(vertexes), &vertexes, GL_STATIC_DRAW);

/*Draw to the screen*/

这使我的程序崩溃。GL_ARRAY_BUFFER为什么在设置顶点属性时需要绑定一个 VBO ?对我来说,glVertexAttribPointer所做的只是设置 OpenGL 最终用来绘制事物的顶点格式。它不是特定于任何 VBO。因此,如果多个 VBO 想要使用相同的顶点格式,则无需再次格式化 VBO 中的顶点。

4

2 回答 2

3

我相信这是因为最后一个参数glVertexAttribPointerpointer在 VBO 之后的偏移量,glBindBuffer(nonzero)但是当 VBO 未绑定时,它应该是指向实际数据数组的指针。因此,如果您根本不使用 VBO,则最后一个参数将是&vertexes并且它不会崩溃。

于 2012-06-23T03:11:57.400 回答
3

为什么我只是设置顶点属性时需要绑定到 GL_ARRAY_BUFFER 的 VBO?

不,您不是“只是”设置顶点属性。您实际上是在使用当前绑定的缓冲区对象创建一个引用。

如果没有绑定缓冲区对象,则 gl...Pointer 将创建对指向给定地址的进程地址空间的引用。由于在您的情况下这是一个空指针,因此任何取消引用顶点的尝试都会导致分段错误/访问冲突。

对我来说,glVertexAttribPointer 所做的只是设置 OpenGL 最终用来绘制事物的顶点格式。

不,它还创建了从何处获取数据的引用。

它不是特定于任何 VBO。

是的,它实际上特定于绑定的 VBO,或者如果没有绑定 VBO,则特定于进程地址空间。并且更改缓冲区绑定不会沿 gl…指针引用更新。

于 2012-06-23T11:20:33.143 回答