//顶点着色器--顶点坐标、纹理坐标
var VSHADER_SOURCE =
'attribute vec4 a_Position;\n' +
'attribute vec2 a_TexCoord;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
'gl_Position = a_Position;\n' +
'v_TexCoord = a_TexCoord;\n' +
'}\n';
//片元着色器
var FSHADER_SOURCE =
//精度限定
'#ifdef GL_ES\n' +
'precision mediump float;\n' +
'#endif\n' +
'uniform sampler2D u_Sampler0;\n' +
'uniform sampler2D u_Sampler1;\n' +
'varying vec2 v_TexCoord;\n' +
'void main() {\n' +
'vec4 color0 = texture2D(u_Sampler0, v_TexCoord);\n' +
'vec4 color1 = texture2D(u_Sampler1, v_TexCoord);\n' +
'gl_FragColor = color0 * color1;\n' +
'}\n';
//创建main()函数
function main() {
//获取cancas元素
var canvas = document.getElementById('webgl');
//获取webgl上下文对象
var gl = getWebGLContext(canvas);
if(!gl){
console.log('Failed to get the rendering context for WebGL');
return;
}
//初始化着色器
if(!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)){
return;
}
//设置顶点位置
var n = initVertexBuffers(gl);
if(n < 0){
console.log('Failed to set the position of the vertices');
return;
}
//设置canvas背景颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
//设置纹理
if(!initTextures(gl, n)){
console.log('Failed to intialize the texture.');
return;
}
};
//设置顶点位置
function initVertexBuffers(gl) {
//设置顶点坐标&纹理坐标--类型化数组
var verticesTexCoords = 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,
]);
//顶点的个数
var n = 4;
//创建缓冲区对象
var vertexTexCoordBuffer = gl.createBuffer();
if(!vertexTexCoordBuffer){
console.log('vertexTexCoordBuffer Failed to create the buffer object');
return -1;
}
//绑定缓冲区对象
gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);
//向缓冲区写入数据
gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);
//获取顶点的存储位置
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
if (a_Position < 0) {
console.log('Failed to get the storage location of a_Position');
return -1;
}
//获取类型化数组分量
var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;
//将缓冲区对象分配给a_Position变量
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);
//连接a_Position变量与分配给它的缓冲区对象--开启
gl.enableVertexAttribArray(a_Position);
//获取纹理坐标的存储位置
var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');
//将纹理坐标分配给a_TexCoord
gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);
//连接a_TexCoord变量与分配给它的缓冲区对象--开启
gl.enableVertexAttribArray(a_TexCoord);
return n;
};
//设置纹理
function initTextures(gl, n) {
//创建纹理对象
var texture0 = gl.createTexture();
var texture1 = gl.createTexture();
//获取u_Sampler的存储位置
var u_Sampler0 = gl.getUniformLocation(gl.program, 'u_Sampler0');
var u_Sampler1 = gl.getUniformLocation(gl.program, 'u_Sampler1');
//创建一个image对象
var image0 = new Image();
var image1 = new Image();
//浏览器加载图像url
image0.src = '../WebGL/resources/sky.JPG';
image1.src = '../WebGL/resources/circle.gif';
//注册图像加载事件的响应函数
image0.onload = function() {
loadTexture(gl, n, texture0, u_Sampler0, image0, 0);
};
image1.onload = function() {
loadTexture(gl, n, texture1, u_Sampler1, image1, 1);
};
return true;
};
//标记纹理单元是否已经就绪
var g_texUnit0 = false, g_texUnit1 = false;
//注册图像加载事件的响应函数
function loadTexture(gl, n, texture, u_Sampler, image, texUnit) {
//将图像进行Y轴反转
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1);
//激活纹理单元
if(texUnit == 0) {
gl.activeTexture(gl.TEXTURE0);
g_texUnit0 = true;
} else {
gl.activeTexture(gl.TEXTURE1);
g_texUnit1 = true;
}
//绑定纹理对象
gl.bindTexture(gl.TEXTURE_2D, texture);
//配置纹理参数
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
//配置纹理图像
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
//将0号纹理传递给着色器
gl.uniform1i(u_Sampler, texUnit);
//清空canvas
gl.clear(gl.COLOR_BUFFER_BIT);
//绘制矩形
if(g_texUnit0 && g_texUnit1) {
gl.drawArrays(gl.TRIANGLE_STRIP, 0, n);
}
};