10 WebGL的缓冲区对象使用

前面的方法只能绘制一个点,而不能绘制多个顶点组成的图形,比如三角形、矩形和立方体,像那些方法我们需要一次性的将图形的顶点全部传入顶点着色器,然后才能把图形画出来。

WebGL提供了一种很方便的机制,就是缓冲区对象,它可以一次性向着色器传入多个顶点的数据。缓冲区对象是WebGL系统中的一块内存区域,我们可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用。

案例查看地址:点击这里

<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body οnlοad="main()">
<canvas id="canvas" height="400" width="400">
    你的浏览器不支持WebGL,请更换新的浏览器
</canvas>
</body>
<script src="lib/webgl-utils.js" ></script>
<script src="lib/webgl-debug.js" ></script>
<script src="lib/cuon-utils.js" ></script>
<script>
    //顶点着色器程序
    var VSHADER_SOURCE="" +
        "attribute vec4 a_Position;\n" +
        "void main(){\n" +
        "   gl_Position = a_Position;\n" +//设置坐标
        "   gl_PointSize = 5.0;\n" +//设置尺寸
        "}\n";

    //片元着色器程序
    var FSHADER_SOURCE = "" +
        "void main(){\n" +
        "   gl_FragColor = vec4(1.0,0.0,0.0,1.0);\n" +//设置颜色
        "}\n";

    function main() {
        //首先获取到canvas的dom对象
        var canvas = document.getElementById("canvas");

        //获取到WebGL的上下文
        var gl = getWebGLContext(canvas);

        //不支持WebGL的浏览器将打印一个错误,并结束代码运行
        if (!gl) {
            console.log("浏览器不支持WebGL");
            return;
        }

        //初始化着色器
        if(!initShaders(gl,VSHADER_SOURCE,FSHADER_SOURCE)){
            console.log("初始化着色器失败");
            return;
        }

        //设置顶点位置
        var n = initVertexBuffers(gl);
        if(n < 0){
            console.log("无法获取顶点相关的信息");
            return;
        }

        //指定一个覆盖(清空)canvas的颜色
        gl.clearColor(0.0, 0.0, 0.0, 1.0);

        //清除canvas
        gl.clear(gl.COLOR_BUFFER_BIT);

        //将三个点绘制出来
        gl.drawArrays(gl.POINTS,0,n);
    }

    function initVertexBuffers(gl) {
        var vertices = new Float32Array([0.0,0.5,-0.5,-0.5,0.5,-0.5]);
        var n = 3; //绘制点的个数

        //创建缓冲区对象
        var vertexBuffer = gl.createBuffer();
        if(!vertexBuffer){
            console.log("创建缓冲区对象失败");
            return -1;
        }

        //将缓冲区对象绑定到目标
        gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);

        //向缓冲区对象中写入数据
        gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);

        //获取attribute变量的存储位置
        var a_Position = gl.getAttribLocation(gl.program, "a_Position");

        if(a_Position < 0){
            console.log("无法获取变量的存储位置");
            return;
        }

        //将缓冲区对象分配给a_Position变量
        gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0);

        //链接a_Position变量与分配给它的缓冲区对象
        gl.enableVertexAttribArray(a_Position);

        return n;
    }
</script>
</html>
前面的代码和以前没什么区别,有区别的地方就是从书写创建顶点开始,写入了一个方法内

首先我们创建了一个类型化数组,使用了new运算符,并以[第一个顶点的x坐标,第一个顶点的y坐标,第二个顶点的x坐标,第二个y坐标......]的形式创建这个数组。

由于javascript没有对“大量元素都是同一种类型”的数组这种情况进行优化,所以WebGL引入了类型化数组,Float32Array就是其中之一


类型化数组

为了绘制三维图形,WebGL通常需要同时处理大量相同类型的数据,例如顶点的坐标和颜色数据。为了优化性能,WebGL为每种基本数据类型引入了一种特殊的数组(类型化数组)。浏览器事先知道数组中的数据类型,所以处理起来也更加效率(处理每一项的时候不用处理类型了)


类型化数组不支持push()和pop()方法


你也可以通过制定数组元素的个数来创建一个空的类型化数组

var vertices = new Float32Array(4);

我们解析一下这个方法,这个方法遵循了五个步骤:

第一步:创建缓冲区对象(gl.createBuffer())
第二步:绑定缓冲区对象(gl.bindBuffer())
第三步:将数据写入缓冲区对象(gl.bufferData())
第四步:将缓冲区对象分配给一个attribute变量(gl.vertexAttribPointer())
第五步:开启attribute变量(gl.enableVertexAttribArray())
第一步:创建缓冲区对象方法(gl.createBuffer())和对应的删除缓冲区对象方法(gl.deleteBuffer())

gl.createBuffer()

gl.deleteBuffer()


第二步:绑定缓冲区(gl.bindBuffer())


第三步:向缓存区对象中写入数据(gl.bufferData())

我们不能直接向缓冲区写入数据,而只能向“目标”写入数据,所以要想缓冲区写数据,必须先绑定。



将缓冲区对象分配给attribute变量(gl.vertexAttribPointer())


这一步完成后,我们就已经将缓冲区对象分配给了attribute变量,现在attribute变量处于待命状态,需要我们进行开启


开启attribute变量(gl.enableVertexAttribArray())


同样,你也可以使用gl.diableVertexAttribArray()来关闭分配


最后,我们还是使用gl.drawArrays()方法将缓冲区的顶点绘制出来即可

注意:开启attribute变量后,你就不能使用gl.vertexAttrib[1234]f()向它传数据了,除非你显式地关闭该变量attribute变量。实际上,你无法(也不应该)同时使用这两个函数。


gl.drawArrays()的第2个和第3个参数


我们设置了第二个值为0,第三个值为3,表示从第一个坐标开始绘制,一共绘制了三次。


  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
基本信息 原书名:WebGL Programming Guide: Interactive 3D Graphics Programming with WebGL (OpenGL) 原出版社: Addison-Wesley Professional 作者: (美)Kouichi Matsuda Rodger Lea(松田浩一,罗杰.李) 译者: 谢光磊 出版社:电子工业出版社 ISBN:9787121229428 上架时间:2014-6-11 出版日期:2014 年6月 开本:16开 页码:470 版次:1-1 ---------------------------------------- 目录 《WebGL编程指南》 第1 章 WebGL 概述 1 WebGL 的优势 3 使用文本编辑器开发三维应用 3 轻松发布三维图形程序 4 充分利用浏览器的功能 5 学习和使用WebGL 很简单 5 WebGL 的起源 5 WebGL 程序的结构 6 总结 7 第2 章 WebGL 入门 9 Canvas 是什么? 10 使用[canvas] 标签 11 DrawRectangle.js 13 最短的WebGL 程序:清空绘图区 16 HTML 文件(HelloCanvas.html) 16 JavaScript 程序(HelloCanvas.js) 17 用示例程序做实验 22 绘制一个点(版本1) 22 HelloPoint1.html 24 HelloPoint1.js 24 着色器是什么? 25 使用着色器的WebGL 程序的结构 27 初始化着色器 29 顶点着色器 31 片元着色器 33 绘制操作 34 WebGL 坐标系统 35 用示例程序做实验 37 绘制一个点(版本2) 38 使用attribute 变量 38 示例程序(HelloPoint2.js) 39 获取attribute 变量的存储位置 41 向attribute 变量赋值 42 gl.vertexAttrib3f() 的同族函数 44 用示例程序做实验 45 通过鼠标点击绘点 46 示例程序(ClickedPoints.js) 47 注册事件响应函数 48 响应鼠标点击事件 50 用示例程序做实验 53 改变点的颜色 55 示例程序(ColoredPoints.js) 56 uniform 变量 58 获取uniform 变量的存储地址 59 向uniform 变量赋值 60 gl.uniform4f() 的同族函数 61 总结 62 第3 章 绘制和变换三角形 63 绘制多个点 64 示例程序(MultiPoint.js) 66 使用缓冲区对象 69 创建缓冲区对象(gl.createBuffer()) 70 绑定缓冲区(gl.bindBuffer()) 71 向缓冲区对象中写入数据(gl.bufferData()) 72 类型化数组 74 将缓冲区对象分配给attribute 变量(gl.vertexAttribPointer()) 75 开启attribute 变量(gl.enableVertexAttribArray()) 77 gl.drawArrays() 的第2 个和第3 个参数 78 用示例程序做实验 79 Hello Triangle 80 示例程序(HelloTriangle.js) 80 基本图形 82 用示例程序做实验 83 Hello Rectangle(HelloQuad) 84 用示例程序做实验 85 移动、旋转和缩放 86 平移 87 示例程序(TranslatedTriangle.js) 88 旋转 91 示例程序(RotatedTriangle.js) 93 变换矩阵:旋转 97 变换矩阵:平移 100 4×4 的旋转矩阵 101 示例程序(RotatedTriangle_Matrix.js) 102 平移:相同的策略 105 变换矩阵:缩放 106 总结 108 第4 章 高级变换与动画基础 109 平移,然后旋转 109 矩阵变换库:cuon-matrix.js 110 示例程序(RotatedTriangle_Matrix4.js) 111 复合变换 113 示例程序(RotatedTranslatedTriangle.js) 115 用示例程序做实验 117 动画 118 动画基础 119 示例程序(RotatingTriangle.js) 119 反复调用绘制函数(tick()) 123 按照指定的旋转角度绘制三角形(dr

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值