vao对象及其使用

       本篇主要介绍vao对象的创建及其使用,通过本篇学习,希望大家能熟悉怎么为vertex shader提供各种输入。vao(vertex array object)是OpenGL中的一个非常基本的数据类型,代表vertex shader 的输入,可以把van对象当成一个媒介,一方面,该对象内部提供很多的binding point可以绑定自定义的vbo对象,另一方面,该对象提供了很多attribute index对应 vertex shader的输入变量,openGL提供接口可以将一个shader的输入和一个vbo对象连接起来。具体来说,使用分以下几个步骤:

     1  vao对象的创建,方法如下:

      GLuint vao

      glCreateVertexArrays(1,&vao)

      glBindVertexArray(vao)

      2 属性和buffer绑定,创建对象后,可以将内部某一个属性和一个binding point绑定到一起,并将该binding point 和一个vbo对象绑定到一起,具体定义如下:

      //vaobj代表操作的vai对象,attribindex代表属性index,binding index代表binding point,也是一个index,buffer代表vbo对象,offset代表缓冲区的偏移量,stride代表从一个顶点数据跳转到下一个顶点数据需要跳转的size大小

      void glVertexArrayAttribBinding(GLuint vaobj,GLuint attribindex,GLuint bindingindex)

      void glVertexArrayVertexBuffer(GLuint vaobj,GLuint bindingindex,GLuint buffer,GLintptr offset,GLsizei stride)

       3 指定缓冲区数据格式,定义如下:

       //第一个参数是vao对象,第二个参数是属性index,第三个参数是component个数,比如1,2,3,4,第四个是数据类型,详细见上篇文章,第五个参数代表数据传给shader的时候是否需要归一化,第六个参数是vbo对象中的偏移量

      void glVertexArrayAttribFormat(GLuint vaobj,GLuint attribindex,GLint size,GLenum type,GLboolean normalized,GLuint relativeoffset)

       4 启用功能,调用一个方法启用自动为vertex shader填充数据的功能,使用完再调用对应方法关掉此功能,定义如下:

       void glEnableVertexAttribArray(GLuint index)

       void glDisableAttribArray(GLuint index)

       5 在shader中进行绑定。以上都是在客户端来实现的功能,在vertex shader 中还需要将输入变量和attribute index绑定到一起,非常简单,如下:

        layout (location = 0) in vec3 position;

        layout (location = 1) in vec3 color;

       上述代码定义了两个输入变量,分别从vao对象的attribute index 为0和1对应的vbo对象中获取数据。


        以上就是vao对象的基本使用步骤,但这只设计一个属性,实际使用中,每一个顶点都对应很多属性,例如位置,颜色,法向量,纹理坐标等等,每一个属性的数据类型和数据大小都可能不一样,怎样为顶点填充多个属性,系统提供了两种机制,一种称为seprate attributes,一种称为interleaved attributes,顾名思义,前一种是将各个属性分开存放,可以放到不同的vbo缓冲区中,也可以放到同一个缓冲区的不同位置,后一种方法是放在一起,只有一个缓冲区,而且所有的属性构成一个结构体,缓冲区是中是一个一个按序排列的结构体。从效率上来说,OpenGL更推荐后一种方法。

       下面代码片段是第一种实现:

        GLuint buffer[2];

        GLuint vao;

        static const GLfloat positions[] = {…};//位置信息

        static const GLfloat colors[] = {…}; //颜色信息

        glCreateVertexArrays(1,&vao);

        glCreateBuffers(2,&buffer[0]);

        //设置第一个属性

        glNamedBufferStorage(buffer[0],sizeof(positons),positions,0);

        glVertexArrayVertexBuffer(vao,0,buffer[0],0,sizeof(vmtah::vec3));

        glVertexArrayAttribFormat(vao,0,3,GL_FLOAT,GL_FALSE,0);

        glVertexArrayAttribBinding(vao,0,0);

        glEnableVertexArrayAttrib(0);

        //设置第二个属性

        glNamedBufferStorage(buffer[1],sizeof(colors),colors,0);

        glVertexArrayVertexBuffer(vao,1,buffer[1],0,sizeof(vmtah::vec3));

        glVertexArrayAttribFormat(vao,1,3,GL_FLOAT,GL_FALSE,0);

        glVertexArrayAttribBinding(vao,1,1);

        glEnableVertexArrayAttrib(vao,1);

        以下代码实现是第二种方法:

        struct vertex

        { 

            //position

            float x;

            float y;

            float z;

            //color

            float r;

            float g;

            float b;

         };

 

        GLuint vao;

        GLuint buffer;

        static const vertex vertices[] = {…};

        glCreateVertexArrays(1,&vao);

        glCreateBuffers(1,&buffer);


        glNamedBufferStorage(buffer,sizeof(vertices),vertices,0);

        glVertexArrayAttribBinding(vao,0,0);

        glVertexArrayAttribFormat(vao,0,3,GL_FLOAT,GL_FALSE,offsetof(vertex,x));

        glEnableVertexArrayAttrib(0);


        glVertexArrayAttribBinding(vao,1,0);

        glVertexArrayAttribFormat(vao,1,3,GL_FLOAT,GL_FALSE,offsetof(vertex,r));

        glEnableVertexArrayAttrib(1);


        glVertexArrayVertexBuffer(vao,0,buffer)


       以上就是vao的基本使用方法,不管多么复杂的数据模型或者shader,都不外乎以上几种提供数据的方法,接下来准备钻研一下uniform变量。

       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值