VBO Vertex Buffer object 为什么要用VBO 不使用VBO时,我们每次绘制( glDrawArrays )图形时都是从本地内存处获取顶点数据然后传输给OpenGL来绘制,这样就会频繁的操作 使用VBO,我们就能把顶点数据缓存到GPU开辟的一段内存中,然后使用时不必再从本地获取,而是直接从显存中获取,这样就能提升绘制的效率。 创建VBO的主要步骤: //1. 根据id绑定VBO GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId); //3. 解绑VBO GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 使用VBO的主要步骤: //1. 解绑VBO GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0); 我使用绘制图片纹理的代码来进行改造为VBO,OpenGLES 绘制图片纹理 改造的只有BitmapTexture
这篇文章其实不必写,这位博主讲得已经很好了http://www.cnblogs.com/kesalin/archive/2012/12/20/vbo.html。 还是提出来的原因是,这是一步步的路: 为什么我们要使用VBO? 使用顶点缓存(VBO)能够大大减少CPU-GPU 之间的数据拷贝开销,因此显著地提升了程序运行的效率。 既然如此,那就一定要用VBO。 这篇文章我就将《OpenGLES-05 立方体3D变换》里的代码改为VBO,阅读VBO使用请点上面链接就好。 若绘制图形众多,你还需考虑使用VAO,VAO用法也是比较简单的,对性能提升也很大。
VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VAO 和 EBO 实际上是对同一类 OpenGLES3.0 编程中, VBO 和 EBO 的出现就是为了解决这个问题。 VBO(EBO)的创建和更新: // 创建 2 个 VBO(EBO 实际上跟 VBO 一样,只是按照用途的另一种称呼) glGenBuffers(2, m_VboIds); // 绑定第一个 VBO, VBO更新后内存中的数据结构 由于顶点位置和颜色数据在同一个数组里,一起更新到 VBO 里面,所以需要知道 2 个属性的步长和偏移量。 使用 VBO 和 EBO 进行绘制。
image.png 三角形三个顶点分别为 (0,1,0) (-1,-1,0) (1,-1,0) VBO的函数调用 ? image.png ? image.png glGenBuffers(1, &VBO) 生成一个buffer,VBO初始化,第一个参数是buffer数量,第二个是要初始化的VBO指针。 glBindBuffer(GL_ARRAY_BUFFER, VBO); 第一个参数buffer类型,第二个参数是buffer。 glDeleteBuffers() 释放VBO VAO ? 由于OpenGL是个状态机,当绑定当前VAO之后,后面的VBO操作自然而然的都是在该VAO上进行的。 glDeleteVertexArrays 释放VAO
顶点数组对象名称 存放于 VAOs 数组中 glBindVertexArray(VAOs[Triangles]); // 创建新的顶点数组对象并与其名称关联起来 Vertex Buffer Object,VBO 我们通过顶点缓冲对象(Vertex Buffer Objects, VBO)管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。 打个简单的比分,类似大家做高铁去目的地,VAO 就像一个个人,VBO 就是高铁,等很多人都到高铁站台了,我们通过 VBO 高铁将大家一起打包快速的送到 目的地(缓存对象 对应的GPU 内存),一个人一个人的送到目的地不划算 ; glGenBuffers(1, &VBO); // 生成一个可用的缓存对象名称 存放于 VBO glBindBuffer(GL_ARRAY_BUFFER, VBO); // 创建一个新的缓存对象 ,与 VBO 关联 glBufferData(GL_ARRAY_BUFFER, sizeof(Vertices), Vertices, GL_STATIC_DRAW); // 分配缓存对象所需的内存,
VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VAO 和 EBO 实际上是对同一类 OpenGL ES 3.0 编程中, VBO 和 EBO 的出现就是为了解决这个问题。 VBO(EBO)的创建和更新: // 创建 2 个 VBO(EBO 实际上跟 VBO 一样,只是按照用途的另一种称呼) glGenBuffers(2, m_VboIds); // 绑定第一个 VBO, 使用 VBO 和 EBO 进行绘制。 ); // 在绑定 VAO 之后,操作 VBO ,当前 VAO 会记录 VBO 的操作 glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); glEnableVertexAttribArray
7、VBO、EBO 和 VAO 当我们开始上手写 OpenGL 的程序了,我们就要开始逐渐接触 VBO、EBO、VAO 了。 0.0f, 0.5f, 0.0f }; // 使用 VBO: GLuint VBO; glGenBuffers(1, &VBO); // 创建 VBO 对象 glBindBuffer(GL_ARRAY_BUFFER 0, 1, 3, // 第一个三角形 1, 2, 3 // 第二个三角形 }; // 使用 VBO: GLuint VBO; glGenBuffers(1, &VBO); // 创建 VBO : GLuint VBO; glGenBuffers(1, &VBO); // 创建 VBO 对象 // 创建 VAO: GLuint VAO; glGenVertexArrays(1, &VAO); 管理 VBO 布局格式 当 VAO 管理 VBO 和 EBO 时,布局格式如下图所示: VAO 管理 VBO 和 EBO 布局格式 参考: Learn OpenGL[1] VBO、EBO 和 VAO
9)什么是 VBO、EBO 和 VAO? 可以认为它们是在 OpenGL 中处理数据的三大类缓冲内存对象。 VBO(Vertex Buffer Objects)顶点缓冲区对象,指的是在 GPU 显存里面存储的顶点数据(位置、颜色)。 ; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof (vertices), vertices, GL_STATIC_DRAW); 这时候对应的 VBO 布局格式如下图所示: VBO 布局格式 11)Vertex Array Object 的布局格式是怎样的 当 VAO 只管理 VBO 时,布局格式如下图所示: VAO 管理 VBO 布局格式当 VAO 管理 VBO 和 EBO 时,布局格式如下图所示: VAO 管理 VBO 和 EBO 布局格式
, VAO glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof VBO之内的顶点数据实际上没有语义,只是以二进制的形式缓存,故VBO不可以直接进行绘制。 VAO、VBO和顶点属性指针的关系可以参考下图。 VAO、VBO与顶点属性指针(图源Reference) 可以看到,真正绑定VBO的并不是VAO,而是相应的顶点属性指针。 另外,由于VAO和VBO没有直接的关系,因此VAO、VBO绑定的先后顺序并不重要,只要都先于glVertexAttribPointer即可。 // 准备数据 glGenBuffers(1, &VBO); glGenVertexArrays(1, &VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData
VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VBO 和 EBO 实际上是对同一类 OpenGL ES 3.0 编程中, VBO 和 EBO 的出现就是为了解决这个问题。 VBO(EBO)的创建和更新: // 创建 2 个 VBO(EBO 实际上跟 VBO 一样,只是按照用途的另一种称呼) glGenBuffers(2, m_VboIds); // 绑定第一个 VBO, VBO更新后内存中的数据结构 由于顶点位置和颜色数据在同一个数组里,一起更新到 VBO 里面,所以需要知道 2 个属性的步长和偏移量。 使用 VBO 和 EBO 进行绘制。
// 创建顶点缓冲对象和索引缓冲对象unsigned int VBO, VAO, EBO;glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers (1, &EBO);// 绑定VAOglBindVertexArray(VAO);// 绑定VBO并设置顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);// 解绑VBO // 清理资源glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);// 终止GLFWglfwTerminate
Pass 功能的文章: LearnGL – 17 – Geometry Shader – 几何着色器 – 直接网页锚点定位到对应的 Pass 实现 一般 OpenGL 中,绘制一个对象,就是提供,VBO ,IBO(IBO还不一定需要提供,可以使用 DrawArray 直接通过VBO来绘制,如果通过DrawArrayIndex 之类的就需要 IBO 了,前面的 VBO,IBO 也可以通过 VAO 统一绑定后设置 ,IBO,等数据打包到一个大的 VBO、 IBO 中,然后在调用一次 DrawCall,从而提升性能:SetPass 的 State 时,或是多次 Draw API 调用产生过多的 CPU 消耗的性能的问题 , ibo batchInfo.vbo = vertexBufferStream.GetRawBytes(); batchInfo.ibo = indexBufferStream.GetRawBytes , sizeof(batchInfo.vbo), &vbo, ...); glGenBuffer(GL_ELEMENT_BUFFER, batchInfo.ibo, sizeof(batchInfo.ibo
0.0f, 1.0f,1.0f, 0.5f, 0.5f, 0.0f, 1.0f,0.0f }; // 载入顶点数据 glGenBuffers(1, &_VBO ); glBindBuffer(GL_ARRAY_BUFFER, _VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertexs), vertexs, GL_FALSE, 5 * sizeof(GLfloat), BUFFER_OFFSET(0)); // 启用纹理缓存数据 glBindBuffer(GL_ARRAY_BUFFER, _VBO 清除缓存 - (void)dealloc { [EAGLContext setCurrentContext:((GLKView *)self.view).context]; if (_VBO = 0){ glDeleteBuffers (1,&_VBO); _VBO = 0; } [EAGLContext setCurrentContext:nil
VBO 和 EBO VBO(Vertex Buffer Object)是指顶点缓冲区对象,而 EBO(Element Buffer Object)是指图元索引缓冲区对象,VAO 和 EBO 实际上是对同一类 OpenGL ES 3.0 编程中, VBO 和 EBO 的出现就是为了解决这个问题。 VBO(EBO)的创建和更新: // 创建 2 个 VBO(EBO 实际上跟 VBO 一样,只是按照用途的另一种称呼) glGenBuffers(2, m_VboIds); // 绑定第一个 VBO,拷贝顶点数组到显存 使用 VBO 和 EBO 进行绘制。 ); // 在绑定 VAO 之后,操作 VBO ,当前 VAO 会记录 VBO 的操作 glBindBuffer(GL_ARRAY_BUFFER, m_VboIds[0]); glEnableVertexAttribArray
一般这种情况下注册的是VBO和PBO,VBO一般用于存储顶点坐标、索引等数据;PBO则一般用于存储图像数据,因此称作Pixel Buffer Object。 CUDA锁定资源,获取操作资源的指针,在CUDA核函数中进行处理 CUDA释放资源,在OpenGL中使用Buffer Object 下面就以代码为例,讲讲两种方式的异同: (1)OpenGL PBO/VBO array object glGenVertexArrays(1, &this->VAO); //Create vertex buffer object glGenBuffers(2, this->VBO first, then bind and set vertex buffer(s) and attribute pointer(s). glBindVertexArray(this->VAO); // 绑定VBO 后即在CUDA中注册Buffer Object glBindBuffer(GL_ARRAY_BUFFER, this->VBO[0]); glBufferData(GL_ARRAY_BUFFER, sizeof
尽管 VBO 是显卡的扩展,其实没有用到GPU运算,也就是说 VBO 不用写着色语言,直接用opengl函数就可以调用,主要目的是用于加快渲染的速。 如果把这些都放到初始化时候完成,使用一种结构记录该次绘制所需要的所有 VBO 所需信息,把它保存到 VBO特定位置,绘制的时候直接在这个位置取信息绘制,会简化渲染流程、提升渲染速度。 根据我查到的资料,几乎所有的显卡都支持 VBO,但不是所有的显卡都支持 VAO,而 VAO 仅仅是优化了 VBO 的使用方法,对于加速并没有实质性的影响,因此本文只讨论 VBO 技术。 如下: from OpenGL.arrays import vbo vbo_vertices = vbo.VBO(vertices) vbo_indices = vbo.VBO(indices, target , int(vbo_indices .size/4), GL_UNSIGNED_INT, None) vbo_indices.unbind() vbo_indices.unbind() 致谢: 写作过程中
addShaderFromSourceCode(QOpenGLShader::Vertex,vsrc); program->link(); program->bind(); //初始化VBO 0.0f, 0.0f, 0.0f, //左上 1.0f, 1.0f, 0.0f, 1.0f, 0.0f //右上 }; vbo.create (); vbo.bind(); vbo.bind(); //绑定到当前的OpenGL上下文, vbo.allocate(vertices, sizeof (vertices)); vbo.setUsagePattern(QOpenGLBuffer::StaticDraw); //设置为一次修改,多次使用(坐标不变,变得只是像素点) / enableAttributeArray(0); //使能 program->enableAttributeArray(1); //解绑所有对象 vao.release(); vbo.release
SDL_CreateWindowAndRenderer(400, 300, 0, &window, nullptr); // 针对 OpenGL ES,表示要生成几个 vao,后面顶点属性绑定 vbo ; glGenBuffers(1, &vbo); // 绑定缓冲区到上下文 glBindBuffer(GL_ARRAY_BUFFER, vbo); // 将 顶点数据 复制到 缓冲区 GL_COLOR_BUFFER_BIT); // 清空颜色缓存 glDrawArrays(GL_TRIANGLES, 0, 3); // 绘制三角形 glDeleteBuffers(1, &vbo ; glGenBuffers(1, &vbo); glBindBuffer(GL_ARRAY_BUFFER, vbo); glBufferData(GL_ARRAY_BUFFER, 24, ); glClear(GL_COLOR_BUFFER_BIT); glDrawArrays(GL_TRIANGLES, 0, 3); glDeleteBuffers(1, &vbo
通过顶点缓冲对象(Vertex Buffer Objects, VBO)管理这个内存,它会在GPU内存(通常被称为显存)中储存大量顶点。 就像OpenGL中的其它对象一样,这个缓冲有一个独一无二的ID,所以我们可以使用glGenBuffers函数和一个缓冲ID生成一个VBO对象: unsigned int VBO; glGenBuffers (1, &VBO); glGenBuffers--返回n个当前未使用的缓存对象名称,并保存到buffers数组中。 CPU -> GPU 1.obj序列化 2.在GPU中存成VBO(Vertex Buffer Object) 3.VAO 添加UV信息后 # Blender v2.79 (sub 0) OBJ File unsigned int VBO; glGenBuffers(1, &VBO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData
QResizeEvent *e) ; private: QOpenGLShaderProgram *program; QOpenGLVertexArrayObject vao; QOpenGLBuffer vbo ); program->addShader(fshader); program->link(); program->bind();//激活Program对象 //4.初始化VBO float vertices[] = { -0.5f, -0.5f, 0.0f, 0.5f, -0.5f, 0.0f, 0.0f, 0.5f, 0.0f }; vbo.create (); vbo.bind(); //绑定到当前的OpenGL上下文, vbo.allocate(vertices, 9*sizeof(GLfloat)); vbo.setUsagePattern ); //设置顶点属性 program->enableAttributeArray(aPos); //使能顶点属性 //6.解绑所有对象 vao.release(); vbo.release