一次需要绘制多个点,需要同时传递进去多个点的数据。刚好,在WebGL中提供了一种机制:缓存区对象(buffer data),缓存区对象可以同时向着色器传递多个顶点坐标。缓存区是WebGL中的一块内存区域,我们可以向里面存放大量顶点坐标数据,可随时供着色器使用。
使用缓存区步骤
1.创建缓存区对象(gl.createBuffer())
2.绑定缓存区对象(gl.bindBuffer())
3.将数据写入缓存区对象(gl.bufferData())
4.将缓存区对象分配给一个attribute变量(gl.vertexAttribPointer())
5.开启attribute变量(gl.enableVertexAttribArray())
首先,需要创建一个缓冲区来承载大量顶点的坐标
//创建缓存区
var vertexBuffer = gl.createBuffer();
if(!vertexBuffer) {
log('创建缓存区失败。');
return -1;
}
//将创建的缓存区对象绑定到target表示的目标上
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//开辟存储空间,向绑定在target上的缓存区对象中写入数据
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
//获取着色器中的变量值
var a_position = gl.getAttribLocation(gl.program, 'a_p');
//将缓存区对象绑定到着色器变量中
gl.vertexAttribPointer(a_position, 3, gl.FLOAT, false, 0, 0);
// 启用缓存区
gl.enableVertexAttribArray(a_position);
// 绘制缓存区中画的多个顶点
gl.drawArrays(gl.POINTS, 0 , array);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>cmd_webgl_study3</title>
</head>
<body>
<!-- 1.创建webgl标签 -->
<canvas id="webgl" width="500" height="500"></canvas>
<script type="shader" id="vertex">
attribute vec4 apos;
attribute float a_PointSize;
void main(){
gl_PointSize = 20.0;
gl_Position = apos;
}
</script>
<script type="shader" id="fragment">
precision mediump float;
uniform vec4 vColor;
void main(){
gl_FragColor = vec4(0.0,1.0,0.0,1.0);
}
</script>
<script src="./libs/webgl_libs.js"></script>
<script>
// 2.得到canvas element
let canvas = document.getElementById('webgl');
// 3.得到上下文对象 context
let gl = canvas.getContext('webgl');
//4.编写顶点着色器源代码、实际绘制的代码,GPU:描述一个顶点的大小、位置(3d坐标) 顶点着色器
let vertex_shader_source = document.getElementById("vertex").innerHTML;
//5.片元着色器源代码:描述一个点的颜色 片元着色器
let fragment_shader_source = document.getElementById("fragment").innerHTML;
let program = create_program(gl,vertex_shader_source,fragment_shader_source);
let apos = gl.getAttribLocation(program,'apos');
// 1.创建buf
let buffer = gl.createBuffer();
//2.绑定buf
gl.bindBuffer(gl.ARRAY_BUFFER,buffer);
/*3.由于javascript没有对“大量元素都是同一种类型”的数组这种情况进行优化,
所以WebGL引入了类型化数组,Float32Array就是其中之一.
*/
let data = new Float32Array([
0.3,0.5,
0.6,0.0,
0.9,0.7
]);
//向缓存区对象中写入数据 gl.STATIC_DRAW : 只会向缓存区对象中写入一次数据,但需要绘制很多次
gl.bufferData(gl.ARRAY_BUFFER,data,gl.STATIC_DRAW);
/*将缓冲区对象分配给指定变量.
1.赋值的apos变量
2:指定每个顶点数据的分量个数(1或4)
*/
gl.vertexAttribPointer(apos,2,gl.FLOAT,false,0,0);
//开启apos变量
gl.enableVertexAttribArray(apos);
// 13.设置背景色
gl.clearColor(1.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
// 14.绘制
gl.drawArrays(gl.POINTS,0,3);
</script>
</body>
</html>
网友评论