void Painter::renderSDF(SymbolBucket& bucket, const RenderTile& tile, float sdfFontSize, std::array<float, 2> texsize, SDFShader& sdfShader, void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&, bool), // Layout AlignmentType rotationAlignment, AlignmentType pitchAlignment, float layoutSize, // Paint float opacity, Color color, Color haloColor, float haloWidth, float haloBlur, std::array<float, 2> translate, TranslateAnchorType translateAnchor, float paintSize) { mat4 vtxMatrix = tile.translatedMatrix(translate, translateAnchor, state); // If layerStyle.size > bucket.info.fontSize then labels may collide float fontSize = paintSize; float fontScale = fontSize / sdfFontSize; bool rotateWithMap = rotationAlignment == AlignmentType::Map; bool pitchWithMap = pitchAlignment == AlignmentType::Map; std::array<float, 2> extrudeScale; float gammaScale; if (pitchWithMap) { gammaScale = 1.0 / std::cos(state.getPitch()); extrudeScale.fill(tile.id.pixelsToTileUnits(1, state.getZoom()) * fontScale); } else { gammaScale = 1.0; extrudeScale = {{ pixelsToGLUnits[0] * fontScale * state.getAltitude(), pixelsToGLUnits[1] * fontScale * state.getAltitude() }}; } config.program = sdfShader.getID(); sdfShader.u_matrix = vtxMatrix; sdfShader.u_extrude_scale = extrudeScale; sdfShader.u_texsize = texsize; sdfShader.u_rotate_with_map = rotateWithMap; sdfShader.u_pitch_with_map = pitchWithMap; sdfShader.u_texture = 0; sdfShader.u_pitch = state.getPitch() * util::DEG2RAD; sdfShader.u_bearing = -1.0f * state.getAngle(); sdfShader.u_aspect_ratio = (state.getWidth() * 1.0f) / (state.getHeight() * 1.0f); // adjust min/max zooms for variable font sies float zoomAdjust = std::log(fontSize / layoutSize) / std::log(2); sdfShader.u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level frameHistory.bind(store, config, 1); sdfShader.u_fadetexture = 1; // The default gamma value has to be adjust for the current pixelratio so that we're not // drawing blurry font on retina screens. const float gamma = 0.105 * sdfFontSize / fontSize / frame.pixelRatio; const float sdfPx = 8.0f; const float blurOffset = 1.19f; const float haloOffset = 6.0f; // We're drawing in the translucent pass which is bottom-to-top, so we need // to draw the halo first. if (haloColor.a > 0.0f && haloWidth > 0.0f) { sdfShader.u_gamma = (haloBlur * blurOffset / fontScale / sdfPx + gamma) * gammaScale; sdfShader.u_color = haloColor; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (haloOffset - haloWidth / fontScale) / sdfPx; setDepthSublayer(0); (bucket.*drawSDF)(sdfShader, store, isOverdraw()); } // Then, we draw the text/icon over the halo if (color.a > 0.0f) { sdfShader.u_gamma = gamma * gammaScale; sdfShader.u_color = color; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f; setDepthSublayer(1); (bucket.*drawSDF)(sdfShader, store, isOverdraw()); } }
void Painter::renderSDF(SymbolBucket &bucket, const UnwrappedTileID &tileID, const mat4 &matrix, float sdfFontSize, std::array<float, 2> texsize, SDFShader& sdfShader, void (SymbolBucket::*drawSDF)(SDFShader&, gl::ObjectStore&), // Layout RotationAlignmentType rotationAlignment, float layoutSize, // Paint float opacity, Color color, Color haloColor, float haloWidth, float haloBlur, std::array<float, 2> translate, TranslateAnchorType translateAnchor, float paintSize) { mat4 vtxMatrix = translatedMatrix(matrix, translate, tileID, translateAnchor); // If layerStyle.size > bucket.info.fontSize then labels may collide float fontSize = paintSize; float fontScale = fontSize / sdfFontSize; float scale = fontScale; std::array<float, 2> exScale = extrudeScale; bool alignedWithMap = rotationAlignment == RotationAlignmentType::Map; float gammaScale = 1.0f; if (alignedWithMap) { scale *= tileID.pixelsToTileUnits(1, state.getZoom()); exScale.fill(scale); gammaScale /= std::cos(state.getPitch()); } else { exScale = {{ exScale[0] * scale, exScale[1] * scale }}; } config.program = sdfShader.getID(); sdfShader.u_matrix = vtxMatrix; sdfShader.u_extrude_scale = exScale; sdfShader.u_texsize = texsize; sdfShader.u_skewed = alignedWithMap; sdfShader.u_texture = 0; // adjust min/max zooms for variable font sies float zoomAdjust = std::log(fontSize / layoutSize) / std::log(2); sdfShader.u_zoom = (state.getZoom() - zoomAdjust) * 10; // current zoom level config.activeTexture = GL_TEXTURE1; frameHistory.bind(store); sdfShader.u_fadetexture = 1; // The default gamma value has to be adjust for the current pixelratio so that we're not // drawing blurry font on retina screens. const float gamma = 0.105 * sdfFontSize / fontSize / frame.pixelRatio; const float sdfPx = 8.0f; const float blurOffset = 1.19f; const float haloOffset = 6.0f; // We're drawing in the translucent pass which is bottom-to-top, so we need // to draw the halo first. if (haloColor[3] > 0.0f && haloWidth > 0.0f) { sdfShader.u_gamma = (haloBlur * blurOffset / fontScale / sdfPx + gamma) * gammaScale; sdfShader.u_color = haloColor; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (haloOffset - haloWidth / fontScale) / sdfPx; setDepthSublayer(0); (bucket.*drawSDF)(sdfShader, store); } // Then, we draw the text/icon over the halo if (color[3] > 0.0f) { sdfShader.u_gamma = gamma * gammaScale; sdfShader.u_color = color; sdfShader.u_opacity = opacity; sdfShader.u_buffer = (256.0f - 64.0f) / 256.0f; setDepthSublayer(1); (bucket.*drawSDF)(sdfShader, store); } }