一.html中添加画布
<body onload="main()">
<canvas id="glcanvas" width="640" height="480">
你的浏览器似乎不支持或者禁用了 HTML5 <code><canvas></code> 元素。
</canvas>
</body>
二.初始化 WebGL 上下文
const canvas = document.querySelector("#glcanvas");
// 初始化 WebGL 上下文
const gl = canvas.getContext("webgl");
// 确认 WebGL 支持性
if (!gl) {
alert("无法初始化 WebGL,你的浏览器、操作系统或硬件等可能不支持 WebGL。");
return;
}
三.开始绘制
(1) 清空绘图区
// 使用完全不透明的黑色清除所有图像
gl.clearColor(0.0, 0.0, 0.0,1.0);
// 用上面指定的颜色清除缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
缓冲区: gl.COLOR_BUFFER_BIT 颜色缓冲区、gl.DEPTH_BUFFER_BIT 深度缓冲区、gl.STENCIL_BUFFER_BIT 模板缓冲区
清理函数: gl.clearColor(red,green,blue,alpha)、gl.clearDepth(depth)、gl.clearStencil(s)
(2)添加着色器
顶点着色器:顶点着色器是用来描述顶点特性(如位置、尺寸等)的程序,顶点代表的是组成物体的每一个点。
片元着色器:进行片元处理过程如光照的程序。片元(fragment)是一个WebGL术语,你可以将其理解为像素(图像的单元)。
//定义顶点着色器
//着色器以字符串的形式,通过创建一个主函数 void main() {}
//attribute变量 传输时那些与顶点相关的数据 将会从缓冲中获取数据
//gl_Position: 指定绘制的坐标,接收一个拥有4个浮点分量的vec4数据。分别代表 x,y,z,w数据
//gl_PointSize: 表示要绘制图形的尺寸大小
//gl_FragColor: 定义图形颜色
const vsSource = `
attribute vec4 aVertexPosition;
void main() {
gl_Position = aVertexPosition;
gl_PointSize = 30.0;
}
`;
//定义片元着色器
const fsSource = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 1.0, 1.0);
}
`;
//创建顶点着色器
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
//数据添加并编译
gl.shaderSource(vertexShader, vsSource);
gl.compileShader(vertexShader);
//创建片元着色器
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//数据添加并编译
gl.shaderSource(fragmentShader, fsSource);
gl.compileShader(fragmentShader);
(3)创建着色程序
//将着色器添加到程序中
const program = gl.createProgram();
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
//关联program
gl.linkProgram(program);
//使用program
gl.useProgram(program);
(4)图形绘制
//获取着色器声明的变量
var positionAttributeLocation = gl.getAttribLocation(program, "aVertexPosition");
//通过此方法激活属性
gl.enableVertexAttribArray(positionAttributeLocation);
//属性值从缓冲中获取数据,所以我们创建一个缓冲对象
const positionBuffer = gl.createBuffer();
//将绑定点gl.ARRAY_BUFFER 绑定到缓冲数据
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
// 三个二维点坐标
const positions = [
0, 0,
0, 1,
0.5, 1
];
//指定读取数据的方式
//加载缓冲数据 通过绑定点向缓冲中存放数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW)
var size = 2; // 每次迭代运行提取两个单位数据
var type = gl.FLOAT; // 每个单位的数据类型是32位浮点型
var normalize = false; // 不需要归一化数据
var stride = 0; // 0 = 移动单位数量 * 每个单位占用内存(sizeof(type))
// 每次迭代运行运动多少内存到下一个数据开始点
var offset = 0; // 从缓冲起始位置开始读取
//gl.vertexAttribPointer是将属性绑定到当前的ARRAY_BUFFER(即positionBuffer)中
gl.vertexAttribPointer(positionAttributeLocation, size, type, normalize, stride, offset)
var mode = gl.TRIANGLES;
var offset = 0;
var count = 3;
//表示从第一个顶点开始画一个三角形
gl.drawArrays(mode, offset, count);
//也可以绘制点
gl.drawArrays(gl.POINTS, 0, 1);