WebGL简易教程:纹理
Posted aa1212
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WebGL简易教程:纹理相关的知识,希望对你有一定的参考价值。
基于《WebGL简易教程(九):综合实例:地形的绘制》中的JS代码进行改进:
// 顶点着色器程序507383170
var VSHADER_SOURCE =
‘attribute vec4 a_Position;
‘ + //位置
‘attribute vec4 a_Color;
‘ + //颜色
‘uniform mat4 u_MvpMatrix;
‘ +
‘varying vec4 v_Color;
‘ +
‘varying vec4 v_position;
‘ +
‘void main() {
‘ +
‘ v_position = a_Position;
‘ +
‘ gl_Position = u_MvpMatrix * a_Position;
‘ + // 设置顶点坐标
‘ v_Color = a_Color;
‘ +
‘}
‘;
// 片元着色器程序
var FSHADER_SOURCE =
‘precision mediump float;
‘ +
‘uniform vec2 u_RangeX;
‘ + //X方向范围
‘uniform vec2 u_RangeY;
‘ + //Y方向范围
‘uniform sampler2D u_Sampler;
‘ +
‘varying vec4 v_Color;
‘ +
‘varying vec4 v_position;
‘ +
‘void main() {
‘ +
‘ vec2 v_TexCoord = vec2((v_position.x-u_RangeX[0]) / (u_RangeX[1]-u_RangeX[0]), 1.0-(v_position.y-u_RangeY[0]) / (u_RangeY[1]-u_RangeY[0]));
‘ +
‘ gl_FragColor = texture2D(u_Sampler, v_TexCoord);
‘ +
‘}
‘;
//定义一个矩形体:混合构造函数原型模式
function Cuboid(minX, maxX, minY, maxY, minZ, maxZ) {
this.minX = minX;
this.maxX = maxX;
this.minY = minY;
this.maxY = maxY;
this.minZ = minZ;
this.maxZ = maxZ;
}
Cuboid.prototype = {
constructor: Cuboid,
CenterX: function () {
return (this.minX + this.maxX) / 2.0;
},
CenterY: function () {
return (this.minY + this.maxY) / 2.0;
},
CenterZ: function () {
return (this.minZ + this.maxZ) / 2.0;
},
LengthX: function () {
return (this.maxX - this.minX);
},
LengthY: function () {
return (this.maxY - this.minY);
}
}
//定义DEM
function Terrain() { }
Terrain.prototype = {
constructor: Terrain,
setWH: function (col, row) {
this.col = col;
this.row = row;
}
}
var currentAngle = [0.0, 0.0]; // 绕X轴Y轴的旋转角度 ([x-axis, y-axis])
var curScale = 1.0; //当前的缩放比例
var initTexSuccess = false; //纹理图像是否加载完成
function main() {
var demFile = document.getElementById(‘demFile‘);
if (!demFile) {
console.log("Failed to get demFile element!");
return;
}
//加载文件后的事件
demFile.addEventListener("change", function (event) {
//判断浏览器是否支持FileReader接口
if (typeof FileReader == ‘undefined‘) {
console.log("你的浏览器不支持FileReader接口!");
return;
}
//读取文件后的事件
var reader = new FileReader();
reader.onload = function () {
if (reader.result) {
var terrain = new Terrain();
if (!readDEMFile(reader.result, terrain)) {
console.log("文件格式有误,不能读取该文件!");
}
//绘制函数
onDraw(gl, canvas, terrain);
}
}
var input = event.target;
reader.readAsText(input.files[0]);
});
// 获取 <canvas> 元素
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)) {
console.log(‘Failed to intialize shaders.‘);
return;
}
// 指定清空<canvas>的颜色
gl.clearColor(0.0, 0.0, 0.0, 1.0);
// 开启深度测试
gl.enable(gl.DEPTH_TEST);
//清空颜色和深度缓冲区
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
}
//绘制函数
function onDraw(gl, canvas, terrain) {
// 设置顶点位置
//var cuboid = new Cuboid(399589.072, 400469.072, 3995118.062, 3997558.062, 732, 1268);
var n = initVertexBuffers(gl, terrain);
if (n < 0) {
console.log(‘Failed to set the positions of the vertices‘);
return;
}
//设置纹理
if (!initTextures(gl, terrain)) {
console.log(‘Failed to intialize the texture.‘);
return;
}
//注册鼠标事件
initEventHandlers(canvas);
//绘制函数
var tick = function () {
if (initTexSuccess) {
//设置MVP矩阵
setMVPMatrix(gl, canvas, terrain.cuboid);
//清空颜色和深度缓冲区
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
//绘制矩形体
gl.drawElements(gl.TRIANGLES, n, gl.UNSIGNED_SHORT, 0);
//gl.drawArrays(gl.Points, 0, n);
}
//请求浏览器调用tick
requestAnimationFrame(tick);
};
//开始绘制
tick();
}
function initTextures(gl, terrain) {
// 传递X方向和Y方向上的范围到着色器
var u_RangeX = gl.getUniformLocation(gl.program, ‘u_RangeX‘);
var u_RangeY = gl.getUniformLocation(gl.program, ‘u_RangeY‘);
if (!u_RangeX || !u_RangeY) {
console.log(‘Failed to get the storage location of u_RangeX or u_RangeY‘);
return;
}
gl.uniform2f(u_RangeX, terrain.cuboid.minX, terrain.cuboid.maxX);
gl.uniform2f(u_RangeY, terrain.cuboid.minY, terrain.cuboid.maxY);
//创建一个image对象
var image = new Image();
if (!image) {
console.log(‘Failed to create the image object‘);
return false;
}
//图像加载的响应函数
image.onload = function () {
if (loadTexture(gl, image)) {
initTexSuccess = true;
}
};
//浏览器开始加载图像
image.src = ‘tex.jpg‘;
return true;
}
function loadTexture(gl, image) {
// 创建纹理对象
var texture = gl.createTexture();
if (!texture) {
console.log(‘Failed to create the texture object‘);
return false;
}
// 开启0号纹理单元
gl.activeTexture(gl.TEXTURE0);
// 绑定纹理对象
gl.bindTexture(gl.TEXTURE_2D, texture);
// 设置纹理参数
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_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.CLAMP_TO_EDGE);
// 配置纹理图像
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);
// 将0号单元纹理传递给着色器中的取样器变量
var u_Sampler = gl.getUniformLocation(gl.program, ‘u_Sampler‘);
if (!u_Sampler) {
console.log(‘Failed to get the storage location of u_Sampler‘);
return false;
}
gl.uniform1i(u_Sampler,