mirror of https://gitee.com/antv-l7/antv-l7
feat: 清理渲染流程代码
This commit is contained in:
parent
f519a6dce0
commit
8adec0eccd
|
@ -40,6 +40,7 @@ export default () => {
|
|||
|
||||
scene.on('loaded', () => {
|
||||
scene.addLayer(pointLayer);
|
||||
// scene.render();
|
||||
})
|
||||
}, [])
|
||||
return (
|
||||
|
|
|
@ -66,9 +66,7 @@ export default class CoordinateSystemService
|
|||
* TODO: 使用 memoize 缓存参数以及计算结果
|
||||
*/
|
||||
public refresh(offsetCenter?: [number, number]): void {
|
||||
// if (!this.needRefresh) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
const zoom = this.cameraService.getZoom();
|
||||
const zoomScale = this.cameraService.getZoomScale();
|
||||
const center = offsetCenter ? offsetCenter : this.cameraService.getCenter();
|
||||
|
|
|
@ -303,12 +303,7 @@ export default class PickingService implements IPickingService {
|
|||
}
|
||||
}
|
||||
private async pickingAllLayer(target: IInteractionTarget) {
|
||||
// 判断是否进行拾取操作
|
||||
if (!this.layerService.needPick(target.type) ||!this.isPickingAllLayer()) return;
|
||||
this.alreadyInPicking = true;
|
||||
await this.pickingLayers(target);
|
||||
this.layerService.renderLayers();
|
||||
this.alreadyInPicking = false;
|
||||
|
||||
}
|
||||
|
||||
private isPickingAllLayer() {
|
||||
|
|
|
@ -40,12 +40,11 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
private readonly mapService: IMapService;
|
||||
|
||||
public reRender = throttle(() => {
|
||||
this.updateLayerRenderList();
|
||||
this.renderLayers();
|
||||
|
||||
}, 32);
|
||||
|
||||
public throttleRenderLayers = throttle(() => {
|
||||
this.renderLayers();
|
||||
|
||||
}, 16);
|
||||
|
||||
public needPick(type:string): boolean {
|
||||
|
@ -64,11 +63,7 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
}
|
||||
|
||||
public addMask(mask: ILayer) {
|
||||
if (this.sceneInited) {
|
||||
mask.init().then(() => {
|
||||
this.renderLayers();
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public async initLayers() {
|
||||
|
@ -103,97 +98,39 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
}
|
||||
|
||||
public remove(layer: ILayer, parentLayer?: ILayer): void {
|
||||
// Tip: layer.layerChildren 当 layer 存在子图层的情况
|
||||
if (parentLayer) {
|
||||
const layerIndex = parentLayer.layerChildren.indexOf(layer);
|
||||
if (layerIndex > -1) {
|
||||
parentLayer.layerChildren.splice(layerIndex, 1);
|
||||
}
|
||||
} else {
|
||||
const layerIndex = this.layers.indexOf(layer);
|
||||
if (layerIndex > -1) {
|
||||
this.layers.splice(layerIndex, 1);
|
||||
}
|
||||
}
|
||||
this.updateLayerRenderList();
|
||||
layer.destroy();
|
||||
this.renderLayers();
|
||||
this.emit('layerChange', this.layers);
|
||||
|
||||
}
|
||||
|
||||
public removeAllLayers() {
|
||||
this.destroy();
|
||||
this.renderLayers();
|
||||
|
||||
}
|
||||
|
||||
public setEnableRender(flag: boolean) {
|
||||
this.enableRender = flag;
|
||||
}
|
||||
|
||||
public async renderLayers() {
|
||||
if (this.alreadyInRendering || !this.enableRender) {
|
||||
return;
|
||||
}
|
||||
this.alreadyInRendering = true;
|
||||
public renderLayers() {
|
||||
console.log('renderLayers');
|
||||
|
||||
this.clear();
|
||||
for (const layer of this.layerList) {
|
||||
if (layer.masks.filter((m)=>m.inited).length > 0) {
|
||||
// 清除上一次的模版缓存
|
||||
this.renderService.clear({
|
||||
stencil: 0,
|
||||
depth: 1,
|
||||
framebuffer: null,
|
||||
});
|
||||
layer.masks.map(async (m: ILayer) => {
|
||||
m.render();
|
||||
})
|
||||
}
|
||||
|
||||
if (layer.getLayerConfig().enableMultiPassRenderer) {
|
||||
// multiPassRender 不是同步渲染完成的
|
||||
await layer.renderMultiPass();
|
||||
} else {
|
||||
await layer.render();
|
||||
|
||||
}
|
||||
|
||||
layer.render();
|
||||
}
|
||||
this.alreadyInRendering = false;
|
||||
}
|
||||
|
||||
public renderMask(masks:ILayer[]) {
|
||||
masks.filter(m => m.inited)
|
||||
.map(m =>{
|
||||
m.render();
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
public async beforeRenderData(layer: ILayer) {
|
||||
const flag = await layer.hooks.beforeRenderData.promise();
|
||||
if(flag) {
|
||||
this.renderLayers();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
async renderLayer(layer: ILayer){
|
||||
|
||||
if (layer.masks.filter((m)=>m.inited).length > 0) {
|
||||
layer.masks.map(mask =>{
|
||||
this.renderService.clear({
|
||||
stencil: 0,
|
||||
depth: 1,
|
||||
framebuffer: null,
|
||||
});
|
||||
mask.render();
|
||||
})
|
||||
|
||||
}
|
||||
if (layer.getLayerConfig().enableMultiPassRenderer) {
|
||||
// multiPassRender 不是同步渲染完成的
|
||||
await layer.renderMultiPass();
|
||||
} else {
|
||||
await layer.render();
|
||||
}
|
||||
|
||||
layer.render();
|
||||
|
||||
}
|
||||
|
||||
|
@ -270,10 +207,6 @@ export default class LayerService extends EventEmitter<LayerServiceEvent>
|
|||
}
|
||||
|
||||
private runRender() {
|
||||
this.renderLayers();
|
||||
this.layerRenderID = $window.requestAnimationFrame(
|
||||
this.runRender.bind(this),
|
||||
);
|
||||
}
|
||||
|
||||
private stopRender() {
|
||||
|
|
|
@ -245,14 +245,14 @@ export default class PixelPickingPass<
|
|||
// @ts-ignore
|
||||
const [r, g, b] = pickedColors;
|
||||
this.layer.hooks.beforeHighlight.call([r, g, b]);
|
||||
this.layerService.renderLayers();
|
||||
|
||||
}
|
||||
|
||||
private selectFeature(pickedColors: Uint8Array | undefined) {
|
||||
// @ts-ignore
|
||||
const [r, g, b] = pickedColors;
|
||||
this.layer.hooks.beforeSelect.call([r, g, b]);
|
||||
this.layerService.renderLayers();
|
||||
|
||||
}
|
||||
|
||||
private selectFeatureHandle({ featureId }: Partial<IInteractionTarget>) {
|
||||
|
|
|
@ -295,10 +295,7 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
}
|
||||
|
||||
public async render() {
|
||||
if (this.rendering || this.destroyed) {
|
||||
return;
|
||||
}
|
||||
this.rendering = true;
|
||||
|
||||
// 首次初始化,或者地图的容器被强制销毁的需要重新初始化
|
||||
if (!this.inited) {
|
||||
// 还未初始化完成需要等待
|
||||
|
@ -309,20 +306,18 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
}
|
||||
// FIXME: 初始化 marker 容器,可以放到 map 初始化方法中?
|
||||
await this.layerService.initLayers();
|
||||
|
||||
|
||||
|
||||
this.layerService.renderLayers();
|
||||
this.controlService.addControls();
|
||||
this.loaded = true;
|
||||
this.emit('loaded');
|
||||
this.inited = true;
|
||||
} else {
|
||||
// 尝试初始化未初始化的图层
|
||||
await this.layerService.initLayers();
|
||||
await this.layerService.renderLayers();
|
||||
|
||||
this.layerService.renderLayers();
|
||||
}
|
||||
|
||||
// 组件需要等待layer 初始化完成之后添加
|
||||
this.rendering = false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -460,6 +455,7 @@ export default class Scene extends EventEmitter implements ISceneService {
|
|||
canvas.style.height = '100%';
|
||||
}
|
||||
|
||||
// map move -> render
|
||||
private handleMapCameraChanged = (viewport: IViewport) => {
|
||||
this.cameraService.update(viewport);
|
||||
this.render();
|
||||
|
|
|
@ -51,10 +51,12 @@ import {
|
|||
StyleAttributeField,
|
||||
StyleAttributeOption,
|
||||
Triangulation,
|
||||
CameraUniform,
|
||||
CoordinateUniform,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import Source from '@antv/l7-source';
|
||||
import { encodePickingColor, WorkerSourceMap } from '@antv/l7-utils';
|
||||
import { encodePickingColor } from '@antv/l7-utils';
|
||||
import { EventEmitter } from 'eventemitter3';
|
||||
import { Container } from 'inversify';
|
||||
import { isFunction, isObject, isUndefined } from 'lodash';
|
||||
|
@ -173,6 +175,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
|
||||
protected coordinateService: ICoordinateSystemService;
|
||||
|
||||
protected coordinateSystemService: ICoordinateSystemService;
|
||||
|
||||
protected iconService: IIconService;
|
||||
|
||||
protected fontService: IFontService;
|
||||
|
@ -340,13 +344,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
TYPES.IPickingService,
|
||||
);
|
||||
this.mapService = this.container.get<IMapService>(TYPES.IMapService);
|
||||
const { enableMultiPassRenderer, passes } = this.getLayerConfig();
|
||||
if (enableMultiPassRenderer && passes?.length && passes.length > 0) {
|
||||
// Tip: 兼容 multiPassRender 在 amap1 时存在的图层不同步问题 zoom
|
||||
this.mapService.on('mapAfterFrameChange', () => {
|
||||
this.renderLayers();
|
||||
});
|
||||
}
|
||||
const { enableMultiPassRenderer } = this.getLayerConfig();
|
||||
|
||||
|
||||
this.cameraService = this.container.get<ICameraService>(
|
||||
TYPES.ICameraService,
|
||||
|
@ -354,6 +353,11 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
this.coordinateService = this.container.get<ICoordinateSystemService>(
|
||||
TYPES.ICoordinateSystemService,
|
||||
);
|
||||
|
||||
this.coordinateSystemService = this.container.get<ICoordinateSystemService>(
|
||||
TYPES.ICoordinateSystemService,
|
||||
);
|
||||
|
||||
this.shaderModuleService = this.container.get<IShaderModuleService>(
|
||||
TYPES.IShaderModuleService,
|
||||
);
|
||||
|
@ -675,28 +679,53 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
* 渲染所有的图层
|
||||
*/
|
||||
public renderLayers(): void {
|
||||
this.rendering = true;
|
||||
this.layerService.renderLayers();
|
||||
|
||||
this.rendering = false;
|
||||
|
||||
}
|
||||
|
||||
public render(): ILayer {
|
||||
if (this.tileLayer) {
|
||||
// 瓦片图层执行单独的 render 渲染队列
|
||||
this.tileLayer.render();
|
||||
return this;
|
||||
}
|
||||
this.layerService.beforeRenderData(this);
|
||||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return this;
|
||||
}
|
||||
|
||||
this.updateUniform();
|
||||
|
||||
// Tip: this.getEncodedData().length !== 0 这个判断是为了解决在 2.5.x 引入数据纹理后产生的 空数据渲染导致 texture 超出上限问题
|
||||
this.renderModels();
|
||||
this.models.forEach((model) => {
|
||||
model.draw({ uniforms: {} });
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public updateUniform() {
|
||||
// 重新计算坐标系参数
|
||||
this.coordinateSystemService.refresh();
|
||||
|
||||
const { width, height } = this.rendererService.getViewportSize();
|
||||
this.models.forEach((model) => {
|
||||
model.addUniforms({
|
||||
// 相机参数,包含 VP 矩阵、缩放等级
|
||||
[CameraUniform.ProjectionMatrix]:
|
||||
this.cameraService.getProjectionMatrix(),
|
||||
[CameraUniform.ViewMatrix]: this.cameraService.getViewMatrix(),
|
||||
[CameraUniform.ViewProjectionMatrix]:
|
||||
this.cameraService.getViewProjectionMatrix(),
|
||||
[CameraUniform.Zoom]: this.cameraService.getZoom(),
|
||||
[CameraUniform.ZoomScale]: this.cameraService.getZoomScale(),
|
||||
[CoordinateUniform.CoordinateSystem]:
|
||||
this.coordinateSystemService.getCoordinateSystem(),
|
||||
[CoordinateUniform.ViewportCenter]:
|
||||
this.coordinateSystemService.getViewportCenter(),
|
||||
[CoordinateUniform.ViewportCenterProjection]:
|
||||
this.coordinateSystemService.getViewportCenterProjection(),
|
||||
[CoordinateUniform.PixelsPerDegree]:
|
||||
this.coordinateSystemService.getPixelsPerDegree(),
|
||||
[CoordinateUniform.PixelsPerDegree2]:
|
||||
this.coordinateSystemService.getPixelsPerDegree2(),
|
||||
[CoordinateUniform.PixelsPerMeter]:
|
||||
this.coordinateSystemService.getPixelsPerMeter(),
|
||||
u_SceneCenterMKT: [0, 0],
|
||||
u_ViewportSize: [width, height],
|
||||
u_ModelMatrix: this.cameraService.getModelMatrix(),
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* renderMultiPass 专门用于渲染支持 multipass 的 layer
|
||||
*/
|
||||
|
@ -704,15 +733,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
if (this.encodeDataLength <= 0 && !this.forceRender) {
|
||||
return;
|
||||
}
|
||||
if (this.multiPassRenderer && this.multiPassRenderer.getRenderFlag()) {
|
||||
// multi render 开始执行 multiPassRender 的渲染流程
|
||||
await this.multiPassRenderer.render();
|
||||
} else if (this.multiPassRenderer) {
|
||||
// renderPass 触发的渲染
|
||||
this.renderModels();
|
||||
} else {
|
||||
this.renderModels();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public active(options: IActiveOption | boolean) {
|
||||
|
@ -848,8 +869,7 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
}
|
||||
public setIndex(index: number): ILayer {
|
||||
this.zIndex = index;
|
||||
this.layerService.updateLayerRenderList();
|
||||
this.layerService.renderLayers();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -1301,18 +1321,8 @@ export default class BaseLayer<ChildLayerStyleOptions = {}>
|
|||
await multiPassRenderer.render();
|
||||
}
|
||||
|
||||
public renderModels(isPicking?: boolean) {
|
||||
|
||||
this.hooks.beforeRender.call();
|
||||
this.models.forEach((model) => {
|
||||
model.draw(
|
||||
{
|
||||
uniforms: {},
|
||||
}
|
||||
);
|
||||
});
|
||||
this.hooks.afterRender.call();
|
||||
return this;
|
||||
public renderModels() {
|
||||
|
||||
}
|
||||
|
||||
public updateStyleAttribute(
|
||||
|
|
|
@ -9,7 +9,6 @@ import {
|
|||
IRendererService,
|
||||
TYPES,
|
||||
} from '@antv/l7-core';
|
||||
import { $window } from '@antv/l7-utils';
|
||||
import { inject, injectable } from 'inversify';
|
||||
import 'reflect-metadata';
|
||||
|
||||
|
@ -31,84 +30,10 @@ export default class ShaderUniformPlugin implements ILayerPlugin {
|
|||
@inject(TYPES.IRendererService)
|
||||
private readonly rendererService: IRendererService;
|
||||
|
||||
@inject(TYPES.IMapService)
|
||||
private readonly mapService: IMapService;
|
||||
|
||||
public apply(layer: ILayer) {
|
||||
const version = this.mapService.version;
|
||||
|
||||
let mvp = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]; // default matrix (for gaode2.x)
|
||||
let sceneCenterMKT = [0, 0];
|
||||
layer.hooks.beforeRender.tap('ShaderUniformPlugin', () => {
|
||||
// @ts-ignore
|
||||
const offset = layer.getLayerConfig().tileOrigin;
|
||||
// 重新计算坐标系参数
|
||||
this.coordinateSystemService.refresh(offset);
|
||||
|
||||
if (version === 'GAODE2.x') {
|
||||
this.setLayerCenter(layer);
|
||||
// @ts-ignore
|
||||
mvp = this.mapService.map.customCoords.getMVPMatrix();
|
||||
// mvp = amapCustomCoords.getMVPMatrix()
|
||||
// @ts-ignore
|
||||
sceneCenterMKT = this.mapService.getCustomCoordCenter();
|
||||
}
|
||||
|
||||
const { width, height } = this.rendererService.getViewportSize();
|
||||
layer.models.forEach((model) => {
|
||||
model.addUniforms({
|
||||
// 相机参数,包含 VP 矩阵、缩放等级
|
||||
[CameraUniform.ProjectionMatrix]:
|
||||
this.cameraService.getProjectionMatrix(),
|
||||
[CameraUniform.ViewMatrix]: this.cameraService.getViewMatrix(),
|
||||
[CameraUniform.ViewProjectionMatrix]:
|
||||
this.cameraService.getViewProjectionMatrix(),
|
||||
[CameraUniform.Zoom]: this.cameraService.getZoom(),
|
||||
[CameraUniform.ZoomScale]: this.cameraService.getZoomScale(),
|
||||
[CameraUniform.FocalDistance]: this.cameraService.getFocalDistance(),
|
||||
[CameraUniform.CameraPosition]:
|
||||
this.cameraService.getCameraPosition(),
|
||||
// 坐标系参数
|
||||
[CoordinateUniform.CoordinateSystem]:
|
||||
this.coordinateSystemService.getCoordinateSystem(),
|
||||
[CoordinateUniform.ViewportCenter]:
|
||||
this.coordinateSystemService.getViewportCenter(),
|
||||
[CoordinateUniform.ViewportCenterProjection]:
|
||||
this.coordinateSystemService.getViewportCenterProjection(),
|
||||
[CoordinateUniform.PixelsPerDegree]:
|
||||
this.coordinateSystemService.getPixelsPerDegree(),
|
||||
[CoordinateUniform.PixelsPerDegree2]:
|
||||
this.coordinateSystemService.getPixelsPerDegree2(),
|
||||
[CoordinateUniform.PixelsPerMeter]:
|
||||
this.coordinateSystemService.getPixelsPerMeter(),
|
||||
// 坐标系是高德2.0的时候单独计算
|
||||
[CoordinateUniform.Mvp]: mvp,
|
||||
u_SceneCenterMKT: sceneCenterMKT,
|
||||
// 其他参数,例如视口大小、DPR 等
|
||||
u_ViewportSize: [width, height],
|
||||
u_ModelMatrix: this.cameraService.getModelMatrix(),
|
||||
u_DevicePixelRatio: $window.devicePixelRatio,
|
||||
// u_ModelMatrix: [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1],
|
||||
u_PickingBuffer: layer.getLayerConfig().pickingBuffer || 0,
|
||||
// Tip: 当前地图是否在拖动
|
||||
u_shaderPick: Number(layer.getShaderPickStat()),
|
||||
});
|
||||
});
|
||||
|
||||
// TODO:脏检查,决定是否需要渲染
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 对于每个 layer 都有不同的几何中心点,因此在绘制每个 layer 的时候都需要重新设置
|
||||
* @param layer
|
||||
*/
|
||||
private setLayerCenter(layer: ILayer) {
|
||||
if (layer.coordCenter === undefined) {
|
||||
layer.coordCenter = layer.getSource().center;
|
||||
}
|
||||
if (this.mapService.setCoordCenter) {
|
||||
this.mapService.setCoordCenter(layer.coordCenter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,50 +4,39 @@ import {
|
|||
IEncodeFeature,
|
||||
ILayer,
|
||||
TYPES,
|
||||
IShaderModuleService,
|
||||
IRendererService,
|
||||
IStyleAttributeService,
|
||||
} from '@antv/l7-core';
|
||||
|
||||
import pointFillFrag from '../shaders/fill_frag.glsl';
|
||||
import pointFillVert from '../shaders/fill_vert.glsl';
|
||||
|
||||
import StyleAttribute from '../../../../core/src/services/layer/StyleAttribute'
|
||||
|
||||
import { vert, frag } from './fillShader';
|
||||
export default class FillModel {
|
||||
protected layer: ILayer;
|
||||
private attributes: any[] = [];
|
||||
|
||||
protected shaderModuleService: IShaderModuleService;
|
||||
|
||||
protected rendererService: IRendererService;
|
||||
|
||||
protected styleAttributeService: IStyleAttributeService;
|
||||
|
||||
|
||||
constructor(layer: ILayer) {
|
||||
this.layer = layer;
|
||||
this.rendererService = layer
|
||||
.getContainer()
|
||||
.get<IRendererService>(TYPES.IRendererService);
|
||||
|
||||
|
||||
this.shaderModuleService = layer
|
||||
.getContainer()
|
||||
.get<IShaderModuleService>(TYPES.IShaderModuleService);
|
||||
|
||||
this.styleAttributeService = layer
|
||||
.getContainer()
|
||||
.get<IStyleAttributeService>(TYPES.IStyleAttributeService);
|
||||
|
||||
this.registerBuiltinAttributes();
|
||||
}
|
||||
|
||||
public createAttributesAndIndices(
|
||||
features: IEncodeFeature[],
|
||||
triangulation: Triangulation,
|
||||
segmentNumber: number,
|
||||
|
||||
) {
|
||||
|
||||
function triangulation() {
|
||||
const coordinates = [120, 30]
|
||||
return {
|
||||
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
|
||||
indices: [0, 1, 2, 2, 3, 0],
|
||||
size: 2,
|
||||
};
|
||||
}
|
||||
|
||||
const descriptors = this.attributes.map((attr) => {
|
||||
attr.resetDescriptor();
|
||||
|
@ -70,7 +59,7 @@ export default class FillModel {
|
|||
size: vertexSize,
|
||||
indexes,
|
||||
count,
|
||||
} = triangulation(feature, segmentNumber);
|
||||
} = triangulation(feature);
|
||||
|
||||
if (typeof count === 'number') {
|
||||
vecticesCount += count;
|
||||
|
@ -104,7 +93,7 @@ export default class FillModel {
|
|||
vertexIndex = indexes[vertexIdx];
|
||||
}
|
||||
|
||||
descriptors.forEach((descriptor, attributeIdx) => {
|
||||
descriptors.forEach((descriptor) => {
|
||||
if (descriptor && descriptor.update) {
|
||||
(descriptor.buffer.data as number[]).push(
|
||||
...descriptor.update(
|
||||
|
@ -129,10 +118,8 @@ export default class FillModel {
|
|||
|
||||
const attributes = {};
|
||||
|
||||
descriptors.forEach((descriptor, attributeIdx) => {
|
||||
descriptors.forEach((descriptor) => {
|
||||
if (descriptor) {
|
||||
// IAttribute 参数透传
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { buffer, update, name, ...rest } = descriptor;
|
||||
|
||||
const vertexAttribute = createAttribute({
|
||||
|
@ -141,8 +128,6 @@ export default class FillModel {
|
|||
...rest,
|
||||
});
|
||||
attributes[descriptor.name || ''] = vertexAttribute;
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -159,44 +144,41 @@ export default class FillModel {
|
|||
return attributesAndIndices;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public buildLayerModel( options: any ) {
|
||||
const {
|
||||
moduleName,
|
||||
vertexShader,
|
||||
fragmentShader,
|
||||
triangulation,
|
||||
segmentNumber,
|
||||
...rest
|
||||
} = options;
|
||||
|
||||
this.shaderModuleService.registerModule(moduleName, {
|
||||
vs: vertexShader,
|
||||
fs: fragmentShader,
|
||||
});
|
||||
const { vs, fs, uniforms } = this.shaderModuleService.getModule(moduleName);
|
||||
public buildLayerModel() {
|
||||
const uniforms = {
|
||||
u_CameraPosition: [0, 0, 0],
|
||||
u_CoordinateSystem: 0,
|
||||
u_DevicePixelRatio: 0,
|
||||
u_FocalDistance: 0,
|
||||
u_ModelMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
u_Mvp: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
u_PixelsPerDegree: [0, 0, 0],
|
||||
u_PixelsPerDegree2: [0, 0, 0],
|
||||
u_PixelsPerMeter: [0, 0, 0],
|
||||
u_ProjectionMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
u_ViewMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
u_ViewProjectionMatrix: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
||||
u_ViewportCenter: [0, 0],
|
||||
u_ViewportCenterProjection: [0, 0, 0, 0],
|
||||
u_ViewportSize: [0, 0],
|
||||
u_Zoom: 1,
|
||||
u_ZoomScale: 1
|
||||
}
|
||||
|
||||
const { createModel } = this.rendererService;
|
||||
const { attributes, elements } =this.createAttributesAndIndices(
|
||||
[{
|
||||
color: [1, 0, 0, 1],
|
||||
coordinates: [120, 30],
|
||||
id: 0,
|
||||
shape: 'circle',
|
||||
size: 16
|
||||
}],
|
||||
triangulation,
|
||||
segmentNumber,
|
||||
);
|
||||
|
||||
const modelOptions = {
|
||||
attributes,
|
||||
uniforms,
|
||||
fs,
|
||||
vs,
|
||||
fs: frag,
|
||||
vs: vert,
|
||||
elements,
|
||||
...rest,
|
||||
};
|
||||
|
||||
return createModel(modelOptions);
|
||||
|
@ -204,23 +186,7 @@ export default class FillModel {
|
|||
|
||||
|
||||
public buildModels() {
|
||||
|
||||
function PointFillTriangulation() {
|
||||
const coordinates = [120, 30]
|
||||
return {
|
||||
vertices: [...coordinates, ...coordinates, ...coordinates, ...coordinates],
|
||||
indices: [0, 1, 2, 2, 3, 0],
|
||||
size: 2,
|
||||
};
|
||||
}
|
||||
|
||||
const model = this
|
||||
.buildLayerModel({
|
||||
moduleName: 'pointFill',
|
||||
vertexShader: pointFillVert,
|
||||
fragmentShader: pointFillFrag,
|
||||
triangulation: PointFillTriangulation,
|
||||
});
|
||||
const model = this.buildLayerModel();
|
||||
return [model];
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
export const vert = `
|
||||
attribute vec3 a_Position;
|
||||
attribute vec3 a_Extrude;
|
||||
|
||||
uniform mat4 u_ModelMatrix;
|
||||
|
||||
|
||||
#define TILE_SIZE 512.0
|
||||
#define PI 3.1415926536
|
||||
#define WORLD_SCALE TILE_SIZE / (PI * 2.0)
|
||||
|
||||
#define COORDINATE_SYSTEM_LNGLAT 1.0 // mapbox
|
||||
#define COORDINATE_SYSTEM_LNGLAT_OFFSET 2.0 // mapbox offset
|
||||
#define COORDINATE_SYSTEM_VECTOR_TILE 3.0
|
||||
#define COORDINATE_SYSTEM_IDENTITY 4.0
|
||||
#define COORDINATE_SYSTEM_P20 5.0 // amap
|
||||
#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset
|
||||
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
|
||||
|
||||
attribute vec3 a_Position;
|
||||
attribute vec3 a_Extrude;
|
||||
|
||||
uniform mat4 u_ModelMatrix;
|
||||
|
||||
#define COORDINATE_SYSTEM_P20_2 8.0 // amap2.0
|
||||
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
|
||||
|
@ -32,6 +37,8 @@ uniform vec3 u_PixelsPerDegree2;
|
|||
|
||||
uniform vec3 u_PixelsPerMeter;
|
||||
|
||||
|
||||
|
||||
vec2 project_mercator(vec2 lnglat) {
|
||||
float x = lnglat.x;
|
||||
return vec2(
|
||||
|
@ -45,6 +52,7 @@ float project_scale(float meters) {
|
|||
}
|
||||
|
||||
|
||||
// offset coords -> world coords
|
||||
vec4 project_offset(vec4 offset) {
|
||||
float dy = offset.y;
|
||||
dy = clamp(dy, -1., 1.);
|
||||
|
@ -52,8 +60,24 @@ vec4 project_offset(vec4 offset) {
|
|||
return vec4(offset.xyz * pixels_per_unit, offset.w);
|
||||
}
|
||||
|
||||
|
||||
vec4 project_position(vec4 position) {
|
||||
float a = COORDINATE_SYSTEM_LNGLAT_OFFSET;
|
||||
float b = COORDINATE_SYSTEM_P20_OFFSET;
|
||||
float c = COORDINATE_SYSTEM_LNGLAT;
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET
|
||||
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
float X = position.x - u_ViewportCenter.x;
|
||||
float Y = position.y - u_ViewportCenter.y;
|
||||
return project_offset(vec4(X, Y, position.z, position.w));
|
||||
}
|
||||
if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) {
|
||||
return vec4(
|
||||
project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale,
|
||||
project_scale(position.z),
|
||||
position.w
|
||||
);
|
||||
}
|
||||
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
|
||||
return vec4(
|
||||
(project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.),
|
||||
|
@ -61,23 +85,33 @@ vec4 project_position(vec4 position) {
|
|||
position.w
|
||||
);
|
||||
}
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
vec2 project_pixel(vec2 pixel) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||
}
|
||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
||||
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
|
||||
}
|
||||
return pixel * -1.;
|
||||
}
|
||||
|
||||
|
||||
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET ||
|
||||
u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
|
||||
// Needs to be divided with project_uCommonUnitsPerMeter
|
||||
position.w *= u_PixelsPerMeter.z;
|
||||
}
|
||||
|
||||
return viewProjectionMatrix * position + center;
|
||||
}
|
||||
|
||||
// Projects from common space coordinates to clip space
|
||||
vec4 project_common_position_to_clipspace(vec4 position) {
|
||||
return project_common_position_to_clipspace(
|
||||
position,
|
||||
|
@ -86,18 +120,13 @@ vec4 project_common_position_to_clipspace(vec4 position) {
|
|||
);
|
||||
}
|
||||
|
||||
vec4 unproject_clipspace_to_position(vec4 clipspacePos, mat4 u_InverseViewProjectionMatrix) {
|
||||
vec4 pos = u_InverseViewProjectionMatrix * (clipspacePos - u_ViewportCenterProjection);
|
||||
return pos;
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 offset = a_Extrude.xy * 10.0;
|
||||
|
||||
offset = project_pixel(offset);
|
||||
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
|
||||
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
}
|
||||
`;
|
||||
|
|
|
@ -1,6 +1,11 @@
|
|||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
|
||||
|
||||
}
|
||||
}
|
|
@ -2,9 +2,122 @@ attribute vec3 a_Position;
|
|||
attribute vec3 a_Extrude;
|
||||
|
||||
uniform mat4 u_ModelMatrix;
|
||||
uniform mat4 u_Mvp;
|
||||
|
||||
#pragma include "projection"
|
||||
|
||||
#define TILE_SIZE 512.0
|
||||
#define PI 3.1415926536
|
||||
#define WORLD_SCALE TILE_SIZE / (PI * 2.0)
|
||||
|
||||
#define COORDINATE_SYSTEM_LNGLAT 1.0 // mapbox
|
||||
#define COORDINATE_SYSTEM_LNGLAT_OFFSET 2.0 // mapbox offset
|
||||
#define COORDINATE_SYSTEM_VECTOR_TILE 3.0
|
||||
#define COORDINATE_SYSTEM_IDENTITY 4.0
|
||||
#define COORDINATE_SYSTEM_P20 5.0 // amap
|
||||
#define COORDINATE_SYSTEM_P20_OFFSET 6.0 // amap offset
|
||||
#define COORDINATE_SYSTEM_METER_OFFSET 7.0
|
||||
|
||||
#define COORDINATE_SYSTEM_P20_2 8.0 // amap2.0
|
||||
|
||||
uniform mat4 u_ViewProjectionMatrix;
|
||||
|
||||
uniform float u_Zoom;
|
||||
|
||||
uniform float u_ZoomScale;
|
||||
|
||||
uniform float u_CoordinateSystem;
|
||||
|
||||
uniform vec2 u_ViewportCenter;
|
||||
|
||||
uniform vec4 u_ViewportCenterProjection;
|
||||
|
||||
uniform vec3 u_PixelsPerDegree;
|
||||
|
||||
uniform vec3 u_PixelsPerDegree2;
|
||||
|
||||
uniform vec3 u_PixelsPerMeter;
|
||||
|
||||
|
||||
|
||||
vec2 project_mercator(vec2 lnglat) {
|
||||
float x = lnglat.x;
|
||||
return vec2(
|
||||
radians(x) + PI,
|
||||
PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5))
|
||||
);
|
||||
}
|
||||
|
||||
float project_scale(float meters) {
|
||||
return meters * u_PixelsPerMeter.z;
|
||||
}
|
||||
|
||||
|
||||
// offset coords -> world coords
|
||||
vec4 project_offset(vec4 offset) {
|
||||
float dy = offset.y;
|
||||
dy = clamp(dy, -1., 1.);
|
||||
vec3 pixels_per_unit = u_PixelsPerDegree + u_PixelsPerDegree2 * dy;
|
||||
return vec4(offset.xyz * pixels_per_unit, offset.w);
|
||||
}
|
||||
|
||||
vec4 project_position(vec4 position) {
|
||||
float a = COORDINATE_SYSTEM_LNGLAT_OFFSET;
|
||||
float b = COORDINATE_SYSTEM_P20_OFFSET;
|
||||
float c = COORDINATE_SYSTEM_LNGLAT;
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET
|
||||
|| u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
float X = position.x - u_ViewportCenter.x;
|
||||
float Y = position.y - u_ViewportCenter.y;
|
||||
return project_offset(vec4(X, Y, position.z, position.w));
|
||||
}
|
||||
if (u_CoordinateSystem < COORDINATE_SYSTEM_LNGLAT + 0.01 && u_CoordinateSystem >COORDINATE_SYSTEM_LNGLAT - 0.01) {
|
||||
return vec4(
|
||||
project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale,
|
||||
project_scale(position.z),
|
||||
position.w
|
||||
);
|
||||
}
|
||||
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20) {
|
||||
return vec4(
|
||||
(project_mercator(position.xy) * WORLD_SCALE * u_ZoomScale - vec2(215440491., 106744817.)) * vec2(1., -1.),
|
||||
project_scale(position.z),
|
||||
position.w
|
||||
);
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
vec2 project_pixel(vec2 pixel) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_P20 || u_CoordinateSystem == COORDINATE_SYSTEM_P20_OFFSET) {
|
||||
// P20 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减1
|
||||
return pixel * pow(2.0, (19.0 - u_Zoom));
|
||||
}
|
||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) {
|
||||
// P20_2 坐标系下,为了和 Web 墨卡托坐标系统一,zoom 默认减3
|
||||
return pixel * pow(2.0, (19.0 - 3.0 - u_Zoom));
|
||||
}
|
||||
return pixel * -1.;
|
||||
}
|
||||
|
||||
|
||||
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
|
||||
if (u_CoordinateSystem == COORDINATE_SYSTEM_METER_OFFSET ||
|
||||
u_CoordinateSystem == COORDINATE_SYSTEM_LNGLAT_OFFSET) {
|
||||
// Needs to be divided with project_uCommonUnitsPerMeter
|
||||
position.w *= u_PixelsPerMeter.z;
|
||||
}
|
||||
|
||||
return viewProjectionMatrix * position + center;
|
||||
}
|
||||
|
||||
// Projects from common space coordinates to clip space
|
||||
vec4 project_common_position_to_clipspace(vec4 position) {
|
||||
return project_common_position_to_clipspace(
|
||||
position,
|
||||
u_ViewProjectionMatrix,
|
||||
u_ViewportCenterProjection
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec2 offset = a_Extrude.xy * 10.0;
|
||||
|
@ -13,10 +126,5 @@ void main() {
|
|||
|
||||
vec4 project_pos = project_position(vec4(a_Position.xy, 0.0, 1.0));
|
||||
|
||||
|
||||
if(u_CoordinateSystem == COORDINATE_SYSTEM_P20_2) { // gaode2.x
|
||||
gl_Position = u_Mvp * vec4(project_pos.xy + offset, 0.0, 1.0);
|
||||
} else {
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
}
|
||||
}
|
||||
gl_Position = project_common_position_to_clipspace(vec4(project_pos.xy + offset, 0.0, 1.0));
|
||||
}
|
|
@ -35,7 +35,7 @@ export class Base {
|
|||
}
|
||||
|
||||
public render() {
|
||||
this.parent.renderLayers();
|
||||
|
||||
}
|
||||
|
||||
public hasTile(tile: SourceTile) {
|
||||
|
|
|
@ -76,9 +76,6 @@ export default class ReglModel implements IModel {
|
|||
}
|
||||
|
||||
public draw(options: IModelDrawOptions) {
|
||||
|
||||
|
||||
|
||||
this.drawCommand(this.uniforms);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue