package.src.render.draw_circle.js Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mapbox-gl Show documentation
Show all versions of mapbox-gl Show documentation
A WebGL interactive maps library
The newest version!
// @flow
import StencilMode from '../gl/stencil_mode';
import DepthMode from '../gl/depth_mode';
import CullFaceMode from '../gl/cull_face_mode';
import Program from './program';
import {circleUniformValues} from './program/circle_program';
import SegmentVector from '../data/segment';
import {OverscaledTileID} from '../source/tile_id';
import type Painter from './painter';
import type SourceCache from '../source/source_cache';
import type CircleStyleLayer from '../style/style_layer/circle_style_layer';
import type CircleBucket from '../data/bucket/circle_bucket';
import type ProgramConfiguration from '../data/program_configuration';
import type VertexBuffer from '../gl/vertex_buffer';
import type IndexBuffer from '../gl/index_buffer';
import type {UniformValues} from './uniform_binding';
import type {CircleUniformsType} from './program/circle_program';
export default drawCircles;
type TileRenderState = {
programConfiguration: ProgramConfiguration,
program: Program<*>,
layoutVertexBuffer: VertexBuffer,
indexBuffer: IndexBuffer,
uniformValues: UniformValues
};
type SegmentsTileRenderState = {
segments: SegmentVector,
sortKey: number,
state: TileRenderState
};
function drawCircles(painter: Painter, sourceCache: SourceCache, layer: CircleStyleLayer, coords: Array) {
if (painter.renderPass !== 'translucent') return;
const opacity = layer.paint.get('circle-opacity');
const strokeWidth = layer.paint.get('circle-stroke-width');
const strokeOpacity = layer.paint.get('circle-stroke-opacity');
const sortFeaturesByKey = layer.layout.get('circle-sort-key').constantOr(1) !== undefined;
if (opacity.constantOr(1) === 0 && (strokeWidth.constantOr(1) === 0 || strokeOpacity.constantOr(1) === 0)) {
return;
}
const context = painter.context;
const gl = context.gl;
const depthMode = painter.depthModeForSublayer(0, DepthMode.ReadOnly);
// Turn off stencil testing to allow circles to be drawn across boundaries,
// so that large circles are not clipped to tiles
const stencilMode = StencilMode.disabled;
const colorMode = painter.colorModeForRenderPass();
const segmentsRenderStates: Array = [];
for (let i = 0; i < coords.length; i++) {
const coord = coords[i];
const tile = sourceCache.getTile(coord);
const bucket: ?CircleBucket<*> = (tile.getBucket(layer): any);
if (!bucket) continue;
const programConfiguration = bucket.programConfigurations.get(layer.id);
const program = painter.useProgram('circle', programConfiguration);
const layoutVertexBuffer = bucket.layoutVertexBuffer;
const indexBuffer = bucket.indexBuffer;
const uniformValues = circleUniformValues(painter, coord, tile, layer);
const state: TileRenderState = {
programConfiguration,
program,
layoutVertexBuffer,
indexBuffer,
uniformValues,
};
if (sortFeaturesByKey) {
const oldSegments = bucket.segments.get();
for (const segment of oldSegments) {
segmentsRenderStates.push({
segments: new SegmentVector([segment]),
sortKey: ((segment.sortKey: any): number),
state
});
}
} else {
segmentsRenderStates.push({
segments: bucket.segments,
sortKey: 0,
state
});
}
}
if (sortFeaturesByKey) {
segmentsRenderStates.sort((a, b) => a.sortKey - b.sortKey);
}
for (const segmentsState of segmentsRenderStates) {
const {programConfiguration, program, layoutVertexBuffer, indexBuffer, uniformValues} = segmentsState.state;
const segments = segmentsState.segments;
program.draw(context, gl.TRIANGLES, depthMode, stencilMode, colorMode, CullFaceMode.disabled,
uniformValues, layer.id,
layoutVertexBuffer, indexBuffer, segments,
layer.paint, painter.transform.zoom, programConfiguration);
}
}