VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VAO 和 EBO 实际上是对同一类 GL_ELEMENT_ARRAY_BUFFER, m_VboIds[1]); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0); VAO VAO 与 VBO 之间的关系 基于上小节的例子创建 VAO : // 创建并绑定 VAO glGenVertexArrays(1, &m_VaoId); glBindVertexArray(m_VaoId ); // 在绑定 VAO 之后,操作 VBO ,当前 VAO 会记录 VBO 的操作 glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); glEnableVertexAttribArray sizeof(GLfloat))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[1]); glBindVertexArray(GL_NONE); 使用 VAO
注:参考自bilibili系列视频,OpenGL 从入门到成魔-第4章-VAO 和 VBO https://www.bilibili.com/video/BV1zt4y1C7dh OpenGL中的坐标系 glDeleteBuffers() 释放VBO VAO ? image.png glGenVertexArrays(1, &VAO) 创建 glBindVertexArray(VAO) 绑定当前使用的VAO。 由于OpenGL是个状态机,当绑定当前VAO之后,后面的VBO操作自然而然的都是在该VAO上进行的。 glDeleteVertexArrays 释放VAO
用户输入的数据 以 顶点数组对象表示 Vertex Array Object,VAO void glGenVertexArrays(GLsizei n, GLuint *arrays); 返回 n个 application-allocated vertex-array objects and returns to the default state for vertex arrays. enum VAO_IDs 打个简单的比分,类似大家做高铁去目的地,VAO 就像一个个人,VBO 就是高铁,等很多人都到高铁站台了,我们通过 VBO 高铁将大家一起打包快速的送到 目的地(缓存对象 对应的GPU 内存),一个人一个人的送到目的地不划算
顶点数组对象的优点 这样做的优点是: 一旦为一个 对象指定了一个VAO之后,可以ton通过对该VAO对象进行简单的绑定操作来导入对象的所有引用和状态。 在之后绘制对象时候,不需要在手动来导入对象的引用和状态,VAO替你记住了它。 通过VAO可以简化缓冲区的绑定过程,即可以减少代码的调用次数,也提升了WebGL状态切换的效率。 ); 第一行代码创建了一个VAO对象,第二行代码绑定该VAO对象,这两行代码的作用是: 后面关于顶点缓冲对象的操作和状态,都会被记录到这个VAO对象中,以后绘制的时候,只需要调用gl.bindVertexArray 有次可以看出,使用VAO对象的好处: 减少代码量,提高开发效率 提高绘制效率(因为减少了WebGL相关函数的调用,并且WebGL内部对VAO进行了优化) WebGL1中如何使用VAO 在WebGL1.0 有了上面的ext对象,便可以创建VAO了: var vao = ext.createVertexArrayOES(); 有了VAO对象之后,就可以进行绑定操作: // bind ext.bindVertexArrayOES
VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VAO 和 EBO 实际上是对同一类 GL_ELEMENT_ARRAY_BUFFER, m_VboIds[1]); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, (const void *)0); VAO VAO 与 VBO 之间的关系 基于上小节的例子创建 VAO : // 创建并绑定 VAO glGenVertexArrays(1, &m_VaoId); glBindVertexArray(m_VaoId ); // 在绑定 VAO 之后,操作 VBO ,当前 VAO 会记录 VBO 的操作 glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); glEnableVertexAttribArray GLfloat))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, m_VboIds[1]); glBindVertexArray(GL_NONE); 使用 VAO
VAO的创建类似于VBO,可以通过glGenVertexArrays创建VAO,并通过glBindVertexArray进行绑定。 VAO、VBO和顶点属性指针的关系可以参考下图。 VAO、VBO与顶点属性指针(图源Reference) 可以看到,真正绑定VBO的并不是VAO,而是相应的顶点属性指针。 另外,由于VAO和VBO没有直接的关系,因此VAO、VBO绑定的先后顺序并不重要,只要都先于glVertexAttribPointer即可。 EBO可以理解为阅读VAO顶点数据的顺序,因此需要绑定给VAO,绑定的过程是在glBindBuffer发生的。一个使用了EBO的绘制示例如下。 VAO就是状态对象。
7、VBO、EBO 和 VAO 当我们开始上手写 OpenGL 的程序了,我们就要开始逐渐接触 VBO、EBO、VAO 了。 VAO 如何实现这些能力呢? : GLuint VAO; glGenVertexArrays(1, &VAO); // 创建 VAO 对象,注意这里用的是 glGenVertexArrays // 在绑定 VAO 后操作 VBO, 当前 VAO 会记录 VBO 的操作,我们下面用缩进表示操作 VBO 的代码: glBindVertexArray(VAO); // 绑定 VAO,注意这里用的是 glBindVertexArray 只管理 VBO 时,布局格式如下图所示: VAO 管理 VBO 布局格式 当 VAO 管理 VBO 和 EBO 时,布局格式如下图所示: VAO 管理 VBO 和 EBO 布局格式 参考: Learn
4、什么是 VAO,什么是 VBO,它们的作用是什么? 1、iOS 中系统 API 提供了哪些视频编码的方式? 不同 PSNR 的图像质量对比 4、什么是 VAO,什么是 VBO,它们的作用是什么? 2、Vertex Array Object (VAO) VAO(Vertex Array Object)顶点数组对象,主要作用是用于管理 VBO 或 EBO。 VAO 可以把这些所有的配置都存储在一个对象中,每次绘制模型时,只需要绑定这个 VAO 对象就可以了,可以减少 glBindBuffer 、glEnableVertexAttribArray、 glVertexAttribPointer
CPU -> GPU 1.obj序列化 2.在GPU中存成VBO(Vertex Buffer Object) 3.VAO 添加UV信息后 # Blender v2.79 (sub 0) OBJ File 顶点数组对象(Vertex Array Object, VAO)可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在这个VAO中。 这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。这使在不同顶点数据和属性配置之间切换变得非常简单,只需要绑定不同的VAO就行了。 刚刚设置的所有状态都将存储在VAO中 unsigned int VAO; glGenVertexArrays(1, &VAO); glBindVertexArray(VAO) 最后一个参数指定我们打算绘制多少个顶点,这里是6 glBindVertexArray(VAO); glUseProgram(shaderProgram);
// 创建顶点缓冲对象和索引缓冲对象unsigned int VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers (1, &EBO);// 绑定VAOglBindVertexArray(VAO);// 绑定VBO并设置顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData 0.3f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); // 使用着色器程序 glUseProgram(shaderProgram); // 绑定VAO glBindVertexArray(VAO); // 绘制模型 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_INT, 0); // // 清理资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);// 终止GLFWglfwTerminate
顶点数组对象(Vertex Array Object, VAO)可以像顶点缓冲对象那样被绑定,任何随后的顶点属性调用都会储存在这个VAO中。 这样的好处就是,当配置顶点属性指针时,你只需要将那些调用执行一次,之后再绘制物体的时候只需要绑定相应的VAO就行了。这使在不同顶点数据和属性配置之间切换变得非常简单,只需要绑定不同的VAO就行了。 刚刚设置的所有状态都将存储在VAO中(OpenGL核心模式要求使用VAO)。 元素缓冲对象EBO EBO是一个缓冲区,就像一个顶点缓冲区对象一样,它存储 OpenGL 用来决定要绘制哪些顶点的索引。 int VBO, VAO, EBO; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); // //glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); // You can unbind the VAO afterwards so other VAO calls
四.绑定顶点数据和纹理数据 首先,我们写一个函数用于绑定顶点数据: fun bindVertexData(){ //创建vao glGenVertexArrays(1,vao ,0) //创建vbo glGenBuffers(1,vbo,0) //一定要先绑定vao,再绑定vbo glBindVertexArray(vao[ 那vao是用来干嘛的呢? vao就是用于解决这个问题的,vao的作用就相当于一个指针,指向我们所开辟的内存的首地址,如下图所示。 当然,如果只有一份数据,不使用vao也行。
; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer glClear(GL_COLOR_BUFFER_BIT); glUseProgram(shaderProgram); glBindVertexArray(VAO 左下角顶点,绿色 0.5f, -0.5f, 0.0f, 0.0f, 0.0f, 1.0f // 右下角顶点,蓝色 }; unsigned int VBO, VAO ; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glBindVertexArray(VAO); glBindBuffer glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection)); glBindVertexArray(VAO
然后在paintGL()中,每次当我们要绘制不同的物体时,便调用bind()来绑定对象、绘制完后,解绑对象,如果还要绘制下个物体,那么就取出对应的VAO,绑定它,绘制完物体后,再解绑。 resizeEvent(QResizeEvent *e) ; private: QOpenGLShaderProgram *program; QOpenGLVertexArrayObject vao (); //绑定激活vao glDrawArrays(GL_TRIANGLES, 0, 3); //绘制3个定点,样式为三角形 vao.release(); // 9*sizeof(GLfloat)); vbo.setUsagePattern(QOpenGLBuffer::StreamDraw); //设置为一次修改,多次使用 //5.初始化VAO ,设置顶点数据状态(顶点,法线,纹理坐标等) vao.create(); vao.bind(); GLint aPos = program->attributeLocation("aPos
(); //绑定激活vao m_texture->bind(); glDrawArrays(GL_TRIANGLES, 0, 3); //绘制3个定点,样式为三角形 m_texture->release(); vao.release(); //解绑 } void myGlWidget::initializeGL() { // 为当前环境初始化 ,设置顶点数据状态(顶点,法线,纹理坐标等) vao.create(); vao.bind(); // void setAttributeBuffer(int location, GLenum (); //绑定激活vao m_texture->bind(); program->setUniformValue("texture1", 0); m_texture-> ,设置顶点数据状态(顶点,法线,纹理坐标等) vao.create(); vao.bind(); // void setAttributeBuffer(int location, GLenum
若绘制图形众多,你还需考虑使用VAO,VAO用法也是比较简单的,对性能提升也很大。 这就是VAO做的事情,它将所有顶点绘制过程中的这些设置和绑定过程集中存储在一起,当我们需要时,只需要使用相应的VAO即可。 VAO的这种方式有点像一个中介,把所有繁琐的绑定和顶点设置工作都集中起来处理,我们需要绘制时,直接找这个中介就好了。
顶点数组对象:Vertex Array Object,VAO,用于存储顶点状态配置信息,每当界面刷新时,则通过VAO进行绘制. )中,每次刷新时,就可以通过VAO来恢复状态. 2.9 顶点数组对象VAO实现 glClearColor(0.2f, 0.3f, 0.3f, 1.0f); //设置清除颜色(背景色)为rgba(0.2f int VAO; glGenVertexArrays(1, &VAO); // 注册VAO glBindVertexArray(VAO); // 绑定VAO //2. 的时候,避免出错(如果只绘制一个VAO,也可以无需多次解绑). afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens.
parent) { } void myGlWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT); // 渲染Shader vao.bind QOpenGLShader::Vertex,vsrc); program->link(); program->bind(); //初始化VBO,将顶点数据存储到buffer中,等待VAO vertices)); vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); //设置为一次修改,多次使用(坐标不变,变得只是像素点) //初始化VAO ,设置顶点数据状态(顶点,法线,纹理坐标等) vao.create(); vao.bind(); // void setAttributeBuffer(int location program->enableAttributeArray(0); //使能 program->enableAttributeArray(1); //解绑所有对象 vao.release
9)什么是 VBO、EBO 和 VAO? 可以认为它们是在 OpenGL 中处理数据的三大类缓冲内存对象。 VAO(Vertex Array Object)顶点数组对象,主要作用是用于管理 VBO 或 EBO,减少 glBindBuffer、glEnableVertexAttribArray、glVertexAttribPointer 当 VAO 只管理 VBO 时,布局格式如下图所示: VAO 管理 VBO 布局格式当 VAO 管理 VBO 和 EBO 时,布局格式如下图所示: VAO 管理 VBO 和 EBO 布局格式
SDL_Window *window; SDL_CreateWindowAndRenderer(400, 300, 0, &window, nullptr); // 针对 OpenGL ES,表示要生成几个 vao ,后面顶点属性绑定 vbo 时会保存到这里 GLuint vao; glGenVertexArraysOES(1, &vao); glBindVertexArrayOES(vao); 400x300 的画布 SDL_Window *window; SDL_CreateWindowAndRenderer(400, 300, 0, &window, nullptr); GLuint vao ; glGenVertexArraysOES(1, &vao); glBindVertexArrayOES(vao); GLuint vertexShader = glCreateShader