我会持续更新关于wegl的编程指南中的代码。
当前的代码不会使用书中的缩写,每一步都是会展开写。希望能给后来学习的一些帮助
git代码地址 :空
上一章节中我们学习texParameteri的使用,这一章节中我们两个图片进行混合
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport">
<title>Document</title>
<style>
#canvas {
width: 100vw;
height: 100vw;
border: 1px solid greenyellow;
}
</style>
</head>
<body>
!!!!!需要指出的是要选择当前文件夹下的sky.jpg!!!!!!
<!-- <input type="file" accept="image/*" onchange="loadFile(event)"> -->
<input type="file" onchange="loadFile(event)">
<canvas id="canvas"></canvas>
<script>
let imgSrc = 'https://p2.music.126.net/UrFqYFILx5wBDx-dsIz15A==/109951163025047288.jpg?param=256y256';
let jpgImgSrc = 'https://p1.music.126.net/LOTxqRjFm03VJEOHJbUqMw==/109951165944804127.jpg?param=256y256';
// let jpgImgSrc = 'https://img-blog.csdnimg.cn/361654c6611d49bebab085509bd6a244.jpeg';
// let gifImagSrc = 'https://img-blog.csdnimg.cn/04f072cdb3934051a505a54a4d6f46ed.gif';
let vexterSource = `
precision mediump float;
attribute vec4 a_Position;
attribute vec2 a_TexCoord;
varying vec2 v_TexCoord;
void main(){
gl_Position = a_Position;//顶点坐标
v_TexCoord = a_TexCoord;//纹理坐标系下的坐标
}
`
let fragmentSource = `
precision mediump float;
uniform sampler2D u_Sampler0;//纹理
uniform sampler2D u_Sampler1;//纹理
varying vec2 v_TexCoord;//纹理坐标系下的坐标
void main(){
vec4 color0 = texture2D(u_Sampler0,v_TexCoord);
vec4 color1 = texture2D(u_Sampler1,v_TexCoord);
gl_FragColor = color0 * color1;
}
`
let canvas = document.getElementById('canvas');
let gl = canvas.getContext('webgl');
//创建顶点着色器
let vertextShader = gl.createShader(gl.VERTEX_SHADER);
//给顶点着色器赋值
gl.shaderSource(vertextShader, vexterSource);
//编译顶点着色器
gl.compileShader(vertextShader);
//创建片元着色器
let fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
//给片元着色器赋值
gl.shaderSource(fragmentShader, fragmentSource)
//编译片元着色器
gl.compileShader(fragmentShader)
//检测着色器创建是否正确
if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(fragmentShader));
}
//创建程序
let program = gl.createProgram();
//给程序赋值
gl.attachShader(program, vertextShader);
gl.attachShader(program, fragmentShader);
//连接程序
gl.linkProgram(program);
//使用此着色器
gl.useProgram(program);
//变量的处理
//获取顶点着色器中的变量a_Position
let a_Position = gl.getAttribLocation(program, 'a_Position');
//获取顶点着色器中的变量a_TexCoord
let a_TexCoord = gl.getAttribLocation(program, 'a_TexCoord');
//获取片元着色器中的变量u_Sampler
let u_Sampler0 = gl.getUniformLocation(program, 'u_Sampler0');
//获取片元着色器中的变量u_Sampler
let u_Sampler1 = gl.getUniformLocation(program, 'u_Sampler1');
//顶点坐标与纹理坐标
let vertexTexCoords = new Float32Array([
-0.5, 0.5, 0.0, 1.0,
-0.5, -0.5, 0.0, 0.0,
0.5, 0.5, 1.0, 1.0,
0.5, -0.5, 1.0, 0.0,
])
let f32Seize = vertexTexCoords.BYTES_PER_ELEMENT;
//给定点设置坐标 几何图形与纹理的坐标
let vertexBuffer = gl.createBuffer();
//绑定buffer
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
//绑定数据
gl.bufferData(gl.ARRAY_BUFFER, vertexTexCoords, gl.STATIC_DRAW);
//给a_Position赋值
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, f32Seize * 4, 0);
//使用此变量
gl.enableVertexAttribArray(a_Position);
//纹理坐标
let texCoordBuffer = gl.createBuffer();
//绑定buffer
gl.bindBuffer(gl.ARRAY_BUFFER, texCoordBuffer);
//绑定数据
gl.bufferData(gl.ARRAY_BUFFER, vertexTexCoords, gl.STATIC_DRAW);
//给a_TexCoord赋值
gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, f32Seize * 4, f32Seize * 2);
//使用此变量
gl.enableVertexAttribArray(a_TexCoord);
gl.clearColor(0, 0, 0, 1.0);
//获取图片的素材
getImage(imgSrc, u_Sampler1, gl.TEXTURE0, 0);
getImage(jpgImgSrc, u_Sampler1, gl.TEXTURE1, 1);
function getImage(imgYrl, u_Sampler, TEXTURE, num) {
// 文件里的文本会在这里被打印出来
let img = new Image();
img.src = imgYrl;
img.crossOrigin = ""
img.onload = () => {
let texture = gl.createTexture();
showImage(texture, img, u_Sampler, TEXTURE, num)
document.body.appendChild(img)
}
}
function showImage(texture, img, u_Sampler, TEXTURE, texUnit) {
console.log(texture, img, u_Sampler, TEXTURE, texUnit)
document.body.appendChild(img)
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
//开始0号纹理通道
gl.activeTexture(TEXTURE);
//想目标绑定纹理对象
gl.bindTexture(gl.TEXTURE_2D, texture);
//配置纹理的参数
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.MIRRORED_REPEAT);
//设置着色器参数
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, img);
//设置纹理数据
gl.uniform1i(u_Sampler, texUnit)
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)
}
</script>
</body>
</html>