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/renderer/query.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_frontend.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_observer.hpp
|
||||
${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.hpp
|
||||
${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/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_outline.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp
|
||||
|
||||
@@ -25,7 +25,6 @@ enum class DepthMaskType : bool;
|
||||
class DrawableTweaker;
|
||||
class ShaderProgramBase;
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
using DrawPriority = int64_t;
|
||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||
|
||||
@@ -178,12 +177,5 @@ private:
|
||||
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 mbgl
|
||||
|
||||
@@ -25,6 +25,9 @@ using DrawablePtr = std::shared_ptr<Drawable>;
|
||||
using UniqueDrawable = std::unique_ptr<Drawable>;
|
||||
} // namespace gfx
|
||||
|
||||
class LayerTweaker;
|
||||
using LayerTweakerPtr = std::shared_ptr<LayerTweaker>;
|
||||
|
||||
/**
|
||||
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.
|
||||
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:
|
||||
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> {
|
||||
static constexpr const char* name = "BackgroundShader";
|
||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||
layout (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform BackgroundDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
vec2 pad;
|
||||
};
|
||||
|
||||
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* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||
|
||||
layout (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform FillDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
vec2 pad;
|
||||
|
||||
@@ -12,7 +12,7 @@ struct ShaderSource<BuiltIn::FillOutlineShader, gfx::Backend::Type::OpenGL> {
|
||||
static constexpr const char* name = "FillOutlineShader";
|
||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||
|
||||
layout (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform FillDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
vec2 pad;
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#ifdef MBGL_RENDER_BACKEND_OPENGL
|
||||
#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_outline.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_fill_pattern.hpp>
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace shaders {
|
||||
enum class BuiltIn {
|
||||
None,
|
||||
BackgroundShader,
|
||||
CircleShader,
|
||||
FillShader,
|
||||
FillOutlineShader,
|
||||
FillPatternShader,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
layout (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform BackgroundDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
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 (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform FillDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
vec2 pad;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
|
||||
layout (std140) uniform DrawableUBO {
|
||||
layout (std140) uniform FillDrawableUBO {
|
||||
mat4 u_matrix;
|
||||
vec2 u_world;
|
||||
vec2 pad;
|
||||
|
||||
@@ -6,6 +6,13 @@
|
||||
"glsl_frag": "drawable.background.fragment.glsl",
|
||||
"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",
|
||||
"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 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);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -94,6 +94,7 @@ void registerTypes(gfx::ShaderRegistry& registry, gl::Context& glContext, const
|
||||
|
||||
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramParameters& programParameters) {
|
||||
registerTypes<shaders::BuiltIn::BackgroundShader,
|
||||
shaders::BuiltIn::CircleShader,
|
||||
shaders::BuiltIn::FillShader,
|
||||
shaders::BuiltIn::FillOutlineShader,
|
||||
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/background_layer_tweaker.hpp>
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/shader_registry.hpp>
|
||||
@@ -62,7 +62,9 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
|
||||
evaluatedProperties = std::move(properties);
|
||||
evaluatedPropertiesChange = true;
|
||||
if (tileLayerGroup) {
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderBackgroundLayer::hasTransition() const {
|
||||
@@ -73,10 +75,16 @@ bool RenderBackgroundLayer::hasCrossfade() const {
|
||||
return getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
||||
}
|
||||
|
||||
static bool enableDefaultRender = false;
|
||||
|
||||
void RenderBackgroundLayer::render(PaintParameters& parameters) {
|
||||
// Note that for bottommost layers without a pattern, the background color
|
||||
// is drawn with glClear rather than this method.
|
||||
|
||||
if (!enableDefaultRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure programs are available
|
||||
if (!parameters.shaders.populate(backgroundProgram)) return;
|
||||
if (!parameters.shaders.populate(backgroundPatternProgram)) return;
|
||||
@@ -210,6 +218,10 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
gfx::Context& context,
|
||||
const TransformState& state,
|
||||
UniqueChangeRequestVec& changes) {
|
||||
if (enableDefaultRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> guard(mutex);
|
||||
|
||||
if (!shader) {
|
||||
@@ -253,19 +265,12 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
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) {
|
||||
tileLayerGroup = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64);
|
||||
if (!tileLayerGroup) {
|
||||
return;
|
||||
}
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<BackgroundLayerTweaker>(evaluatedProperties));
|
||||
changes.emplace_back(std::make_unique<AddLayerGroupRequest>(tileLayerGroup, /*canReplace=*/true));
|
||||
}
|
||||
|
||||
@@ -306,7 +311,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
|
||||
if (tileDrawable) {
|
||||
// Already created, update it.
|
||||
tileDrawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -332,7 +336,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
if (!newDrawables.empty()) {
|
||||
auto& drawable = newDrawables[0];
|
||||
drawable->setTileID(tileID);
|
||||
drawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
|
||||
tileLayerGroup->addDrawable(renderPass, tileID, std::move(drawable));
|
||||
++stats.tileDrawablesAdded;
|
||||
}
|
||||
|
||||
@@ -52,29 +52,4 @@ private:
|
||||
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
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#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/layer_group.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
@@ -7,6 +9,7 @@
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/style/layers/circle_layer_impl.hpp>
|
||||
#include <mbgl/geometry/feature_index.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/gfx/cull_face_mode.hpp>
|
||||
#include <mbgl/gfx/shader_registry.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
@@ -69,6 +72,9 @@ void RenderCircleLayer::evaluate(const PropertyEvaluationParameters& parameters)
|
||||
: RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
if (tileLayerGroup) {
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<CircleLayerTweaker>(evaluatedProperties));
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderCircleLayer::hasTransition() const {
|
||||
@@ -79,8 +85,15 @@ bool RenderCircleLayer::hasCrossfade() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool enableDefaultRender = false;
|
||||
|
||||
void RenderCircleLayer::render(PaintParameters& parameters) {
|
||||
assert(renderTiles);
|
||||
|
||||
if (!enableDefaultRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (parameters.pass == RenderPass::Opaque) {
|
||||
return;
|
||||
}
|
||||
@@ -236,4 +249,214 @@ bool RenderCircleLayer::queryIntersectsFeature(const GeometryCoordinates& queryG
|
||||
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
|
||||
|
||||
@@ -13,6 +13,15 @@ public:
|
||||
explicit RenderCircleLayer(Immutable<style::CircleLayer::Impl>);
|
||||
~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:
|
||||
void transition(const TransitionParameters&) override;
|
||||
void evaluate(const PropertyEvaluationParameters&) override;
|
||||
@@ -28,11 +37,16 @@ private:
|
||||
const mat4&,
|
||||
const FeatureState&) const override;
|
||||
|
||||
/// Remove all drawables for the tile from the layer group
|
||||
void removeTile(RenderPass, const OverscaledTileID&);
|
||||
|
||||
// Paint properties
|
||||
style::CirclePaintProperties::Unevaluated unevaluated;
|
||||
|
||||
// Programs
|
||||
std::shared_ptr<CircleProgram> circleProgram;
|
||||
|
||||
gfx::ShaderProgramBasePtr circleShader;
|
||||
};
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <mbgl/renderer/buckets/fill_bucket.hpp>
|
||||
#include <mbgl/renderer/image_manager.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/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
@@ -64,8 +65,9 @@ void RenderFillLayer::evaluate(const PropertyEvaluationParameters& parameters) {
|
||||
}
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
evaluatedPropertiesChange = true;
|
||||
if (tileLayerGroup) {
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(evaluatedProperties));
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderFillLayer::hasTransition() const {
|
||||
@@ -287,6 +289,10 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
||||
gfx::Context& context,
|
||||
const TransformState& /*state*/,
|
||||
UniqueChangeRequestVec& changes) {
|
||||
if (enableDefaultRender) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> guard(mutex);
|
||||
|
||||
if (!renderTiles || renderTiles->empty()) {
|
||||
@@ -303,6 +309,7 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
||||
if (!tileLayerGroup) {
|
||||
return;
|
||||
}
|
||||
tileLayerGroup->setLayerTweaker(std::make_shared<FillLayerTweaker>(evaluatedProperties));
|
||||
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) {
|
||||
// tileDrawable->mutableUniformBuffers().addOrReplace("FillLayerUBO", uniformBuffer);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -169,8 +169,6 @@ protected:
|
||||
TileLayerGroupPtr tileLayerGroup;
|
||||
|
||||
std::mutex mutex;
|
||||
bool evaluatedPropertiesChange = false;
|
||||
gfx::UniformBufferPtr uniformBuffer = nullptr;
|
||||
|
||||
struct Stats {
|
||||
size_t propertyEvaluations = 0;
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <mbgl/gfx/upload_pass.hpp>
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||
#include <mbgl/renderer/pattern_atlas.hpp>
|
||||
#include <mbgl/renderer/renderer_observer.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
|
||||
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) {
|
||||
parameters.currentLayer = i;
|
||||
const RenderItem& renderItem = it->get();
|
||||
if (renderItem.getName() == "background") {
|
||||
continue;
|
||||
}
|
||||
if (renderItem.hasRenderPass(parameters.pass)) {
|
||||
const auto layerDebugGroup(parameters.renderPass->createDebugGroup(renderItem.getName().c_str()));
|
||||
renderItem.render(parameters);
|
||||
|
||||
Reference in New Issue
Block a user