searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

OpenGL缓冲对象之VBO、EBO、VAO

2023-11-28 02:37:10
12
0

介绍

  • VBO(Vertex Buffer Objects)顶点缓冲区对象,指的是在 GPU 显存里面存储的顶点数据(位置、颜色)
  • EBO/IBO(Element/Index Buffer Object)索引缓冲区对象,指的是为了更高效的利用数据,存储索引来达到减少重复数据的索引数据
  • VAO(Vertex Array Object)顶点数组对象,主要作用是用于管理 VBO 或 EBO,减少 glBindBuffer、glEnableVertexAttribArray、glVertexAttribPointer 这些调用操作,高效地实现在顶点数组配置之间切换。

VBO与EBO

OpenGL在调用glDraw*函数的时候,需要从内存中拷贝顶点数据到显存中,这样就存在一些性能消耗,如果在GPU显存中直接缓存这些数据的话,就可以大幅减少 CPU 内存到 GPU 显存的数据拷贝的开销,这就是 VBO 和 EBO 出现的原因。VBO 和 EBO 的作用是在 GPU 显存中开辟一块存储空间来缓存顶点数据或者图元索引数据,避免每次绘制时 CPU 内存到 GPU 显存的数据拷贝,从而提升渲染性能。

VBO是用来缓存顶点数据

VBO的内存布局

如有以下的顶点数据,他的内存布局

GLfloat vertices[] = {
    // 位置               // 颜色
     0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下
    -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下
     0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部
};

 

EBO是用用来缓存glDrawElements函数时的索引数据

 

样例代码:

// 这次我们只定义了 4 个顶点:
GLfloat vertices[] = {
     0.5f,  0.5f, 0.0f, // 右上角
     0.5f, -0.5f, 0.0f, // 右下角
    -0.5f, -0.5f, 0.0f, // 左下角
    -0.5f,  0.5f, 0.0f  // 左上角
};

// 但是通过索引指定了每个三角形的 3 个顶点:
GLuint indices[] = { // 注意索引从 0 开始! 
    0, 1, 3, // 第一个三角形
    1, 2, 3  // 第二个三角形
};

// 使用 VBO:
GLuint VBO;
glGenBuffers(1, &VBO); // 创建 VBO 对象
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 把新创建的 VBO 绑定到 GL_ARRAY_BUFFER 目标上,同时也绑定到了 OpenGL 渲染管线上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 将顶点数据 (CPU 内存) 拷贝到 VBO(GPU 显存)

// 使用 EBO:
GLuint EBO;
glGenBuffers(1, &EBO); // 创建 EBO 对象
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // 把新创建的 EBO 绑定到 GL_ELEMENT_ARRAY_BUFFER 目标上,同时也绑定到了 OpenGL 渲染管线上
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // 将顶点数据 (CPU 内存) 拷贝到 EBO(GPU 显存)

// 绘制:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 使用 glDrawElements 来绘制

 

VAO

VAO的作用与VBO和EBO有所不同,VAO主要是用来管理VBO或者EBO,减少 glBindBuffer、glEnableVertexAttribArray、glVertexAttribPointer 这些调用操作

// 创建 VBO:
GLuint VBO;
glGenBuffers(1, &VBO); // 创建 VBO 对象

// 创建 VAO:
GLuint VAO;
glGenVertexArrays(1, &VAO); // 创建 VAO 对象,注意这里用的是 glGenVertexArrays

// 在绑定 VAO 后操作 VBO,当前 VAO 会记录 VBO 的操作,我们下面用缩进表示操作 VBO 的代码:
glBindVertexArray(VAO); // 绑定 VAO,注意这里用的是 glBindVertexArray
    // 绑定 VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // 把顶点数组复制到缓冲中供 OpenGL 使用
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    // 设置顶点属性指针
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0);
    glEnableVertexAttribArray(0);

 

 

0条评论
0 / 1000
刘****成
3文章数
0粉丝数
刘****成
3 文章 | 0 粉丝
刘****成
3文章数
0粉丝数
刘****成
3 文章 | 0 粉丝
原创

OpenGL缓冲对象之VBO、EBO、VAO

2023-11-28 02:37:10
12
0

介绍

  • VBO(Vertex Buffer Objects)顶点缓冲区对象,指的是在 GPU 显存里面存储的顶点数据(位置、颜色)
  • EBO/IBO(Element/Index Buffer Object)索引缓冲区对象,指的是为了更高效的利用数据,存储索引来达到减少重复数据的索引数据
  • VAO(Vertex Array Object)顶点数组对象,主要作用是用于管理 VBO 或 EBO,减少 glBindBuffer、glEnableVertexAttribArray、glVertexAttribPointer 这些调用操作,高效地实现在顶点数组配置之间切换。

VBO与EBO

OpenGL在调用glDraw*函数的时候,需要从内存中拷贝顶点数据到显存中,这样就存在一些性能消耗,如果在GPU显存中直接缓存这些数据的话,就可以大幅减少 CPU 内存到 GPU 显存的数据拷贝的开销,这就是 VBO 和 EBO 出现的原因。VBO 和 EBO 的作用是在 GPU 显存中开辟一块存储空间来缓存顶点数据或者图元索引数据,避免每次绘制时 CPU 内存到 GPU 显存的数据拷贝,从而提升渲染性能。

VBO是用来缓存顶点数据

VBO的内存布局

如有以下的顶点数据,他的内存布局

GLfloat vertices[] = {
    // 位置               // 颜色
     0.5f, -0.5f, 0.0f,  1.0f, 0.0f, 0.0f,   // 右下
    -0.5f, -0.5f, 0.0f,  0.0f, 1.0f, 0.0f,   // 左下
     0.0f,  0.5f, 0.0f,  0.0f, 0.0f, 1.0f    // 顶部
};

 

EBO是用用来缓存glDrawElements函数时的索引数据

 

样例代码:

// 这次我们只定义了 4 个顶点:
GLfloat vertices[] = {
     0.5f,  0.5f, 0.0f, // 右上角
     0.5f, -0.5f, 0.0f, // 右下角
    -0.5f, -0.5f, 0.0f, // 左下角
    -0.5f,  0.5f, 0.0f  // 左上角
};

// 但是通过索引指定了每个三角形的 3 个顶点:
GLuint indices[] = { // 注意索引从 0 开始! 
    0, 1, 3, // 第一个三角形
    1, 2, 3  // 第二个三角形
};

// 使用 VBO:
GLuint VBO;
glGenBuffers(1, &VBO); // 创建 VBO 对象
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 把新创建的 VBO 绑定到 GL_ARRAY_BUFFER 目标上,同时也绑定到了 OpenGL 渲染管线上
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 将顶点数据 (CPU 内存) 拷贝到 VBO(GPU 显存)

// 使用 EBO:
GLuint EBO;
glGenBuffers(1, &EBO); // 创建 EBO 对象
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); // 把新创建的 EBO 绑定到 GL_ELEMENT_ARRAY_BUFFER 目标上,同时也绑定到了 OpenGL 渲染管线上
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); // 将顶点数据 (CPU 内存) 拷贝到 EBO(GPU 显存)

// 绘制:
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); // 使用 glDrawElements 来绘制

 

VAO

VAO的作用与VBO和EBO有所不同,VAO主要是用来管理VBO或者EBO,减少 glBindBuffer、glEnableVertexAttribArray、glVertexAttribPointer 这些调用操作

// 创建 VBO:
GLuint VBO;
glGenBuffers(1, &VBO); // 创建 VBO 对象

// 创建 VAO:
GLuint VAO;
glGenVertexArrays(1, &VAO); // 创建 VAO 对象,注意这里用的是 glGenVertexArrays

// 在绑定 VAO 后操作 VBO,当前 VAO 会记录 VBO 的操作,我们下面用缩进表示操作 VBO 的代码:
glBindVertexArray(VAO); // 绑定 VAO,注意这里用的是 glBindVertexArray
    // 绑定 VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // 把顶点数组复制到缓冲中供 OpenGL 使用
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); 
    // 设置顶点属性指针
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (GLvoid *) 0);
    glEnableVertexAttribArray(0);

 

 

文章来自个人专栏
GPU
3 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0