Skip to content

Commit

Permalink
Custom Drawable Layer: Symbol Icon (#1908)
Browse files Browse the repository at this point in the history
  • Loading branch information
stefankarschti authored Feb 16, 2024
1 parent 612b256 commit d6db72e
Show file tree
Hide file tree
Showing 32 changed files with 788 additions and 29 deletions.
5 changes: 4 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ endif()

if(MLN_DRAWABLE_RENDERER)
list(APPEND INCLUDE_FILES
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/context.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_data.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_impl.hpp
Expand Down Expand Up @@ -465,7 +466,6 @@ list(APPEND SRC_FILES
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/attribute.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/color_mode.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/command_encoder.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/context.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/cull_face_mode.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/debug_group.hpp
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/depth_mode.hpp
Expand Down Expand Up @@ -1142,6 +1142,7 @@ if(MLN_WITH_OPENGL)
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/hillshade_prepare_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/line_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/custom_drawable_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/raster_layer_ubo.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/shader_defines.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/symbol_layer_ubo.hpp
Expand Down Expand Up @@ -1211,6 +1212,7 @@ if(MBGL_WITH_METAL)
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision_box.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision_circle.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/custom_symbol_icon.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/debug.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill.hpp
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/fill_extrusion.hpp
Expand Down Expand Up @@ -1256,6 +1258,7 @@ if(MBGL_WITH_METAL)
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/collision_box.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/collision_circle.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/clipping_mask.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/custom_symbol_icon.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/debug.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/fill.cpp
${PROJECT_SOURCE_DIR}src/mbgl/shaders/mtl/fill_extrusion.cpp
Expand Down
6 changes: 5 additions & 1 deletion bazel/core.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ MLN_GENERATED_OPENGL_SHADER_HEADERS = [
"include/mbgl/shaders/gl/drawable_circle.hpp",
"include/mbgl/shaders/gl/drawable_collision_box.hpp",
"include/mbgl/shaders/gl/drawable_collision_circle.hpp",
"include/mbgl/shaders/gl/drawable_custom_symbol_icon.hpp",
"include/mbgl/shaders/gl/drawable_debug.hpp",
"include/mbgl/shaders/gl/drawable_fill.hpp",
"include/mbgl/shaders/gl/drawable_fill_outline.hpp",
Expand Down Expand Up @@ -143,7 +144,6 @@ MLN_CORE_SOURCE = [
"include/mbgl/gfx/backend.hpp",
"src/mbgl/gfx/color_mode.hpp",
"src/mbgl/gfx/command_encoder.hpp",
"src/mbgl/gfx/context.hpp",
"src/mbgl/gfx/cull_face_mode.hpp",
"src/mbgl/gfx/debug_group.hpp",
"src/mbgl/gfx/depth_mode.hpp",
Expand Down Expand Up @@ -648,6 +648,7 @@ MLN_CORE_SOURCE = [
]

MLN_CORE_HEADERS = [
"include/mbgl/gfx/context.hpp",
"include/mbgl/actor/actor.hpp",
"include/mbgl/actor/actor_ref.hpp",
"include/mbgl/actor/aspiring_actor.hpp",
Expand Down Expand Up @@ -980,6 +981,7 @@ MLN_DRAWABLES_HEADERS = [
"include/mbgl/shaders/background_layer_ubo.hpp",
"include/mbgl/shaders/circle_layer_ubo.hpp",
"include/mbgl/shaders/collision_layer_ubo.hpp",
"include/mbgl/shaders/custom_drawable_layer_ubo.hpp",
"include/mbgl/shaders/debug_layer_ubo.hpp",
"include/mbgl/shaders/fill_layer_ubo.hpp",
"include/mbgl/shaders/fill_extrusion_layer_ubo.hpp",
Expand Down Expand Up @@ -1054,6 +1056,7 @@ MLN_DRAWABLES_MTL_SOURCE = [
"src/mbgl/shaders/mtl/collision_box.cpp",
"src/mbgl/shaders/mtl/collision_circle.cpp",
"src/mbgl/shaders/mtl/clipping_mask.cpp",
"src/mbgl/shaders/mtl/custom_symbol_icon.cpp",
"src/mbgl/shaders/mtl/debug.cpp",
"src/mbgl/shaders/mtl/fill.cpp",
"src/mbgl/shaders/mtl/fill_extrusion.cpp",
Expand Down Expand Up @@ -1098,6 +1101,7 @@ MLN_DRAWABLES_MTL_HEADERS = [
"include/mbgl/shaders/mtl/collision_box.hpp",
"include/mbgl/shaders/mtl/collision_circle.hpp",
"include/mbgl/shaders/mtl/common.hpp",
"include/mbgl/shaders/mtl/custom_symbol_icon.hpp",
"include/mbgl/shaders/mtl/debug.hpp",
"include/mbgl/shaders/mtl/fill.hpp",
"include/mbgl/shaders/mtl/fill_extrusion.hpp",
Expand Down
File renamed without changes.
36 changes: 36 additions & 0 deletions include/mbgl/shaders/custom_drawable_layer_ubo.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#pragma once

#include <mbgl/shaders/layer_ubo.hpp>

namespace mbgl {
namespace shaders {

/// Custom Symbol Icon matrix
struct alignas(16) CustomSymbolIconDrawableUBO {
/* 0 */ std::array<float, 4 * 4> matrix;
/* 64 */
};
static_assert(sizeof(CustomSymbolIconDrawableUBO) == 4 * 16);

/// Custom Symbol Icon Parameters
struct alignas(16) CustomSymbolIconParametersUBO {
/* 0 */ std::array<float, 2> extrude_scale;
/* 8 */ std::array<float, 2> anchor;
/* 16 */ float angle_degrees;
/* 20 */ uint32_t scale_with_map;
/* 24 */ uint32_t pitch_with_map;
/* 28 */ float camera_to_center_distance;
/* 32 */ float aspect_ratio;
/* 36 */ float pad0, pad1, pad2;
/* 48 */
};
static_assert(sizeof(CustomSymbolIconParametersUBO) == 3 * 16);

enum {
idCustomSymbolIconDrawableUBO,
idCustomSymbolIconParametersUBO,
customDrawableUBOCount
};

} // namespace shaders
} // namespace mbgl
92 changes: 92 additions & 0 deletions include/mbgl/shaders/gl/drawable_custom_symbol_icon.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Generated code, do not modify this file!
#pragma once
#include <mbgl/shaders/shader_source.hpp>

namespace mbgl {
namespace shaders {

template <>
struct ShaderSource<BuiltIn::CustomSymbolIconShader, gfx::Backend::Type::OpenGL> {
static constexpr const char* name = "CustomSymbolIconShader";
static constexpr const char* vertex = R"(layout(location = 0) in vec2 a_pos;
layout(location = 1) in vec2 a_tex;
layout(std140) uniform CustomSymbolIconDrawableUBO {
highp mat4 u_matrix;
};
layout(std140) uniform CustomSymbolIconParametersUBO {
highp vec2 u_extrude_scale;
highp vec2 u_anchor;
highp float u_angle_degrees;
bool u_scale_with_map;
bool u_pitch_with_map;
highp float u_camera_to_center_distance;
highp float u_aspect_ratio;
highp float pad0, pad1, pad3;
};
out vec2 v_tex;
vec2 rotateVec2(vec2 v, float angle) {
float cosA = cos(angle);
float sinA = sin(angle);
return vec2(v.x * cosA - v.y * sinA, v.x * sinA + v.y * cosA);
}
vec2 ellipseRotateVec2(vec2 v, float angle, float radiusRatio /* A/B */) {
float cosA = cos(angle);
float sinA = sin(angle);
float invRatio = 1.0 / radiusRatio;
return vec2(v.x * cosA - radiusRatio * v.y * sinA, invRatio * v.x * sinA + v.y * cosA);
}
void main() {
// decode the extrusion vector (-1, -1) to (1, 1)
vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);
// make anchor relative to (0.5, 0.5) and corners in range (-1, -1) to (1, 1)
vec2 anchor = (u_anchor - vec2(0.5, 0.5)) * 2.0;
// decode center
vec2 center = floor(a_pos * 0.5);
// rotate extrusion around anchor
float angle = radians(-u_angle_degrees);
vec2 corner = extrude - anchor;
// compute
if (u_pitch_with_map) {
if (u_scale_with_map) {
corner *= u_extrude_scale;
} else {
vec4 projected_center = u_matrix * vec4(center, 0, 1);
corner *= u_extrude_scale * (projected_center.w / u_camera_to_center_distance);
}
corner = center + rotateVec2(corner, angle);
gl_Position = u_matrix * vec4(corner, 0, 1);
} else {
gl_Position = u_matrix * vec4(center, 0, 1);
if (u_scale_with_map) {
gl_Position.xy += ellipseRotateVec2(corner * u_extrude_scale * u_camera_to_center_distance, angle, u_aspect_ratio);
} else {
gl_Position.xy += ellipseRotateVec2(corner * u_extrude_scale * gl_Position.w, angle, u_aspect_ratio);
}
}
// texture coordinates
v_tex = a_tex;
}
)";
static constexpr const char* fragment = R"(uniform sampler2D u_texture;
in vec2 v_tex;
void main() {
fragColor = texture(u_texture, v_tex);
}
)";
};

} // namespace shaders
} // namespace mbgl
6 changes: 6 additions & 0 deletions include/mbgl/shaders/gl/shader_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,12 @@ struct ShaderInfo<BuiltIn::CollisionCircleShader, gfx::Backend::Type::OpenGL> {
static const std::vector<TextureInfo> textures;
};

template <>
struct ShaderInfo<BuiltIn::CustomSymbolIconShader, gfx::Backend::Type::OpenGL> {
static const std::vector<UniformBlockInfo> uniformBlocks;
static const std::vector<TextureInfo> textures;
};

template <>
struct ShaderInfo<BuiltIn::DebugShader, gfx::Backend::Type::OpenGL> {
static const std::vector<UniformBlockInfo> uniformBlocks;
Expand Down
105 changes: 105 additions & 0 deletions include/mbgl/shaders/mtl/custom_symbol_icon.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
#pragma once

#include <mbgl/shaders/mtl/common.hpp>
#include <mbgl/shaders/mtl/shader_program.hpp>
#include <mbgl/shaders/shader_source.hpp>
#include <mbgl/shaders/custom_drawable_layer_ubo.hpp>

namespace mbgl {
namespace shaders {

template <>
struct ShaderSource<BuiltIn::CustomSymbolIconShader, gfx::Backend::Type::Metal> {
static constexpr auto name = "CustomSymbolIconShader";
static constexpr auto vertexMainFunction = "vertexMain";
static constexpr auto fragmentMainFunction = "fragmentMain";

static const std::array<AttributeInfo, 2> attributes;
static const std::array<UniformBlockInfo, 2> uniforms;
static const std::array<TextureInfo, 1> textures;

static constexpr auto source = R"(
struct alignas(16) CustomSymbolIconDrawableUBO {
float4x4 matrix;
};
struct alignas(16) CustomSymbolIconParametersUBO {
float2 extrude_scale;
float2 anchor;
float angle_degrees;
int scale_with_map;
int pitch_with_map;
float camera_to_center_distance;
float aspect_ratio;
float pad0, pad1, pad3;
};
struct VertexStage {
float2 a_pos [[attribute(0)]];
float2 a_tex [[attribute(1)]];
};
struct FragmentStage {
float4 position [[position, invariant]];
half2 tex;
};
float2 rotateVec2(float2 v, float angle) {
float cosA = cos(angle);
float sinA = sin(angle);
return float2(v.x * cosA - v.y * sinA, v.x * sinA + v.y * cosA);
}
float2 ellipseRotateVec2(float2 v, float angle, float radiusRatio /* A/B */) {
float cosA = cos(angle);
float sinA = sin(angle);
float invRatio = 1.0 / radiusRatio;
return float2(v.x * cosA - radiusRatio * v.y * sinA, invRatio * v.x * sinA + v.y * cosA);
}
FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]],
device const CustomSymbolIconDrawableUBO& drawable [[buffer(2)]],
device const CustomSymbolIconParametersUBO& parameters [[buffer(3)]]) {
const float2 extrude = glMod(float2(vertx.a_pos), 2.0) * 2.0 - 1.0;
const float2 anchor = (parameters.anchor - float2(0.5, 0.5)) * 2.0;
const float2 center = floor(float2(vertx.a_pos) * 0.5);
const float angle = radians(-parameters.angle_degrees);
float2 corner = extrude - anchor;
float4 position;
if (parameters.pitch_with_map) {
if (parameters.scale_with_map) {
corner *= parameters.extrude_scale;
} else {
float4 projected_center = drawable.matrix * float4(center, 0, 1);
corner *= parameters.extrude_scale * (projected_center.w / parameters.camera_to_center_distance);
}
corner = center + rotateVec2(corner, angle);
position = drawable.matrix * float4(corner, 0, 1);
} else {
position = drawable.matrix * float4(center, 0, 1);
const float factor = parameters.scale_with_map ? parameters.camera_to_center_distance : position.w;
position.xy += ellipseRotateVec2(corner * parameters.extrude_scale * factor, angle, parameters.aspect_ratio);
}
return {
.position = position,
.tex = half2(vertx.a_tex)
};
}
half4 fragment fragmentMain(FragmentStage in [[stage_in]],
texture2d<float, access::sample> image [[texture(0)]],
sampler image_sampler [[sampler(0)]]) {
#if defined(OVERDRAW_INSPECTOR)
return half4(1.0);
#endif
return half4(image.sample(image_sampler, float2(in.tex)));
}
)";
};

} // namespace shaders
} // namespace mbgl
8 changes: 8 additions & 0 deletions include/mbgl/shaders/shader_defines.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <mbgl/shaders/background_layer_ubo.hpp>
#include <mbgl/shaders/circle_layer_ubo.hpp>
#include <mbgl/shaders/collision_layer_ubo.hpp>
#include <mbgl/shaders/custom_drawable_layer_ubo.hpp>
#include <mbgl/shaders/debug_layer_ubo.hpp>
#include <mbgl/shaders/fill_layer_ubo.hpp>
#include <mbgl/shaders/fill_extrusion_layer_ubo.hpp>
Expand All @@ -22,6 +23,7 @@ namespace shaders {
static constexpr auto maxUBOCountPerShader = std::max({static_cast<size_t>(backgroundUBOCount),
static_cast<size_t>(circleUBOCount),
static_cast<size_t>(collisionUBOCount),
static_cast<size_t>(customDrawableUBOCount),
static_cast<size_t>(debugUBOCount),
static_cast<size_t>(fillUBOCount),
static_cast<size_t>(fillOutlineUBOCount),
Expand Down Expand Up @@ -53,6 +55,11 @@ enum {
collisionTextureCount
};

enum {
idCustomSymbolIconTexture,
customSymbolIconTextureCount
};

enum {
idDebugOverlayTexture,
debugTextureCount
Expand Down Expand Up @@ -99,6 +106,7 @@ enum {
static constexpr auto maxTextureCountPerShader = std::max({static_cast<size_t>(backgroundTextureCount),
static_cast<size_t>(circleTextureCount),
static_cast<size_t>(collisionTextureCount),
static_cast<size_t>(customSymbolIconTextureCount),
static_cast<size_t>(debugTextureCount),
static_cast<size_t>(fillTextureCount),
static_cast<size_t>(fillExtrusionTextureCount),
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/shaders/shader_manifest.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <mbgl/shaders/gl/drawable_symbol_icon.hpp>
#include <mbgl/shaders/gl/drawable_symbol_sdf.hpp>
#include <mbgl/shaders/gl/drawable_symbol_text_and_icon.hpp>
#include <mbgl/shaders/gl/drawable_custom_symbol_icon.hpp>
#include <mbgl/shaders/gl/prelude.hpp>
#include <mbgl/shaders/gl/background.hpp>
#include <mbgl/shaders/gl/background_pattern.hpp>
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/shaders/shader_source.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ enum class BuiltIn {
SymbolIconShader,
SymbolSDFIconShader,
SymbolTextAndIconShader,
CustomSymbolIconShader,
Prelude,
BackgroundProgram,
BackgroundPatternProgram,
Expand Down
Loading

0 comments on commit d6db72e

Please sign in to comment.