#include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace mbgl { using namespace style; void Painter::renderSymbol(PaintParameters& parameters, SymbolBucket& bucket, const SymbolLayer& layer, const RenderTile& tile) { if (pass == RenderPass::Opaque) { return; } const auto& layout = bucket.layout; frameHistory.bind(context, 1); auto draw = [&] (auto& shader, auto&& uniformValues, const auto& buffers, const SymbolPropertyValues& values_) { // In some cases, we disable the stencil test so that labels aren't clipped // to tile boundaries. // // Layers with features that may be drawn overlapping aren't clipped. These // layers are sorted in the y direction, and to draw the correct ordering near // tile edges the icons are included in both tiles and clipped when drawing. // // TODO remove the `true ||` when #1673 is implemented const bool drawAcrossEdges = (frame.mapMode == MapMode::Continuous) && (true || !(layout.textAllowOverlap || layout.iconAllowOverlap || layout.textIgnorePlacement || layout.iconIgnorePlacement)); context.draw({ values_.pitchAlignment == AlignmentType::Map ? depthModeForSublayer(0, gl::DepthMode::ReadOnly) : gl::DepthMode::disabled(), drawAcrossEdges ? gl::StencilMode::disabled() : stencilModeForClipping(tile.clip), colorModeForRenderPass(), shader, std::move(uniformValues), gl::Segmented( *buffers.vertexBuffer, *buffers.indexBuffer, buffers.segments ) }); }; if (bucket.hasIconData()) { auto values = layer.impl->iconPropertyValues(layout); SpriteAtlas& atlas = *layer.impl->spriteAtlas; const bool iconScaled = values.paintSize != 1.0f || frame.pixelRatio != atlas.getPixelRatio() || bucket.iconsNeedLinear; const bool iconTransformed = values.rotationAlignment == AlignmentType::Map || state.getPitch() != 0; atlas.bind(bucket.sdfIcons || state.isChanging() || iconScaled || iconTransformed, context, 0); const Size texsize = atlas.getSize(); if (bucket.sdfIcons) { if (values.hasHalo()) { draw(parameters.shaders.symbolIconSDF, SymbolSDFUniforms::haloValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio), bucket.icon, values); } if (values.hasForeground()) { draw(parameters.shaders.symbolIconSDF, SymbolSDFUniforms::foregroundValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio), bucket.icon, values); } } else { draw(parameters.shaders.symbolIcon, SymbolIconUniforms::values(values, texsize, pixelsToGLUnits, tile, state), bucket.icon, values); } } if (bucket.hasTextData()) { glyphAtlas->bind(context, 0); auto values = layer.impl->textPropertyValues(layout); const Size texsize = glyphAtlas->getSize()x§; if (values.hasHalo()) { draw(parameters.shaders.symbolGlyph, SymbolSDFUniforms::haloValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio), bucket.text, values); } if (values.hasForeground()) { draw(parameters.shaders.symbolGlyph, SymbolSDFUniforms::foregroundValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio), bucket.text, values); } } if (bucket.hasCollisionBoxData()) { context.draw({ gl::DepthMode::disabled(), gl::StencilMode::disabled(), colorModeForRenderPass(), shaders->collisionBox, CollisionBoxUniforms::values( tile.matrix, std::pow(2.0f, state.getZoom() - tile.tile.id.overscaledZ), state.getZoom() * 10, (tile.id.canonical.z + 1) * 10 ), gl::Unindexed( *bucket.collisionBox.vertexBuffer, 1.0f ) }); } } } // namespace mbgl