webgl使用
https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext
var canvas = document.getElementById('myCanvas');
// 返回WebGLRenderingContent对象
var gl = canvas.getContext('webgl');
webgl-utils.js,webgl-debug.js,cuon-utils.js 到下面的地址去下载
https://github.com/GrayMind/WebGL-Programming-Guide
1、清空绘图区
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="./lib/webgl-utils.js"></script>
<script src="./lib/webgl-debug.js"></script>
<script src="./lib/cuon-utils.js"></script>
<script>
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
}
debugger
main()
</script>
</body>
</html>
2、绘制一个点
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="./lib/webgl-utils.js"></script>
<script src="./lib/webgl-debug.js"></script>
<script src="./lib/cuon-utils.js"></script>
<script>
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE =
'void main() {\n' +
// vec4(x, y, z, w); x表示横向轴,y表示纵向轴,z轴
// w是齐次坐标 齐次坐标(x, y, z, w) 等价于 (x/w, y/w, z/w);
' gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' + // 设置点的位置
' gl_PointSize = 10.0;\n' + // 设置点的大小
'}\n';
// 片元着色气
var FSHADER_SOURCE =
'void main() {\n' +
' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
setShaders(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
}
main()
</script>
</body>
</html>
2.1、绘制一个点(版本2),使用attribute变量,使用uniform变量
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
// vec4(x, y, z, w); x表示横向轴,y表示纵向轴,z轴, w齐次坐标(默认为1)
// w是齐次坐标 齐次坐标(x, y, z, w) 等价于 (x/w, y/w, z/w);
' gl_Position = a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色气
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_Position < 0 || a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
setShaders(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);
}
main()
</script>
</body>
</html>
3、使用缓冲区绘制多个点
1、创建缓冲区对象
const buffer = gl.createBuffer()
2、将缓冲区对象绑定到target对象上
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
3、将顶点坐标数据写入缓冲区对象
gl.bufferData(gl.ARRAY_BUFFER, buffer, gl.STATIC_DRAW)
4、将顶点坐标数据分配给对应的attribute变量
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
5、开启attribute变量
gl.enableVertexAttribArray(a_Position)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
// vec4(x, y, z, w); x表示横向轴,y表示纵向轴,z轴, w齐次坐标(默认为1)
// w是齐次坐标 齐次坐标(x, y, z, w) 等价于 (x/w, y/w, z/w);
' gl_Position = a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色气
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
var initVertexBuffers = function () {
// 1.创建缓冲区对象
// gl.dleteBuffer(buffer); 删除缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new TypeError("创建缓冲区失败");
}
var vertices = new Float32Array([
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
])
// 2.绑定缓冲区对象到目标
// gl.bindBuffer(gl.ARRAY_BUFFER|gl.ELEMENT|ARRAY_BUFFER|buffer, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区写入数据
// gl.bufferData(gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER, data, usage);
// usage gl.STATIC_DRAW | gl.STREAM_DRAW | gl.DYNAMIC_DRAW
// gl.STATIC_DRAW: 只会想缓冲区对象写入一次数据,但需要绘制很多次
// gl.STREAM_DRAW: 只会想缓冲区对象写入一次数据,然后绘制若干次
// gl.DYNAMIC_DRAW: 会向缓冲区对象中多次写入数据,并绘制很多次
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 4.将缓冲区对象分配给变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
throw new TypeError("无法获取变量的存储位置")
}
// gl.vertexAttribPointer(location, size, type, normalize, stride, offset);
// location 就是变量
// size 可选值是 1-4,和vec4的赋值一样
// type 表示类型,gl.FLOAT 浮点型,gl.INT(int32Array) 整形,...
// normalize 传入true或false,表明是否将非浮点型的数据归一化到[1,0]或[-1,1]区间
// stride 指定相邻两个顶点间的字节数,默认为0
// offset 指定缓冲区对象中的偏移量(以字节为单位)即attribute变量从缓冲区中何处开始存储。如果从起始位置开始,offset设置为0
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 5.连接a_Poistion变量于分配给它缓冲区对象
// 开启变量 gl.enableVertexAttribArray(location);
gl.enableVertexAttribArray(a_Position);
return 3;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.drawArrays(mode, first, count);
// mode 表示绘制的方式
// first 从那个顶点开始绘制
// count 绘制几个顶点
gl.drawArrays(gl.POINTS, 0, n);
}
main()
</script>
</body>
</html>
3.1绘制正方形
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
// vec4(x, y, z, w); x表示横向轴,y表示纵向轴,z轴, w齐次坐标(默认为1)
// w是齐次坐标 齐次坐标(x, y, z, w) 等价于 (x/w, y/w, z/w);
' gl_Position = a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色气
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
var initVertexBuffers = function () {
// 1.创建缓冲区对象
// gl.dleteBuffer(buffer); 删除缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new TypeError("创建缓冲区失败");
}
// 三角形
var TRIANGLE = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]
// 正方形
var square = [
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, 0.5, // v2
0.5, -0.5 // v3
]
var vertices = new Float32Array(square);
// 2.绑定缓冲区对象到目标
// gl.bindBuffer(gl.ARRAY_BUFFER|gl.ELEMENT|ARRAY_BUFFER|buffer, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区写入数据
// gl.bufferData(gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER, data, usage);
// usage gl.STATIC_DRAW | gl.STREAM_DRAW | gl.DYNAMIC_DRAW
// gl.STATIC_DRAW: 只会想缓冲区对象写入一次数据,但需要绘制很多次
// gl.STREAM_DRAW: 只会想缓冲区对象写入一次数据,然后绘制若干次
// gl.DYNAMIC_DRAW: 会向缓冲区对象中多次写入数据,并绘制很多次
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 4.将缓冲区对象分配给变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
throw new TypeError("无法获取变量的存储位置")
}
// gl.vertexAttribPointer(location, size, type, normalize, stride, offset);
// location 就是变量
// size 可选值是 1-4,和vec4的赋值一样
// type 表示类型,gl.FLOAT 浮点型,gl.INT(int32Array) 整形,...
// normalize 传入true或false,表明是否将非浮点型的数据归一化到[1,0]或[-1,1]区间
// stride 指定相邻两个顶点间的字节数,默认为0
// offset 指定缓冲区对象中的偏移量(以字节为单位)即attribute变量从缓冲区中何处开始存储。如果从起始位置开始,offset设置为0
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 5.连接a_Poistion变量于分配给它缓冲区对象
// 开启变量 gl.enableVertexAttribArray(location);
gl.enableVertexAttribArray(a_Position);
return 4;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.POINTS 点
// gl.LINES 线段,此时只画出一条线段(一次画一条)
// gl.LINE_STRIP 线条,此时画出两条线,但是没有闭合线段
// gl.LINE_LOOP 回路,一个三角形被画出来,但是都是线段的,没有填充
// gl.TRIANGLES 三角形,一个三角形被画出来,填充了颜色
// gl.TRIANGLES_STRIP 三角带
// g.TRIANGLE_FAN 三角扇
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
main()
</script>
</body>
</html>
3.2 位移
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色器
var VSHADER_SOURCE =
'uniform vec4 u_Translation;\n'+ // 设置偏移位置
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
// a_Position v1 v2 v3 v4
// 加 + + + +
// u_Translation v1 v2 v3 v4
' gl_Position = a_Position + u_Translation;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色器
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
var initVertexBuffers = function () {
// 1.创建缓冲区对象
// gl.dleteBuffer(buffer); 删除缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new TypeError("创建缓冲区失败");
}
// 三角形
var TRIANGLE = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]
// 正方形
var square = [
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, 0.5, // v2
0.5, -0.5 // v3
]
var vertices = new Float32Array(square);
// 2.绑定缓冲区对象到目标
// gl.bindBuffer(gl.ARRAY_BUFFER|gl.ELEMENT|ARRAY_BUFFER|buffer, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区写入数据
// gl.bufferData(gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER, data, usage);
// usage gl.STATIC_DRAW | gl.STREAM_DRAW | gl.DYNAMIC_DRAW
// gl.STATIC_DRAW: 只会想缓冲区对象写入一次数据,但需要绘制很多次
// gl.STREAM_DRAW: 只会想缓冲区对象写入一次数据,然后绘制若干次
// gl.DYNAMIC_DRAW: 会向缓冲区对象中多次写入数据,并绘制很多次
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 4.将缓冲区对象分配给变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
throw new TypeError("无法获取变量的存储位置")
}
var u_Translation = gl.getUniformLocation(gl.program, "u_Translation");
gl.uniform4f(u_Translation, 0.5, 0.5, 0.5, 0.0);
// gl.vertexAttribPointer(location, size, type, normalize, stride, offset);
// location 就是变量
// size 可选值是 1-4,和vec4的赋值一样
// type 表示类型,gl.FLOAT 浮点型,gl.INT(int32Array) 整形,...
// normalize 传入true或false,表明是否将非浮点型的数据归一化到[1,0]或[-1,1]区间
// stride 指定相邻两个顶点间的字节数,默认为0
// offset 指定缓冲区对象中的偏移量(以字节为单位)即attribute变量从缓冲区中何处开始存储。如果从起始位置开始,offset设置为0
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 5.连接a_Poistion变量于分配给它缓冲区对象
// 开启变量 gl.enableVertexAttribArray(location);
gl.enableVertexAttribArray(a_Position);
return 4;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.POINTS 点
// gl.LINES 线段,此时只画出一条线段(一次画一条)
// gl.LINE_STRIP 线条,此时画出两条线,但是没有闭合线段
// gl.LINE_LOOP 回路,一个三角形被画出来,但是都是线段的,没有填充
// gl.TRIANGLES 三角形,一个三角形被画出来,填充了颜色
// gl.TRIANGLES_STRIP 三角带
// g.TRIANGLE_FAN 三角扇
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
main()
</script>
</body>
</html>
3.3 旋转
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<div>
<button onclick="main()">角度+</button>
<div id="angle">
</div>
</div>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
var ANGLE = 0.0;
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'uniform float u_CosB, u_SinB;\n' +
'void main() {\n' +
' gl_Position.x = a_Position.x * u_CosB - a_Position.y * u_SinB;\n' +
' gl_Position.y = a_Position.x * u_SinB - a_Position.y * u_CosB;\n' +
' gl_Position.z = a_Position.z;\n' +
' gl_Position.w = 1.0;\n' +
// ' gl_Position = a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色器
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
var initVertexBuffers = function () {
// 1.创建缓冲区对象
// gl.dleteBuffer(buffer); 删除缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new TypeError("创建缓冲区失败");
}
// 三角形
var TRIANGLE = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]
// 正方形
var square = [
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, 0.5, // v2
0.5, -0.5 // v3
]
var vertices = new Float32Array(TRIANGLE);
// 2.绑定缓冲区对象到目标
// gl.bindBuffer(gl.ARRAY_BUFFER|gl.ELEMENT|ARRAY_BUFFER|buffer, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区写入数据
// gl.bufferData(gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER, data, usage);
// usage gl.STATIC_DRAW | gl.STREAM_DRAW | gl.DYNAMIC_DRAW
// gl.STATIC_DRAW: 只会想缓冲区对象写入一次数据,但需要绘制很多次
// gl.STREAM_DRAW: 只会想缓冲区对象写入一次数据,然后绘制若干次
// gl.DYNAMIC_DRAW: 会向缓冲区对象中多次写入数据,并绘制很多次
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 4.将缓冲区对象分配给变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
throw new TypeError("无法获取变量的存储位置")
}
// gl.vertexAttribPointer(location, size, type, normalize, stride, offset);
// location 就是变量
// size 可选值是 1-4,和vec4的赋值一样
// type 表示类型,gl.FLOAT 浮点型,gl.INT(int32Array) 整形,...
// normalize 传入true或false,表明是否将非浮点型的数据归一化到[1,0]或[-1,1]区间
// stride 指定相邻两个顶点间的字节数,默认为0
// offset 指定缓冲区对象中的偏移量(以字节为单位)即attribute变量从缓冲区中何处开始存储。如果从起始位置开始,offset设置为0
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 5.连接a_Poistion变量于分配给它缓冲区对象
// 开启变量 gl.enableVertexAttribArray(location);
gl.enableVertexAttribArray(a_Position);
var radian = Math.PI * ANGLE / 180.0;
var cosB = Math.cos(radian);
var sinB = Math.sin(radian);
var u_CosB = gl.getUniformLocation(gl.program, "u_CosB");
var u_SinB = gl.getUniformLocation(gl.program, "u_SinB");
document.getElementById("angle").innerHTML = ANGLE.toString();
ANGLE+=1.0;
if (!u_CosB || !u_SinB) {
throw new TypeError("uniform 变量不存在")
}
gl.uniform1f(u_CosB, cosB);
gl.uniform1f(u_SinB, sinB);
return 3;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.POINTS 点
// gl.LINES 线段,此时只画出一条线段(一次画一条)
// gl.LINE_STRIP 线条,此时画出两条线,但是没有闭合线段
// gl.LINE_LOOP 回路,一个三角形被画出来,但是都是线段的,没有填充
// gl.TRIANGLES 三角形,一个三角形被画出来,填充了颜色
// gl.TRIANGLES_STRIP 三角带
// g.TRIANGLE_FAN 三角扇
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
main()
</script>
</body>
</html>
4、 矩阵旋转 + 动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<div>
<button onclick="main()">角度+</button>
<div id="angle">
</div>
</div>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script src="../lib/cuon-matrix.js"></script>
<script>
var ANGLE = 0.0;
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色器
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'uniform mat4 u_xformMatrix;\n' +
'void main() {\n' +
' gl_Position = u_xformMatrix * a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色器
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
var initVertexBuffers = function () {
// 1.创建缓冲区对象
// gl.dleteBuffer(buffer); 删除缓冲区对象
var vertexBuffer = gl.createBuffer();
if (!vertexBuffer) {
throw new TypeError("创建缓冲区失败");
}
// 三角形
var TRIANGLE = [
0.0, 0.5,
-0.5, -0.5,
0.5, -0.5
]
// 正方形
var square = [
-0.5, 0.5, // v0
-0.5, -0.5, // v1
0.5, 0.5, // v2
0.5, -0.5 // v3
]
var vertices = new Float32Array(TRIANGLE);
// 2.绑定缓冲区对象到目标
// gl.bindBuffer(gl.ARRAY_BUFFER|gl.ELEMENT|ARRAY_BUFFER|buffer, buffer);
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
// 3.向缓冲区写入数据
// gl.bufferData(gl.ARRAY_BUFFER|gl.ELEMENT_ARRAY_BUFFER, data, usage);
// usage gl.STATIC_DRAW | gl.STREAM_DRAW | gl.DYNAMIC_DRAW
// gl.STATIC_DRAW: 只会想缓冲区对象写入一次数据,但需要绘制很多次
// gl.STREAM_DRAW: 只会想缓冲区对象写入一次数据,然后绘制若干次
// gl.DYNAMIC_DRAW: 会向缓冲区对象中多次写入数据,并绘制很多次
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);
// 4.将缓冲区对象分配给变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
throw new TypeError("无法获取变量的存储位置")
}
// gl.vertexAttribPointer(location, size, type, normalize, stride, offset);
// location 就是变量
// size 可选值是 1-4,和vec4的赋值一样
// type 表示类型,gl.FLOAT 浮点型,gl.INT(int32Array) 整形,...
// normalize 传入true或false,表明是否将非浮点型的数据归一化到[1,0]或[-1,1]区间
// stride 指定相邻两个顶点间的字节数,默认为0
// offset 指定缓冲区对象中的偏移量(以字节为单位)即attribute变量从缓冲区中何处开始存储。如果从起始位置开始,offset设置为0
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
// 5.连接a_Poistion变量于分配给它缓冲区对象
// 开启变量 gl.enableVertexAttribArray(location);
gl.enableVertexAttribArray(a_Position);
var u_xformMatrix = gl.getUniformLocation(gl.program, "u_xformMatrix")
// cuon-matrix.js 提供的 Matrix4 对象
var xformMatrix = new Matrix4();
xformMatrix.setRotate(ANGLE, 0, 0, 1);
document.getElementById("angle").innerHTML = ANGLE.toString();
ANGLE+=1;
// gl.uniformMatrix4fv的第二个参数在webgl中固定是false
gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix.elements);
return 3;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.POINTS 点
// gl.LINES 线段,此时只画出一条线段(一次画一条)
// gl.LINE_STRIP 线条,此时画出两条线,但是没有闭合线段
// gl.LINE_LOOP 回路,一个三角形被画出来,但是都是线段的,没有填充
// gl.TRIANGLES 三角形,一个三角形被画出来,填充了颜色
// gl.TRIANGLES_STRIP 三角带
// g.TRIANGLE_FAN 三角扇
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
// 旋转速度,多少度1s
var ANGLE_STEP = 1.0;
// 上一次的时间
var g_lost = new Date().getTime();
function animate (__angle) {
var now = Date.now();
var elapsed = now - g_lost; // 经过了多长时间
g_lost = now;
var newAngle = ANGLE + (ANGLE_STEP * elapsed) / 1000;
ANGLE = newAngle;
}
var tick = function() {
main();
animate();
requestAnimationFrame(tick);
}
tick();
</script>
</body>
</html>
画圆
方案一, 通过圆形的画点位,然后使用 g.TRIANGLE_FAN
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script>
function getXYByIndex(index, stepAngle) {
let pai = 3.1415926;
let circleRadius = 0.6;
let angle = stepAngle * index;
let angleInRadian = angle * pai / 180;
let x = Math.cos(angleInRadian) * circleRadius;
let y = Math.sin(angleInRadian) * circleRadius;
return {x, y}
}
//生成顶点着色器需要的所有点的位置
function initVertexBuffers(gl) {
let circleCenter = [0, 0];
let n = 360;
let stepAngle = 360 / n;
let arr = [circleCenter[0], circleCenter[1]];
for (let i = 0; i < n; i++) {
let xy = getXYByIndex(i, stepAngle);
let {x, y} = xy;
arr.push(x);
arr.push(y);
}
//如果没有下面3行代码,会出现一个缺口
let xyRight = getXYByIndex(0, n);
arr.push(xyRight.x);
arr.push(xyRight.y);
let verticesColors = new Float32Array(arr);
let buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
let a_Position = gl.getAttribLocation(gl.program, "a_Position");
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);
return n + 2;
}
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute float a_PointSize;\n' +
'void main() {\n' +
// vec4(x, y, z, w); x表示横向轴,y表示纵向轴,z轴, w齐次坐标(默认为1)
// w是齐次坐标 齐次坐标(x, y, z, w) 等价于 (x/w, y/w, z/w);
' gl_Position = a_Position;\n' + // 设置点的位置
' gl_PointSize = a_PointSize;\n' + // 设置点的大小
'}\n';
// 片元着色气
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (a_PointSize < 0 || !u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
// vertexAttrib3f向变量attribute赋值
// gl.vertexAttrib3f(location, v0, v1, v2)
// 同类型方法有gl.vertexAttrib1f(location, v0)
// 同类型方法有gl.vertexAttrib2f(location, v0, v1)
// 同类型方法有gl.vertexAttrib4f(location, v0, v1, v2, v3)
gl.vertexAttrib1f(a_PointSize, 10.0);
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
setShaders(gl);
var n = initVertexBuffers(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.drawArrays(mode, first, count);
// mode 表示绘制的方式
// first 从那个顶点开始绘制
// count 绘制几个顶点
gl.drawArrays(gl.TRIANGLE_FAN, 0, n);
}
main()
</script>
</body>
</html>
方案二,JavaScript中只算好等间隔的角度,通过角度在顶点着色器中计算出坐标
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Clear canvas</title>
</head>
<body>
<canvas id="webgl" width="400" height="400">
Please use the browser supporting "canvas"
</canvas>
<script src="../lib/webgl-utils.js"></script>
<script src="../lib/webgl-debug.js"></script>
<script src="../lib/cuon-utils.js"></script>
<script src="../lib/cuon-matrix.js"></script>
<script>
function initAngles(gl) {
let n = 360;
let step = 360 / n;
let arr = [];
for (let i = 0; i < n; i++) {
arr.push(step * i);
}
var pai = 3.1415926
for (let i = 0; i < arr.length; i++) {
console.log(Math.cos(arr[i] * pai / 180.0),
Math.sin(arr[i] * pai / 180.0), 0.0, 1.0)
}
let verticesColors = new Float32Array(arr);
let buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);
let a_Angle = gl.getAttribLocation(gl.program, "a_Angle");
gl.vertexAttribPointer(a_Angle, 1, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Angle);
var u_xformMatrix = gl.getUniformLocation(gl.program, "u_xformMatrix")
// cuon-matrix.js 提供的 Matrix4 对象
var xformMatrix = new Matrix4();
xformMatrix.setScale(0.5, 0.5, 0)
// gl.uniformMatrix4fv的第二个参数在webgl中固定是false
gl.uniformMatrix4fv(u_xformMatrix, false, xformMatrix.elements);
return n;
}
/**
* 设置着色器
*/
function setShaders(gl) {
// 顶底着色气
var VSHADER_SOURCE = `
#define pai 3.1415926
precision mediump float;
attribute float a_Angle;//圆上的某个点相对于Z轴的旋转角度
uniform mat4 u_xformMatrix;
void main()
{
//下述的180.0,如果去掉小数点以及其后的0,那么就会报错
float x=cos(a_Angle * pai / 180.0);
float y=sin(a_Angle * pai / 180.0);
gl_Position= u_xformMatrix * vec4(x, y, 0.0, 1.0);
}
`
// 片元着色气
var FSHADER_SOURCE =
'precision mediump float;\n' +
'uniform vec4 u_FragColor;\n' + // uniform变量
'void main() {\n' +
' gl_FragColor = u_FragColor;\n' + // 设置颜色,rgba
'}\n';
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
throw new TypeError("未能初始化着色器");
}
// gl.getAttribLocation 方法是获取attribute变量的存储位置
// var a_PointSize = gl.getAttribLocation(gl.program, 'a_PointSize');
// gl.getUniformLocation 获取uniform变量的存储位置
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor')
if (!u_FragColor) {
throw new TypeError("无法获取变量的存储位置")
}
gl.uniform4f(u_FragColor, 0.0, 1.0, 0.0, 1)
}
function main() {
// 获取 <canvas> 元素
var canvas = document.getElementById('webgl');
// 获取 WebGL 绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log('Failed to get the rendering context for WebGL');
return;
}
setShaders(gl);
var n = initAngles(gl);
// 设置背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 可以查询 gl.COLOR_BUFFER_BIT 的含义,以及clear方法的使用 https://developer.mozilla.org/zh-CN/docs/Web/API/WebGLRenderingContext/clear#%E5%8F%A5%E6%B3%95
// gl.COLOR_BUFFER_BIT 颜色缓冲区
// 清空颜色缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
// gl.drawArrays(mode, first, count);
// mode 表示绘制的方式
// first 从那个顶点开始绘制
// count 绘制几个顶点
gl.drawArrays(gl.TRIANGLE_FAN, 0, n);
}
main()
</script>
</body>
</html>
方案三、
顶点着色器绘制一个和canvas重合的矩形,利用gl_FragCoord的坐标来对每个片元进行圆内筛选
让我觉得可以在片元着色器中来画圆的想法,是来自于片元着色器中的gl_FragCoord对象,gl_FragCoord.xyz可以读取每个像素的x、y、z坐标,拿到坐标,我就可以根据distance()方法来画圆,因为顶点坐标是骨架,再借鉴shaderToy的做法,实现思路,先在顶点着色器中画一个覆盖整个canvas的一个矩形,然后在片元着色器中来画圆
precision mediump float;
void main(){
//canvas是一个400px*400px的矩形,我要在中心点画一个圆
vec2 center=vec2(200, 200);
//gl_FragCoord是一个二维坐标系,坐标原点位于canvas的左下角
vec2 uv=gl_FragCoord.xy;
//画一个半径为150px的圆
bool isInCircle=distance(center, uv)<=150.0;
if (isInCircle){
gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
} else {
//如果没有下述语句,即使设置了gl.clearColor(),圆外底色会变成白色
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}