WAYNETS.ORG

Game and Program

OpenGL基础

作者:

发表于

Context Polling System Post-Processing Renderer

一. 顶点数组对象(Vertex Array Object, VAO)

(1)什么是 VAO?

VAO 是一个状态对象,它记录了顶点属性配置的状态,比如:

  • 使用哪个 VBO
  • 每个 glVertexAttribPointer 是怎么设置的
  • 哪些属性启用/禁用(glEnableVertexAttribArray

VAO 是一个记录“顶点输入布局”的容器,保存你告诉 GPU 如何读取顶点数据的信息。

(2)为什么需要 VAO?

OpenGL 3.3 之后,VAO 是必需的。在早期版本中,OpenGL 会自动记录你的配置,但现代 OpenGL 强制你显式指定这些状态,这样可以:

  • 避免错误
  • 提高性能(因为切换 VAO 比重复配置更快)
  • 实现更清晰的渲染流程

(3)VAO 的创建与使用

unsigned int VAO;
glGenVertexArrays(1, &VAO);        //生成VAO
glBindVertexArray(VAO);            //绑定VAO(激活)

//以下这段期间的配置会被VAO记录
glBindBuffer(GL_ARRAY_BUFFER, VBO);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, stride, (void*)0);
glEnableVertexAttribArray(0);     //启用顶点属性数组

//解绑 VAO(可选)
glBindVertexArray(0);

之后,只需要绑定这个 VAO,就可以直接渲染:

glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);

(4)顶点属性(Input Vertex Attribute)

顶点属性是 GPU 渲染管线中,每个顶点附带的数据。例如:

属性名称常见维度类型说明
Positionvec3 (x, y, z)float顶点坐标
Normalvec3float法线方向
TexCoordvec2float纹理坐标
Colorvec4float 或 byte顶点颜色

二. 顶点缓冲对象(Vertex Buffer Object, VBO)

(1)什么是 VBO?

VBO 是显存(GPU memory)中的一块缓冲区,用于存储顶点数据。

通俗来讲:VBO 就是“把顶点数据从 CPU 传到 GPU 的容器”。

这种数据可以包括:

  • 顶点位置(vec3)
  • 颜色(vec3 或 vec4)
  • 法线(vec3)
  • 纹理坐标(vec2)
  • 自定义属性(如骨骼权重、实例索引等)

(2)为什么需要 VBO?

在旧的 OpenGL(如 immediate mode)中,数据是每帧用 glVertex3f() 之类的函数传输的,非常慢。

现代 OpenGL 把数据一次性上传到 GPU(VBO),GPU 可以直接访问,速度极快。

(3)如何使用 VBO?

创建VBO

unsigned int VBO;
glGenBuffers(1, &VBO); // 生成一个缓冲对象 ID

绑定VBO(告诉 OpenGL:我现在操作的是这个缓冲)

glBindBuffer(GL_ARRAY_BUFFER, VBO);

上传数据到GPU

glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

参数解释:

  • GL_ARRAY_BUFFER:类型为顶点数据
  • sizeof(vertices):数据大小(单位是字节)
  • vertices:CPU 端的原始数据
  • GL_STATIC_DRAW:数据使用频率(静态绘制,通常不改动)

完整流程代码

float vertices[] = {
     0.5f,  0.5f, 0.0f,  // 顶点 1
    -0.5f,  0.5f, 0.0f,  // 顶点 2
    -0.5f, -0.5f, 0.0f   // 顶点 3
};

unsigned int VBO;
glGenBuffers(1, &VBO);                             // 创建
glBindBuffer(GL_ARRAY_BUFFER, VBO);                // 绑定
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 上传数据

三. VAO 和 VBO 的关系

项目VBO(Vertex Buffer Object)VAO(Vertex Array Object)
功能存储顶点数据(如位置、颜色、法线)存储“如何读取”这些数据的方式
作用对象实际的 GPU 缓冲区数据属性格式和状态(指针、启用等)
是否必须是,数据载体是,OpenGL 3.3+ 中必须先绑定 VAO 才能绘制
生命周期一般只创建一个大型 VBO 可复用每种绘制结构一般创建一个 VAO

Leave a comment