1、开发环境
- 浏览器 : 火狐 firefox(配置参考博客)
- 编程语言:webgl
- 编程软件:webstorm
在上一篇 博客上修改完善
2、内容说明
模拟太阳系运动;有光照和纹理
1、计算球体的坐标和纹理
球体坐标值的计算公式
x = rcos(θ) cos(φ)
y = rcos(θ) sin(φ)
z = rsin(θ)
var latitudeBands = 50;//纬度带
var longitudeBands = 50;//经度带
var positions = [];//存储x,y,z坐标
var indices = [];//三角形列表(索引值)
for(var latNum = 0; latNum <= latitudeBands; latNum++){
//纬度范围从-π/2到π/2
var lat = latNum * Math.PI / (latitudeBands) - Math.PI / 2;
var sinLat = Math.sin(lat);
var cosLat = Math.cos(lat);
for(var longNum = 0; longNum <= longitudeBands; longNum++){
//经度范围从-π到π
var lon = longNum * 2 * Math.PI / (longitudeBands) - Math.PI;
var sinLon = Math.sin(lon);
var cosLon = Math.cos(lon);
var x = cosLat * cosLon;
var y = cosLat * sinLon;
var z = sinLat;
var u = (longNum / (longitudeBands));
var v = (latNum / (latitudeBands));
positions.push(x);//坐标x
positions.push(y);//坐标y
positions.push(z);//坐标z
positions.push(u);//纹理u
positions.push(v);//纹理v
}
}
2、求顶点索引
把坐标点排序,求出顶点索引列表,将每个四边形分成一对三角形,缝合成一个球体
//生成一个顶点索引列表,将每个四边形分成一对三角形
for(var latNum = 0; latNum < latitudeBands; latNum++){
for(var longNum = 0; longNum < longitudeBands; longNum++)
{
var first = latNum * (longitudeBands + 1) + longNum;
var second = first + longitudeBands + 1;
//第一个三角形的3个点索引
indices.push(first);
indices.push(first + 1);
indices.push(second);
//第二个三角形的3个点索引
indices.push(second);
indices.push(second + 1);
indices.push(first + 1);
}
}
3、数据加载到缓存中
把生成的顶点和索引数据绑定到对应的缓存中,给着色器提供数据
var vertices = new Float32Array(positions);//顶点坐标数据和纹理坐标
var indices = new Uint16Array(indices);//顶点索引数据
// 创建顶点缓冲
this.shpereVAO = gl.createBuffer();
// 绑定顶点缓冲
gl.bindBuffer(gl.ARRAY_BUFFER, this.shpereVAO);
// 提交顶点数据
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
///创建顶点索引
this.shpereVEO = gl.createBuffer();
// 绑定顶点索引
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.shpereVEO);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
4、绘制球体
使用刚才的缓存中的数据,调用绘制命令进行绘制
gl.bindBuffer(gl.ARRAY_BUFFER, this.shpereVAO);//绑定顶点缓存
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.shpereVEO);//绑定索引缓冲
gl.drawElements(gl.TRIANGLES,50*50*6,gl.UNSIGNED_SHORT,0);//绘制命令
5、其他
纹理和光照就不在叙述