diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index 7d39c043950..e43a87aa2b4 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -8,6 +8,16 @@ namespace mbgl { namespace attributes { +/* + * Pack a pair of values, interpreted as uint8's, into a single float. + * Used to conserve vertex attributes. Values are unpacked in the vertex + * shader using the `unpack_float()` function, defined in _prelude.vertex.glsl. + */ +template +inline uint16_t packUint8Pair(T a, T b) { + return static_cast(a) * 256 + static_cast(b); +} + // Layout attributes MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); diff --git a/src/mbgl/programs/symbol_program.hpp b/src/mbgl/programs/symbol_program.hpp index 9b01b8ec5df..060c7fdd5ac 100644 --- a/src/mbgl/programs/symbol_program.hpp +++ b/src/mbgl/programs/symbol_program.hpp @@ -57,13 +57,17 @@ struct SymbolLayoutAttributes : gl::Attributes< }}, {{ static_cast(tx / 4), - static_cast(ty / 4) + static_cast(ty / 4), + mbgl::attributes::packUint8Pair( + static_cast(labelminzoom * 10), // 1/10 zoom levels: z16 == 160 + static_cast(labelangle) + ), + mbgl::attributes::packUint8Pair( + static_cast(minzoom * 10), + static_cast(::fmin(maxzoom, 25) * 10) + ) }}, {{ - static_cast(labelminzoom * 10), // 1/10 zoom levels: z16 == 160 - static_cast(labelangle), - static_cast(minzoom * 10), - static_cast(::fmin(maxzoom, 25) * 10) }} }; } diff --git a/src/mbgl/style/paint_property_binder.hpp b/src/mbgl/style/paint_property_binder.hpp index e6e957958c5..d26ab16f8e2 100644 --- a/src/mbgl/style/paint_property_binder.hpp +++ b/src/mbgl/style/paint_property_binder.hpp @@ -26,16 +26,12 @@ inline std::array attributeValue(float v) { uses 8-bit precision for each color component, for each float we use the upper 8 bits for one component (e.g. (color.r * 255) * 256), and the lower 8 for another. - Also note: - - Colors come in as floats 0..1, so we scale by 255. - - Casting the scaled values to ints is important: without doing this, e.g., the - fractional part of the `r` component would corrupt the lower-8 bits of the encoded - value, which must be reserved for the `g` component. + Also note that colors come in as floats 0..1, so we scale by 255. */ inline std::array attributeValue(const Color& color) { return {{ - static_cast(static_cast(color.r * 255) * 256 + static_cast(color.g * 255)), - static_cast(static_cast(color.b * 255) * 256 + static_cast(color.a * 255)) + static_cast(mbgl::attributes::packUint8Pair(255 * color.r, 255 * color.g)), + static_cast(mbgl::attributes::packUint8Pair(255 * color.b, 255 * color.a)) }}; }