mapbox-gl:自定義webgl圖層(1)
在mapbox-gl的開(kāi)發(fā)中,除了默認(rèn)的地圖動(dòng)態(tài)效果,可以通過(guò)兩種方式增加地圖中的顯示效果,一是修改mapboxg-gl的源代碼,另外就是通過(guò)加載自定義圖層(CustomLayer)的方式,CustomLayer上可以以webgl的方式實(shí)現(xiàn),也能夠以html5 canvas形式去實(shí)現(xiàn)。
下邊簡(jiǎn)單的以代碼形式展示地圖上的--動(dòng)態(tài)閃光圓環(huán)效果:
//定義著色器代碼
const vertexSource =
`uniform mat4 u_matrix;
? ? ? ? ? ? attribute vec4 a_position;
? ? ? ? ? ? ?void main() {
? ? ? ? ? ? ? ?gl_Position = u_matrix * a_position;
? ? ? ? ? ? ? ?gl_PointSize = 64.0;
? ? ? ? ? ? ? }`;
? ?//定義片段著色器代碼
const frameSource = `precision mediump float;? ?
?uniform float time;
?void main(){
? ? ?vec2 p = gl_PointCoord.xy - vec2(0.5, 0.5);
? ? ?float l = 0.1 / abs(length(p) - 0.4); ? ??
?if(length(p) > 0.427||length(p)<0.350)
?{
?vec4(0.0);
?}else
? ? ?? ?{?
?gl_FragColor = vec4(1.0,0.0,0.0, time);
? ? ? ? }
? ? ?}`;
//定義時(shí)間變換變量
var utime = 1.0;
//定義mapbox-gl的自定義圖層
var customLayer = {
id: 'mycustomlayer',
type: 'custom',
renderingMode: '3d',
//添加方法
onAdd: function(map, gl) {
//webgl的基礎(chǔ)編譯代碼,文章最后會(huì)分享webgl的基礎(chǔ)學(xué)習(xí)網(wǎng)站,可以參見(jiàn)
const fragmentSource = frameSource ;
const vertexShader = gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(vertexShader, vertexSource);
gl.compileShader(vertexShader);
const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
gl.shaderSource(fragmentShader, fragmentSource);
gl.compileShader(fragmentShader);
this.program = gl.createProgram();
gl.attachShader(this.program, vertexShader);
gl.attachShader(this.program, fragmentShader);
gl.linkProgram(this.program);
//傳遞位置信息
var positionLocation = gl.getAttribLocation(this.program, "a_position");
//傳遞事件變化參數(shù)
this.aTime = gl.getUniformLocation(this.program, "time");
var positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.enableVertexAttribArray(positionLocation);
setData(gl);
var size = 3;
var type = gl.FLOAT;
var normalize = false;
var stride = 0;
var offset = 0;
gl.vertexAttribPointer(positionLocation, size, type, normalize, stride, offset);
},
//渲染方法
render: function(gl, matrix) {
gl.useProgram(this.program);
gl.uniformMatrix4fv(gl.getUniformLocation(this.program, "u_matrix"), false, matrix);
gl.uniform1f(this.aTime, utime);
var duration = 1000;
utime = (performance.now() % duration) / duration;
gl.drawArrays(gl.POINTS, 0, 2);
//實(shí)現(xiàn)實(shí)時(shí)渲染
map.triggerRepaint();
return true; }
};
//添加測(cè)試圓環(huán)數(shù)據(jù)
function setData(gl) {
//以墨卡托的形式添加坐標(biāo)數(shù)據(jù)
var singlepoint = mapboxgl.MercatorCoordinate.fromLngLat([117.0, 36.0], 20);
var singlepoint1 = mapboxgl.MercatorCoordinate.fromLngLat([117.06, 36.01], 20);
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array([
singlepoint.x, singlepoint.y, singlepoint.z,
singlepoint1.x, singlepoint1.y, singlepoint1.z
]),
gl.STATIC_DRAW);
}
實(shí)現(xiàn)效果圖:
