这是一些绘制到屏幕上的简单代码。
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中格式化顶点。
答案 0 :(得分:3)
我相信这是因为glVertexAttribPointer
的最后一个参数是pointer
,它是glBindBuffer(nonzero)
之后VBO的偏移,但是当一个VBO没有被绑定时,它应该是一个指针一个实际的数据数组。因此,如果您没有使用VBO,那么最后一个参数将是&vertexes
并且它不会崩溃。
答案 1 :(得分:3)
为什么在我设置顶点属性时需要绑定到GL_ARRAY_BUFFER的VBO?
不,你不是“只是”设置顶点属性。您实际上是使用当前绑定的缓冲区对象创建引用。
如果没有绑定缓冲区对象,则gl ...指针将创建对指向给定地址的进程地址空间的引用。由于这是一个空指针,因此任何取消引用顶点的尝试都会导致分段错误/访问冲突。
对我来说,glVertexAttribPointer所做的只是设置OpenGL最终用于绘制内容的顶点格式。
没有。它还创建了从何处获取数据的引用。
它并非特定于任何VBO。
是的,它实际上特定于绑定的VBO,或者如果没有绑定VBO则为进程地址空间。并且更改缓冲区绑定不会沿着gl ...指针引用更新。