初探webgl——点的绘制
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<met httpsa name="viewport" content="width=device-width, initial-scale=1.0">
<title>点</title>
</head>
<body>
<canvas width="500" height="500" id='canvas'></canvas>
<script type="GLSL" id="vertex">
attribute vec2 a_position;
uniform vec2 screenSize;
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 = 10.0;
}
</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)
let a_position = gl.getAttribLocation(program, 'a_position')
let screenSize = gl.getUniformLocation(program, 'screenSize')
let a_color = gl.getAttribLocation(program, 'a_color')
gl.uniform2f(screenSize, oCanvas.clientWidth, oCanvas.clientHeight)
gl.clearColor(0, 0, 1, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
function bindEvent() {
oCanvas.onmousedown = function (e) {
let x = e.offsetX;
let y = e.offsetY;
points.push({
x,
y,
color: [Math.random(), Math.random(), Math.random(), 0.5 + Math.random() * 0.4]
})
gl.clearColor(0, 0, 1, 1)
gl.clear(gl.COLOR_BUFFER_BIT)
points.map((i) => {
//向attribute变量赋值
gl.vertexAttrib2f(a_position, i.x, i.y)
gl.vertexAttrib4f(a_color, ...i.color)
gl.drawArrays(gl.POINTS, 0, 1)
})
// gl.vertexAttrib2f(a_position, x, y)
// gl.vertexAttrib4f(a_color, Math.random(), Math.random(), Math.random(), 0.5 + Math.random() * 0.4)
// gl.drawArrays(gl.POINTS, 0, 1) 这是一个异步操作 类似于vue试图更新 当发生多点绘制时 他会等待数据 一起执行绘制
//缓存区 多点绘制
// let f32Arr =[]
// points.map((i)=>{
// f32Arr.push(i.x,i.y,...i.color)
// })
// let pointBuffer = gl.createBuffer()
// gl.bindBuffer(gl.ARRAY_BUFFER, pointBuffer)
// gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(f32Arr), gl.STATIC_DRAW)
// gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false,4*6, 0)
// gl.vertexAttribPointer(a_color,4, gl.FLOAT, false, 4 * 6, 4*2)
// //启动
// gl.enableVertexAttribArray(a_position)
// gl.enableVertexAttribArray(a_color)
// //参数 绘制类型 起始位置 顶点个数
// gl.drawArrays(gl.POINTS, 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>