diff --git a/CMakeLists.txt b/CMakeLists.txt index 812c66458f2..ca99779658a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1035,6 +1035,7 @@ if(MLN_WITH_OPENGL) ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_circle.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_collision_box.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_collision_circle.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_custom_geometry.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_custom_symbol_icon.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_debug.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill.hpp @@ -1217,6 +1218,7 @@ if(MLN_WITH_METAL) ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/clipping_mask.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/common.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/collision.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/custom_geometry.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 @@ -1226,6 +1228,7 @@ if(MLN_WITH_METAL) ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/hillshade.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/hillshade_prepare.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/line.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/location_indicator.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/raster.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_group.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program.hpp @@ -1256,6 +1259,7 @@ if(MLN_WITH_METAL) ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/circle.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/collision.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/clipping_mask.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/custom_geometry.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 @@ -1265,6 +1269,7 @@ if(MLN_WITH_METAL) ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/hillshade.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/hillshade_prepare.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/line.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/location_indicator.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/raster.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/symbol.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/mtl/widevector.cpp @@ -1314,6 +1319,7 @@ if(MLN_WITH_VULKAN) ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/clipping_mask.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/collision.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/common.hpp + ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/custom_geometry.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/fill.hpp ${PROJECT_SOURCE_DIR}/include/mbgl/shaders/vulkan/fill_extrusion.hpp @@ -1354,6 +1360,7 @@ if(MLN_WITH_VULKAN) ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/circle.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/clipping_mask.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/collision.cpp + ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/custom_geometry.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/custom_symbol_icon.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/debug.cpp ${PROJECT_SOURCE_DIR}/src/mbgl/shaders/vulkan/fill.cpp diff --git a/MODULE.bazel b/MODULE.bazel index 663b54e130a..bb68cc766b9 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -54,6 +54,14 @@ http_archive( urls = ["https://github.com/glfw/glfw/releases/download/3.4/glfw-3.4.zip"], ) +new_git_repository = use_repo_rule("@bazel_tools//tools/build_defs/repo:git.bzl", "new_git_repository") + +new_git_repository( + name = "tinyobjloader", + remote = "https://github.com/tinyobjloader/tinyobjloader.git", + branch = "release", +) + darwin_config = use_repo_rule("//platform/darwin:bazel/darwin_config_repository_rule.bzl", "darwin_config") darwin_config( diff --git a/bazel/core.bzl b/bazel/core.bzl index 75a30b5b152..d5ffae905f0 100644 --- a/bazel/core.bzl +++ b/bazel/core.bzl @@ -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_geometry.hpp", "include/mbgl/shaders/gl/drawable_custom_symbol_icon.hpp", "include/mbgl/shaders/gl/drawable_debug.hpp", "include/mbgl/shaders/gl/drawable_fill.hpp", @@ -1010,6 +1011,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_geometry_ubo.hpp", "include/mbgl/shaders/custom_drawable_layer_ubo.hpp", "include/mbgl/shaders/debug_layer_ubo.hpp", "include/mbgl/shaders/fill_layer_ubo.hpp", @@ -1081,6 +1083,7 @@ MLN_DRAWABLES_MTL_SOURCE = [ "src/mbgl/shaders/mtl/circle.cpp", "src/mbgl/shaders/mtl/collision.cpp", "src/mbgl/shaders/mtl/clipping_mask.cpp", + "src/mbgl/shaders/mtl/custom_geometry.cpp", "src/mbgl/shaders/mtl/custom_symbol_icon.cpp", "src/mbgl/shaders/mtl/debug.cpp", "src/mbgl/shaders/mtl/fill.cpp", @@ -1090,6 +1093,7 @@ MLN_DRAWABLES_MTL_SOURCE = [ "src/mbgl/shaders/mtl/hillshade.cpp", "src/mbgl/shaders/mtl/hillshade_prepare.cpp", "src/mbgl/shaders/mtl/line.cpp", + "src/mbgl/shaders/mtl/location_indicator.cpp", "src/mbgl/shaders/mtl/raster.cpp", "src/mbgl/shaders/mtl/symbol.cpp", "src/mbgl/shaders/mtl/widevector.cpp", @@ -1120,6 +1124,7 @@ MLN_DRAWABLES_MTL_HEADERS = [ "include/mbgl/shaders/mtl/clipping_mask.hpp", "include/mbgl/shaders/mtl/collision.hpp", "include/mbgl/shaders/mtl/common.hpp", + "include/mbgl/shaders/mtl/custom_geometry.hpp", "include/mbgl/shaders/mtl/custom_symbol_icon.hpp", "include/mbgl/shaders/mtl/debug.hpp", "include/mbgl/shaders/mtl/fill.hpp", @@ -1129,6 +1134,7 @@ MLN_DRAWABLES_MTL_HEADERS = [ "include/mbgl/shaders/mtl/hillshade.hpp", "include/mbgl/shaders/mtl/hillshade_prepare.hpp", "include/mbgl/shaders/mtl/line.hpp", + "include/mbgl/shaders/mtl/location_indicator.hpp", "include/mbgl/shaders/mtl/raster.hpp", "include/mbgl/shaders/mtl/shader_group.hpp", "include/mbgl/shaders/mtl/shader_program.hpp", diff --git a/include/mbgl/gfx/context.hpp b/include/mbgl/gfx/context.hpp index abfdd383e95..e55b141db22 100644 --- a/include/mbgl/gfx/context.hpp +++ b/include/mbgl/gfx/context.hpp @@ -130,6 +130,8 @@ class Context { bool persistent = false, bool ssbo = false) = 0; + virtual UniqueUniformBufferArray createLayerUniformBufferArray() = 0; + /// Get the generic shader with the specified name virtual gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) = 0; diff --git a/include/mbgl/gfx/uniform_buffer.hpp b/include/mbgl/gfx/uniform_buffer.hpp index 390459c5748..ea803a319a8 100644 --- a/include/mbgl/gfx/uniform_buffer.hpp +++ b/include/mbgl/gfx/uniform_buffer.hpp @@ -12,6 +12,7 @@ namespace gfx { class Context; class UniformBuffer; class UniformBufferArray; +class RenderPass; using UniformBufferPtr = std::shared_ptr; using UniqueUniformBuffer = std::unique_ptr; @@ -75,6 +76,8 @@ class UniformBufferArray { createOrUpdate(id, data, sizeof(T), context, persistent); } + virtual void bind(gfx::RenderPass& renderPass) = 0; + UniformBufferArray& operator=(UniformBufferArray&&); UniformBufferArray& operator=(const UniformBufferArray&); diff --git a/include/mbgl/gl/uniform_buffer_gl.hpp b/include/mbgl/gl/uniform_buffer_gl.hpp index b186715e9c5..3a205cfbeb8 100644 --- a/include/mbgl/gl/uniform_buffer_gl.hpp +++ b/include/mbgl/gl/uniform_buffer_gl.hpp @@ -62,6 +62,8 @@ class UniformBufferArrayGL final : public gfx::UniformBufferArray { void bind() const; void unbind() const; + void bind(gfx::RenderPass&) override { bind(); } + private: std::unique_ptr copy(const gfx::UniformBuffer& uniformBuffers) override { return std::make_unique(static_cast(uniformBuffers).clone()); diff --git a/include/mbgl/mtl/context.hpp b/include/mbgl/mtl/context.hpp index 41c354b4dde..46c6e2c08e0 100644 --- a/include/mbgl/mtl/context.hpp +++ b/include/mbgl/mtl/context.hpp @@ -41,6 +41,7 @@ class VertexBufferResource; using UniqueShaderProgram = std::unique_ptr; using UniqueVertexBufferResource = std::unique_ptr; +using UniqueUniformBufferArray = std::unique_ptr; class Context final : public gfx::Context { public: @@ -88,6 +89,8 @@ class Context final : public gfx::Context { bool persistent = false, bool ssbo = false) override; + UniqueUniformBufferArray createLayerUniformBufferArray() override; + gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override; TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override; diff --git a/include/mbgl/mtl/index_buffer_resource.hpp b/include/mbgl/mtl/index_buffer_resource.hpp index 703a561aa2a..248d9fdd5eb 100644 --- a/include/mbgl/mtl/index_buffer_resource.hpp +++ b/include/mbgl/mtl/index_buffer_resource.hpp @@ -8,7 +8,6 @@ namespace mtl { class IndexBufferResource : public gfx::IndexBufferResource { public: - IndexBufferResource() noexcept = delete; IndexBufferResource(BufferResource&&) noexcept; IndexBufferResource(IndexBufferResource&& other) noexcept : buffer(std::move(other.buffer)) {} diff --git a/include/mbgl/mtl/uniform_buffer.hpp b/include/mbgl/mtl/uniform_buffer.hpp index 9352bfedc47..0e0f95f9ebb 100644 --- a/include/mbgl/mtl/uniform_buffer.hpp +++ b/include/mbgl/mtl/uniform_buffer.hpp @@ -42,8 +42,8 @@ class UniformBufferArray final : public gfx::UniformBufferArray { return *this; } - void bind(RenderPass& renderPass) const noexcept; - void unbind(RenderPass&) const noexcept {} + void bindMtl(RenderPass&) const noexcept; + void bind(gfx::RenderPass& renderPass) override; private: gfx::UniqueUniformBuffer copy(const gfx::UniformBuffer& buffer) override { diff --git a/include/mbgl/mtl/vertex_buffer_resource.hpp b/include/mbgl/mtl/vertex_buffer_resource.hpp index a52d718e757..62d5f47f0b8 100644 --- a/include/mbgl/mtl/vertex_buffer_resource.hpp +++ b/include/mbgl/mtl/vertex_buffer_resource.hpp @@ -10,7 +10,6 @@ namespace mtl { class VertexBufferResource : public gfx::VertexBufferResource { public: - VertexBufferResource() noexcept = delete; VertexBufferResource(BufferResource&&) noexcept; VertexBufferResource(VertexBufferResource&& other) noexcept : buffer(std::move(other.buffer)) {} diff --git a/include/mbgl/shaders/custom_geometry_ubo.hpp b/include/mbgl/shaders/custom_geometry_ubo.hpp new file mode 100644 index 00000000000..50a9f052d13 --- /dev/null +++ b/include/mbgl/shaders/custom_geometry_ubo.hpp @@ -0,0 +1,16 @@ +#pragma once + +#include + +namespace mbgl { +namespace shaders { + +struct alignas(16) CustomGeometryDrawableUBO { + /* 0 */ std::array matrix; + /* 64 */ Color color; + /* 80 */ +}; +static_assert(sizeof(CustomGeometryDrawableUBO) == 5 * 16); + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/gl/drawable_custom_geometry.hpp b/include/mbgl/shaders/gl/drawable_custom_geometry.hpp new file mode 100644 index 00000000000..cd4ad682051 --- /dev/null +++ b/include/mbgl/shaders/gl/drawable_custom_geometry.hpp @@ -0,0 +1,39 @@ +// Generated code, do not modify this file! +#pragma once +#include + +namespace mbgl { +namespace shaders { + +template <> +struct ShaderSource { + static constexpr const char* name = "CustomGeometryShader"; + static constexpr const char* vertex = R"(layout (std140) uniform CustomGeometryDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec3 a_pos; +layout(location = 1) in vec2 a_uv; + +out vec2 frag_uv; + +void main() { + frag_uv = a_uv; + gl_Position = u_matrix * vec4(a_pos, 1.0); +})"; + static constexpr const char* fragment = R"(layout (std140) uniform CustomGeometryDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +in vec2 frag_uv; +uniform sampler2D u_image; + +void main() { + fragColor = texture(u_image, frag_uv) * u_color; +})"; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/gl/drawable_location_indicator.hpp b/include/mbgl/shaders/gl/drawable_location_indicator.hpp index af1c0d5c465..5d0b261f9c5 100644 --- a/include/mbgl/shaders/gl/drawable_location_indicator.hpp +++ b/include/mbgl/shaders/gl/drawable_location_indicator.hpp @@ -8,8 +8,24 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "LocationIndicatorShader"; - static constexpr const char* vertex = R"()"; - static constexpr const char* fragment = R"()"; + static constexpr const char* vertex = R"(layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec2 a_pos; + +void main() { + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); +})"; + static constexpr const char* fragment = R"(layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +void main() { + fragColor = u_color; +})"; }; } // namespace shaders diff --git a/include/mbgl/shaders/gl/drawable_location_indicator_textured.hpp b/include/mbgl/shaders/gl/drawable_location_indicator_textured.hpp index cc26f8711af..2993936c4ba 100644 --- a/include/mbgl/shaders/gl/drawable_location_indicator_textured.hpp +++ b/include/mbgl/shaders/gl/drawable_location_indicator_textured.hpp @@ -8,8 +8,31 @@ namespace shaders { template <> struct ShaderSource { static constexpr const char* name = "LocationIndicatorTexturedShader"; - static constexpr const char* vertex = R"()"; - static constexpr const char* fragment = R"()"; + static constexpr const char* vertex = R"(layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec2 a_pos; +layout(location = 1) in vec2 a_uv; + +out vec2 frag_uv; + +void main() { + frag_uv = a_uv; + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); +})"; + static constexpr const char* fragment = R"(layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +in vec2 frag_uv; +uniform sampler2D u_image; + +void main() { + fragColor = texture(u_image, frag_uv); +})"; }; } // namespace shaders diff --git a/include/mbgl/shaders/gl/shader_info.hpp b/include/mbgl/shaders/gl/shader_info.hpp index 6447924f327..7d9228a2dd3 100644 --- a/include/mbgl/shaders/gl/shader_info.hpp +++ b/include/mbgl/shaders/gl/shader_info.hpp @@ -65,6 +65,13 @@ struct ShaderInfo { static const std::vector textures; }; +template <> +struct ShaderInfo { + static const std::vector attributes; + static const std::vector uniformBlocks; + static const std::vector textures; +}; + template <> struct ShaderInfo { static const std::vector attributes; @@ -184,6 +191,20 @@ struct ShaderInfo { static const std::vector textures; }; +template <> +struct ShaderInfo { + static const std::vector attributes; + static const std::vector uniformBlocks; + static const std::vector textures; +}; + +template <> +struct ShaderInfo { + static const std::vector attributes; + static const std::vector uniformBlocks; + static const std::vector textures; +}; + template <> struct ShaderInfo { static const std::vector attributes; diff --git a/include/mbgl/shaders/mtl/custom_geometry.hpp b/include/mbgl/shaders/mtl/custom_geometry.hpp new file mode 100644 index 00000000000..c1947359743 --- /dev/null +++ b/include/mbgl/shaders/mtl/custom_geometry.hpp @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace shaders { + +constexpr auto customGeometryShaderPrelude = R"( + +enum { + idCustomGeometryDrawableUBO = drawableReservedUBOCount, + customGeometryUBOCount +}; + +struct alignas(16) CustomGeometryDrawableUBO { + /* 0 */ float4x4 matrix; + /* 64 */ float4 color; + /* 80 */ +}; +static_assert(sizeof(CustomGeometryDrawableUBO) == 5 * 16, "wrong size"); + +)"; + +template <> +struct ShaderSource { + static constexpr auto name = "CustomGeometryShader"; + static constexpr auto vertexMainFunction = "vertexMain"; + static constexpr auto fragmentMainFunction = "fragmentMain"; + + static const std::array attributes; + static constexpr std::array instanceAttributes{}; + static const std::array textures; + + static constexpr auto prelude = customGeometryShaderPrelude; + static constexpr auto source = R"( + +struct VertexStage { + float3 position [[attribute(customGeometryUBOCount + 0)]]; + float2 uv [[attribute(customGeometryUBOCount + 1)]]; +}; + +struct FragmentStage { + float4 position [[position, invariant]]; + float2 uv; +}; + +FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]], + device const CustomGeometryDrawableUBO& drawable [[buffer(idCustomGeometryDrawableUBO)]]) { + + return { + .position = drawable.matrix * float4(vertx.position, 1.0), + .uv = vertx.uv + }; +} + +half4 fragment fragmentMain(FragmentStage in [[stage_in]], + device const CustomGeometryDrawableUBO& drawable [[buffer(idCustomGeometryDrawableUBO)]], + texture2d colorTexture [[texture(0)]]) { + constexpr sampler sampler2d(coord::normalized, filter::linear); + const float4 color = colorTexture.sample(sampler2d, in.uv) * drawable.color; + + return half4(color); +} +)"; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/mtl/location_indicator.hpp b/include/mbgl/shaders/mtl/location_indicator.hpp new file mode 100644 index 00000000000..93d8d5ff891 --- /dev/null +++ b/include/mbgl/shaders/mtl/location_indicator.hpp @@ -0,0 +1,107 @@ +#pragma once + +#include +#include +#include + +namespace mbgl { +namespace shaders { + +constexpr auto locationIndicatorShaderPrelude = R"( + +enum { + idLocationIndicatorUBO = drawableReservedUBOCount, + locationIndicatorUBOCount +}; + +struct alignas(16) LocationIndicatorDrawableUBO { + /* 0 */ float4x4 matrix; + /* 64 */ float4 color; + /* 80 */ +}; +static_assert(sizeof(LocationIndicatorDrawableUBO) == 5 * 16, "wrong size"); + +)"; + +template <> +struct ShaderSource { + static constexpr auto name = "LocationIndicatorShader"; + static constexpr auto vertexMainFunction = "vertexMain"; + static constexpr auto fragmentMainFunction = "fragmentMain"; + + static const std::array attributes; + static constexpr std::array instanceAttributes{}; + static constexpr std::array textures{}; + + static constexpr auto prelude = locationIndicatorShaderPrelude; + static constexpr auto source = R"( + +struct VertexStage { + float2 position [[attribute(locationIndicatorUBOCount + 0)]]; +}; + +struct FragmentStage { + float4 position [[position, invariant]]; +}; + +FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]], + device const LocationIndicatorDrawableUBO& drawable [[buffer(idLocationIndicatorUBO)]]) { + + return { + .position = drawable.matrix * float4(vertx.position, 1.0) + }; +} + +half4 fragment fragmentMain(FragmentStage in [[stage_in]], + device const LocationIndicatorDrawableUBO& drawable [[buffer(idLocationIndicatorUBO)]]) { + return half4(drawable.color); +} +)"; +}; + +template <> +struct ShaderSource { + static constexpr auto name = "LocationIndicatorTexturedShader"; + static constexpr auto vertexMainFunction = "vertexMain"; + static constexpr auto fragmentMainFunction = "fragmentMain"; + + static const std::array attributes; + static constexpr std::array instanceAttributes{}; + static const std::array textures; + + static constexpr auto prelude = locationIndicatorShaderPrelude; + static constexpr auto source = R"( + +struct VertexStage { + float2 position [[attribute(locationIndicatorUBOCount + 0)]]; + float2 uv [[attribute(locationIndicatorUBOCount + 1)]]; +}; + +struct FragmentStage { + float4 position [[position, invariant]]; + float2 uv; +}; + +FragmentStage vertex vertexMain(thread const VertexStage vertx [[stage_in]], + device const LocationIndicatorDrawableUBO& drawable [[buffer(idLocationIndicatorUBO)]]) { + + return { + .position = drawable.matrix * float4(vertx.position, 1.0), + .uv = vertx.uv + }; +} + +half4 fragment fragmentMain(FragmentStage in [[stage_in]], + device const LocationIndicatorDrawableUBO& drawable [[buffer(idLocationIndicatorUBO)]], + texture2d colorTexture [[texture(0)]]) { + + constexpr sampler sampler2d(coord::normalized, filter::linear); + const float4 color = colorTexture.sample(sampler2d, in.uv); + + return half4(color); +} +)"; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/shader_defines.hpp b/include/mbgl/shaders/shader_defines.hpp index 557921146e2..daee8ca31a6 100644 --- a/include/mbgl/shaders/shader_defines.hpp +++ b/include/mbgl/shaders/shader_defines.hpp @@ -30,6 +30,11 @@ enum { collisionDrawableUBOCount }; +enum { + idCustomGeometryDrawableUBO = drawableReservedUBOCount, + customGeometryDrawableUBOCount +}; + enum { idCustomSymbolDrawableUBO = idDrawableReservedVertexOnlyUBO, customSymbolDrawableUBOCount = drawableReservedUBOCount @@ -101,26 +106,27 @@ enum { wideVectorDrawableUBOCount }; -static constexpr auto layerSSBOStartId = globalUBOCount; -static constexpr auto layerUBOStartId = std::max({static_cast(backgroundDrawableUBOCount), - static_cast(circleDrawableUBOCount), - static_cast(clippingMaskDrawableUBOCount), - static_cast(collisionDrawableUBOCount), - static_cast(customSymbolDrawableUBOCount), - static_cast(debugDrawableUBOCount), - static_cast(fillDrawableUBOCount), - static_cast(fillExtrusionDrawableUBOCount), - static_cast(heatmapDrawableUBOCount), - static_cast(heatmapTextureDrawableUBOCount), - static_cast(hillshadeDrawableUBOCount), - static_cast(hillshadePrepareDrawableUBOCount), - static_cast(lineDrawableUBOCount), - static_cast(locationIndicatorDrawableUBOCount), - static_cast(rasterDrawableUBOCount), - static_cast(symbolDrawableUBOCount), - static_cast(wideVectorDrawableUBOCount)}); - -static constexpr auto maxUBOCountPerDrawable = layerUBOStartId - globalUBOCount; +static constexpr uint32_t layerSSBOStartId = globalUBOCount; +static constexpr uint32_t layerUBOStartId = std::max({static_cast(backgroundDrawableUBOCount), + static_cast(circleDrawableUBOCount), + static_cast(clippingMaskDrawableUBOCount), + static_cast(collisionDrawableUBOCount), + static_cast(customGeometryDrawableUBOCount), + static_cast(customSymbolDrawableUBOCount), + static_cast(debugDrawableUBOCount), + static_cast(fillDrawableUBOCount), + static_cast(fillExtrusionDrawableUBOCount), + static_cast(heatmapDrawableUBOCount), + static_cast(heatmapTextureDrawableUBOCount), + static_cast(hillshadeDrawableUBOCount), + static_cast(hillshadePrepareDrawableUBOCount), + static_cast(lineDrawableUBOCount), + static_cast(locationIndicatorDrawableUBOCount), + static_cast(rasterDrawableUBOCount), + static_cast(symbolDrawableUBOCount), + static_cast(wideVectorDrawableUBOCount)}); + +static constexpr uint32_t maxUBOCountPerDrawable = layerUBOStartId - globalUBOCount; // layer UBOs @@ -148,6 +154,10 @@ enum { collisionUBOCount = getLayerStartValue(collisionDrawableUBOCount) }; +enum { + customGeometryUBOCount = getLayerStartValue(customGeometryDrawableUBOCount) +}; + enum { customSymbolUBOCount = getLayerStartValue(customSymbolDrawableUBOCount) }; @@ -211,26 +221,26 @@ enum { #undef getLayerStartValue -static constexpr auto maxUBOCountPerShader = std::max({static_cast(backgroundUBOCount), - static_cast(circleUBOCount), - static_cast(clippingMaskUBOCount), - static_cast(collisionUBOCount), - static_cast(customSymbolUBOCount), - static_cast(debugUBOCount), - static_cast(fillUBOCount), - static_cast(fillExtrusionUBOCount), - static_cast(heatmapUBOCount), - static_cast(heatmapTextureUBOCount), - static_cast(hillshadeUBOCount), - static_cast(hillshadePrepareUBOCount), - static_cast(lineUBOCount), - static_cast(locationIndicatorUBOCount), - static_cast(rasterUBOCount), - static_cast(symbolUBOCount), - static_cast(wideVectorUBOCount)}); - -static constexpr auto maxSSBOCountPerLayer = maxUBOCountPerDrawable; -static constexpr auto maxUBOCountPerLayer = maxUBOCountPerShader - layerUBOStartId; +static constexpr uint32_t maxUBOCountPerShader = std::max({static_cast(backgroundUBOCount), + static_cast(circleUBOCount), + static_cast(clippingMaskUBOCount), + static_cast(collisionUBOCount), + static_cast(customSymbolUBOCount), + static_cast(debugUBOCount), + static_cast(fillUBOCount), + static_cast(fillExtrusionUBOCount), + static_cast(heatmapUBOCount), + static_cast(heatmapTextureUBOCount), + static_cast(hillshadeUBOCount), + static_cast(hillshadePrepareUBOCount), + static_cast(lineUBOCount), + static_cast(locationIndicatorUBOCount), + static_cast(rasterUBOCount), + static_cast(symbolUBOCount), + static_cast(wideVectorUBOCount)}); + +static constexpr uint32_t maxSSBOCountPerLayer = maxUBOCountPerDrawable; +static constexpr uint32_t maxUBOCountPerLayer = maxUBOCountPerShader - layerUBOStartId; // Texture defines enum { @@ -251,8 +261,8 @@ enum { }; enum { - idCommonTexture, - commonTextureCount + idCustomGeometryTexture, + customGeometryTextureCount }; enum { @@ -286,6 +296,11 @@ enum { hillshadeTextureCount }; +enum { + idLocationIndicatorTexture, + locationIndicatorTextureCount +}; + enum { idLineImageTexture, lineTextureCount @@ -303,20 +318,21 @@ enum { symbolTextureCount }; -static constexpr auto maxTextureCountPerShader = std::max({static_cast(backgroundTextureCount), - static_cast(circleTextureCount), - static_cast(clippingMaskTextureCount), - static_cast(collisionTextureCount), - static_cast(commonTextureCount), - static_cast(customSymbolTextureCount), - static_cast(debugTextureCount), - static_cast(fillTextureCount), - static_cast(fillExtrusionTextureCount), - static_cast(heatmapTextureCount), - static_cast(hillshadeTextureCount), - static_cast(lineTextureCount), - static_cast(rasterTextureCount), - static_cast(symbolTextureCount)}); +static constexpr uint32_t maxTextureCountPerShader = std::max({static_cast(backgroundTextureCount), + static_cast(circleTextureCount), + static_cast(clippingMaskTextureCount), + static_cast(collisionTextureCount), + static_cast(customGeometryTextureCount), + static_cast(customSymbolTextureCount), + static_cast(debugTextureCount), + static_cast(fillTextureCount), + static_cast(fillExtrusionTextureCount), + static_cast(heatmapTextureCount), + static_cast(hillshadeTextureCount), + static_cast(lineTextureCount), + static_cast(locationIndicatorTextureCount), + static_cast(rasterTextureCount), + static_cast(symbolTextureCount)}); // Vertex attribute defines enum { @@ -354,9 +370,9 @@ enum { }; enum { - idCommonPosVertexAttribute, - idCommonTexVertexAttribute, - commonVertexAttributeCount + idCustomGeometryPosVertexAttribute, + idCustomGeometryTexVertexAttribute, + customGeometryVertexAttributeCount }; enum { @@ -431,6 +447,12 @@ enum { lineVertexAttributeCount }; +enum { + idLocationIndicatorPosVertexAttribute, + idLocationIndicatorTexVertexAttribute, + locationIndicatorVertexAttributeCount +}; + enum { idRasterPosVertexAttribute, idRasterTexturePosVertexAttribute, @@ -471,23 +493,24 @@ enum { wideVectorInstanceAttributeCount }; -static constexpr auto maxVertexAttributeCountPerShader = std::max({ - static_cast(backgroundVertexAttributeCount), - static_cast(circleVertexAttributeCount), - static_cast(clippingMaskVertexAttributeCount), - static_cast(collisionVertexAttributeCount), - static_cast(commonVertexAttributeCount), - static_cast(customSymbolVertexAttributeCount), - static_cast(debugVertexAttributeCount), - static_cast(fillVertexAttributeCount), - static_cast(fillExtrusionVertexAttributeCount), - static_cast(heatmapVertexAttributeCount), - static_cast(hillshadeVertexAttributeCount), - static_cast(lineVertexAttributeCount), - static_cast(rasterVertexAttributeCount), - static_cast(symbolVertexAttributeCount), - static_cast(wideVectorAttributeCount), - static_cast(wideVectorInstanceAttributeCount), +static constexpr uint32_t maxVertexAttributeCountPerShader = std::max({ + static_cast(backgroundVertexAttributeCount), + static_cast(circleVertexAttributeCount), + static_cast(clippingMaskVertexAttributeCount), + static_cast(collisionVertexAttributeCount), + static_cast(customGeometryVertexAttributeCount), + static_cast(customSymbolVertexAttributeCount), + static_cast(debugVertexAttributeCount), + static_cast(fillVertexAttributeCount), + static_cast(fillExtrusionVertexAttributeCount), + static_cast(heatmapVertexAttributeCount), + static_cast(hillshadeVertexAttributeCount), + static_cast(lineVertexAttributeCount), + static_cast(locationIndicatorVertexAttributeCount), + static_cast(rasterVertexAttributeCount), + static_cast(symbolVertexAttributeCount), + static_cast(wideVectorAttributeCount), + static_cast(wideVectorInstanceAttributeCount), }); } // namespace shaders diff --git a/include/mbgl/shaders/shader_manifest.hpp b/include/mbgl/shaders/shader_manifest.hpp index 79b6e38ea5c..1f537fae29f 100644 --- a/include/mbgl/shaders/shader_manifest.hpp +++ b/include/mbgl/shaders/shader_manifest.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include diff --git a/include/mbgl/shaders/shader_source.hpp b/include/mbgl/shaders/shader_source.hpp index 167b95647f9..4ae34388e05 100644 --- a/include/mbgl/shaders/shader_source.hpp +++ b/include/mbgl/shaders/shader_source.hpp @@ -14,6 +14,7 @@ enum class BuiltIn { CircleShader, CollisionBoxShader, CollisionCircleShader, + CustomGeometryShader, CustomSymbolIconShader, DebugShader, FillShader, diff --git a/include/mbgl/shaders/vulkan/background.hpp b/include/mbgl/shaders/vulkan/background.hpp index 2fa7df3478d..e4fb28b4df9 100644 --- a/include/mbgl/shaders/vulkan/background.hpp +++ b/include/mbgl/shaders/vulkan/background.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define BACKGROUND_SHADER_COMMON \ - R"( +constexpr auto backgroundShaderPrelude = R"( #define idBackgroundDrawableUBO idDrawableReservedVertexOnlyUBO #define idBackgroundPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = BACKGROUND_SHADER_COMMON R"( + static constexpr auto prelude = backgroundShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -48,7 +48,7 @@ void main() { } )"; - static constexpr auto fragment = BACKGROUND_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) out vec4 out_color; layout(set = LAYER_SET_INDEX, binding = idBackgroundPropsUBO) uniform BackgroundPropsUBO { @@ -79,7 +79,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = BACKGROUND_SHADER_COMMON R"( + static constexpr auto prelude = backgroundShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(push_constant) uniform Constants { @@ -135,7 +136,7 @@ void main() { } )"; - static constexpr auto fragment = BACKGROUND_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_pos_a; layout(location = 1) in vec2 frag_pos_b; diff --git a/include/mbgl/shaders/vulkan/circle.hpp b/include/mbgl/shaders/vulkan/circle.hpp index 9b5e900330e..88633221d6f 100644 --- a/include/mbgl/shaders/vulkan/circle.hpp +++ b/include/mbgl/shaders/vulkan/circle.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define CIRCLE_SHADER_PRELUDE \ - R"( +constexpr auto circleShaderPrelude = R"( #define idCircleDrawableUBO idDrawableReservedVertexOnlyUBO #define idCircleEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = CIRCLE_SHADER_PRELUDE R"( + static constexpr auto prelude = circleShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -204,7 +204,7 @@ void main() { } )"; - static constexpr auto fragment = CIRCLE_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_extrude; layout(location = 1) in float frag_antialiasblur; diff --git a/include/mbgl/shaders/vulkan/clipping_mask.hpp b/include/mbgl/shaders/vulkan/clipping_mask.hpp index 3b3dd7e4408..676e95d9f98 100644 --- a/include/mbgl/shaders/vulkan/clipping_mask.hpp +++ b/include/mbgl/shaders/vulkan/clipping_mask.hpp @@ -20,6 +20,7 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; + static constexpr auto prelude = ""; static constexpr auto vertex = R"( layout(location = 0) in ivec2 position; diff --git a/include/mbgl/shaders/vulkan/collision.hpp b/include/mbgl/shaders/vulkan/collision.hpp index b5bdda8387c..aece0c81d3c 100644 --- a/include/mbgl/shaders/vulkan/collision.hpp +++ b/include/mbgl/shaders/vulkan/collision.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define COLLISION_SHADER_COMMON \ - R"( +constexpr auto collisionShaderPrelude = R"( #define idCollisionDrawableUBO idDrawableReservedVertexOnlyUBO #define idCollisionTilePropsUBO drawableReservedUBOCount -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = COLLISION_SHADER_COMMON R"( + static constexpr auto prelude = collisionShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec2 in_anchor_position; @@ -61,7 +61,7 @@ void main() { } )"; - static constexpr auto fragment = COLLISION_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in float frag_placed; layout(location = 1) in float frag_notUsed; @@ -98,7 +98,8 @@ struct ShaderSource static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = COLLISION_SHADER_COMMON R"( + static constexpr auto prelude = collisionShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec2 in_anchor_position; @@ -143,7 +144,7 @@ void main() { } )"; - static constexpr auto fragment = COLLISION_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in float frag_placed; layout(location = 1) in float frag_notUsed; diff --git a/include/mbgl/shaders/vulkan/custom_geometry.hpp b/include/mbgl/shaders/vulkan/custom_geometry.hpp new file mode 100644 index 00000000000..17cc135b0bb --- /dev/null +++ b/include/mbgl/shaders/vulkan/custom_geometry.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include +#include + +namespace mbgl { +namespace shaders { + +constexpr auto customGeometryShaderPrelude = R"(#define idCustomGeometryDrawableUBO drawableReservedUBOCount)"; + +template <> +struct ShaderSource { + static constexpr const char* name = "CustomGeometryShader"; + + static const std::array attributes; + static constexpr std::array instanceAttributes{}; + static const std::array textures; + + static constexpr auto prelude = customGeometryShaderPrelude; + static constexpr auto vertex = R"( +layout(location = 0) in vec3 in_position; +layout(location = 1) in vec2 in_texcoord; + +layout(set = DRAWABLE_UBO_SET_INDEX, binding = idCustomGeometryDrawableUBO) uniform CustomDrawableDrawableUBO { + mat4 matrix; + vec4 color; +} drawable; + +layout(location = 0) out vec2 frag_uv; + +void main() { + frag_uv = in_texcoord; + + gl_Position = drawable.matrix * vec4(in_position, 1.0); + applySurfaceTransform(); +} +)"; + + static constexpr auto fragment = R"( +layout(location = 0) in vec2 frag_uv; +layout(location = 0) out vec4 out_color; + +layout(set = DRAWABLE_UBO_SET_INDEX, binding = idCustomGeometryDrawableUBO) uniform CustomDrawableDrawableUBO { + mat4 matrix; + vec4 color; +} drawable; + +layout(set = DRAWABLE_IMAGE_SET_INDEX, binding = 0) uniform sampler2D image_sampler; + +void main() { + out_color = texture(image_sampler, frag_uv) * drawable.color; +} +)"; +}; + +} // namespace shaders +} // namespace mbgl diff --git a/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp b/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp index f294035d436..69a4fb9331d 100644 --- a/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp +++ b/include/mbgl/shaders/vulkan/custom_symbol_icon.hpp @@ -6,12 +6,7 @@ namespace mbgl { namespace shaders { -#define CUSTOM_SYMBOL_ICON_SHADER_PRELUDE \ - R"( - -#define idCustomSymbolDrawableUBO idDrawableReservedVertexOnlyUBO - -)" +constexpr auto customSymbolIconShaderPrelude = R"(#define idCustomSymbolDrawableUBO idDrawableReservedVertexOnlyUBO)"; template <> struct ShaderSource { @@ -21,7 +16,8 @@ struct ShaderSource static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = CUSTOM_SYMBOL_ICON_SHADER_PRELUDE R"( + static constexpr auto prelude = customSymbolIconShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in vec2 in_position; layout(location = 1) in vec2 in_tex; @@ -85,7 +81,7 @@ void main() { } )"; - static constexpr auto fragment = CUSTOM_SYMBOL_ICON_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_tex; layout(location = 0) out vec4 out_color; diff --git a/include/mbgl/shaders/vulkan/debug.hpp b/include/mbgl/shaders/vulkan/debug.hpp index 9c36febd777..0725a0524ca 100644 --- a/include/mbgl/shaders/vulkan/debug.hpp +++ b/include/mbgl/shaders/vulkan/debug.hpp @@ -6,12 +6,7 @@ namespace mbgl { namespace shaders { -#define DEBUG_SHADER_PRELUDE \ - R"( - -#define idDebugUBO drawableReservedUBOCount - -)" +constexpr auto debugShaderPrelude = R"(#define idDebugUBO drawableReservedUBOCount)"; template <> struct ShaderSource { @@ -21,7 +16,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = DEBUG_SHADER_PRELUDE R"( + static constexpr auto prelude = debugShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -47,7 +43,7 @@ void main() { } )"; - static constexpr auto fragment = DEBUG_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_uv; layout(location = 0) out vec4 out_color; diff --git a/include/mbgl/shaders/vulkan/fill.hpp b/include/mbgl/shaders/vulkan/fill.hpp index d54c8c27844..2241d74b250 100644 --- a/include/mbgl/shaders/vulkan/fill.hpp +++ b/include/mbgl/shaders/vulkan/fill.hpp @@ -6,14 +6,13 @@ namespace mbgl { namespace shaders { -#define FILL_SHADER_COMMON \ - R"( +constexpr auto fillShaderPrelude = R"( #define idFillDrawableUBO idDrawableReservedVertexOnlyUBO #define idFillTilePropsUBO drawableReservedUBOCount #define idFillEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -23,7 +22,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_SHADER_COMMON R"( + static constexpr auto prelude = fillShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -77,7 +77,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_SHADER_COMMON R"( + static constexpr auto fragment = R"( #if !defined(HAS_UNIFORM_u_color) layout(location = 0) in vec4 frag_color; @@ -125,7 +125,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_SHADER_COMMON R"( + static constexpr auto prelude = fillShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -183,7 +184,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_SHADER_COMMON R"( + static constexpr auto fragment = R"( #if !defined(HAS_UNIFORM_u_outline_color) layout(location = 0) in vec4 frag_color; @@ -240,7 +241,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_SHADER_COMMON R"( + static constexpr auto prelude = fillShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -352,7 +354,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_pos_a; layout(location = 1) in vec2 frag_pos_b; @@ -451,7 +453,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_SHADER_COMMON R"( + static constexpr auto prelude = fillShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -566,7 +569,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_pos_a; layout(location = 1) in vec2 frag_pos_b; @@ -669,7 +672,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_SHADER_COMMON R"( + static constexpr auto prelude = fillShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_pos_normal; layout(location = 1) in uvec4 in_data; @@ -735,7 +739,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in float frag_width2; layout(location = 1) in vec2 frag_normal; diff --git a/include/mbgl/shaders/vulkan/fill_extrusion.hpp b/include/mbgl/shaders/vulkan/fill_extrusion.hpp index 0e6b166d5d6..8a04b99aa8b 100644 --- a/include/mbgl/shaders/vulkan/fill_extrusion.hpp +++ b/include/mbgl/shaders/vulkan/fill_extrusion.hpp @@ -6,14 +6,13 @@ namespace mbgl { namespace shaders { -#define FILL_EXTRUSION_SHADER_COMMON \ - R"( +constexpr auto fillExtrusionShaderPrelude = R"( #define idFillExtrusionDrawableUBO idDrawableReservedVertexOnlyUBO #define idFillExtrusionTilePropsUBO drawableReservedUBOCount #define idFillExtrusionPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -23,7 +22,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_EXTRUSION_SHADER_COMMON R"( + static constexpr auto prelude = fillExtrusionShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec4 in_normal_ed; @@ -151,7 +151,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_EXTRUSION_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in vec4 frag_color; layout(location = 0) out vec4 out_color; @@ -170,7 +170,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = FILL_EXTRUSION_SHADER_COMMON R"( + static constexpr auto prelude = fillExtrusionShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec4 in_normal_ed; @@ -336,7 +337,7 @@ void main() { } )"; - static constexpr auto fragment = FILL_EXTRUSION_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in mediump vec4 frag_lighting; layout(location = 1) in mediump vec2 frag_pos_a; diff --git a/include/mbgl/shaders/vulkan/heatmap.hpp b/include/mbgl/shaders/vulkan/heatmap.hpp index 19418a03b0a..f2235e52b73 100644 --- a/include/mbgl/shaders/vulkan/heatmap.hpp +++ b/include/mbgl/shaders/vulkan/heatmap.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define HEATMAP_SHADER_PRELUDE \ - R"( +constexpr auto heatmapShaderPrelude = R"( #define idHeatmapDrawableUBO idDrawableReservedVertexOnlyUBO #define idHeatmapEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = HEATMAP_SHADER_PRELUDE R"( + static constexpr auto prelude = heatmapShaderPrelude; + static constexpr auto vertex = R"( // Effective "0" in the kernel density texture to adjust the kernel size to; // this empirically chosen number minimizes artifacts on overlapping kernels @@ -117,7 +117,7 @@ void main() { } )"; - static constexpr auto fragment = HEATMAP_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( // Gaussian kernel coefficient: 1 / sqrt(2 * PI) #define GAUSS_COEF 0.3989422804014327 diff --git a/include/mbgl/shaders/vulkan/heatmap_texture.hpp b/include/mbgl/shaders/vulkan/heatmap_texture.hpp index 60c1439e1d6..1ac432dfd1d 100644 --- a/include/mbgl/shaders/vulkan/heatmap_texture.hpp +++ b/include/mbgl/shaders/vulkan/heatmap_texture.hpp @@ -6,12 +6,7 @@ namespace mbgl { namespace shaders { -#define HEATMAP_TEXTURE_SHADER_PRELUDE \ - R"( - -#define idHeatmapTexturePropsUBO layerUBOStartId - -)" +constexpr auto heatmapTextureShaderPrelude = R"(#define idHeatmapTexturePropsUBO layerUBOStartId)"; template <> struct ShaderSource { @@ -21,7 +16,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = HEATMAP_TEXTURE_SHADER_PRELUDE R"( + static constexpr auto prelude = heatmapTextureShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; @@ -44,7 +40,7 @@ void main() { } )"; - static constexpr auto fragment = HEATMAP_TEXTURE_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_position; layout(location = 0) out vec4 out_color; diff --git a/include/mbgl/shaders/vulkan/hillshade.hpp b/include/mbgl/shaders/vulkan/hillshade.hpp index 9a7709a933a..9306762608d 100644 --- a/include/mbgl/shaders/vulkan/hillshade.hpp +++ b/include/mbgl/shaders/vulkan/hillshade.hpp @@ -6,14 +6,13 @@ namespace mbgl { namespace shaders { -#define HILLSHADE_SHADER_PRELUDE \ - R"( +constexpr auto hillshadeShaderPrelude = R"( #define idHillshadeDrawableUBO idDrawableReservedVertexOnlyUBO #define idHillshadeTilePropsUBO idDrawableReservedFragmentOnlyUBO #define idHillshadeEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -23,7 +22,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = HILLSHADE_SHADER_PRELUDE R"( + static constexpr auto prelude = hillshadeShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec2 in_texture_position; @@ -53,7 +53,7 @@ void main() { } )"; - static constexpr auto fragment = HILLSHADE_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_position; layout(location = 0) out vec4 out_color; diff --git a/include/mbgl/shaders/vulkan/hillshade_prepare.hpp b/include/mbgl/shaders/vulkan/hillshade_prepare.hpp index 4b079a07596..a2aa699b421 100644 --- a/include/mbgl/shaders/vulkan/hillshade_prepare.hpp +++ b/include/mbgl/shaders/vulkan/hillshade_prepare.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define HILLSHADE_PREPARE_SHADER_PRELUDE \ - R"( +constexpr auto hillshadePrepareShaderPrelude = R"( #define idHillshadePrepareDrawableUBO idDrawableReservedVertexOnlyUBO #define idHillshadePrepareTilePropsUBO drawableReservedUBOCount -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = HILLSHADE_PREPARE_SHADER_PRELUDE R"( + static constexpr auto prelude = hillshadePrepareShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec2 in_texture_position; @@ -51,7 +51,7 @@ void main() { } )"; - static constexpr auto fragment = HILLSHADE_PREPARE_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_position; layout(location = 0) out vec4 out_color; diff --git a/include/mbgl/shaders/vulkan/line.hpp b/include/mbgl/shaders/vulkan/line.hpp index 852d1eb48e1..480b4d05da3 100644 --- a/include/mbgl/shaders/vulkan/line.hpp +++ b/include/mbgl/shaders/vulkan/line.hpp @@ -6,14 +6,13 @@ namespace mbgl { namespace shaders { -#define LINE_SHADER_COMMON \ - R"( +constexpr auto lineShadePrelude = R"( #define idLineDrawableUBO idDrawableReservedVertexOnlyUBO #define idLineTilePropsUBO idDrawableReservedFragmentOnlyUBO #define idLineEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -23,7 +22,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LINE_SHADER_COMMON R"( + static constexpr auto prelude = lineShadePrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_pos_normal; layout(location = 1) in uvec4 in_data; @@ -182,7 +182,7 @@ void main() { } )"; - static constexpr auto fragment = LINE_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in lowp vec2 frag_normal; layout(location = 1) in lowp vec2 frag_width2; @@ -261,7 +261,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LINE_SHADER_COMMON R"( + static constexpr auto prelude = lineShadePrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_pos_normal; layout(location = 1) in uvec4 in_data; @@ -410,7 +411,7 @@ void main() { } )"; - static constexpr auto fragment = LINE_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in lowp vec2 frag_normal; layout(location = 1) in lowp vec2 frag_width2; @@ -486,7 +487,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LINE_SHADER_COMMON R"( + static constexpr auto prelude = lineShadePrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_pos_normal; layout(location = 1) in uvec4 in_data; @@ -660,7 +662,7 @@ void main() { } )"; - static constexpr auto fragment = LINE_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in lowp vec2 frag_normal; layout(location = 1) in lowp vec2 frag_width2; @@ -802,7 +804,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LINE_SHADER_COMMON R"( + static constexpr auto prelude = lineShadePrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_pos_normal; layout(location = 1) in uvec4 in_data; @@ -987,7 +990,7 @@ void main() { } )"; - static constexpr auto fragment = LINE_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in lowp vec2 frag_normal; layout(location = 1) in lowp vec2 frag_width2; diff --git a/include/mbgl/shaders/vulkan/location_indicator.hpp b/include/mbgl/shaders/vulkan/location_indicator.hpp index a1181fdc9b2..f1f3067370a 100644 --- a/include/mbgl/shaders/vulkan/location_indicator.hpp +++ b/include/mbgl/shaders/vulkan/location_indicator.hpp @@ -6,12 +6,7 @@ namespace mbgl { namespace shaders { -#define LOCATION_INDICATOR_SHADER_PRELUDE \ - R"( - -#define idLocationIndicatorDrawableUBO drawableReservedUBOCount - -)" +constexpr auto locationIndicatorShaderPrelude = R"(#define idLocationIndicatorDrawableUBO drawableReservedUBOCount)"; template <> struct ShaderSource { @@ -21,7 +16,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LOCATION_INDICATOR_SHADER_PRELUDE R"( + static constexpr auto prelude = locationIndicatorShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in vec2 in_position; layout(set = DRAWABLE_UBO_SET_INDEX, binding = idLocationIndicatorDrawableUBO) uniform LocationIndicatorDrawableUBO { @@ -35,7 +31,7 @@ void main() { } )"; - static constexpr auto fragment = LOCATION_INDICATOR_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) out vec4 out_color; layout(set = DRAWABLE_UBO_SET_INDEX, binding = idLocationIndicatorDrawableUBO) uniform LocationIndicatorDrawableUBO { @@ -57,7 +53,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = LOCATION_INDICATOR_SHADER_PRELUDE R"( + static constexpr auto prelude = locationIndicatorShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in vec2 in_position; layout(location = 1) in vec2 in_texcoord; diff --git a/include/mbgl/shaders/vulkan/raster.hpp b/include/mbgl/shaders/vulkan/raster.hpp index 6727ec0dc31..9affa974eb2 100644 --- a/include/mbgl/shaders/vulkan/raster.hpp +++ b/include/mbgl/shaders/vulkan/raster.hpp @@ -3,13 +3,12 @@ #include #include -#define RASTER_SHADER_PRELUDE \ - R"( +constexpr auto rasterShaderPrelude = R"( #define idRasterDrawableUBO idDrawableReservedVertexOnlyUBO #define idRasterEvaluatedPropsUBO layerUBOStartId -)" +)"; namespace mbgl { namespace shaders { @@ -22,7 +21,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = RASTER_SHADER_PRELUDE R"( + static constexpr auto prelude = rasterShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec2 in_position; layout(location = 1) in ivec2 in_texture_position; @@ -73,7 +73,7 @@ void main() { } )"; - static constexpr auto fragment = RASTER_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( layout(location = 0) in vec2 frag_position0; layout(location = 1) in vec2 frag_position1; diff --git a/include/mbgl/shaders/vulkan/shader_group.hpp b/include/mbgl/shaders/vulkan/shader_group.hpp index 67d56d9bc3a..475336502a2 100644 --- a/include/mbgl/shaders/vulkan/shader_group.hpp +++ b/include/mbgl/shaders/vulkan/shader_group.hpp @@ -47,6 +47,7 @@ class ShaderGroup final : public ShaderGroupBase { std::string_view /*firstAttribName*/) override { using ShaderSource = shaders::ShaderSource; constexpr auto& name = ShaderSource::name; + constexpr auto& prelude = ShaderSource::prelude; constexpr auto& vert = ShaderSource::vertex; constexpr auto& frag = ShaderSource::fragment; @@ -60,8 +61,13 @@ class ShaderGroup final : public ShaderGroupBase { DefinesMap additionalDefines; addAdditionalDefines(propertiesAsUniforms, additionalDefines); + const std::string preludeSource(prelude); + const std::string vertexSource = preludeSource + vert; + const std::string fragmentSource = preludeSource + frag; + auto& context = static_cast(gfxContext); - shader = context.createProgram(ShaderID, shaderName, vert, frag, programParameters, additionalDefines); + shader = context.createProgram( + ShaderID, shaderName, vertexSource, fragmentSource, programParameters, additionalDefines); assert(shader); if (!shader || !registerShader(shader, shaderName)) { assert(false); diff --git a/include/mbgl/shaders/vulkan/symbol.hpp b/include/mbgl/shaders/vulkan/symbol.hpp index 09edcf28abc..75be0c266ca 100644 --- a/include/mbgl/shaders/vulkan/symbol.hpp +++ b/include/mbgl/shaders/vulkan/symbol.hpp @@ -6,14 +6,13 @@ namespace mbgl { namespace shaders { -#define SYMBOL_SHADER_COMMON \ - R"( +constexpr auto symbolShaderPrelude = R"( #define idSymbolDrawableUBO idDrawableReservedVertexOnlyUBO #define idSymbolTilePropsUBO idDrawableReservedFragmentOnlyUBO #define idSymbolEvaluatedPropsUBO layerUBOStartId -)" +)"; template <> struct ShaderSource { @@ -23,7 +22,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = SYMBOL_SHADER_COMMON R"( + static constexpr auto prelude = symbolShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec4 in_pos_offset; layout(location = 1) in uvec4 in_data; @@ -144,7 +144,7 @@ void main() { } )"; - static constexpr auto fragment = SYMBOL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in mediump vec2 frag_tex; layout(location = 1) in mediump float frag_opacity; @@ -210,7 +210,8 @@ struct ShaderSource { static constexpr std::array instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = SYMBOL_SHADER_COMMON R"( + static constexpr auto prelude = symbolShaderPrelude; + static constexpr auto vertex = R"( layout(location = 0) in ivec4 in_pos_offset; layout(location = 1) in uvec4 in_data; @@ -386,7 +387,7 @@ void main() { } )"; - static constexpr auto fragment = SYMBOL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in mediump vec2 frag_tex; layout(location = 1) in mediump float frag_fade_opacity; @@ -504,7 +505,8 @@ struct ShaderSource instanceAttributes{}; static const std::array textures; - static constexpr auto vertex = SYMBOL_SHADER_COMMON R"( + static constexpr auto prelude = symbolShaderPrelude; + static constexpr auto vertex = R"( #define SDF 1.0 #define ICON 0.0 @@ -687,7 +689,7 @@ void main() { } )"; - static constexpr auto fragment = SYMBOL_SHADER_COMMON R"( + static constexpr auto fragment = R"( layout(location = 0) in mediump vec2 frag_tex; layout(location = 1) in mediump float frag_fade_opacity; diff --git a/include/mbgl/shaders/vulkan/widevector.hpp b/include/mbgl/shaders/vulkan/widevector.hpp index 7f26c1d58ea..b0e34b7599c 100644 --- a/include/mbgl/shaders/vulkan/widevector.hpp +++ b/include/mbgl/shaders/vulkan/widevector.hpp @@ -6,13 +6,12 @@ namespace mbgl { namespace shaders { -#define WIDEVECTOR_SHADER_PRELUDE \ - R"( +constexpr auto wideVectorShaderPrelude = R"( #define idWideVectorUniformsUBO idDrawableReservedVertexOnlyUBO #define idWideVectorUniformWideVecUBO drawableReservedUBOCount -)" +)"; template <> struct ShaderSource { @@ -22,7 +21,8 @@ struct ShaderSource { static const std::array instanceAttributes; static const std::array textures; - static constexpr auto vertex = WIDEVECTOR_SHADER_PRELUDE R"( + static constexpr auto prelude = wideVectorShaderPrelude; + static constexpr auto vertex = R"( /** Expressions are used to change values like width and opacity over zoom levels. **/ #define WKSExpStops 8 @@ -58,7 +58,7 @@ layout(set = DRAWABLE_UBO_SET_INDEX, binding = idWideVectorUniformWideVecUBO) un float offset; float edge; float texRepeat; - vec4 texOffset; + vec2 texOffset; float miterLimit; int join; int cap; @@ -66,6 +66,17 @@ layout(set = DRAWABLE_UBO_SET_INDEX, binding = idWideVectorUniformWideVecUBO) un float interClipLimit; } wideVec; +// Instance info for the wide vector (new) vertex shader +typedef struct +{ + // Center of the point on the line + vec3 center; + // Color + vec4 color; + // Used to track loops and such + int prev,next; // set to -1 for non-loops +} VertexTriWideVecInstance; + struct IntersectInfo { bool valid; vec2 interPt; @@ -110,16 +121,28 @@ IntersectInfo intersectWideLines(vec2 p0,vec2 p1,vec2 p2, vec2 n0,vec2 n1) return intersectLines(p0 + n0, p1 + n0, p1 + n1, p2 + n1); } +// Used to track what info we have about a center point +struct CenterInfo { + /// Screen coordinates of the line segment endpoint + vec2 screenPos; + /// Length of the segment (in screen coordinates) + float len; + /// Normalized direction of the segment + vec2 nDir; + /// Normalized plane normal, perpendicular to the segment + vec2 norm; +}; + vec3 viewPos(const mat4 &mat, vec3 vec) { const vec4 p = mat * vec4(vec, 1.0); return p.xyz; // / p.w; ? } -float2 screenPos_MVP(const Uniforms &u, float3 viewPos) { - const float4 p4 = float4(viewPos, 1.0); +vec2 screenPos_MVP(const Uniforms &u, vec3 viewPos) { + const vec4 p4 = vec4(viewPos, 1.0); // Use the MVP matrix - const float4 s = u.mvpMatrix * p4; + const vec4 s = u.mvpMatrix * p4; return s.xy / s.w; } @@ -156,7 +179,7 @@ void main() { } )"; - static constexpr auto fragment = WIDEVECTOR_SHADER_PRELUDE R"( + static constexpr auto fragment = R"( // TODO )"; }; diff --git a/include/mbgl/style/layers/custom_drawable_layer.hpp b/include/mbgl/style/layers/custom_drawable_layer.hpp index 7ba5481e88f..ec7c602a71f 100644 --- a/include/mbgl/style/layers/custom_drawable_layer.hpp +++ b/include/mbgl/style/layers/custom_drawable_layer.hpp @@ -35,17 +35,17 @@ class CustomDrawableLayerHost::Interface { public: enum class LineShaderType { Classic, - MetalWideVector + WideVector }; struct LineOptions { gfx::PolylineGeneratorOptions geometry; + float blur = 0.f; float opacity = 1.f; float gapWidth = 0.f; float offset = 0.f; float width = 1.f; - LineShaderType shaderType = LineShaderType::Classic; Color color; }; @@ -58,12 +58,30 @@ class CustomDrawableLayerHost::Interface { Size size; gfx::Texture2DPtr texture; std::array anchor{0.5f, 0.5f}; - std::array, 2> textureCoordinates{{{0, 0}, {1, 1}}}; float angleDegrees{.0f}; bool scaleWithMap{false}; bool pitchWithMap{false}; }; + struct GeometryVertex { + std::array position; + std::array texcoords; + }; + + struct GeometryOptions { + mat4 matrix = matrix::identity4(); + Color color = Color::white(); + gfx::Texture2DPtr texture; + }; + + template + using TweakerCallback = std::function; + + using LineTweakerCallback = TweakerCallback; + using FillTweakerCallback = TweakerCallback; + using SymbolTweakerCallback = TweakerCallback; + using GeometryTweakerCallback = TweakerCallback; + public: /// @brief Construct a new Interface object (internal core use only) Interface(RenderLayer& layer, @@ -109,37 +127,59 @@ class CustomDrawableLayerHost::Interface { */ void setSymbolOptions(const SymbolOptions& options); + /** + * @brief Set the geometry options + * + * @param options + */ + void setGeometryOptions(const GeometryOptions& options); + + void setLineTweakerCallback(LineTweakerCallback&& callback) { lineTweakerCallback = callback; } + void setFillTweakerCallback(FillTweakerCallback&& callback) { fillTweakerCallback = callback; } + void setSymbolTweakerCallback(SymbolTweakerCallback&& callback) { symbolTweakerCallback = callback; } + void setGeometryTweakerCallback(GeometryTweakerCallback&& callback) { geometryTweakerCallback = callback; } + /** * @brief Add a polyline * * @param coordinates in tile range - * @return true if the polyline was added + * @param shaderType + * @return a valid util::SimpleIdentity if the polyline was added */ - bool addPolyline(const GeometryCoordinates& coordinates); + util::SimpleIdentity addPolyline(const GeometryCoordinates& coordinates, + LineShaderType shaderType = LineShaderType::Classic); /** * @brief Add a polyline * * @param coordinates Geographic coordinates - * @return true if the polyline was added + * @param shaderType + * @return a valid util::SimpleIdentity if the poline was added */ - bool addPolyline(const LineString& coordinates); + util::SimpleIdentity addPolyline(const LineString& coordinates, + LineShaderType shaderType = LineShaderType::Classic); /** * @brief Add a multipolygon area fill * * @param geometry a collection of rings with optional holes - * @return true if the fill was added + * @return a valid util::SimpleIdentity if the fill was added */ - bool addFill(const GeometryCollection& geometry); + util::SimpleIdentity addFill(const GeometryCollection& geometry); /** * @brief Add a symbol * * @param point - * @return true if the symbol was added + * @param textureCoordinates (optional mapping) + * @return a valid util::SimpleIdentity if the symbol was added */ - bool addSymbol(const GeometryCoordinate& point); + util::SimpleIdentity addSymbol(const GeometryCoordinate& point, + const std::array, 2>& textureCoordinates = {{{0, 0}, {1, 1}}}); + + util::SimpleIdentity addGeometry(std::shared_ptr> vertices, + std::shared_ptr> indices, + bool is3D); /** * @brief Finish the current drawable building session @@ -147,6 +187,8 @@ class CustomDrawableLayerHost::Interface { */ void finish(); + void removeDrawable(const util::SimpleIdentity& id); + public: RenderLayer& layer; LayerGroupBasePtr& layerGroup; @@ -162,13 +204,15 @@ class CustomDrawableLayerHost::Interface { gfx::ShaderPtr lineShaderWideVector() const; gfx::ShaderPtr fillShaderDefault() const; gfx::ShaderPtr symbolShaderDefault() const; + gfx::ShaderPtr geometryShaderDefault() const; enum class BuilderType { None, LineClassic, LineWideVector, Fill, - Symbol + Symbol, + Geometry }; std::unique_ptr createBuilder(const std::string& name, gfx::ShaderPtr shader) const; @@ -177,13 +221,15 @@ class CustomDrawableLayerHost::Interface { std::unique_ptr builder; std::optional tileID; - gfx::ShaderPtr lineShader; - gfx::ShaderPtr fillShader; - gfx::ShaderPtr symbolShader; - LineOptions lineOptions; FillOptions fillOptions; SymbolOptions symbolOptions; + GeometryOptions geometryOptions; + + LineTweakerCallback lineTweakerCallback; + FillTweakerCallback fillTweakerCallback; + SymbolTweakerCallback symbolTweakerCallback; + GeometryTweakerCallback geometryTweakerCallback; BuilderType builderType{BuilderType::None}; }; diff --git a/include/mbgl/vulkan/context.hpp b/include/mbgl/vulkan/context.hpp index da4a6cd94a1..b9fb8c608fe 100644 --- a/include/mbgl/vulkan/context.hpp +++ b/include/mbgl/vulkan/context.hpp @@ -43,6 +43,7 @@ class Texture2D; using UniqueShaderProgram = std::unique_ptr; using UniqueVertexBufferResource = std::unique_ptr; +using UniqueUniformBufferArray = std::unique_ptr; class Context final : public gfx::Context { public: @@ -79,6 +80,8 @@ class Context final : public gfx::Context { bool persistent, bool ssbo = false) override; + UniqueUniformBufferArray createLayerUniformBufferArray() override; + gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override; TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override; diff --git a/include/mbgl/vulkan/tile_layer_group.hpp b/include/mbgl/vulkan/tile_layer_group.hpp index 079d3af85cf..d3bde6e925f 100644 --- a/include/mbgl/vulkan/tile_layer_group.hpp +++ b/include/mbgl/vulkan/tile_layer_group.hpp @@ -24,8 +24,8 @@ class TileLayerGroup : public mbgl::TileLayerGroup { void upload(gfx::UploadPass&) override; void render(RenderOrchestrator&, PaintParameters&) override; - const gfx::UniformBufferArray& getUniformBuffers() const override { return uniformBuffers; }; - gfx::UniformBufferArray& mutableUniformBuffers() override { return uniformBuffers; }; + const gfx::UniformBufferArray& getUniformBuffers() const override { return uniformBuffers; } + gfx::UniformBufferArray& mutableUniformBuffers() override { return uniformBuffers; } protected: UniformBufferArray uniformBuffers; diff --git a/include/mbgl/vulkan/uniform_buffer.hpp b/include/mbgl/vulkan/uniform_buffer.hpp index d2a1be8d94c..38c867e4682 100644 --- a/include/mbgl/vulkan/uniform_buffer.hpp +++ b/include/mbgl/vulkan/uniform_buffer.hpp @@ -66,6 +66,8 @@ class UniformBufferArray final : public gfx::UniformBufferArray { void createOrUpdate( const size_t id, const void* data, std::size_t size, gfx::Context& context, bool persistent = false) override; + void bind(gfx::RenderPass& renderPass) override; + void bindDescriptorSets(CommandEncoder& encoder); void freeDescriptorSets() { descriptorSet.reset(); } diff --git a/platform/darwin/app/ExampleCustomDrawableStyleLayer.mm b/platform/darwin/app/ExampleCustomDrawableStyleLayer.mm index 453566aeb35..1a9b9a67573 100644 --- a/platform/darwin/app/ExampleCustomDrawableStyleLayer.mm +++ b/platform/darwin/app/ExampleCustomDrawableStyleLayer.mm @@ -58,12 +58,12 @@ void update(Interface& interface) override { constexpr auto numLines = 6; Interface::LineOptions options[numLines] { - {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, /*shaderType=*/{}, /*color=*/Color::red() }, - {/*geometry=*/{}, /*blur=*/4.0f, /*opacity=*/1.0f, /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, /*shaderType=*/{}, /*color=*/Color::blue() }, - {/*geometry=*/{}, /*blur=*/16.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, /*shaderType=*/{}, /*color=*/Color(1.f, 0.5f, 0, 0.5f) }, - {/*geometry=*/{}, /*blur=*/2.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, /*shaderType=*/{}, /*color=*/Color(1.f, 1.f, 0, 0.3f) }, - {/*geometry=*/{}, /*blur=*/0.5f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, /*shaderType=*/{}, /*color=*/Color::black() }, - {/*geometry=*/{}, /*blur=*/24.0f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, /*shaderType=*/{}, /*color=*/Color(1.f, 0, 1.f, 0.2f) }, + {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, /*color=*/Color::red() }, + {/*geometry=*/{}, /*blur=*/4.0f, /*opacity=*/1.0f, /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, /*color=*/Color::blue() }, + {/*geometry=*/{}, /*blur=*/16.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, /*color=*/Color(1.f, 0.5f, 0, 0.5f) }, + {/*geometry=*/{}, /*blur=*/2.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, /*color=*/Color(1.f, 1.f, 0, 0.3f) }, + {/*geometry=*/{}, /*blur=*/0.5f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, /*color=*/Color::black() }, + {/*geometry=*/{}, /*blur=*/24.0f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, /*color=*/Color(1.f, 0, 1.f, 0.2f) }, }; for(auto& opt: options) { opt.geometry.beginCap = style::LineCapType::Butt; @@ -86,7 +86,7 @@ void update(Interface& interface) override { interface.setLineOptions(options[index]); // add polyline - interface.addPolyline(polyline); + interface.addPolyline(polyline, Interface::LineShaderType::Classic); } } @@ -99,12 +99,12 @@ void update(Interface& interface) override { constexpr auto numLines = 6; Interface::LineOptions options[numLines] { - {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color::red() }, - {/*geometry=*/{}, /*blur=*/4.0f, /*opacity=*/1.0f, /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color::blue() }, - {/*geometry=*/{}, /*blur=*/16.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color(1.f, 0.5f, 0, 0.5f) }, - {/*geometry=*/{}, /*blur=*/2.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color(1.f, 1.f, 0, 0.3f) }, - {/*geometry=*/{}, /*blur=*/0.5f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color::black() }, - {/*geometry=*/{}, /*blur=*/24.0f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/Color(1.f, 0, 1.f, 0.2f) }, + {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, /*color=*/Color::red() }, + {/*geometry=*/{}, /*blur=*/4.0f, /*opacity=*/1.0f, /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, /*color=*/Color::blue() }, + {/*geometry=*/{}, /*blur=*/16.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, /*color=*/Color(1.f, 0.5f, 0, 0.5f) }, + {/*geometry=*/{}, /*blur=*/2.0f, /*opacity=*/1.0f, /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, /*color=*/Color(1.f, 1.f, 0, 0.3f) }, + {/*geometry=*/{}, /*blur=*/0.5f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, /*color=*/Color::black() }, + {/*geometry=*/{}, /*blur=*/24.0f, /*opacity=*/0.5f, /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, /*color=*/Color(1.f, 0, 1.f, 0.2f) }, }; for(auto& opt: options) { opt.geometry.beginCap = style::LineCapType::Butt; @@ -128,13 +128,13 @@ void update(Interface& interface) override { interface.setLineOptions(options[index]); // add polyline - interface.addPolyline(polyline); + interface.addPolyline(polyline, Interface::LineShaderType::WideVector); // add clone for(auto &p : polyline) { p.y += 0.05f * extent / numLines; } - interface.addPolyline(polyline); + interface.addPolyline(polyline, Interface::LineShaderType::WideVector); for(auto &p : polyline) { p.y -= 0.05f * extent / numLines; } @@ -193,9 +193,9 @@ void update(Interface& interface) override { options.texture = interface.context.createTexture2D(); options.texture->setImage(image); options.texture->setSamplerConfiguration({gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp}); - options.textureCoordinates = {{{0.0f, 0.08f}, {1.0f, 0.9f}}}; - const float xspan = options.textureCoordinates[1][0] - options.textureCoordinates[0][0]; - const float yspan = options.textureCoordinates[1][1] - options.textureCoordinates[0][1]; + const std::array, 2> textureCoordinates = {{{0.0f, 0.08f}, {1.0f, 0.9f}}}; + const float xspan = textureCoordinates[1][0] - textureCoordinates[0][0]; + const float yspan = textureCoordinates[1][1] - textureCoordinates[0][1]; assert(xspan > 0.0f && yspan > 0.0f); options.size = {static_cast(image->size.width * xspan), static_cast(image->size.height * yspan)}; options.anchor = {0.5f, 0.95f}; @@ -205,7 +205,7 @@ void update(Interface& interface) override { interface.setSymbolOptions(options); // add symbol - interface.addSymbol(position); + interface.addSymbol(position, textureCoordinates); } // add polylines using wide vectors using geographic coordinates @@ -213,7 +213,7 @@ void update(Interface& interface) override { using namespace mbgl; // add polyline with geographic coordinates - Interface::LineOptions options = {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/12.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/{.0f, .0f, .0f, .5f} }; + Interface::LineOptions options = {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/12.0f, /*color=*/{.0f, .0f, .0f, .5f} }; options.geometry.beginCap = style::LineCapType::Square; options.geometry.endCap = style::LineCapType::Square; options.geometry.joinType = style::LineJoinType::Bevel; @@ -235,7 +235,7 @@ void update(Interface& interface) override { // New York {-74.04454331829972, 40.6892168305434}, }; - interface.addPolyline(polyline_geo); + interface.addPolyline(polyline_geo, Interface::LineShaderType::WideVector); } // add polylines using wide vectors in tile coordinates @@ -246,7 +246,7 @@ void update(Interface& interface) override { interface.setTileID({11, 327, 790}); Interface::LineOptions options - {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/7.0f, /*shaderType=*/Interface::LineShaderType::MetalWideVector, /*color=*/{1.0f, 0, 0, .5f} }; + {/*geometry=*/{}, /*blur=*/0.0f, /*opacity=*/1.0f, /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/7.0f, /*color=*/{1.0f, 0, 0, .5f} }; options.geometry.beginCap = style::LineCapType::Round; options.geometry.endCap = style::LineCapType::Round; options.geometry.joinType = style::LineJoinType::Round; @@ -271,8 +271,8 @@ void update(Interface& interface) override { options.geometry.type = FeatureType::Polygon; interface.setLineOptions(options); - interface.addPolyline(polyline_tile[0]); - interface.addPolyline(polyline_tile[1]); + interface.addPolyline(polyline_tile[0], Interface::LineShaderType::WideVector); + interface.addPolyline(polyline_tile[1], Interface::LineShaderType::WideVector); } diff --git a/platform/default/src/mbgl/layermanager/layer_manager.cpp b/platform/default/src/mbgl/layermanager/layer_manager.cpp index 982accce96a..fbbeb429682 100644 --- a/platform/default/src/mbgl/layermanager/layer_manager.cpp +++ b/platform/default/src/mbgl/layermanager/layer_manager.cpp @@ -70,12 +70,9 @@ LayerManagerDefault::LayerManagerDefault() { addLayerType(std::make_unique()); #endif #endif -#if defined(MLN_RENDER_BACKEND_OPENGL) || MLN_RENDER_BACKEND_VULKAN #if !defined(MBGL_LAYER_LOCATION_INDICATOR_DISABLE_ALL) addLayerType(std::make_unique()); #endif -#endif - #if MLN_DRAWABLE_RENDERER #if !defined(MLN_LAYER_CUSTOM_DRAWABLE_DISABLE_ALL) addLayerType(std::make_unique()); diff --git a/platform/glfw/BUILD.bazel b/platform/glfw/BUILD.bazel index e7fb784c058..8e025fd4433 100644 --- a/platform/glfw/BUILD.bazel +++ b/platform/glfw/BUILD.bazel @@ -16,13 +16,6 @@ objc_library( ], ) -filegroup( - name = "mapbox_puck_assets", - srcs = glob([ - "assets/*.png", - ]), -) - cc_binary( name = "glfw_app", srcs = glob( @@ -43,11 +36,9 @@ cc_binary( ], }), copts = CPP_FLAGS + MAPLIBRE_FLAGS, - data = [ - ":mapbox_puck_assets", - ], + data = glob(["assets/*"]), defines = [ - r"MAPBOX_PUCK_ASSETS_PATH=\"./platform/glfw/assets/\"", + r"MLN_ASSETS_PATH=\"assets/\"", ], linkopts = [ "-lglfw", @@ -64,6 +55,7 @@ cc_binary( deps = [ "//:maplibre_lib", "@glfw", + "@tinyobjloader", ] + select({ "@platforms//os:macos": ["metal_backend"], "@platforms//os:linux": ["//platform/linux:impl"], diff --git a/platform/glfw/CMakeLists.txt b/platform/glfw/CMakeLists.txt index 21f044c9d34..387479b94b0 100644 --- a/platform/glfw/CMakeLists.txt +++ b/platform/glfw/CMakeLists.txt @@ -22,11 +22,20 @@ add_executable( ${PROJECT_SOURCE_DIR}/platform/glfw/settings_json.cpp ${PROJECT_SOURCE_DIR}/platform/glfw/test_writer.cpp ${PROJECT_SOURCE_DIR}/platform/default/src/mbgl/map/map_snapshotter.cpp + ${PROJECT_SOURCE_DIR}/platform/glfw/example_custom_drawable_style_layer.cpp +) + + +include(${PROJECT_SOURCE_DIR}/vendor/tinyobjloader.cmake) + +target_link_libraries( + mbgl-glfw + PRIVATE tinyobjloader ) set_property( SOURCE ${PROJECT_SOURCE_DIR}/platform/glfw/glfw_view.cpp - PROPERTY COMPILE_DEFINITIONS MAPBOX_PUCK_ASSETS_PATH=\"${PROJECT_SOURCE_DIR}/platform/glfw/assets/\" + PROPERTY COMPILE_DEFINITIONS MLN_ASSETS_PATH=\"${PROJECT_SOURCE_DIR}/platform/glfw/assets/\" ) if(MLN_WITH_OPENGL) @@ -87,10 +96,12 @@ target_include_directories( PRIVATE ${PROJECT_SOURCE_DIR}/src ) +include(${PROJECT_SOURCE_DIR}/vendor/tinyobjloader.cmake) + # Use target_link_directories when we move away from CMake 3.10. target_link_libraries( mbgl-glfw - PRIVATE $<$:-L${GLFW_LIBRARY_DIRS}> + PRIVATE $<$:-L${GLFW_LIBRARY_DIRS}> tinyobjloader ) if(WIN32) diff --git a/platform/glfw/assets/sphere.obj b/platform/glfw/assets/sphere.obj new file mode 100644 index 00000000000..d876cd13b74 --- /dev/null +++ b/platform/glfw/assets/sphere.obj @@ -0,0 +1,1851 @@ +#### +# +# OBJ File Generated by Meshlab +# +#### +# Object sphere.obj +# +# Vertices: 362 +# Faces: 720 +# +#### +mtllib ./sphere.obj.mtl + +vn -6.205741 0.000000 0.000000 +v -20.000000 0.000000 0.000003 +vn -6.102607 -0.975688 0.603007 +v -19.660480 -3.121540 1.929214 +vn -6.102607 0.975688 -0.603006 +v -19.660480 3.121540 -1.929208 +vn -6.066922 -1.133715 -0.615069 +v -19.562960 -3.719220 -1.859610 +vn -6.066921 0.043121 1.289095 +v -19.562960 0.000000 4.158220 +vn -6.066921 -0.043121 -1.289095 +v -19.562960 0.000000 -4.158220 +vn -6.066923 1.133714 0.615069 +v -19.562960 3.719220 1.859614 +vn -5.831218 -2.132169 0.027703 +v -18.784100 -6.866620 0.085786 +vn -5.831220 -0.978313 1.894677 +v -18.784100 -3.147580 6.103320 +vn -5.831217 0.978316 -1.894682 +v -18.784100 3.147580 -6.103320 +vn -5.831218 2.132169 -0.027704 +v -18.784100 6.866620 -0.085781 +vn -5.787061 -1.162111 -1.880331 +v -18.683439 -3.751860 -6.070620 +vn -5.787063 1.162107 1.880332 +v -18.683439 3.751860 6.070620 +vn -5.788622 -1.911468 1.181353 +v -18.653400 -6.137100 3.792940 +vn -5.788622 1.911468 -1.181355 +v -18.653400 6.137100 -3.792940 +vn -5.665953 -2.237497 -1.166955 +v -18.270901 -7.275940 -3.637960 +vn -5.665956 0.043120 2.523154 +v -18.270901 0.000000 8.134740 +vn -5.665954 -0.043116 -2.523156 +v -18.270901 0.000000 -8.134740 +vn -5.665953 2.237495 1.166955 +v -18.270901 7.275940 3.637980 +vn -5.377474 -3.043252 0.615451 +v -17.320360 -9.806680 1.958150 +vn -5.377474 -1.911461 2.446727 +v -17.320360 -6.137100 7.895660 +vn -5.377477 1.911459 -2.446728 +v -17.320360 6.137100 -7.895640 +vn -5.377474 3.043252 -0.615450 +v -17.320360 9.806680 -1.958144 +vn -5.291559 -3.208326 -0.513324 +v -17.039619 -10.336121 -1.678082 +vn -5.291550 -0.975674 3.099188 +v -17.039619 -3.121540 9.995380 +vn -5.291561 0.975679 -3.099177 +v -17.039619 3.121540 -9.995359 +vn -5.291553 3.208333 0.513325 +v -17.039619 10.336121 1.678088 +vn -5.284099 -2.778008 1.716898 +v -17.013020 -8.944281 5.527860 +vn -5.284098 2.778005 -1.716901 +v -17.013020 8.944281 -5.527860 +vn -5.269775 -2.237496 -2.386267 +v -16.919821 -7.275940 -7.796180 +vn -5.269774 -1.133705 -3.068446 +v -16.919821 -3.719220 -9.994360 +vn -5.269769 1.133709 3.068451 +v -16.919821 3.719220 9.994360 +vn -5.269765 2.237492 2.386282 +v -16.919821 7.275940 7.796200 +vn -5.020554 -3.262545 -1.631274 +v -16.180340 -10.514621 -5.257300 +vn -5.020547 -0.000003 3.647644 +v -16.180340 0.000000 11.755700 +vn -5.020551 0.000001 -3.647639 +v -16.180340 0.000000 -11.755700 +vn -5.020547 3.262553 1.631270 +v -16.180340 10.514621 5.257320 +vn -4.733833 -3.999146 0.384269 +v -15.247080 -12.884160 1.235034 +vn -4.733829 -2.132165 3.405105 +v -15.247080 -6.866620 10.971621 +vn -4.733835 2.132167 -3.405095 +v -15.247080 6.866620 -10.971621 +vn -4.733832 3.999147 -0.384260 +v -15.247080 12.884160 -1.235030 +vn -4.712213 -3.742752 1.531091 +v -15.163440 -12.074600 4.926900 +vn -4.712214 -3.043260 2.662891 +v -15.163440 -9.806680 8.596479 +vn -4.712215 3.043257 -2.662890 +v -15.163440 9.806680 -8.596479 +vn -4.712214 3.742751 -1.531091 +v -15.163440 12.074600 -4.926900 +vn -4.701271 -2.132166 -3.449915 +v -15.146240 -6.866620 -11.110420 +vn -4.701271 2.132169 3.449924 +v -15.146219 6.866620 11.110420 +vn -4.582682 -3.208333 -2.695006 +v -14.771700 -10.336121 -8.658040 +vn -4.582676 -0.975675 -4.074869 +v -14.771700 -3.121540 -13.116899 +vn -4.582672 0.975681 4.074869 +v -14.771700 3.121540 13.116899 +vn -4.582674 3.208334 2.695017 +v -14.771700 10.336121 8.658040 +vn -4.546713 -4.141646 -0.803292 +v -14.733720 -13.293780 -2.488660 +vn -4.546714 1.133709 -4.063646 +v -14.733720 3.719220 -13.003281 +vn -4.546717 -1.133710 4.063653 +v -14.733700 -3.719220 13.003281 +vn -4.546715 4.141654 0.803293 +v -14.733700 13.293780 2.488660 +vn -4.150531 -4.141654 -2.022615 +v -13.382620 -13.293780 -6.646880 +vn -4.150539 -0.043111 4.608945 +v -13.382620 0.000000 14.862880 +vn -4.150537 0.043119 -4.608949 +v -13.382620 0.000000 -14.862880 +vn -4.150532 4.141650 2.022617 +v -13.382620 13.293780 6.646880 +vn -4.055620 -3.999146 2.471599 +v -13.061080 -12.884160 7.962840 +vn -4.055616 3.999146 -2.471603 +v -13.061080 12.884160 -7.962840 +vn -3.988708 -3.043260 -3.658711 +v -12.861500 -9.806680 -11.764820 +vn -3.988709 -1.911464 -4.358202 +v -12.861500 -6.137100 -14.032741 +vn -3.988713 1.911459 4.358198 +v -12.861500 6.137100 14.032741 +vn -3.988712 3.043259 3.658705 +v -12.861500 9.806680 11.764820 +vn -3.979237 -4.588192 1.292931 +v -12.798981 -14.794980 4.158640 +vn -3.979234 -3.208329 3.525591 +v -12.798981 -10.336121 11.373240 +vn -3.979229 3.208333 -3.525590 +v -12.798981 10.336121 -11.373240 +vn -3.979236 4.588191 -1.292931 +v -12.798981 14.794980 -4.158640 +vn -3.897928 -4.823828 0.089688 +v -12.643120 -15.491940 0.388778 +vn -3.897935 -2.237500 4.274450 +v -12.643120 -7.275940 13.682539 +vn -3.897929 2.237500 -4.274455 +v -12.643120 7.275940 -13.682539 +vn -3.897932 4.823824 -0.089683 +v -12.643120 15.491940 -0.388774 +vn -3.603886 -3.999147 -3.093352 +v -11.609221 -12.884160 -9.961160 +vn -3.603896 -0.978311 -4.960329 +v -11.609221 -3.147580 -15.978700 +vn -3.603892 0.978312 4.960337 +v -11.609200 3.147580 15.978700 +vn -3.603884 3.999150 3.093360 +v -11.609200 12.884160 9.961160 +vn -3.576594 -4.922777 -1.162109 +v -11.547001 -15.893080 -3.751840 +vn -3.576597 -1.162109 4.922763 +v -11.547001 -3.751860 15.893101 +vn -3.576598 1.162111 -4.922771 +v -11.547001 3.751860 -15.893080 +vn -3.576598 4.922772 1.162108 +v -11.547001 15.893080 3.751860 +vn -3.265750 -2.778012 -4.494916 +v -10.514621 -8.944281 -14.472140 +vn -3.265750 2.778012 4.494916 +v -10.514621 8.944281 14.472140 +vn -3.206206 -4.823825 2.218588 +v -10.457020 -15.491940 7.116920 +vn -3.206207 -4.141645 3.322369 +v -10.457020 -13.293780 10.673639 +vn -3.206215 4.141646 -3.322370 +v -10.457020 13.293780 -10.673619 +vn -3.206212 4.823822 -2.218587 +v -10.457020 15.491940 -7.116920 +vn -3.102865 -5.278914 1.008183 +v -10.000000 -17.013020 3.249200 +vn -3.102872 -3.262539 4.270739 +v -10.000000 -10.514621 13.763820 +vn -3.102872 3.262543 -4.270734 +v -10.000000 10.514621 -13.763820 +vn -3.102865 5.278914 -1.008183 +v -10.000000 17.013020 -3.249200 +vn -3.100777 -4.823829 -2.363698 +v -9.999980 -15.491940 -7.745960 +vn -3.100783 -0.043106 5.371634 +v -9.999980 0.000000 17.320520 +vn -3.100778 0.043124 -5.371637 +v -9.999980 0.000000 -17.320520 +vn -3.100774 4.823819 2.363712 +v -9.999980 15.491940 7.745980 +vn -2.912313 -3.742750 -4.008451 +v -9.371520 -12.074600 -12.898780 +vn -2.912314 -1.911463 -5.140248 +v -9.371520 -6.137100 -16.568359 +vn -2.912310 1.911454 5.140251 +v -9.371520 6.137100 16.568359 +vn -2.912309 3.742757 4.008443 +v -9.371520 12.074600 12.898780 +vn -2.860714 -5.497847 -0.247332 +v -9.105940 -17.790541 -0.760526 +vn -2.860710 -2.237500 5.028033 +v -9.105940 -7.275940 16.252460 +vn -2.860715 2.237494 -5.028032 +v -9.105940 7.275940 -16.252460 +vn -2.860714 5.497847 0.247331 +v -9.105940 17.790541 0.760528 +vn -2.459307 -4.588188 -3.384936 +v -7.910220 -14.794980 -10.887460 +vn -2.459298 -0.975682 -5.617589 +v -7.910220 -3.121540 -18.102060 +vn -2.459301 0.975697 5.617588 +v -7.910200 3.121540 18.102060 +vn -2.459302 4.588187 3.384946 +v -7.910200 14.794980 10.887460 +vn -2.459745 -5.497846 -1.481394 +v -7.813880 -17.790541 -4.737060 +vn -2.459738 -1.133721 5.579926 +v -7.813880 -3.719220 18.030819 +vn -2.459745 1.133713 -5.579923 +v -7.813880 3.719220 -18.030819 +vn -2.459742 5.497849 1.481392 +v -7.813880 17.790541 4.737060 +vn -2.247059 -3.043255 -4.924094 +v -7.214600 -9.806680 -15.867539 +vn -2.247056 3.043255 4.924094 +v -7.214600 9.806680 15.867539 +vn -2.210456 -4.922780 3.042432 +v -7.136440 -15.893080 9.822460 +vn -2.210456 4.922773 -3.042428 +v -7.136440 15.893101 -9.822460 +vn -2.168987 -5.497849 1.881584 +v -6.919820 -17.790541 5.967620 +vn -2.168983 -4.141646 4.075955 +v -6.919820 -13.293780 13.243560 +vn -2.168988 4.141642 -4.075958 +v -6.919820 13.293780 -13.243560 +vn -2.168987 5.497852 -1.881576 +v -6.919820 17.790541 -5.967620 +vn -2.123378 -5.794199 0.689931 +v -6.861480 -18.653400 2.229440 +vn -2.123379 -3.208327 4.873949 +v -6.861480 -10.336121 15.687079 +vn -2.123379 3.208327 -4.873949 +v -6.861480 10.336121 -15.687079 +vn -2.123378 5.794199 -0.689931 +v -6.861480 18.653400 -2.229440 +vn -1.917679 -5.278916 -2.639454 +v -6.180340 -17.013020 -8.506500 +vn -1.917677 0.000003 5.902004 +v -6.180340 0.000000 19.021141 +vn -1.917681 0.000000 -5.902011 +v -6.180340 0.000000 -19.021120 +vn -1.917676 5.278914 2.639459 +v -6.180340 17.013020 8.506500 +vn -1.828302 -3.999146 -4.383397 +v -5.886200 -12.884160 -14.119181 +vn -1.828295 -2.132165 -5.537262 +v -5.886200 -6.866620 -17.838219 +vn -1.828292 2.132160 5.537266 +v -5.886180 6.866620 17.838219 +vn -1.828299 3.999151 4.383395 +v -5.886180 12.884160 14.119181 +vn -1.775610 -5.921519 -0.576930 +v -5.723020 -19.073259 -1.859520 +vn -1.775602 -2.132165 5.554380 +v -5.723020 -6.866620 17.891239 +vn -1.775602 2.132168 -5.554380 +v -5.723020 6.866620 -17.891239 +vn -1.775610 5.921519 0.576930 +v -5.723020 19.073259 1.859522 +vn -1.289836 -4.823826 -3.679434 +v -4.276700 -15.491940 -11.904181 +vn -1.289831 -1.133712 -5.960054 +v -4.276700 -3.719220 -19.180120 +vn -1.289828 1.133722 5.960055 +v -4.276680 3.719220 19.180120 +vn -1.289829 4.823826 3.679436 +v -4.276680 15.491940 11.904181 +vn -1.312324 -5.794198 -1.806254 +v -4.240640 -18.653400 -5.836720 +vn -1.312322 0.975686 -5.990263 +v -4.240640 3.121540 -19.294380 +vn -1.312324 5.794198 1.806254 +v -4.240640 18.653400 5.836720 +vn -1.312312 -0.975697 5.990266 +v -4.240620 -3.121540 19.294380 +vn -1.146988 -3.208326 -5.191195 +v -3.669580 -10.336121 -16.724201 +vn -1.146991 3.208326 5.191194 +v -3.669580 10.336121 16.724201 +vn -1.119240 -5.497846 2.644273 +v -3.537200 -17.790541 8.425240 +vn -1.119236 -4.823829 3.734861 +v -3.537200 -15.491940 12.144460 +vn -1.119230 4.823828 -3.734865 +v -3.537200 15.491940 -12.144460 +vn -1.119233 5.497850 -2.644270 +v -3.537200 17.790541 -8.425240 +vn -1.097389 -5.921518 1.510425 +v -3.537020 -19.073259 4.868300 +vn -1.097379 -3.999141 4.620892 +v -3.537020 -12.884160 14.882480 +vn -1.097379 3.999141 -4.620892 +v -3.537020 12.884160 -14.882480 +vn -1.097388 5.921518 -1.510425 +v -3.537020 19.073259 -4.868300 +vn -1.076410 -6.105439 0.349746 +v -3.489980 -19.660480 1.133962 +vn -1.076405 -3.043250 5.304465 +v -3.489980 -9.806680 17.077740 +vn -1.076405 3.043250 -5.304465 +v -3.489980 9.806680 -17.077740 +vn -1.076410 6.105439 -0.349746 +v -3.489980 19.660480 -1.133962 +vn -0.641046 -4.141644 -4.572416 +v -2.186100 -13.293780 -14.781639 +vn -0.641045 -2.237492 -5.749249 +v -2.186100 -7.275940 -18.500860 +vn -0.641048 2.237491 5.749248 +v -2.186100 7.275940 18.500860 +vn -0.641046 4.141648 4.572411 +v -2.186100 13.293780 14.781639 +vn -0.665257 -6.105438 -0.915650 +v -2.156920 -19.660480 -2.968760 +vn -0.665248 -1.911462 5.870365 +v -2.156920 -6.137100 18.912521 +vn -0.665246 1.911463 -5.870364 +v -2.156920 6.137100 -18.912521 +vn -0.665257 6.105438 0.915650 +v -2.156920 19.660480 2.968760 +vn -0.648790 -5.497851 -2.797124 +v -2.090580 -17.790541 -8.895280 +vn -0.648783 0.043113 6.168337 +v -2.090580 0.000000 19.890440 +vn -0.648790 -0.043113 -6.168336 +v -2.090580 0.000000 -19.890440 +vn -0.648786 5.497847 2.797131 +v -2.090580 17.790541 8.895280 +vn -0.000000 -3.262544 -5.278922 +v -0.000002 -10.514621 -17.013020 +vn 0.000001 -1.162108 -6.084874 +v -0.000001 -3.751860 -19.644939 +vn 0.000001 -4.922774 -3.760647 +v -0.000001 -15.893101 -12.141239 +vn -0.000000 0.978324 -6.131309 +v -0.000001 3.147580 -19.750759 +vn -0.000000 -5.921519 -1.866988 +v -0.000001 -19.073259 -6.017540 +vn -0.000000 -6.211829 0.000001 +v 0.000000 -20.000000 0.000000 +vn 0.000000 2.778005 -5.556029 +v 0.000000 8.944281 -17.888540 +vn -0.000000 3.742743 -4.954723 +v 0.000000 12.074600 -15.943780 +vn -0.000000 4.588188 -4.184014 +v 0.000000 14.794980 -13.457660 +vn -0.000000 5.278917 -3.262545 +v 0.000000 17.013020 -10.514621 +vn -0.000000 5.794196 -2.232656 +v 0.000000 18.653400 -7.214600 +vn -0.000000 6.105440 -1.131802 +v 0.000000 19.660480 -3.669580 +vn 0.000000 6.211829 -0.000001 +v 0.000000 20.000000 0.000000 +vn 0.000000 -6.105439 1.131802 +v 0.000000 -19.660480 3.669580 +vn 0.000000 5.921519 1.866987 +v 0.000001 19.073259 6.017540 +vn 0.000000 -5.794197 2.232656 +v 0.000001 -18.653400 7.214600 +vn 0.000000 -5.278917 3.262545 +v 0.000001 -17.013020 10.514621 +vn 0.000000 4.922778 3.760653 +v 0.000001 15.893080 12.141239 +vn 0.000000 -4.588188 4.184014 +v 0.000001 -14.794980 13.457660 +vn 0.000000 -3.742743 4.954723 +v 0.000001 -12.074600 15.943780 +vn 0.000000 3.262544 5.278922 +v 0.000002 10.514621 17.013020 +vn 0.000000 -2.778005 5.556029 +v 0.000002 -8.944281 17.888540 +vn -0.000001 1.162109 6.084874 +v 0.000002 3.751860 19.644939 +vn -0.000001 -0.978324 6.131309 +v 0.000002 -3.147580 19.750759 +vn 0.648790 -5.497850 -2.797125 +v 2.090580 -17.790541 -8.895280 +vn 0.648790 0.043113 6.168336 +v 2.090580 0.000000 19.890440 +vn 0.648782 -0.043114 -6.168337 +v 2.090580 0.000000 -19.890440 +vn 0.648786 5.497846 2.797131 +v 2.090580 17.790541 8.895280 +vn 0.665257 -6.105438 -0.915650 +v 2.156920 -19.660480 -2.968760 +vn 0.665246 -1.911463 5.870364 +v 2.156920 -6.137100 18.912521 +vn 0.665246 1.911463 -5.870364 +v 2.156920 6.137100 -18.912521 +vn 0.665257 6.105439 0.915650 +v 2.156920 19.660480 2.968760 +vn 0.641049 -4.141644 -4.572415 +v 2.186100 -13.293780 -14.781639 +vn 0.641048 -2.237491 -5.749248 +v 2.186100 -7.275940 -18.500860 +vn 0.641045 2.237492 5.749248 +v 2.186100 7.275940 18.500860 +vn 0.641043 4.141648 4.572411 +v 2.186100 13.293780 14.781639 +vn 1.076410 -6.105439 0.349746 +v 3.489980 -19.660480 1.133962 +vn 1.076406 -3.043250 5.304465 +v 3.489980 -9.806680 17.077740 +vn 1.076406 3.043250 -5.304465 +v 3.489980 9.806680 -17.077740 +vn 1.076410 6.105439 -0.349746 +v 3.489980 19.660480 -1.133962 +vn 1.097389 -5.921517 1.510426 +v 3.537020 -19.073259 4.868300 +vn 1.097379 -3.999141 4.620892 +v 3.537020 -12.884160 14.882480 +vn 1.097379 3.999141 -4.620892 +v 3.537020 12.884160 -14.882480 +vn 1.097389 5.921517 -1.510425 +v 3.537020 19.073259 -4.868300 +vn 1.119240 -5.497847 2.644273 +v 3.537200 -17.790541 8.425240 +vn 1.119236 -4.823828 3.734861 +v 3.537200 -15.491940 12.144460 +vn 1.119236 4.823828 -3.734861 +v 3.537200 15.491940 -12.144460 +vn 1.119240 5.497846 -2.644273 +v 3.537200 17.790541 -8.425240 +vn 1.146991 -3.208326 -5.191194 +v 3.669580 -10.336121 -16.724201 +vn 1.146989 3.208326 5.191195 +v 3.669580 10.336121 16.724201 +vn 1.312324 -5.794198 -1.806254 +v 4.240640 -18.653400 -5.836720 +vn 1.312322 -0.975686 5.990263 +v 4.240640 -3.121540 19.294380 +vn 1.312315 0.975697 -5.990263 +v 4.240640 3.121540 -19.294380 +vn 1.312324 5.794198 1.806254 +v 4.240640 18.653400 5.836720 +vn 1.289837 -4.823825 -3.679435 +v 4.276680 -15.491940 -11.904181 +vn 1.289828 -1.133722 -5.960055 +v 4.276680 -3.719220 -19.180120 +vn 1.289827 4.823828 3.679435 +v 4.276680 15.491940 11.904181 +vn 1.289831 1.133712 5.960054 +v 4.276700 3.719220 19.180120 +vn 1.775610 -5.921519 -0.576930 +v 5.723020 -19.073259 -1.859522 +vn 1.775602 -2.132168 5.554380 +v 5.723020 -6.866620 17.891239 +vn 1.775602 2.132168 -5.554380 +v 5.723020 6.866620 -17.891239 +vn 1.775610 5.921520 0.576930 +v 5.723020 19.073259 1.859522 +vn 1.828299 -3.999151 -4.383395 +v 5.886180 -12.884160 -14.119181 +vn 1.828292 -2.132160 -5.537266 +v 5.886180 -6.866620 -17.838219 +vn 1.828295 2.132165 5.537262 +v 5.886200 6.866620 17.838219 +vn 1.828302 3.999149 4.383393 +v 5.886200 12.884160 14.119181 +vn 1.917680 -5.278913 -2.639458 +v 6.180340 -17.013020 -8.506500 +vn 1.917681 -0.000000 5.902011 +v 6.180340 0.000000 19.021120 +vn 1.917678 -0.000005 -5.902003 +v 6.180340 0.000000 -19.021141 +vn 1.917680 5.278913 2.639458 +v 6.180340 17.013020 8.506500 +vn 2.123378 -5.794199 0.689931 +v 6.861480 -18.653400 2.229440 +vn 2.123379 -3.208327 4.873949 +v 6.861480 -10.336121 15.687079 +vn 2.123379 3.208327 -4.873949 +v 6.861480 10.336121 -15.687079 +vn 2.123378 5.794199 -0.689931 +v 6.861480 18.653400 -2.229440 +vn 2.168987 -5.497849 1.881584 +v 6.919820 -17.790541 5.967620 +vn 2.168988 -4.141646 4.075952 +v 6.919820 -13.293780 13.243560 +vn 2.168983 4.141646 -4.075955 +v 6.919820 13.293780 -13.243560 +vn 2.168987 5.497849 -1.881584 +v 6.919820 17.790541 -5.967620 +vn 2.210459 -4.922777 3.042433 +v 7.136440 -15.893080 9.822460 +vn 2.210456 4.922780 -3.042432 +v 7.136440 15.893080 -9.822460 +vn 2.247056 -3.043255 -4.924094 +v 7.214600 -9.806680 -15.867539 +vn 2.247059 3.043255 4.924094 +v 7.214600 9.806680 15.867539 +vn 2.459745 -5.497846 -1.481394 +v 7.813880 -17.790541 -4.737060 +vn 2.459745 -1.133713 5.579923 +v 7.813880 -3.719220 18.030819 +vn 2.459748 1.133721 -5.579921 +v 7.813880 3.719220 -18.030819 +vn 2.459746 5.497846 1.481394 +v 7.813880 17.790541 4.737060 +vn 2.459304 -4.588189 -3.384941 +v 7.910200 -14.794980 -10.887460 +vn 2.459301 -0.975697 -5.617588 +v 7.910200 -3.121540 -18.102060 +vn 2.459306 4.588190 3.384939 +v 7.910200 14.794980 10.887460 +vn 2.459298 0.975682 5.617588 +v 7.910220 3.121540 18.102060 +vn 2.860714 -5.497846 -0.247332 +v 9.105940 -17.790541 -0.760528 +vn 2.860714 -2.237494 5.028032 +v 9.105940 -7.275940 16.252460 +vn 2.860714 2.237494 -5.028032 +v 9.105940 7.275940 -16.252460 +vn 2.860714 5.497846 0.247332 +v 9.105940 17.790541 0.760526 +vn 2.912310 -3.742757 -4.008443 +v 9.371520 -12.074600 -12.898780 +vn 2.912311 -1.911454 -5.140251 +v 9.371520 -6.137100 -16.568359 +vn 2.912314 1.911463 5.140248 +v 9.371520 6.137100 16.568359 +vn 2.912314 3.742756 4.008442 +v 9.371520 12.074600 12.898780 +vn 3.100777 -4.823822 -2.363706 +v 9.999980 -15.491940 -7.745960 +vn 3.100778 -0.043124 5.371636 +v 9.999980 0.000000 17.320520 +vn 3.100786 0.043113 -5.371632 +v 9.999980 0.000000 -17.320520 +vn 3.100777 4.823822 2.363706 +v 9.999980 15.491940 7.745960 +vn 3.102865 -5.278914 1.008183 +v 10.000000 -17.013020 3.249200 +vn 3.102872 -3.262543 4.270734 +v 10.000000 -10.514621 13.763820 +vn 3.102872 3.262539 -4.270739 +v 10.000000 10.514621 -13.763820 +vn 3.102865 5.278914 -1.008183 +v 10.000000 17.013020 -3.249200 +vn 3.206206 -4.823822 2.218591 +v 10.457020 -15.491940 7.116920 +vn 3.206209 -4.141650 3.322369 +v 10.457020 -13.293780 10.673619 +vn 3.206207 4.141645 -3.322369 +v 10.457020 13.293780 -10.673639 +vn 3.206206 4.823825 -2.218588 +v 10.457020 15.491940 -7.116920 +vn 3.265750 -2.778012 -4.494917 +v 10.514621 -8.944281 -14.472140 +vn 3.265750 2.778012 4.494917 +v 10.514621 8.944281 14.472140 +vn 3.576598 -4.922773 -1.162107 +v 11.547001 -15.893080 -3.751840 +vn 3.576598 -1.162111 4.922771 +v 11.547001 -3.751860 15.893080 +vn 3.576598 1.162111 -4.922771 +v 11.547001 3.751860 -15.893080 +vn 3.576594 4.922777 1.162109 +v 11.547001 15.893080 3.751840 +vn 3.603882 -3.999153 -3.093357 +v 11.609200 -12.884160 -9.961160 +vn 3.603892 -0.978311 -4.960337 +v 11.609200 -3.147580 -15.978700 +vn 3.603882 3.999153 3.093357 +v 11.609200 12.884160 9.961160 +vn 3.603896 0.978311 4.960329 +v 11.609221 3.147580 15.978700 +vn 3.897932 -4.823824 0.089683 +v 12.643120 -15.491940 0.388776 +vn 3.897929 -2.237500 4.274455 +v 12.643120 -7.275940 13.682539 +vn 3.897929 2.237500 -4.274455 +v 12.643120 7.275940 -13.682539 +vn 3.897928 4.823828 -0.089688 +v 12.643120 15.491940 -0.388778 +vn 3.979237 -4.588191 1.292931 +v 12.798981 -14.794980 4.158640 +vn 3.979229 -3.208333 3.525590 +v 12.798981 -10.336121 11.373240 +vn 3.979234 3.208329 -3.525591 +v 12.798981 10.336121 -11.373240 +vn 3.979236 4.588192 -1.292931 +v 12.798981 14.794980 -4.158640 +vn 3.988712 -3.043259 -3.658705 +v 12.861500 -9.806680 -11.764820 +vn 3.988713 -1.911459 -4.358198 +v 12.861500 -6.137100 -14.032741 +vn 3.988709 1.911464 4.358202 +v 12.861500 6.137100 14.032741 +vn 3.988707 3.043265 3.658707 +v 12.861500 9.806680 11.764820 +vn 4.055616 -3.999147 2.471603 +v 13.061080 -12.884160 7.962840 +vn 4.055620 3.999146 -2.471599 +v 13.061080 12.884160 -7.962840 +vn 4.150528 -4.141654 -2.022616 +v 13.382620 -13.293780 -6.646880 +vn 4.150537 -0.043119 4.608949 +v 13.382620 0.000000 14.862880 +vn 4.150534 0.043112 -4.608950 +v 13.382620 0.000000 -14.862880 +vn 4.150528 4.141652 2.022621 +v 13.382620 13.293780 6.646880 +vn 4.546714 -4.141654 -0.803294 +v 14.733700 -13.293780 -2.488660 +vn 4.546714 -1.133709 4.063646 +v 14.733720 -3.719220 13.003281 +vn 4.546710 1.133709 -4.063651 +v 14.733720 3.719220 -13.003281 +vn 4.546713 4.141646 0.803292 +v 14.733720 13.293780 2.488660 +vn 4.582676 -3.208331 -2.695015 +v 14.771700 -10.336121 -8.658040 +vn 4.582672 -0.975681 -4.074869 +v 14.771700 -3.121540 -13.116899 +vn 4.582676 0.975675 4.074869 +v 14.771700 3.121540 13.116899 +vn 4.582677 3.208337 2.695007 +v 14.771700 10.336121 8.658040 +vn 4.701273 -2.132169 -3.449920 +v 15.146219 -6.866620 -11.110420 +vn 4.701271 2.132166 3.449915 +v 15.146240 6.866620 11.110420 +vn 4.712214 -3.742751 1.531091 +v 15.163440 -12.074600 4.926900 +vn 4.712215 -3.043257 2.662890 +v 15.163440 -9.806680 8.596479 +vn 4.712215 3.043257 -2.662890 +v 15.163440 9.806680 -8.596479 +vn 4.712214 3.742752 -1.531091 +v 15.163440 12.074600 -4.926900 +vn 4.733832 -3.999147 0.384260 +v 15.247080 -12.884160 1.235030 +vn 4.733835 -2.132167 3.405095 +v 15.247080 -6.866620 10.971621 +vn 4.733833 2.132171 -3.405096 +v 15.247080 6.866620 -10.971621 +vn 4.733833 3.999146 -0.384269 +v 15.247080 12.884160 -1.235032 +vn 5.020549 -3.262548 -1.631272 +v 16.180340 -10.514621 -5.257320 +vn 5.020551 -0.000001 3.647639 +v 16.180340 0.000000 11.755700 +vn 5.020550 -0.000004 -3.647642 +v 16.180340 0.000000 -11.755700 +vn 5.020554 3.262545 1.631274 +v 16.180340 10.514621 5.257300 +vn 5.269771 -2.237493 -2.386276 +v 16.919821 -7.275940 -7.796180 +vn 5.269769 -1.133713 -3.068449 +v 16.919821 -3.719220 -9.994360 +vn 5.269774 1.133705 3.068446 +v 16.919821 3.719220 9.994360 +vn 5.269775 2.237495 2.386266 +v 16.919821 7.275940 7.796180 +vn 5.284098 -2.778005 1.716901 +v 17.013020 -8.944281 5.527860 +vn 5.284098 2.778004 -1.716901 +v 17.013020 8.944281 -5.527860 +vn 5.291554 -3.208332 -0.513326 +v 17.039619 -10.336121 -1.678086 +vn 5.291560 -0.975679 3.099177 +v 17.039619 -3.121540 9.995359 +vn 5.291556 0.975677 -3.099179 +v 17.039619 3.121540 -9.995380 +vn 5.291559 3.208326 0.513325 +v 17.039619 10.336121 1.678084 +vn 5.377473 -3.043252 0.615450 +v 17.320360 -9.806680 1.958146 +vn 5.377477 -1.911459 2.446728 +v 17.320360 -6.137100 7.895640 +vn 5.377478 1.911463 -2.446725 +v 17.320360 6.137100 -7.895640 +vn 5.377474 3.043252 -0.615451 +v 17.320360 9.806680 -1.958148 +vn 5.665954 -2.237496 -1.166954 +v 18.270901 -7.275940 -3.637960 +vn 5.665954 0.043116 2.523156 +v 18.270901 0.000000 8.134740 +vn 5.665956 -0.043120 -2.523154 +v 18.270901 0.000000 -8.134740 +vn 5.665953 2.237498 1.166955 +v 18.270901 7.275940 3.637960 +vn 5.788622 -1.911468 1.181355 +v 18.653400 -6.137100 3.792940 +vn 5.788622 1.911468 -1.181355 +v 18.653400 6.137100 -3.792940 +vn 5.787062 -1.162111 -1.880332 +v 18.683439 -3.751860 -6.070620 +vn 5.787062 1.162111 1.880332 +v 18.683439 3.751860 6.070620 +vn 5.831218 -2.132169 0.027703 +v 18.784100 -6.866620 0.085783 +vn 5.831217 -0.978316 1.894682 +v 18.784100 -3.147580 6.103320 +vn 5.831219 0.978316 -1.894679 +v 18.784100 3.147580 -6.103320 +vn 5.831218 2.132169 -0.027703 +v 18.784100 6.866620 -0.085784 +vn 6.066922 -1.133715 -0.615069 +v 19.562960 -3.719220 -1.859612 +vn 6.066921 0.043121 1.289095 +v 19.562960 0.000000 4.158220 +vn 6.066921 -0.043121 -1.289095 +v 19.562960 0.000000 -4.158220 +vn 6.066922 1.133715 0.615069 +v 19.562960 3.719220 1.859612 +vn 6.102607 -0.975688 0.603006 +v 19.660480 -3.121540 1.929210 +vn 6.102607 0.975688 -0.603007 +v 19.660480 3.121540 -1.929212 +vn 6.205740 -0.000000 -0.000000 +v 20.000000 0.000000 -0.000001 +# 362 vertices, 0 vertices normals + + +usemtl material_0 +vt 0.750000 0.941264 +vt 0.650000 1.000000 +vt 0.550000 0.941264 +f 181/1/181 182/2/182 209/3/209 +vt 0.650000 0.902721 +vt 0.550000 0.882528 +f 213/4/213 209/3/209 243/5/243 +vt 0.750000 0.882528 +f 181/1/181 213/4/213 180/6/180 +f 181/1/181 209/3/209 213/4/213 +vt 0.613262 0.848966 +vt 0.550000 0.823792 +f 247/7/247 243/5/243 275/8/275 +vt 0.686738 0.848966 +f 217/9/217 213/4/213 247/7/247 +vt 0.750000 0.823792 +f 180/6/180 217/9/217 179/10/179 +f 213/4/213 243/5/243 247/7/247 +f 180/6/180 213/4/213 217/9/217 +vt 0.595108 0.782047 +vt 0.550000 0.765056 +f 279/11/279 275/8/275 297/12/297 +vt 0.650000 0.792348 +f 249/13/249 247/7/247 279/11/279 +vt 0.704892 0.782047 +f 217/9/217 249/13/249 216/14/216 +vt 0.750000 0.765056 +f 179/10/179 216/14/216 178/15/178 +f 247/7/247 275/8/275 279/11/279 +f 217/9/217 247/7/247 249/13/249 +f 179/10/179 217/9/217 216/14/216 +vt 0.587136 0.722813 +vt 0.550000 0.706319 +f 303/16/303 297/12/297 321/17/321 +vt 0.626631 0.731436 +f 278/18/278 279/11/279 303/16/303 +vt 0.673369 0.731436 +f 246/19/246 249/13/249 278/18/278 +vt 0.712864 0.722813 +f 216/14/216 246/19/246 212/20/212 +vt 0.750000 0.706319 +f 178/15/178 212/20/212 177/21/177 +f 279/11/279 297/12/297 303/16/303 +f 249/13/249 279/11/279 278/18/278 +f 216/14/216 249/13/249 246/19/246 +f 178/15/178 216/14/216 212/20/212 +vt 0.582083 0.663125 +vt 0.550000 0.647584 +f 320/22/320 321/17/321 335/23/335 +vt 0.615623 0.672879 +f 296/24/296 303/16/303 320/22/320 +vt 0.650000 0.676208 +f 274/25/274 278/18/278 296/24/296 +vt 0.684377 0.672879 +f 246/19/246 274/25/274 242/26/242 +vt 0.717917 0.663125 +f 212/20/212 242/26/242 208/27/208 +vt 0.750000 0.647584 +f 177/21/177 208/27/208 176/28/176 +f 303/16/303 321/17/321 320/22/320 +f 278/18/278 303/16/303 296/24/296 +f 246/19/246 278/18/278 274/25/274 +f 212/20/212 246/19/246 242/26/242 +f 177/21/177 212/20/212 208/27/208 +vt 0.450000 1.000000 +vt 0.350000 0.941264 +f 209/3/209 182/29/182 201/30/201 +vt 0.450000 0.902721 +vt 0.350000 0.882528 +f 231/31/231 201/30/201 223/32/223 +f 209/3/209 231/31/231 243/5/243 +f 209/3/209 201/30/201 231/31/231 +vt 0.413262 0.848966 +vt 0.350000 0.823792 +f 255/33/255 223/32/223 239/34/239 +vt 0.486738 0.848966 +f 263/35/263 231/31/231 255/33/255 +f 243/5/243 263/35/263 275/8/275 +f 231/31/231 223/32/223 255/33/255 +f 243/5/243 231/31/231 263/35/263 +vt 0.395108 0.782047 +vt 0.350000 0.765056 +f 271/36/271 239/34/239 258/37/258 +vt 0.450000 0.792348 +f 285/38/285 255/33/255 271/36/271 +vt 0.504893 0.782047 +f 263/35/263 285/38/285 293/39/293 +f 275/8/275 293/39/293 297/12/297 +f 255/33/255 239/34/239 271/36/271 +f 263/35/263 255/33/255 285/38/285 +f 275/8/275 263/35/263 293/39/293 +vt 0.387136 0.722813 +vt 0.350000 0.706320 +f 288/40/288 258/37/258 267/41/267 +vt 0.426631 0.731436 +f 307/42/307 271/36/271 288/40/288 +vt 0.473369 0.731436 +f 311/43/311 285/38/285 307/42/307 +vt 0.512864 0.722813 +f 293/39/293 311/43/311 325/44/325 +f 297/12/297 325/44/325 321/17/321 +f 271/36/271 258/37/258 288/40/288 +f 285/38/285 271/36/271 307/42/307 +f 293/39/293 285/38/285 311/43/311 +f 297/12/297 293/39/293 325/44/325 +vt 0.382083 0.663125 +vt 0.350000 0.647584 +f 301/45/301 267/41/267 281/46/281 +vt 0.415623 0.672879 +f 315/47/315 288/40/288 301/45/301 +vt 0.450000 0.676208 +f 329/48/329 307/42/307 315/47/315 +vt 0.484377 0.672879 +f 311/43/311 329/48/329 339/49/339 +vt 0.517917 0.663125 +f 325/44/325 339/49/339 343/50/343 +f 321/17/321 343/50/343 335/23/335 +f 288/40/288 267/41/267 301/45/301 +f 307/42/307 288/40/288 315/47/315 +f 311/43/311 307/42/307 329/48/329 +f 325/44/325 311/43/311 339/49/339 +f 321/17/321 325/44/325 343/50/343 +vt 0.250000 1.000000 +vt 0.150000 0.941264 +f 201/30/201 182/51/182 165/52/165 +vt 0.250000 0.902721 +vt 0.150000 0.882528 +f 184/53/184 165/52/165 142/54/142 +f 201/30/201 184/53/184 223/32/223 +f 201/30/201 165/52/165 184/53/184 +vt 0.213262 0.848966 +vt 0.150000 0.823792 +f 169/55/169 142/54/142 127/56/127 +vt 0.286738 0.848966 +f 197/57/197 184/53/184 169/55/169 +f 223/32/223 197/57/197 239/34/239 +f 184/53/184 142/54/142 169/55/169 +f 223/32/223 184/53/184 197/57/197 +vt 0.195108 0.782047 +vt 0.150000 0.765056 +f 139/58/139 127/56/127 107/59/107 +vt 0.250000 0.792348 +f 187/60/187 169/55/169 139/58/139 +vt 0.304892 0.782047 +f 197/57/197 187/60/187 226/61/226 +f 239/34/239 226/61/226 258/37/258 +f 169/55/169 127/56/127 139/58/139 +f 197/57/197 169/55/169 187/60/187 +f 239/34/239 197/57/197 226/61/226 +vt 0.187136 0.722813 +vt 0.150000 0.706320 +f 131/62/131 107/59/107 99/63/99 +vt 0.226632 0.731436 +f 161/64/161 139/58/139 131/62/131 +vt 0.273369 0.731436 +f 205/65/205 187/60/187 161/64/161 +vt 0.312864 0.722813 +f 226/61/226 205/65/205 235/66/235 +f 258/37/258 235/66/235 267/41/267 +f 139/58/139 107/59/107 131/62/131 +f 187/60/187 139/58/139 161/64/161 +f 226/61/226 187/60/187 205/65/205 +f 258/37/258 226/61/226 235/66/235 +vt 0.182083 0.663125 +vt 0.150000 0.647584 +f 113/67/113 99/63/99 83/68/83 +vt 0.215623 0.672879 +f 145/69/145 131/62/131 113/67/113 +vt 0.250000 0.676208 +f 190/70/190 161/64/161 145/69/145 +vt 0.284377 0.672879 +f 205/65/205 190/70/190 219/71/219 +vt 0.317917 0.663125 +f 235/66/235 219/71/219 251/72/251 +f 267/41/267 251/72/251 281/46/281 +f 131/62/131 99/63/99 113/67/113 +f 161/64/161 131/62/131 145/69/145 +f 205/65/205 161/64/161 190/70/190 +f 235/66/235 205/65/205 219/71/219 +f 267/41/267 235/66/235 251/72/251 +vt 0.050000 1.000000 +vt -0.050000 0.941264 +f 182/73/182 157/74/157 165/52/165 +vt 1.050000 0.902721 +vt 0.950000 0.941264 +vt 0.950000 0.882528 +f 135/75/135 157/76/157 123/77/123 +vt 0.050000 0.902721 +f 165/52/165 135/78/135 142/54/142 +f 165/52/165 157/74/157 135/78/135 +vt 1.013260 0.848966 +vt 0.950000 0.823792 +f 103/79/103 123/77/123 91/80/91 +vt 0.013262 0.848966 +vt 0.086738 0.848966 +f 135/78/135 103/81/103 111/82/111 +f 142/54/142 111/82/111 127/56/127 +f 135/75/135 123/77/123 103/79/103 +f 142/54/142 135/78/135 111/82/111 +vt 0.995108 0.782047 +vt 0.950000 0.765056 +f 73/83/73 91/80/91 69/84/69 +vt 0.050000 0.792348 +vt -0.004892 0.782047 +f 81/85/81 103/81/103 73/86/73 +vt 0.104893 0.782047 +f 111/82/111 81/85/81 95/87/95 +f 127/56/127 95/87/95 107/59/107 +f 103/79/103 91/80/91 73/83/73 +f 111/82/111 103/81/103 81/85/81 +f 127/56/127 111/82/111 95/87/95 +vt 0.987136 0.722813 +vt 0.950000 0.706319 +f 41/88/41 69/84/69 45/89/45 +vt 0.026631 0.731436 +vt -0.012864 0.722813 +f 55/90/55 73/86/73 41/91/41 +vt 0.073368 0.731436 +f 81/85/81 55/90/55 59/92/59 +vt 0.112864 0.722813 +f 95/87/95 59/92/59 77/93/77 +f 107/59/107 77/93/77 99/63/99 +f 73/83/73 69/84/69 41/88/41 +f 81/85/81 73/86/73 55/90/55 +f 95/87/95 81/85/81 59/92/59 +f 107/59/107 95/87/95 77/93/77 +vt 0.982083 0.663125 +vt 0.950000 0.647584 +f 23/94/23 45/89/45 29/95/29 +vt 1.015620 0.672879 +f 27/96/27 41/88/41 23/94/23 +vt 0.050000 0.676208 +vt 0.015623 0.672879 +f 37/97/37 55/90/55 27/98/27 +vt 0.084377 0.672879 +f 59/92/59 37/97/37 51/99/51 +vt 0.117917 0.663125 +f 77/93/77 51/99/51 65/100/65 +f 99/63/99 65/100/65 83/68/83 +f 41/88/41 45/89/45 23/94/23 +f 55/90/55 41/91/41 27/98/27 +f 59/92/59 55/90/55 37/97/37 +f 77/93/77 59/92/59 51/99/51 +f 99/63/99 77/93/77 65/100/65 +vt 0.850000 1.000000 +f 182/101/182 181/1/181 157/76/157 +vt 0.850000 0.902721 +f 153/102/153 181/1/181 180/6/180 +f 157/76/157 153/102/153 123/77/123 +f 157/76/157 181/1/181 153/102/153 +vt 0.813262 0.848966 +f 149/103/149 180/6/180 179/10/179 +vt 0.886738 0.848966 +f 153/102/153 149/103/149 119/104/119 +f 123/77/123 119/104/119 91/80/91 +f 153/102/153 180/6/180 149/103/149 +f 123/77/123 153/102/153 119/104/119 +vt 0.795108 0.782047 +f 148/105/148 179/10/179 178/15/178 +vt 0.850000 0.792348 +f 115/106/115 149/103/149 148/105/148 +vt 0.904892 0.782047 +f 119/104/119 115/106/115 87/107/87 +f 91/80/91 87/107/87 69/84/69 +f 149/103/149 179/10/179 148/105/148 +f 119/104/119 149/103/149 115/106/115 +f 91/80/91 119/104/119 87/107/87 +vt 0.787136 0.722813 +f 152/108/152 178/15/178 177/21/177 +vt 0.826631 0.731436 +f 118/109/118 148/105/148 152/108/152 +vt 0.873369 0.731436 +f 115/106/115 118/109/118 86/110/86 +vt 0.912864 0.722813 +f 87/107/87 86/110/86 61/111/61 +f 69/84/69 61/111/61 45/89/45 +f 148/105/148 178/15/178 152/108/152 +f 115/106/115 148/105/148 118/109/118 +f 87/107/87 115/106/115 86/110/86 +f 69/84/69 87/107/87 61/111/61 +vt 0.782083 0.663125 +f 156/112/156 177/21/177 176/28/176 +vt 0.815623 0.672879 +f 122/113/122 152/108/152 156/112/156 +vt 0.850000 0.676208 +f 90/114/90 118/109/118 122/113/122 +vt 0.884377 0.672879 +f 86/110/86 90/114/90 68/115/68 +vt 0.917917 0.663125 +f 61/111/61 68/115/68 44/116/44 +f 45/89/45 44/116/44 29/95/29 +f 152/108/152 177/21/177 156/112/156 +f 118/109/118 152/108/152 122/113/122 +f 86/110/86 118/109/118 90/114/90 +f 61/111/61 86/110/86 68/115/68 +f 45/89/45 61/111/61 44/116/44 +vt 0.650000 0.058736 +vt 0.450000 0.058736 +vt 0.550000 0.000000 +f 198/117/198 206/118/206 175/119/175 +vt 0.650000 0.117472 +vt 0.550000 0.097279 +f 220/120/220 228/121/228 198/117/198 +vt 0.450000 0.117472 +f 228/121/228 240/122/240 206/118/206 +f 198/117/198 228/121/228 206/118/206 +vt 0.650000 0.176208 +vt 0.586738 0.151034 +f 236/123/236 252/124/252 220/120/220 +vt 0.513262 0.151034 +f 252/124/252 260/125/260 228/121/228 +vt 0.450000 0.176208 +f 260/125/260 272/126/272 240/122/240 +f 220/120/220 252/124/252 228/121/228 +f 260/125/260 240/122/240 228/121/228 +vt 0.650000 0.234944 +vt 0.604892 0.217953 +f 256/127/256 268/128/268 236/123/236 +vt 0.550000 0.207652 +f 268/128/268 282/129/282 252/124/252 +vt 0.495108 0.217953 +f 282/129/282 290/130/290 260/125/260 +vt 0.450000 0.234944 +f 290/130/290 294/131/294 272/126/272 +f 236/123/236 268/128/268 252/124/252 +f 252/124/252 282/129/282 260/125/260 +f 290/130/290 272/126/272 260/125/260 +vt 0.650000 0.293680 +vt 0.612864 0.277187 +f 264/132/264 286/133/286 256/127/256 +vt 0.573369 0.268564 +f 286/133/286 304/134/304 268/128/268 +vt 0.526631 0.268564 +f 304/134/304 308/135/308 282/129/282 +vt 0.487136 0.277187 +f 308/135/308 322/136/322 290/130/290 +vt 0.450000 0.293681 +f 322/136/322 318/137/318 294/131/294 +f 256/127/256 286/133/286 268/128/268 +f 268/128/268 304/134/304 282/129/282 +f 308/135/308 290/130/290 282/129/282 +f 322/136/322 294/131/294 290/130/290 +vt 0.650000 0.352416 +vt 0.617917 0.336875 +f 280/138/280 298/139/298 264/132/264 +vt 0.584377 0.327121 +f 298/139/298 312/140/312 286/133/286 +vt 0.550000 0.323792 +f 312/140/312 326/141/326 304/134/304 +vt 0.515623 0.327121 +f 326/141/326 336/142/336 308/135/308 +vt 0.482083 0.336875 +f 336/142/336 340/143/340 322/136/322 +vt 0.450000 0.352416 +f 340/143/340 334/144/334 318/137/318 +f 264/132/264 298/139/298 286/133/286 +f 286/133/286 312/140/312 304/134/304 +f 304/134/304 326/141/326 308/135/308 +f 336/142/336 322/136/322 308/135/308 +f 340/143/340 318/137/318 322/136/322 +vt 0.250000 0.058736 +vt 0.350000 0.000000 +f 206/118/206 183/145/183 175/146/175 +vt 0.350000 0.097279 +f 240/122/240 210/147/210 206/118/206 +vt 0.250000 0.117472 +f 210/147/210 185/148/185 183/145/183 +f 206/118/206 210/147/210 183/145/183 +vt 0.386738 0.151034 +f 272/126/272 244/149/244 240/122/240 +vt 0.313262 0.151034 +f 244/149/244 214/150/214 210/147/210 +vt 0.250000 0.176208 +f 214/150/214 186/151/186 185/148/185 +f 240/122/240 244/149/244 210/147/210 +f 214/150/214 185/148/185 210/147/210 +vt 0.404892 0.217953 +f 294/131/294 276/152/276 272/126/272 +vt 0.350000 0.207652 +f 276/152/276 248/153/248 244/149/244 +vt 0.295108 0.217953 +f 248/153/248 215/154/215 214/150/214 +vt 0.250000 0.234944 +f 215/154/215 188/155/188 186/151/186 +f 272/126/272 276/152/276 244/149/244 +f 244/149/244 248/153/248 214/150/214 +f 215/154/215 186/151/186 214/150/214 +vt 0.412864 0.277187 +f 318/137/318 302/156/302 294/131/294 +vt 0.373369 0.268564 +f 302/156/302 277/157/277 276/152/276 +vt 0.326631 0.268564 +f 277/157/277 245/158/245 248/153/248 +vt 0.287136 0.277187 +f 245/158/245 211/159/211 215/154/215 +vt 0.250000 0.293681 +f 211/159/211 189/160/189 188/155/188 +f 294/131/294 302/156/302 276/152/276 +f 276/152/276 277/157/277 248/153/248 +f 245/158/245 215/154/215 248/153/248 +f 211/159/211 188/155/188 215/154/215 +vt 0.417917 0.336875 +f 334/144/334 319/161/319 318/137/318 +vt 0.384377 0.327121 +f 319/161/319 295/162/295 302/156/302 +vt 0.350000 0.323792 +f 295/162/295 273/163/273 277/157/277 +vt 0.315623 0.327121 +f 273/163/273 241/164/241 245/158/245 +vt 0.282083 0.336875 +f 241/164/241 207/165/207 211/159/211 +vt 0.250000 0.352416 +f 207/165/207 191/166/191 189/160/189 +f 318/137/318 319/161/319 302/156/302 +f 302/156/302 295/162/295 277/157/277 +f 277/157/277 273/163/273 245/158/245 +f 241/164/241 211/159/211 245/158/245 +f 207/165/207 189/160/189 211/159/211 +vt 0.050000 0.058736 +vt 0.150000 0.000000 +f 183/145/183 154/167/154 175/168/175 +vt 0.150000 0.097279 +f 185/148/185 150/169/150 183/145/183 +vt 0.050000 0.117472 +f 150/169/150 120/170/120 154/167/154 +f 150/169/150 154/167/154 183/145/183 +vt 0.186738 0.151034 +f 186/151/186 146/171/146 185/148/185 +vt 0.113262 0.151034 +f 146/171/146 116/172/116 150/169/150 +vt 0.050000 0.176208 +f 116/172/116 88/173/88 120/170/120 +f 185/148/185 146/171/146 150/169/150 +f 116/172/116 120/170/120 150/169/150 +vt 0.204892 0.217953 +f 188/155/188 147/174/147 186/151/186 +vt 0.150000 0.207652 +f 147/174/147 114/175/114 146/171/146 +vt 0.095108 0.217953 +f 114/175/114 84/176/84 116/172/116 +vt 0.050000 0.234944 +f 84/176/84 66/177/66 88/173/88 +f 186/151/186 147/174/147 146/171/146 +f 114/175/114 116/172/116 146/171/146 +f 84/176/84 88/173/88 116/172/116 +vt 0.212864 0.277187 +f 189/160/189 151/178/151 188/155/188 +vt 0.173369 0.268564 +f 151/178/151 117/179/117 147/174/147 +vt 0.126632 0.268564 +f 117/179/117 85/180/85 114/175/114 +vt 0.087136 0.277187 +f 85/180/85 60/181/60 84/176/84 +vt 0.050000 0.293681 +f 60/181/60 42/182/42 66/177/66 +f 188/155/188 151/178/151 147/174/147 +f 147/174/147 117/179/117 114/175/114 +f 85/180/85 84/176/84 114/175/114 +f 60/181/60 66/177/66 84/176/84 +vt 0.217917 0.336875 +f 191/166/191 155/183/155 189/160/189 +vt 0.184377 0.327121 +f 155/183/155 121/184/121 151/178/151 +vt 0.150000 0.323792 +f 121/184/121 89/185/89 117/179/117 +vt 0.115623 0.327121 +f 89/185/89 67/186/67 85/180/85 +vt 0.082083 0.336875 +f 67/186/67 43/187/43 60/181/60 +vt 0.050000 0.352416 +f 43/187/43 28/188/28 42/182/42 +f 189/160/189 155/183/155 151/178/151 +f 151/178/151 121/184/121 117/179/117 +f 89/185/89 85/180/85 117/179/117 +f 67/186/67 60/181/60 85/180/85 +f 43/187/43 42/182/42 60/181/60 +vt 1.050000 0.058736 +vt 0.850000 0.058736 +vt 0.950000 0.000000 +f 154/189/154 162/190/162 175/191/175 +vt -0.050000 0.097279 +f 120/170/120 132/192/132 154/167/154 +vt 0.950000 0.097279 +vt 0.850000 0.117472 +f 132/193/132 140/194/140 162/190/162 +f 132/193/132 162/190/162 154/189/154 +vt -0.013262 0.151034 +f 88/173/88 100/195/100 120/170/120 +vt 0.986738 0.151034 +vt 0.913262 0.151034 +f 100/196/100 108/197/108 132/193/132 +vt 0.850000 0.176208 +f 108/197/108 124/198/124 140/194/140 +f 120/170/120 100/195/100 132/192/132 +f 108/197/108 140/194/140 132/193/132 +vt 0.004893 0.217953 +f 66/177/66 70/199/70 88/173/88 +vt 1.004890 0.217953 +vt 0.950000 0.207652 +f 70/200/70 78/201/78 100/196/100 +vt 0.895108 0.217953 +f 78/201/78 92/202/92 108/197/108 +vt 0.850000 0.234944 +f 92/202/92 104/203/104 124/198/124 +f 88/173/88 70/199/70 100/195/100 +f 78/201/78 108/197/108 100/196/100 +f 92/202/92 124/198/124 108/197/108 +vt 0.012864 0.277187 +f 42/182/42 38/204/38 66/177/66 +vt 1.012860 0.277187 +vt 0.973369 0.268564 +f 38/205/38 52/206/52 70/200/70 +vt 0.926631 0.268564 +f 52/206/52 56/207/56 78/201/78 +vt 0.887136 0.277187 +f 56/207/56 74/208/74 92/202/92 +vt 0.850000 0.293680 +f 74/208/74 96/209/96 104/203/104 +f 66/177/66 38/204/38 70/199/70 +f 70/200/70 52/206/52 78/201/78 +f 56/207/56 92/202/92 78/201/78 +f 74/208/74 104/203/104 92/202/92 +vt 0.017917 0.336875 +f 28/188/28 20/210/20 42/182/42 +vt -0.015623 0.327121 +f 20/210/20 24/211/24 38/204/38 +vt 0.984377 0.327121 +vt 0.950000 0.323792 +f 24/212/24 34/213/34 52/206/52 +vt 0.915623 0.327121 +f 34/213/34 48/214/48 56/207/56 +vt 0.882083 0.336875 +f 48/214/48 62/215/62 74/208/74 +vt 0.850000 0.352416 +f 62/215/62 82/216/82 96/209/96 +f 42/182/42 20/210/20 38/204/38 +f 38/205/38 24/212/24 52/206/52 +f 34/213/34 56/207/56 52/206/52 +f 48/214/48 74/208/74 56/207/56 +f 62/215/62 96/209/96 74/208/74 +vt 0.750000 0.000000 +f 162/190/162 198/117/198 175/217/175 +vt 0.750000 0.097279 +f 140/194/140 174/218/174 162/190/162 +f 174/218/174 220/120/220 198/117/198 +f 174/218/174 198/117/198 162/190/162 +vt 0.786738 0.151034 +f 124/198/124 166/219/166 140/194/140 +vt 0.713262 0.151034 +f 166/219/166 194/220/194 174/218/174 +f 194/220/194 236/123/236 220/120/220 +f 140/194/140 166/219/166 174/218/174 +f 194/220/194 220/120/220 174/218/174 +vt 0.804893 0.217953 +f 104/203/104 136/221/136 124/198/124 +vt 0.750000 0.207652 +f 136/221/136 172/222/172 166/219/166 +vt 0.695108 0.217953 +f 172/222/172 224/223/224 194/220/194 +f 224/223/224 256/127/256 236/123/236 +f 124/198/124 136/221/136 166/219/166 +f 172/222/172 194/220/194 166/219/166 +f 224/223/224 236/123/236 194/220/194 +vt 0.812864 0.277187 +f 96/209/96 128/224/128 104/203/104 +vt 0.773368 0.268564 +f 128/224/128 158/225/158 136/221/136 +vt 0.726632 0.268564 +f 158/225/158 202/226/202 172/222/172 +vt 0.687136 0.277187 +f 202/226/202 232/227/232 224/223/224 +f 232/227/232 264/132/264 256/127/256 +f 104/203/104 128/224/128 136/221/136 +f 136/221/136 158/225/158 172/222/172 +f 202/226/202 224/223/224 172/222/172 +f 232/227/232 256/127/256 224/223/224 +vt 0.817917 0.336875 +f 82/216/82 112/228/112 96/209/96 +vt 0.784377 0.327121 +f 112/228/112 144/229/144 128/224/128 +vt 0.750000 0.323792 +f 144/229/144 170/230/170 158/225/158 +vt 0.715623 0.327121 +f 170/230/170 218/231/218 202/226/202 +vt 0.682083 0.336875 +f 218/231/218 250/232/250 232/227/232 +f 250/232/250 280/138/280 264/132/264 +f 96/209/96 112/228/112 128/224/128 +f 128/224/128 144/229/144 158/225/158 +f 158/225/158 170/230/170 202/226/202 +f 218/231/218 232/227/232 202/226/202 +f 250/232/250 264/132/264 232/227/232 +vt 0.731927 0.599277 +f 176/28/176 208/27/208 200/233/200 +vt 0.700727 0.611555 +f 208/27/208 242/26/242 230/234/230 +vt 0.715567 0.549885 +f 200/233/200 230/234/230 222/235/222 +f 208/27/208 230/234/230 200/233/200 +vt 0.668719 0.618520 +f 242/26/242 274/25/274 262/236/262 +vt 0.684916 0.559540 +f 230/234/230 262/236/262 254/237/254 +vt 0.700000 0.500000 +f 222/235/222 254/237/254 238/238/238 +f 242/26/242 262/236/262 230/234/230 +f 230/234/230 254/237/254 222/235/222 +vt 0.631281 0.618520 +f 274/25/274 296/24/296 292/239/292 +vt 0.650000 0.560069 +f 262/236/262 292/239/292 284/240/284 +vt 0.666667 0.500000 +f 254/237/254 284/240/284 270/241/270 +vt 0.684433 0.450115 +f 238/238/238 270/241/270 257/242/257 +f 262/236/262 274/25/274 292/239/292 +f 262/236/262 284/240/284 254/237/254 +f 238/238/238 254/237/254 270/241/270 +vt 0.599273 0.611555 +f 296/24/296 320/22/320 324/243/324 +vt 0.615084 0.559540 +f 292/239/292 324/243/324 310/244/310 +vt 0.633333 0.500000 +f 284/240/284 310/244/310 306/245/306 +vt 0.650000 0.449696 +f 270/241/270 306/245/306 287/246/287 +vt 0.668073 0.400723 +f 257/242/257 287/246/287 265/247/265 +f 292/239/292 296/24/296 324/243/324 +f 284/240/284 292/239/292 310/244/310 +f 270/241/270 284/240/284 306/245/306 +f 257/242/257 270/241/270 287/246/287 +vt 0.568073 0.599277 +f 320/22/320 335/23/335 342/248/342 +vt 0.584433 0.549885 +f 324/243/324 342/248/342 338/249/338 +vt 0.600000 0.500000 +f 310/244/310 338/249/338 328/250/328 +vt 0.615567 0.450115 +f 306/245/306 328/250/328 313/251/313 +vt 0.631927 0.400723 +f 287/246/287 313/251/313 299/252/299 +f 265/247/265 299/252/299 280/138/280 +f 324/243/324 320/22/320 342/248/342 +f 310/244/310 324/243/324 338/249/338 +f 306/245/306 310/244/310 328/250/328 +f 306/245/306 313/251/313 287/246/287 +f 265/247/265 287/246/287 299/252/299 +vt 0.531927 0.599277 +f 335/23/335 343/50/343 349/253/349 +vt 0.500727 0.611555 +f 343/50/343 339/49/339 355/254/355 +vt 0.515567 0.549885 +f 349/253/349 355/254/355 361/255/361 +f 343/50/343 355/254/355 349/253/349 +vt 0.468719 0.618520 +f 339/49/339 329/48/329 347/256/347 +vt 0.484916 0.559540 +f 355/254/355 347/256/347 359/257/359 +vt 0.500000 0.500000 +f 361/255/361 359/257/359 362/258/362 +f 339/49/339 347/256/347 355/254/355 +f 355/254/355 359/257/359 361/255/361 +vt 0.431281 0.618520 +f 329/48/329 315/47/315 333/259/333 +vt 0.450000 0.560069 +f 347/256/347 333/259/333 351/260/351 +vt 0.466667 0.500000 +f 359/257/359 351/260/351 357/261/357 +vt 0.484433 0.450115 +f 362/258/362 357/261/357 360/262/360 +f 347/256/347 329/48/329 333/259/333 +f 347/256/347 351/260/351 359/257/359 +f 362/258/362 359/257/359 357/261/357 +vt 0.399273 0.611555 +f 315/47/315 301/45/301 317/263/317 +vt 0.415084 0.559540 +f 333/259/333 317/263/317 332/264/332 +vt 0.433333 0.500000 +f 351/260/351 332/264/332 345/265/345 +vt 0.450000 0.449696 +f 357/261/357 345/265/345 353/266/353 +vt 0.468073 0.400723 +f 360/262/360 353/266/353 348/267/348 +f 333/259/333 315/47/315 317/263/317 +f 351/260/351 333/259/333 332/264/332 +f 357/261/357 351/260/351 345/265/345 +f 360/262/360 357/261/357 353/266/353 +vt 0.368073 0.599277 +f 301/45/301 281/46/281 300/268/300 +vt 0.384433 0.549885 +f 317/263/317 300/268/300 314/269/314 +vt 0.400000 0.500000 +f 332/264/332 314/269/314 327/270/327 +vt 0.415568 0.450115 +f 345/265/345 327/270/327 337/271/337 +vt 0.431927 0.400723 +f 353/266/353 337/271/337 341/272/341 +f 348/267/348 341/272/341 334/144/334 +f 317/263/317 301/45/301 300/268/300 +f 332/264/332 317/263/317 314/269/314 +f 345/265/345 332/264/332 327/270/327 +f 345/265/345 337/271/337 353/266/353 +f 348/267/348 353/266/353 341/272/341 +vt 0.331927 0.599277 +f 281/46/281 251/72/251 266/273/266 +vt 0.300727 0.611555 +f 251/72/251 219/71/219 234/274/234 +vt 0.315568 0.549885 +f 266/273/266 234/274/234 259/275/259 +f 251/72/251 234/274/234 266/273/266 +vt 0.268719 0.618520 +f 219/71/219 190/70/190 204/276/204 +vt 0.284916 0.559540 +f 234/274/234 204/276/204 227/277/227 +vt 0.300000 0.500000 +f 259/275/259 227/277/227 237/278/237 +f 219/71/219 204/276/204 234/274/234 +f 234/274/234 227/277/227 259/275/259 +vt 0.231281 0.618520 +f 190/70/190 145/69/145 160/279/160 +vt 0.250000 0.560069 +f 204/276/204 160/279/160 192/280/192 +vt 0.266667 0.500000 +f 227/277/227 192/280/192 195/281/195 +vt 0.284433 0.450115 +f 237/278/237 195/281/195 221/282/221 +f 204/276/204 190/70/190 160/279/160 +f 204/276/204 192/280/192 227/277/227 +f 237/278/237 227/277/227 195/281/195 +vt 0.199273 0.611555 +f 145/69/145 113/67/113 130/283/130 +vt 0.215084 0.559540 +f 160/279/160 130/283/130 138/284/138 +vt 0.233333 0.500000 +f 192/280/192 138/284/138 167/285/167 +vt 0.250000 0.449696 +f 195/281/195 167/285/167 193/286/193 +vt 0.268073 0.400723 +f 221/282/221 193/286/193 199/287/199 +f 160/279/160 145/69/145 130/283/130 +f 192/280/192 160/279/160 138/284/138 +f 195/281/195 192/280/192 167/285/167 +f 221/282/221 195/281/195 193/286/193 +vt 0.168073 0.599277 +f 113/67/113 83/68/83 98/288/98 +vt 0.184433 0.549885 +f 130/283/130 98/288/98 106/289/106 +vt 0.200000 0.500000 +f 138/284/138 106/289/106 125/290/125 +vt 0.215568 0.450115 +f 167/285/167 125/290/125 143/291/143 +vt 0.231927 0.400723 +f 193/286/193 143/291/143 163/292/163 +f 199/287/199 163/292/163 191/166/191 +f 130/283/130 113/67/113 98/288/98 +f 138/284/138 130/283/130 106/289/106 +f 138/284/138 125/290/125 167/285/167 +f 167/285/167 143/291/143 193/286/193 +f 199/287/199 193/286/193 163/292/163 +vt 0.131927 0.599277 +f 83/68/83 65/100/65 64/293/64 +vt 0.100727 0.611555 +f 65/100/65 51/99/51 47/294/47 +vt 0.115567 0.549885 +f 64/293/64 47/294/47 50/295/50 +f 65/100/65 47/294/47 64/293/64 +vt 0.068719 0.618520 +f 51/99/51 37/97/37 33/296/33 +vt 0.084916 0.559540 +f 47/294/47 33/296/33 32/297/32 +vt 0.100000 0.500000 +f 50/295/50 32/297/32 35/298/35 +f 51/99/51 33/296/33 47/294/47 +f 47/294/47 32/297/32 50/295/50 +vt 0.031281 0.618520 +f 37/97/37 27/98/27 19/299/19 +vt 0.050000 0.560069 +f 33/296/33 19/299/19 13/300/13 +vt 0.066667 0.500000 +f 32/297/32 13/300/13 17/301/17 +vt 0.084433 0.450115 +f 35/298/35 17/301/17 25/302/25 +f 37/97/37 19/299/19 33/296/33 +f 33/296/33 13/300/13 32/297/32 +f 32/297/32 17/301/17 35/298/35 +vt 0.999273 0.611555 +f 27/96/27 23/94/23 11/303/11 +vt -0.000727 0.611555 +vt 0.015084 0.559540 +f 19/299/19 11/304/11 7/305/7 +vt 0.033333 0.500000 +f 13/300/13 7/305/7 5/306/5 +vt 0.050000 0.449696 +f 17/301/17 5/306/5 9/307/9 +vt 0.068073 0.400723 +f 25/302/25 9/307/9 21/308/21 +f 19/299/19 27/98/27 11/304/11 +f 13/300/13 19/299/19 7/305/7 +f 13/300/13 5/306/5 17/301/17 +f 25/302/25 17/301/17 9/307/9 +vt 0.968073 0.599277 +f 23/94/23 29/95/29 15/309/15 +vt 0.984433 0.549885 +f 11/303/11 15/309/15 3/310/3 +vt 1.015080 0.559540 +vt 1.000000 0.500000 +f 7/311/7 3/310/3 1/312/1 +vt 0.000000 0.500000 +vt 0.015568 0.450115 +f 5/306/5 1/313/1 2/314/2 +vt 0.031927 0.400723 +f 9/307/9 2/314/2 14/315/14 +f 21/308/21 14/315/14 28/188/28 +f 11/303/11 23/94/23 15/309/15 +f 7/311/7 11/303/11 3/310/3 +f 7/305/7 1/313/1 5/306/5 +f 5/306/5 2/314/2 9/307/9 +f 9/307/9 14/315/14 21/308/21 +vt 0.931927 0.599277 +f 29/95/29 44/116/44 22/316/22 +vt 0.900727 0.611555 +f 44/116/44 68/115/68 40/317/40 +vt 0.915568 0.549885 +f 22/316/22 40/317/40 26/318/26 +f 44/116/44 40/317/40 22/316/22 +vt 0.868719 0.618520 +f 68/115/68 90/114/90 72/319/72 +vt 0.884916 0.559540 +f 40/317/40 72/319/72 53/320/53 +vt 0.900000 0.500000 +f 26/318/26 53/320/53 36/321/36 +f 68/115/68 72/319/72 40/317/40 +f 40/317/40 53/320/53 26/318/26 +vt 0.831281 0.618520 +f 90/114/90 122/113/122 102/322/102 +vt 0.850000 0.560069 +f 72/319/72 102/322/102 80/323/80 +vt 0.866667 0.500000 +f 53/320/53 80/323/80 58/324/58 +vt 0.884433 0.450115 +f 36/321/36 58/324/58 49/325/49 +f 90/114/90 102/322/102 72/319/72 +f 72/319/72 80/323/80 53/320/53 +f 53/320/53 58/324/58 36/321/36 +vt 0.799273 0.611555 +f 122/113/122 156/112/156 134/326/134 +vt 0.815084 0.559540 +f 102/322/102 134/326/134 110/327/110 +vt 0.833333 0.500000 +f 80/323/80 110/327/110 94/328/94 +vt 0.850000 0.449696 +f 58/324/58 94/328/94 75/329/75 +vt 0.868073 0.400723 +f 49/325/49 75/329/75 63/330/63 +f 102/322/102 122/113/122 134/326/134 +f 80/323/80 102/322/102 110/327/110 +f 80/323/80 94/328/94 58/324/58 +f 49/325/49 58/324/58 75/329/75 +vt 0.768073 0.599277 +f 156/112/156 176/28/176 164/331/164 +vt 0.784433 0.549885 +f 134/326/134 164/331/164 141/332/141 +vt 0.800000 0.500000 +f 110/327/110 141/332/141 126/333/126 +vt 0.815568 0.450115 +f 94/328/94 126/333/126 105/334/105 +vt 0.831927 0.400723 +f 75/329/75 105/334/105 97/335/97 +f 63/330/63 97/335/97 82/216/82 +f 134/326/134 156/112/156 164/331/164 +f 110/327/110 134/326/134 141/332/141 +f 110/327/110 126/333/126 94/328/94 +f 94/328/94 105/334/105 75/329/75 +f 75/329/75 97/335/97 63/330/63 +f 348/267/348 334/144/334 340/143/340 +vt 0.499273 0.388445 +f 352/336/352 340/143/340 336/142/336 +f 360/262/360 348/267/348 352/336/352 +f 352/336/352 348/267/348 340/143/340 +vt 0.531281 0.381480 +f 344/337/344 336/142/336 326/141/326 +vt 0.515084 0.440460 +f 356/338/356 352/336/352 344/337/344 +f 362/258/362 360/262/360 356/338/356 +f 344/337/344 352/336/352 336/142/336 +f 356/338/356 360/262/360 352/336/352 +vt 0.568719 0.381480 +f 312/140/312 330/339/330 326/141/326 +vt 0.550000 0.439931 +f 330/339/330 350/340/350 344/337/344 +vt 0.533333 0.500000 +f 358/341/358 356/338/356 350/340/350 +f 358/341/358 361/255/361 362/258/362 +f 330/339/330 344/337/344 326/141/326 +f 350/340/350 356/338/356 344/337/344 +f 358/341/358 362/258/362 356/338/356 +vt 0.600727 0.388445 +f 298/139/298 316/342/316 312/140/312 +vt 0.584916 0.440460 +f 316/342/316 331/343/331 330/339/330 +vt 0.566667 0.500000 +f 331/343/331 346/344/346 350/340/350 +vt 0.550000 0.550304 +f 346/344/346 354/345/354 358/341/358 +f 354/345/354 349/253/349 361/255/361 +f 316/342/316 330/339/330 312/140/312 +f 331/343/331 350/340/350 330/339/330 +f 346/344/346 358/341/358 350/340/350 +f 354/345/354 361/255/361 358/341/358 +f 280/138/280 299/252/299 298/139/298 +f 299/252/299 313/251/313 316/342/316 +f 313/251/313 328/250/328 331/343/331 +f 328/250/328 338/249/338 346/344/346 +f 342/248/342 354/345/354 338/249/338 +f 342/248/342 335/23/335 349/253/349 +f 299/252/299 316/342/316 298/139/298 +f 313/251/313 331/343/331 316/342/316 +f 328/250/328 346/344/346 331/343/331 +f 338/249/338 354/345/354 346/344/346 +f 342/248/342 349/253/349 354/345/354 +f 199/287/199 191/166/191 207/165/207 +vt 0.299273 0.388445 +f 229/346/229 207/165/207 241/164/241 +f 221/282/221 199/287/199 229/346/229 +f 229/346/229 199/287/199 207/165/207 +vt 0.331281 0.381480 +f 261/347/261 241/164/241 273/163/273 +vt 0.315084 0.440460 +f 253/348/253 229/346/229 261/347/261 +f 237/278/237 221/282/221 253/348/253 +f 261/347/261 229/346/229 241/164/241 +f 253/348/253 221/282/221 229/346/229 +vt 0.368719 0.381480 +f 295/162/295 291/349/291 273/163/273 +vt 0.350000 0.439931 +f 291/349/291 283/350/283 261/347/261 +vt 0.333333 0.500000 +f 269/351/269 253/348/253 283/350/283 +f 269/351/269 259/275/259 237/278/237 +f 291/349/291 261/347/261 273/163/273 +f 283/350/283 253/348/253 261/347/261 +f 269/351/269 237/278/237 253/348/253 +vt 0.400727 0.388445 +f 319/161/319 323/352/323 295/162/295 +vt 0.384916 0.440460 +f 323/352/323 309/353/309 291/349/291 +vt 0.366667 0.500000 +f 309/353/309 305/354/305 283/350/283 +vt 0.350000 0.550304 +f 305/354/305 289/355/289 269/351/269 +f 289/355/289 266/273/266 259/275/259 +f 323/352/323 291/349/291 295/162/295 +f 309/353/309 283/350/283 291/349/291 +f 305/354/305 269/351/269 283/350/283 +f 289/355/289 259/275/259 269/351/269 +f 334/144/334 341/272/341 319/161/319 +f 341/272/341 337/271/337 323/352/323 +f 337/271/337 327/270/327 309/353/309 +f 327/270/327 314/269/314 305/354/305 +f 300/268/300 289/355/289 314/269/314 +f 300/268/300 281/46/281 266/273/266 +f 341/272/341 323/352/323 319/161/319 +f 337/271/337 309/353/309 323/352/323 +f 327/270/327 305/354/305 309/353/309 +f 314/269/314 289/355/289 305/354/305 +f 300/268/300 266/273/266 289/355/289 +f 21/308/21 28/188/28 43/187/43 +vt 0.099273 0.388445 +f 39/356/39 43/187/43 67/186/67 +f 25/302/25 21/308/21 39/356/39 +f 39/356/39 21/308/21 43/187/43 +vt 0.131281 0.381480 +f 71/357/71 67/186/67 89/185/89 +vt 0.115084 0.440460 +f 54/358/54 39/356/39 71/357/71 +f 35/298/35 25/302/25 54/358/54 +f 71/357/71 39/356/39 67/186/67 +f 54/358/54 25/302/25 39/356/39 +vt 0.168719 0.381480 +f 121/184/121 101/359/101 89/185/89 +vt 0.150000 0.439931 +f 79/360/79 71/357/71 101/359/101 +vt 0.133333 0.500000 +f 57/361/57 54/358/54 79/360/79 +f 50/295/50 35/298/35 57/361/57 +f 101/359/101 71/357/71 89/185/89 +f 79/360/79 54/358/54 71/357/71 +f 57/361/57 35/298/35 54/358/54 +vt 0.200727 0.388445 +f 155/183/155 133/362/133 121/184/121 +vt 0.184916 0.440460 +f 133/362/133 109/363/109 101/359/101 +vt 0.166667 0.500000 +f 109/363/109 93/364/93 79/360/79 +vt 0.150000 0.550304 +f 76/365/76 57/361/57 93/364/93 +f 76/365/76 64/293/64 50/295/50 +f 133/362/133 101/359/101 121/184/121 +f 109/363/109 79/360/79 101/359/101 +f 93/364/93 57/361/57 79/360/79 +f 76/365/76 50/295/50 57/361/57 +f 191/166/191 163/292/163 155/183/155 +f 163/292/163 143/291/143 133/362/133 +f 143/291/143 125/290/125 109/363/109 +f 106/289/106 93/364/93 125/290/125 +f 98/288/98 76/365/76 106/289/106 +f 83/68/83 64/293/64 98/288/98 +f 163/292/163 133/362/133 155/183/155 +f 143/291/143 109/363/109 133/362/133 +f 125/290/125 93/364/93 109/363/109 +f 106/289/106 76/365/76 93/364/93 +f 98/288/98 64/293/64 76/365/76 +f 63/330/63 82/216/82 62/215/62 +vt 0.899273 0.388445 +f 46/366/46 62/215/62 48/214/48 +f 49/325/49 63/330/63 46/366/46 +f 46/366/46 63/330/63 62/215/62 +vt 0.931281 0.381480 +f 30/367/30 48/214/48 34/213/34 +vt 0.915084 0.440460 +f 31/368/31 46/366/46 30/367/30 +f 36/321/36 49/325/49 31/368/31 +f 30/367/30 46/366/46 48/214/48 +f 31/368/31 49/325/49 46/366/46 +vt 0.968719 0.381480 +f 24/212/24 16/369/16 34/213/34 +vt 0.950000 0.439931 +f 12/370/12 30/367/30 16/369/16 +vt 0.933333 0.500000 +f 18/371/18 31/368/31 12/370/12 +f 26/318/26 36/321/36 18/371/18 +f 16/369/16 30/367/30 34/213/34 +f 12/370/12 31/368/31 30/367/30 +f 18/371/18 36/321/36 31/368/31 +vt 0.000727 0.388445 +f 20/210/20 8/372/8 24/211/24 +vt 1.000730 0.388445 +vt 0.984916 0.440460 +f 8/373/8 4/374/4 16/369/16 +vt 0.966667 0.500000 +f 4/374/4 6/375/6 12/370/12 +vt 0.950000 0.550304 +f 10/376/10 18/371/18 6/375/6 +f 10/376/10 22/316/22 26/318/26 +f 8/373/8 16/369/16 24/212/24 +f 4/374/4 12/370/12 16/369/16 +f 6/375/6 18/371/18 12/370/12 +f 10/376/10 26/318/26 18/371/18 +f 28/188/28 14/315/14 20/210/20 +f 14/315/14 2/314/2 8/372/8 +vt -0.015084 0.440460 +f 2/314/2 1/313/1 4/377/4 +f 3/310/3 6/375/6 1/312/1 +f 15/309/15 10/376/10 3/310/3 +f 29/95/29 22/316/22 15/309/15 +f 14/315/14 8/372/8 20/210/20 +f 2/314/2 4/377/4 8/372/8 +f 1/312/1 6/375/6 4/374/4 +f 3/310/3 10/376/10 6/375/6 +f 15/309/15 22/316/22 10/376/10 +f 265/247/265 280/138/280 250/232/250 +vt 0.699273 0.388445 +f 233/378/233 250/232/250 218/231/218 +f 257/242/257 265/247/265 233/378/233 +f 233/378/233 265/247/265 250/232/250 +vt 0.731281 0.381480 +f 203/379/203 218/231/218 170/230/170 +vt 0.715084 0.440460 +f 225/380/225 233/378/233 203/379/203 +f 238/238/238 257/242/257 225/380/225 +f 203/379/203 233/378/233 218/231/218 +f 225/380/225 257/242/257 233/378/233 +vt 0.768719 0.381480 +f 144/229/144 159/381/159 170/230/170 +vt 0.750000 0.439931 +f 159/381/159 171/382/171 203/379/203 +vt 0.733333 0.500000 +f 196/383/196 225/380/225 171/382/171 +f 196/383/196 222/235/222 238/238/238 +f 159/381/159 203/379/203 170/230/170 +f 171/382/171 225/380/225 203/379/203 +f 196/383/196 238/238/238 225/380/225 +vt 0.800727 0.388445 +f 112/228/112 129/384/129 144/229/144 +vt 0.784917 0.440460 +f 129/384/129 137/385/137 159/381/159 +vt 0.766667 0.500000 +f 137/385/137 168/386/168 171/382/171 +vt 0.750000 0.550304 +f 168/386/168 173/387/173 196/383/196 +f 173/387/173 200/233/200 222/235/222 +f 129/384/129 159/381/159 144/229/144 +f 137/385/137 171/382/171 159/381/159 +f 168/386/168 196/383/196 171/382/171 +f 173/387/173 222/235/222 196/383/196 +f 82/216/82 97/335/97 112/228/112 +f 97/335/97 105/334/105 129/384/129 +f 105/334/105 126/333/126 137/385/137 +f 141/332/141 168/386/168 126/333/126 +f 164/331/164 173/387/173 141/332/141 +f 164/331/164 176/28/176 200/233/200 +f 97/335/97 129/384/129 112/228/112 +f 105/334/105 137/385/137 129/384/129 +f 126/333/126 168/386/168 137/385/137 +f 141/332/141 173/387/173 168/386/168 +f 164/331/164 200/233/200 173/387/173 +# 720 faces, 387 coords texture + +# End of File diff --git a/platform/glfw/example_custom_drawable_style_layer.cpp b/platform/glfw/example_custom_drawable_style_layer.cpp new file mode 100644 index 00000000000..0ea02911553 --- /dev/null +++ b/platform/glfw/example_custom_drawable_style_layer.cpp @@ -0,0 +1,606 @@ +#include "example_custom_drawable_style_layer.hpp" + +#if MLN_DRAWABLE_RENDERER + +#include +#include +#include +#include +#include + +#include +#include +#include + +#define TINYOBJLOADER_IMPLEMENTATION +#include "tiny_obj_loader.h" + +ExampleCustomDrawableStyleLayerHost::ExampleCustomDrawableStyleLayerHost(const std::string& assetsPath_) + : assetsPath(assetsPath_) {} + +ExampleCustomDrawableStyleLayerHost::~ExampleCustomDrawableStyleLayerHost() {} + +void ExampleCustomDrawableStyleLayerHost::initialize() {} + +void ExampleCustomDrawableStyleLayerHost::deinitialize() {} + +void ExampleCustomDrawableStyleLayerHost::update(Interface& interface) { + // if we have built our drawable(s) already, either update or skip + if (interface.getDrawableCount() == 0) { + createDrawables(interface); + return; + } +} + +mbgl::Point ExampleCustomDrawableStyleLayerHost::project(const mbgl::LatLng& c, const mbgl::TransformState& s) { + mbgl::LatLng unwrappedLatLng = c.wrapped(); + unwrappedLatLng.unwrapForShortestPath(s.getLatLng(mbgl::LatLng::Wrapped)); + return mbgl::Projection::project(unwrappedLatLng, s.getScale()); +} + +void ExampleCustomDrawableStyleLayerHost::createDrawables(Interface& interface) { + constexpr float extent = mbgl::util::EXTENT; + + // add classic polylines + { + using namespace mbgl; + + // set tile + interface.setTileID({11, 327, 792}); + + constexpr auto numLines = 6; + Interface::LineOptions options[numLines]{ + {/*geometry=*/{}, + /*blur=*/0.0f, + /*opacity=*/1.0f, + /*gapWidth=*/0.0f, + /*offset=*/0.0f, + /*width=*/8.0f, + /*color=*/Color::red()}, + + {/*geometry=*/{}, + /*blur=*/4.0f, + /*opacity=*/1.0f, + /*gapWidth=*/2.0f, + /*offset=*/-1.0f, + /*width=*/4.0f, + /*color=*/Color::blue()}, + + {/*geometry=*/{}, + /*blur=*/16.0f, + /*opacity=*/1.0f, + /*gapWidth=*/1.0f, + /*offset=*/2.0f, + /*width=*/16.0f, + /*color=*/Color(1.f, 0.5f, 0, 0.5f)}, + + {/*geometry=*/{}, + /*blur=*/2.0f, + /*opacity=*/1.0f, + /*gapWidth=*/1.0f, + /*offset=*/-2.0f, + /*width=*/2.0f, + /*color=*/Color(1.f, 1.f, 0, 0.3f)}, + + {/*geometry=*/{}, + /*blur=*/0.5f, + /*opacity=*/0.5f, + /*gapWidth=*/1.0f, + /*offset=*/0.5f, + /*width=*/0.5f, + /*color=*/Color::black()}, + + {/*geometry=*/{}, + /*blur=*/24.0f, + /*opacity=*/0.5f, + /*gapWidth=*/1.0f, + /*offset=*/-5.0f, + /*width=*/24.0f, + /*color=*/Color(1.f, 0, 1.f, 0.2f)}, + }; + + for (auto& opt : options) { + opt.geometry.beginCap = style::LineCapType::Butt; + opt.geometry.endCap = style::LineCapType::Butt; + opt.geometry.joinType = style::LineJoinType::Miter; + } + + constexpr auto numPoints = 10; + GeometryCoordinates polyline; + for (auto ipoint{0}; ipoint < numPoints; ++ipoint) { + polyline.emplace_back( + static_cast(ipoint * extent / numPoints), + static_cast(std::sin(ipoint * 2 * M_PI / numPoints) * extent / numLines / 2.f)); + } + + for (auto index{0}; index < numLines; ++index) { + for (auto& p : polyline) { + p.y += extent / numLines; + } + + // set property values + interface.setLineOptions(options[index]); + + // add polyline + interface.addPolyline(polyline, Interface::LineShaderType::Classic); + } + } + + // add wide vector polylines with tile coordinates + { + using namespace mbgl; + + // set tile + interface.setTileID({11, 327, 792}); + + constexpr auto numLines = 6; + Interface::LineOptions options[numLines]{ + {/*geometry=*/{}, + /*blur=*/0.0f, + /*opacity=*/1.0f, + /*gapWidth=*/0.0f, + /*offset=*/0.0f, + /*width=*/8.0f, + /*color=*/Color::red()}, + + {/*geometry=*/{}, + /*blur=*/4.0f, + /*opacity=*/1.0f, + /*gapWidth=*/2.0f, + /*offset=*/-1.0f, + /*width=*/4.0f, + /*color=*/Color::blue()}, + + {/*geometry=*/{}, + /*blur=*/16.0f, + /*opacity=*/1.0f, + /*gapWidth=*/1.0f, + /*offset=*/2.0f, + /*width=*/16.0f, + /*color=*/Color(1.f, 0.5f, 0, 0.5f)}, + + {/*geometry=*/{}, + /*blur=*/2.0f, + /*opacity=*/1.0f, + /*gapWidth=*/1.0f, + /*offset=*/-2.0f, + /*width=*/2.0f, + /*color=*/Color(1.f, 1.f, 0, 0.3f)}, + + {/*geometry=*/{}, + /*blur=*/0.5f, + /*opacity=*/0.5f, + /*gapWidth=*/1.0f, + /*offset=*/0.5f, + /*width=*/0.5f, + /*color=*/Color::black()}, + + {/*geometry=*/{}, + /*blur=*/24.0f, + /*opacity=*/0.5f, + /*gapWidth=*/1.0f, + /*offset=*/-5.0f, + /*width=*/24.0f, + /*color=*/Color(1.f, 0, 1.f, 0.2f)}, + }; + + for (auto& opt : options) { + opt.geometry.beginCap = style::LineCapType::Butt; + opt.geometry.endCap = style::LineCapType::Butt; + opt.geometry.joinType = style::LineJoinType::Miter; + } + + constexpr auto numPoints = 10; + GeometryCoordinates polyline; + for (auto ipoint{0}; ipoint < numPoints; ++ipoint) { + polyline.emplace_back( + static_cast(ipoint * extent / numPoints), + static_cast(std::sin(ipoint * 2 * M_PI / numPoints) * extent / numLines / 2.f)); + } + + for (auto index{0}; index < numLines; ++index) { + for (auto& p : polyline) { + if (0 == index) p.y += 0.25f * extent / numLines; + p.y += extent / numLines; + } + + // set property values + interface.setLineOptions(options[index]); + + // add polyline + interface.addPolyline(polyline, Interface::LineShaderType::WideVector); + + // add clone + for (auto& p : polyline) { + p.y += 0.05f * extent / numLines; + } + interface.addPolyline(polyline, Interface::LineShaderType::WideVector); + for (auto& p : polyline) { + p.y -= 0.05f * extent / numLines; + } + } + } + + // add fill polygon + { + using namespace mbgl; + + // set tile + interface.setTileID({11, 327, 790}); + + GeometryCollection geometry{ + { + // ring 1 + {static_cast(extent * 0.1f), static_cast(extent * 0.2f)}, + {static_cast(extent * 0.5f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.7f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.5f), static_cast(extent * 1.0f)}, + {static_cast(extent * 0.0f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.1f), static_cast(extent * 0.2f)}, + }, + { + // ring 2 + {static_cast(extent * 0.1f), static_cast(extent * 0.25f)}, + {static_cast(extent * 0.15f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.25f), static_cast(extent * 0.45f)}, + {static_cast(extent * 0.1f), static_cast(extent * 0.25f)}, + }, + }; + + // set properties + interface.setFillOptions({/*color=*/Color::green(), /*opacity=*/0.5f}); + + // add fill + interface.addFill(geometry); + } + + // add symbol + { + using namespace mbgl; + + // set tile + interface.setTileID({11, 327, 789}); + + GeometryCoordinate position{static_cast(extent * 0.0f), static_cast(extent * 0.5f)}; + + // load image + std::shared_ptr image = std::make_shared( + mbgl::decodeImage(mbgl::util::read_file(assetsPath + "puck_hat.png"))); + + // set symbol options + Interface::SymbolOptions options; + options.texture = interface.context.createTexture2D(); + options.texture->setImage(image); + options.texture->setSamplerConfiguration( + {gfx::TextureFilterType::Linear, gfx::TextureWrapType::Repeat, gfx::TextureWrapType::Repeat}); + + const std::array, 2> textureCoordinates = {{{0.0f, 0.0f}, {10.0f, 10.0f}}}; + options.size = {static_cast(image->size.width), static_cast(image->size.height)}; + + options.anchor = {0.5f, 0.95f}; + options.angleDegrees = 45.0f; + options.scaleWithMap = true; + options.pitchWithMap = false; + interface.setSymbolOptions(options); + + // add symbol + interface.addSymbol(position, textureCoordinates); + } + + { + using namespace mbgl; + + GeometryCoordinate position{static_cast(extent * 1.0f), static_cast(extent * 0.5f)}; + + // load image + std::shared_ptr image = std::make_shared( + mbgl::decodeImage(mbgl::util::read_file(assetsPath + "puck_hat.png"))); + + // set symbol options + Interface::SymbolOptions options; + options.texture = interface.context.createTexture2D(); + options.texture->setImage(image); + options.texture->setSamplerConfiguration( + {gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp}); + + options.size = {static_cast(image->size.width), static_cast(image->size.height)}; + + options.anchor = {0.5f, 0.95f}; + options.angleDegrees = 45.0f; + options.scaleWithMap = true; + options.pitchWithMap = false; + interface.setSymbolOptions(options); + + // add symbol + interface.addSymbol(position); + } + + // add polylines using wide vectors using geographic coordinates + { + using namespace mbgl; + + // add polyline with geographic coordinates + Interface::LineOptions options = {/*geometry=*/{}, + /*blur=*/0.0f, + /*opacity=*/1.0f, + /*gapWidth=*/0.0f, + /*offset=*/0.0f, + /*width=*/12.0f, + /*color=*/{.0f, .0f, .0f, .5f}}; + + options.geometry.beginCap = style::LineCapType::Square; + options.geometry.endCap = style::LineCapType::Square; + options.geometry.joinType = style::LineJoinType::Bevel; + options.geometry.type = FeatureType::LineString; + interface.setLineOptions(options); + + LineString polyline_geo{ + // San Francisco + {-122.38186800073211, 37.77466003457463}, + {-122.3869373450997, 37.774352128895615}, + {-122.38680767979824, 37.773294612880306}, + {-122.38476465260224, 37.773350946288765}, + {-122.38146223043374, 37.77194168964067}, + {-122.6813560305925, 37.666084247570964}, + {-122.26765538866474, 37.65037232584494}, + {-122.42528413673159, 38.020443518012584}, + // Seattle + {-122.34927775216809, 47.62050663596438}, + // New York + {-74.04454331829972, 40.6892168305434}, + }; + interface.addPolyline(polyline_geo, Interface::LineShaderType::WideVector); + } + + // add polylines using wide vectors in tile coordinates + { + using namespace mbgl; + + // set tile + interface.setTileID({11, 327, 790}); + + Interface::LineOptions options{/*geometry=*/{}, + /*blur=*/0.0f, + /*opacity=*/1.0f, + /*gapWidth=*/0.0f, + /*offset=*/0.0f, + /*width=*/7.0f, + /*color=*/{1.0f, 0, 0, .5f}}; + + options.geometry.beginCap = style::LineCapType::Round; + options.geometry.endCap = style::LineCapType::Round; + options.geometry.joinType = style::LineJoinType::Round; + + // add polyline with tile coordinates + GeometryCollection polyline_tile{ + { + // ring 1 + {static_cast(extent * 0.1f), static_cast(extent * 0.2f)}, + {static_cast(extent * 0.5f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.7f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.5f), static_cast(extent * 1.0f)}, + {static_cast(extent * 0.0f), static_cast(extent * 0.5f)}, + }, + { + // ring 2 + {static_cast(extent * 0.1f), static_cast(extent * 0.25f)}, + {static_cast(extent * 0.15f), static_cast(extent * 0.5f)}, + {static_cast(extent * 0.25f), static_cast(extent * 0.45f)}, + }, + }; + + options.geometry.type = FeatureType::Polygon; + interface.setLineOptions(options); + interface.addPolyline(polyline_tile[0], Interface::LineShaderType::WideVector); + interface.addPolyline(polyline_tile[1], Interface::LineShaderType::WideVector); + } + + generateGeometry(interface); + loadGeometry(interface); + + // finish + interface.finish(); +} + +void ExampleCustomDrawableStyleLayerHost::generateGeometry(Interface& interface) { + constexpr float itemScale = 10.0f; + const mbgl::LatLng location{37.78, -122.47}; + + Interface::GeometryOptions options; + + // load image + std::shared_ptr image = std::make_shared( + mbgl::decodeImage(mbgl::util::read_file(assetsPath + "puck.png"))); + + options.texture = interface.context.createTexture2D(); + options.texture->setImage(image); + options.texture->setSamplerConfiguration( + {mbgl::gfx::TextureFilterType::Linear, mbgl::gfx::TextureWrapType::Clamp, mbgl::gfx::TextureWrapType::Clamp}); + + const std::shared_ptr sharedVertices = std::make_shared(); + VertexVector& vertices = *sharedVertices; + + const std::shared_ptr sharedIndices = std::make_shared(); + TriangleIndexVector& indices = *sharedIndices; + + const unsigned long numVtxCircumference = 72; + const float bearingStep = 360.0f / static_cast(numVtxCircumference - 1); + + vertices.emplace_back(Interface::GeometryVertex{{0.0f, 0.0f, 0.0f}, {0.5f, 0.5f}}); + + for (unsigned long i = 1; i <= numVtxCircumference; ++i) { + const float rad = mbgl::util::deg2radf((i - 1) * bearingStep); + + Interface::GeometryVertex vertex; + vertex.position = {sinf(rad) / 2.0f, cosf(rad) / 2.0f, 0.0f}; + vertex.texcoords = {0.5f + vertex.position[0], 0.5f - vertex.position[1]}; + + vertices.emplace_back(std::move(vertex)); + } + + for (uint16_t i = 1; i < vertices.elements() - 1; ++i) { + indices.emplace_back(0, i, static_cast(i + 1)); + } + indices.emplace_back(0, static_cast(vertices.elements() - 1), 1); + + interface.setGeometryOptions(options); + + interface.setGeometryTweakerCallback([=, frameCount = 0]([[maybe_unused]] mbgl::gfx::Drawable& drawable, + const mbgl::PaintParameters& params, + Interface::GeometryOptions& currentOptions) mutable { + frameCount++; + + const mbgl::Point& center = project(location, params.state); + + const float scale = itemScale * static_cast(std::pow(2.f, params.state.getZoom())) * + params.pixelsToGLUnits[0]; + + mbgl::mat4 matrix = mbgl::matrix::identity4(); + mbgl::matrix::translate(matrix, matrix, center.x, center.y, 0.0); + mbgl::matrix::rotate_z(matrix, matrix, frameCount * 0.05f); + mbgl::matrix::scale(matrix, matrix, scale, scale, 1.0f); + mbgl::matrix::multiply(currentOptions.matrix, params.transformParams.nearClippedProjMatrix, matrix); + + if (frameCount % 100 == 0) { + if (currentOptions.color.g > 0.0f) { + currentOptions.color = mbgl::Color::red(); + } else { + currentOptions.color = mbgl::Color::white(); + } + } + }); + + interface.addGeometry(sharedVertices, sharedIndices, false); +} + +void ExampleCustomDrawableStyleLayerHost::loadGeometry(Interface& interface) { + constexpr float itemScale = 0.1f; + constexpr std::array itemRotation = {90.0f, 0.0f, 0.0f}; + const mbgl::LatLng location{37.76, -122.47}; + + Interface::GeometryOptions options; + + interface.setGeometryTweakerCallback([=]([[maybe_unused]] mbgl::gfx::Drawable& drawable, + const mbgl::PaintParameters& params, + Interface::GeometryOptions& currentOptions) mutable { + const mbgl::Point& center = project(location, params.state); + + const float scale = itemScale * static_cast(std::pow(2.f, params.state.getZoom())) * + params.pixelsToGLUnits[0]; + + mbgl::mat4 matrix = mbgl::matrix::identity4(); + mbgl::matrix::translate(matrix, matrix, center.x, center.y, 0.0); + mbgl::matrix::rotate_x(matrix, matrix, mbgl::util::deg2radf(itemRotation[0])); + mbgl::matrix::rotate_y(matrix, matrix, mbgl::util::deg2radf(itemRotation[1])); + mbgl::matrix::rotate_z(matrix, matrix, mbgl::util::deg2radf(itemRotation[2])); + mbgl::matrix::scale(matrix, matrix, scale, scale, scale); + mbgl::matrix::multiply(currentOptions.matrix, params.transformParams.nearClippedProjMatrix, matrix); + }); + + const std::shared_ptr sharedVertices = std::make_shared(); + const std::shared_ptr sharedIndices = std::make_shared(); + + // importObj(interface, "../../_deps/tinyobjloader-src/models/cube.obj", *sharedVertices, *sharedIndices, options); + importObj(interface, assetsPath + "sphere.obj", *sharedVertices, *sharedIndices, options); + + interface.setGeometryOptions(options); + interface.addGeometry(sharedVertices, sharedIndices, true); +} + +void ExampleCustomDrawableStyleLayerHost::importObj(Interface& interface, + const std::string& filename, + VertexVector& vertices, + TriangleIndexVector& indices, + Interface::GeometryOptions& options) { + tinyobj::ObjReaderConfig readerConfig; + + readerConfig.triangulate = true; + readerConfig.vertex_color = false; + + tinyobj::ObjReader reader; + + if (!reader.ParseFromFile(filename, readerConfig)) { + if (!reader.Error().empty()) { + mbgl::Log::Error(mbgl::Event::General, reader.Error()); + } + + assert(false); + throw std::runtime_error(std::string("Cannot read obj file ") + filename); + } + + if (!reader.Warning().empty()) { + mbgl::Log::Error(mbgl::Event::General, reader.Warning()); + } + + const tinyobj::attrib_t& attributes = reader.GetAttrib(); + const std::vector& shapes = reader.GetShapes(); + + if (attributes.texcoords.empty()) { + options.color = mbgl::Color::green(); + } else { + // TODO parse material + + options.texture = createCheckerboardTexture(interface, 32, 32, 40, {255, 255, 255, 255}, {0, 0, 0, 255}); + } + + for (const auto& shape : shapes) { + const auto shapeIndexStart = static_cast(indices.elements()); + + for (uint16_t face = 0; face < shape.mesh.indices.size(); face += 3) { + for (size_t i = 0; i < 3; ++i) { + const tinyobj::index_t index = shape.mesh.indices[face + i]; + + Interface::GeometryVertex vertex = {}; + + std::copy(attributes.vertices.begin() + vertex.position.size() * index.vertex_index, + attributes.vertices.begin() + vertex.position.size() * (index.vertex_index + 1), + vertex.position.begin()); + + if (!attributes.texcoords.empty()) { + std::copy(attributes.texcoords.begin() + vertex.texcoords.size() * index.texcoord_index, + attributes.texcoords.begin() + vertex.texcoords.size() * (index.texcoord_index + 1), + vertex.texcoords.begin()); + } + + vertices.emplace_back(std::move(vertex)); + } + + indices.emplace_back(shapeIndexStart + face, shapeIndexStart + face + 1, shapeIndexStart + face + 2); + } + } +} + +mbgl::gfx::Texture2DPtr ExampleCustomDrawableStyleLayerHost::createCheckerboardTexture( + Interface& interface, + uint16_t wb, + uint16_t hb, + uint16_t blockSize, + const std::array& color1, + const std::array& color2) { + std::shared_ptr image = std::make_shared( + mbgl::Size(wb * blockSize, hb * blockSize)); + + constexpr uint8_t pixelSize = sizeof(uint8_t) * 4; + + for (uint16_t row = 0; row < hb; ++row) { + for (uint16_t blockRow = 0; blockRow < blockSize; ++blockRow) { + for (uint16_t col = 0; col < wb; ++col) { + for (uint16_t blockCol = 0; blockCol < blockSize; ++blockCol) { + auto index = (row * blockSize + blockRow) * image->stride() + + (col * blockSize + blockCol) * pixelSize; + + memcpy(image->data.get() + index, (row + col) % 2 == 0 ? color1.data() : color2.data(), pixelSize); + } + } + } + } + + auto texture = interface.context.createTexture2D(); + texture->setSamplerConfiguration( + {mbgl::gfx::TextureFilterType::Linear, mbgl::gfx::TextureWrapType::Clamp, mbgl::gfx::TextureWrapType::Clamp}); + texture->setImage(std::move(image)); + + return texture; +} + +#endif diff --git a/platform/glfw/example_custom_drawable_style_layer.hpp b/platform/glfw/example_custom_drawable_style_layer.hpp new file mode 100644 index 00000000000..b511e13b27e --- /dev/null +++ b/platform/glfw/example_custom_drawable_style_layer.hpp @@ -0,0 +1,43 @@ +#pragma once + +#include + +#if MLN_DRAWABLE_RENDERER + +class ExampleCustomDrawableStyleLayerHost : public mbgl::style::CustomDrawableLayerHost { +public: + using VertexVector = mbgl::gfx::VertexVector; + using TriangleIndexVector = mbgl::gfx::IndexVector; + + ExampleCustomDrawableStyleLayerHost(const std::string& assetsPath); + ~ExampleCustomDrawableStyleLayerHost(); + + void initialize() override; + void deinitialize() override; + + void update(Interface& interface) override; + +protected: + static mbgl::Point project(const mbgl::LatLng& c, const mbgl::TransformState& s); + + void createDrawables(Interface& interface); + void generateGeometry(Interface& interface); + void loadGeometry(Interface& interface); + void importObj(Interface& interface, + const std::string& filename, + VertexVector& vertices, + TriangleIndexVector& indices, + Interface::GeometryOptions& options); + + mbgl::gfx::Texture2DPtr createCheckerboardTexture(Interface& interface, + uint16_t wb, + uint16_t hb, + uint16_t blockSize, + const std::array& color1, + const std::array& color2); + +protected: + const std::string assetsPath; +}; + +#endif diff --git a/platform/glfw/glfw_metal_backend.mm b/platform/glfw/glfw_metal_backend.mm index 25092c2e461..6ef1d697092 100644 --- a/platform/glfw/glfw_metal_backend.mm +++ b/platform/glfw/glfw_metal_backend.mm @@ -6,7 +6,7 @@ #include #include -GLFWMetalBackend::GLFWMetalBackend(GLFWwindow* window_, const bool capFrameRate) +GLFWMetalBackend::GLFWMetalBackend(GLFWwindow* window_, [[maybe_unused]] const bool capFrameRate) : window(glfwGetCocoaWindow(window_)), rendererBackend(window) diff --git a/platform/glfw/glfw_view.cpp b/platform/glfw/glfw_view.cpp index 79ce2c76401..7d688718d5c 100644 --- a/platform/glfw/glfw_view.cpp +++ b/platform/glfw/glfw_view.cpp @@ -28,6 +28,10 @@ #include #include +#if !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) && MLN_DRAWABLE_RENDERER +#include "example_custom_drawable_style_layer.hpp" +#endif + #ifdef _MSC_VER #pragma warning(push) #pragma warning(disable : 4244) @@ -66,7 +70,7 @@ using namespace std::numbers; #ifdef ENABLE_LOCATION_INDICATOR namespace { -const std::string mbglPuckAssetsPath{MAPBOX_PUCK_ASSETS_PATH}; +const std::string mbglPuckAssetsPath{MLN_ASSETS_PATH}; mbgl::Color premultiply(mbgl::Color c) { c.r *= c.a; @@ -366,6 +370,9 @@ void GLFWView::onKey(GLFWwindow *window, int key, int /*scancode*/, int action, case GLFW_KEY_C: view->clearAnnotations(); break; + case GLFW_KEY_V: + view->toggleCustomDrawableStyle(); + break; case GLFW_KEY_I: view->resetDatabaseCallback(); break; @@ -823,6 +830,23 @@ void GLFWView::popAnnotation() { annotationIDs.pop_back(); } +void GLFWView::toggleCustomDrawableStyle() { +#if !defined(MBGL_LAYER_CUSTOM_DISABLE_ALL) && MLN_DRAWABLE_RENDERER + auto &style = map->getStyle(); + + const std::string identifier = "ExampleCustomDrawableStyleLayer"; + const auto &existingLayer = style.getLayer(identifier); + + if (!existingLayer) { + style.addLayer(std::make_unique( + identifier, std::make_unique(MLN_ASSETS_PATH))); + } else { + style.removeLayer(identifier); + } + +#endif +} + void GLFWView::makeSnapshot(bool withOverlay) { MLN_TRACE_FUNC(); diff --git a/platform/glfw/glfw_view.hpp b/platform/glfw/glfw_view.hpp index 2ee15e7435f..ffea1020a26 100644 --- a/platform/glfw/glfw_view.hpp +++ b/platform/glfw/glfw_view.hpp @@ -113,6 +113,7 @@ class GLFWView : public mbgl::MapObserver { void clearAnnotations(); void popAnnotation(); + void toggleCustomDrawableStyle(); void makeSnapshot(bool withOverlay = false); mbgl::AnnotationIDs annotationIDs; diff --git a/shaders/drawable.custom_geometry.fragment.glsl b/shaders/drawable.custom_geometry.fragment.glsl new file mode 100644 index 00000000000..42c8156a118 --- /dev/null +++ b/shaders/drawable.custom_geometry.fragment.glsl @@ -0,0 +1,11 @@ +layout (std140) uniform CustomGeometryDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +in vec2 frag_uv; +uniform sampler2D u_image; + +void main() { + fragColor = texture(u_image, frag_uv) * u_color; +} diff --git a/shaders/drawable.custom_geometry.vertex.glsl b/shaders/drawable.custom_geometry.vertex.glsl new file mode 100644 index 00000000000..c731979708f --- /dev/null +++ b/shaders/drawable.custom_geometry.vertex.glsl @@ -0,0 +1,14 @@ +layout (std140) uniform CustomGeometryDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec3 a_pos; +layout(location = 1) in vec2 a_uv; + +out vec2 frag_uv; + +void main() { + frag_uv = a_uv; + gl_Position = u_matrix * vec4(a_pos, 1.0); +} diff --git a/shaders/drawable.location_indicator.fragment.glsl b/shaders/drawable.location_indicator.fragment.glsl new file mode 100644 index 00000000000..0956f100e3d --- /dev/null +++ b/shaders/drawable.location_indicator.fragment.glsl @@ -0,0 +1,8 @@ +layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +void main() { + fragColor = u_color; +} diff --git a/shaders/drawable.location_indicator.vertex.glsl b/shaders/drawable.location_indicator.vertex.glsl new file mode 100644 index 00000000000..045634b387d --- /dev/null +++ b/shaders/drawable.location_indicator.vertex.glsl @@ -0,0 +1,10 @@ +layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec2 a_pos; + +void main() { + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); +} diff --git a/shaders/drawable.location_indicator_textured.fragment.glsl b/shaders/drawable.location_indicator_textured.fragment.glsl new file mode 100644 index 00000000000..4ca7698a360 --- /dev/null +++ b/shaders/drawable.location_indicator_textured.fragment.glsl @@ -0,0 +1,11 @@ +layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +in vec2 frag_uv; +uniform sampler2D u_image; + +void main() { + fragColor = texture(u_image, frag_uv); +} diff --git a/shaders/drawable.location_indicator_textured.vertex.glsl b/shaders/drawable.location_indicator_textured.vertex.glsl new file mode 100644 index 00000000000..e577f419d63 --- /dev/null +++ b/shaders/drawable.location_indicator_textured.vertex.glsl @@ -0,0 +1,14 @@ +layout (std140) uniform LocationIndicatorDrawableUBO { + mat4 u_matrix; + vec4 u_color; +}; + +layout(location = 0) in vec2 a_pos; +layout(location = 1) in vec2 a_uv; + +out vec2 frag_uv; + +void main() { + frag_uv = a_uv; + gl_Position = u_matrix * vec4(a_pos, 0.0, 1.0); +} diff --git a/shaders/manifest.json b/shaders/manifest.json index 49829a196b0..8d4345588ae 100644 --- a/shaders/manifest.json +++ b/shaders/manifest.json @@ -34,6 +34,13 @@ "glsl_frag": "drawable.collision_circle.fragment.glsl", "uses_ubos": true }, + { + "name": "CustomGeometryShader", + "header": "drawable_custom_geometry", + "glsl_vert": "drawable.custom_geometry.vertex.glsl", + "glsl_frag": "drawable.custom_geometry.fragment.glsl", + "uses_ubos": true + }, { "name": "CustomSymbolIconShader", "header": "drawable_custom_symbol_icon", @@ -149,15 +156,15 @@ { "name": "LocationIndicatorShader", "header": "drawable_location_indicator", - "glsl_vert": "_empty.glsl", - "glsl_frag": "_empty.glsl", + "glsl_vert": "drawable.location_indicator.vertex.glsl", + "glsl_frag": "drawable.location_indicator.fragment.glsl", "uses_ubos": true }, { "name": "LocationIndicatorTexturedShader", "header": "drawable_location_indicator_textured", - "glsl_vert": "_empty.glsl", - "glsl_frag": "_empty.glsl", + "glsl_vert": "drawable.location_indicator_textured.vertex.glsl", + "glsl_frag": "drawable.location_indicator_textured.fragment.glsl", "uses_ubos": true }, { diff --git a/src/mbgl/gfx/drawable.cpp b/src/mbgl/gfx/drawable.cpp index 34fea6d9211..82d053f08ea 100644 --- a/src/mbgl/gfx/drawable.cpp +++ b/src/mbgl/gfx/drawable.cpp @@ -5,8 +5,8 @@ #include #include #include -#include #include +#include namespace mbgl { namespace gfx { @@ -24,7 +24,7 @@ struct Drawable::Impl { Drawable::Drawable(std::string name_) : name(name_), - renderPass(RenderPass::Opaque), + renderPass(mbgl::RenderPass::Opaque), depthType(DepthMaskType::ReadOnly), impl(std::make_unique()) {} diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index d8a8dcac2b7..5ad750c8a83 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -620,6 +620,10 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, return std::make_shared(data, size, *uboAllocator); } +gfx::UniqueUniformBufferArray Context::createLayerUniformBufferArray() { + return std::make_unique(); +} + gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) { MLN_TRACE_FUNC(); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 0c34475a9a9..9f9eed740ea 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -125,6 +125,8 @@ class Context final : public gfx::Context { bool persistent = false, bool ssbo = false) override; + gfx::UniqueUniformBufferArray createLayerUniformBufferArray() override; + gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override; TileLayerGroupPtr createTileLayerGroup(int32_t layerIndex, std::size_t initialCapacity, std::string name) override; diff --git a/src/mbgl/gl/layer_group_gl.cpp b/src/mbgl/gl/layer_group_gl.cpp index 7f931d8a1c3..6dab46f05a2 100644 --- a/src/mbgl/gl/layer_group_gl.cpp +++ b/src/mbgl/gl/layer_group_gl.cpp @@ -115,6 +115,11 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) const auto debugGroupTile = parameters.encoder->createDebugGroup(labelPtr); #endif + if (!bindUBOs) { + uniformBuffers.bind(); + bindUBOs = true; + } + for (const auto& tweaker : drawable.getTweakers()) { tweaker->execute(drawable, parameters); } @@ -126,11 +131,6 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) context.setStencilMode(drawable.getEnableStencil() ? stencilMode3d : gfx::StencilMode::disabled()); } - if (!bindUBOs) { - uniformBuffers.bind(); - bindUBOs = true; - } - drawable.draw(parameters); }); @@ -176,16 +176,15 @@ void LayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) { #if !defined(NDEBUG) const auto debugGroup = parameters.encoder->createDebugGroup(drawable.getName().c_str()); #endif - - for (const auto& tweaker : drawable.getTweakers()) { - tweaker->execute(drawable, parameters); - } - if (!bindUBOs) { uniformBuffers.bind(); bindUBOs = true; } + for (const auto& tweaker : drawable.getTweakers()) { + tweaker->execute(drawable, parameters); + } + drawable.draw(parameters); }); diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index fa8badc2d6e..f43f4ccb50d 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -125,6 +125,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar shaders::BuiltIn::CircleShader, shaders::BuiltIn::CollisionBoxShader, shaders::BuiltIn::CollisionCircleShader, + shaders::BuiltIn::CustomGeometryShader, shaders::BuiltIn::CustomSymbolIconShader, shaders::BuiltIn::DebugShader, shaders::BuiltIn::FillShader, @@ -142,6 +143,8 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar shaders::BuiltIn::LineGradientShader, shaders::BuiltIn::LinePatternShader, shaders::BuiltIn::LineSDFShader, + shaders::BuiltIn::LocationIndicatorShader, + shaders::BuiltIn::LocationIndicatorTexturedShader, shaders::BuiltIn::RasterShader, shaders::BuiltIn::SymbolIconShader, shaders::BuiltIn::SymbolSDFIconShader, diff --git a/src/mbgl/mtl/context.cpp b/src/mbgl/mtl/context.cpp index eb57ffd12b9..23624fcb3bd 100644 --- a/src/mbgl/mtl/context.cpp +++ b/src/mbgl/mtl/context.cpp @@ -204,6 +204,10 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t createBuffer(data, size, gfx::BufferUsageType::StaticDraw, /*isIndexBuffer=*/false, persistent)); } +UniqueUniformBufferArray Context::createLayerUniformBufferArray() { + return std::make_unique(); +} + gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) { const auto shaderGroup = shaders.getShaderGroup(name); auto shader = shaderGroup ? shaderGroup->getOrCreateShader(*this, {}) : gfx::ShaderProgramBasePtr{}; @@ -226,7 +230,7 @@ RenderTargetPtr Context::createRenderTarget(const Size size, const gfx::TextureC return std::make_shared(*this, size, type); } -void Context::resetState(gfx::DepthMode depthMode, gfx::ColorMode colorMode) {} +void Context::resetState(gfx::DepthMode, gfx::ColorMode) {} bool Context::emplaceOrUpdateUniformBuffer(gfx::UniformBufferPtr& buffer, const void* data, @@ -459,7 +463,7 @@ std::unique_ptr Context::createTextureResource(Size, return nullptr; } -std::unique_ptr Context::createRenderbufferResource(gfx::RenderbufferPixelType, Size size) { +std::unique_ptr Context::createRenderbufferResource(gfx::RenderbufferPixelType, Size) { return std::make_unique(); } @@ -475,7 +479,7 @@ gfx::VertexAttributeArrayPtr Context::createVertexAttributeArray() const { #if !defined(NDEBUG) void Context::visualizeStencilBuffer() {} -void Context::visualizeDepthBuffer(float depthRangeSize) {} +void Context::visualizeDepthBuffer(float) {} #endif // !defined(NDEBUG) void Context::clearStencilBuffer(int32_t) { @@ -625,7 +629,7 @@ MTLDepthStencilStatePtr Context::makeDepthStencilState(const gfx::DepthMode& dep void Context::bindGlobalUniformBuffers(gfx::RenderPass& renderPass) const noexcept { auto& mtlRenderPass = static_cast(renderPass); - globalUniformBuffers.bind(mtlRenderPass); + globalUniformBuffers.bindMtl(mtlRenderPass); } } // namespace mtl diff --git a/src/mbgl/mtl/drawable.cpp b/src/mbgl/mtl/drawable.cpp index e41d8c79c95..84c760373b9 100644 --- a/src/mbgl/mtl/drawable.cpp +++ b/src/mbgl/mtl/drawable.cpp @@ -316,7 +316,6 @@ void Drawable::draw(PaintParameters& parameters) const { } } - impl->uniformBuffers.unbind(renderPass); unbindTextures(renderPass); unbindAttributes(renderPass); } diff --git a/src/mbgl/mtl/layer_group.cpp b/src/mbgl/mtl/layer_group.cpp index e3016cbf6c6..f13552770a4 100644 --- a/src/mbgl/mtl/layer_group.cpp +++ b/src/mbgl/mtl/layer_group.cpp @@ -51,21 +51,17 @@ void LayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) { return; } - for (const auto& tweaker : drawable.getTweakers()) { - tweaker->execute(drawable, parameters); - } - if (!bindUBOs) { - uniformBuffers.bind(renderPass); + uniformBuffers.bindMtl(renderPass); bindUBOs = true; } + for (const auto& tweaker : drawable.getTweakers()) { + tweaker->execute(drawable, parameters); + } + drawable.draw(parameters); }); - - if (bindUBOs) { - uniformBuffers.unbind(renderPass); - } } } // namespace mtl diff --git a/src/mbgl/mtl/renderer_backend.cpp b/src/mbgl/mtl/renderer_backend.cpp index 6e8748e912a..3fc14b25a37 100644 --- a/src/mbgl/mtl/renderer_backend.cpp +++ b/src/mbgl/mtl/renderer_backend.cpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -57,21 +59,21 @@ PremultipliedImage RendererBackend::readFramebuffer(const Size& size) { return PremultipliedImage(size); } -void RendererBackend::assumeFramebufferBinding(const mtl::FramebufferID fbo) {} +void RendererBackend::assumeFramebufferBinding(const mtl::FramebufferID) {} -void RendererBackend::assumeViewport(int32_t x, int32_t y, const Size& size) {} +void RendererBackend::assumeViewport(int32_t, int32_t, const Size&) {} -void RendererBackend::assumeScissorTest(bool enabled) {} +void RendererBackend::assumeScissorTest(bool) {} bool RendererBackend::implicitFramebufferBound() { return false; } -void RendererBackend::setFramebufferBinding(const mtl::FramebufferID fbo) {} +void RendererBackend::setFramebufferBinding(const mtl::FramebufferID) {} -void RendererBackend::setViewport(int32_t x, int32_t y, const Size& size) {} +void RendererBackend::setViewport(int32_t, int32_t, const Size&) {} -void RendererBackend::setScissorTest(bool enabled) {} +void RendererBackend::setScissorTest(bool) {} /// @brief Register a list of types with a shader registry instance /// @tparam ...ShaderID Pack of BuiltIn:: shader IDs @@ -105,6 +107,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar shaders::BuiltIn::ClippingMaskProgram, shaders::BuiltIn::CollisionBoxShader, shaders::BuiltIn::CollisionCircleShader, + shaders::BuiltIn::CustomGeometryShader, shaders::BuiltIn::CustomSymbolIconShader, shaders::BuiltIn::DebugShader, shaders::BuiltIn::FillShader, @@ -122,6 +125,8 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar shaders::BuiltIn::LineGradientShader, shaders::BuiltIn::LineSDFShader, shaders::BuiltIn::LinePatternShader, + shaders::BuiltIn::LocationIndicatorShader, + shaders::BuiltIn::LocationIndicatorTexturedShader, shaders::BuiltIn::RasterShader, shaders::BuiltIn::SymbolIconShader, shaders::BuiltIn::SymbolSDFIconShader, diff --git a/src/mbgl/mtl/tile_layer_group.cpp b/src/mbgl/mtl/tile_layer_group.cpp index 82eb2ff6cb3..6716adda976 100644 --- a/src/mbgl/mtl/tile_layer_group.cpp +++ b/src/mbgl/mtl/tile_layer_group.cpp @@ -125,6 +125,11 @@ void TileLayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) { return; } + if (!bindUBOs) { + uniformBuffers.bindMtl(renderPass); + bindUBOs = true; + } + for (const auto& tweaker : drawable.getTweakers()) { tweaker->execute(drawable, parameters); } @@ -137,17 +142,8 @@ void TileLayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) { renderPass.setDepthStencilState(state); } - if (!bindUBOs) { - uniformBuffers.bind(renderPass); - bindUBOs = true; - } - drawable.draw(parameters); }); - - if (bindUBOs) { - uniformBuffers.unbind(renderPass); - } } } // namespace mtl diff --git a/src/mbgl/mtl/uniform_buffer.cpp b/src/mbgl/mtl/uniform_buffer.cpp index f800323225a..29446412653 100644 --- a/src/mbgl/mtl/uniform_buffer.cpp +++ b/src/mbgl/mtl/uniform_buffer.cpp @@ -39,7 +39,7 @@ void UniformBuffer::update(const void* data, std::size_t dataSize) { buffer.update(data, dataSize, /*offset=*/0); } -void UniformBufferArray::bind(RenderPass& renderPass) const noexcept { +void UniformBufferArray::bindMtl(RenderPass& renderPass) const noexcept { for (size_t id = 0; id < allocatedSize(); id++) { const auto& uniformBuffer = get(id); if (!uniformBuffer) continue; @@ -54,5 +54,9 @@ void UniformBufferArray::bind(RenderPass& renderPass) const noexcept { } } +void UniformBufferArray::bind(gfx::RenderPass& renderPass) { + bindMtl(static_cast(renderPass)); +} + } // namespace mtl } // namespace mbgl diff --git a/src/mbgl/mtl/upload_pass.cpp b/src/mbgl/mtl/upload_pass.cpp index e31af6e5be4..fefbc41637e 100644 --- a/src/mbgl/mtl/upload_pass.cpp +++ b/src/mbgl/mtl/upload_pass.cpp @@ -81,30 +81,27 @@ void UploadPass::updateIndexBufferResource(gfx::IndexBufferResource& resource, c static_cast(resource).get().update(data, size, /*offset=*/0); } -std::unique_ptr UploadPass::createTextureResource(const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { +std::unique_ptr UploadPass::createTextureResource(const Size, + const void*, + gfx::TexturePixelType, + gfx::TextureChannelDataType) { assert(false); throw std::runtime_error("UploadPass::createTextureResource not implemented on Metal!"); } -void UploadPass::updateTextureResource(gfx::TextureResource& resource, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { +void UploadPass::updateTextureResource( + gfx::TextureResource&, const Size, const void*, gfx::TexturePixelType, gfx::TextureChannelDataType) { assert(false); throw std::runtime_error("UploadPass::updateTextureResource not implemented on Metal!"); } -void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, - const uint16_t xOffset, - const uint16_t yOffset, - const Size size, - const void* data, - gfx::TexturePixelType format, - gfx::TextureChannelDataType type) { +void UploadPass::updateTextureResourceSub(gfx::TextureResource&, + const uint16_t, + const uint16_t, + const Size, + const void*, + gfx::TexturePixelType, + gfx::TextureChannelDataType) { assert(false); throw std::runtime_error("UploadPass::updateTextureResourceSub not implemented on Metal!"); } @@ -151,10 +148,10 @@ const gfx::UniqueVertexBufferResource& UploadPass::getBuffer(const gfx::VertexVe } gfx::AttributeBindingArray UploadPass::buildAttributeBindings( - const std::size_t vertexCount, - const gfx::AttributeDataType vertexType, - const std::size_t vertexAttributeIndex, - const std::vector& vertexData, + [[maybe_unused]] const std::size_t vertexCount, + [[maybe_unused]] const gfx::AttributeDataType vertexType, + [[maybe_unused]] const std::size_t vertexAttributeIndex, + [[maybe_unused]] const std::vector& vertexData, const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& overrides, const gfx::BufferUsageType usage, @@ -166,7 +163,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( bindings.resize(defaults.allocatedSize()); // For each attribute in the program, with the corresponding default and optional override... - const auto resolveAttr = [&](const size_t id, auto& default_, auto& override_) -> void { + const auto resolveAttr = [&]([[maybe_unused]] const size_t id, auto& default_, auto& override_) -> void { auto& effectiveAttr = override_ ? *override_ : default_; const auto& defaultAttr = static_cast(default_); const auto index = static_cast(defaultAttr.getIndex()); diff --git a/src/mbgl/renderer/layers/render_location_indicator_layer.cpp b/src/mbgl/renderer/layers/render_location_indicator_layer.cpp index bc8e551883c..e123a18282d 100644 --- a/src/mbgl/renderer/layers/render_location_indicator_layer.cpp +++ b/src/mbgl/renderer/layers/render_location_indicator_layer.cpp @@ -42,7 +42,7 @@ #endif -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR #include #include @@ -145,7 +145,7 @@ class RenderLocationIndicatorImpl { friend vec2 operator-(const vec2& v1, const vec2& v2) { return {v1.x - v2.x, v1.y - v2.y}; } }; -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR struct Shader { virtual ~Shader() { release(); } void release() { @@ -420,7 +420,7 @@ void main() { #endif -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR struct TextureInfo { std::shared_ptr texture; std::optional> image; @@ -485,7 +485,7 @@ void main() { } void release() { -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR if (!simpleShader.program) return; for (const auto& t : textures) t.second->release(); buffer.release(); @@ -515,7 +515,7 @@ void main() { params.puckShadowScale != oldParams.puckShadowScale) bearingChanged = true; // changes puck geometry but not necessarily the location if (params.errorRadiusMeters != oldParams.errorRadiusMeters) radiusChanged = true; -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR bearingChanged |= setTextureFromImageID(params.puckImagePath, texPuck, params); bearingChanged |= setTextureFromImageID(params.puckShadowImagePath, texShadow, params); bearingChanged |= setTextureFromImageID(params.puckHatImagePath, texPuckHat, params); @@ -551,7 +551,7 @@ void main() { if (!dirtyFeature) return; dirtyFeature = false; featureEnvelope->clear(); -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR if (!texPuck || !texPuck->isValid()) return; #else if (!puckDrawableInfo.textureInfo.texture) return; @@ -593,7 +593,7 @@ void main() { } void updateRadius(const mbgl::LocationIndicatorRenderParameters& params) { -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR auto& circle = circleDrawableInfo.geometry; circleDrawableInfo.dirty = true; #endif @@ -711,7 +711,7 @@ void main() { params.perspectiveCompensation; // Compensation factor for the perspective deformation // ^ clamping this to 0.8 to avoid growing the puck too much close to the camera. -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR const double shadowRadius = ((texShadow) ? texShadow->width / texShadow->pixelRatio : 0.0) * params.puckShadowScale * M_SQRT2 * 0.5 * horizontalScaleFactor; // Technically it's not the radius, but @@ -756,7 +756,7 @@ void main() { } } -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR void drawRadius(const mbgl::LocationIndicatorRenderParameters& params) { if (!(params.errorRadiusMeters > 0.0) || (params.errorRadiusColor.a == 0.0 && params.errorRadiusBorderColor.a == 0.0)) @@ -818,7 +818,7 @@ void main() { return s.screenCoordinateToLatLng(flippedPoint, wrapMode); } -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR bool setTextureFromImageID(const std::string& imagePath, std::shared_ptr& texture, const mbgl::LocationIndicatorRenderParameters& params) { @@ -879,7 +879,7 @@ void main() { bool initialized = false; bool dirtyFeature = true; -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR public: struct QuadDrawableInfo { @@ -1015,7 +1015,7 @@ void RenderLocationIndicatorLayer::populateDynamicRenderFeatureIndex(DynamicFeat if (!renderImpl->featureEnvelope->empty()) index.insert(renderImpl->feature, renderImpl->featureEnvelope); } -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR void RenderLocationIndicatorLayer::render(PaintParameters& paintParameters) { auto& glContext = static_cast(paintParameters.context); @@ -1035,7 +1035,7 @@ void RenderLocationIndicatorLayer::render(PaintParameters& paintParameters) { } #endif -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, gfx::Context& context, @@ -1092,8 +1092,11 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, const auto createQuadGeometry = [&](gfx::Drawable& drawable, const auto& geometry) { auto vertexAttrs = context.createVertexAttributeArray(); + drawable.setVertices({}, 4, gfx::AttributeDataType::Float2); + vertexAttrs->set(shaders::idLocationIndicatorPosVertexAttribute, 0, gfx::AttributeDataType::Float2, 4); + if (const auto& attr = vertexAttrs->set( - shaders::idCommonTexVertexAttribute, 0, gfx::AttributeDataType::Float2)) { + shaders::idLocationIndicatorTexVertexAttribute, 0, gfx::AttributeDataType::Float2, 4)) { const std::array texCoords = { {{0.0f, 1.0f}, {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}}}; @@ -1125,7 +1128,9 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, drawable->setName(name); drawable->setRenderPass(drawPasses); - drawable->setDepthType(gfx::DepthMaskType::ReadWrite); + drawable->setDepthType(gfx::DepthMaskType::ReadOnly); + drawable->setEnableDepth(false); + drawable->setEnableStencil(false); drawable->setColorMode(drawPasses == RenderPass::Translucent ? gfx::ColorMode::alphaBlended() : gfx::ColorMode::unblended()); @@ -1146,7 +1151,9 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, drawable->setName(name); drawable->setRenderPass(drawPasses); - drawable->setDepthType(gfx::DepthMaskType::ReadWrite); + drawable->setDepthType(gfx::DepthMaskType::ReadOnly); + drawable->setEnableDepth(false); + drawable->setEnableStencil(false); drawable->setColorMode(drawPasses == RenderPass::Translucent ? gfx::ColorMode::alphaBlended() : gfx::ColorMode::unblended()); @@ -1240,7 +1247,7 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, } auto& circleVertexAttrs = circleDrawable.getVertexAttributes(); - if (const auto& attr = circleVertexAttrs->set(shaders::idCommonPosVertexAttribute)) { + if (const auto& attr = circleVertexAttrs->set(shaders::idLocationIndicatorPosVertexAttribute)) { attr->setSharedRawData( verts, 0, 0, sizeof(RenderLocationIndicatorImpl::vec2), gfx::AttributeDataType::Float2); } @@ -1254,7 +1261,7 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, auto vertexAttrs = drawable.getVertexAttributes(); if (const auto& attr = vertexAttrs->set( - shaders::idCommonPosVertexAttribute, 0, gfx::AttributeDataType::Float2)) { + shaders::idLocationIndicatorPosVertexAttribute, 0, gfx::AttributeDataType::Float2)) { auto geoDataPtr = reinterpret_cast(info.geometry.data()); auto geoDataSize = info.geometry.size() * sizeof(RenderLocationIndicatorImpl::vec2); @@ -1281,7 +1288,7 @@ void RenderLocationIndicatorLayer::update(gfx::ShaderRegistry& shaders, info.textureInfo.image.reset(); } - drawable.setTexture(info.textureInfo.texture, shaders::idCommonTexture); + drawable.setTexture(info.textureInfo.texture, shaders::idLocationIndicatorTexture); info.textureInfo.dirty = false; } }; diff --git a/src/mbgl/renderer/layers/render_location_indicator_layer.hpp b/src/mbgl/renderer/layers/render_location_indicator_layer.hpp index fffeae0b3f9..35eab959117 100644 --- a/src/mbgl/renderer/layers/render_location_indicator_layer.hpp +++ b/src/mbgl/renderer/layers/render_location_indicator_layer.hpp @@ -5,6 +5,10 @@ #include #include +#if !MLN_RENDER_BACKEND_OPENGL +#define MLN_DRAWABLE_LOCATION_INDICATOR +#endif + namespace mbgl { class RenderLocationIndicatorImpl; class RenderLocationIndicatorLayer final : public RenderLayer { @@ -21,7 +25,7 @@ class RenderLocationIndicatorLayer final : public RenderLayer { explicit RenderLocationIndicatorLayer(Immutable); ~RenderLocationIndicatorLayer() override; -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR void update(gfx::ShaderRegistry &, gfx::Context &, const TransformState &, @@ -38,7 +42,7 @@ class RenderLocationIndicatorLayer final : public RenderLayer { void markContextDestroyed() override; void prepare(const LayerPrepareParameters &) override; -#if MLN_RENDER_BACKEND_OPENGL +#ifndef MLN_DRAWABLE_LOCATION_INDICATOR void render(PaintParameters &) override; #endif @@ -49,7 +53,7 @@ class RenderLocationIndicatorLayer final : public RenderLayer { std::unique_ptr renderImpl; style::LocationIndicatorPaintProperties::Unevaluated unevaluated; -#if !MLN_RENDER_BACKEND_OPENGL +#ifdef MLN_DRAWABLE_LOCATION_INDICATOR // Drawable shaders gfx::ShaderProgramBasePtr quadShader; gfx::ShaderProgramBasePtr circleShader; diff --git a/src/mbgl/shaders/gl/shader_info.cpp b/src/mbgl/shaders/gl/shader_info.cpp index c51b8da8b0e..7e9e28a5cb7 100644 --- a/src/mbgl/shaders/gl/shader_info.cpp +++ b/src/mbgl/shaders/gl/shader_info.cpp @@ -95,6 +95,20 @@ const std::vector CollisionCircleShaderInfo::attributes = { }; const std::vector CollisionCircleShaderInfo::textures = {}; +// Custom Geometry +using CustomGeometryInfo = ShaderInfo; + +const std::vector CustomGeometryInfo::uniformBlocks = { + UniformBlockInfo{"CustomGeometryDrawableUBO", idCustomGeometryDrawableUBO}, +}; +const std::vector CustomGeometryInfo::attributes = { + AttributeInfo{"a_pos", idCustomGeometryPosVertexAttribute}, + AttributeInfo{"a_uv", idCustomGeometryTexVertexAttribute}, +}; +const std::vector CustomGeometryInfo::textures = { + TextureInfo{"u_image", idCustomGeometryTexture}, +}; + // Custom Symbol Icon using CustomSymbolIconShaderInfo = ShaderInfo; @@ -322,6 +336,30 @@ const std::vector LineShaderInfo::attributes = { }; const std::vector LineShaderInfo::textures = {}; +// Location Indicator +using LocationIndicatorInfo = ShaderInfo; + +const std::vector LocationIndicatorInfo::uniformBlocks = { + UniformBlockInfo{"LocationIndicatorDrawableUBO", idLocationIndicatorDrawableUBO}, +}; +const std::vector LocationIndicatorInfo::attributes = { + AttributeInfo{"a_pos", idLocationIndicatorPosVertexAttribute}, +}; +const std::vector LocationIndicatorInfo::textures = {}; + +using LocationIndicatorTexturedInfo = ShaderInfo; + +const std::vector LocationIndicatorTexturedInfo::uniformBlocks = { + UniformBlockInfo{"LocationIndicatorDrawableUBO", idLocationIndicatorDrawableUBO}, +}; +const std::vector LocationIndicatorTexturedInfo::attributes = { + AttributeInfo{"a_pos", idLocationIndicatorPosVertexAttribute}, + AttributeInfo{"a_uv", idLocationIndicatorTexVertexAttribute}, +}; +const std::vector LocationIndicatorTexturedInfo::textures = { + TextureInfo{"u_image", idLocationIndicatorTexture}, +}; + // Line Gradient using LineGradientShaderInfo = ShaderInfo; diff --git a/src/mbgl/shaders/mtl/custom_geometry.cpp b/src/mbgl/shaders/mtl/custom_geometry.cpp new file mode 100644 index 00000000000..45cfe5b074b --- /dev/null +++ b/src/mbgl/shaders/mtl/custom_geometry.cpp @@ -0,0 +1,17 @@ +#include +#include + +namespace mbgl { +namespace shaders { + +using CustomGeometryShaderSource = ShaderSource; + +const std::array CustomGeometryShaderSource::attributes = { + AttributeInfo{customGeometryUBOCount + 0, gfx::AttributeDataType::Float3, idCustomGeometryPosVertexAttribute}, + AttributeInfo{customGeometryUBOCount + 1, gfx::AttributeDataType::Float2, idCustomGeometryTexVertexAttribute}, +}; + +const std::array CustomGeometryShaderSource::textures = {TextureInfo{0, idCustomGeometryTexture}}; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/mtl/location_indicator.cpp b/src/mbgl/shaders/mtl/location_indicator.cpp new file mode 100644 index 00000000000..fcdd06d4eee --- /dev/null +++ b/src/mbgl/shaders/mtl/location_indicator.cpp @@ -0,0 +1,25 @@ +#include +#include + +namespace mbgl { +namespace shaders { + +using LocationIndicatorShaderSource = ShaderSource; + +const std::array LocationIndicatorShaderSource::attributes = {AttributeInfo{ + locationIndicatorUBOCount + 0, gfx::AttributeDataType::Float2, idLocationIndicatorPosVertexAttribute}}; + +using LocationIndicatorTexturedShaderSource = + ShaderSource; + +const std::array LocationIndicatorTexturedShaderSource::attributes = { + AttributeInfo{locationIndicatorUBOCount + 0, gfx::AttributeDataType::Float2, idLocationIndicatorPosVertexAttribute}, + AttributeInfo{locationIndicatorUBOCount + 1, gfx::AttributeDataType::Float2, idLocationIndicatorTexVertexAttribute}, +}; + +const std::array LocationIndicatorTexturedShaderSource::textures = { + TextureInfo{0, idLocationIndicatorTexture}, +}; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/vulkan/custom_geometry.cpp b/src/mbgl/shaders/vulkan/custom_geometry.cpp new file mode 100644 index 00000000000..d224402fe6c --- /dev/null +++ b/src/mbgl/shaders/vulkan/custom_geometry.cpp @@ -0,0 +1,20 @@ +#include +#include +#include + +namespace mbgl { +namespace shaders { + +using CustomGeometryShaderSource = ShaderSource; + +const std::array CustomGeometryShaderSource::attributes = { + AttributeInfo{0, gfx::AttributeDataType::Float3, idCustomGeometryPosVertexAttribute}, + AttributeInfo{1, gfx::AttributeDataType::Float2, idCustomGeometryTexVertexAttribute}, +}; + +const std::array CustomGeometryShaderSource::textures = { + TextureInfo{0, idCustomGeometryTexture}, +}; + +} // namespace shaders +} // namespace mbgl diff --git a/src/mbgl/shaders/vulkan/location_indicator.cpp b/src/mbgl/shaders/vulkan/location_indicator.cpp index 2eb9f8e87b4..31c1aaee77c 100644 --- a/src/mbgl/shaders/vulkan/location_indicator.cpp +++ b/src/mbgl/shaders/vulkan/location_indicator.cpp @@ -11,7 +11,7 @@ namespace shaders { using LocationIndicatorShaderSource = ShaderSource; const std::array LocationIndicatorShaderSource::attributes = { - AttributeInfo{0, gfx::AttributeDataType::Float2, idCommonPosVertexAttribute}, + AttributeInfo{0, gfx::AttributeDataType::Float2, idLocationIndicatorPosVertexAttribute}, }; const std::array LocationIndicatorShaderSource::textures = {}; @@ -22,11 +22,11 @@ using LocationIndicatorShaderTexturedSource = ShaderSource; const std::array LocationIndicatorShaderTexturedSource::attributes = { - AttributeInfo{0, gfx::AttributeDataType::Float2, idCommonPosVertexAttribute}, - AttributeInfo{1, gfx::AttributeDataType::Float2, idCommonTexVertexAttribute}, + AttributeInfo{0, gfx::AttributeDataType::Float2, idLocationIndicatorPosVertexAttribute}, + AttributeInfo{1, gfx::AttributeDataType::Float2, idLocationIndicatorTexVertexAttribute}, }; const std::array LocationIndicatorShaderTexturedSource::textures = { - TextureInfo{0, idCommonTexture}, + TextureInfo{0, idLocationIndicatorTexture}, }; } // namespace shaders diff --git a/src/mbgl/style/layers/custom_drawable_layer.cpp b/src/mbgl/style/layers/custom_drawable_layer.cpp index 004b441f7b9..3df0ee2c493 100644 --- a/src/mbgl/style/layers/custom_drawable_layer.cpp +++ b/src/mbgl/style/layers/custom_drawable_layer.cpp @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include @@ -89,8 +91,11 @@ const LayerTypeInfo* CustomDrawableLayer::Impl::staticTypeInfo() noexcept { class LineDrawableTweaker : public gfx::DrawableTweaker { public: - LineDrawableTweaker(const shaders::LineEvaluatedPropsUBO& properties) - : propsUBO(properties) {} + LineDrawableTweaker(const CustomDrawableLayerHost::Interface::LineOptions& options_, + CustomDrawableLayerHost::Interface::LineTweakerCallback&& callback_) + : options(options_), + callback(callback_) {} + ~LineDrawableTweaker() override = default; void init(gfx::Drawable&) override {} @@ -100,14 +105,55 @@ class LineDrawableTweaker : public gfx::DrawableTweaker { return; } + if (callback) { + callback(drawable, parameters, options); + } + +#if MLN_UBO_CONSOLIDATION + if (!layerUniforms) { + layerUniforms = parameters.context.createLayerUniformBufferArray(); + } +#endif + const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); const auto zoom = parameters.state.getZoom(); - mat4 tileMatrix; - parameters.state.matrixFor(/*out*/ tileMatrix, tileID); const auto matrix = LayerTweaker::getTileMatrix( tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false); + const shaders::LineEvaluatedPropsUBO propsUBO = {options.color, + options.blur, + options.opacity, + options.gapWidth, + options.offset, + options.width, + /*floorwidth=*/0.0f, + LineExpressionMask::None, + 0}; + + // We would need to set up `idLineExpressionUBO` if the expression mask isn't empty + assert(propsUBO.expressionMask == LineExpressionMask::None); + + if (!expressionUniformBuffer) { + const LineExpressionUBO exprUBO = { + /* .color = */ nullptr, + /* .blur = */ nullptr, + /* .opacity = */ nullptr, + /* .gapwidth = */ nullptr, + /* .offset = */ nullptr, + /* .width = */ nullptr, + /* .floorWidth = */ nullptr, + }; + + expressionUniformBuffer = parameters.context.createUniformBuffer(&exprUBO, sizeof(exprUBO)); +#if MLN_UBO_CONSOLIDATION + layerUniforms->set(idLineExpressionUBO, expressionUniformBuffer); +#else + auto& drawableUniforms = drawable.mutableUniformBuffers(); + drawableUniforms.set(idLineExpressionUBO, expressionUniformBuffer); +#endif + } + #if MLN_UBO_CONSOLIDATION shaders::LineDrawableUnionUBO drawableUBO; drawableUBO.lineDrawableUBO = { @@ -125,33 +171,45 @@ class LineDrawableTweaker : public gfx::DrawableTweaker { /* .width_t = */ 0.f, /* .pad1 = */ 0 }; - auto& drawableUniforms = drawable.mutableUniformBuffers(); - drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, parameters.context, true); - drawableUniforms.createOrUpdate(idLineEvaluatedPropsUBO, &propsUBO, parameters.context); - // We would need to set up `idLineExpressionUBO` if the expression mask isn't empty - assert(propsUBO.expressionMask == LineExpressionMask::None); +#if MLN_UBO_CONSOLIDATION + if (!drawableUniformBuffer) { + drawableUniformBuffer = parameters.context.createUniformBuffer( + &drawableUBO, sizeof(drawableUBO), false, true); + + layerUniforms->set(idLineDrawableUBO, drawableUniformBuffer); + drawable.setUBOIndex(0); + } else { + drawableUniformBuffer->update(&drawableUBO, sizeof(drawableUBO)); + } - const LineExpressionUBO exprUBO = { - /* .color = */ nullptr, - /* .blur = */ nullptr, - /* .opacity = */ nullptr, - /* .gapwidth = */ nullptr, - /* .offset = */ nullptr, - /* .width = */ nullptr, - /* .floorWidth = */ nullptr, - }; - drawableUniforms.createOrUpdate(idLineExpressionUBO, &exprUBO, parameters.context); + layerUniforms->createOrUpdate(idLineEvaluatedPropsUBO, &propsUBO, sizeof(propsUBO), parameters.context); + layerUniforms->bind(*parameters.renderPass); +#else + auto& drawableUniforms = drawable.mutableUniformBuffers(); + drawableUniforms.createOrUpdate(idLineDrawableUBO, &drawableUBO, parameters.context); + drawableUniforms.createOrUpdate(idLineEvaluatedPropsUBO, &propsUBO, parameters.context); +#endif }; private: - shaders::LineEvaluatedPropsUBO propsUBO; + CustomDrawableLayerHost::Interface::LineOptions options; + CustomDrawableLayerHost::Interface::LineTweakerCallback callback; + +#if MLN_UBO_CONSOLIDATION + gfx::UniqueUniformBufferArray layerUniforms; + gfx::UniformBufferPtr drawableUniformBuffer; +#endif + + gfx::UniformBufferPtr expressionUniformBuffer; }; class WideVectorDrawableTweaker : public gfx::DrawableTweaker { public: - WideVectorDrawableTweaker(const CustomDrawableLayerHost::Interface::LineOptions& options_) - : options(options_) {} + WideVectorDrawableTweaker(const CustomDrawableLayerHost::Interface::LineOptions& options_, + CustomDrawableLayerHost::Interface::LineTweakerCallback&& callback_) + : options(options_), + callback(callback_) {} void init(gfx::Drawable&) override {} @@ -160,6 +218,10 @@ class WideVectorDrawableTweaker : public gfx::DrawableTweaker { return; } + if (callback) { + callback(drawable, parameters, options); + } + const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); mat4 tileMatrix; @@ -211,13 +273,16 @@ class WideVectorDrawableTweaker : public gfx::DrawableTweaker { private: CustomDrawableLayerHost::Interface::LineOptions options; + CustomDrawableLayerHost::Interface::LineTweakerCallback callback; }; class FillDrawableTweaker : public gfx::DrawableTweaker { public: - FillDrawableTweaker(const Color& color_, float opacity_) - : color(color_), - opacity(opacity_) {} + FillDrawableTweaker(const CustomDrawableLayerHost::Interface::FillOptions& options_, + CustomDrawableLayerHost::Interface::FillTweakerCallback&& callback_) + : options(options_), + callback(callback_) {} + ~FillDrawableTweaker() override = default; void init(gfx::Drawable&) override {} @@ -227,15 +292,29 @@ class FillDrawableTweaker : public gfx::DrawableTweaker { return; } - const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); - mat4 tileMatrix; - parameters.state.matrixFor(/*out*/ tileMatrix, tileID); + if (callback) { + callback(drawable, parameters, options); + } + +#if MLN_UBO_CONSOLIDATION + if (!layerUniforms) { + layerUniforms = parameters.context.createLayerUniformBufferArray(); + } +#endif + const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); const auto matrix = LayerTweaker::getTileMatrix( tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false); + const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ options.color, + /* .outline_color = */ Color::white(), + /* .opacity = */ options.opacity, + /* .fade = */ 0.f, + /* .from_scale = */ 0.f, + /* .to_scale = */ 0.f}; + #if MLN_UBO_CONSOLIDATION - shaders::FillDrawableUnionUBO drawableUBO; + FillDrawableUnionUBO drawableUBO; drawableUBO.fillDrawableUBO = { #else const shaders::FillDrawableUBO drawableUBO = { @@ -248,26 +327,42 @@ class FillDrawableTweaker : public gfx::DrawableTweaker { /* .pad2 = */ 0 }; - const shaders::FillEvaluatedPropsUBO propsUBO = {/* .color = */ color, - /* .outline_color = */ Color::white(), - /* .opacity = */ opacity, - /* .fade = */ 0.f, - /* .from_scale = */ 0.f, - /* .to_scale = */ 0.f}; +#if MLN_UBO_CONSOLIDATION + if (!drawableUniformBuffer) { + drawableUniformBuffer = parameters.context.createUniformBuffer( + &drawableUBO, sizeof(drawableUBO), false, true); + + layerUniforms->set(idFillDrawableUBO, drawableUniformBuffer); + drawable.setUBOIndex(0); + } else { + drawableUniformBuffer->update(&drawableUBO, sizeof(drawableUBO)); + } + + layerUniforms->createOrUpdate(idFillEvaluatedPropsUBO, &propsUBO, sizeof(propsUBO), parameters.context); + layerUniforms->bind(*parameters.renderPass); +#else auto& drawableUniforms = drawable.mutableUniformBuffers(); drawableUniforms.createOrUpdate(idFillDrawableUBO, &drawableUBO, parameters.context); drawableUniforms.createOrUpdate(idFillEvaluatedPropsUBO, &propsUBO, parameters.context); +#endif }; private: - Color color; - float opacity; + CustomDrawableLayerHost::Interface::FillOptions options; + CustomDrawableLayerHost::Interface::FillTweakerCallback callback; + +#if MLN_UBO_CONSOLIDATION + gfx::UniqueUniformBufferArray layerUniforms; + gfx::UniformBufferPtr drawableUniformBuffer; +#endif }; class SymbolDrawableTweaker : public gfx::DrawableTweaker { public: - SymbolDrawableTweaker(const CustomDrawableLayerHost::Interface::SymbolOptions& options_) - : options(options_) {} + SymbolDrawableTweaker(const CustomDrawableLayerHost::Interface::SymbolOptions& options_, + CustomDrawableLayerHost::Interface::SymbolTweakerCallback&& callback_) + : options(options_), + callback(callback_) {} ~SymbolDrawableTweaker() override = default; void init(gfx::Drawable&) override {} @@ -277,9 +372,11 @@ class SymbolDrawableTweaker : public gfx::DrawableTweaker { return; } + if (callback) { + callback(drawable, parameters, options); + } + const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); - mat4 tileMatrix; - parameters.state.matrixFor(/*out*/ tileMatrix, tileID); const auto matrix = LayerTweaker::getTileMatrix( tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false); @@ -312,6 +409,38 @@ class SymbolDrawableTweaker : public gfx::DrawableTweaker { private: CustomDrawableLayerHost::Interface::SymbolOptions options; + CustomDrawableLayerHost::Interface::SymbolTweakerCallback callback; +}; + +class GeometryDrawableTweaker : public gfx::DrawableTweaker { +public: + GeometryDrawableTweaker(const CustomDrawableLayerHost::Interface::GeometryOptions& options_, + CustomDrawableLayerHost::Interface::GeometryTweakerCallback&& callback_) + : options(options_), + callback(callback_) {} + ~GeometryDrawableTweaker() override = default; + + void init(gfx::Drawable&) override {} + + void execute(gfx::Drawable& drawable, PaintParameters& parameters) override { + if (!drawable.getTileID().has_value()) { + return; + } + + if (callback) { + callback(drawable, parameters, options); + } + + CustomGeometryDrawableUBO drawableUBO = {/* .matrix = */ util::cast(options.matrix), + /* .color = */ options.color}; + + auto& drawableUniforms = drawable.mutableUniformBuffers(); + drawableUniforms.createOrUpdate(idCustomGeometryDrawableUBO, &drawableUBO, parameters.context); + }; + +private: + CustomDrawableLayerHost::Interface::GeometryOptions options; + CustomDrawableLayerHost::Interface::GeometryTweakerCallback callback; }; CustomDrawableLayerHost::Interface::Interface(RenderLayer& layer_, @@ -364,6 +493,11 @@ void CustomDrawableLayerHost::Interface::setSymbolOptions(const SymbolOptions& o symbolOptions = options; } +void CustomDrawableLayerHost::Interface::setGeometryOptions(const GeometryOptions& options) { + finish(); + geometryOptions = options; +} + bool CustomDrawableLayerHost::Interface::updateBuilder(BuilderType type, const std::string& name, gfx::ShaderPtr shader) { @@ -378,17 +512,22 @@ bool CustomDrawableLayerHost::Interface::updateBuilder(BuilderType type, return true; }; -bool CustomDrawableLayerHost::Interface::addPolyline(const LineString& coordinates) { - switch (lineOptions.shaderType) { +util::SimpleIdentity CustomDrawableLayerHost::Interface::addPolyline(const LineString& coordinates, + LineShaderType shaderType) { +#if !MLN_RENDER_BACKEND_METAL + shaderType = LineShaderType::Classic; +#endif + + switch (shaderType) { case LineShaderType::Classic: { // TODO: build classic polyline with Geo coordinates - return false; + return util::SimpleIdentity::Empty; } break; - case LineShaderType::MetalWideVector: { + case LineShaderType::WideVector: { // build wide vector polyline with Geo coordinates if (!updateBuilder(BuilderType::LineWideVector, "custom-lines-widevector", lineShaderWideVector())) - return false; + return util::SimpleIdentity::Empty; // geographic coordinates require tile {0, 0, 0} setTileID({0, 0, 0}); @@ -397,32 +536,42 @@ bool CustomDrawableLayerHost::Interface::addPolyline(const LineString& c } break; } - return true; + return builder->getCurrentDrawable(true)->getID(); } -bool CustomDrawableLayerHost::Interface::addPolyline(const GeometryCoordinates& coordinates) { - switch (lineOptions.shaderType) { +util::SimpleIdentity CustomDrawableLayerHost::Interface::addPolyline(const GeometryCoordinates& coordinates, + LineShaderType shaderType) { +#if !MLN_RENDER_BACKEND_METAL + shaderType = LineShaderType::Classic; +#endif + + switch (shaderType) { case LineShaderType::Classic: { // build classic polyline with Tile coordinates - if (!updateBuilder(BuilderType::LineClassic, "custom-lines", lineShaderDefault())) return false; + if (!updateBuilder(BuilderType::LineClassic, "custom-lines", lineShaderDefault())) { + return util::SimpleIdentity::Empty; + } + builder->addPolyline(coordinates, lineOptions.geometry); } break; - case LineShaderType::MetalWideVector: { + case LineShaderType::WideVector: { // build wide vector polyline if (!updateBuilder(BuilderType::LineWideVector, "custom-lines-widevector", lineShaderWideVector())) - return false; + return util::SimpleIdentity::Empty; builder->addWideVectorPolylineLocal(coordinates, lineOptions.geometry); } break; } - return true; + return builder->getCurrentDrawable(true)->getID(); } -bool CustomDrawableLayerHost::Interface::addFill(const GeometryCollection& geometry) { +util::SimpleIdentity CustomDrawableLayerHost::Interface::addFill(const GeometryCollection& geometry) { // build fill - if (!updateBuilder(BuilderType::Fill, "custom-fill", fillShaderDefault())) return false; + if (!updateBuilder(BuilderType::Fill, "custom-fill", fillShaderDefault())) { + return util::SimpleIdentity::Empty; + } // provision buffers for fill vertices, indexes and segments using VertexVector = gfx::VertexVector; @@ -451,15 +600,20 @@ bool CustomDrawableLayerHost::Interface::addFill(const GeometryCollection& geome builder->setRawVertices({}, vertices.elements(), gfx::AttributeDataType::Short2); builder->setSegments(gfx::Triangles(), sharedTriangles, triangleSegments.data(), triangleSegments.size()); + const auto& id = builder->getCurrentDrawable(true)->getID(); + // flush current builder drawable builder->flush(context); - return true; + return id; } -bool CustomDrawableLayerHost::Interface::addSymbol(const GeometryCoordinate& point) { +util::SimpleIdentity CustomDrawableLayerHost::Interface::addSymbol( + const GeometryCoordinate& point, const std::array, 2>& textureCoordinates) { // build symbol - if (!updateBuilder(BuilderType::Symbol, "custom-symbol", symbolShaderDefault())) return false; + if (!updateBuilder(BuilderType::Symbol, "custom-symbol", symbolShaderDefault())) { + return util::SimpleIdentity::Empty; + } // temporary: buffers struct CustomSymbolIcon { @@ -477,7 +631,7 @@ bool CustomDrawableLayerHost::Interface::addSymbol(const GeometryCoordinate& poi for (int x = 0; x <= 1; ++x) { vertices.emplace_back( CustomSymbolIcon{{static_cast(point.x * 2 + x), static_cast(point.y * 2 + y)}, - {symbolOptions.textureCoordinates[x][0], symbolOptions.textureCoordinates[y][1]}}); + {textureCoordinates[x][0], textureCoordinates[y][1]}}); } } @@ -517,13 +671,83 @@ bool CustomDrawableLayerHost::Interface::addSymbol(const GeometryCoordinate& poi } // create symbol tweaker - auto tweaker = std::make_shared(symbolOptions); + auto tweaker = std::make_shared(symbolOptions, std::move(symbolTweakerCallback)); builder->addTweaker(tweaker); + const auto& id = builder->getCurrentDrawable(true)->getID(); + // flush current builder drawable builder->flush(context); - return true; + return id; +} + +util::SimpleIdentity CustomDrawableLayerHost::Interface::addGeometry( + std::shared_ptr> vertices, + std::shared_ptr> indices, + bool is3D) { + if (!vertices || !indices) { + return util::SimpleIdentity::Empty; + } + + if (!updateBuilder(BuilderType::Geometry, "custom-geometry", geometryShaderDefault())) { + return util::SimpleIdentity::Empty; + } + + // geographic coordinates require tile {0, 0, 0} + setTileID({0, 0, 0}); + + SegmentVector triangleSegments; + triangleSegments.emplace_back(Segment{0, 0, vertices->elements(), indices->elements()}); + + // add to builder + auto attrs = context.createVertexAttributeArray(); + if (const auto& attr = attrs->set(idCustomGeometryPosVertexAttribute)) { + attr->setSharedRawData(vertices, + offsetof(GeometryVertex, position), + /*vertexOffset=*/0, + sizeof(GeometryVertex), + gfx::AttributeDataType::Float3); + } + + if (const auto& attr = attrs->set(idCustomGeometryTexVertexAttribute)) { + attr->setSharedRawData(vertices, + offsetof(GeometryVertex, texcoords), + /*vertexOffset=*/0, + sizeof(GeometryVertex), + gfx::AttributeDataType::Float2); + } + + builder->setVertexAttributes(std::move(attrs)); + builder->setRawVertices({}, vertices->elements(), gfx::AttributeDataType::Float3); + builder->setSegments(gfx::Triangles(), indices, triangleSegments.data(), triangleSegments.size()); + + builder->setEnableDepth(true); + + if (is3D) { + builder->setDepthType(gfx::DepthMaskType::ReadWrite); + builder->setIs3D(true); + } + + // white texture + if (!geometryOptions.texture) { + auto image = std::make_shared(mbgl::Size(2, 2)); + image->fill(255); + + geometryOptions.texture = context.createTexture2D(); + geometryOptions.texture->setImage(std::move(image)); + } + + builder->setTexture(geometryOptions.texture, shaders::idCustomGeometryTexture); + + builder->addTweaker(std::make_shared(geometryOptions, std::move(geometryTweakerCallback))); + + const auto& id = builder->getCurrentDrawable(true)->getID(); + + // flush current builder drawable + builder->flush(context); + + return id; } void CustomDrawableLayerHost::Interface::finish() { @@ -552,16 +776,7 @@ void CustomDrawableLayerHost::Interface::finish() { // finish building classic lines // create line tweaker - const shaders::LineEvaluatedPropsUBO linePropertiesUBO = {lineOptions.color, - lineOptions.blur, - lineOptions.opacity, - lineOptions.gapWidth, - lineOptions.offset, - lineOptions.width, - /*floorwidth=*/0, - LineExpressionMask::None, - 0}; - auto tweaker = std::make_shared(linePropertiesUBO); + auto tweaker = std::make_shared(lineOptions, std::move(lineTweakerCallback)); // finish drawables finish_(tweaker); @@ -570,7 +785,7 @@ void CustomDrawableLayerHost::Interface::finish() { // finish building wide vector lines // create line tweaker - auto tweaker = std::make_shared(lineOptions); + auto tweaker = std::make_shared(lineOptions, std::move(lineTweakerCallback)); // finish drawables finish_(tweaker); @@ -579,7 +794,7 @@ void CustomDrawableLayerHost::Interface::finish() { // finish building fills // create fill tweaker - auto tweaker = std::make_shared(fillOptions.color, fillOptions.opacity); + auto tweaker = std::make_shared(fillOptions, std::move(fillTweakerCallback)); // finish drawables finish_(tweaker); @@ -588,12 +803,21 @@ void CustomDrawableLayerHost::Interface::finish() { // finish building symbols finish_(nullptr); break; + + case BuilderType::Geometry: + finish_(nullptr); + break; default: break; } } } +void CustomDrawableLayerHost::Interface::removeDrawable(const util::SimpleIdentity& id) { + TileLayerGroup* tileLayerGroup = static_cast(layerGroup.get()); + tileLayerGroup->removeDrawablesIf([&](gfx::Drawable& drawable) { return drawable.getID() == id; }); +} + gfx::ShaderPtr CustomDrawableLayerHost::Interface::lineShaderDefault() const { gfx::ShaderGroupPtr shaderGroup = shaders.getShaderGroup("LineShader"); assert(shaderGroup); @@ -630,6 +854,10 @@ gfx::ShaderPtr CustomDrawableLayerHost::Interface::symbolShaderDefault() const { return context.getGenericShader(shaders, "CustomSymbolIconShader"); } +gfx::ShaderPtr CustomDrawableLayerHost::Interface::geometryShaderDefault() const { + return context.getGenericShader(shaders, "CustomGeometryShader"); +} + std::unique_ptr CustomDrawableLayerHost::Interface::createBuilder(const std::string& name, gfx::ShaderPtr shader) const { std::unique_ptr builder_ = context.createDrawableBuilder(name); diff --git a/src/mbgl/vulkan/context.cpp b/src/mbgl/vulkan/context.cpp index 678ca378da4..ed795052dfa 100644 --- a/src/mbgl/vulkan/context.cpp +++ b/src/mbgl/vulkan/context.cpp @@ -366,6 +366,11 @@ gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t data, size, ssbo ? VK_BUFFER_USAGE_STORAGE_BUFFER_BIT : VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, persistent)); } +UniqueUniformBufferArray Context::createLayerUniformBufferArray() { + return std::make_unique( + DescriptorSetType::Layer, shaders::globalUBOCount, shaders::maxSSBOCountPerLayer, shaders::maxUBOCountPerLayer); +} + gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) { const auto shaderGroup = shaders.getShaderGroup(name); auto shader = shaderGroup ? shaderGroup->getOrCreateShader(*this, {}) : gfx::ShaderProgramBasePtr{}; diff --git a/src/mbgl/vulkan/drawable.cpp b/src/mbgl/vulkan/drawable.cpp index 06f52581e52..257cea6b64f 100644 --- a/src/mbgl/vulkan/drawable.cpp +++ b/src/mbgl/vulkan/drawable.cpp @@ -260,23 +260,30 @@ void Drawable::draw(PaintParameters& parameters) const { sizeof(uboIndex), &uboIndex); - if (is3D) { - impl->pipelineInfo.setDepthMode(impl->depthFor3D); - impl->pipelineInfo.setStencilMode(impl->stencilFor3D); - } else { - if (enableDepth) { + if (enableDepth) { + if (impl->depthFor3D.has_value()) { + impl->pipelineInfo.setDepthMode(impl->depthFor3D.value()); + } else if (is3D) { + impl->pipelineInfo.setDepthMode(parameters.depthModeFor3D()); + } else { const auto& depthMode = parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType()); impl->pipelineInfo.setDepthMode(depthMode); - } else { - impl->pipelineInfo.setDepthMode(gfx::DepthMode::disabled()); } + } else { + impl->pipelineInfo.setDepthMode(gfx::DepthMode::disabled()); + } - if (enableStencil) { + if (enableStencil) { + if (impl->stencilFor3D.has_value()) { + impl->pipelineInfo.setStencilMode(impl->stencilFor3D.value()); + } else if (is3D) { + impl->pipelineInfo.setStencilMode(parameters.stencilModeFor3D()); + } else { const auto& stencilMode = parameters.stencilModeForClipping(tileID->toUnwrapped()); impl->pipelineInfo.setStencilMode(stencilMode); - } else { - impl->pipelineInfo.setStencilMode(gfx::StencilMode::disabled()); } + } else { + impl->pipelineInfo.setStencilMode(gfx::StencilMode::disabled()); } impl->pipelineInfo.setRenderable(renderPass_.getDescriptor().renderable); diff --git a/src/mbgl/vulkan/drawable_impl.hpp b/src/mbgl/vulkan/drawable_impl.hpp index a159fa6adc0..b74b5d5f6ce 100644 --- a/src/mbgl/vulkan/drawable_impl.hpp +++ b/src/mbgl/vulkan/drawable_impl.hpp @@ -44,8 +44,8 @@ class Drawable::Impl final { std::optional renderPassDescriptor; - gfx::DepthMode depthFor3D = gfx::DepthMode::disabled(); - gfx::StencilMode stencilFor3D = gfx::StencilMode::disabled(); + std::optional depthFor3D; + std::optional stencilFor3D; PipelineInfo pipelineInfo; diff --git a/src/mbgl/vulkan/layer_group.cpp b/src/mbgl/vulkan/layer_group.cpp index 9d9d57fba07..3bcf1b0a9b7 100644 --- a/src/mbgl/vulkan/layer_group.cpp +++ b/src/mbgl/vulkan/layer_group.cpp @@ -56,15 +56,15 @@ void LayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) { return; } - for (const auto& tweaker : drawable.getTweakers()) { - tweaker->execute(drawable, parameters); - } - if (!bindUBOs) { uniformBuffers.bindDescriptorSets(encoder); bindUBOs = true; } + for (const auto& tweaker : drawable.getTweakers()) { + tweaker->execute(drawable, parameters); + } + drawable.draw(parameters); }); } diff --git a/src/mbgl/vulkan/renderer_backend.cpp b/src/mbgl/vulkan/renderer_backend.cpp index 277d332ebbc..e20826c3d08 100644 --- a/src/mbgl/vulkan/renderer_backend.cpp +++ b/src/mbgl/vulkan/renderer_backend.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -669,6 +670,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar shaders::BuiltIn::ClippingMaskProgram, shaders::BuiltIn::CollisionBoxShader, shaders::BuiltIn::CollisionCircleShader, + shaders::BuiltIn::CustomGeometryShader, shaders::BuiltIn::CustomSymbolIconShader, shaders::BuiltIn::DebugShader, shaders::BuiltIn::FillShader, diff --git a/src/mbgl/vulkan/tile_layer_group.cpp b/src/mbgl/vulkan/tile_layer_group.cpp index f1326b13b6f..c33c716ba18 100644 --- a/src/mbgl/vulkan/tile_layer_group.cpp +++ b/src/mbgl/vulkan/tile_layer_group.cpp @@ -92,15 +92,15 @@ void TileLayerGroup::render(RenderOrchestrator&, PaintParameters& parameters) { return; } - for (const auto& tweaker : drawable.getTweakers()) { - tweaker->execute(drawable, parameters); - } - if (!bindUBOs) { uniformBuffers.bindDescriptorSets(encoder); bindUBOs = true; } + for (const auto& tweaker : drawable.getTweakers()) { + tweaker->execute(drawable, parameters); + } + if (features3d) { auto& drawableImpl = static_cast(drawable); diff --git a/src/mbgl/vulkan/uniform_buffer.cpp b/src/mbgl/vulkan/uniform_buffer.cpp index 839622a0dc3..615fc4130f6 100644 --- a/src/mbgl/vulkan/uniform_buffer.cpp +++ b/src/mbgl/vulkan/uniform_buffer.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -68,6 +69,10 @@ void UniformBufferArray::createOrUpdate( gfx::UniformBufferArray::createOrUpdate(id, data, size, context, persistent); } +void UniformBufferArray::bind(gfx::RenderPass& renderPass) { + bindDescriptorSets(static_cast(renderPass).getEncoder()); +} + void UniformBufferArray::bindDescriptorSets(CommandEncoder& encoder) { if (!descriptorSet) { descriptorSet = std::make_unique(encoder.getContext(), descriptorSetType); diff --git a/test/api/custom_drawable_layer.test.cpp b/test/api/custom_drawable_layer.test.cpp index c3e6bd6e57a..5c20485c21e 100644 --- a/test/api/custom_drawable_layer.test.cpp +++ b/test/api/custom_drawable_layer.test.cpp @@ -48,7 +48,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/0.0f, /*offset=*/0.0f, /*width=*/8.0f, - /*shaderType*/ {}, /*color=*/Color::red(), }, { @@ -58,7 +57,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/2.0f, /*offset=*/-1.0f, /*width=*/4.0f, - {}, /*color=*/Color::blue(), }, { @@ -68,7 +66,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/1.0f, /*offset=*/2.0f, /*width=*/16.0f, - {}, /*color=*/Color(1.f, 0.5f, 0, 0.5f), }, { @@ -78,7 +75,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/1.0f, /*offset=*/-2.0f, /*width=*/2.0f, - {}, /*color=*/Color(1.f, 1.f, 0, 0.3f), }, { @@ -88,7 +84,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/1.0f, /*offset=*/0.5f, /*width=*/0.5f, - {}, /*color=*/Color::black(), }, { @@ -98,7 +93,6 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { /*gapWidth=*/1.0f, /*offset=*/-5.0f, /*width=*/24.0f, - {}, /*color=*/Color(1.f, 0, 1.f, 0.2f), }, }; @@ -125,7 +119,7 @@ class LineTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost { interface.setLineOptions(options[index]); // add polyline - interface.addPolyline(polyline); + interface.addPolyline(polyline, Interface::LineShaderType::Classic); } } @@ -219,10 +213,10 @@ class SymbolIconTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost options.texture->setImage(image); options.texture->setSamplerConfiguration( {gfx::TextureFilterType::Linear, gfx::TextureWrapType::Clamp, gfx::TextureWrapType::Clamp}); - options.textureCoordinates = {{{0.0f, 0.08f}, {1.0f, 0.9f}}}; - const float xspan = options.textureCoordinates[1][0] - options.textureCoordinates[0][0]; - const float yspan = options.textureCoordinates[1][1] - options.textureCoordinates[0][1]; - assert(xspan > 0.0f && yspan > 0.0f); + constexpr std::array, 2> textureCoordinates = {{{0.0f, 0.08f}, {1.0f, 0.9f}}}; + constexpr float xspan = textureCoordinates[1][0] - textureCoordinates[0][0]; + constexpr float yspan = textureCoordinates[1][1] - textureCoordinates[0][1]; + static_assert(xspan > 0.0f && yspan > 0.0f); options.size = {static_cast(image->size.width * 0.2f * xspan), static_cast(image->size.height * 0.2f * yspan)}; options.anchor = {0.5f, 0.95f}; @@ -232,7 +226,7 @@ class SymbolIconTestDrawableLayer : public mbgl::style::CustomDrawableLayerHost interface.setSymbolOptions(options); // add symbol - interface.addSymbol(position); + interface.addSymbol(position, textureCoordinates); } // finish diff --git a/test/util/hash.test.cpp b/test/util/hash.test.cpp index d2563a7f743..7d8c32ad8eb 100644 --- a/test/util/hash.test.cpp +++ b/test/util/hash.test.cpp @@ -14,6 +14,8 @@ #include #include #include +#include +#include #include #include #include @@ -22,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -128,6 +131,8 @@ TEST(OrderIndependentHash, Shaders) { BuiltIn::CircleShader, BuiltIn::CollisionBoxShader, BuiltIn::CollisionCircleShader, + BuiltIn::CustomGeometryShader, + BuiltIn::CustomSymbolIconShader, BuiltIn::DebugShader, BuiltIn::FillShader, BuiltIn::FillOutlineShader, @@ -144,6 +149,8 @@ TEST(OrderIndependentHash, Shaders) { BuiltIn::LineGradientShader, BuiltIn::LinePatternShader, BuiltIn::LineSDFShader, + BuiltIn::LocationIndicatorShader, + BuiltIn::LocationIndicatorTexturedShader, BuiltIn::RasterShader, BuiltIn::SymbolIconShader, BuiltIn::SymbolSDFIconShader, diff --git a/vendor/tinyobjloader.cmake b/vendor/tinyobjloader.cmake new file mode 100644 index 00000000000..b8b50348f18 --- /dev/null +++ b/vendor/tinyobjloader.cmake @@ -0,0 +1,19 @@ +include(FetchContent) + +FetchContent_Declare( + tinyobjloader + GIT_REPOSITORY "https://github.com/tinyobjloader/tinyobjloader.git" + GIT_TAG release + GIT_SHALLOW TRUE + GIT_PROGRESS TRUE +) + +FetchContent_MakeAvailable(tinyobjloader) + +set_target_properties( + tinyobjloader + PROPERTIES + INTERFACE_MAPLIBRE_NAME "tinyobjloader" + INTERFACE_MAPLIBRE_URL "https://github.com/tinyobjloader/tinyobjloader.git" + INTERFACE_MAPLIBRE_LICENSE ${CMAKE_CURRENT_LIST_DIR}/tinyobjloader/LICENSE +)