<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>WebGL 绘制点</title> <script type="x-shader/x-vertex" id="vertexShader"> //设置浮点数精度为中等精度 precision mediump float; // 接收点在canvas坐标系上的坐标(x,y) attribute vec2 a_Position; // 接受canvas 的宽高尺寸 attribute vec2 a_Screen_Size; void main(){ //start 将屏幕坐标系转化为裁剪坐标(裁剪坐标系) vec2 position = (a_Position / a_Screen_Size) * 2.0 - 1.0; position = position * vec2(1.0, -1.0); gl_Position = vec4(position, 0.0, 1.0); //end 将屏幕坐标系转化为裁剪坐标(裁剪坐标系) //声明要绘制的点的大小。 gl_PointSize = 10.0; } </script> <script type="x-shader/x-fragment" id="fragmentShader"> //设置浮点数精度为中等精度 precision mediump float; //接收 JavaScript 传过来的颜色值(RGBA)。 uniform vec4 u_Color; void main(){ //将普通的颜色表示转化为 WebGL 需要的表示方式,即将【0-255】转化到【0,1】之间。 vec4 color = u_Color / vec4(255, 255, 255, 1); gl_FragColor = color; } </script> </head> <body> <canvas id="canvas"></canvas> </body> </html> <script> function createShaderFromScript(gl, mode, id) { // 获取着色器源码 var shaderSource = document.getElementById(id).innerHTML; // 创建着色器对象 var shader = gl.createShader(mode); // 将源码分配给着色器对象 gl.shaderSource(shader,shaderSource); // 编译着色器 gl.compileShader(shader);
return shader; } function createProgram(gl, vertexShader, fragmentShader) { var program = gl.createProgram(); // 将顶点着色器挂载在着色器程序上。 gl.attachShader(program, vertexShader); //将片元着色器挂载在着色器程序上。 gl.attachShader(program, fragmentShader); //链接着色器程序 gl.linkProgram(program);
return program; }
var canvas = document.getElementById(‘canvas‘); var gl = canvas.getContext(‘webgl‘) || canvas.getContext("experimental-webgl");
<!--region 创建着色器对象--> var vertexShader = createShaderFromScript(gl, gl.VERTEX_SHADER, ‘vertexShader‘); var fragmentShader = createShaderFromScript(gl, gl.FRAGMENT_SHADER, ‘fragmentShader‘) <!--endregion-->
<!--region 创建着色器程序--> //创建着色器程序 let program = createProgram(gl, vertexShader, fragmentShader);
// 使用刚刚创建好的着色器程序 gl.useProgram(program); <!--endregion-->
//找到顶点着色器中的变量a_Position var a_Position = gl.getAttribLocation(program, ‘a_Position‘); //找到顶点着色器中的变量a_Screen_Size var a_Screen_Size = gl.getAttribLocation(program, ‘a_Screen_Size‘); //找到片元着色器中的变量u_Color var u_Color = gl.getUniformLocation(program, ‘u_Color‘); //为顶点着色器中的 a_Screen_Size 传递 canvas 的宽高信息 gl.vertexAttrib2f(a_Screen_Size, canvas.width, canvas.height); //存储点击位置的数组。 var points = []; function randomColor(){ return { r: Math.ceil(Math.random() * 255), g: Math.ceil(Math.random() * 255), b: Math.ceil(Math.random() * 255), a: Math.ceil(Math.random()), }; } canvas.addEventListener(‘click‘,e=>{ var x = e.pageX; var y = e.pageY;
var color = randomColor();
points.push({x,y,color}); gl.clearColor(0, 0, 0, 1.0); //用上一步设置的清空画布颜色清空画布。 gl.clear(gl.COLOR_BUFFER_BIT);
for (let i = 0; i < points.length; i++) { let color = points[i].color; gl.uniform4f(u_Color, color.r, color.g, color.b, color.a); //为顶点着色器中的 a_Position 传递顶点坐标。 gl.vertexAttrib2f(a_Position, points[i].x, points[i].y);
// 绘制点 gl.drawArrays(gl.POINTS, 0, 1); } })
//设置清空画布颜色为黑色。 gl.clearColor(0.0,0.0,0.0,1.0); //用上一步设置的清空画布颜色清空画布。 gl.clear(gl.COLOR_BUFFER_BIT);
</script>
|