<!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>动态桌面</title>
<script id="shader-vs" type="x-shader/x-vertex">
attribute vec4 a_position;
attribute float a_pointsize;
void main(){
gl_Position = a_position;
gl_PointSize = a_pointsize;
}
</script>
<!-- 片段着色器,画笔是⚪ -->
<script id="shader-fs" type="x-shader/x-fragment">
precision mediump float;
uniform vec4 a_color;
void main() {
float d = distance(gl_PointCoord, vec2(0.5,0.5));
if(d < 0.5) {
gl_FragColor = a_color;
} else {
discard;
}
}
</script>
</head>
<body>
<canvas id="webgl" width="600" height="600"></canvas>
</body>
<script>
var numGrap = 0;
var canvas = document.querySelector('#webgl');
var gl = canvas.getContext('webgl');
var width = canvas.clientWidth;
var height = canvas.clientHeight;
// 初始webgl画布,画~
function initWebgl() {
let vertexShaderSource = document.querySelector('#shader-vs').text;
let fragmentShaderSource = document.querySelector('#shader-fs').text;
let vertexShader = createShader(gl,gl.VERTEX_SHADER,vertexShaderSource);
let fragmentShader = createShader(gl,gl.FRAGMENT_SHADER,fragmentShaderSource);
let glProgram = createProgram(gl, vertexShader, fragmentShader);
gl.useProgram(glProgram);
render();
}
// 创建着色器
function createShader(gl,type,source) {
let shader = gl.createShader(type);
// 绑定资源
gl.shaderSource(shader, source);
// 编译顶点着色器
gl.compileShader(shader);
// 查看编译结果 失败的话打印失败信息
let success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if(success) {
return shader;
} else {
console.log(gl.getShaderInfoLog(shader));
}
}
// 创建程序
function createProgram(gl, vertexShader, fragmentShader) {
// 创建着色器程序
glProgram = gl.createProgram();
// 顶点着色器/片段着色器添加到着色器程序
gl.attachShader(glProgram, vertexShader);
gl.attachShader(glProgram, fragmentShader);
// 着色器链接成一个完整的程序
gl.linkProgram(glProgram);
return glProgram;
}
function render() {
// webgl的大小
gl.viewport(0,0,width,height);
// 清色
gl.clearColor(0.0,0.0,0.0,1.0);
// webgl.COLOR_BUFFER_BIT 真缓冲区
gl.clear(gl.COLOR_BUFFER_BIT);
const { points, nums } = createPoints(5, numGrap);
setPoints(gl,points, nums, 1.5, [0.0,1.0,0.0,1.0]);
numGrap+=0.5;
if(numGrap > 1000) {
return;
} else {
requestAnimationFrame(render);
}
}
// gap 间隙
function createPoints(gap,gapNum) {
let m = 100;
let n = 10;
let arr = [];
let numToDeg = function(num) {
return Math.PI * Number((num + gapNum) / 30);
};
for(let i =0; i< n; i++) {
for(let j =0; j< m; j++) {
let x = -1 + (j+ j*gap)/(2*m);
let y = -1 + (i + i*(gap-i/2))/50 + 0.1*Math.sin(numToDeg(j));
let z = -i*0.05;
arr.push(x);
arr.push(y);
}
}
let points = new Float32Array(arr);
let nums = 6;
return {
points: points,
nums: m*n,
}
}
function setPoints(gl,data, num, size, color) {
// 创建缓存区对象
let vertexBuffer = gl.createBuffer();
if(!vertexBuffer) {
console.log('创建缓存失败');
return -1;
}
let aPointsize = gl.getAttribLocation(glProgram, "a_pointsize");
let aColor = gl.getUniformLocation(glProgram, "a_color");
gl.vertexAttrib1f(aPointsize, size);
gl.uniform4f(aColor, ...color);
// 绑定缓冲区对象
// gl.ARRAY_BUFFER 包含顶点属性的Buffer,顶点坐标纹理坐标,顶点颜色数据
// gl.ELEMENT_ARRAT_BUFFER 用于元素索引的Buffer
gl.bindBuffer(gl.ARRAY_BUFFER,vertexBuffer);
// 写入数据
// gl.STATIC_DRAW 缓冲区的内容可能经常使用,不会更改 不读
// gl.DYNAMIC_DRAW 缓冲区内容可能经常使用经常更改
// gl.STREAM_DRAW 缓冲区内容不经常使用
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);
// 获取变量位置
let a_position = gl.getAttribLocation(glProgram, "a_position");
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 0, 0);
// 连接缓冲区对象和a_position变量
gl.enableVertexAttribArray(a_position);
// 画三个点
gl.drawArrays(gl.POINTS, 0, num);
// 画三角形 gl.TRIANGLES 每三个点一个三角形
// gl.drawArrays(gl.TRIANGLES, 0, num);
// gl.drawArrays(gl.Lines, 0, num);
// gl.drawArrays(gl.points, 0, num);
}
initWebgl();
</script>
</html>
01-30
“相关推荐”对你有帮助么?
-
非常没帮助
-
没帮助
-
一般
-
有帮助
-
非常有帮助
提交