在之前的步骤中,绘制步骤为
绑定Shader glUseProgram(shader)
-> 绑定顶点缓冲区(Vertex Buffer) glBindBuffer(GL_ARRAY_BUFFER, buffer)
-> 设置顶点布局 glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, (const void *)0)
-> 绑定索引缓冲区(Index Buffer) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
如果有了Vertex Array,那么步骤就变为了
绑定Shader glUseProgram(shader)
-> 绑定顶点数组(Vertex Array)
-> 绑定索引缓冲区(Index Buffer) glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, ibo)
不难发现,绑定顶点数组(Vertex Array)替代了原来的 绑定顶点缓冲区(Vertex Buffer) 和 设置顶点布局 两步
Vertex Array的使用
// source Chatgpt
// 顶点数据
GLfloat vertices[] = {
// 顶点位置 // 颜色
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 顶点1
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 顶点2
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶点3
};
// 创建VAO和VBO
GLuint VAO, VBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
// 绑定VAO
glBindVertexArray(VAO);
// 绑定VBO并传输数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// 配置顶点属性指针
// 位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// 颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
// 解绑VBO(不是必须的,但是为了避免后续的误操作,建议这样做)
glBindBuffer(GL_ARRAY_BUFFER, 0);
// 解绑VAO(不是必须的,但是为了避免后续的误操作,建议这样做)
glBindVertexArray(0);
// ...(在这里,你需要创建和设置着色器程序)
// 渲染循环中
while (!glfwWindowShouldClose(window))
{
// ...(在这里,你需要处理输入和清除缓冲区)
// 绘制物体
glUseProgram(shaderProgram); // 使用着色器程序
glBindVertexArray(VAO); // 绑定VAO
glDrawArrays(GL_TRIANGLES, 0, 3); // 绘制三角形
glBindVertexArray(0); // 解绑VAO
// ...(在这里,你需要交换缓冲区和轮询事件)
}
// 删除VAO和VBO
glDeleteVertexArrays(1, &VAO);
glDeleteBuffers(1, &VBO);
如果没有Vertex Array,对比代码
// 顶点数据
GLfloat vertices[] = {
// 顶点位置 // 颜色
0.0f, 0.5f, 0.0f, 1.0f, 0.0f, 0.0f, // 顶点1
0.5f, -0.5f, 0.0f, 0.0f, 1.0f, 0.0f, // 顶点2
-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 顶点3
};
// 创建VBO
GLuint VBO;
glGenBuffers(1, &VBO);
// 绑定VBO并传输数据
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
// ...(在这里,你需要创建和设置着色器程序)
// 渲染循环中
while (!glfwWindowShouldClose(window))
{
// ...(在这里,你需要处理输入和清除缓冲区)
// 绘制物体
glUseProgram(shaderProgram); // 使用着色器程序
// 因为没有VAO,我们需要在每次绘制前设置顶点属性指针
glBindBuffer(GL_ARRAY_BUFFER, VBO);
// 位置属性
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
glEnableVertexAttribArray(0);
// 颜色属性
glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));
glEnableVertexAttribArray(1);
glDrawArrays(GL_TRIANGLES, 0, 3); // 绘制三角形
// 禁用顶点属性指针
glDisableVertexAttribArray(0);
glDisableVertexAttribArray(1);
// ...(在这里,你需要交换缓冲区和轮询事件)
}
// 删除VBO
glDeleteBuffers(1, &VBO);