From 1a3e0863ccf251dc76944f11aab5abf9205c6a0d Mon Sep 17 00:00:00 2001 From: John Firebaugh Date: Thu, 10 Aug 2017 11:47:31 -0700 Subject: [core] Use separate attribute component for line normals Selective cherry pick of 822df3dd514ec3d05f876e6746cb8ba6348ac89d --- include/mbgl/util/constants.hpp | 3 ++- src/mbgl/programs/attributes.hpp | 1 + src/mbgl/programs/line_program.cpp | 2 +- src/mbgl/programs/line_program.hpp | 12 +++++++----- src/mbgl/renderer/line_bucket.cpp | 6 +++--- src/mbgl/shaders/line.cpp | 20 +++++++++----------- src/mbgl/shaders/line_pattern.cpp | 19 +++++++++---------- src/mbgl/shaders/line_sdf.cpp | 19 +++++++++---------- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/include/mbgl/util/constants.hpp b/include/mbgl/util/constants.hpp index 0f2779e33b..dbc4bddde5 100644 --- a/include/mbgl/util/constants.hpp +++ b/include/mbgl/util/constants.hpp @@ -19,7 +19,8 @@ constexpr float tileSize = 512; * * Positions are stored as signed 16bit integers. * One bit is lost for signedness to support features extending past the left edge of the tile. - * One bit is lost because the line vertex buffer packs 1 bit of other data into the int. + * One bit is lost because the line vertex buffer used to pack 1 bit of other data into the int. + * This is no longer the case but we're reserving this bit anyway. * One bit is lost to support features extending past the extent on the right edge of the tile. * This leaves us with 2^13 = 8192 */ diff --git a/src/mbgl/programs/attributes.hpp b/src/mbgl/programs/attributes.hpp index a0b2b93e16..53eae49b77 100644 --- a/src/mbgl/programs/attributes.hpp +++ b/src/mbgl/programs/attributes.hpp @@ -23,6 +23,7 @@ inline uint16_t packUint8Pair(T a, T b) { MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 2, a_extrude); MBGL_DEFINE_ATTRIBUTE(int16_t, 4, a_pos_offset); +MBGL_DEFINE_ATTRIBUTE(int16_t, 3, a_pos_normal); MBGL_DEFINE_ATTRIBUTE(uint16_t, 2, a_texture_pos); MBGL_DEFINE_ATTRIBUTE(int16_t, 3, a_normal); MBGL_DEFINE_ATTRIBUTE(uint16_t, 1, a_edgedistance); diff --git a/src/mbgl/programs/line_program.cpp b/src/mbgl/programs/line_program.cpp index d9778ba7ce..d18dc1e7eb 100644 --- a/src/mbgl/programs/line_program.cpp +++ b/src/mbgl/programs/line_program.cpp @@ -10,7 +10,7 @@ namespace mbgl { using namespace style; -static_assert(sizeof(LineLayoutVertex) == 8, "expected LineLayoutVertex size"); +static_assert(sizeof(LineLayoutVertex) == 10, "expected LineLayoutVertex size"); template Values makeValues(const LinePaintProperties::Evaluated& properties, diff --git a/src/mbgl/programs/line_program.hpp b/src/mbgl/programs/line_program.hpp index b2e55a4f3b..0a56ae5dad 100644 --- a/src/mbgl/programs/line_program.hpp +++ b/src/mbgl/programs/line_program.hpp @@ -31,7 +31,7 @@ MBGL_DEFINE_UNIFORM_VECTOR(float, 2, u_gl_units_to_pixels); } // namespace uniforms struct LineLayoutAttributes : gl::Attributes< - attributes::a_pos, + attributes::a_pos_normal, attributes::a_data> {}; @@ -52,14 +52,16 @@ public: /* * @param p vertex position * @param e extrude normal - * @param t texture normal + * @param round whether the vertex uses a round line cap + * @param up whether the line normal points up or down * @param dir direction of the line cap (-1/0/1) */ - static LayoutVertex layoutVertex(Point p, Point e, Point t, int8_t dir, int32_t linesofar = 0) { + static LayoutVertex layoutVertex(Point p, Point e, bool round, bool up, int8_t dir, int32_t linesofar = 0) { return LayoutVertex { {{ - static_cast((p.x * 2) | t.x), - static_cast((p.y * 2) | t.y) + p.x, + p.y, + static_cast(attributes::packUint8Pair(round ? 1 : 0, up ? 1 : 0)) }}, {{ // add 128 to store a byte in an unsigned byte diff --git a/src/mbgl/renderer/line_bucket.cpp b/src/mbgl/renderer/line_bucket.cpp index 7bb4e2f202..c80b8900ea 100644 --- a/src/mbgl/renderer/line_bucket.cpp +++ b/src/mbgl/renderer/line_bucket.cpp @@ -398,7 +398,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate, Point extrude = normal; if (endLeft) extrude = extrude - (util::perp(normal) * endLeft); - vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, false }, endLeft, distance * LINE_DISTANCE_SCALE)); + vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, false, endLeft, distance * LINE_DISTANCE_SCALE)); e3 = vertices.vertexSize() - 1 - startVertex; if (e1 >= 0 && e2 >= 0) { triangleStore.emplace_back(e1, e2, e3); @@ -409,7 +409,7 @@ void LineBucket::addCurrentVertex(const GeometryCoordinate& currentCoordinate, extrude = normal * -1.0; if (endRight) extrude = extrude - (util::perp(normal) * endRight); - vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, { round, true }, -endRight, distance * LINE_DISTANCE_SCALE)); + vertices.emplace_back(LineProgram::layoutVertex(currentCoordinate, extrude, round, true, -endRight, distance * LINE_DISTANCE_SCALE)); e3 = vertices.vertexSize() - 1 - startVertex; if (e1 >= 0 && e2 >= 0) { triangleStore.emplace_back(e1, e2, e3); @@ -434,7 +434,7 @@ void LineBucket::addPieSliceVertex(const GeometryCoordinate& currentVertex, std::size_t startVertex, std::vector& triangleStore) { Point flippedExtrude = extrude * (lineTurnsLeft ? -1.0 : 1.0); - vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, { false, lineTurnsLeft }, 0, distance * LINE_DISTANCE_SCALE)); + vertices.emplace_back(LineProgram::layoutVertex(currentVertex, flippedExtrude, false, lineTurnsLeft, 0, distance * LINE_DISTANCE_SCALE)); e3 = vertices.vertexSize() - 1 - startVertex; if (e1 >= 0 && e2 >= 0) { triangleStore.emplace_back(e1, e2, e3); diff --git a/src/mbgl/shaders/line.cpp b/src/mbgl/shaders/line.cpp index dce6046257..ce62ecb3bd 100644 --- a/src/mbgl/shaders/line.cpp +++ b/src/mbgl/shaders/line.cpp @@ -21,7 +21,7 @@ const char* line::vertexSource = R"MBGL_SHADER( // #define scale 63.0 #define scale 0.015873016 -attribute vec2 a_pos; +attribute vec3 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -107,20 +107,21 @@ void main() { vec2 a_extrude = a_data.xy - 128.0; float a_direction = mod(a_data.z, 4.0) - 1.0; - // We store the texture normals in the most insignificant bit - // transform y so that 0 => -1 and 1 => 1 + vec2 pos = a_pos_normal.xy; + + // transform y normal so that 0 => -1 and 1 => 1 // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = mod(a_pos, 2.0); + mediump vec2 normal = unpack_float(a_pos_normal.z); normal.y = sign(normal.y - 0.5); - v_normal = normal; + v_normal = normal; - // these transformations used to be applied in the JS and native code bases. - // moved them into the shader for clarity and simplicity. + // these transformations used to be applied in the JS and native code bases. + // moved them into the shader for clarity and simplicity. gapwidth = gapwidth / 2.0; float width = u_width / 2.0; - offset = -1.0 * offset; + offset = -1.0 * offset; float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0); float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING; @@ -137,9 +138,6 @@ void main() { mediump float t = 1.0 - abs(u); mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t); - // Remove the texture normal bit to get the position - vec2 pos = floor(a_pos * 0.5); - vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; diff --git a/src/mbgl/shaders/line_pattern.cpp b/src/mbgl/shaders/line_pattern.cpp index 1c07b4f515..f43b3a3cf7 100644 --- a/src/mbgl/shaders/line_pattern.cpp +++ b/src/mbgl/shaders/line_pattern.cpp @@ -23,7 +23,7 @@ const char* line_pattern::vertexSource = R"MBGL_SHADER( // Retina devices need a smaller distance to avoid aliasing. #define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0 -attribute vec2 a_pos; +attribute vec3 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -97,19 +97,21 @@ void main() { float a_direction = mod(a_data.z, 4.0) - 1.0; float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE; - // We store the texture normals in the most insignificant bit - // transform y so that 0 => -1 and 1 => 1 + vec2 pos = a_pos_normal.xy; + + // transform y normal so that 0 => -1 and 1 => 1 // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = mod(a_pos, 2.0); + mediump vec2 normal = unpack_float(a_pos_normal.z); normal.y = sign(normal.y - 0.5); + v_normal = normal; - // these transformations used to be applied in the JS and native code bases. - // moved them into the shader for clarity and simplicity. + // these transformations used to be applied in the JS and native code bases. + // moved them into the shader for clarity and simplicity. gapwidth = gapwidth / 2.0; float width = u_width / 2.0; - offset = -1.0 * offset; + offset = -1.0 * offset; float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0); float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING; @@ -126,9 +128,6 @@ void main() { mediump float t = 1.0 - abs(u); mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t); - // Remove the texture normal bit to get the position - vec2 pos = floor(a_pos * 0.5); - vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; diff --git a/src/mbgl/shaders/line_sdf.cpp b/src/mbgl/shaders/line_sdf.cpp index b37bf688d4..24b7153c7f 100644 --- a/src/mbgl/shaders/line_sdf.cpp +++ b/src/mbgl/shaders/line_sdf.cpp @@ -23,7 +23,7 @@ const char* line_sdf::vertexSource = R"MBGL_SHADER( // Retina devices need a smaller distance to avoid aliasing. #define ANTIALIASING 1.0 / DEVICE_PIXEL_RATIO / 2.0 -attribute vec2 a_pos; +attribute vec3 a_pos_normal; attribute vec4 a_data; uniform mat4 u_matrix; @@ -116,20 +116,22 @@ void main() { float a_direction = mod(a_data.z, 4.0) - 1.0; float a_linesofar = (floor(a_data.z / 4.0) + a_data.w * 64.0) * LINE_DISTANCE_SCALE; - // We store the texture normals in the most insignificant bit - // transform y so that 0 => -1 and 1 => 1 + vec2 pos = a_pos_normal.xy; + + // transform y normal so that 0 => -1 and 1 => 1 // In the texture normal, x is 0 if the normal points straight up/down and 1 if it's a round cap // y is 1 if the normal points up, and -1 if it points down - mediump vec2 normal = mod(a_pos, 2.0); + mediump vec2 normal = unpack_float(a_pos_normal.z); normal.y = sign(normal.y - 0.5); + v_normal = normal; - // these transformations used to be applied in the JS and native code bases. - // moved them into the shader for clarity and simplicity. + // these transformations used to be applied in the JS and native code bases. + // moved them into the shader for clarity and simplicity. gapwidth = gapwidth / 2.0; float width = u_width / 2.0; offset = -1.0 * offset; - + float inset = gapwidth + (gapwidth > 0.0 ? ANTIALIASING : 0.0); float outset = gapwidth + width * (gapwidth > 0.0 ? 2.0 : 1.0) + ANTIALIASING; @@ -145,9 +147,6 @@ void main() { mediump float t = 1.0 - abs(u); mediump vec2 offset2 = offset * a_extrude * scale * normal.y * mat2(t, -u, u, t); - // Remove the texture normal bit to get the position - vec2 pos = floor(a_pos * 0.5); - vec4 projected_extrude = u_matrix * vec4(dist / u_ratio, 0.0, 0.0); gl_Position = u_matrix * vec4(pos + offset2 / u_ratio, 0.0, 1.0) + projected_extrude; -- cgit v1.2.1