Circle layer (#1153)
This commit is contained in:
committed by
Bart Louwers
parent
5df482b12e
commit
2c53c138c8
@@ -181,6 +181,7 @@ list(APPEND INCLUDE_FILES
|
|||||||
${PROJECT_SOURCE_DIR}/include/mbgl/platform/thread.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/platform/thread.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/query.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/query.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/layer_group.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/layer_group.hpp
|
||||||
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/layer_tweaker.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_frontend.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_frontend.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_observer.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/renderer/renderer_observer.hpp
|
||||||
@@ -520,6 +521,13 @@ list(APPEND SRC_FILES
|
|||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager.hpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager_observer.hpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/image_manager_observer.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_group.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_group.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layer_tweaker.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/background_layer_tweaker.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/background_layer_tweaker.hpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/circle_layer_tweaker.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/circle_layer_tweaker.hpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/fill_layer_tweaker.cpp
|
||||||
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/fill_layer_tweaker.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.cpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.hpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_background_layer.hpp
|
||||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_circle_layer.cpp
|
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/render_circle_layer.cpp
|
||||||
@@ -929,6 +937,7 @@ if(MLN_WITH_OPENGL)
|
|||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/prelude.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/prelude.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/background.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_background.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_background.hpp
|
||||||
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_circle.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline.hpp
|
||||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp
|
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ enum class DepthMaskType : bool;
|
|||||||
class DrawableTweaker;
|
class DrawableTweaker;
|
||||||
class ShaderProgramBase;
|
class ShaderProgramBase;
|
||||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
|
||||||
using DrawPriority = int64_t;
|
using DrawPriority = int64_t;
|
||||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||||
|
|
||||||
@@ -178,12 +177,5 @@ private:
|
|||||||
bool desc;
|
bool desc;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(16) DrawableUBO {
|
|
||||||
std::array<float, 4 * 4> matrix;
|
|
||||||
std::array<float, 2> world;
|
|
||||||
std::array<float, 2> padding;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(DrawableUBO) % 16 == 0);
|
|
||||||
|
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -25,6 +25,9 @@ using DrawablePtr = std::shared_ptr<Drawable>;
|
|||||||
using UniqueDrawable = std::unique_ptr<Drawable>;
|
using UniqueDrawable = std::unique_ptr<Drawable>;
|
||||||
} // namespace gfx
|
} // namespace gfx
|
||||||
|
|
||||||
|
class LayerTweaker;
|
||||||
|
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
A layer-like group of drawables, not a group of layers.
|
A layer-like group of drawables, not a group of layers.
|
||||||
*/
|
*/
|
||||||
@@ -54,8 +57,15 @@ public:
|
|||||||
/// Call the provided function for each drawable in undefined order, allowing ownership to be taken.
|
/// Call the provided function for each drawable in undefined order, allowing ownership to be taken.
|
||||||
virtual void observeDrawables(std::function<void(gfx::UniqueDrawable&)>) = 0;
|
virtual void observeDrawables(std::function<void(gfx::UniqueDrawable&)>) = 0;
|
||||||
|
|
||||||
|
/// Attach a tweaker to be run on this layer group for each frame
|
||||||
|
void setLayerTweaker(LayerTweakerPtr tweaker) { layerTweaker = std::move(tweaker); }
|
||||||
|
|
||||||
|
/// Get the tweaker attached to this layer group
|
||||||
|
const LayerTweakerPtr& getLayerTweaker() const { return layerTweaker; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32_t layerIndex;
|
int32_t layerIndex;
|
||||||
|
LayerTweakerPtr layerTweaker;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
33
include/mbgl/renderer/layer_tweaker.hpp
Normal file
33
include/mbgl/renderer/layer_tweaker.hpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mbgl/util/immutable.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
namespace style {
|
||||||
|
class LayerProperties;
|
||||||
|
} // namespace style
|
||||||
|
|
||||||
|
class PaintParameters;
|
||||||
|
class LayerGroup;
|
||||||
|
|
||||||
|
/**
|
||||||
|
Base class for layer tweakers, which manipulate layer group per frame
|
||||||
|
*/
|
||||||
|
class LayerTweaker {
|
||||||
|
protected:
|
||||||
|
LayerTweaker() = delete;
|
||||||
|
LayerTweaker(Immutable<style::LayerProperties> properties);
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~LayerTweaker() = default;
|
||||||
|
|
||||||
|
virtual void execute(LayerGroup&, const PaintParameters&) = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Immutable<style::LayerProperties> evaluatedProperties;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
@@ -11,10 +11,8 @@ template <>
|
|||||||
struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::OpenGL> {
|
struct ShaderSource<BuiltIn::BackgroundShader, gfx::Backend::Type::OpenGL> {
|
||||||
static constexpr const char* name = "BackgroundShader";
|
static constexpr const char* name = "BackgroundShader";
|
||||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform BackgroundDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
|
||||||
vec2 pad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|||||||
234
include/mbgl/shaders/gl/drawable_circle.hpp
Normal file
234
include/mbgl/shaders/gl/drawable_circle.hpp
Normal file
@@ -0,0 +1,234 @@
|
|||||||
|
// Generated code, do not modify this file!
|
||||||
|
// Generated on 2023-05-17T18:24:20.170Z by alex using shaders/generate_shader_code.js
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include <mbgl/shaders/shader_source.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
namespace shaders {
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct ShaderSource<BuiltIn::CircleShader, gfx::Backend::Type::OpenGL> {
|
||||||
|
static constexpr const char* name = "CircleShader";
|
||||||
|
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||||
|
out vec3 v_data;
|
||||||
|
|
||||||
|
layout (std140) uniform CircleDrawableUBO {
|
||||||
|
mat4 u_matrix;
|
||||||
|
vec2 u_extrude_scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CirclePaintParamsUBO {
|
||||||
|
highp float u_camera_to_center_distance;
|
||||||
|
lowp float u_device_pixel_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CircleEvaluatedPropsUBO {
|
||||||
|
highp vec4 u_color;
|
||||||
|
highp vec4 u_stroke_color;
|
||||||
|
mediump float u_radius;
|
||||||
|
lowp float u_blur;
|
||||||
|
lowp float u_opacity;
|
||||||
|
mediump float u_stroke_width;
|
||||||
|
lowp float u_stroke_opacity;
|
||||||
|
bool u_scale_with_map;
|
||||||
|
bool u_pitch_with_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CircleInterpolateUBO {
|
||||||
|
lowp float u_color_t;
|
||||||
|
lowp float u_radius_t;
|
||||||
|
lowp float u_blur_t;
|
||||||
|
lowp float u_opacity_t;
|
||||||
|
lowp float u_stroke_color_t;
|
||||||
|
lowp float u_stroke_width_t;
|
||||||
|
lowp float u_stroke_opacity_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef HAS_UNIFORM_u_color
|
||||||
|
layout (location = 1) in highp vec4 a_color;
|
||||||
|
out highp vec4 color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_radius
|
||||||
|
layout (location = 2) in mediump vec2 a_radius;
|
||||||
|
out mediump float radius;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_blur
|
||||||
|
layout (location = 3) in lowp vec2 a_blur;
|
||||||
|
out lowp float blur;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_opacity
|
||||||
|
layout (location = 4) in lowp vec2 a_opacity;
|
||||||
|
out lowp float opacity;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_color
|
||||||
|
layout (location = 5) in highp vec4 a_stroke_color;
|
||||||
|
out highp vec4 stroke_color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_width
|
||||||
|
layout (location = 6) in mediump vec2 a_stroke_width;
|
||||||
|
out mediump float stroke_width;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_opacity
|
||||||
|
layout (location = 7) in lowp vec2 a_stroke_opacity;
|
||||||
|
out lowp float stroke_opacity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
#ifndef HAS_UNIFORM_u_color
|
||||||
|
color = unpack_mix_color(a_color, u_color_t);
|
||||||
|
#else
|
||||||
|
highp vec4 color = u_color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_radius
|
||||||
|
radius = unpack_mix_vec2(a_radius, u_radius_t);
|
||||||
|
#else
|
||||||
|
mediump float radius = u_radius;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_blur
|
||||||
|
blur = unpack_mix_vec2(a_blur, u_blur_t);
|
||||||
|
#else
|
||||||
|
lowp float blur = u_blur;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_opacity
|
||||||
|
opacity = unpack_mix_vec2(a_opacity, u_opacity_t);
|
||||||
|
#else
|
||||||
|
lowp float opacity = u_opacity;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_color
|
||||||
|
stroke_color = unpack_mix_color(a_stroke_color, u_stroke_color_t);
|
||||||
|
#else
|
||||||
|
highp vec4 stroke_color = u_stroke_color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_width
|
||||||
|
stroke_width = unpack_mix_vec2(a_stroke_width, u_stroke_width_t);
|
||||||
|
#else
|
||||||
|
mediump float stroke_width = u_stroke_width;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_opacity
|
||||||
|
stroke_opacity = unpack_mix_vec2(a_stroke_opacity, u_stroke_opacity_t);
|
||||||
|
#else
|
||||||
|
lowp float stroke_opacity = u_stroke_opacity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// unencode the extrusion vector that we snuck into the a_pos vector
|
||||||
|
vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);
|
||||||
|
|
||||||
|
// multiply a_pos by 0.5, since we had it * 2 in order to sneak
|
||||||
|
// in extrusion data
|
||||||
|
vec2 circle_center = floor(a_pos * 0.5);
|
||||||
|
if (u_pitch_with_map) {
|
||||||
|
vec2 corner_position = circle_center;
|
||||||
|
if (u_scale_with_map) {
|
||||||
|
corner_position += extrude * (radius + stroke_width) * u_extrude_scale;
|
||||||
|
} else {
|
||||||
|
// Pitching the circle with the map effectively scales it with the map
|
||||||
|
// To counteract the effect for pitch-scale: viewport, we rescale the
|
||||||
|
// whole circle based on the pitch scaling effect at its central point
|
||||||
|
vec4 projected_center = u_matrix * vec4(circle_center, 0, 1);
|
||||||
|
corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = u_matrix * vec4(corner_position, 0, 1);
|
||||||
|
} else {
|
||||||
|
gl_Position = u_matrix * vec4(circle_center, 0, 1);
|
||||||
|
|
||||||
|
if (u_scale_with_map) {
|
||||||
|
gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance;
|
||||||
|
} else {
|
||||||
|
gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a minimum blur distance that serves as a faux-antialiasing for
|
||||||
|
// the circle. since blur is a ratio of the circle's size and the intent is
|
||||||
|
// to keep the blur at roughly 1px, the two are inversely related.
|
||||||
|
lowp float antialiasblur = 1.0 / u_device_pixel_ratio / (radius + stroke_width);
|
||||||
|
|
||||||
|
v_data = vec3(extrude.x, extrude.y, antialiasblur);
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
static constexpr const char* fragment = R"(in vec3 v_data;
|
||||||
|
|
||||||
|
layout (std140) uniform CircleEvaluatedPropsUBO {
|
||||||
|
highp vec4 u_color;
|
||||||
|
highp vec4 u_stroke_color;
|
||||||
|
mediump float u_radius;
|
||||||
|
lowp float u_blur;
|
||||||
|
lowp float u_opacity;
|
||||||
|
mediump float u_stroke_width;
|
||||||
|
lowp float u_stroke_opacity;
|
||||||
|
bool u_scale_with_map;
|
||||||
|
bool u_pitch_with_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef HAS_UNIFORM_u_color
|
||||||
|
in highp vec4 color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_radius
|
||||||
|
in mediump float radius;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_blur
|
||||||
|
in lowp float blur;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_opacity
|
||||||
|
in lowp float opacity;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_color
|
||||||
|
in highp vec4 stroke_color;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_width
|
||||||
|
in mediump float stroke_width;
|
||||||
|
#endif
|
||||||
|
#ifndef HAS_UNIFORM_u_stroke_opacity
|
||||||
|
in lowp float stroke_opacity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
#ifdef HAS_UNIFORM_u_color
|
||||||
|
highp vec4 color = u_color;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_radius
|
||||||
|
mediump float radius = u_radius;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_blur
|
||||||
|
lowp float blur = u_blur;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_opacity
|
||||||
|
lowp float opacity = u_opacity;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_stroke_color
|
||||||
|
highp vec4 stroke_color = u_stroke_color;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_stroke_width
|
||||||
|
mediump float stroke_width = u_stroke_width;
|
||||||
|
#endif
|
||||||
|
#ifdef HAS_UNIFORM_u_stroke_opacity
|
||||||
|
lowp float stroke_opacity = u_stroke_opacity;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
vec2 extrude = v_data.xy;
|
||||||
|
float extrude_length = length(extrude);
|
||||||
|
|
||||||
|
lowp float antialiasblur = v_data.z;
|
||||||
|
float antialiased_blur = -max(blur, antialiasblur);
|
||||||
|
|
||||||
|
float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);
|
||||||
|
|
||||||
|
float color_t = stroke_width < 0.01 ? 0.0 : smoothstep(
|
||||||
|
antialiased_blur,
|
||||||
|
0.0,
|
||||||
|
extrude_length - radius / (radius + stroke_width)
|
||||||
|
);
|
||||||
|
|
||||||
|
fragColor = opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t);
|
||||||
|
|
||||||
|
#ifdef OVERDRAW_INSPECTOR
|
||||||
|
fragColor = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
)";
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace shaders
|
||||||
|
} // namespace mbgl
|
||||||
@@ -12,7 +12,7 @@ struct ShaderSource<BuiltIn::FillShader, gfx::Backend::Type::OpenGL> {
|
|||||||
static constexpr const char* name = "FillShader";
|
static constexpr const char* name = "FillShader";
|
||||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||||
|
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform FillDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
vec2 u_world;
|
||||||
vec2 pad;
|
vec2 pad;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::OpenGL> {
|
|||||||
static constexpr const char* name = "FillOutlineShader";
|
static constexpr const char* name = "FillOutlineShader";
|
||||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||||
|
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform FillDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
vec2 u_world;
|
||||||
vec2 pad;
|
vec2 pad;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#ifdef MBGL_RENDER_BACKEND_OPENGL
|
#ifdef MBGL_RENDER_BACKEND_OPENGL
|
||||||
#include <mbgl/shaders/gl/drawable_background.hpp>
|
#include <mbgl/shaders/gl/drawable_background.hpp>
|
||||||
|
#include <mbgl/shaders/gl/drawable_circle.hpp>
|
||||||
#include <mbgl/shaders/gl/drawable_fill.hpp>
|
#include <mbgl/shaders/gl/drawable_fill.hpp>
|
||||||
#include <mbgl/shaders/gl/drawable_fill_outline.hpp>
|
#include <mbgl/shaders/gl/drawable_fill_outline.hpp>
|
||||||
#include <mbgl/shaders/gl/drawable_fill_pattern.hpp>
|
#include <mbgl/shaders/gl/drawable_fill_pattern.hpp>
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ namespace shaders {
|
|||||||
enum class BuiltIn {
|
enum class BuiltIn {
|
||||||
None,
|
None,
|
||||||
BackgroundShader,
|
BackgroundShader,
|
||||||
|
CircleShader,
|
||||||
FillShader,
|
FillShader,
|
||||||
FillOutlineShader,
|
FillOutlineShader,
|
||||||
FillPatternShader,
|
FillPatternShader,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
layout (location = 0) in vec2 a_pos;
|
layout (location = 0) in vec2 a_pos;
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform BackgroundDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
vec2 u_world;
|
||||||
vec2 pad;
|
vec2 pad;
|
||||||
|
|||||||
51
shaders/drawable.circle.fragment.glsl
Normal file
51
shaders/drawable.circle.fragment.glsl
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
in vec3 v_data;
|
||||||
|
|
||||||
|
layout (std140) uniform CircleEvaluatedPropsUBO {
|
||||||
|
highp vec4 u_color;
|
||||||
|
mediump float u_radius;
|
||||||
|
lowp float u_blur;
|
||||||
|
lowp float u_opacity;
|
||||||
|
highp vec4 u_stroke_color;
|
||||||
|
mediump float u_stroke_width;
|
||||||
|
lowp float u_stroke_opacity;
|
||||||
|
bool u_scale_with_map;
|
||||||
|
bool u_pitch_with_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mapbox: define highp vec4 color
|
||||||
|
#pragma mapbox: define mediump float radius
|
||||||
|
#pragma mapbox: define lowp float blur
|
||||||
|
#pragma mapbox: define lowp float opacity
|
||||||
|
#pragma mapbox: define highp vec4 stroke_color
|
||||||
|
#pragma mapbox: define mediump float stroke_width
|
||||||
|
#pragma mapbox: define lowp float stroke_opacity
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
#pragma mapbox: initialize highp vec4 color
|
||||||
|
#pragma mapbox: initialize mediump float radius
|
||||||
|
#pragma mapbox: initialize lowp float blur
|
||||||
|
#pragma mapbox: initialize lowp float opacity
|
||||||
|
#pragma mapbox: initialize highp vec4 stroke_color
|
||||||
|
#pragma mapbox: initialize mediump float stroke_width
|
||||||
|
#pragma mapbox: initialize lowp float stroke_opacity
|
||||||
|
|
||||||
|
vec2 extrude = v_data.xy;
|
||||||
|
float extrude_length = length(extrude);
|
||||||
|
|
||||||
|
lowp float antialiasblur = v_data.z;
|
||||||
|
float antialiased_blur = -max(blur, antialiasblur);
|
||||||
|
|
||||||
|
float opacity_t = smoothstep(0.0, antialiased_blur, extrude_length - 1.0);
|
||||||
|
|
||||||
|
float color_t = stroke_width < 0.01 ? 0.0 : smoothstep(
|
||||||
|
antialiased_blur,
|
||||||
|
0.0,
|
||||||
|
extrude_length - radius / (radius + stroke_width)
|
||||||
|
);
|
||||||
|
|
||||||
|
fragColor = opacity_t * mix(color * opacity, stroke_color * stroke_opacity, color_t);
|
||||||
|
|
||||||
|
#ifdef OVERDRAW_INSPECTOR
|
||||||
|
fragColor = vec4(1.0);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
88
shaders/drawable.circle.vertex.glsl
Normal file
88
shaders/drawable.circle.vertex.glsl
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
layout (location = 0) in vec2 a_pos;
|
||||||
|
out vec3 v_data;
|
||||||
|
|
||||||
|
layout (std140) uniform CircleDrawableUBO {
|
||||||
|
mat4 u_matrix;
|
||||||
|
vec2 u_extrude_scale;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CirclePaintParamsUBO {
|
||||||
|
highp float u_camera_to_center_distance;
|
||||||
|
lowp float u_device_pixel_ratio;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CircleEvaluatedPropsUBO {
|
||||||
|
highp vec4 u_color;
|
||||||
|
highp vec4 u_stroke_color;
|
||||||
|
mediump float u_radius;
|
||||||
|
lowp float u_blur;
|
||||||
|
lowp float u_opacity;
|
||||||
|
mediump float u_stroke_width;
|
||||||
|
lowp float u_stroke_opacity;
|
||||||
|
bool u_scale_with_map;
|
||||||
|
bool u_pitch_with_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
layout (std140) uniform CircleInterpolateUBO {
|
||||||
|
lowp float u_color_t;
|
||||||
|
lowp float u_radius_t;
|
||||||
|
lowp float u_blur_t;
|
||||||
|
lowp float u_opacity_t;
|
||||||
|
lowp float u_stroke_color_t;
|
||||||
|
lowp float u_stroke_width_t;
|
||||||
|
lowp float u_stroke_opacity_t;
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma mapbox: define highp vec4 color
|
||||||
|
#pragma mapbox: define mediump float radius
|
||||||
|
#pragma mapbox: define lowp float blur
|
||||||
|
#pragma mapbox: define lowp float opacity
|
||||||
|
#pragma mapbox: define highp vec4 stroke_color
|
||||||
|
#pragma mapbox: define mediump float stroke_width
|
||||||
|
#pragma mapbox: define lowp float stroke_opacity
|
||||||
|
|
||||||
|
void main(void) {
|
||||||
|
#pragma mapbox: initialize highp vec4 color
|
||||||
|
#pragma mapbox: initialize mediump float radius
|
||||||
|
#pragma mapbox: initialize lowp float blur
|
||||||
|
#pragma mapbox: initialize lowp float opacity
|
||||||
|
#pragma mapbox: initialize highp vec4 stroke_color
|
||||||
|
#pragma mapbox: initialize mediump float stroke_width
|
||||||
|
#pragma mapbox: initialize lowp float stroke_opacity
|
||||||
|
|
||||||
|
// unencode the extrusion vector that we snuck into the a_pos vector
|
||||||
|
vec2 extrude = vec2(mod(a_pos, 2.0) * 2.0 - 1.0);
|
||||||
|
|
||||||
|
// multiply a_pos by 0.5, since we had it * 2 in order to sneak
|
||||||
|
// in extrusion data
|
||||||
|
vec2 circle_center = floor(a_pos * 0.5);
|
||||||
|
if (u_pitch_with_map) {
|
||||||
|
vec2 corner_position = circle_center;
|
||||||
|
if (u_scale_with_map) {
|
||||||
|
corner_position += extrude * (radius + stroke_width) * u_extrude_scale;
|
||||||
|
} else {
|
||||||
|
// Pitching the circle with the map effectively scales it with the map
|
||||||
|
// To counteract the effect for pitch-scale: viewport, we rescale the
|
||||||
|
// whole circle based on the pitch scaling effect at its central point
|
||||||
|
vec4 projected_center = u_matrix * vec4(circle_center, 0, 1);
|
||||||
|
corner_position += extrude * (radius + stroke_width) * u_extrude_scale * (projected_center.w / u_camera_to_center_distance);
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_Position = u_matrix * vec4(corner_position, 0, 1);
|
||||||
|
} else {
|
||||||
|
gl_Position = u_matrix * vec4(circle_center, 0, 1);
|
||||||
|
|
||||||
|
if (u_scale_with_map) {
|
||||||
|
gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * u_camera_to_center_distance;
|
||||||
|
} else {
|
||||||
|
gl_Position.xy += extrude * (radius + stroke_width) * u_extrude_scale * gl_Position.w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is a minimum blur distance that serves as a faux-antialiasing for
|
||||||
|
// the circle. since blur is a ratio of the circle's size and the intent is
|
||||||
|
// to keep the blur at roughly 1px, the two are inversely related.
|
||||||
|
lowp float antialiasblur = 1.0 / u_device_pixel_ratio / (radius + stroke_width);
|
||||||
|
|
||||||
|
v_data = vec3(extrude.x, extrude.y, antialiasblur);
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
layout (location = 0) in vec2 a_pos;
|
layout (location = 0) in vec2 a_pos;
|
||||||
|
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform FillDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
vec2 u_world;
|
||||||
vec2 pad;
|
vec2 pad;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
layout (location = 0) in vec2 a_pos;
|
layout (location = 0) in vec2 a_pos;
|
||||||
|
|
||||||
layout (std140) uniform DrawableUBO {
|
layout (std140) uniform FillDrawableUBO {
|
||||||
mat4 u_matrix;
|
mat4 u_matrix;
|
||||||
vec2 u_world;
|
vec2 u_world;
|
||||||
vec2 pad;
|
vec2 pad;
|
||||||
|
|||||||
@@ -6,6 +6,13 @@
|
|||||||
"glsl_frag": "drawable.background.fragment.glsl",
|
"glsl_frag": "drawable.background.fragment.glsl",
|
||||||
"uses_ubos": true
|
"uses_ubos": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "CircleShader",
|
||||||
|
"header": "drawable_circle",
|
||||||
|
"glsl_vert": "drawable.circle.vertex.glsl",
|
||||||
|
"glsl_frag": "drawable.circle.fragment.glsl",
|
||||||
|
"uses_ubos": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "FillShader",
|
"name": "FillShader",
|
||||||
"header": "drawable_fill",
|
"header": "drawable_fill",
|
||||||
|
|||||||
@@ -81,22 +81,6 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
|
|||||||
const auto labelPtr = (label.empty() ? drawable.getName() : label).c_str();
|
const auto labelPtr = (label.empty() ? drawable.getName() : label).c_str();
|
||||||
const auto debugGroup = parameters.encoder->createDebugGroup(labelPtr);
|
const auto debugGroup = parameters.encoder->createDebugGroup(labelPtr);
|
||||||
|
|
||||||
mat4 matrix = drawable.getMatrix();
|
|
||||||
if (drawable.getTileID()) {
|
|
||||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
|
||||||
const auto tileMat = parameters.matrixForTile(tileID);
|
|
||||||
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
|
|
||||||
matrix = tileMat;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
|
||||||
|
|
||||||
gfx::DrawableUBO drawableUBO;
|
|
||||||
drawableUBO.matrix = util::cast<float>(matrix);
|
|
||||||
drawableUBO.world = {(float)renderableSize.width, (float)renderableSize.height};
|
|
||||||
auto uniformBuffer = context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
|
||||||
drawable.mutableUniformBuffers().addOrReplace("DrawableUBO", uniformBuffer);
|
|
||||||
|
|
||||||
drawable.draw(parameters);
|
drawable.draw(parameters);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ void registerTypes(gfx::ShaderRegistry& registry, gl::Context& glContext, const
|
|||||||
|
|
||||||
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramParameters& programParameters) {
|
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramParameters& programParameters) {
|
||||||
registerTypes<shaders::BuiltIn::BackgroundShader,
|
registerTypes<shaders::BuiltIn::BackgroundShader,
|
||||||
|
shaders::BuiltIn::CircleShader,
|
||||||
shaders::BuiltIn::FillShader,
|
shaders::BuiltIn::FillShader,
|
||||||
shaders::BuiltIn::FillOutlineShader,
|
shaders::BuiltIn::FillOutlineShader,
|
||||||
shaders::BuiltIn::FillOutlinePatternShader,
|
shaders::BuiltIn::FillOutlinePatternShader,
|
||||||
|
|||||||
9
src/mbgl/renderer/layer_tweaker.cpp
Normal file
9
src/mbgl/renderer/layer_tweaker.cpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
|
#include <mbgl/style/layer_properties.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
LayerTweaker::LayerTweaker(Immutable<style::LayerProperties> properties)
|
||||||
|
: evaluatedProperties(std::move(properties)){};
|
||||||
|
|
||||||
|
}
|
||||||
72
src/mbgl/renderer/layers/background_layer_tweaker.cpp
Normal file
72
src/mbgl/renderer/layers/background_layer_tweaker.cpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#include <mbgl/renderer/layers/background_layer_tweaker.hpp>
|
||||||
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
|
#include <mbgl/style/layers/background_layer_properties.hpp>
|
||||||
|
#include <mbgl/gfx/context.hpp>
|
||||||
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
|
#include <mbgl/util/convert.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
using namespace style;
|
||||||
|
|
||||||
|
struct alignas(16) BackgroundDrawableUBO {
|
||||||
|
std::array<float, 4 * 4> matrix;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(BackgroundDrawableUBO) % 16 == 0);
|
||||||
|
|
||||||
|
struct alignas(16) BackgroundLayerUBO {
|
||||||
|
Color color;
|
||||||
|
float opacity;
|
||||||
|
float padding[3];
|
||||||
|
};
|
||||||
|
static_assert(sizeof(BackgroundLayerUBO) % 16 == 0);
|
||||||
|
|
||||||
|
struct alignas(16) BackgroundPatternLayerUBO {
|
||||||
|
std::array<float, 2> pattern_tl_a;
|
||||||
|
std::array<float, 2> pattern_br_a;
|
||||||
|
std::array<float, 2> pattern_tl_b;
|
||||||
|
std::array<float, 2> pattern_br_b;
|
||||||
|
std::array<float, 2> texsize;
|
||||||
|
std::array<float, 2> pattern_size_a;
|
||||||
|
std::array<float, 2> pattern_size_b;
|
||||||
|
std::array<float, 2> pixel_coord_upper;
|
||||||
|
std::array<float, 2> pixel_coord_lower;
|
||||||
|
float tile_units_to_pixels;
|
||||||
|
float scale_a;
|
||||||
|
float scale_b;
|
||||||
|
float mix;
|
||||||
|
float opacity;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(BackgroundPatternLayerUBO) % 16 == 0);
|
||||||
|
|
||||||
|
void BackgroundLayerTweaker::execute(LayerGroup& layerGroup, const PaintParameters& parameters) {
|
||||||
|
const auto& evaluated = static_cast<const BackgroundLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
|
if (!layerUniformBuffer) {
|
||||||
|
BackgroundLayerUBO layerUBO;
|
||||||
|
layerUBO.color = evaluated.get<BackgroundColor>();
|
||||||
|
layerUBO.opacity = evaluated.get<BackgroundOpacity>();
|
||||||
|
layerUniformBuffer = parameters.context.createUniformBuffer(&layerUBO, sizeof(layerUBO));
|
||||||
|
}
|
||||||
|
|
||||||
|
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", layerUniformBuffer);
|
||||||
|
|
||||||
|
if (!drawable.getTileID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mat4 matrix = drawable.getMatrix();
|
||||||
|
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||||
|
const auto tileMat = parameters.matrixForTile(tileID);
|
||||||
|
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
|
||||||
|
matrix = tileMat;
|
||||||
|
|
||||||
|
BackgroundDrawableUBO drawableUBO;
|
||||||
|
drawableUBO.matrix = util::cast<float>(matrix);
|
||||||
|
auto drawableUniformBuffer = parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("BackgroundDrawableUBO", drawableUniformBuffer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
29
src/mbgl/renderer/layers/background_layer_tweaker.hpp
Normal file
29
src/mbgl/renderer/layers/background_layer_tweaker.hpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
class UniformBuffer;
|
||||||
|
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||||
|
} // namespace gfx
|
||||||
|
|
||||||
|
/**
|
||||||
|
Background layer specific tweaker
|
||||||
|
*/
|
||||||
|
class BackgroundLayerTweaker : public LayerTweaker {
|
||||||
|
public:
|
||||||
|
BackgroundLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||||
|
: LayerTweaker(properties){};
|
||||||
|
|
||||||
|
public:
|
||||||
|
~BackgroundLayerTweaker() override = default;
|
||||||
|
|
||||||
|
void execute(LayerGroup&, const PaintParameters&) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gfx::UniformBufferPtr layerUniformBuffer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
110
src/mbgl/renderer/layers/circle_layer_tweaker.cpp
Normal file
110
src/mbgl/renderer/layers/circle_layer_tweaker.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
#include <mbgl/renderer/layers/circle_layer_tweaker.hpp>
|
||||||
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
|
#include <mbgl/style/layers/circle_layer_properties.hpp>
|
||||||
|
#include <mbgl/gfx/context.hpp>
|
||||||
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
|
#include <mbgl/util/convert.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
using namespace style;
|
||||||
|
|
||||||
|
struct alignas(16) CircleDrawableUBO {
|
||||||
|
std::array<float, 4 * 4> matrix;
|
||||||
|
std::array<float, 2> extrude_scale;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CircleDrawableUBO) % 16 == 0);
|
||||||
|
|
||||||
|
struct alignas(16) CirclePaintParamsUBO {
|
||||||
|
float camera_to_center_distance;
|
||||||
|
float device_pixel_ratio;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CirclePaintParamsUBO) % 16 == 0);
|
||||||
|
|
||||||
|
struct alignas(16) CircleEvaluatedPropsUBO {
|
||||||
|
Color color;
|
||||||
|
Color stroke_color;
|
||||||
|
float radius;
|
||||||
|
float blur;
|
||||||
|
float opacity;
|
||||||
|
float stroke_width;
|
||||||
|
float stroke_opacity;
|
||||||
|
int scale_with_map;
|
||||||
|
int pitch_with_map;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CircleEvaluatedPropsUBO) % 16 == 0);
|
||||||
|
|
||||||
|
struct alignas(16) CircleInterpolateUBO {
|
||||||
|
float color_t;
|
||||||
|
float radius_t;
|
||||||
|
float blur_t;
|
||||||
|
float opacity_t;
|
||||||
|
float stroke_color_t;
|
||||||
|
float stroke_width_t;
|
||||||
|
float stroke_opacity_t;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(CircleInterpolateUBO) % 16 == 0);
|
||||||
|
|
||||||
|
void CircleLayerTweaker::execute(LayerGroup& layerGroup, const PaintParameters& parameters) {
|
||||||
|
const auto& evaluated = static_cast<const CircleLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
|
CirclePaintParamsUBO paintParamsUBO;
|
||||||
|
paintParamsUBO.camera_to_center_distance = parameters.state.getCameraToCenterDistance();
|
||||||
|
paintParamsUBO.device_pixel_ratio = parameters.pixelRatio;
|
||||||
|
auto paintParamsUniformBuffer = parameters.context.createUniformBuffer(&paintParamsUBO, sizeof(paintParamsUBO));
|
||||||
|
|
||||||
|
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
|
||||||
|
|
||||||
|
if (!evaluatedPropsUniformBuffer) {
|
||||||
|
CircleEvaluatedPropsUBO evaluatedPropsUBO;
|
||||||
|
evaluatedPropsUBO.color = evaluated.get<CircleColor>().constantOr(Color());
|
||||||
|
evaluatedPropsUBO.radius = evaluated.get<CircleRadius>().constantOr(0);
|
||||||
|
evaluatedPropsUBO.blur = evaluated.get<CircleBlur>().constantOr(0);
|
||||||
|
evaluatedPropsUBO.opacity = evaluated.get<CircleOpacity>().constantOr(0);
|
||||||
|
evaluatedPropsUBO.stroke_color = evaluated.get<CircleStrokeColor>().constantOr(Color());
|
||||||
|
evaluatedPropsUBO.stroke_width = evaluated.get<CircleStrokeWidth>().constantOr(0);
|
||||||
|
evaluatedPropsUBO.stroke_opacity = evaluated.get<CircleStrokeOpacity>().constantOr(0);
|
||||||
|
evaluatedPropsUBO.scale_with_map = evaluated.get<CirclePitchScale>() == CirclePitchScaleType::Map;
|
||||||
|
evaluatedPropsUBO.pitch_with_map = pitchWithMap;
|
||||||
|
evaluatedPropsUniformBuffer = parameters.context.createUniformBuffer(&evaluatedPropsUBO,
|
||||||
|
sizeof(evaluatedPropsUBO));
|
||||||
|
}
|
||||||
|
|
||||||
|
CircleInterpolateUBO interpolateUBO;
|
||||||
|
interpolateUBO.color_t = 0;
|
||||||
|
interpolateUBO.radius_t = 0;
|
||||||
|
interpolateUBO.blur_t = 0;
|
||||||
|
interpolateUBO.opacity_t = 0;
|
||||||
|
interpolateUBO.stroke_color_t = 0;
|
||||||
|
interpolateUBO.stroke_width_t = 0;
|
||||||
|
interpolateUBO.stroke_opacity_t = 0;
|
||||||
|
auto interpolateUniformBuffer = parameters.context.createUniformBuffer(&interpolateUBO, sizeof(interpolateUBO));
|
||||||
|
|
||||||
|
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("CirclePaintParamsUBO", paintParamsUniformBuffer);
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("CircleEvaluatedPropsUBO", evaluatedPropsUniformBuffer);
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("CircleInterpolateUBO", interpolateUniformBuffer);
|
||||||
|
|
||||||
|
if (!drawable.getTileID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mat4 matrix = drawable.getMatrix();
|
||||||
|
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||||
|
const auto tileMat = parameters.matrixForTile(tileID);
|
||||||
|
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
|
||||||
|
matrix = tileMat;
|
||||||
|
|
||||||
|
CircleDrawableUBO drawableUBO;
|
||||||
|
drawableUBO.matrix = util::cast<float>(matrix);
|
||||||
|
drawableUBO.extrude_scale =
|
||||||
|
pitchWithMap
|
||||||
|
? std::array<float, 2>{{tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||||
|
tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom()))}}
|
||||||
|
: parameters.pixelsToGLUnits;
|
||||||
|
auto drawableUniformBuffer = parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("CircleDrawableUBO", drawableUniformBuffer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
29
src/mbgl/renderer/layers/circle_layer_tweaker.hpp
Normal file
29
src/mbgl/renderer/layers/circle_layer_tweaker.hpp
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
namespace gfx {
|
||||||
|
class UniformBuffer;
|
||||||
|
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||||
|
} // namespace gfx
|
||||||
|
|
||||||
|
/**
|
||||||
|
Circle layer specific tweaker
|
||||||
|
*/
|
||||||
|
class CircleLayerTweaker : public LayerTweaker {
|
||||||
|
public:
|
||||||
|
CircleLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||||
|
: LayerTweaker(properties){};
|
||||||
|
|
||||||
|
public:
|
||||||
|
~CircleLayerTweaker() override = default;
|
||||||
|
|
||||||
|
void execute(LayerGroup&, const PaintParameters&) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
gfx::UniformBufferPtr evaluatedPropsUniformBuffer = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
61
src/mbgl/renderer/layers/fill_layer_tweaker.cpp
Normal file
61
src/mbgl/renderer/layers/fill_layer_tweaker.cpp
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
#include <mbgl/renderer/layers/fill_layer_tweaker.hpp>
|
||||||
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
|
#include <mbgl/style/layers/fill_layer_properties.hpp>
|
||||||
|
#include <mbgl/gfx/context.hpp>
|
||||||
|
#include <mbgl/gfx/drawable.hpp>
|
||||||
|
#include <mbgl/gfx/renderable.hpp>
|
||||||
|
#include <mbgl/gfx/renderer_backend.hpp>
|
||||||
|
#include <mbgl/util/convert.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
using namespace style;
|
||||||
|
|
||||||
|
struct alignas(16) FillDrawableUBO {
|
||||||
|
std::array<float, 4 * 4> matrix;
|
||||||
|
std::array<float, 2> world;
|
||||||
|
std::array<float, 2> padding;
|
||||||
|
};
|
||||||
|
static_assert(sizeof(FillDrawableUBO) % 16 == 0);
|
||||||
|
|
||||||
|
void FillLayerTweaker::execute(LayerGroup& layerGroup, const PaintParameters& parameters) {
|
||||||
|
// const auto& evaluated = static_cast<const FillLayerProperties&>(*evaluatedProperties).evaluated;
|
||||||
|
|
||||||
|
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||||
|
if (!drawable.getTileID()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/*mat4 matrix = drawable.getMatrix();
|
||||||
|
if (drawable.getTileID()) {
|
||||||
|
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||||
|
const auto tileMat = parameters.matrixForTile(tileID);
|
||||||
|
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
|
||||||
|
matrix = tileMat;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||||
|
|
||||||
|
gfx::DrawableUBO drawableUBO;
|
||||||
|
drawableUBO.matrix = util::cast<float>(matrix);
|
||||||
|
drawableUBO.world = {(float)renderableSize.width, (float)renderableSize.height};
|
||||||
|
auto uniformBuffer = context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("DrawableUBO", uniformBuffer);*/
|
||||||
|
|
||||||
|
mat4 matrix = drawable.getMatrix();
|
||||||
|
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||||
|
const auto tileMat = parameters.matrixForTile(tileID);
|
||||||
|
matrix::multiply(matrix, drawable.getMatrix(), tileMat);
|
||||||
|
matrix = tileMat;
|
||||||
|
|
||||||
|
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||||
|
|
||||||
|
FillDrawableUBO drawableUBO;
|
||||||
|
drawableUBO.matrix = util::cast<float>(matrix);
|
||||||
|
drawableUBO.world = {(float)renderableSize.width, (float)renderableSize.height};
|
||||||
|
auto drawableUniformBuffer = parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||||
|
drawable.mutableUniformBuffers().addOrReplace("FillDrawableUBO", drawableUniformBuffer);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
21
src/mbgl/renderer/layers/fill_layer_tweaker.hpp
Normal file
21
src/mbgl/renderer/layers/fill_layer_tweaker.hpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
|
|
||||||
|
namespace mbgl {
|
||||||
|
|
||||||
|
/**
|
||||||
|
Fill layer specific tweaker
|
||||||
|
*/
|
||||||
|
class FillLayerTweaker : public LayerTweaker {
|
||||||
|
public:
|
||||||
|
FillLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||||
|
: LayerTweaker(properties){};
|
||||||
|
|
||||||
|
public:
|
||||||
|
~FillLayerTweaker() override = default;
|
||||||
|
|
||||||
|
void execute(LayerGroup&, const PaintParameters&) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace mbgl
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <mbgl/renderer/layers/render_background_layer.hpp>
|
#include <mbgl/renderer/layers/render_background_layer.hpp>
|
||||||
|
#include <mbgl/renderer/layers/background_layer_tweaker.hpp>
|
||||||
#include <mbgl/gfx/context.hpp>
|
#include <mbgl/gfx/context.hpp>
|
||||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||||
#include <mbgl/gfx/shader_registry.hpp>
|
#include <mbgl/gfx/shader_registry.hpp>
|
||||||
@@ -62,7 +62,9 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
|
|||||||
properties->renderPasses = mbgl::underlying_type(passes);
|
properties->renderPasses = mbgl::underlying_type(passes);
|
||||||
|
|
||||||
evaluatedProperties = std::move(properties);
|
evaluatedProperties = std::move(properties);
|
||||||
evaluatedPropertiesChange = true;
|
if (tileLayerGroup) {
|
||||||
|
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderBackgroundLayer::hasTransition() const {
|
bool RenderBackgroundLayer::hasTransition() const {
|
||||||
@@ -73,10 +75,16 @@ bool RenderBackgroundLayer::hasCrossfade() const {
|
|||||||
return getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
return getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool enableDefaultRender = false;
|
||||||
|
|
||||||
void RenderBackgroundLayer::render(PaintParameters& parameters) {
|
void RenderBackgroundLayer::render(PaintParameters& parameters) {
|
||||||
// Note that for bottommost layers without a pattern, the background color
|
// Note that for bottommost layers without a pattern, the background color
|
||||||
// is drawn with glClear rather than this method.
|
// is drawn with glClear rather than this method.
|
||||||
|
|
||||||
|
if (!enableDefaultRender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Ensure programs are available
|
// Ensure programs are available
|
||||||
if (!parameters.shaders.populate(backgroundProgram)) return;
|
if (!parameters.shaders.populate(backgroundProgram)) return;
|
||||||
if (!parameters.shaders.populate(backgroundPatternProgram)) return;
|
if (!parameters.shaders.populate(backgroundPatternProgram)) return;
|
||||||
@@ -210,6 +218,10 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
|||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& state,
|
const TransformState& state,
|
||||||
UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
|
if (enableDefaultRender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> guard(mutex);
|
std::unique_lock<std::mutex> guard(mutex);
|
||||||
|
|
||||||
if (!shader) {
|
if (!shader) {
|
||||||
@@ -253,19 +265,12 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evaluatedPropertiesChange) {
|
|
||||||
BackgroundLayerUBO backgroundLayerUBO;
|
|
||||||
backgroundLayerUBO.color = evaluated.get<BackgroundColor>();
|
|
||||||
backgroundLayerUBO.opacity = evaluated.get<BackgroundOpacity>();
|
|
||||||
uniformBuffer = context.createUniformBuffer(&backgroundLayerUBO, sizeof(backgroundLayerUBO));
|
|
||||||
evaluatedPropertiesChange = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!tileLayerGroup) {
|
if (!tileLayerGroup) {
|
||||||
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
|
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
|
||||||
if (!tileLayerGroup) {
|
if (!tileLayerGroup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
|
||||||
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,7 +311,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
|||||||
|
|
||||||
if (tileDrawable) {
|
if (tileDrawable) {
|
||||||
// Already created, update it.
|
// Already created, update it.
|
||||||
tileDrawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +336,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
|||||||
if (!newDrawables.empty()) {
|
if (!newDrawables.empty()) {
|
||||||
auto& drawable = newDrawables[0];
|
auto& drawable = newDrawables[0];
|
||||||
drawable->setTileID(tileID);
|
drawable->setTileID(tileID);
|
||||||
drawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
|
||||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||||
++stats.tileDrawablesAdded;
|
++stats.tileDrawablesAdded;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,29 +52,4 @@ private:
|
|||||||
gfx::ShaderProgramBasePtr shader;
|
gfx::ShaderProgramBasePtr shader;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct alignas(16) BackgroundLayerUBO {
|
|
||||||
Color color;
|
|
||||||
float opacity;
|
|
||||||
float padding[3];
|
|
||||||
};
|
|
||||||
static_assert(sizeof(BackgroundLayerUBO) % 16 == 0);
|
|
||||||
|
|
||||||
struct alignas(16) BackgroundPatternLayerUBO {
|
|
||||||
std::array<float, 2> pattern_tl_a;
|
|
||||||
std::array<float, 2> pattern_br_a;
|
|
||||||
std::array<float, 2> pattern_tl_b;
|
|
||||||
std::array<float, 2> pattern_br_b;
|
|
||||||
std::array<float, 2> texsize;
|
|
||||||
std::array<float, 2> pattern_size_a;
|
|
||||||
std::array<float, 2> pattern_size_b;
|
|
||||||
std::array<float, 2> pixel_coord_upper;
|
|
||||||
std::array<float, 2> pixel_coord_lower;
|
|
||||||
float tile_units_to_pixels;
|
|
||||||
float scale_a;
|
|
||||||
float scale_b;
|
|
||||||
float mix;
|
|
||||||
float opacity;
|
|
||||||
};
|
|
||||||
static_assert(sizeof(BackgroundPatternLayerUBO) % 16 == 0);
|
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include <mbgl/renderer/layers/render_circle_layer.hpp>
|
#include <mbgl/renderer/layers/render_circle_layer.hpp>
|
||||||
|
#include <mbgl/renderer/layers/circle_layer_tweaker.hpp>
|
||||||
#include <mbgl/renderer/buckets/circle_bucket.hpp>
|
#include <mbgl/renderer/buckets/circle_bucket.hpp>
|
||||||
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
#include <mbgl/renderer/render_tile.hpp>
|
#include <mbgl/renderer/render_tile.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/programs/programs.hpp>
|
#include <mbgl/programs/programs.hpp>
|
||||||
@@ -7,6 +9,7 @@
|
|||||||
#include <mbgl/tile/tile.hpp>
|
#include <mbgl/tile/tile.hpp>
|
||||||
#include <mbgl/style/layers/circle_layer_impl.hpp>
|
#include <mbgl/style/layers/circle_layer_impl.hpp>
|
||||||
#include <mbgl/geometry/feature_index.hpp>
|
#include <mbgl/geometry/feature_index.hpp>
|
||||||
|
#include <mbgl/gfx/drawable_builder.hpp>
|
||||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||||
#include <mbgl/gfx/shader_registry.hpp>
|
#include <mbgl/gfx/shader_registry.hpp>
|
||||||
#include <mbgl/util/math.hpp>
|
#include <mbgl/util/math.hpp>
|
||||||
@@ -69,6 +72,9 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
|
|||||||
: RenderPass::None;
|
: RenderPass::None;
|
||||||
properties->renderPasses = mbgl::underlying_type(passes);
|
properties->renderPasses = mbgl::underlying_type(passes);
|
||||||
evaluatedProperties = std::move(properties);
|
evaluatedProperties = std::move(properties);
|
||||||
|
if (tileLayerGroup) {
|
||||||
|
tileLayerGroup->setLayerTweaker(std::make_shared<CircleLayerTweaker>(evaluatedProperties));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderCircleLayer::hasTransition() const {
|
bool RenderCircleLayer::hasTransition() const {
|
||||||
@@ -79,8 +85,15 @@ bool RenderCircleLayer::hasCrossfade() const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool enableDefaultRender = false;
|
||||||
|
|
||||||
void RenderCircleLayer::render(PaintParameters& parameters) {
|
void RenderCircleLayer::render(PaintParameters& parameters) {
|
||||||
assert(renderTiles);
|
assert(renderTiles);
|
||||||
|
|
||||||
|
if (!enableDefaultRender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (parameters.pass == RenderPass::Opaque) {
|
if (parameters.pass == RenderPass::Opaque) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -236,4 +249,214 @@ bool RenderCircleLayer::queryIntersectsFeature(const GeometryCoordinates& queryG
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RenderCircleLayer::layerRemoved(UniqueChangeRequestVec& changes) {
|
||||||
|
// Remove everything
|
||||||
|
if (tileLayerGroup) {
|
||||||
|
changes.emplace_back(std::make_unique<RemoveLayerGroupRequest>(tileLayerGroup->getLayerIndex()));
|
||||||
|
tileLayerGroup.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCircleLayer::removeTile(RenderPass renderPass, const OverscaledTileID& tileID) {
|
||||||
|
stats.tileDrawablesRemoved += tileLayerGroup->removeDrawables(renderPass, tileID).size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void RenderCircleLayer::update(const int32_t layerIndex,
|
||||||
|
gfx::ShaderRegistry& shaders,
|
||||||
|
gfx::Context& context,
|
||||||
|
const TransformState& /*state*/,
|
||||||
|
UniqueChangeRequestVec& changes) {
|
||||||
|
if (enableDefaultRender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_lock<std::mutex> guard(mutex);
|
||||||
|
|
||||||
|
if (!renderTiles || renderTiles->empty()) {
|
||||||
|
if (tileLayerGroup) {
|
||||||
|
stats.tileDrawablesRemoved += tileLayerGroup->getDrawableCount();
|
||||||
|
tileLayerGroup->clearDrawables();
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up a layer group
|
||||||
|
if (!tileLayerGroup) {
|
||||||
|
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
|
||||||
|
if (!tileLayerGroup) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
tileLayerGroup->setLayerTweaker(std::make_shared<CircleLayerTweaker>(evaluatedProperties));
|
||||||
|
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!circleShader) {
|
||||||
|
circleShader = context.getGenericShader(shaders, "CircleShader");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unordered_set<OverscaledTileID> newTileIDs(renderTiles->size());
|
||||||
|
std::transform(renderTiles->begin(),
|
||||||
|
renderTiles->end(),
|
||||||
|
std::inserter(newTileIDs, newTileIDs.begin()),
|
||||||
|
[](const auto& renderTile) -> OverscaledTileID { return renderTile.get().getOverscaledTileID(); });
|
||||||
|
|
||||||
|
std::unique_ptr<gfx::DrawableBuilder> circleBuilder;
|
||||||
|
std::vector<gfx::DrawablePtr> newTiles;
|
||||||
|
gfx::VertexAttributeArray circleVertexAttrs;
|
||||||
|
auto renderPass = RenderPass::Translucent;
|
||||||
|
|
||||||
|
if (!(mbgl::underlying_type(renderPass) & evaluatedProperties->renderPasses)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||||
|
const auto tileID = drawable->getTileID();
|
||||||
|
if (tileID && newTileIDs.find(*tileID) == newTileIDs.end()) {
|
||||||
|
// remove it
|
||||||
|
drawable.reset();
|
||||||
|
++stats.tileDrawablesRemoved;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const RenderTile& tile : *renderTiles) {
|
||||||
|
const auto& tileID = tile.getOverscaledTileID();
|
||||||
|
|
||||||
|
auto& tileDrawable = tileLayerGroup->getDrawable(renderPass, tileID);
|
||||||
|
if (tileDrawable) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const LayerRenderData* renderData = getRenderDataForPass(tile, renderPass);
|
||||||
|
if (!renderData) {
|
||||||
|
removeTile(renderPass, tileID);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& bucket = static_cast<CircleBucket&>(*renderData->bucket);
|
||||||
|
|
||||||
|
std::vector<std::array<int16_t, 2>> rawVerts;
|
||||||
|
const auto buildVertices = [&]() {
|
||||||
|
const std::vector<gfx::VertexVector<gfx::detail::VertexType<gfx::AttributeType<int16_t, 2>>>::Vertex>&
|
||||||
|
verts = bucket.vertices.vector();
|
||||||
|
if (rawVerts.size() < verts.size()) {
|
||||||
|
rawVerts.resize(verts.size());
|
||||||
|
std::transform(verts.begin(), verts.end(), rawVerts.begin(), [](const auto& x) { return x.a1; });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
circleVertexAttrs.clear();
|
||||||
|
|
||||||
|
const auto& paintPropertyBinders = bucket.paintPropertyBinders.at(getID());
|
||||||
|
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleColor>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_color")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& packedColor = static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 2>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float4>(
|
||||||
|
i, {packedColor[0], packedColor[1], packedColor[0], packedColor[1]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleRadius>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_radius")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& radius = static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 1>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float2>(i, {radius[0], radius[0]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleBlur>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_blur")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& blur = static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 1>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float2>(i, {blur[0], blur[0]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleOpacity>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_opacity")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& opacity = static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 1>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float2>(i, {opacity[0], opacity[0]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleStrokeColor>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_stroke_color")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& packedStrokeColor =
|
||||||
|
static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 2>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float4>(
|
||||||
|
i, {packedStrokeColor[0], packedStrokeColor[1], packedStrokeColor[0], packedStrokeColor[1]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleStrokeWidth>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_stroke_width")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& strokeWidth = static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 1>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float2>(i, {strokeWidth[0], strokeWidth[0]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (auto& binder = paintPropertyBinders.get<CircleStrokeOpacity>()) {
|
||||||
|
const auto count = binder->getVertexCount();
|
||||||
|
if (auto& attr = circleVertexAttrs.getOrAdd("a_stroke_opacity")) {
|
||||||
|
for (std::size_t i = 0; i < count; ++i) {
|
||||||
|
const auto& strokeOpacity =
|
||||||
|
static_cast<const gfx::detail::VertexType<gfx::AttributeType<float, 1>>*>(
|
||||||
|
binder->getVertexValue(i))
|
||||||
|
->a1;
|
||||||
|
attr->set<gfx::VertexAttribute::float2>(i, {strokeOpacity[0], strokeOpacity[0]});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
circleBuilder = context.createDrawableBuilder("circle");
|
||||||
|
circleBuilder->setShader(circleShader);
|
||||||
|
circleBuilder->setColorAttrMode(gfx::DrawableBuilder::ColorAttrMode::None);
|
||||||
|
circleBuilder->setDepthType((renderPass == RenderPass::Opaque) ? gfx::DepthMaskType::ReadWrite
|
||||||
|
: gfx::DepthMaskType::ReadOnly);
|
||||||
|
circleBuilder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||||
|
circleBuilder->setLayerIndex(layerIndex);
|
||||||
|
|
||||||
|
circleBuilder->setRenderPass(renderPass);
|
||||||
|
circleBuilder->setVertexAttributes(circleVertexAttrs);
|
||||||
|
|
||||||
|
buildVertices();
|
||||||
|
circleBuilder->addVertices(rawVerts, 0, rawVerts.size());
|
||||||
|
|
||||||
|
for (const auto& seg : bucket.segments) {
|
||||||
|
circleBuilder->addTriangles(bucket.triangles.vector(), seg.indexOffset, seg.indexLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
circleBuilder->flush();
|
||||||
|
|
||||||
|
for (auto& drawable : circleBuilder->clearDrawables()) {
|
||||||
|
drawable->setTileID(tileID);
|
||||||
|
|
||||||
|
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||||
|
++stats.tileDrawablesAdded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -13,6 +13,15 @@ public:
|
|||||||
explicit RenderCircleLayer(Immutable<style::CircleLayer::Impl>);
|
explicit RenderCircleLayer(Immutable<style::CircleLayer::Impl>);
|
||||||
~RenderCircleLayer() final = default;
|
~RenderCircleLayer() final = default;
|
||||||
|
|
||||||
|
void layerRemoved(UniqueChangeRequestVec&) override;
|
||||||
|
|
||||||
|
/// Generate any changes needed by the layer
|
||||||
|
void update(int32_t layerIndex,
|
||||||
|
gfx::ShaderRegistry&,
|
||||||
|
gfx::Context&,
|
||||||
|
const TransformState&,
|
||||||
|
UniqueChangeRequestVec&) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void transition(const TransitionParameters&) override;
|
void transition(const TransitionParameters&) override;
|
||||||
void evaluate(const PropertyEvaluationParameters&) override;
|
void evaluate(const PropertyEvaluationParameters&) override;
|
||||||
@@ -28,11 +37,16 @@ private:
|
|||||||
const mat4&,
|
const mat4&,
|
||||||
const FeatureState&) const override;
|
const FeatureState&) const override;
|
||||||
|
|
||||||
|
/// Remove all drawables for the tile from the layer group
|
||||||
|
void removeTile(RenderPass, const OverscaledTileID&);
|
||||||
|
|
||||||
// Paint properties
|
// Paint properties
|
||||||
style::CirclePaintProperties::Unevaluated unevaluated;
|
style::CirclePaintProperties::Unevaluated unevaluated;
|
||||||
|
|
||||||
// Programs
|
// Programs
|
||||||
std::shared_ptr<CircleProgram> circleProgram;
|
std::shared_ptr<CircleProgram> circleProgram;
|
||||||
|
|
||||||
|
gfx::ShaderProgramBasePtr circleShader;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mbgl
|
} // namespace mbgl
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <mbgl/renderer/buckets/fill_bucket.hpp>
|
#include <mbgl/renderer/buckets/fill_bucket.hpp>
|
||||||
#include <mbgl/renderer/image_manager.hpp>
|
#include <mbgl/renderer/image_manager.hpp>
|
||||||
#include <mbgl/renderer/layer_group.hpp>
|
#include <mbgl/renderer/layer_group.hpp>
|
||||||
|
#include <mbgl/renderer/layers/fill_layer_tweaker.hpp>
|
||||||
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
#include <mbgl/renderer/layers/render_fill_layer.hpp>
|
||||||
#include <mbgl/renderer/paint_parameters.hpp>
|
#include <mbgl/renderer/paint_parameters.hpp>
|
||||||
#include <mbgl/renderer/render_source.hpp>
|
#include <mbgl/renderer/render_source.hpp>
|
||||||
@@ -64,8 +65,9 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
|||||||
}
|
}
|
||||||
properties->renderPasses = mbgl::underlying_type(passes);
|
properties->renderPasses = mbgl::underlying_type(passes);
|
||||||
evaluatedProperties = std::move(properties);
|
evaluatedProperties = std::move(properties);
|
||||||
|
if (tileLayerGroup) {
|
||||||
evaluatedPropertiesChange = true;
|
tileLayerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(evaluatedProperties));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RenderFillLayer::hasTransition() const {
|
bool RenderFillLayer::hasTransition() const {
|
||||||
@@ -287,6 +289,10 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
|||||||
gfx::Context& context,
|
gfx::Context& context,
|
||||||
const TransformState& /*state*/,
|
const TransformState& /*state*/,
|
||||||
UniqueChangeRequestVec& changes) {
|
UniqueChangeRequestVec& changes) {
|
||||||
|
if (enableDefaultRender) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::unique_lock<std::mutex> guard(mutex);
|
std::unique_lock<std::mutex> guard(mutex);
|
||||||
|
|
||||||
if (!renderTiles || renderTiles->empty()) {
|
if (!renderTiles || renderTiles->empty()) {
|
||||||
@@ -303,6 +309,7 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
|||||||
if (!tileLayerGroup) {
|
if (!tileLayerGroup) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tileLayerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(evaluatedProperties));
|
||||||
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,16 +449,7 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evaluatedPropertiesChange) {
|
|
||||||
// FillLayerUBO fillLayerUBO;
|
|
||||||
// fillLayerUBO.color = evaluated.get<FillColor>();
|
|
||||||
// fillLayerUBO.opacity = evaluated.get<FillOpacity>();
|
|
||||||
// uniformBuffer = context.createUniformBuffer(&fillLayerUBO, sizeof(fillLayerUBO));
|
|
||||||
evaluatedPropertiesChange = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tileDrawable) {
|
if (tileDrawable) {
|
||||||
// tileDrawable->mutableUniformBuffers().addOrReplace("FillLayerUBO", uniformBuffer);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -169,8 +169,6 @@ protected:
|
|||||||
TileLayerGroupPtr tileLayerGroup;
|
TileLayerGroupPtr tileLayerGroup;
|
||||||
|
|
||||||
std::mutex mutex;
|
std::mutex mutex;
|
||||||
bool evaluatedPropertiesChange = false;
|
|
||||||
gfx::UniformBufferPtr uniformBuffer = nullptr;
|
|
||||||
|
|
||||||
struct Stats {
|
struct Stats {
|
||||||
size_t propertyEvaluations = 0;
|
size_t propertyEvaluations = 0;
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <mbgl/gfx/upload_pass.hpp>
|
#include <mbgl/gfx/upload_pass.hpp>
|
||||||
#include <mbgl/gl/drawable_gl.hpp>
|
#include <mbgl/gl/drawable_gl.hpp>
|
||||||
#include <mbgl/programs/programs.hpp>
|
#include <mbgl/programs/programs.hpp>
|
||||||
|
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||||
#include <mbgl/renderer/pattern_atlas.hpp>
|
#include <mbgl/renderer/pattern_atlas.hpp>
|
||||||
#include <mbgl/renderer/renderer_observer.hpp>
|
#include <mbgl/renderer/renderer_observer.hpp>
|
||||||
#include <mbgl/renderer/render_static_data.hpp>
|
#include <mbgl/renderer/render_static_data.hpp>
|
||||||
@@ -106,6 +107,13 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Run layer tweakers to update any dynamic elements
|
||||||
|
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) {
|
||||||
|
if (layerGroup.getLayerTweaker()) {
|
||||||
|
layerGroup.getLayerTweaker()->execute(layerGroup, parameters);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Give the layers a chance to do setup
|
// Give the layers a chance to do setup
|
||||||
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters); });
|
orchestrator.observeLayerGroups([&](LayerGroup& layerGroup) { layerGroup.preRender(orchestrator, parameters); });
|
||||||
|
|
||||||
@@ -200,9 +208,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
|||||||
for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) {
|
for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) {
|
||||||
parameters.currentLayer = i;
|
parameters.currentLayer = i;
|
||||||
const RenderItem& renderItem = it->get();
|
const RenderItem& renderItem = it->get();
|
||||||
if (renderItem.getName() == "background") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (renderItem.hasRenderPass(parameters.pass)) {
|
if (renderItem.hasRenderPass(parameters.pass)) {
|
||||||
const auto layerDebugGroup(parameters.renderPass->createDebugGroup(renderItem.getName().c_str()));
|
const auto layerDebugGroup(parameters.renderPass->createDebugGroup(renderItem.getName().c_str()));
|
||||||
renderItem.render(parameters);
|
renderItem.render(parameters);
|
||||||
|
|||||||
Reference in New Issue
Block a user