WebGL编程(3)-缓冲区对象和类型化数组

什么是缓冲区对象?

普通方式一次只能向顶点着色器写入一个点,而缓冲区对象可以向着色器一次性传入多个顶点数据,从而快速创建几何图形,如三角形、矩形、立方体等。它是WebGL系统中的一块内存区域,可以填充大量的顶点数据,保存在其中,供顶点着色器使用。

方法:

  1. #.createBuffer()
    创建缓冲区对象。
    返回值 : 非null,新创建的建缓冲区对象;
          null,创建缓冲区对象失败。
    错误:

  2. #.deleteBuffer(buffer)
    删除参数buffer表示的缓冲区对象。
    参数: buffer,待删除的缓冲区对象
    返回值:
    错误:

  3. #.bindBuffer(target,buffer)
    允许使用buffer表示的缓冲区对象并将其绑定到target表示的目标上。
    参数: target参数可以是以下中的一个:
            ①gl.ARRAY_BUFFER,表示缓冲区对象包含了顶点的数据;
            ②gl.ELEMENT_ARRAY_BUFFER,表示缓冲区对象包含了顶点的索引值;
           buffer,指定之前由gl.createBuffer()返回的待绑定的缓冲区对象
    返回值:
    错误: INVALID_ENUM,target不是上述值之一,这时将保持原有的绑定情况不变

  4. #.bufferData(target,data,usage)
    开辟存储空间,向绑定在target上的缓冲区对象中写入数据data。
    参数: target gl.ARRAY_BUFFER或gl.ELEMENT_ARRAY_BUFFER
         data,写入缓冲区对象的数据(类型化数组)
         usage,表示程序将如何使用存储在缓冲区对象中的数据。
           该参数将帮助WebGL优化操作,但是就算传入错误的值,也不会终止程序,仅仅是降低程序的效率:
              ①gl.STATIC_DRAW,只会想缓冲区对象写入一次数据,但需要绘制很多次
              ②gl.STREAM_DRAW,只会向缓冲区对象写入一次数据,然后绘制若干次
              ③gl.DYNAMIC_DRAW,会向缓冲区对象多次写入数据,并绘制很多次
    返回值:
    错误: INVALID_ENUM,target不是上述值之一,这时将保持原有的绑定情况不变

  5. #.vertexAttribPointer(location,size,type,normalized,stride,offset)
    将绑定到gl.ARRAY_BUFFER的缓冲区对象分配给由location指定的attribute变量

参数location指定待分配attribute变量的存储位置
size指定缓冲区中每个顶点的分量个数(1-4),若size比attribute变量需要的分量数小,缺失分量将按照与gl.vertexAttrib[1234]f()相同的规则补全。比如,size为1,那么第2,3分量自动设为0,第4分量为1
type用以下类型之一来指定数据类型:   ①gl.UNSIGNED_BYTE,无符号字节,Uint8Array;   ②gl.SHORT,短整型,Int16Array;   ③gl.UNSIGNED_SHORT,无符号短整型,Uint16Array;   ④gl.INT,整型,Int32Array;   ⑤gl.UNSIGNED_INT,无符号整型,Uint32Array;   ⑥gl.FLOAT,浮点型,Float32Array;
normalize传入true或false,表明是否将非浮点型的数据归一化到[0,1]或[-1,1]区间
stride指定相邻两个顶点间的字节数,默认为0
offset指定缓冲区对象中的偏移量(以字节为单位),即attribute变量从缓冲区中的何处开始存储,如果是从其实位置开始的,offset设为0
返回值
错误INVALID_OPERATION不存在当前程序对象
INVALID_VALUElocation大于等于attribute变量的最大数目(默认为8),或者stride或offset为负值
  1. #.enableVertexAttribArray(location)
    开启location指定的attribute变量
    参数: location,指定attribute变量的存储位置
    返回值:
    错误: INVALID_VALUE,location大于等于attribute变量的最大数目(默认为8)

  2. #.disableVertexAttribArray(location)
    关闭location指定的attribute变量
    参数: location,指定attribute变量的存储位置
    返回值:
    错误: INVALID_VALUE,location大于等于attribute变量的最大数目(默认为8)


类型化数组

在绘制三维图形时,WebGL会处理大量相同类型的数据,例如顶点的坐标和颜色等数据。为了优化性能,WebGL为每种基本数据类型引入了一种特殊的数组,即类型化数组。

数组名每个元素所占字节数描述
Int8Array18位整型数(signed char)
UInt8Array18位无符号整型数(unsigned char)
Int16Array216位整型数(signed short)
UInt16Array216位无符号整型数(usigned short)
Int32Array432位整型数(signed int)
Uint32Array432位无符号整型数(usigned int)
Float32Array4单精度32位浮点数(float)
Float64Array8双精度64位浮点数(double)

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

方法:

  1. #.get(index)
    获取第index个元素值
  2. #.set(index,value)
    设置第index个元素的值为value
  3. #.set(array,offset)
    从第offset个元素开始将数组array中的值填充进去

属性:
#.length
数组的长度

常量:
#.BYTES_PER_ELEMENT
元素中每个元素所占的字节数

初始化数组:

var vertices = new Float32Array(4);//直接声明数组元素个数

var vertices=new Float32Array([0.0,0.5,-0.5,-0.5,0.5,-0.5]);//直接给数组赋值

例子:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>缓冲区对象和类型化数组</title>
		<script type="text/javascript" src="js/lib/webgl-debug.js" ></script>
		<script type="text/javascript" src="js/lib/webgl-utils.js" ></script>
		<script type="text/javascript" src="js/lib/cuon-utils.js" ></script>
	</head>
	<body>
		<canvas id='canvas' width="600" height="600">该浏览器不支持WebGL!</canvas>
		
		<script id="vertexShader" type="x-shader/x-vertex">
			attribute vec4 a_Position;
			void main(){
				gl_Position=a_Position;
				gl_PointSize=5.0;
			}
		</script>
		
		<script id="fragmentShader" type="x-shader/x-fragment">
			void main(){
				gl_FragColor=vec4(1.0,0.0,0.0,1.0);
			}
		</script>
		
		<script>
			(function main(){
				var canvas=document.getElementById("canvas");
				var vShader=document.getElementById("vertexShader").textContent;
				var fShader=document.getElementById("fragmentShader").textContent;
			
				var gl=getWebGLContext(canvas);
				if(!gl){
					console.log("该浏览器不支持WebGL!");
					return ;
				}
				
				if(!initShaders(gl,vShader,fShader)){
					console.log('初始化着色器失败!');
					return ;
				}
				
				//初始化顶点缓冲区,设置顶点位置
				var n=initVertexBuffer(gl);
				if(n<0){
					console.log('无法获取顶点相关信息!');
					return ;
				}
				
				gl.clearColor(0.0,0.0,0.0,1.0);
				gl.clear(gl.COLOR_BUFFER_BIT);
				
				gl.drawArrays(gl.POINTS,0,n);
			}());
			
			function initVertexBuffer(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>
	</body>
</html>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值