maplibre-gl
Version:
BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
80 lines (64 loc) • 3.23 kB
text/typescript
import {DepthMode} from '../depth_mode.ts';
import {StencilMode} from '../stencil_mode.ts';
import type {Painter, RenderOptions} from '../../render/painter.ts';
import type {TileManager} from '../../tile/tile_manager.ts';
import type {CustomLayerProjectionDataParams, CustomRenderMethodInput, CustomStyleLayer} from '../../style/style_layer/custom_style_layer.ts';
import {OverscaledTileID} from '../../tile/tile_id.ts';
export function drawCustom(painter: Painter, tileManager: TileManager, layer: CustomStyleLayer, renderOptions: RenderOptions): void {
const {isRenderingGlobe} = renderOptions;
const context = painter.context;
const implementation = layer.implementation;
const projection = painter.style.projection;
const transform = painter.transform;
const projectionData = transform.getProjectionDataForCustomLayer(isRenderingGlobe);
const customLayerArgs: CustomRenderMethodInput = {
farZ: transform.farZ,
nearZ: transform.nearZ,
fov: transform.fov * Math.PI / 180, // fov converted to radians
modelViewProjectionMatrix: transform.modelViewProjectionMatrix,
projectionMatrix: transform.projectionMatrix,
shaderData: {
variantName: projection.shaderVariantName,
vertexShaderPrelude: `const float PI = 3.141592653589793;\nuniform mat4 u_projection_matrix;\n${projection.shaderPreludeCode.vertexSource}`,
define: projection.shaderDefine,
},
defaultProjectionData: projectionData,
getProjectionData: (params: CustomLayerProjectionDataParams) => {
return transform.getProjectionData({
overscaledTileID: new OverscaledTileID(
params.tileID.canonical.z,
params.tileID.wrap ?? 0,
params.tileID.canonical.z,
params.tileID.canonical.x,
params.tileID.canonical.y,
),
aligned: params.aligned,
applyGlobeMatrix: params.applyGlobeMatrix,
applyTerrainMatrix: params.applyTerrainMatrix,
});
}
};
const renderingMode = implementation.renderingMode ? implementation.renderingMode : '2d';
if (painter.renderPass === 'offscreen') {
const prerender = implementation.prerender;
if (prerender) {
painter.setCustomLayerDefaults();
context.setColorMode(painter.colorModeForRenderPass());
prerender.call(implementation, context.gl, customLayerArgs);
context.setDirty();
painter.setBaseState();
}
} else if (painter.renderPass === 'translucent') {
painter.setCustomLayerDefaults();
context.setColorMode(painter.colorModeForRenderPass());
context.setStencilMode(StencilMode.disabled);
const depthMode = renderingMode === '3d' ?
painter.getDepthModeFor3D() :
painter.getDepthModeForSublayer(0, DepthMode.ReadOnly);
context.setDepthMode(depthMode);
implementation.render(context.gl, customLayerArgs);
context.setDirty();
painter.setBaseState();
context.bindFramebuffer.set(null);
}
}