欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

LearnOpenGL | VAO VBO EBO

程序员文章站 2022-07-04 11:37:46
...

LearnOpenGL | VAO VBO EBO

https://learnopengl-cn.github.io/01 Getting started/04 Hello Triangle/

https://blog.csdn.net/dcrmg/article/details/53556664

顶点缓冲对象(Vertex Buffer Objects,VBO)

  • 顶点缓冲对象VBO是在显卡存储空间中开辟出的一块内存缓存区,用于存储顶点的各类属性信息,如顶点坐标,顶点法向量,顶点颜色数据等。在渲染时,可以直接从VBO中取出顶点的各类属性数据,由于VBO在显存而不是在内存中,不需要从CPU传输数据,处理效率更高。
  • VBO就是显存中的一个存储区域,可以保持大量的顶点属性信息。

VBO的创建与配置

  • 创建VBO的第一步需要开辟(声明/获得)显存空间并分配VBO的ID:
unsigned int VBO;
glGenBuffers(1, &VBO);
  • 创建的VBO可用来保存不同类型的顶点数据,创建之后需要通过分配的ID绑定(bind)一下制定的VBO,对于同一类型的顶点数据一次只能绑定一个VBO。
glBindBuffer(GL_ARRAY_BUFFER, VBO); // 绑定VBO
  • 接下来调用glBufferData把用户定义的数据传输到当前绑定的显存缓冲区中。
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
  • 顶点数据传入GPU之后,还需要通知OpenGL如何解释这些顶点数据,这个工作由函数glVertexAttribPointer完成:
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
/* 
第一个参数指定顶点属性位置,与顶点着色器中layout(location=0)对应。
第二个参数指定顶点的属性size
第三个参数指定数据类型
第四个参数定义是否数据被标准化! [-1,1]
第五个参数为步长 Stride,连续顶点之间属性之间的间隔
第六个参数表示,缓冲区起始位置的偏移量
*/

  • 顶点属性glVertexAttribPointer默认是关闭的,使用时要以顶点属性位置值为参数调用glEnableVertexAttribArray开启。
glEnableVertexAttribArray(0);

顶点数组对象(Vertex Arrary Object,VAO)

  • VBO保存了一个模型的顶点属性信息,每次绘制模型之前需要绑定顶点的所有信息,当数据量很大时,重复这样的动作变得非常麻烦。VAO可以把这些所有的配置都存储在一个对象中,每次绘制模型时,只需要绑定这个VAO对象就可以了。
  • VAO是一个保存了所有顶点数据属性的状态结合,它存储了顶点数据的格式以及顶点数据所需的VBO对象的引用。
  • VAO本身并没有存储顶点的相关属性数据,这些信息是存储在VBO中的,VAO相当于是对很多个VBO的引用,把一些VBO组合在一起作为一个对象统一管理。

VAO的创建与配置

  • 生成一个VAO对象并绑定
unsigned int VAO;
glGenVertexArrays(1, &VAO);
glBindVertexArray(VAO); // 绑定VAO
  • 执行VAO绑定之后其后的所有VBO配置都是这个VAO对象的一部分,可以说VBO是对顶点属性信息的绑定,VAO是对很多个VBO的绑定。

非索引绘图

  • OpenGL中所有的图形都是通过分解成三角形的方式进行绘制,glDrawArrays函数负责把模型绘制出来,它使用当前**的着色器,当前VAO对象中的VBO顶点数据和属性配置来绘制出来基本图形。
glUseProgram(shaderProgram);
glBindVertexArray(VAO);
glDrawArrays(GL_TRIANGLES, 0, 3);
/*
 glDrawArrays (GLenum mode, GLint first, GLsizei count)
 第一个参数是绘制的类型
 第二个参数是从缓冲中的哪一位开始绘制
 第三个是绘制的顶点数量
*/

索引缓冲对象(Element Buffer Object,EBO)

  • 索引缓冲对象,和顶点缓存对象一样,也是一个缓存,它专门存储索引,OpenGL调用这些顶点的索引来决定该绘制哪个顶点。
  • 索引缓冲对象EBO相当于OpenGL中的顶点数组的概念,是为了解决同一个顶点多洗重复调用的问题,可以减少内存空间浪费,提高执行效率。
  • 索引绘制(Indexed Drawing)
  • EBO中存储的内容就是顶点位置的索引indices,EBO跟VBO类似,也是在显存中的一块内存缓冲器,只不过EBO保存的是顶点的索引。

EBO的创建与配置

  • 创建EBO并绑定,用glBufferData(以GL_ELEMENT_ARRAY_BUFFER为参数)把索引存储到EBO中
unsigned int EBO;
glGenBuffers(1, &EBO);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

索引绘图

  • 当用EBO绑定顶点索引的方式绘制模型时,需要使用glDrawElements而不是glDrawArrays
glDrawElements(GL_TRIANGLES, izeof(indices)/sizeof(indices[0]), GL_UNSIGNED_INT, 0);
/*
第一个参数指定了要绘制的模式;
第二个参数指定要绘制的顶点个数;
第三个参数是索引的数据类型;
第四个参数是可选的EBO中偏移量设定。
*/