OpenGL中的状态

时间:2012-06-23 03:00:56

标签: opengl

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

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中格式化顶点。

2 个答案:

答案 0 :(得分:3)

我相信这是因为glVertexAttribPointer的最后一个参数是pointer,它是glBindBuffer(nonzero)之后VBO的偏移,但是当一个VBO没有被绑定时,它应该是一个指针一个实际的数据数组。因此,如果您没有使用VBO,那么最后一个参数将是&vertexes并且它不会崩溃。

答案 1 :(得分:3)

  

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

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

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

  

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

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

  

它并非特定于任何VBO。

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