<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<met httpsa name="viewport" content="width=device-width, initial-scale=1.0">
<title>webgl线</title>
</head>
<body>
<canvas width="500" height="500" id='canvas'></canvas>
<script type="GLSL" id="vertex">
attribute vec2 a_position;
uniform vec2 screenSize;
attribute float pointsize;
attribute vec4 a_color;
varying vec4 v_color;
void main() {
v_color = a_color;
float x = a_position.x*2.0/screenSize.x -1.0;
float y = 1.0 - a_position.y*2.0/screenSize.y;
gl_Position = vec4(x,y,0,1);
gl_PointSize = pointsize;
}
</script>
<script type="GLSL" id="fragment">
precision mediump float;
varying vec4 v_color;
void main() {
gl_FragColor = v_color;
}
</script>
<script>
let oCanvas = document.getElementById('canvas')
let gl = oCanvas.getContext('webgl')
let points = []
if (!gl) {
alert('浏览器版本不支持!请升级版本过着使用谷歌浏览器')
}
let vertexStr = document.getElementById('vertex').innerText
let fragmentStr = document.getElementById('fragment').innerText
let vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexStr)
let fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentStr)
let program = createProgam(gl, vertexShader, fragmentShader)
gl.useProgram(program)
gl.clearColor(0, 0, 1, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
let a_position = gl.getAttribLocation(program, 'a_position')
let pointsize = gl.getAttribLocation(program, 'pointsize')
let screenSize = gl.getUniformLocation(program, 'screenSize')
let a_color = gl.getAttribLocation(program, 'a_color')
gl.uniform2f(screenSize, oCanvas.clientWidth, oCanvas.clientHeight)
function bindEvent() {
oCanvas.onmousedown = function (e) {
let x = e.offsetX;
let y = e.offsetY;
points.push({
x,
y,
size: 10.0
})
if (points.length ) {
gl.vertexAttrib4f(a_color, 0.2, 0.3, 0.4, 0.7)
//创建缓冲区对象
let positionBuffer = gl.createBuffer()
//将其绑定到target(顶点的数据、顶点的索引值)表示的目标上
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer)
//缓存区写入数据
let f32Arr =[]
for (let index = 0; index < points.length; index++) {
f32Arr.push(...[points[index].x,points[index].y,points[index].size])
}
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f32Arr), gl.STATIC_DRAW)
//向缓冲区对象传送数据 第四个参数针对非浮点类型
//相邻两个顶点之间的字节数
gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 4 * 3, 0)
gl.vertexAttribPointer(pointsize, 1, gl.FLOAT, false, 4 * 3, 4 * 2)
//启动
gl.enableVertexAttribArray(a_position)
gl.enableVertexAttribArray(pointsize)
gl.clearColor(0, 0, 1, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
//参数 绘制类型 起始位置 顶点个数
//LINE_STRIP 连线 LINES 线段 LINE_LOOP 回路
gl.drawArrays(gl.LINE_STRIP, 0, points.length)
}
}
}
bindEvent()
function createProgam(gl, vertexShader, fragmentShader) {
let program = gl.createProgram()
console.log(vertexShader, fragmentShader, 'sss');
gl.attachShader(program, vertexShader)
gl.attachShader(program, fragmentShader)
gl.linkProgram(program)
let success = gl.getProgramParameter(program, gl.LINK_STATUS)
if (success) {
return program
} else {
console.log(gl.getProgramInfo(program), '着色器链接失败');
}
}
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), '着色器执行报错');
}
}
</script>
</body>
</html>