vbo对象的创建和赋值

    vbo(vertex buffer object)是opengl中一个非常基本的概念,代表的是一段数据缓冲区,opengl程序中的各种输入数据和输出数据都需要存储在数据缓冲区中,本文简单介绍下vbo对象的创建过程以及各种赋值方法。

    vbo的创建很简单,声明格式及参数含义如下:

            // 第一个参数表示需要的缓冲区对象个数,第二个参数是存储缓冲区名字的数组,每一个缓冲区对象都用一个GLuint数值作为其标识,在后续的方法中使用。

            void glCreateBuffer(GLsizei n, GLuint *buffers)

    创建后一个缓冲区对象后,一般需要将其绑定在一个的binding point上,方便后续操作,声明格式如下:

            //第一个参数代表binding point,第二个参数代表buffer标识符

           void glBindBuffer(GLenum target, GLuint buffer) 

    这里需要特别说明一下,opengl是一个状态机模型,其中包含了很多个可以绑定buffer的target或binding point,比如后面文章会介绍到到vao对象也包含很多binding point,每个vbo对象创建后都可以绑定在任意的binding point上,而且可以同时绑定多个target或binding point。      

     绑定对象后,下一步就是给vbo分配存储空间并提供数据,opengl提供了很多方法为vbo对象赋值,可以在分配存储空间的时候一并赋值,也可以先分配空间,以后再单独赋值。可以一下子赋值整个buffer对象,也可以赋值buffer的一小段空间,大致分为以下五类:

    1 分配空间时赋值,生成vbo对象后,需要为对象分配空间,分配空间的同时,也可以进行数据初始化,具体函数定义如下:

        //第一个参数代表vbo对象,可以用标识符或者绑定的target表示,第二个参数表示空间大小,第三个参数表示初始值,可以为空,第四个代表该空间的用途

         void glBufferStorage(GLenum target,GLSizeptr size,ocnst void *data, GLbitfield flags)

         void glNamedBufferStorage(GLuint buffer,GLsizeiptr size,const void *data,GLbtifield flags)

        需要注意的是GLSizeptr其实代表的是一个整形数,但位数跟系统有关,与系统总线位数相同(即一个指针的bit数),data可以为空,表示没有初始值。比较有意思的是flags参数,该参数代表缓冲区的用途,如果不正确设置,可能导致后续操作会失败,其取值及含义如下:

        GL_DYNAMIC_STORAGE_BIT,表示可以动态更新缓冲区,如果不设置,不能调用glBufferSubData等方法

        GL_MAP_READ_BIT ,表示map的用途是读取缓冲区

        GL_MAP_WRITE_BIT,表示map的用途是写缓冲区

        GL_MAP_PERSISTENT_BIT,Buffer data store will be mapped persistently,其实不太懂,以后懂了再补充

        GL_MAP_COHERENT_BIT,Buffer maps are to be coherent ,也不太懂,以后补充

        GL_CLIENT_STORAGE_BIT,表示缓冲区应尽可能在cpu对应的内存上分配,而不是在gpu对应的显存分配

     2 直接更新vbo对象,调用方法如下

        //第一个参数代表vbo对象,第二个代表偏移量,也是整形,第三个代表要更新的缓冲区大小,第四个代表数据源地址

         void glBufferSubData(GLenum target GLintptr offset,GLsizeptr size,const GLvoid *data)

         void glNamedBufferSubData(GLuint buffer,GLintptr offset,GLsizeiptr size,const void *data)

      3 map方法,该方法将缓冲区对象映射为内存中的一个指针,直接更新即可,openGL提供了两套,分别是更新全部缓冲区和更新部分缓冲区,系统更建议使用后一种方法,因为效率更高,可控性更好,具体方法定义如下:

         全量更新:

                 void *glMapBuffer(GLenum target,GLenum usage)

                 void  *glMapNamedBuffer(GLuint buffer, GLenum usage)

                 void  *glUnmapBuffer(GLenum target)

                 void  *glUnmapNamedBuffer(GLuint buffer)

           部分更新:

                 void *glMapBufferRange(GLenum target,GLintptr offset,GLsizeptr length,GLbitfield access)

                 void *glMapNamedBufferRange(GLuint buffer,GLintptr offset,GLsizeptr length,GLbitfield access)

                 释放函数同上,参数都是比较明显的,不再一一赘述,主要介绍一下第四个access方法,其含义也是代表被影射缓冲区的用途,具体取值如下:

                           GL_MAP_READ_BIT ,表示map的用途是读取缓冲区

                           GL_MAP_WRITE_BIT,表示map的用途是写缓冲区

                           GL_MAP_PERSISTENT_BIT,Buffer data store will be mapped persistently,其实不太懂,以后懂了再补充

                           GL_MAP_COHERENT_BIT,Buffer maps are to be coherent ,也不太懂,以后补充

                           GL_MAP_INVALIDATE_RANGE_BIT, Tells OpenGL that you no longer care about the data in the specified range

                           GL_MAP_INVALIDATE_BUFFER_BIT,Tells OpenGL that you no longer care about any of the data in the whole buffer

                           GL_MAP_FLUSH_EXPLICIT_BIT, You Promise to tell OpenGL about any data you modify inside the mapped range

                           GL_MAP_UNSYNCHRONIZED_BIT,Tells OpenGL that you will perform any synchronization yourself

     4 clear方法,该方法适用于将缓冲区都设置为一个常量,此种情况用此方法效率较高,具体方法定义如下:

                /* 第一个参数代表vbo对象,第二个代表opengl内部存储格式,这个格式种类非常多,以后再详细介绍,第三个代表要更新区域的偏移量,第四个代表更新区域的大小

                 * 第五个参数代表格式,包括GL_RED,GL_RG,GL_RGB,GL_RGBA四种,分别包括1,2,3,4个组成部分,第六个参数代表data里面的数据类型,取值范围

                * 包括 GL_BYTE GL_UNSIGNED_BYTE GL_SHORT GL_UNSIGNED_SHORT GL_INT GL_UNSIGNED_INT GL_FLOAT GL_DOUBLE,第七个参数代表数据地址

               */

                 void glClearBufferSubData(GLenum target,GLenum internalformat,GLintptr offset,GLsizeiptr  size,GLenum format,GLenum type,const void *data)

                 void glClearNamedBufferSubData(GLuint buffer,GLenum internalformat,GLintptr offset,GLsizeiptr  size,GLenum format,GLenum type,const void *data)


     5 buffer copy 方法,刚方法从一个vbo对象copy到另一个vbo对象,具体方法定义如下:

                  void glCopyBufferSubData(GLenum readtarget,GLenum writetarget,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)

                  void glCopyNamedBufferSubData(GLuint readbuffer,GLuint writeBuffer,GLintptr readoffset,GLintptr writeoffset,GLsizeiptr size)

                  各个参数含义同上,需要注意的是系统提供了GL_COPY_READ_BUFFER,GL_COPY_WRITE_BUFFER两个targets来方便使用者在两个vbo对象之间copy 数据

     以上就是OpenGl提供的vbo相关方法,这是非常基本的概念,所有的数据提供几乎都需要vbo对象,这些方法必须熟练掌握才能学好OpenGl,接下来的一篇我会介绍下怎么让OpenGl自动从vbo对象中获取vertex shader所需的顶点数据。






          

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值