Vertex Array

在之前的步骤中,绘制步骤为

绑定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);

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

大纲

Share the Post:
滚动至顶部