WebGL(五)——WEBGL缓冲区,绘制三角形
在 WebGL(四)—— 第一个WEBGL程序 一篇中,留了一个问题,
像下面这样的写法,字符串拼接真的很让人觉得麻烦:
关于改进:
缓冲区对象
缓冲区对象(buffer object): 缓冲区对象是WebGL系统中的一块内存区域,我们可以一次性地向缓冲区对象中填充大量的顶点数据,然后将这些数据保存在其中,供顶点着色器使用。
绘制一个三角形,了解缓冲区对象的使用。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<canvas id="webgl" width="500" height="500" style="background-color: honeydew"></canvas>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec4 a_Position;
void main(){
gl_Position = a_Position;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 u_FragColor;
void main(){
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
</script>
<script>
let canvas = document.getElementById("webgl");
let gl = canvas.getContext("webgl");
let vertexSource = document.getElementById("vertexShader").innerText;
let fragmentSource = document.getElementById("fragmentShader").innerText;
//创建着色器+编译
let verShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(verShader,vertexSource);
gl.compileShader(verShader);
let fragShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragShader,fragmentSource);
gl.compileShader(fragShader);
//着色器已经完成了
//创建webgl program
var shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram,verShader);
gl.attachShader(shaderProgram,fragShader);
gl.linkProgram(shaderProgram);
gl.useProgram(shaderProgram);
//program准备完成
//缓冲区部分:
//初始化缓冲区:
let n = initBuffers(gl);
gl.clearColor(0.0,0.0,0.0,1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES,0,n);
function initBuffers(gl){
let vertices = new Float32Array([
0.0,0.5,-0.5,-0.5,0.5,-0.5
])
let n = 3;//点的个数
//创建缓冲区,通知webgl,开辟一个显存空间
let vertexBuffer = gl.createBuffer();
//缓冲区对象绑定到目标对象
//ARRAY_BUFFER表示缓冲区对象中包含的顶点数据
//ELEMENT_ARRAY_BUFFER包含缓冲区对象中包含的顶点的索引值
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
//向缓冲区写入数据
//bufferData方法将vertices传输到gl.ARRAY_BUFFER中,gl.STATIC_DRAW是传输的属性
//gl.STATIC_DRAW允许向缓冲区写入一次数据,但是需要绘制很多次,一次修改,多次使用
//gl.STREAM_DRAW只会向缓冲区对象中写入一次数据,但是绘制若干次,一次修改,一次使用
//gl.DYNAMIC_DRAW会向缓冲区多次写入数据,并且绘制很多次,多次修改,多次使用
gl.bufferData(gl.ARRAY_BUFFER, vertices ,gl.STATIC_DRAW);
//获取webglProgram对象中a_Position变量
let a_Position = gl.getAttribLocation(shaderProgram,'a_Position');
//获取program对象 分配给内置变量
gl.vertexAttribPointer(a_Position,2,gl.FLOAT,false,0,0);
//建立缓冲区与内置变量的连接
gl.enableVertexAttribArray(a_Position);
return n;
}
</script>
</body>
</html>
最终效果: