Files
MapLibreParticleLab/src/mbgl/renderer/painter_symbol.cpp
2017-02-02 09:44:42 -08:00

142 lines
5.0 KiB
C++

#include <mbgl/renderer/painter.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/renderer/symbol_bucket.hpp>
#include <mbgl/renderer/render_tile.hpp>
#include <mbgl/style/layers/symbol_layer.hpp>
#include <mbgl/style/layers/symbol_layer_impl.hpp>
#include <mbgl/text/glyph_atlas.hpp>
#include <mbgl/sprite/sprite_atlas.hpp>
#include <mbgl/programs/programs.hpp>
#include <mbgl/programs/symbol_program.hpp>
#include <mbgl/programs/collision_box_program.hpp>
#include <mbgl/util/math.hpp>
#include <mbgl/tile/tile.hpp>
#include <cmath>
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& program,
auto&& uniformValues,
const auto& buffers,
const SymbolPropertyValues& values_)
{
// We clip symbols to their tile extent in still mode.
const bool needsClipping = frame.mapMode == MapMode::Still;
program.draw(
context,
gl::Triangles(),
values_.pitchAlignment == AlignmentType::Map
? depthModeForSublayer(0, gl::DepthMode::ReadOnly)
: gl::DepthMode::disabled(),
needsClipping
? stencilModeForClipping(tile.clip)
: gl::StencilMode::disabled(),
colorModeForRenderPass(),
std::move(uniformValues),
*buffers.vertexBuffer,
*buffers.indexBuffer,
buffers.segments,
bucket.paintPropertyBinders.at(layer.getID()),
layer.impl->paint.evaluated,
state.getZoom()
);
};
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.programs.symbolIconSDF,
SymbolSDFProgram::haloUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
bucket.icon,
values);
}
if (values.hasForeground()) {
draw(parameters.programs.symbolIconSDF,
SymbolSDFProgram::foregroundUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
bucket.icon,
values);
}
} else {
draw(parameters.programs.symbolIcon,
SymbolIconProgram::uniformValues(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();
if (values.hasHalo()) {
draw(parameters.programs.symbolGlyph,
SymbolSDFProgram::haloUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
bucket.text,
values);
}
if (values.hasForeground()) {
draw(parameters.programs.symbolGlyph,
SymbolSDFProgram::foregroundUniformValues(values, texsize, pixelsToGLUnits, tile, state, frame.pixelRatio),
bucket.text,
values);
}
}
if (bucket.hasCollisionBoxData()) {
static const style::PaintProperties<>::Evaluated properties {};
static const CollisionBoxProgram::PaintPropertyBinders paintAttributeData(properties, 0);
programs->collisionBox.draw(
context,
gl::Lines { 1.0f },
gl::DepthMode::disabled(),
gl::StencilMode::disabled(),
colorModeForRenderPass(),
CollisionBoxProgram::UniformValues {
uniforms::u_matrix::Value{ tile.matrix },
uniforms::u_scale::Value{ std::pow(2.0f, float(state.getZoom() - tile.tile.id.overscaledZ)) },
uniforms::u_zoom::Value{ float(state.getZoom() * 10) },
uniforms::u_maxzoom::Value{ float((tile.id.canonical.z + 1) * 10) },
},
*bucket.collisionBox.vertexBuffer,
*bucket.collisionBox.indexBuffer,
bucket.collisionBox.segments,
paintAttributeData,
properties,
state.getZoom()
);
}
}
} // namespace mbgl