1.缓冲区的使用:
//创建顶点缓冲区
GLuint VBO,VAO,EBO;
glGenVertexArrays(1,&VAO);
glGenBuffers(1,&VBO); //该函数用于生成缓冲区对象名称
glGenBuffers(1,&EBO);
//绑定缓冲区
glBindVertexArray(VAO);
glBindBuffer(GL_ARRAY_BUFFER,VBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,EBO);
//缓冲区写入数据
glBufferData(GL_ARRAY_BUFFER,sizeof(vertices),vertices,GL_STATIC_DRAW);
glBufferData(GL_ELEMENT_ARRAY_BUFFER,sizeof(indices),indices,GL_STATIC_DRAW);
//缓冲区绑定至变量(设置顶点属性指针)
glVertexAttribPointer(0,3,GL_FLOAT,GL_FALSE,3*sizeof(float),(void *)0);
//开启变量
glEnableVertexAttribArray(0);
2.VAO,VBO,EBO搭配使用
// ..:: 初始化代码 :: ..
// 1. 绑定顶点数组对象
glBindVertexArray(VAO);
// 2. 把我们的顶点数组复制到一个顶点缓冲中,供OpenGL使用
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 3. 复制我们的索引数组到一个索引缓冲中,供OpenGL使用
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
// 4. 设定顶点属性指针
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);
//5.解绑VAO
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindVertexArray(0);
[...]
// ..:: 绘制代码(渲染循环中) :: ..
glUseProgram(shaderProgram);
//使用VAO进行绘制
glBindVertexArray(VAO);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0)
glBindVertexArray(0);
说明:VAO相当于一个中介,解决的是当我们绘制多个物体时的重复性工作,每个物体都要进行VBO,EBO的设置流程然后进行绘制,VAO将VBO和EBO中的设置进行保存,当需要绘制时直接使用VAO就可以进行绘制,(注意:当target是GL_ELEMENT_ARRAY_BUFFER时,VAO会自动存储glBindBuffer的调用,包括解绑的调用,也就是说不可以在解绑VAO之前解绑EBO,否则VAO中就会缺失EBO的数据)OpenGL要求我们必须使用VAO(WebGL中则仅使用VBO,EBO也能够完成绘制)
上面的代码中glBindVertexArray()方法被多次调用可能会造成疑惑,下面做详细说明 glBindVertexArray()可以完成三项任务:
(1)如果传入变量非0且由 glGenVertexArrays()方法进行了分配,那么将创建一个新的顶点数组对象并与其名称相关联起来
(2)如果绑定到一个已经创建的顶点数组对象中,那么会激活该顶点数组对象并且直接影响对象中保存的顶点状态
(3)如果输入变量为0,那么将不再使用程序分配的任何顶点对象并将渲染状态重设为顶点数组的默认状态