1. 如何使用webgl的缓冲区,使其一次性的写入多条数据,渲染多条数据。
这个的实现需要发这几步走。
1. 创建缓冲区
2. 将已经创建的缓冲区绑定到WebGL系统中已经存在的 “目标”
3. 向缓冲区传入(写入)数据
4. 将缓冲区的数据分配给webgl中的变量(attribute);
5. 开启attribute变量。
2.创建缓冲区
const vertexBuffer = gl.createBuffer()
此时的webgl系统中的变化为
3.将已经创建的缓冲区绑定到WebGL系统中已经存在的 “目标”
1.因为我们不能直接向缓冲区写入数据,而只能向"目标"写入数据
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
此时的webgl系统中的变化为
4.向缓冲区中写入数据
1.我们不能直接向缓冲区中写入数据,只能向“目标”写入数据。
2.所以需要先将缓冲区和“目标”绑定到一起。
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
此时webgl中的变化
5. 将缓冲区的数据分配给webgl中的变量(attribute);
这一步是将缓冲区的数据,分配给webgl中的变量,所以、、
1.先要获取这个变量的存储地址
2.然后才能分配。
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
a_Position 是 webgl中的变量,
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
6.开启attribute变量。
gl.enableVertexAttribArray(a_Position);
6.案例代码(同时绘制三个点)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
#canvas {
height: 300px;
width: 300px;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
// 获取webGL执行的执行上下文
// const VSHADER_SOURCE =
// 'void main() { \n'+
// ' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
// ' gl_PointSize = 5.0;\n'+
// '}\n';
const VSHADER_SOURCE =
'attribute vec4 a_Position;\n'+
'void main() { \n'+
' gl_Position = a_Position;\n'+
' gl_PointSize = 10.0;\n'+
'}\n';
// const FSHADER_SOURCE =
// 'void main() { \n'+
// ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n'+
// '};\n'
const FSHADER_SOURCE =
'void main() { \n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';
const gl = canvas.getContext('webgl');
function createshader(gl, type, source) {
const shader = gl.createShader(type); // 创建type类型的着色器(顶点着色器,片源着色器);
gl.shaderSource(shader, source); // 向shader设置GLSL代码,其实就是设置数据源。
gl.compileShader(shader); // 开始编译shader(着色器);
const compileStatus = gl.getShaderParameter(shader, gl.COMPILE_STATUS); status
if (!compileStatus) {
const err = gl.getShaderInfoLog(shader); // 获取编译 shader的信息。
console.log(`着色器编译报错的信息为:${
err}`);
gl.deleteShader(shader); // 编译报错,就要删除对应的着色器(shader);
return null
}
return shader;
}
function createProgram(gl, vshader, fshader) {
const vertexShader = createshader(gl, gl.VERTEX_SHADER, vshader);
// return;
const fragmentShader = createshader(gl, gl.FRAGMENT_SHADER, fshader);
if (!vertexShader || !fragmentShader) {
console.log('着色器创建失败')
return null;
}
const program = gl.createProgram(); // 创建一个webgl程序吧
gl.attachShader(program, vertexShader); // 为 program绑定一个着色器
gl.attachShader(program, fragmentShader); // 为 program绑定一个着色器
gl.linkProgram(program);
const linkState = gl.getProgramParameter(program, gl.LINK_STATUS); // 获取program与着色器链接的状态。
if (!linkState) {
const err = gl.getProgramInfoLog(program); // 获取program的链接信息
console.log(err, 'sd')
console.log(`链接报错的原因是${
err}`)
gl.deleteShader(vertexShader); // 删除顶点着色器
gl.deleteShader(fragmentShader); // 删除片源着色器
gl.deleteProgram(program); // 删除program;
return null;
}
return program
}
function initShader() {
const program = createProgram(gl, VSHADER_SOURCE, FSHADER_SOURCE);
if (!program) {
console.log('程序创建失败');
return false;
}
gl.useProgram(program);
gl.program = program;
}
initShader();
function onTime(data) {
// 1.创建一个缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer); // 将已经创建的缓冲区,绑定到webgl系统中存在的目标。
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); // 将数据写入缓冲区,是在gl.ARRAY_BUFFER中的缓冲区
// 获取a_Position这个变量的存储地址.
const a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// 为a_Position这个变量存储的地址,分配缓冲区数据
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
gl.clearColor(0.0, 0.0, 1.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINIS, 0, 3);
}
const data = new Float32Array([0.0,0.5,0.5,0,-0.5,0.0])
onTime(data)
// gl.clearColor(0.0, 0.0, 1.0, 1.0);
// gl.clear(gl.COLOR_BUFFER_BIT);
// gl.drawArrays(gl.POINIS, 0, 1);
</script>
</body>
</html>