UNPKG

4.19 kBPlain TextView Raw
1import StencilMode from '../gl/stencil_mode';
2import DepthMode from '../gl/depth_mode';
3import CullFaceMode from '../gl/cull_face_mode';
4import Program from './program';
5import {circleUniformValues} from './program/circle_program';
6import SegmentVector from '../data/segment';
7import {OverscaledTileID} from '../source/tile_id';
8
9import type Painter from './painter';
10import type SourceCache from '../source/source_cache';
11import type CircleStyleLayer from '../style/style_layer/circle_style_layer';
12import type CircleBucket from '../data/bucket/circle_bucket';
13import type ProgramConfiguration from '../data/program_configuration';
14import type VertexBuffer from '../gl/vertex_buffer';
15import type IndexBuffer from '../gl/index_buffer';
16import type {UniformValues} from './uniform_binding';
17import type {CircleUniformsType} from './program/circle_program';
18
19export default drawCircles;
20
21type TileRenderState = {
22 programConfiguration: ProgramConfiguration;
23 program: Program<any>;
24 layoutVertexBuffer: VertexBuffer;
25 indexBuffer: IndexBuffer;
26 uniformValues: UniformValues<CircleUniformsType>;
27};
28
29type SegmentsTileRenderState = {
30 segments: SegmentVector;
31 sortKey: number;
32 state: TileRenderState;
33};
34
35function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleStyleLayer, coords: Array<OverscaledTileID>) {
36 if (painter.renderPass !== 'translucent') return;
37
38 const opacity = layer.paint.get('circle-opacity');
39 const strokeWidth = layer.paint.get('circle-stroke-width');
40 const strokeOpacity = layer.paint.get('circle-stroke-opacity');
41 const sortFeaturesByKey = !layer.layout.get('circle-sort-key').isConstant();
42
43 if (opacity.constantOr(1) === 0 && (strokeWidth.constantOr(1) === 0 || strokeOpacity.constantOr(1) === 0)) {
44 return;
45 }
46
47 const context = painter.context;
48 const gl = context.gl;
49
50 const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly);
51 // Turn off stencil testing to allow circles to be drawn across boundaries,
52 // so that large circles are not clipped to tiles
53 const stencilMode = StencilMode.disabled;
54 const colorMode = painter.colorModeForRenderPass();
55
56 const segmentsRenderStates: Array<SegmentsTileRenderState> = [];
57
58 for (let i = 0; i < coords.length; i++) {
59 const coord = coords[i];
60
61 const tile = sourceCache.getTile(coord);
62 const bucket: CircleBucket<any> = (tile.getBucket(layer) as any);
63 if (!bucket) continue;
64
65 const programConfiguration = bucket.programConfigurations.get(layer.id);
66 const program = painter.useProgram('circle', programConfiguration);
67 const layoutVertexBuffer = bucket.layoutVertexBuffer;
68 const indexBuffer = bucket.indexBuffer;
69 const uniformValues = circleUniformValues(painter, coord, tile, layer);
70
71 const state: TileRenderState = {
72 programConfiguration,
73 program,
74 layoutVertexBuffer,
75 indexBuffer,
76 uniformValues,
77 };
78
79 if (sortFeaturesByKey) {
80 const oldSegments = bucket.segments.get();
81 for (const segment of oldSegments) {
82 segmentsRenderStates.push({
83 segments: new SegmentVector([segment]),
84 sortKey: (segment.sortKey as any as number),
85 state
86 });
87 }
88 } else {
89 segmentsRenderStates.push({
90 segments: bucket.segments,
91 sortKey: 0,
92 state
93 });
94 }
95
96 }
97
98 if (sortFeaturesByKey) {
99 segmentsRenderStates.sort((a, b) => a.sortKey - b.sortKey);
100 }
101
102 for (const segmentsState of segmentsRenderStates) {
103 const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues} = segmentsState.state;
104 const segments = segmentsState.segments;
105
106 program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
107 uniformValues, layer.id,
108 layoutVertexBuffer, indexBuffer, segments,
109 layer.paint, painter.transform.zoom, programConfiguration);
110 }
111}