前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebGL2系列之顶点数组对象

WebGL2系列之顶点数组对象

作者头像
用户3158888
发布2019-05-28 14:34:25
1.1K0
发布2019-05-28 14:34:25
举报
文章被收录于专栏:计算机图形学 前端可视化 WebGL

顶点数组对象,在WebGL1中,是一个扩展对象,该扩展对象的名称是OES_vertex_array_object;而在WebGL2中可以直接使用;如果你在WebGL1中已经使用过OES_vertex_array_object,那么你只需要了解在WebGL2和WebGL1的调用方式的差异即可

下面会对顶点数组对象做详细的介绍。

顶点数组对象

顶点数组对象( VAO )是这样一种对象: 它封装了与顶点处理器有关的所有数据,它记录了顶点缓存区和索引缓冲区的引用,以及顶点的各种属性的布局而不是实际的数据。

顶点数组对象的优点

这样做的优点是: 一旦为一个 对象指定了一个VAO之后,可以ton通过对该VAO对象进行简单的绑定操作来导入对象的所有引用和状态。在之后绘制对象时候,不需要在手动来导入对象的引用和状态,VAO替你记住了它。 通过VAO可以简化缓冲区的绑定过程,即可以减少代码的调用次数,也提升了WebGL状态切换的效率。

案例:用顶点数组对象绘制两个三角形

下面通过代码来说明顶点数组对象的使用,本案例代码绘制两个顶点色的三角形,最终显示的效果如下:

代码语言:javascript
复制
var triangleArray = gl.createVertexArray();
        gl.bindVertexArray(triangleArray);

        var positions = new Float32Array([
            -0.5, -0.5, 0.0,
            0.0, -0.5, 0.0,
            0.0, 0.0, 0.0
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

        var triangleArray2 = gl.createVertexArray();
        gl.bindVertexArray(triangleArray2);

        var positions2 = new Float32Array([
            0.0, -0.0, 0.0,
            0.5, 0.0, 0.0,
            0.0, 0.5, 0.0
        ]);
        var positionBuffer2 = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer2);
        gl.bufferData(gl.ARRAY_BUFFER, positions2, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors2 = new Float32Array([
            1.0, 1.0, 0.0,
            0.0, 1.0, 1.0,
            0.0, 1.0, 1.0
        ]);
        var colorBuffer2 = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer2);
        gl.bufferData(gl.ARRAY_BUFFER, colors2, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);
        ////////////////
        // DRAW
        ////////////////
        gl.clear(gl.COLOR_BUFFER_BIT);

        gl.bindVertexArray(triangleArray);
        gl.drawArrays(gl.TRIANGLES, 0, 3);

        gl.bindVertexArray(triangleArray2);
        gl.drawArrays(gl.TRIANGLES, 0, 3);

定义三角形相关数据和缓冲区

首先,定义了三角形的顶点数据和缓冲区和WebGL1的代码很类似,下面是一个三角相关数据定义的代码

代码语言:javascript
复制
var triangleArray = gl.createVertexArray();
        gl.bindVertexArray(triangleArray);

        var positions = new Float32Array([
            -0.5, -0.5, 0.0,
            0.0, -0.5, 0.0,
            0.0, 0.0, 0.0
        ]);
        var positionBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, positions, gl.STATIC_DRAW);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        var colors = new Float32Array([
            1.0, 0.0, 0.0,
            0.0, 1.0, 0.0,
            0.0, 0.0, 1.0
        ]);
        var colorBuffer = gl.createBuffer();
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.bufferData(gl.ARRAY_BUFFER, colors, gl.STATIC_DRAW);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

可以看出除了前两行 创建VAO和绑定VAO代码外,其他的代码都是WebGL1一样的代码:

  • 定义坐标数组
  • 创建顶点坐标缓冲区
  • 绑定缓冲区并填充缓冲区数据
  • 把缓冲区分配给attribute变量
  • 启用attribute变量

代码中定义了两种顶点信息:顶点坐标和顶点颜色

创建另外一个三角形的相关数据的代码和第一个类似,不重复说明。

VAO对象在创建顶点数据的作用

现在回到前面两行代码:

代码语言:javascript
复制
var triangleArray = gl.createVertexArray();
gl.bindVertexArray(triangleArray);

第一行代码创建了一个VAO对象,第二行代码绑定该VAO对象,这两行代码的作用是: 后面关于顶点缓冲对象的操作和状态,都会被记录到这个VAO对象中,以后绘制的时候,只需要调用gl.bindVertexArray方法,绑定该对象,就会自动使用相关的状态。

VAO 对象在绘制的时候的作用

下面在看绘制的代码

代码语言:javascript
复制
       gl.clear(gl.COLOR_BUFFER_BIT);// 清空颜色缓冲区
        // 绘制第一个三角形
        gl.bindVertexArray(triangleArray);
        gl.drawArrays(gl.TRIANGLES, 0, 3);
        // 绘制第二个三角形
        gl.bindVertexArray(triangleArray2);
        gl.drawArrays(gl.TRIANGLES, 0, 3);

第一行代码,清空颜色缓冲区,和WebGL1一样;然后绘制第一个三角形,绘制时候,

  • 先调用 gl.bindVertexArray(triangleArray)把第一个三角形相关的缓冲区状态恢复,
  • 然后调用gl.drawArrays(gl.TRIANGLES, 0, 3)绘制

绘制第二个三角形和第一个三角形类似; 回顾下,如果不使用顶点数组对象,绘制第一个三角形的代码便是这样:

代码语言:javascript
复制
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

        gl.drawArrays(gl.TRIANGLES, 0, 3);

绘制第二个三角形类似,由此可以看出,使用VAO对象之后,gl.bindVertexArray这一行代码相当于以下代码:

代码语言:javascript
复制
        gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
        gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(0);
        gl.bindBuffer(gl.ARRAY_BUFFER, colorBuffer);
        gl.vertexAttribPointer(1, 3, gl.FLOAT, false, 0, 0);
        gl.enableVertexAttribArray(1);

也就是绑定缓冲区对象,分配attribute和启用attribute变量等等操作都可以在绘制的时候可以不再调用了。 有次可以看出,使用VAO对象的好处:

  • 减少代码量,提高开发效率
  • 提高绘制效率(因为减少了WebGL相关函数的调用,并且WebGL内部对VAO进行了优化)

WebGL1中如何使用VAO

在WebGL1.0中VAO是通过扩展方式提供的,首先需要获取对应的扩展对象:

代码语言:javascript
复制
var ext = gl.getExtension("OES_vertex_array_object");

如果返回的ext位null说明浏览器不支持该扩展。 有了上面的ext对象,便可以创建VAO了:

代码语言:javascript
复制
var vao = ext.createVertexArrayOES();

有了VAO对象之后,就可以进行绑定操作:

代码语言:javascript
复制
// bind
ext.bindVertexArrayOES(vao);
// unbind
ext.bindVertexArrayOES(null);
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 顶点数组对象
    • 顶点数组对象的优点
      • 案例:用顶点数组对象绘制两个三角形
        • 定义三角形相关数据和缓冲区
        • VAO对象在创建顶点数据的作用
        • VAO 对象在绘制的时候的作用
      • WebGL1中如何使用VAO
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档