webgl——VAO

        上次说到了对VAO、VBO的理解,明白了使用VAO相比传统模式在IO方面对加载性能的提升,今天我对其在WebGL上进行了实现。

        在WebGL中由于很多API与OpenGLES大为不同(一般常用的API大致是相同的),开始时费了很多劲,最后还是通过MSDN找到了相关的API及方法,这里对设计VAO的主要的部分进行介绍,对VAO还不是很理解的同学可以看这篇文章:http://blog.csdn.net/srk19960903/article/details/74999018

        这次我们还用的是上次那个篮球在地面上弹的例子,只是把篮球和地面加载的部分换成了VAO方法,篮球阴影的加载还使用的是传统方法,以便于对照。

function ObjObject
  (
     gl,                    //GL上下文
     vertexDataIn,    //顶点坐标数组
     vertexNormalIn,   //顶点法向量数组
     vertexTexCoorIn,  //顶点纹理坐标数组
     programIn          //着色器程序对象
  )
  {
         //加载着色器程序
         this.program=programIn;
         this.ext = gl.getExtension("OES_vertex_array_object");
         //create VAO
         this.vao = this.ext.createVertexArrayOES();
         // bind vao
         this.ext.bindVertexArrayOES(this.vao);

     //接收顶点数据
     this.vertexData=vertexDataIn;
     //得到顶点数量
     this.vcount=this.vertexData.length/3;
     //创建顶点数据缓冲
     this.vertexBuffer=gl.createBuffer();

       gl.bindBuffer(gl.ARRAY_BUFFER,this.vertexBuffer);
       gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(this.vertexData),gl.STATIC_DRAW);

         var apos = gl.getAttribLocation(this.program, "aPosition");
         gl.vertexAttribPointer(apos, 3, gl.FLOAT, false, 0, 0);
         //启用顶点数据
         gl.enableVertexAttribArray(apos);
         //此处省略法线和纹理坐标的数据
         this.ext.bindVertexArrayOES(null);}

        这里可以看到在初始化的部分代码明显变多,主要是因为将每次传递顶点、法线、纹理坐标位置的数据从drawSelf移到了初始化函数中,这里值得一提的是,在OpenGLES中的Gen开头的API在WebGL中都没有,取而代之的是gl.getExtension("OES_vertex_array_object");然后创建VAO并对其进行绑定,最后在完成之后取消绑定。还有就是一定要注意顺序,每次创建数据缓冲、启用顶点数据和绑定缓冲的代码必须一次完成,之前我写的时候总是报:

WebGL GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1

这个错就是因为顺序不对,导致在最后绘制的时候数据溢出了。

        下面是drawSelf的方法:

    this.drawSelf=function(ms,texture)
    {
           gl.useProgram(this.program);//指定使用某套着色器程序(重要)
   //送入总矩阵
var uMVPMatrixHandle=gl.getUniformLocation(this.program, "uMVPMatrix");   
gl.uniformMatrix4fv(uMVPMatrixHandle,false,new Float32Array(ms.getFinalMatrix())); 

         //送入变换矩阵
         var uMMatrixHandle=gl.getUniformLocation(this.program, "uMMatrix");
         gl.uniformMatrix4fv(uMMatrixHandle,false,new Float32Array(ms.currMatrix)); 
         
         //送入光源位置
         var uLightLocationHandle=gl.getUniformLocation(this.program, "uLightLocation");
         gl.uniform3fv(uLightLocationHandle,new Float32Array([lightManager.lx,lightManager.ly,lightManager.lz]));
         
         //送入摄像机位置
         var uCameraHandle=gl.getUniformLocation(this.program, "uCamera");
         gl.uniform3fv(uCameraHandle,new Float32Array([ms.cx,ms.cy,ms.cz]));

           //绑定纹理
           gl.bindTexture(gl.TEXTURE_2D, texture);
           this.ext.bindVertexArrayOES(this.vao);

//用顶点法绘制物体
   gl.drawArrays(gl.TRIANGLES, 0, this.vcount); 
    }    
        这次在传递完uniform的参数之后,直接打开了bindVertexArrayOES,使用其中的数据当做绘制时需要用的顶点数据、法线数据、纹理坐标数据,这样在每次绘制时就不用再次传递了。

        实现的效果与阴影那片相同,主要是将obj加载方法换成了VAO的方式。

        下面是Github地址:https://github.com/StringKun/WebGL-VAO

        



  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值