持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
上次写了在《webgl中实现三角形》,我们这次修改一下为它加上texture
分析
先分析想为三角形上texture,我们需要做什么
- 请求图片资源,拿到图片的数据
- 修改着色器
- 将图片的坐标与三角形的坐标匹配
- 绑定纹理坐标与绘制
请求图片资源,拿到图片的数据
我们可以创建img标签,赋值上url 通过onLoad判断是否请求完
function initTextures({ gl, n, src }) {
var texture = gl.createTexture();
var u_sampler = gl.getUniformLocation(gl.program, "u_image");
var image = new Image();
image.onload = function () {
loadTexture({ gl, n, texture, u_sampler, image });
};
image.src = src;
return true;
}
修改着色器
我们需要将uv坐标从顶点着色器中提供到片段着色器,所以需要声明两个变量a_textCoord、v_textCoord,直接将a_textCoord赋值给v_textCoord就行了,这样这个会传到片段着色器中,而片段着色器中我们声明纹理,并且从纹理坐标读取到正确的映射
const vertexCode = `
attribute vec4 a_position;
attribute vec2 a_textCoord;
varying vec2 v_textCoord;
void main(){
gl_Position = a_position;
v_textCoord = a_textCoord;
}
`;
const fragmentCode = `
precision mediump float;
varying vec2 v_textCoord;
uniform sampler2D u_image;
void main(){
gl_FragColor = texture2D(u_image, v_textCoord);
}
`;
将图片的坐标与三角形的坐标匹配
texture的坐标是从左上角开始的,Y向下,X向左
const aTextCoordLocation = gl.getAttribLocation(gl.program, "a_textCoord");
gl.vertexAttribPointer(
aTextCoordLocation,
2,
gl.FLOAT,
false,
FSIZE * 4,
FSIZE * 2
);
绑定纹理坐标与如何绘制
先将创建的texture绑定到上下文中,然后声明越界的如何处理,最后绘制即可
function loadTexture({ gl, n, texture, u_sampler, image }) {
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
最后绘制即可。