Topic/drawable extrusion (#1288)
Co-authored-by: Alex Cristici <alex.cristici@gmail.com>
This commit is contained in:
committed by
Bart Louwers
parent
813ddb024a
commit
8d9fe37a6b
@@ -141,6 +141,7 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/drawable_atlases_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_block.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/uniform_buffer.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gfx/vertex_attribute.hpp
|
||||
@@ -153,12 +154,10 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/mtl/shader_program_mtl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/util/identity.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/util/suppress_copies.hpp
|
||||
|
||||
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/shader_program_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_builder.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/drawable_gl_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/layer_group_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/render_target_gl.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/gl/uniform_block_gl.hpp
|
||||
@@ -170,7 +169,7 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_builder_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/drawable_atlases_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/image_drawable_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/line_drawable_data.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gfx/shader_group.cpp
|
||||
@@ -188,6 +187,8 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${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/fill_extrusion_layer_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/raster_layer_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/raster_layer_tweaker.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/renderer/layers/symbol_layer_tweaker.cpp
|
||||
@@ -200,7 +201,6 @@ if(MLN_DRAWABLE_RENDERER)
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_builder.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_impl.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/drawable_gl_tweaker.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/layer_group_gl.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/texture2d.cpp
|
||||
${PROJECT_SOURCE_DIR}/src/mbgl/gl/uniform_block_gl.cpp
|
||||
@@ -1014,6 +1014,8 @@ if(MLN_WITH_OPENGL)
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_line_sdf.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_extrusion.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_fill_extrusion_pattern.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_heatmap.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_heatmap_texture.hpp
|
||||
${PROJECT_SOURCE_DIR}/include/mbgl/shaders/gl/drawable_raster.hpp
|
||||
|
||||
@@ -844,6 +844,8 @@ MLN_OPENGL_HEADERS = [
|
||||
"include/mbgl/shaders/gl/drawable_fill.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_fill_outline.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_fill_outline_pattern.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_fill_extrusion.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_fill_extrusion_pattern.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_fill_pattern.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_line_gradient.hpp",
|
||||
"include/mbgl/shaders/gl/drawable_line_pattern.hpp",
|
||||
@@ -883,7 +885,7 @@ MLN_DRAWABLES_SOURCE = [
|
||||
"src/mbgl/gfx/drawable.cpp",
|
||||
"src/mbgl/gfx/drawable_builder.cpp",
|
||||
"src/mbgl/gfx/drawable_builder_impl.hpp",
|
||||
"src/mbgl/gfx/drawable_tweaker.cpp",
|
||||
"src/mbgl/gfx/drawable_atlases_tweaker.cpp",
|
||||
"src/mbgl/gfx/image_drawable_data.hpp",
|
||||
"src/mbgl/gfx/line_drawable_data.hpp",
|
||||
"src/mbgl/gfx/symbol_drawable_data.hpp",
|
||||
@@ -901,6 +903,8 @@ MLN_DRAWABLES_SOURCE = [
|
||||
"src/mbgl/renderer/layers/circle_layer_tweaker.hpp",
|
||||
"src/mbgl/renderer/layers/fill_layer_tweaker.cpp",
|
||||
"src/mbgl/renderer/layers/fill_layer_tweaker.hpp",
|
||||
"src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.cpp",
|
||||
"src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp",
|
||||
"src/mbgl/renderer/layers/heatmap_layer_tweaker.cpp",
|
||||
"src/mbgl/renderer/layers/heatmap_layer_tweaker.hpp",
|
||||
"src/mbgl/renderer/layers/heatmap_texture_layer_tweaker.cpp",
|
||||
@@ -918,7 +922,6 @@ MLN_DRAWABLES_SOURCE = [
|
||||
"src/mbgl/gl/drawable_gl.cpp",
|
||||
"src/mbgl/gl/drawable_gl_builder.cpp",
|
||||
"src/mbgl/gl/drawable_gl_impl.hpp",
|
||||
"src/mbgl/gl/drawable_gl_tweaker.cpp",
|
||||
"src/mbgl/gl/layer_group_gl.cpp",
|
||||
"src/mbgl/gl/render_target_gl.cpp",
|
||||
"src/mbgl/gl/texture2d.cpp",
|
||||
@@ -933,6 +936,7 @@ MLN_DRAWABLES_HEADERS = [
|
||||
"include/mbgl/gfx/drawable_impl.hpp",
|
||||
"include/mbgl/gfx/drawable_builder.hpp",
|
||||
"include/mbgl/gfx/drawable_tweaker.hpp",
|
||||
"include/mbgl/gfx/drawable_atlases_tweaker.hpp",
|
||||
"include/mbgl/gfx/uniform_block.hpp",
|
||||
"include/mbgl/gfx/uniform_buffer.hpp",
|
||||
"include/mbgl/gfx/vertex_attribute.hpp",
|
||||
@@ -948,7 +952,6 @@ MLN_DRAWABLES_HEADERS = [
|
||||
"include/mbgl/shaders/gl/shader_program_gl.hpp",
|
||||
"include/mbgl/gl/drawable_gl.hpp",
|
||||
"include/mbgl/gl/drawable_gl_builder.hpp",
|
||||
"include/mbgl/gl/drawable_gl_tweaker.hpp",
|
||||
"include/mbgl/gl/layer_group_gl.hpp",
|
||||
"include/mbgl/gl/render_target_gl.hpp",
|
||||
"include/mbgl/gl/uniform_block_gl.hpp",
|
||||
|
||||
@@ -50,7 +50,7 @@ public:
|
||||
const util::SimpleIdentity& getId() const { return uniqueID; }
|
||||
|
||||
/// Draw the drawable
|
||||
virtual void draw(const PaintParameters&) const = 0;
|
||||
virtual void draw(PaintParameters&) const = 0;
|
||||
|
||||
/// Drawable name is used for debugging and troubleshooting
|
||||
const std::string& getName() const { return name; }
|
||||
@@ -101,37 +101,38 @@ public:
|
||||
/// @param location A sampler location in the shader being used with this drawable.
|
||||
void setTexture(gfx::Texture2DPtr texture, int32_t location);
|
||||
|
||||
using TexSourceFunc = std::function<Textures()>;
|
||||
|
||||
/// @brief Provide a function to get the current textures
|
||||
void setTextureSource(TexSourceFunc value) { textureSource = std::move(value); }
|
||||
const TexSourceFunc& getTextureSource() const { return textureSource; }
|
||||
|
||||
/// @brief Provide all texture sources at once
|
||||
void setTextureSources(std::vector<TexSourceFunc>);
|
||||
|
||||
/// Whether the drawble should be drawn
|
||||
bool getEnabled() const { return enabled; }
|
||||
void setEnabled(bool value) { enabled = value; }
|
||||
|
||||
/// Whether to do stenciling (based on the Tile ID)
|
||||
bool getNeedsStencil() const { return needsStencil; }
|
||||
void setNeedsStencil(bool value) { needsStencil = value; }
|
||||
/// Whether to render to the color target
|
||||
bool getEnableColor() const { return enableColor; }
|
||||
void setEnableColor(bool value) { enableColor = value; }
|
||||
|
||||
/// Whether to do stenciling (based on the Tile ID or 3D)
|
||||
bool getEnableStencil() const { return enableStencil; }
|
||||
void setEnableStencil(bool value) { enableStencil = value; }
|
||||
|
||||
/// not used for anything yet
|
||||
DrawPriority getDrawPriority() const { return drawPriority; }
|
||||
void setDrawPriority(DrawPriority value) { drawPriority = value; }
|
||||
|
||||
/// Determines depth range within the layer
|
||||
/// Determines depth range within the layer for 2D drawables
|
||||
int32_t getSubLayerIndex() const { return subLayerIndex; }
|
||||
void setSubLayerIndex(int32_t value) { subLayerIndex = value; }
|
||||
|
||||
const std::optional<OverscaledTileID>& getTileID() const { return tileID; }
|
||||
void setTileID(const OverscaledTileID& value) { tileID = value; }
|
||||
|
||||
/// Depth writability for 2D drawables
|
||||
DepthMaskType getDepthType() const { return depthType; }
|
||||
void setDepthType(DepthMaskType value) { depthType = value; }
|
||||
|
||||
/// Uses 3D depth mode
|
||||
bool getIs3D() const { return is3D; }
|
||||
void setIs3D(bool value) { is3D = value; }
|
||||
|
||||
/// The ID of the tile that this drawable represents, if any
|
||||
const std::optional<OverscaledTileID>& getTileID() const { return tileID; }
|
||||
void setTileID(const OverscaledTileID& value) { tileID = value; }
|
||||
|
||||
const gfx::CullFaceMode& getCullFaceMode() const;
|
||||
void setCullFaceMode(const gfx::CullFaceMode&);
|
||||
|
||||
@@ -148,6 +149,9 @@ public:
|
||||
|
||||
/// Get the tweakers attached to this drawable
|
||||
const std::vector<DrawableTweakerPtr>& getTweakers() const { return tweakers; }
|
||||
void addTweaker(DrawableTweakerPtr value) { tweakers.emplace_back(std::move(value)); }
|
||||
void setTweakers(std::vector<DrawableTweakerPtr> value) { tweakers = std::move(value); }
|
||||
void clearTweakers() { tweakers.clear(); }
|
||||
|
||||
/// Get the uniform buffers attached to this drawable
|
||||
virtual const gfx::UniformBufferArray& getUniformBuffers() const = 0;
|
||||
@@ -168,7 +172,9 @@ public:
|
||||
|
||||
protected:
|
||||
bool enabled = true;
|
||||
bool needsStencil = false;
|
||||
bool enableColor = true;
|
||||
bool enableStencil = false;
|
||||
bool is3D = false;
|
||||
std::string name;
|
||||
util::SimpleIdentity uniqueID;
|
||||
gfx::ShaderProgramBasePtr shader;
|
||||
@@ -184,7 +190,6 @@ protected:
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
Textures textures;
|
||||
TexSourceFunc textureSource;
|
||||
std::vector<DrawableTweakerPtr> tweakers;
|
||||
};
|
||||
|
||||
|
||||
39
include/mbgl/gfx/drawable_atlases_tweaker.hpp
Normal file
39
include/mbgl/gfx/drawable_atlases_tweaker.hpp
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/drawable_tweaker.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
class TileAtlasTextures;
|
||||
using TileAtlasTexturesPtr = std::shared_ptr<TileAtlasTextures>;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
class Drawable;
|
||||
|
||||
/**
|
||||
Tweaker that applies the latest values from a retained `TileAtlasTexturesPtr`
|
||||
*/
|
||||
class DrawableAtlasesTweaker : public gfx::DrawableTweaker {
|
||||
public:
|
||||
DrawableAtlasesTweaker(TileAtlasTexturesPtr atlases_, std::string iconName_, std::string glyphName_, bool isText_)
|
||||
: atlases(std::move(atlases_)),
|
||||
iconName(std::move(iconName_)),
|
||||
glyphName(std::move(glyphName_)),
|
||||
isText(isText_) {}
|
||||
~DrawableAtlasesTweaker() override = default;
|
||||
|
||||
void execute(Drawable&, const PaintParameters&) override;
|
||||
|
||||
protected:
|
||||
TileAtlasTexturesPtr atlases;
|
||||
std::string iconName;
|
||||
std::string glyphName;
|
||||
bool isText;
|
||||
};
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -50,6 +50,10 @@ public:
|
||||
/// Get the ID of the drawable we're currently working on, if any
|
||||
util::SimpleIdentity getDrawableId();
|
||||
|
||||
/// Whether the drawble should be drawn
|
||||
bool getEnabled() const { return enabled; }
|
||||
void setEnabled(bool value) { enabled = value; }
|
||||
|
||||
/// The pass on which we'll be rendered
|
||||
mbgl::RenderPass getRenderPass() const { return renderPass; }
|
||||
void setRenderPass(mbgl::RenderPass value) { renderPass = value; }
|
||||
@@ -58,10 +62,18 @@ public:
|
||||
DrawPriority getDrawPriority() const;
|
||||
void setDrawPriority(DrawPriority);
|
||||
|
||||
/// The layer index assigned to generated drawables
|
||||
/// Determines depth range within the layer for 2D drawables
|
||||
int32_t getSubLayerIndex() const { return subLayerIndex; }
|
||||
void setSubLayerIndex(int32_t value) { subLayerIndex = value; }
|
||||
|
||||
/// Depth writability for 2D drawables
|
||||
DepthMaskType getDepthType() const { return depthType; }
|
||||
void setDepthType(DepthMaskType value) { depthType = value; }
|
||||
|
||||
/// Uses 3D depth mode
|
||||
bool getIs3D() const { return is3D; }
|
||||
void setIs3D(bool value) { is3D = value; }
|
||||
|
||||
/// Set the draw priority on all drawables including those already generated
|
||||
void resetDrawPriority(DrawPriority);
|
||||
|
||||
@@ -69,12 +81,13 @@ public:
|
||||
float getLineWidth() const { return lineWidth; }
|
||||
void setLineWidth(float value) { lineWidth = value; }
|
||||
|
||||
/// Whether to do stenciling (based on the Tile ID)
|
||||
bool getNeedsStencil() const { return needsStencil; }
|
||||
void setNeedsStencil(bool value) { needsStencil = value; }
|
||||
/// Whether to render to the color target
|
||||
bool getEnableColor() const { return enableColor; }
|
||||
void setEnableColor(bool value) { enableColor = value; }
|
||||
|
||||
DepthMaskType getDepthType() const { return depthType; }
|
||||
void setDepthType(DepthMaskType value) { depthType = value; }
|
||||
/// Whether to do stenciling (based on the Tile ID or 3D)
|
||||
bool getEnableStencil() const { return enableStencil; }
|
||||
void setEnableStencil(bool value) { enableStencil = value; }
|
||||
|
||||
const gfx::ColorMode& getColorMode() const;
|
||||
void setColorMode(const gfx::ColorMode& value);
|
||||
@@ -100,8 +113,8 @@ public:
|
||||
/// @param location A sampler location in the shader being used.
|
||||
void setTexture(const gfx::Texture2DPtr&, int32_t location);
|
||||
|
||||
/// @brief Provide a function to get the current texture
|
||||
void setTextureSource(Drawable::TexSourceFunc value) { textureSource = std::move(value); }
|
||||
void addTweaker(DrawableTweakerPtr value) { tweakers.emplace_back(std::move(value)); }
|
||||
void clearTweakers() { tweakers.clear(); }
|
||||
|
||||
/// Add a triangle
|
||||
void addTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2);
|
||||
@@ -156,7 +169,10 @@ protected:
|
||||
std::string drawableName;
|
||||
std::string vertexAttrName;
|
||||
mbgl::RenderPass renderPass;
|
||||
bool needsStencil = false;
|
||||
bool enabled = true;
|
||||
bool enableColor = true;
|
||||
bool enableStencil = false;
|
||||
bool is3D = false;
|
||||
float lineWidth = 1.0f;
|
||||
DrawPriority drawPriority = 0;
|
||||
int32_t subLayerIndex = 0;
|
||||
@@ -166,7 +182,7 @@ protected:
|
||||
std::vector<UniqueDrawable> drawables;
|
||||
VertexAttributeArray vertexAttrs;
|
||||
gfx::Drawable::Textures textures;
|
||||
Drawable::TexSourceFunc textureSource;
|
||||
std::vector<DrawableTweakerPtr> tweakers;
|
||||
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl;
|
||||
|
||||
@@ -20,6 +20,7 @@ protected:
|
||||
public:
|
||||
virtual ~DrawableTweaker() = default;
|
||||
|
||||
/// Called just before rendering
|
||||
virtual void execute(Drawable&, const PaintParameters&) = 0;
|
||||
};
|
||||
|
||||
|
||||
@@ -255,6 +255,14 @@ public:
|
||||
return propertiesAsUniforms;
|
||||
}
|
||||
|
||||
virtual void copy(const VertexAttributeArray& other) {
|
||||
for (const auto& kv : other.attrs) {
|
||||
if (kv.second) {
|
||||
attrs.insert(std::make_pair(kv.first, copy(*kv.second)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
const std::unique_ptr<VertexAttribute>& add(std::string name, std::unique_ptr<VertexAttribute>&& attr) {
|
||||
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
|
||||
@@ -270,14 +278,6 @@ protected:
|
||||
return std::make_unique<VertexAttribute>(index, dataType, count, count);
|
||||
}
|
||||
|
||||
virtual void copy(const VertexAttributeArray& other) {
|
||||
for (const auto& kv : other.attrs) {
|
||||
if (kv.second) {
|
||||
attrs.insert(std::make_pair(kv.first, copy(*kv.second)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual std::unique_ptr<VertexAttribute> copy(const gfx::VertexAttribute& attr) const {
|
||||
return std::make_unique<VertexAttribute>(attr);
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
DrawableGL(std::string name);
|
||||
~DrawableGL() override;
|
||||
|
||||
void draw(const PaintParameters&) const override;
|
||||
void draw(PaintParameters&) const override;
|
||||
|
||||
struct DrawSegmentGL;
|
||||
void setIndexData(std::vector<std::uint16_t> indexes, std::vector<UniqueDrawSegment> segments);
|
||||
@@ -61,6 +61,9 @@ protected:
|
||||
DrawableGL(std::unique_ptr<Impl>);
|
||||
|
||||
private:
|
||||
gfx::ColorMode makeColorMode(PaintParameters&) const;
|
||||
gfx::StencilMode makeStencilMode(PaintParameters&) const;
|
||||
|
||||
void uploadTextures() const;
|
||||
|
||||
void bindUniformBuffers() const;
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/gfx/drawable_tweaker.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
namespace gfx {
|
||||
class Drawable;
|
||||
}
|
||||
|
||||
namespace gl {
|
||||
|
||||
/**
|
||||
OpenGL-specific drawable tweaker
|
||||
*/
|
||||
class DrawableGLTweaker : public gfx::DrawableTweaker {
|
||||
public:
|
||||
DrawableGLTweaker() = default;
|
||||
|
||||
public:
|
||||
~DrawableGLTweaker() override = default;
|
||||
|
||||
void execute(gfx::Drawable&, const PaintParameters&) override;
|
||||
};
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -36,11 +36,15 @@ public:
|
||||
virtual void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) = 0;
|
||||
|
||||
protected:
|
||||
/// Calculate matrices for this tile.
|
||||
/// @param nearClipped If true, the near plane is moved further to enhance depth buffer precision.
|
||||
/// @param inViewportPixelUnits If false, the translation is scaled based on the current zoom.
|
||||
static mat4 getTileMatrix(const UnwrappedTileID&,
|
||||
const RenderTree&,
|
||||
const TransformState&,
|
||||
const std::array<float, 2>& translation,
|
||||
style::TranslateAnchorType,
|
||||
bool nearClipped,
|
||||
bool inViewportPixelUnits);
|
||||
|
||||
protected:
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
|
||||
135
include/mbgl/shaders/gl/drawable_fill_extrusion.hpp
Normal file
135
include/mbgl/shaders/gl/drawable_fill_extrusion.hpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// Generated code, do not modify this file!
|
||||
#pragma once
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
template <>
|
||||
struct ShaderSource<BuiltIn::FillExtrusionShader, gfx::Backend::Type::OpenGL> {
|
||||
static constexpr const char* name = "FillExtrusionShader";
|
||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||
layout (location = 1) in vec4 a_normal_ed;
|
||||
out vec4 v_color;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
#ifndef HAS_UNIFORM_u_base
|
||||
layout (location = 2) in highp vec2 a_base;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_height
|
||||
layout (location = 3) in highp vec2 a_height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_color
|
||||
layout (location = 4) in highp vec4 a_color;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#ifndef HAS_UNIFORM_u_base
|
||||
highp float base = unpack_mix_vec2(a_base, u_base_t);
|
||||
#else
|
||||
highp float base = u_base;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_height
|
||||
highp float height = unpack_mix_vec2(a_height, u_height_t);
|
||||
#else
|
||||
highp float height = u_height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_color
|
||||
highp vec4 color = unpack_mix_color(a_color, u_color_t);
|
||||
#else
|
||||
highp vec4 color = u_color;
|
||||
#endif
|
||||
|
||||
vec3 normal = a_normal_ed.xyz;
|
||||
|
||||
base = max(0.0, base);
|
||||
height = max(0.0, height);
|
||||
|
||||
float t = mod(normal.x, 2.0);
|
||||
|
||||
gl_Position = u_matrix * vec4(a_pos, t > 0.0 ? height : base, 1);
|
||||
|
||||
// Relative luminance (how dark/bright is the surface color?)
|
||||
float colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
|
||||
|
||||
v_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// Add slight ambient lighting so no extrusions are totally black
|
||||
vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);
|
||||
color += ambientlight;
|
||||
|
||||
// Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray
|
||||
float directional = clamp(dot(normal / 16384.0, u_lightpos), 0.0, 1.0);
|
||||
|
||||
// Adjust directional so that
|
||||
// the range of values for highlight/shading is narrower
|
||||
// with lower light intensity
|
||||
// and with lighter/brighter surface colors
|
||||
directional = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), directional);
|
||||
|
||||
// Add gradient along z axis of side surfaces
|
||||
if (normal.y != 0.0) {
|
||||
// This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,
|
||||
// and otherwise calculates the gradient based on base + height
|
||||
directional *= (
|
||||
(1.0 - u_vertical_gradient) +
|
||||
(u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0)));
|
||||
}
|
||||
|
||||
// Assign final color based on surface + ambient light color, diffuse light directional, and light color
|
||||
// with lower bounds adjusted to hue of light
|
||||
// so that shading is tinted with the complementary (opposite) color to the light color
|
||||
v_color.r += clamp(color.r * directional * u_lightcolor.r, mix(0.0, 0.3, 1.0 - u_lightcolor.r), 1.0);
|
||||
v_color.g += clamp(color.g * directional * u_lightcolor.g, mix(0.0, 0.3, 1.0 - u_lightcolor.g), 1.0);
|
||||
v_color.b += clamp(color.b * directional * u_lightcolor.b, mix(0.0, 0.3, 1.0 - u_lightcolor.b), 1.0);
|
||||
v_color *= u_opacity;
|
||||
}
|
||||
)";
|
||||
static constexpr const char* fragment = R"(in vec4 v_color;
|
||||
|
||||
void main() {
|
||||
fragColor = v_color;
|
||||
|
||||
#ifdef OVERDRAW_INSPECTOR
|
||||
fragColor = vec4(1.0);
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
232
include/mbgl/shaders/gl/drawable_fill_extrusion_pattern.hpp
Normal file
232
include/mbgl/shaders/gl/drawable_fill_extrusion_pattern.hpp
Normal file
@@ -0,0 +1,232 @@
|
||||
// Generated code, do not modify this file!
|
||||
#pragma once
|
||||
#include <mbgl/shaders/shader_source.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace shaders {
|
||||
|
||||
template <>
|
||||
struct ShaderSource<BuiltIn::FillExtrusionPatternShader, gfx::Backend::Type::OpenGL> {
|
||||
static constexpr const char* name = "FillExtrusionPatternShader";
|
||||
static constexpr const char* vertex = R"(layout (location = 0) in vec2 a_pos;
|
||||
layout (location = 1) in vec4 a_normal_ed;
|
||||
|
||||
out vec2 v_pos_a;
|
||||
out vec2 v_pos_b;
|
||||
out vec4 v_lighting;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
#ifndef HAS_UNIFORM_u_base
|
||||
layout (location = 2) in lowp vec2 a_base;
|
||||
out lowp float base;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_height
|
||||
layout (location = 3) in lowp vec2 a_height;
|
||||
out lowp float height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
layout (location = 4) in mediump vec4 a_pattern_from;
|
||||
out mediump vec4 pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
layout (location = 5) in mediump vec4 a_pattern_to;
|
||||
out mediump vec4 pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#ifndef HAS_UNIFORM_u_base
|
||||
base = unpack_mix_vec2(a_base, u_base_t);
|
||||
#else
|
||||
lowp float base = u_base;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_height
|
||||
height = unpack_mix_vec2(a_height, u_height_t);
|
||||
#else
|
||||
lowp float height = u_height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
pattern_from = a_pattern_from;
|
||||
#else
|
||||
mediump vec4 pattern_from = u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
pattern_to = a_pattern_to;
|
||||
#else
|
||||
mediump vec4 pattern_to = u_pattern_to;
|
||||
#endif
|
||||
|
||||
vec2 pattern_tl_a = pattern_from.xy;
|
||||
vec2 pattern_br_a = pattern_from.zw;
|
||||
vec2 pattern_tl_b = pattern_to.xy;
|
||||
vec2 pattern_br_b = pattern_to.zw;
|
||||
|
||||
float pixelRatio = u_scale.x;
|
||||
float tileRatio = u_scale.y;
|
||||
float fromScale = u_scale.z;
|
||||
float toScale = u_scale.w;
|
||||
|
||||
vec3 normal = a_normal_ed.xyz;
|
||||
float edgedistance = a_normal_ed.w;
|
||||
|
||||
vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
|
||||
vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
|
||||
|
||||
base = max(0.0, base);
|
||||
height = max(0.0, height);
|
||||
|
||||
float t = mod(normal.x, 2.0);
|
||||
float z = t > 0.0 ? height : base;
|
||||
|
||||
gl_Position = u_matrix * vec4(a_pos, z, 1);
|
||||
|
||||
vec2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0
|
||||
? a_pos // extrusion top
|
||||
: vec2(edgedistance, z * u_height_factor); // extrusion side
|
||||
|
||||
v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, fromScale * display_size_a, tileRatio, pos);
|
||||
v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, toScale * display_size_b, tileRatio, pos);
|
||||
|
||||
v_lighting = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
float directional = clamp(dot(normal / 16383.0, u_lightpos), 0.0, 1.0);
|
||||
directional = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), directional);
|
||||
|
||||
if (normal.y != 0.0) {
|
||||
// This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,
|
||||
// and otherwise calculates the gradient based on base + height
|
||||
directional *= (
|
||||
(1.0 - u_vertical_gradient) +
|
||||
(u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0)));
|
||||
}
|
||||
|
||||
v_lighting.rgb += clamp(directional * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));
|
||||
v_lighting *= u_opacity;
|
||||
}
|
||||
)";
|
||||
static constexpr const char* fragment = R"(in vec2 v_pos_a;
|
||||
in vec2 v_pos_b;
|
||||
in vec4 v_lighting;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
uniform sampler2D u_image;
|
||||
|
||||
#ifndef HAS_UNIFORM_u_base
|
||||
in lowp float base;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_height
|
||||
in lowp float height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
in mediump vec4 pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
in mediump vec4 pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
#ifdef HAS_UNIFORM_u_base
|
||||
lowp float base = u_base;
|
||||
#endif
|
||||
#ifdef HAS_UNIFORM_u_height
|
||||
lowp float height = u_height;
|
||||
#endif
|
||||
#ifdef HAS_UNIFORM_u_pattern_from
|
||||
mediump vec4 pattern_from = u_pattern_from;
|
||||
#endif
|
||||
#ifdef HAS_UNIFORM_u_pattern_to
|
||||
mediump vec4 pattern_to = u_pattern_to;
|
||||
#endif
|
||||
|
||||
vec2 pattern_tl_a = pattern_from.xy;
|
||||
vec2 pattern_br_a = pattern_from.zw;
|
||||
vec2 pattern_tl_b = pattern_to.xy;
|
||||
vec2 pattern_br_b = pattern_to.zw;
|
||||
|
||||
vec2 imagecoord = mod(v_pos_a, 1.0);
|
||||
vec2 pos = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, imagecoord);
|
||||
vec4 color1 = texture(u_image, pos);
|
||||
|
||||
vec2 imagecoord_b = mod(v_pos_b, 1.0);
|
||||
vec2 pos2 = mix(pattern_tl_b / u_texsize, pattern_br_b / u_texsize, imagecoord_b);
|
||||
vec4 color2 = texture(u_image, pos2);
|
||||
|
||||
vec4 mixedColor = mix(color1, color2, u_fade);
|
||||
|
||||
fragColor = mixedColor * v_lighting;
|
||||
|
||||
#ifdef OVERDRAW_INSPECTOR
|
||||
fragColor = vec4(1.0);
|
||||
#endif
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
} // namespace shaders
|
||||
} // namespace mbgl
|
||||
@@ -31,7 +31,6 @@ layout (location = 3) in highp vec2 a_height;
|
||||
#else
|
||||
uniform highp float u_height;
|
||||
#endif
|
||||
|
||||
#ifndef HAS_UNIFORM_u_color
|
||||
uniform lowp float u_color_t;
|
||||
layout (location = 4) in highp vec4 a_color;
|
||||
|
||||
@@ -43,17 +43,17 @@ uniform lowp float u_height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
uniform lowp float u_pattern_from_t;
|
||||
layout (location = 4) in lowp vec4 a_pattern_from;
|
||||
out lowp vec4 pattern_from;
|
||||
layout (location = 4) in mediump vec4 a_pattern_from;
|
||||
out mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
uniform lowp float u_pattern_to_t;
|
||||
layout (location = 5) in lowp vec4 a_pattern_to;
|
||||
out lowp vec4 pattern_to;
|
||||
layout (location = 5) in mediump vec4 a_pattern_to;
|
||||
out mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
@@ -145,14 +145,14 @@ in lowp float height;
|
||||
uniform lowp float u_height;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
in lowp vec4 pattern_from;
|
||||
in mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
in lowp vec4 pattern_to;
|
||||
in mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -29,17 +29,17 @@ uniform lowp float u_opacity;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
uniform lowp float u_pattern_from_t;
|
||||
layout (location = 2) in lowp vec4 a_pattern_from;
|
||||
out lowp vec4 pattern_from;
|
||||
layout (location = 2) in mediump vec4 a_pattern_from;
|
||||
out mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
uniform lowp float u_pattern_to_t;
|
||||
layout (location = 3) in lowp vec4 a_pattern_to;
|
||||
out lowp vec4 pattern_to;
|
||||
layout (location = 3) in mediump vec4 a_pattern_to;
|
||||
out mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
@@ -95,14 +95,14 @@ in lowp float opacity;
|
||||
uniform lowp float u_opacity;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
in lowp vec4 pattern_from;
|
||||
in mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
in lowp vec4 pattern_to;
|
||||
in mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -27,17 +27,17 @@ uniform lowp float u_opacity;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
uniform lowp float u_pattern_from_t;
|
||||
layout (location = 2) in lowp vec4 a_pattern_from;
|
||||
out lowp vec4 pattern_from;
|
||||
layout (location = 2) in mediump vec4 a_pattern_from;
|
||||
out mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
uniform lowp float u_pattern_to_t;
|
||||
layout (location = 3) in lowp vec4 a_pattern_to;
|
||||
out lowp vec4 pattern_to;
|
||||
layout (location = 3) in mediump vec4 a_pattern_to;
|
||||
out mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
@@ -89,14 +89,14 @@ in lowp float opacity;
|
||||
uniform lowp float u_opacity;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
in lowp vec4 pattern_from;
|
||||
in mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
in lowp vec4 pattern_to;
|
||||
in mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -67,17 +67,17 @@ uniform mediump float u_width;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
uniform lowp float u_pattern_from_t;
|
||||
layout (location = 7) in lowp vec4 a_pattern_from;
|
||||
out lowp vec4 pattern_from;
|
||||
layout (location = 7) in mediump vec4 a_pattern_from;
|
||||
out mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
uniform lowp float u_pattern_to_t;
|
||||
layout (location = 8) in lowp vec4 a_pattern_to;
|
||||
out lowp vec4 pattern_to;
|
||||
layout (location = 8) in mediump vec4 a_pattern_to;
|
||||
out mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
@@ -180,14 +180,14 @@ in float v_linesofar;
|
||||
in float v_gamma_scale;
|
||||
|
||||
#ifndef HAS_UNIFORM_u_pattern_from
|
||||
in lowp vec4 pattern_from;
|
||||
in mediump vec4 pattern_from;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_from;
|
||||
uniform mediump vec4 u_pattern_from;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_pattern_to
|
||||
in lowp vec4 pattern_to;
|
||||
in mediump vec4 pattern_to;
|
||||
#else
|
||||
uniform lowp vec4 u_pattern_to;
|
||||
uniform mediump vec4 u_pattern_to;
|
||||
#endif
|
||||
#ifndef HAS_UNIFORM_u_blur
|
||||
in lowp float blur;
|
||||
@@ -207,7 +207,6 @@ mediump vec4 pattern_from = u_pattern_from;
|
||||
#ifdef HAS_UNIFORM_u_pattern_to
|
||||
mediump vec4 pattern_to = u_pattern_to;
|
||||
#endif
|
||||
|
||||
#ifdef HAS_UNIFORM_u_blur
|
||||
lowp float blur = u_blur;
|
||||
#endif
|
||||
|
||||
@@ -14,12 +14,14 @@
|
||||
#include <mbgl/shaders/gl/drawable_line.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_fill_pattern.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_fill_outline_pattern.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_fill_extrusion.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_fill_extrusion_pattern.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_heatmap.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_heatmap_texture.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_raster.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_symbol_icon.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_symbol_sdf_icon.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_symbol_sdf_text.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_symbol_sdf_icon.hpp>
|
||||
#include <mbgl/shaders/gl/drawable_symbol_text_and_icon.hpp>
|
||||
#include <mbgl/shaders/gl/prelude.hpp>
|
||||
#include <mbgl/shaders/gl/background.hpp>
|
||||
|
||||
@@ -20,6 +20,8 @@ enum class BuiltIn {
|
||||
LineShader,
|
||||
FillPatternShader,
|
||||
FillOutlinePatternShader,
|
||||
FillExtrusionShader,
|
||||
FillExtrusionPatternShader,
|
||||
HeatmapShader,
|
||||
HeatmapTextureShader,
|
||||
RasterShader,
|
||||
|
||||
9
shaders/drawable.fill_extrusion.fragment.glsl
Normal file
9
shaders/drawable.fill_extrusion.fragment.glsl
Normal file
@@ -0,0 +1,9 @@
|
||||
in vec4 v_color;
|
||||
|
||||
void main() {
|
||||
fragColor = v_color;
|
||||
|
||||
#ifdef OVERDRAW_INSPECTOR
|
||||
fragColor = vec4(1.0);
|
||||
#endif
|
||||
}
|
||||
92
shaders/drawable.fill_extrusion.vertex.glsl
Normal file
92
shaders/drawable.fill_extrusion.vertex.glsl
Normal file
@@ -0,0 +1,92 @@
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
layout (location = 1) in vec4 a_normal_ed;
|
||||
out vec4 v_color;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
#pragma mapbox: define highp float base
|
||||
#pragma mapbox: define highp float height
|
||||
#pragma mapbox: define highp vec4 color
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize highp float base
|
||||
#pragma mapbox: initialize highp float height
|
||||
#pragma mapbox: initialize highp vec4 color
|
||||
|
||||
vec3 normal = a_normal_ed.xyz;
|
||||
|
||||
base = max(0.0, base);
|
||||
height = max(0.0, height);
|
||||
|
||||
float t = mod(normal.x, 2.0);
|
||||
|
||||
gl_Position = u_matrix * vec4(a_pos, t > 0.0 ? height : base, 1);
|
||||
|
||||
// Relative luminance (how dark/bright is the surface color?)
|
||||
float colorvalue = color.r * 0.2126 + color.g * 0.7152 + color.b * 0.0722;
|
||||
|
||||
v_color = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
// Add slight ambient lighting so no extrusions are totally black
|
||||
vec4 ambientlight = vec4(0.03, 0.03, 0.03, 1.0);
|
||||
color += ambientlight;
|
||||
|
||||
// Calculate cos(theta), where theta is the angle between surface normal and diffuse light ray
|
||||
float directional = clamp(dot(normal / 16384.0, u_lightpos), 0.0, 1.0);
|
||||
|
||||
// Adjust directional so that
|
||||
// the range of values for highlight/shading is narrower
|
||||
// with lower light intensity
|
||||
// and with lighter/brighter surface colors
|
||||
directional = mix((1.0 - u_lightintensity), max((1.0 - colorvalue + u_lightintensity), 1.0), directional);
|
||||
|
||||
// Add gradient along z axis of side surfaces
|
||||
if (normal.y != 0.0) {
|
||||
// This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,
|
||||
// and otherwise calculates the gradient based on base + height
|
||||
directional *= (
|
||||
(1.0 - u_vertical_gradient) +
|
||||
(u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0)));
|
||||
}
|
||||
|
||||
// Assign final color based on surface + ambient light color, diffuse light directional, and light color
|
||||
// with lower bounds adjusted to hue of light
|
||||
// so that shading is tinted with the complementary (opposite) color to the light color
|
||||
v_color.r += clamp(color.r * directional * u_lightcolor.r, mix(0.0, 0.3, 1.0 - u_lightcolor.r), 1.0);
|
||||
v_color.g += clamp(color.g * directional * u_lightcolor.g, mix(0.0, 0.3, 1.0 - u_lightcolor.g), 1.0);
|
||||
v_color.b += clamp(color.b * directional * u_lightcolor.b, mix(0.0, 0.3, 1.0 - u_lightcolor.b), 1.0);
|
||||
v_color *= u_opacity;
|
||||
}
|
||||
73
shaders/drawable.fill_extrusion_pattern.fragment.glsl
Normal file
73
shaders/drawable.fill_extrusion_pattern.fragment.glsl
Normal file
@@ -0,0 +1,73 @@
|
||||
in vec2 v_pos_a;
|
||||
in vec2 v_pos_b;
|
||||
in vec4 v_lighting;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
uniform sampler2D u_image;
|
||||
|
||||
#pragma mapbox: define lowp float base
|
||||
#pragma mapbox: define lowp float height
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float base
|
||||
#pragma mapbox: initialize lowp float height
|
||||
#pragma mapbox: initialize mediump vec4 pattern_from
|
||||
#pragma mapbox: initialize mediump vec4 pattern_to
|
||||
|
||||
vec2 pattern_tl_a = pattern_from.xy;
|
||||
vec2 pattern_br_a = pattern_from.zw;
|
||||
vec2 pattern_tl_b = pattern_to.xy;
|
||||
vec2 pattern_br_b = pattern_to.zw;
|
||||
|
||||
vec2 imagecoord = mod(v_pos_a, 1.0);
|
||||
vec2 pos = mix(pattern_tl_a / u_texsize, pattern_br_a / u_texsize, imagecoord);
|
||||
vec4 color1 = texture(u_image, pos);
|
||||
|
||||
vec2 imagecoord_b = mod(v_pos_b, 1.0);
|
||||
vec2 pos2 = mix(pattern_tl_b / u_texsize, pattern_br_b / u_texsize, imagecoord_b);
|
||||
vec4 color2 = texture(u_image, pos2);
|
||||
|
||||
vec4 mixedColor = mix(color1, color2, u_fade);
|
||||
|
||||
fragColor = mixedColor * v_lighting;
|
||||
|
||||
#ifdef OVERDRAW_INSPECTOR
|
||||
fragColor = vec4(1.0);
|
||||
#endif
|
||||
}
|
||||
99
shaders/drawable.fill_extrusion_pattern.vertex.glsl
Normal file
99
shaders/drawable.fill_extrusion_pattern.vertex.glsl
Normal file
@@ -0,0 +1,99 @@
|
||||
layout (location = 0) in vec2 a_pos;
|
||||
layout (location = 1) in vec4 a_normal_ed;
|
||||
|
||||
out vec2 v_pos_a;
|
||||
out vec2 v_pos_b;
|
||||
out vec4 v_lighting;
|
||||
|
||||
layout (std140) uniform FillExtrusionDrawableTilePropsUBO {
|
||||
highp vec4 u_pattern_from;
|
||||
highp vec4 u_pattern_to;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionInterpolateUBO {
|
||||
highp float u_base_t;
|
||||
highp float u_height_t;
|
||||
highp float u_color_t;
|
||||
highp float u_pattern_from_t;
|
||||
highp float u_pattern_to_t;
|
||||
highp float u_pad_interp1, u_pad_interp2, u_pad_interp3;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawableUBO {
|
||||
highp mat4 u_matrix;
|
||||
highp vec4 u_scale;
|
||||
highp vec2 u_texsize;
|
||||
highp vec2 u_pixel_coord_upper;
|
||||
highp vec2 u_pixel_coord_lower;
|
||||
highp float u_height_factor;
|
||||
highp float u_pad_drawable;
|
||||
};
|
||||
layout (std140) uniform FillExtrusionDrawablePropsUBO {
|
||||
highp vec4 u_color;
|
||||
highp vec3 u_lightcolor;
|
||||
highp float u_pad1;
|
||||
highp vec3 u_lightpos;
|
||||
highp float u_base;
|
||||
highp float u_height;
|
||||
highp float u_lightintensity;
|
||||
highp float u_vertical_gradient;
|
||||
highp float u_opacity;
|
||||
highp float u_fade;
|
||||
highp float u_pad_props2, u_pad_props3, u_pad_props4;
|
||||
};
|
||||
|
||||
#pragma mapbox: define lowp float base
|
||||
#pragma mapbox: define lowp float height
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float base
|
||||
#pragma mapbox: initialize lowp float height
|
||||
#pragma mapbox: initialize mediump vec4 pattern_from
|
||||
#pragma mapbox: initialize mediump vec4 pattern_to
|
||||
|
||||
vec2 pattern_tl_a = pattern_from.xy;
|
||||
vec2 pattern_br_a = pattern_from.zw;
|
||||
vec2 pattern_tl_b = pattern_to.xy;
|
||||
vec2 pattern_br_b = pattern_to.zw;
|
||||
|
||||
float pixelRatio = u_scale.x;
|
||||
float tileRatio = u_scale.y;
|
||||
float fromScale = u_scale.z;
|
||||
float toScale = u_scale.w;
|
||||
|
||||
vec3 normal = a_normal_ed.xyz;
|
||||
float edgedistance = a_normal_ed.w;
|
||||
|
||||
vec2 display_size_a = vec2((pattern_br_a.x - pattern_tl_a.x) / pixelRatio, (pattern_br_a.y - pattern_tl_a.y) / pixelRatio);
|
||||
vec2 display_size_b = vec2((pattern_br_b.x - pattern_tl_b.x) / pixelRatio, (pattern_br_b.y - pattern_tl_b.y) / pixelRatio);
|
||||
|
||||
base = max(0.0, base);
|
||||
height = max(0.0, height);
|
||||
|
||||
float t = mod(normal.x, 2.0);
|
||||
float z = t > 0.0 ? height : base;
|
||||
|
||||
gl_Position = u_matrix * vec4(a_pos, z, 1);
|
||||
|
||||
vec2 pos = normal.x == 1.0 && normal.y == 0.0 && normal.z == 16384.0
|
||||
? a_pos // extrusion top
|
||||
: vec2(edgedistance, z * u_height_factor); // extrusion side
|
||||
|
||||
v_pos_a = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, fromScale * display_size_a, tileRatio, pos);
|
||||
v_pos_b = get_pattern_pos(u_pixel_coord_upper, u_pixel_coord_lower, toScale * display_size_b, tileRatio, pos);
|
||||
|
||||
v_lighting = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
float directional = clamp(dot(normal / 16383.0, u_lightpos), 0.0, 1.0);
|
||||
directional = mix((1.0 - u_lightintensity), max((0.5 + u_lightintensity), 1.0), directional);
|
||||
|
||||
if (normal.y != 0.0) {
|
||||
// This avoids another branching statement, but multiplies by a constant of 0.84 if no vertical gradient,
|
||||
// and otherwise calculates the gradient based on base + height
|
||||
directional *= (
|
||||
(1.0 - u_vertical_gradient) +
|
||||
(u_vertical_gradient * clamp((t + base) * pow(height / 150.0, 0.5), mix(0.7, 0.98, 1.0 - u_lightintensity), 1.0)));
|
||||
}
|
||||
|
||||
v_lighting.rgb += clamp(directional * u_lightcolor, mix(vec3(0.0), vec3(0.3), 1.0 - u_lightcolor), vec3(1.0));
|
||||
v_lighting *= u_opacity;
|
||||
}
|
||||
@@ -11,7 +11,6 @@ out vec4 v_color;
|
||||
|
||||
#pragma mapbox: define highp float base
|
||||
#pragma mapbox: define highp float height
|
||||
|
||||
#pragma mapbox: define highp vec4 color
|
||||
|
||||
void main() {
|
||||
|
||||
@@ -9,8 +9,8 @@ in vec4 v_lighting;
|
||||
|
||||
#pragma mapbox: define lowp float base
|
||||
#pragma mapbox: define lowp float height
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float base
|
||||
|
||||
@@ -19,8 +19,8 @@ out vec4 v_lighting;
|
||||
|
||||
#pragma mapbox: define lowp float base
|
||||
#pragma mapbox: define lowp float height
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float base
|
||||
|
||||
@@ -8,8 +8,8 @@ in vec2 v_pos_b;
|
||||
in vec2 v_pos;
|
||||
|
||||
#pragma mapbox: define lowp float opacity
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float opacity
|
||||
|
||||
@@ -11,8 +11,8 @@ out vec2 v_pos_b;
|
||||
out vec2 v_pos;
|
||||
|
||||
#pragma mapbox: define lowp float opacity
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float opacity
|
||||
|
||||
@@ -7,8 +7,8 @@ in vec2 v_pos_a;
|
||||
in vec2 v_pos_b;
|
||||
|
||||
#pragma mapbox: define lowp float opacity
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float opacity
|
||||
|
||||
@@ -9,8 +9,8 @@ out vec2 v_pos_a;
|
||||
out vec2 v_pos_b;
|
||||
|
||||
#pragma mapbox: define lowp float opacity
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float opacity
|
||||
|
||||
@@ -10,15 +10,14 @@ in vec2 v_width2;
|
||||
in float v_linesofar;
|
||||
in float v_gamma_scale;
|
||||
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
#pragma mapbox: define lowp float blur
|
||||
#pragma mapbox: define lowp float opacity
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize mediump vec4 pattern_from
|
||||
#pragma mapbox: initialize mediump vec4 pattern_to
|
||||
|
||||
#pragma mapbox: initialize lowp float blur
|
||||
#pragma mapbox: initialize lowp float opacity
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ out float v_gamma_scale;
|
||||
#pragma mapbox: define lowp float offset
|
||||
#pragma mapbox: define mediump float gapwidth
|
||||
#pragma mapbox: define mediump float width
|
||||
#pragma mapbox: define lowp vec4 pattern_from
|
||||
#pragma mapbox: define lowp vec4 pattern_to
|
||||
#pragma mapbox: define mediump vec4 pattern_from
|
||||
#pragma mapbox: define mediump vec4 pattern_to
|
||||
|
||||
void main() {
|
||||
#pragma mapbox: initialize lowp float blur
|
||||
|
||||
@@ -76,6 +76,20 @@
|
||||
"glsl_frag": "drawable.fill_outline_pattern.fragment.glsl",
|
||||
"uses_ubos": true
|
||||
},
|
||||
{
|
||||
"name": "FillExtrusionShader",
|
||||
"header": "drawable_fill_extrusion",
|
||||
"glsl_vert": "drawable.fill_extrusion.vertex.glsl",
|
||||
"glsl_frag": "drawable.fill_extrusion.fragment.glsl",
|
||||
"uses_ubos": true
|
||||
},
|
||||
{
|
||||
"name": "FillExtrusionPatternShader",
|
||||
"header": "drawable_fill_extrusion_pattern",
|
||||
"glsl_vert": "drawable.fill_extrusion_pattern.vertex.glsl",
|
||||
"glsl_frag": "drawable.fill_extrusion_pattern.fragment.glsl",
|
||||
"uses_ubos": true
|
||||
},
|
||||
{
|
||||
"name": "HeatmapShader",
|
||||
"header": "drawable_heatmap",
|
||||
|
||||
@@ -38,13 +38,11 @@ class ShaderRegistry;
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
class Drawable;
|
||||
class DrawableBuilder;
|
||||
class DrawableTweaker;
|
||||
class ShaderProgramBase;
|
||||
class Texture2D;
|
||||
|
||||
using DrawablePtr = std::shared_ptr<Drawable>;
|
||||
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
|
||||
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
|
||||
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
|
||||
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
|
||||
using Texture2DPtr = std::shared_ptr<Texture2D>;
|
||||
@@ -120,9 +118,6 @@ public:
|
||||
/// Create a new drawable builder
|
||||
virtual UniqueDrawableBuilder createDrawableBuilder(std::string name) = 0;
|
||||
|
||||
/// Create a new drawable tweaker
|
||||
virtual DrawableTweakerPtr createDrawableTweaker() = 0;
|
||||
|
||||
/// Create a new uniform buffer
|
||||
virtual UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) = 0;
|
||||
|
||||
|
||||
25
src/mbgl/gfx/drawable_atlases_tweaker.cpp
Normal file
25
src/mbgl/gfx/drawable_atlases_tweaker.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
|
||||
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/renderer/tile_render_data.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
void DrawableAtlasesTweaker::execute(gfx::Drawable& drawable, const PaintParameters&) {
|
||||
if (const auto& shader = drawable.getShader()) {
|
||||
if (const auto samplerLocation = shader->getSamplerLocation(glyphName)) {
|
||||
if (const auto iconSamplerLocation = shader->getSamplerLocation(iconName)) {
|
||||
assert(*samplerLocation != *iconSamplerLocation);
|
||||
drawable.setTexture(atlases ? atlases->glyph : nullptr, *samplerLocation);
|
||||
drawable.setTexture(atlases ? atlases->icon : nullptr, *iconSamplerLocation);
|
||||
} else {
|
||||
drawable.setTexture(atlases ? (isText ? atlases->glyph : atlases->icon) : nullptr, *samplerLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gfx
|
||||
} // namespace mbgl
|
||||
@@ -41,17 +41,20 @@ void DrawableBuilder::flush() {
|
||||
const auto vertexCount = curVertexCount();
|
||||
if (vertexCount) {
|
||||
const auto& draw = getCurrentDrawable(/*createIfNone=*/true);
|
||||
draw->setEnabled(enabled);
|
||||
draw->setLineWidth(static_cast<int32_t>(lineWidth));
|
||||
draw->setNeedsStencil(needsStencil);
|
||||
draw->setEnableColor(enableColor);
|
||||
draw->setEnableStencil(enableStencil);
|
||||
draw->setRenderPass(renderPass);
|
||||
draw->setDrawPriority(drawPriority);
|
||||
draw->setSubLayerIndex(subLayerIndex);
|
||||
draw->setDepthType(depthType);
|
||||
draw->setIs3D(is3D);
|
||||
draw->setColorMode(impl->colorMode);
|
||||
draw->setCullFaceMode(impl->cullFaceMode);
|
||||
draw->setShader(shader);
|
||||
draw->setTextures(textures);
|
||||
draw->setTextureSource(textureSource);
|
||||
draw->setTweakers(tweakers);
|
||||
|
||||
if (auto drawAttrs = getVertexAttributes().clone()) {
|
||||
vertexAttrs.observeAttributes([&](const std::string& iName, const VertexAttribute& iAttr) {
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
#include <mbgl/gl/drawable_gl_builder.hpp>
|
||||
#include <mbgl/gl/drawable_gl_tweaker.hpp>
|
||||
#include <mbgl/gl/layer_group_gl.hpp>
|
||||
#include <mbgl/gl/render_target_gl.hpp>
|
||||
#include <mbgl/gl/uniform_buffer_gl.hpp>
|
||||
@@ -464,10 +463,6 @@ gfx::UniqueDrawableBuilder Context::createDrawableBuilder(std::string name) {
|
||||
return std::make_unique<gl::DrawableGLBuilder>(std::move(name));
|
||||
}
|
||||
|
||||
gfx::DrawableTweakerPtr Context::createDrawableTweaker() {
|
||||
return std::make_shared<gl::DrawableGLTweaker>();
|
||||
}
|
||||
|
||||
gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t size) {
|
||||
return std::make_shared<gl::UniformBufferGL>(data, size);
|
||||
}
|
||||
|
||||
@@ -108,7 +108,6 @@ public:
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
gfx::UniqueDrawableBuilder createDrawableBuilder(std::string name) override;
|
||||
gfx::DrawableTweakerPtr createDrawableTweaker() override;
|
||||
gfx::UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) override;
|
||||
|
||||
gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override;
|
||||
|
||||
@@ -21,7 +21,7 @@ DrawableGL::~DrawableGL() {
|
||||
impl->attributeBuffer.reset();
|
||||
}
|
||||
|
||||
void DrawableGL::draw(const PaintParameters& parameters) const {
|
||||
void DrawableGL::draw(PaintParameters& parameters) const {
|
||||
auto& context = static_cast<gl::Context&>(parameters.context);
|
||||
|
||||
if (shader) {
|
||||
@@ -36,16 +36,13 @@ void DrawableGL::draw(const PaintParameters& parameters) const {
|
||||
return;
|
||||
}
|
||||
|
||||
context.setDepthMode(parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType()));
|
||||
context.setDepthMode(getIs3D() ? parameters.depthModeFor3D()
|
||||
: parameters.depthModeForSublayer(getSubLayerIndex(), getDepthType()));
|
||||
|
||||
// force disable depth test for debugging
|
||||
// context.setDepthMode({gfx::DepthFunctionType::Always, gfx::DepthMaskType::ReadOnly, {0,1}});
|
||||
|
||||
if (needsStencil && tileID) {
|
||||
context.setStencilMode(parameters.stencilModeForClipping(tileID->toUnwrapped()));
|
||||
} else {
|
||||
context.setStencilMode(gfx::StencilMode::disabled());
|
||||
}
|
||||
context.setStencilMode(makeStencilMode(parameters));
|
||||
|
||||
context.setColorMode(getColorMode());
|
||||
context.setCullFaceMode(getCullFaceMode());
|
||||
@@ -196,12 +193,6 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
};
|
||||
}
|
||||
|
||||
if (const auto src = getTextureSource()) {
|
||||
for (auto& pair : src()) {
|
||||
setTexture(std::move(pair.second), pair.first);
|
||||
}
|
||||
}
|
||||
|
||||
const bool texturesNeedUpload = std::any_of(
|
||||
textures.begin(), textures.end(), [](const auto& pair) { return pair.second && pair.second->needsUpload(); });
|
||||
|
||||
@@ -210,6 +201,22 @@ void DrawableGL::upload(gfx::UploadPass& uploadPass) {
|
||||
}
|
||||
}
|
||||
|
||||
gfx::ColorMode DrawableGL::makeColorMode(PaintParameters& parameters) const {
|
||||
return enableColor ? parameters.colorModeForRenderPass() : gfx::ColorMode::disabled();
|
||||
}
|
||||
|
||||
gfx::StencilMode DrawableGL::makeStencilMode(PaintParameters& parameters) const {
|
||||
if (enableStencil) {
|
||||
if (is3D) {
|
||||
return parameters.stencilModeFor3D();
|
||||
} else if (tileID) {
|
||||
return parameters.stencilModeForClipping(tileID->toUnwrapped());
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
return gfx::StencilMode::disabled();
|
||||
}
|
||||
|
||||
void DrawableGL::uploadTextures() const {
|
||||
for (const auto& pair : textures) {
|
||||
if (const auto& tex = pair.second) {
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#include <mbgl/gl/drawable_gl_tweaker.hpp>
|
||||
#include <mbgl/gl/drawable_gl.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gl {
|
||||
|
||||
void DrawableGLTweaker::execute(gfx::Drawable& drawable, const PaintParameters&) {
|
||||
auto& drawGL = (gl::DrawableGL&)drawable;
|
||||
// apply expressions based on current state, update attributes, uniforms, etc.
|
||||
drawGL.getId();
|
||||
}
|
||||
|
||||
} // namespace gl
|
||||
} // namespace mbgl
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/gl/layer_group_gl.hpp>
|
||||
|
||||
#include <mbgl/gfx/drawable_tweaker.hpp>
|
||||
#include <mbgl/gfx/render_pass.hpp>
|
||||
#include <mbgl/gfx/renderable.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
@@ -54,7 +55,7 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
|
||||
// Collect the tile IDs relevant to stenciling and update the stencil buffer, if necessary.
|
||||
std::set<UnwrappedTileID> tileIDs;
|
||||
observeDrawables([&](const gfx::Drawable& drawable) {
|
||||
if (drawable.getEnabled() && drawable.getNeedsStencil() && drawable.getTileID() &&
|
||||
if (drawable.getEnabled() && !drawable.getIs3D() && drawable.getEnableStencil() && drawable.getTileID() &&
|
||||
drawable.hasRenderPass(parameters.pass)) {
|
||||
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
|
||||
}
|
||||
@@ -81,6 +82,10 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
|
||||
const auto debugGroupTile = parameters.encoder->createDebugGroup(labelPtr);
|
||||
#endif
|
||||
|
||||
for (const auto& tweaker : drawable.getTweakers()) {
|
||||
tweaker->execute(drawable, parameters);
|
||||
}
|
||||
|
||||
drawable.draw(parameters);
|
||||
});
|
||||
}
|
||||
@@ -127,6 +132,10 @@ void LayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters) {
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(drawable.getName().c_str());
|
||||
#endif
|
||||
|
||||
for (const auto& tweaker : drawable.getTweakers()) {
|
||||
tweaker->execute(drawable, parameters);
|
||||
}
|
||||
|
||||
drawable.draw(parameters);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -104,6 +104,8 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders, const ProgramPar
|
||||
shaders::BuiltIn::LineGradientShader,
|
||||
shaders::BuiltIn::FillOutlinePatternShader,
|
||||
shaders::BuiltIn::FillPatternShader,
|
||||
shaders::BuiltIn::FillExtrusionShader,
|
||||
shaders::BuiltIn::FillExtrusionPatternShader,
|
||||
shaders::BuiltIn::HeatmapShader,
|
||||
shaders::BuiltIn::HeatmapTextureShader,
|
||||
shaders::BuiltIn::RasterShader,
|
||||
|
||||
@@ -11,12 +11,12 @@ using namespace style;
|
||||
|
||||
static_assert(sizeof(FillExtrusionLayoutVertex) == 12, "expected FillExtrusionLayoutVertex size");
|
||||
|
||||
std::array<float, 3> lightColor(const EvaluatedLight& light) {
|
||||
std::array<float, 3> FillExtrusionProgram::lightColor(const EvaluatedLight& light) {
|
||||
const auto color = light.get<LightColor>();
|
||||
return {{color.r, color.g, color.b}};
|
||||
}
|
||||
|
||||
std::array<float, 3> lightPosition(const EvaluatedLight& light, const TransformState& state) {
|
||||
std::array<float, 3> FillExtrusionProgram::lightPosition(const EvaluatedLight& light, const TransformState& state) {
|
||||
auto lightPos = light.get<LightPosition>().getCartesian();
|
||||
mat3 lightMat;
|
||||
matrix::identity(lightMat);
|
||||
@@ -27,26 +27,26 @@ std::array<float, 3> lightPosition(const EvaluatedLight& light, const TransformS
|
||||
return lightPos;
|
||||
}
|
||||
|
||||
float lightIntensity(const EvaluatedLight& light) {
|
||||
float FillExtrusionProgram::lightIntensity(const EvaluatedLight& light) {
|
||||
return light.get<LightIntensity>();
|
||||
}
|
||||
|
||||
FillExtrusionProgram::LayoutUniformValues FillExtrusionProgram::layoutUniformValues(mat4 matrix,
|
||||
FillExtrusionProgram::LayoutUniformValues FillExtrusionProgram::layoutUniformValues(const mat4& matrix,
|
||||
const TransformState& state,
|
||||
const float opacity,
|
||||
const EvaluatedLight& light,
|
||||
const float verticalGradient) {
|
||||
return {uniforms::matrix::Value(matrix),
|
||||
uniforms::opacity::Value(opacity),
|
||||
uniforms::lightcolor::Value(lightColor(light)),
|
||||
uniforms::lightpos::Value(lightPosition(light, state)),
|
||||
uniforms::lightintensity::Value(lightIntensity(light)),
|
||||
uniforms::lightcolor::Value(FillExtrusionProgram::lightColor(light)),
|
||||
uniforms::lightpos::Value(FillExtrusionProgram::lightPosition(light, state)),
|
||||
uniforms::lightintensity::Value(FillExtrusionProgram::lightIntensity(light)),
|
||||
uniforms::vertical_gradient::Value(verticalGradient)};
|
||||
}
|
||||
|
||||
FillExtrusionPatternProgram::LayoutUniformValues FillExtrusionPatternProgram::layoutUniformValues(
|
||||
mat4 matrix,
|
||||
Size atlasSize,
|
||||
const mat4& matrix,
|
||||
const Size atlasSize,
|
||||
const CrossfadeParameters& crossfade,
|
||||
const UnwrappedTileID& tileID,
|
||||
const TransformState& state,
|
||||
@@ -56,11 +56,11 @@ FillExtrusionPatternProgram::LayoutUniformValues FillExtrusionPatternProgram::la
|
||||
const EvaluatedLight& light,
|
||||
const float verticalGradient) {
|
||||
const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom());
|
||||
int32_t tileSizeAtNearestZoom = static_cast<int32_t>(util::tileSize_D *
|
||||
state.zoomScale(state.getIntegerZoom() - tileID.canonical.z));
|
||||
int32_t pixelX = static_cast<int32_t>(tileSizeAtNearestZoom *
|
||||
(tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)));
|
||||
int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
|
||||
const int32_t tileSizeAtNearestZoom = static_cast<int32_t>(
|
||||
util::tileSize_D * state.zoomScale(state.getIntegerZoom() - tileID.canonical.z));
|
||||
const int32_t pixelX = static_cast<int32_t>(
|
||||
tileSizeAtNearestZoom * (tileID.canonical.x + tileID.wrap * state.zoomScale(tileID.canonical.z)));
|
||||
const int32_t pixelY = tileSizeAtNearestZoom * tileID.canonical.y;
|
||||
|
||||
return {uniforms::matrix::Value(matrix),
|
||||
uniforms::opacity::Value(opacity),
|
||||
@@ -72,9 +72,9 @@ FillExtrusionPatternProgram::LayoutUniformValues FillExtrusionPatternProgram::la
|
||||
uniforms::pixel_coord_lower::Value(
|
||||
std::array<float, 2>{{static_cast<float>(pixelX & 0xFFFF), static_cast<float>(pixelY & 0xFFFF)}}),
|
||||
uniforms::height_factor::Value(heightFactor),
|
||||
uniforms::lightcolor::Value(lightColor(light)),
|
||||
uniforms::lightpos::Value(lightPosition(light, state)),
|
||||
uniforms::lightintensity::Value(lightIntensity(light)),
|
||||
uniforms::lightcolor::Value(FillExtrusionProgram::lightColor(light)),
|
||||
uniforms::lightpos::Value(FillExtrusionProgram::lightPosition(light, state)),
|
||||
uniforms::lightintensity::Value(FillExtrusionProgram::lightIntensity(light)),
|
||||
uniforms::vertical_gradient::Value(verticalGradient)};
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <mbgl/style/style.hpp>
|
||||
#include <mbgl/renderer/render_light.hpp>
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -78,8 +79,12 @@ public:
|
||||
static_cast<int16_t>(e)}}};
|
||||
}
|
||||
|
||||
static std::array<float, 3> lightColor(const EvaluatedLight&);
|
||||
static std::array<float, 3> lightPosition(const EvaluatedLight&, const TransformState&);
|
||||
static float lightIntensity(const EvaluatedLight&);
|
||||
|
||||
static LayoutUniformValues layoutUniformValues(
|
||||
mat4, const TransformState&, float opacity, const EvaluatedLight&, float verticalGradient);
|
||||
const mat4&, const TransformState&, float opacity, const EvaluatedLight&, float verticalGradient);
|
||||
};
|
||||
|
||||
class FillExtrusionPatternProgram final : public Program<FillExtrusionPatternProgram,
|
||||
@@ -95,7 +100,7 @@ public:
|
||||
|
||||
using Program::Program;
|
||||
|
||||
static LayoutUniformValues layoutUniformValues(mat4,
|
||||
static LayoutUniformValues layoutUniformValues(const mat4&,
|
||||
Size atlasSize,
|
||||
const CrossfadeParameters&,
|
||||
const UnwrappedTileID&,
|
||||
|
||||
@@ -16,12 +16,15 @@ mat4 LayerTweaker::getTileMatrix(const UnwrappedTileID& tileID,
|
||||
const TransformState& state,
|
||||
const std::array<float, 2>& translation,
|
||||
style::TranslateAnchorType anchor,
|
||||
bool nearClipped,
|
||||
bool inViewportPixelUnits) {
|
||||
// from RenderTile::prepare
|
||||
mat4 tileMatrix;
|
||||
state.matrixFor(tileMatrix, tileID);
|
||||
state.matrixFor(/*out*/ tileMatrix, tileID);
|
||||
|
||||
const auto& projMatrix = renderTree.getParameters().transformParams.projMatrix;
|
||||
// nearClippedMatrix has near plane moved further, to enhance depth buffer precision
|
||||
const auto& params = renderTree.getParameters().transformParams;
|
||||
const auto& projMatrix = nearClipped ? params.nearClippedProjMatrix : params.projMatrix;
|
||||
matrix::multiply(tileMatrix, projMatrix, tileMatrix);
|
||||
|
||||
return RenderTile::translateVtxMatrix(tileID, tileMatrix, translation, anchor, state, inViewportPixelUnits);
|
||||
|
||||
@@ -58,7 +58,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
CirclePaintParamsUBO paintParamsUBO = {
|
||||
const CirclePaintParamsUBO paintParamsUBO = {
|
||||
/* .camera_to_center_distance = */ parameters.state.getCameraToCenterDistance(),
|
||||
/* .device_pixel_ratio = */ parameters.pixelRatio,
|
||||
/* .padding = */ {0}};
|
||||
@@ -72,7 +72,7 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const bool pitchWithMap = evaluated.get<CirclePitchAlignment>() == AlignmentType::Map;
|
||||
|
||||
if (!evaluatedPropsUniformBuffer) {
|
||||
CircleEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
const CircleEvaluatedPropsUBO evaluatedPropsUBO = {
|
||||
/* .color = */ evaluated.get<CircleColor>().constantOr(CircleColor::defaultValue()),
|
||||
/* .stroke_color = */ evaluated.get<CircleStrokeColor>().constantOr(CircleStrokeColor::defaultValue()),
|
||||
/* .radius = */ evaluated.get<CircleRadius>().constantOr(CircleRadius::defaultValue()),
|
||||
@@ -100,8 +100,9 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto& translation = evaluated.get<CircleTranslate>();
|
||||
const auto anchor = evaluated.get<CircleTranslateAnchor>();
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
constexpr bool nearClipped = false;
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, inViewportPixelUnits);
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
const auto pixelsToTileUnits = tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom()));
|
||||
|
||||
|
||||
152
src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.cpp
Normal file
152
src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.cpp
Normal file
@@ -0,0 +1,152 @@
|
||||
#include <mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp>
|
||||
|
||||
#include <mbgl/gfx/context.hpp>
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/gfx/renderable.hpp>
|
||||
#include <mbgl/gfx/renderer_backend.hpp>
|
||||
#include <mbgl/programs/fill_extrusion_program.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/render_tree.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/paint_property_binder.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#include <mbgl/style/layers/fill_extrusion_layer_properties.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
namespace {
|
||||
|
||||
struct alignas(16) FillExtrusionDrawableUBO {
|
||||
/* 0 */ std::array<float, 4 * 4> matrix;
|
||||
/* 64 */ std::array<float, 4> scale;
|
||||
/* 80 */ std::array<float, 2> texsize;
|
||||
/* 88 */ std::array<float, 2> pixel_coord_upper;
|
||||
/* 96 */ std::array<float, 2> pixel_coord_lower;
|
||||
/* 104 */ float height_factor;
|
||||
/* 108 */ float pad;
|
||||
/* 112 */
|
||||
};
|
||||
static_assert(sizeof(FillExtrusionDrawableUBO) == 7 * 16);
|
||||
|
||||
/// Evaluated properties that do not depend on the tile
|
||||
struct alignas(16) FillExtrusionDrawablePropsUBO {
|
||||
/* 0 */ std::array<float, 4> color;
|
||||
/* 16 */ std::array<float, 3> light_color;
|
||||
/* 28 */ float pad1;
|
||||
/* 32 */ std::array<float, 3> light_position;
|
||||
/* 44 */ float base;
|
||||
/* 48 */ float height;
|
||||
/* 52 */ float light_intensity;
|
||||
/* 56 */ float vertical_gradient;
|
||||
/* 60 */ float opacity;
|
||||
/* 64 */ float fade;
|
||||
/* 68 */ float pad2, pad3, pad4;
|
||||
/* 80 */
|
||||
};
|
||||
static_assert(sizeof(FillExtrusionDrawablePropsUBO) == 5 * 16);
|
||||
|
||||
constexpr auto FillExtrusionDrawableUBOName = "FillExtrusionDrawableUBO";
|
||||
constexpr auto FillExtrusionDrawablePropsUBOName = "FillExtrusionDrawablePropsUBO";
|
||||
|
||||
constexpr auto texUniformName = "u_image";
|
||||
|
||||
template <typename T, class... Is, class... Ts>
|
||||
auto constOrDefault(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& evaluated) {
|
||||
return evaluated.template get<T>().constantOr(T::defaultValue());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const RenderTree& renderTree,
|
||||
const PaintParameters& parameters) {
|
||||
const auto& props = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties);
|
||||
const auto& evaluated = props.evaluated;
|
||||
const auto& crossfade = props.crossfade;
|
||||
const auto& state = parameters.state;
|
||||
|
||||
if (layerGroup.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
const auto label = layerGroup.getName() + "-update-uniforms";
|
||||
const auto debugGroup = parameters.encoder->createDebugGroup(label.c_str());
|
||||
#endif
|
||||
|
||||
// UBO depends on more than just evaluated properties, so we need to update every time.
|
||||
const FillExtrusionDrawablePropsUBO paramsUBO = {
|
||||
/* .color = */ gfx::Drawable::colorAttrRGBA(constOrDefault<FillExtrusionColor>(evaluated)),
|
||||
/* .light_color = */ FillExtrusionProgram::lightColor(parameters.evaluatedLight),
|
||||
/* .pad = */ 0,
|
||||
/* .light_position = */ FillExtrusionProgram::lightPosition(parameters.evaluatedLight, state),
|
||||
/* .base = */ constOrDefault<FillExtrusionBase>(evaluated),
|
||||
/* .height = */ constOrDefault<FillExtrusionHeight>(evaluated),
|
||||
/* .light_intensity = */ FillExtrusionProgram::lightIntensity(parameters.evaluatedLight),
|
||||
/* .vertical_gradient = */ evaluated.get<FillExtrusionVerticalGradient>() ? 1.0f : 0.0f,
|
||||
/* .opacity = */ evaluated.get<FillExtrusionOpacity>(),
|
||||
/* .fade = */ crossfade.t,
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
0};
|
||||
if (!propsBuffer) {
|
||||
propsBuffer = parameters.context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
} else {
|
||||
propsBuffer->update(¶msUBO, sizeof(paramsUBO));
|
||||
}
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.addOrReplace(FillExtrusionDrawablePropsUBOName, propsBuffer);
|
||||
|
||||
if (!drawable.getTileID()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||
|
||||
const auto& translation = evaluated.get<FillExtrusionTranslate>();
|
||||
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
constexpr bool nearClipped = true;
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom());
|
||||
const auto zoomScale = state.zoomScale(tileID.canonical.z);
|
||||
const auto nearestZoomScale = state.zoomScale(state.getIntegerZoom() - tileID.canonical.z);
|
||||
const auto tileSizeAtNearestZoom = std::floor(util::tileSize_D * nearestZoomScale);
|
||||
const auto pixelX = static_cast<int32_t>(tileSizeAtNearestZoom *
|
||||
(tileID.canonical.x + tileID.wrap * zoomScale));
|
||||
const auto pixelY = static_cast<int32_t>(tileSizeAtNearestZoom * tileID.canonical.y);
|
||||
const auto pixelRatio = parameters.pixelRatio;
|
||||
const auto numTiles = std::pow(2, tileID.canonical.z);
|
||||
const auto heightFactor = static_cast<float>(-numTiles / util::tileSize_D / 8.0);
|
||||
|
||||
Size textureSize = {0, 0};
|
||||
if (const auto shader = drawable.getShader()) {
|
||||
if (const auto index = shader->getSamplerLocation(texUniformName)) {
|
||||
if (const auto& tex = drawable.getTexture(*index)) {
|
||||
textureSize = tex->getSize();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const FillExtrusionDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .scale = */ {pixelRatio, tileRatio, crossfade.fromScale, crossfade.toScale},
|
||||
/* .texsize = */ {static_cast<float>(textureSize.width), static_cast<float>(textureSize.height)},
|
||||
/* .pixel_coord_upper = */ {static_cast<float>(pixelX >> 16), static_cast<float>(pixelY >> 16)},
|
||||
/* .pixel_coord_lower = */ {static_cast<float>(pixelX & 0xFFFF), static_cast<float>(pixelY & 0xFFFF)},
|
||||
/* .height_factor = */ heightFactor,
|
||||
/* .pad = */ 0};
|
||||
|
||||
uniforms.createOrUpdate(FillExtrusionDrawableUBOName, &drawableUBO, parameters.context);
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace mbgl
|
||||
49
src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp
Normal file
49
src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <mbgl/renderer/layer_tweaker.hpp>
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
/**
|
||||
Fill extrusion layer specific tweaker
|
||||
*/
|
||||
class FillExtrusionLayerTweaker : public LayerTweaker {
|
||||
public:
|
||||
FillExtrusionLayerTweaker(Immutable<style::LayerProperties> properties)
|
||||
: LayerTweaker(properties){};
|
||||
|
||||
public:
|
||||
~FillExtrusionLayerTweaker() override = default;
|
||||
|
||||
void execute(LayerGroupBase&, const RenderTree&, const PaintParameters&) override;
|
||||
|
||||
static constexpr std::string_view FillExtrusionTilePropsUBOName = "FillExtrusionDrawableTilePropsUBO";
|
||||
static constexpr std::string_view FillExtrusionInterpolateUBOName = "FillExtrusionInterpolateUBO";
|
||||
|
||||
private:
|
||||
gfx::UniformBufferPtr propsBuffer;
|
||||
};
|
||||
|
||||
/// Evaluated properties that depend on the tile
|
||||
struct alignas(16) FillExtrusionDrawableTilePropsUBO {
|
||||
/* 0 */ std::array<float, 4> pattern_from;
|
||||
/* 16 */ std::array<float, 4> pattern_to;
|
||||
/* 32 */
|
||||
};
|
||||
static_assert(sizeof(FillExtrusionDrawableTilePropsUBO) == 2 * 16);
|
||||
|
||||
/// Attribute interpolations
|
||||
struct alignas(16) FillExtrusionInterpolateUBO {
|
||||
/* 0 */ float base_t;
|
||||
/* 4 */ float height_t;
|
||||
/* 8 */ float color_t;
|
||||
/* 12 */ float pattern_from_t;
|
||||
/* 16 */ float pattern_to_t;
|
||||
/* 20 */ float pad1, pad2, pad3;
|
||||
/* 32 */
|
||||
};
|
||||
static_assert(sizeof(FillExtrusionInterpolateUBO) == 2 * 16);
|
||||
|
||||
} // namespace mbgl
|
||||
@@ -33,7 +33,7 @@ struct alignas(16) FillDrawablePropsUBO {
|
||||
/* 0 */ Color color;
|
||||
/* 16 */ Color outline_color;
|
||||
/* 32 */ float opacity;
|
||||
/* 36 */ std::array<float, 3> padding;
|
||||
/* 36 */ float pad1, pad2, pad3;
|
||||
/* 48 */
|
||||
};
|
||||
static_assert(sizeof(FillDrawablePropsUBO) == 48);
|
||||
@@ -62,8 +62,9 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* .color = */ evaluated.get<FillColor>().constantOr(FillColor::defaultValue()),
|
||||
/* .outline_color = */ evaluated.get<FillOutlineColor>().constantOr(FillOutlineColor::defaultValue()),
|
||||
/* .opacity = */ evaluated.get<FillOpacity>().constantOr(FillOpacity::defaultValue()),
|
||||
/* .padding = */ {0},
|
||||
};
|
||||
/* .padding = */ 0,
|
||||
0,
|
||||
0};
|
||||
propsBuffer = parameters.context.createUniformBuffer(¶msUBO, sizeof(paramsUBO));
|
||||
}
|
||||
|
||||
@@ -79,8 +80,9 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto& translation = evaluated.get<FillTranslate>();
|
||||
const auto anchor = evaluated.get<FillTranslateAnchor>();
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
constexpr bool nearClipped = false;
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, inViewportPixelUnits);
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
// from FillPatternProgram::layoutUniformValues
|
||||
const auto renderableSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
|
||||
@@ -42,7 +42,7 @@ struct alignas(16) FillInterpolateUBO {
|
||||
/* 12 */ float pattern_from_t;
|
||||
/* 16 */ float pattern_to_t;
|
||||
/* 20 */ float fade;
|
||||
/* 24 */ std::array<float, 2> padding;
|
||||
/* 24 */ float pad1, pad2;
|
||||
/* 32 */
|
||||
};
|
||||
static_assert(sizeof(FillInterpolateUBO) == 32);
|
||||
|
||||
@@ -62,8 +62,15 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
return;
|
||||
}
|
||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, {0.f, 0.f}, TranslateAnchorType::Viewport, false);
|
||||
constexpr bool nearClipped = false;
|
||||
constexpr bool inViewportPixelUnits = false;
|
||||
const auto matrix = getTileMatrix(tileID,
|
||||
renderTree,
|
||||
parameters.state,
|
||||
{0.f, 0.f},
|
||||
TranslateAnchorType::Viewport,
|
||||
nearClipped,
|
||||
inViewportPixelUnits);
|
||||
HeatmapDrawableUBO drawableUBO = {
|
||||
/* .matrix = */ util::cast<float>(matrix),
|
||||
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
|
||||
@@ -123,7 +123,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto& evaluated = static_cast<const LineLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const LineLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
|
||||
LinePropertiesUBO linePropertiesUBO{
|
||||
const LinePropertiesUBO linePropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
@@ -132,7 +132,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
LineGradientPropertiesUBO lineGradientPropertiesUBO{
|
||||
const LineGradientPropertiesUBO lineGradientPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*gapwidth =*/evaluated.get<LineGapWidth>().constantOr(LineGapWidth::defaultValue()),
|
||||
@@ -140,7 +140,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
LineSDFPropertiesUBO lineSDFPropertiesUBO{
|
||||
const LineSDFPropertiesUBO lineSDFPropertiesUBO{
|
||||
/*color =*/evaluated.get<LineColor>().constantOr(LineColor::defaultValue()),
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
@@ -151,58 +151,62 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
{0, 0}};
|
||||
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
if (!drawable.getTileID()) return;
|
||||
const auto shader = drawable.getShader();
|
||||
if (!drawable.getTileID() || !shader) {
|
||||
return;
|
||||
}
|
||||
|
||||
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
|
||||
const auto& translation = evaluated.get<LineTranslate>();
|
||||
const auto anchor = evaluated.get<LineTranslateAnchor>();
|
||||
constexpr bool nearClipped = false;
|
||||
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
const auto& shaderUniforms = shader->getUniformBlocks();
|
||||
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, parameters.state, translation, anchor, inViewportPixelUnits);
|
||||
tileID, renderTree, parameters.state, translation, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
// simple line
|
||||
if (drawable.getShader()->getUniformBlocks().get(std::string(LineUBOName))) {
|
||||
if (shaderUniforms.get(std::string(LineUBOName))) {
|
||||
// main UBO
|
||||
LineUBO lineUBO{
|
||||
const LineUBO lineUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
drawable.mutableUniformBuffers().createOrUpdate(LineUBOName, &lineUBO, sizeof(lineUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineUBOName, &lineUBO, sizeof(lineUBO), parameters.context);
|
||||
|
||||
// properties UBO
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
uniforms.createOrUpdate(
|
||||
LinePropertiesUBOName, &linePropertiesUBO, sizeof(linePropertiesUBO), parameters.context);
|
||||
}
|
||||
// gradient line
|
||||
else if (drawable.getShader()->getUniformBlocks().get(std::string(LineGradientUBOName))) {
|
||||
else if (shaderUniforms.get(std::string(LineGradientUBOName))) {
|
||||
// main UBO
|
||||
LineGradientUBO lineGradientUBO{
|
||||
const LineGradientUBO lineGradientUBO{
|
||||
/*matrix = */ util::cast<float>(matrix),
|
||||
/*units_to_pixels = */ {1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
/*ratio = */ 1.0f / tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom())),
|
||||
/*device_pixel_ratio = */ parameters.pixelRatio};
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
LineGradientUBOName, &lineGradientUBO, sizeof(lineGradientUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineGradientUBOName, &lineGradientUBO, sizeof(lineGradientUBO), parameters.context);
|
||||
|
||||
// properties UBO
|
||||
drawable.mutableUniformBuffers().createOrUpdate(LineGradientPropertiesUBOName,
|
||||
&lineGradientPropertiesUBO,
|
||||
sizeof(lineGradientPropertiesUBO),
|
||||
parameters.context);
|
||||
uniforms.createOrUpdate(LineGradientPropertiesUBOName,
|
||||
&lineGradientPropertiesUBO,
|
||||
sizeof(lineGradientPropertiesUBO),
|
||||
parameters.context);
|
||||
}
|
||||
// pattern line
|
||||
else if (drawable.getShader()->getUniformBlocks().get(std::string(LinePatternUBOName))) {
|
||||
else if (shaderUniforms.get(std::string(LinePatternUBOName))) {
|
||||
// main UBO
|
||||
Size textureSize{0, 0};
|
||||
if (const auto shader = drawable.getShader()) {
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (const auto& texture = drawable.getTexture(index.value())) {
|
||||
textureSize = texture->getSize();
|
||||
}
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (const auto& texture = drawable.getTexture(index.value())) {
|
||||
textureSize = texture->getSize();
|
||||
}
|
||||
}
|
||||
LinePatternUBO linePatternUBO{
|
||||
const LinePatternUBO linePatternUBO{
|
||||
/*matrix =*/util::cast<float>(matrix),
|
||||
/*scale =*/
|
||||
{parameters.pixelRatio,
|
||||
@@ -215,11 +219,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*device_pixel_ratio =*/parameters.pixelRatio,
|
||||
/*fade =*/crossfade.t,
|
||||
0};
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
LinePatternUBOName, &linePatternUBO, sizeof(linePatternUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LinePatternUBOName, &linePatternUBO, sizeof(linePatternUBO), parameters.context);
|
||||
|
||||
// properties UBO
|
||||
LinePatternPropertiesUBO linePatternPropertiesUBO{
|
||||
const LinePatternPropertiesUBO linePatternPropertiesUBO{
|
||||
/*blur =*/evaluated.get<LineBlur>().constantOr(LineBlur::defaultValue()),
|
||||
/*opacity =*/evaluated.get<LineOpacity>().constantOr(LineOpacity::defaultValue()),
|
||||
/*offset =*/evaluated.get<LineOffset>().constantOr(LineOffset::defaultValue()),
|
||||
@@ -227,27 +230,25 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/*width =*/evaluated.get<LineWidth>().constantOr(LineWidth::defaultValue()),
|
||||
0,
|
||||
{0, 0}};
|
||||
drawable.mutableUniformBuffers().createOrUpdate(LinePatternPropertiesUBOName,
|
||||
&linePatternPropertiesUBO,
|
||||
sizeof(linePatternPropertiesUBO),
|
||||
parameters.context);
|
||||
uniforms.createOrUpdate(LinePatternPropertiesUBOName,
|
||||
&linePatternPropertiesUBO,
|
||||
sizeof(linePatternPropertiesUBO),
|
||||
parameters.context);
|
||||
}
|
||||
// SDF line
|
||||
else if (drawable.getShader()->getUniformBlocks().get(std::string(LineSDFUBOName))) {
|
||||
else if (shaderUniforms.get(std::string(LineSDFUBOName))) {
|
||||
if (const auto& data = drawable.getData()) {
|
||||
const gfx::LineDrawableData& lineData = static_cast<const gfx::LineDrawableData&>(*data);
|
||||
const auto& dashPatternTexture = parameters.lineAtlas.getDashPatternTexture(
|
||||
evaluated.get<LineDasharray>().from, evaluated.get<LineDasharray>().to, lineData.linePatternCap);
|
||||
|
||||
// texture
|
||||
if (const auto shader = drawable.getShader()) {
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (!drawable.getTexture(index.value())) {
|
||||
const auto& texture = dashPatternTexture.getTexture();
|
||||
drawable.setEnabled(!!texture);
|
||||
if (texture) {
|
||||
drawable.setTexture(texture, index.value());
|
||||
}
|
||||
if (const auto index = shader->getSamplerLocation("u_image")) {
|
||||
if (!drawable.getTexture(index.value())) {
|
||||
const auto& texture = dashPatternTexture.getTexture();
|
||||
drawable.setEnabled(!!texture);
|
||||
if (texture) {
|
||||
drawable.setTexture(texture, index.value());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -257,7 +258,7 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const LinePatternPos& posB = dashPatternTexture.getTo();
|
||||
const float widthA = posA.width * crossfade.fromScale;
|
||||
const float widthB = posB.width * crossfade.toScale;
|
||||
LineSDFUBO lineSDFUBO{
|
||||
const LineSDFUBO lineSDFUBO{
|
||||
/* matrix = */ util::cast<float>(matrix),
|
||||
/* units_to_pixels = */
|
||||
{1.0f / parameters.pixelsToGLUnits[0], 1.0f / parameters.pixelsToGLUnits[1]},
|
||||
@@ -272,11 +273,10 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
/* sdfgamma = */ static_cast<float>(dashPatternTexture.getSize().width) /
|
||||
(std::min(widthA, widthB) * 256.0f * parameters.pixelRatio) / 2.0f,
|
||||
/* mix = */ crossfade.t};
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
LineSDFUBOName, &lineSDFUBO, sizeof(lineSDFUBO), parameters.context);
|
||||
uniforms.createOrUpdate(LineSDFUBOName, &lineSDFUBO, sizeof(lineSDFUBO), parameters.context);
|
||||
|
||||
// properties UBO
|
||||
drawable.mutableUniformBuffers().createOrUpdate(
|
||||
uniforms.createOrUpdate(
|
||||
LineSDFPropertiesUBOName, &lineSDFPropertiesUBO, sizeof(lineSDFPropertiesUBO), parameters.context);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
|
||||
layerGroup.observeDrawables([&](gfx::Drawable& drawable) {
|
||||
auto spinWeights = [](float spin) -> std::array<float, 4> {
|
||||
spin = util::deg2radf(spin);
|
||||
float s = std::sin(spin);
|
||||
float c = std::cos(spin);
|
||||
const float s = std::sin(spin);
|
||||
const float c = std::cos(spin);
|
||||
std::array<float, 4> spin_weights = {
|
||||
{(2 * c + 1) / 3, (-std::sqrt(3.0f) * s - c + 1) / 3, (std::sqrt(3.0f) * s - c + 1) / 3, 0}};
|
||||
return spin_weights;
|
||||
@@ -78,21 +78,22 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
|
||||
matrix = parameters.matrixForTile(tileID, !parameters.state.isChanging());
|
||||
}
|
||||
|
||||
RasterDrawableUBO drawableUBO{/*.matrix = */ util::cast<float>(matrix),
|
||||
/*.spin_weigths = */ spinWeights(evaluated.get<RasterHueRotate>()),
|
||||
/*.tl_parent = */ {{0.0f, 0.0f}},
|
||||
/*.scale_parent = */ 1.0f,
|
||||
/*.buffer_scale = */ 1.0f,
|
||||
/*.fade_t = */ 1.0f,
|
||||
/*.opacity = */ evaluated.get<RasterOpacity>(),
|
||||
/*.brightness_low = */ evaluated.get<RasterBrightnessMin>(),
|
||||
/*.brightness_high = */ evaluated.get<RasterBrightnessMax>(),
|
||||
/*.saturation_factor = */ saturationFactor(evaluated.get<RasterSaturation>()),
|
||||
/*.contrast_factor = */ contrastFactor(evaluated.get<RasterContrast>()),
|
||||
0,
|
||||
0};
|
||||
auto drawableUniformBuffer = parameters.context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
|
||||
drawable.mutableUniformBuffers().addOrReplace("RasterDrawableUBO", drawableUniformBuffer);
|
||||
const RasterDrawableUBO drawableUBO{
|
||||
/*.matrix = */ util::cast<float>(matrix),
|
||||
/*.spin_weigths = */ spinWeights(evaluated.get<RasterHueRotate>()),
|
||||
/*.tl_parent = */ {{0.0f, 0.0f}},
|
||||
/*.scale_parent = */ 1.0f,
|
||||
/*.buffer_scale = */ 1.0f,
|
||||
/*.fade_t = */ 1.0f,
|
||||
/*.opacity = */ evaluated.get<RasterOpacity>(),
|
||||
/*.brightness_low = */ evaluated.get<RasterBrightnessMin>(),
|
||||
/*.brightness_high = */ evaluated.get<RasterBrightnessMax>(),
|
||||
/*.saturation_factor = */ saturationFactor(evaluated.get<RasterSaturation>()),
|
||||
/*.contrast_factor = */ contrastFactor(evaluated.get<RasterContrast>()),
|
||||
0,
|
||||
0};
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate("RasterDrawableUBO", &drawableUBO, sizeof(drawableUBO), parameters.context);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -11,19 +11,40 @@
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/render_tile.hpp>
|
||||
#include <mbgl/renderer/tile_render_data.hpp>
|
||||
#include <mbgl/style/expression/image.hpp>
|
||||
#include <mbgl/style/layers/fill_extrusion_layer_impl.hpp>
|
||||
#include <mbgl/tile/geometry_tile.hpp>
|
||||
#include <mbgl/tile/tile.hpp>
|
||||
#include <mbgl/util/convert.hpp>
|
||||
#include <mbgl/util/intersection_tests.hpp>
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
#include <mbgl/renderer/layers/fill_extrusion_layer_tweaker.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
using namespace style;
|
||||
|
||||
namespace {
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
|
||||
constexpr std::string_view FillExtrusionShaderName = "FillExtrusionShader";
|
||||
constexpr std::string_view FillExtrusionPatternShaderName = "FillExtrusionPatternShader";
|
||||
|
||||
constexpr auto NormAttribName = "a_normal_ed";
|
||||
|
||||
constexpr auto IconTextureName = "u_image";
|
||||
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
inline const FillExtrusionLayer::Impl& impl_cast(const Immutable<style::Layer::Impl>& impl) {
|
||||
assert(impl->getTypeInfo() == FillExtrusionLayer::Impl::staticTypeInfo());
|
||||
return static_cast<const FillExtrusionLayer::Impl&>(*impl);
|
||||
@@ -51,6 +72,12 @@ void RenderFillExtrusionLayer::evaluate(const PropertyEvaluationParameters& para
|
||||
: RenderPass::None;
|
||||
properties->renderPasses = mbgl::underlying_type(passes);
|
||||
evaluatedProperties = std::move(properties);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
if (layerGroup) {
|
||||
layerGroup->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(evaluatedProperties));
|
||||
}
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
bool RenderFillExtrusionLayer::hasTransition() const {
|
||||
@@ -65,6 +92,14 @@ bool RenderFillExtrusionLayer::is3D() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderFillExtrusionLayer::prepare(const LayerPrepareParameters& params) {
|
||||
RenderLayer::prepare(params);
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
}
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
assert(renderTiles);
|
||||
@@ -128,7 +163,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||
const auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||
draw(*fillExtrusionProgram,
|
||||
evaluated,
|
||||
crossfade,
|
||||
@@ -176,9 +211,11 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
if (!renderData) {
|
||||
continue;
|
||||
}
|
||||
auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||
std::optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||
std::optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||
const auto& bucket = static_cast<FillExtrusionBucket&>(*renderData->bucket);
|
||||
const std::optional<ImagePosition> patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||
const std::optional<ImagePosition> patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||
const auto numTiles = std::pow(2, tile.id.canonical.z);
|
||||
const auto heightFactor = static_cast<float>(-numTiles / util::tileSize_D / 8.0);
|
||||
|
||||
draw(*fillExtrusionPatternProgram,
|
||||
evaluated,
|
||||
@@ -195,7 +232,7 @@ void RenderFillExtrusionLayer::render(PaintParameters& parameters) {
|
||||
tile.id,
|
||||
parameters.state,
|
||||
evaluated.get<FillExtrusionOpacity>(),
|
||||
static_cast<float>(-std::pow(2, tile.id.canonical.z) / util::tileSize_D / 8.0),
|
||||
heightFactor,
|
||||
parameters.pixelRatio,
|
||||
parameters.evaluatedLight,
|
||||
evaluated.get<FillExtrusionVerticalGradient>()),
|
||||
@@ -241,4 +278,247 @@ bool RenderFillExtrusionLayer::queryIntersectsFeature(const GeometryCoordinates&
|
||||
feature.getGeometries());
|
||||
}
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
|
||||
void RenderFillExtrusionLayer::update(gfx::ShaderRegistry& shaders,
|
||||
gfx::Context& context,
|
||||
const TransformState& state,
|
||||
const RenderTree& /*renderTree*/,
|
||||
UniqueChangeRequestVec& changes) {
|
||||
if (!renderTiles || renderTiles->empty() || passes == RenderPass::None) {
|
||||
removeAllDrawables();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up a layer group
|
||||
if (!layerGroup) {
|
||||
if (auto layerGroup_ = context.createTileLayerGroup(layerIndex, /*initialCapacity=*/64, getID())) {
|
||||
layerGroup_->setLayerTweaker(std::make_shared<FillExtrusionLayerTweaker>(evaluatedProperties));
|
||||
setLayerGroup(std::move(layerGroup_), changes);
|
||||
}
|
||||
}
|
||||
|
||||
if (!fillExtrusionGroup) {
|
||||
fillExtrusionGroup = shaders.getShaderGroup(std::string(FillExtrusionShaderName));
|
||||
}
|
||||
if (!fillExtrusionPatternGroup) {
|
||||
fillExtrusionPatternGroup = shaders.getShaderGroup(std::string(FillExtrusionPatternShaderName));
|
||||
}
|
||||
|
||||
auto* tileLayerGroup = static_cast<TileLayerGroup*>(layerGroup.get());
|
||||
|
||||
const auto& evaluated = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).evaluated;
|
||||
const auto& crossfade = static_cast<const FillExtrusionLayerProperties&>(*evaluatedProperties).crossfade;
|
||||
|
||||
// `passes` is set to (RenderPass::Translucent | RenderPass::Pass3D), but `render()`
|
||||
// only runs on the translucent pass, so although our output is 3D, it does not render
|
||||
// in the "3D pass".
|
||||
constexpr auto drawPass = RenderPass::Translucent;
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
// If the render pass has changed or the tile has dropped out of the cover set, remove it.
|
||||
const auto tileID = drawable->getTileID();
|
||||
if (drawable->getRenderPass() != drawPass || (tileID && renderTileIDs.find(*tileID) == renderTileIDs.end())) {
|
||||
drawable.reset();
|
||||
++stats.drawablesRemoved;
|
||||
}
|
||||
});
|
||||
|
||||
const auto zoom = static_cast<float>(state.getZoom());
|
||||
const auto layerPrefix = getID() + "/";
|
||||
const auto hasPattern = !unevaluated.get<FillExtrusionPattern>().isUndefined();
|
||||
const auto opaque = evaluated.get<FillExtrusionOpacity>() >= 1;
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> depthBuilder;
|
||||
std::unique_ptr<gfx::DrawableBuilder> colorBuilder;
|
||||
gfx::VertexAttributeArray vertexAttrs;
|
||||
std::vector<uint8_t> rawVertices;
|
||||
|
||||
const auto& shaderGroup = hasPattern ? fillExtrusionPatternGroup : fillExtrusionGroup;
|
||||
if (!shaderGroup) {
|
||||
removeAllDrawables();
|
||||
return;
|
||||
}
|
||||
|
||||
for (const RenderTile& tile : *renderTiles) {
|
||||
const auto& tileID = tile.getOverscaledTileID();
|
||||
|
||||
const auto* optRenderData = getRenderDataForPass(tile, passes);
|
||||
if (!optRenderData || !optRenderData->bucket) {
|
||||
removeTile(drawPass, tileID);
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto& renderData = *optRenderData;
|
||||
const auto& bucket = static_cast<const FillExtrusionBucket&>(*renderData.bucket);
|
||||
|
||||
vertexAttrs.clear();
|
||||
|
||||
gfx::DrawableTweakerPtr tweaker;
|
||||
if (depthBuilder) {
|
||||
depthBuilder->clearTweakers();
|
||||
}
|
||||
if (colorBuilder) {
|
||||
colorBuilder->clearTweakers();
|
||||
}
|
||||
|
||||
const auto vertexCount = bucket.vertices.elements();
|
||||
constexpr auto vertexSize = sizeof(FillExtrusionLayoutVertex::a1);
|
||||
|
||||
const auto defPattern = mbgl::Faded<expression::Image>{"", ""};
|
||||
const auto fillPatternValue = evaluated.get<FillExtrusionPattern>().constantOr(defPattern);
|
||||
const auto patternPosA = tile.getPattern(fillPatternValue.from.id());
|
||||
const auto patternPosB = tile.getPattern(fillPatternValue.to.id());
|
||||
|
||||
const auto& binders = bucket.paintPropertyBinders.at(getID());
|
||||
if (hasPattern) {
|
||||
binders.setPatternParameters(patternPosA, patternPosB, crossfade);
|
||||
}
|
||||
|
||||
const FillExtrusionInterpolateUBO interpUBO = {
|
||||
/* .base_t = */ std::get<0>(binders.get<FillExtrusionBase>()->interpolationFactor(zoom)),
|
||||
/* .height_t = */ std::get<0>(binders.get<FillExtrusionHeight>()->interpolationFactor(zoom)),
|
||||
/* .color_t = */ std::get<0>(binders.get<FillExtrusionColor>()->interpolationFactor(zoom)),
|
||||
/* .pattern_from_t = */ std::get<0>(binders.get<FillExtrusionPattern>()->interpolationFactor(zoom)),
|
||||
/* .pattern_to_t = */ std::get<0>(binders.get<FillExtrusionPattern>()->interpolationFactor(zoom)),
|
||||
/* .pad = */ 0,
|
||||
0,
|
||||
0};
|
||||
|
||||
const FillExtrusionDrawableTilePropsUBO tilePropsUBO = {
|
||||
/* pattern_from = */ patternPosA ? util::cast<float>(patternPosA->tlbr()) : std::array<float, 4>{0},
|
||||
/* pattern_to = */ patternPosB ? util::cast<float>(patternPosB->tlbr()) : std::array<float, 4>{0},
|
||||
};
|
||||
|
||||
// If we already have drawables for this tile, update them.
|
||||
if (tileLayerGroup->getDrawableCount(drawPass, tileID) > 0) {
|
||||
// Just update the drawables we already created
|
||||
tileLayerGroup->observeDrawables(drawPass, tileID, [&](gfx::Drawable& drawable) {
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(
|
||||
FillExtrusionLayerTweaker::FillExtrusionTilePropsUBOName, &tilePropsUBO, context);
|
||||
uniforms.createOrUpdate(
|
||||
FillExtrusionLayerTweaker::FillExtrusionInterpolateUBOName, &interpUBO, context);
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto uniformProps = vertexAttrs.readDataDrivenPaintProperties<FillExtrusionBase,
|
||||
FillExtrusionColor,
|
||||
FillExtrusionHeight,
|
||||
FillExtrusionPattern>(binders, evaluated);
|
||||
|
||||
const auto shader = std::static_pointer_cast<gfx::ShaderProgramBase>(
|
||||
shaderGroup->getOrCreateShader(context, uniformProps));
|
||||
if (!shader) {
|
||||
assert(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
// The non-pattern path in `render()` only uses two-pass rendering if there's translucency.
|
||||
// The pattern path always uses two passes.
|
||||
const auto doDepthPass = (!opaque || hasPattern);
|
||||
|
||||
if (doDepthPass && !depthBuilder) {
|
||||
if (auto builder = context.createDrawableBuilder(layerPrefix + "depth")) {
|
||||
builder->setShader(shader);
|
||||
builder->setIs3D(true);
|
||||
builder->setEnableStencil(false);
|
||||
builder->setEnableColor(false);
|
||||
builder->setRenderPass(drawPass);
|
||||
builder->setCullFaceMode(gfx::CullFaceMode::backCCW());
|
||||
if (tweaker) {
|
||||
builder->addTweaker(tweaker);
|
||||
}
|
||||
depthBuilder = std::move(builder);
|
||||
}
|
||||
}
|
||||
if (!colorBuilder) {
|
||||
if (auto builder = context.createDrawableBuilder(layerPrefix + "color")) {
|
||||
builder->setShader(shader);
|
||||
builder->setIs3D(true);
|
||||
builder->setEnableColor(true);
|
||||
builder->setColorMode(gfx::ColorMode::alphaBlended());
|
||||
builder->setRenderPass(drawPass);
|
||||
builder->setCullFaceMode(gfx::CullFaceMode::backCCW());
|
||||
if (tweaker) {
|
||||
builder->addTweaker(tweaker);
|
||||
}
|
||||
colorBuilder = std::move(builder);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasPattern && !tweaker) {
|
||||
if (const auto& atlases = tile.getAtlasTextures()) {
|
||||
tweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
||||
std::string(),
|
||||
std::string(IconTextureName),
|
||||
/*isText=*/false);
|
||||
if (depthBuilder) {
|
||||
depthBuilder->addTweaker(tweaker);
|
||||
}
|
||||
if (colorBuilder) {
|
||||
colorBuilder->addTweaker(tweaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (const auto& attr = vertexAttrs.getOrAdd(NormAttribName)) {
|
||||
const auto count = bucket.vertices.elements();
|
||||
attr->reserve(count);
|
||||
for (auto i = 0ULL; i < count; ++i) {
|
||||
attr->set(i, util::cast<float>(bucket.vertices.at(i).a2)); // int16_t x4
|
||||
}
|
||||
}
|
||||
|
||||
rawVertices.resize(vertexSize * vertexCount);
|
||||
for (std::size_t i = 0; i < vertexCount; ++i) {
|
||||
std::memcpy(&rawVertices[vertexSize * i], &bucket.vertices.at(i).a1, vertexSize);
|
||||
}
|
||||
|
||||
colorBuilder->setEnableStencil(doDepthPass);
|
||||
if (doDepthPass) {
|
||||
auto vertexCopy = rawVertices;
|
||||
depthBuilder->setRawVertices(std::move(vertexCopy), vertexCount, gfx::AttributeDataType::Short2);
|
||||
}
|
||||
colorBuilder->setRawVertices(std::move(rawVertices), vertexCount, gfx::AttributeDataType::Short2);
|
||||
|
||||
if (doDepthPass) {
|
||||
gfx::VertexAttributeArray attribCopy;
|
||||
attribCopy.copy(vertexAttrs);
|
||||
depthBuilder->setVertexAttributes(std::move(attribCopy));
|
||||
}
|
||||
colorBuilder->setVertexAttributes(std::move(vertexAttrs));
|
||||
|
||||
const auto finish = [&](gfx::DrawableBuilder& builder) {
|
||||
builder.setSegments(gfx::Triangles(),
|
||||
bucket.triangles.vector(),
|
||||
bucket.triangleSegments.data(),
|
||||
bucket.triangleSegments.size());
|
||||
|
||||
builder.flush();
|
||||
|
||||
for (auto& drawable : builder.clearDrawables()) {
|
||||
drawable->setTileID(tileID);
|
||||
|
||||
auto& uniforms = drawable->mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(
|
||||
FillExtrusionLayerTweaker::FillExtrusionTilePropsUBOName, &tilePropsUBO, context);
|
||||
uniforms.createOrUpdate(
|
||||
FillExtrusionLayerTweaker::FillExtrusionInterpolateUBOName, &interpUBO, context);
|
||||
|
||||
tileLayerGroup->addDrawable(drawPass, tileID, std::move(drawable));
|
||||
++stats.drawablesAdded;
|
||||
}
|
||||
};
|
||||
|
||||
if (doDepthPass) {
|
||||
finish(*depthBuilder);
|
||||
}
|
||||
finish(*colorBuilder);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
} // namespace mbgl
|
||||
|
||||
@@ -7,8 +7,10 @@
|
||||
|
||||
namespace mbgl {
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
class FillExtrusionProgram;
|
||||
class FillExtrusionPatternProgram;
|
||||
#endif // MLN_LEGACY_RENDERER
|
||||
|
||||
class RenderFillExtrusionLayer final : public RenderLayer {
|
||||
public:
|
||||
@@ -21,11 +23,21 @@ private:
|
||||
bool hasTransition() const override;
|
||||
bool hasCrossfade() const override;
|
||||
bool is3D() const override;
|
||||
void prepare(const LayerPrepareParameters&) override;
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
void render(PaintParameters&) override;
|
||||
#endif
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
/// Generate any changes needed by the layer
|
||||
void update(gfx::ShaderRegistry&,
|
||||
gfx::Context&,
|
||||
const TransformState&,
|
||||
const RenderTree&,
|
||||
UniqueChangeRequestVec&) override;
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
bool queryIntersectsFeature(const GeometryCoordinates&,
|
||||
const GeometryTileFeature&,
|
||||
float,
|
||||
@@ -43,6 +55,11 @@ private:
|
||||
std::shared_ptr<FillExtrusionPatternProgram> fillExtrusionPatternProgram;
|
||||
#endif
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
gfx::ShaderGroupPtr fillExtrusionGroup;
|
||||
gfx::ShaderGroupPtr fillExtrusionPatternGroup;
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
std::unique_ptr<gfx::OffscreenTexture> renderTexture;
|
||||
};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <mbgl/util/std.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/renderer/layers/fill_layer_tweaker.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
@@ -36,10 +37,12 @@ using namespace style;
|
||||
namespace {
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
constexpr std::string_view FillShaderName = "FillShader";
|
||||
constexpr std::string_view FillOutlineShaderName = "FillOutlineShader";
|
||||
constexpr std::string_view FillPatternShaderName = "FillPatternShader";
|
||||
constexpr std::string_view FillOutlinePatternShaderName = "FillOutlinePatternShader";
|
||||
constexpr auto FillShaderName = "FillShader";
|
||||
constexpr auto FillOutlineShaderName = "FillOutlineShader";
|
||||
constexpr auto FillPatternShaderName = "FillPatternShader";
|
||||
constexpr auto FillOutlinePatternShaderName = "FillOutlinePatternShader";
|
||||
|
||||
constexpr auto IconTextureName = "u_image";
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
inline const FillLayer::Impl& impl_cast(const Immutable<style::Layer::Impl>& impl) {
|
||||
@@ -358,7 +361,7 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
const auto commonInit = [&](gfx::DrawableBuilder& builder) {
|
||||
builder.setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||
builder.setNeedsStencil(true);
|
||||
builder.setEnableStencil(true);
|
||||
};
|
||||
|
||||
tileLayerGroup->observeDrawables([&](gfx::UniqueDrawable& drawable) {
|
||||
@@ -396,10 +399,10 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
/* .opacity_t = */ std::get<0>(binders.get<FillOpacity>()->interpolationFactor(zoom)),
|
||||
/* .outline_color_t = */ std::get<0>(binders.get<FillOutlineColor>()->interpolationFactor(zoom)),
|
||||
/* .pattern_from_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
|
||||
/* .pattern_to_t = */ std::get<0>(binders.get<FillColor>()->interpolationFactor(zoom)),
|
||||
/* .pattern_to_t = */ std::get<0>(binders.get<FillPattern>()->interpolationFactor(zoom)),
|
||||
/* .fade = */ crossfade.t,
|
||||
/* .padding = */ {0},
|
||||
};
|
||||
/* .padding = */ 0,
|
||||
0};
|
||||
|
||||
// TODO: only update if properties re-evaluated?
|
||||
const FillDrawableTilePropsUBO tileProps = {
|
||||
@@ -432,6 +435,14 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
fillVertexAttrs.clear();
|
||||
outlineVertexAttrs.clear();
|
||||
|
||||
gfx::DrawableTweakerPtr tweaker;
|
||||
if (fillBuilder) {
|
||||
fillBuilder->clearTweakers();
|
||||
}
|
||||
if (outlineBuilder) {
|
||||
outlineBuilder->clearTweakers();
|
||||
}
|
||||
|
||||
// `Fill*Program` all use `style::FillPaintProperties`
|
||||
const auto fillUniformProps =
|
||||
fillVertexAttrs.readDataDrivenPaintProperties<FillColor, FillOpacity, FillOutlineColor, FillPattern>(
|
||||
@@ -518,6 +529,9 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder->setColorMode(gfx::ColorMode::alphaBlended());
|
||||
builder->setSubLayerIndex(1);
|
||||
builder->setRenderPass(RenderPass::Translucent);
|
||||
if (tweaker) {
|
||||
builder->addTweaker(tweaker);
|
||||
}
|
||||
patternBuilder = std::move(builder);
|
||||
}
|
||||
}
|
||||
@@ -529,10 +543,28 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder->setColorMode(gfx::ColorMode::alphaBlended());
|
||||
builder->setSubLayerIndex(2);
|
||||
builder->setRenderPass(RenderPass::Translucent);
|
||||
if (tweaker) {
|
||||
builder->addTweaker(tweaker);
|
||||
}
|
||||
outlinePatternBuilder = std::move(builder);
|
||||
}
|
||||
}
|
||||
|
||||
if ((patternBuilder || outlineBuilder) && !tweaker) {
|
||||
if (const auto& atlases = tile.getAtlasTextures()) {
|
||||
tweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(atlases,
|
||||
/*glyphName=*/std::string(),
|
||||
std::string(IconTextureName),
|
||||
/*isText=*/false);
|
||||
if (patternBuilder) {
|
||||
patternBuilder->addTweaker(tweaker);
|
||||
}
|
||||
if (outlineBuilder) {
|
||||
outlineBuilder->addTweaker(tweaker);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (patternBuilder) {
|
||||
buildVertices();
|
||||
patternBuilder->setShader(fillShader);
|
||||
@@ -544,14 +576,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
bucket.triangleSegments.data(),
|
||||
bucket.triangleSegments.size());
|
||||
|
||||
if (const auto& atlases = tile.getAtlasTextures()) {
|
||||
if (const auto samplerLocation = fillShader->getSamplerLocation("u_image")) {
|
||||
patternBuilder->setTextureSource([=]() {
|
||||
return gfx::Drawable::Textures{{*samplerLocation, atlases->icon}};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
finish(*patternBuilder, tileID, interpolateUBO, tileProps);
|
||||
}
|
||||
if (outlinePatternBuilder) {
|
||||
@@ -563,14 +587,6 @@ void RenderFillLayer::update(gfx::ShaderRegistry& shaders,
|
||||
outlinePatternBuilder->setSegments(
|
||||
gfx::Lines(2), bucket.lines.vector(), bucket.lineSegments.data(), bucket.lineSegments.size());
|
||||
|
||||
if (const auto& atlases = tile.getAtlasTextures()) {
|
||||
if (const auto samplerLocation = outlineShader->getSamplerLocation("u_image")) {
|
||||
outlinePatternBuilder->setTextureSource([=]() {
|
||||
return gfx::Drawable::Textures{{*samplerLocation, atlases->icon}};
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
finish(*outlinePatternBuilder, tileID, interpolateUBO, tileProps);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -469,7 +469,7 @@ void RenderLineLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder->setColorMode(renderPass == RenderPass::Translucent ? gfx::ColorMode::alphaBlended()
|
||||
: gfx::ColorMode::unblended());
|
||||
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||
builder->setNeedsStencil(true);
|
||||
builder->setEnableStencil(true);
|
||||
builder->setVertexAttrName("a_pos_normal");
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <mbgl/util/math.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/drawable_atlases_tweaker.hpp>
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/gfx/symbol_drawable_data.hpp>
|
||||
#include <mbgl/renderer/layer_group.hpp>
|
||||
@@ -662,12 +663,7 @@ void RenderSymbolLayer::prepare(const LayerPrepareParameters& params) {
|
||||
renderTiles = params.source->getRenderTilesSortedByYPosition();
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
renderTileIDs.clear();
|
||||
renderTileIDs.reserve(renderTiles->size());
|
||||
std::transform(renderTiles->begin(),
|
||||
renderTiles->end(),
|
||||
std::inserter(renderTileIDs, renderTileIDs.end()),
|
||||
[](const auto& tile) { return tile.get().getOverscaledTileID(); });
|
||||
updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
addRenderPassesFromTiles();
|
||||
@@ -899,11 +895,14 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
addRenderables(bucket.text, SymbolType::Text);
|
||||
}
|
||||
|
||||
// We'll be processing renderables across tiles, potentially out-of-order, so keep
|
||||
// track of some things by tile ID so we don't have to re-build them multiple times.
|
||||
using RawVertexVec = std::vector<std::uint8_t>; // <int16_t, 4>
|
||||
struct RawVertices {
|
||||
RawVertexVec text, icon;
|
||||
struct TileInfo {
|
||||
RawVertexVec textVertices, iconVertices;
|
||||
gfx::DrawableTweakerPtr textTweaker, iconTweaker;
|
||||
};
|
||||
std::unordered_map<UnwrappedTileID, RawVertices> rawVertices;
|
||||
std::unordered_map<UnwrappedTileID, TileInfo> tileCache;
|
||||
|
||||
for (auto& renderable : renderableSegments) {
|
||||
const auto isText = (renderable.type == SymbolType::Text);
|
||||
@@ -920,6 +919,14 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
const auto& layout = *bucket.layout;
|
||||
const auto values = isText ? textPropertyValues(evaluated, layout) : iconPropertyValues(evaluated, layout);
|
||||
|
||||
const auto& atlases = tile.getAtlasTextures();
|
||||
if (!atlases) {
|
||||
assert(false);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& tileInfo = tileCache[tile.id];
|
||||
|
||||
const auto buildVertices = [&](const SymbolBucket::Buffer& buffer_, RawVertexVec& dest) -> auto& {
|
||||
const std::vector<SymbolLayoutVertex>& src = buffer_.vertices.vector();
|
||||
const auto vertSize = sizeof(SymbolLayoutVertex::a1);
|
||||
@@ -985,6 +992,10 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
|
||||
const auto interpolateUBO = buildInterpUBO(bucketPaintProperties, isText, currentZoom);
|
||||
|
||||
if (builder) {
|
||||
builder->clearTweakers();
|
||||
}
|
||||
|
||||
const auto draw = [&](const gfx::ShaderGroupPtr& shaderGroup,
|
||||
const Segment<SymbolTextAttributes>& segment,
|
||||
const gfx::IndexVector<gfx::Triangles>& indices,
|
||||
@@ -996,10 +1007,20 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
return;
|
||||
}
|
||||
|
||||
// We can use the same tweakers for all the segments in a tile
|
||||
if (isText && !tileInfo.textTweaker) {
|
||||
tileInfo.textTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(
|
||||
atlases, iconTexUniformName, texUniformName, isText);
|
||||
}
|
||||
if (!isText && !tileInfo.iconTweaker) {
|
||||
tileInfo.iconTweaker = std::make_shared<gfx::DrawableAtlasesTweaker>(
|
||||
atlases, iconTexUniformName, texUniformName, isText);
|
||||
}
|
||||
|
||||
if (!builder) {
|
||||
builder = context.createDrawableBuilder(layerPrefix);
|
||||
builder->setSubLayerIndex(0);
|
||||
builder->setNeedsStencil(false);
|
||||
builder->setEnableStencil(false);
|
||||
builder->setRenderPass(passes);
|
||||
builder->setCullFaceMode(gfx::CullFaceMode::disabled());
|
||||
builder->setDepthType(gfx::DepthMaskType::ReadOnly);
|
||||
@@ -1008,6 +1029,9 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
builder->setVertexAttrName(posOffsetAttribName);
|
||||
}
|
||||
|
||||
builder->clearTweakers();
|
||||
builder->addTweaker(isText ? tileInfo.textTweaker : tileInfo.iconTweaker);
|
||||
|
||||
builder->setDrawableName(layerPrefix + std::string(suffix));
|
||||
builder->setVertexAttributes(std::move(attrs));
|
||||
|
||||
@@ -1023,21 +1047,6 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
// !partiallyEvaluatedTextSize.isZoomConstant; const auto filterType = linear ?
|
||||
// gfx::TextureFilterType::Linear : gfx::TextureFilterType::Nearest;
|
||||
|
||||
if (const auto& atlases = tile.getAtlasTextures()) {
|
||||
if (const auto texSamplerLocation = shader->getSamplerLocation(texUniformName)) {
|
||||
if (const auto iconSamplerLocation = shader->getSamplerLocation(iconTexUniformName)) {
|
||||
assert(*texSamplerLocation != *iconSamplerLocation);
|
||||
builder->setTextureSource([=]() -> gfx::Drawable::Textures {
|
||||
return {{*texSamplerLocation, atlases->glyph}, {*iconSamplerLocation, atlases->icon}};
|
||||
});
|
||||
} else {
|
||||
builder->setTextureSource([=]() -> gfx::Drawable::Textures {
|
||||
return {{*texSamplerLocation, isText ? atlases->glyph : atlases->icon}};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto raw = vertices;
|
||||
builder->setRawVertices(std::move(raw), vertexCount, gfx::AttributeDataType::Short4);
|
||||
builder->setSegments(gfx::Triangles(), indices.vector(), &segment, 1);
|
||||
@@ -1069,7 +1078,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
};
|
||||
|
||||
if (isText) {
|
||||
const auto& vertices = buildVertices(buffer, rawVertices[tile.id].text);
|
||||
const auto& vertices = buildVertices(buffer, tileInfo.textVertices);
|
||||
const auto vertexCount = buffer.vertices.elements();
|
||||
const auto& indices = buffer.triangles;
|
||||
if (bucket.iconsInText) {
|
||||
@@ -1114,7 +1123,7 @@ void RenderSymbolLayer::update(gfx::ShaderRegistry& shaders,
|
||||
}
|
||||
}
|
||||
} else { // icons
|
||||
const auto& vertices = buildVertices(buffer, rawVertices[tile.id].icon);
|
||||
const auto& vertices = buildVertices(buffer, tileInfo.iconVertices);
|
||||
const auto vertexCount = buffer.vertices.elements();
|
||||
const auto& indices = buffer.triangles;
|
||||
if (sdfIcons) {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include <mbgl/style/layers/symbol_layer_properties.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
namespace mbgl {
|
||||
@@ -126,7 +126,6 @@ private:
|
||||
gfx::ShaderGroupPtr symbolSDFTextGroup;
|
||||
gfx::ShaderGroupPtr symbolTextAndIconGroup;
|
||||
|
||||
std::unordered_set<OverscaledTileID> renderTileIDs;
|
||||
std::unordered_map<OverscaledTileID, uint32_t> tileBucketInstances;
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
};
|
||||
|
||||
@@ -78,6 +78,21 @@ auto constOrDefault(const IndexedTuple<TypeList<Is...>, TypeList<Ts...>>& evalua
|
||||
return evaluated.template get<T>().constantOr(T::defaultValue());
|
||||
}
|
||||
|
||||
SymbolDrawablePaintUBO buildPaintUBO(bool isText, const SymbolPaintProperties::PossiblyEvaluated& evaluated) {
|
||||
return {
|
||||
/*.fill_color=*/gfx::Drawable::colorAttrRGBA(isText ? constOrDefault<TextColor>(evaluated)
|
||||
: constOrDefault<IconColor>(evaluated)),
|
||||
/*.halo_color=*/
|
||||
gfx::Drawable::colorAttrRGBA(isText ? constOrDefault<TextHaloColor>(evaluated)
|
||||
: constOrDefault<IconHaloColor>(evaluated)),
|
||||
/*.opacity=*/isText ? constOrDefault<TextOpacity>(evaluated) : constOrDefault<IconOpacity>(evaluated),
|
||||
/*.halo_width=*/
|
||||
isText ? constOrDefault<TextHaloWidth>(evaluated) : constOrDefault<IconHaloWidth>(evaluated),
|
||||
/*.halo_blur=*/isText ? constOrDefault<TextHaloBlur>(evaluated) : constOrDefault<IconHaloBlur>(evaluated),
|
||||
/*.padding=*/0,
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
@@ -104,25 +119,24 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
const auto tileID = drawable.getTileID()->toUnwrapped();
|
||||
const auto& symbolData = static_cast<gfx::SymbolDrawableData&>(*drawable.getData());
|
||||
const auto isText = (symbolData.symbolType == SymbolType::Text);
|
||||
const SymbolDrawablePaintUBO paintUBO = {
|
||||
/*.fill_color=*/gfx::Drawable::colorAttrRGBA(isText ? constOrDefault<TextColor>(evaluated)
|
||||
: constOrDefault<IconColor>(evaluated)),
|
||||
/*.halo_color=*/
|
||||
gfx::Drawable::colorAttrRGBA(isText ? constOrDefault<TextHaloColor>(evaluated)
|
||||
: constOrDefault<IconHaloColor>(evaluated)),
|
||||
/*.opacity=*/isText ? constOrDefault<TextOpacity>(evaluated) : constOrDefault<IconOpacity>(evaluated),
|
||||
/*.halo_width=*/
|
||||
isText ? constOrDefault<TextHaloWidth>(evaluated) : constOrDefault<IconHaloWidth>(evaluated),
|
||||
/*.halo_blur=*/isText ? constOrDefault<TextHaloBlur>(evaluated) : constOrDefault<IconHaloBlur>(evaluated),
|
||||
/*.padding=*/0,
|
||||
};
|
||||
|
||||
if (isText && !textPaintBuffer) {
|
||||
auto props = buildPaintUBO(true, evaluated);
|
||||
textPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
|
||||
}
|
||||
if (!isText && !iconPaintBuffer) {
|
||||
auto props = buildPaintUBO(false, evaluated);
|
||||
iconPaintBuffer = parameters.context.createUniformBuffer(&props, sizeof(props));
|
||||
}
|
||||
|
||||
// from RenderTile::translatedMatrix
|
||||
const auto translate = isText ? evaluated.get<style::TextTranslate>() : evaluated.get<style::IconTranslate>();
|
||||
const auto anchor = isText ? evaluated.get<style::TextTranslateAnchor>()
|
||||
: evaluated.get<style::IconTranslateAnchor>();
|
||||
constexpr bool nearClipped = false;
|
||||
constexpr bool inViewportPixelUnits = false;
|
||||
const auto matrix = getTileMatrix(tileID, renderTree, state, translate, anchor, inViewportPixelUnits);
|
||||
const auto matrix = getTileMatrix(
|
||||
tileID, renderTree, state, translate, anchor, nearClipped, inViewportPixelUnits);
|
||||
|
||||
// from symbol_program, makeValues
|
||||
const auto currentZoom = static_cast<float>(state.getZoom());
|
||||
@@ -169,8 +183,8 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup,
|
||||
};
|
||||
|
||||
auto& uniforms = drawable.mutableUniformBuffers();
|
||||
uniforms.createOrUpdate(SymbolDrawablePaintUBOName, &paintUBO, context);
|
||||
uniforms.createOrUpdate(SymbolDrawableUBOName, &drawableUBO, context);
|
||||
uniforms.addOrReplace(SymbolDrawablePaintUBOName, isText ? textPaintBuffer : iconPaintBuffer);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,8 @@ public:
|
||||
static constexpr std::string_view SymbolDrawableInterpolateUBOName = "SymbolDrawableInterpolateUBO";
|
||||
|
||||
private:
|
||||
gfx::UniformBufferPtr textPaintBuffer;
|
||||
gfx::UniformBufferPtr iconPaintBuffer;
|
||||
};
|
||||
|
||||
/// Evaluated properties that depend on the tile
|
||||
|
||||
@@ -96,14 +96,17 @@ public:
|
||||
public:
|
||||
void renderTileClippingMasks(const RenderTiles&);
|
||||
void renderTileClippingMasks(const std::set<UnwrappedTileID>&);
|
||||
|
||||
/// Clear any tile masks and the stencil buffer, if necessary
|
||||
void clearTileClippingMasks();
|
||||
|
||||
/// Clear the stencil buffer, even if there are no tile masks (for 3D)
|
||||
void clearStencil();
|
||||
|
||||
gfx::StencilMode stencilModeForClipping(const UnwrappedTileID&) const;
|
||||
gfx::StencilMode stencilModeFor3D();
|
||||
|
||||
private:
|
||||
void clearStencil();
|
||||
|
||||
template <typename TIter>
|
||||
using GetTileIDFunc = std::function<const UnwrappedTileID&(const typename TIter::value_type&)>;
|
||||
template <typename TIter>
|
||||
|
||||
@@ -144,6 +144,18 @@ void RenderLayer::removeAllDrawables() {
|
||||
}
|
||||
}
|
||||
|
||||
void RenderLayer::updateRenderTileIDs() {
|
||||
renderTileIDs.clear();
|
||||
if (renderTiles) {
|
||||
const auto inserter = std::inserter(renderTileIDs, renderTileIDs.end());
|
||||
const auto getID = [](const auto& tile) {
|
||||
return tile.get().getOverscaledTileID();
|
||||
};
|
||||
renderTileIDs.reserve(renderTiles->size());
|
||||
std::transform(renderTiles->begin(), renderTiles->end(), inserter, getID);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderLayer::layerIndexChanged(int32_t newLayerIndex, UniqueChangeRequestVec& changes) {
|
||||
layerIndex = newLayerIndex;
|
||||
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
#pragma once
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/renderer/change_request.hpp>
|
||||
#endif
|
||||
#include <mbgl/layout/layout.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/renderer/render_source.hpp>
|
||||
@@ -10,6 +6,13 @@
|
||||
#include <mbgl/tile/geometry_tile_data.hpp>
|
||||
#include <mbgl/util/mat4.hpp>
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/renderer/change_request.hpp>
|
||||
|
||||
#include <unordered_set>
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
@@ -201,7 +204,10 @@ protected:
|
||||
|
||||
/// Remove all the drawables for tiles
|
||||
virtual void removeAllDrawables();
|
||||
#endif
|
||||
|
||||
// Update `renderTileIDs` from `renderTiles`
|
||||
void updateRenderTileIDs();
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
protected:
|
||||
// Stores current set of tiles to be rendered for this layer.
|
||||
@@ -216,6 +222,9 @@ protected:
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
// will need to be overriden to handle their activation.
|
||||
LayerGroupBasePtr layerGroup;
|
||||
|
||||
// The set of Tile IDs in `renderTiles`
|
||||
std::unordered_set<OverscaledTileID> renderTileIDs;
|
||||
#endif
|
||||
// Current layer index as specified by the layerIndexChanged event
|
||||
int32_t layerIndex{0};
|
||||
|
||||
@@ -153,21 +153,40 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Renders any 3D layers bottom-to-top to unique FBOs with texture
|
||||
// attachments, but share the same depth rbo between them.
|
||||
if (parameters.staticData.has3D) {
|
||||
parameters.staticData.backendSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
const auto common3DPass = [&] {
|
||||
if (parameters.staticData.has3D) {
|
||||
parameters.staticData.backendSize = parameters.backend.getDefaultRenderable().getSize();
|
||||
|
||||
const auto debugGroup(parameters.encoder->createDebugGroup("3d"));
|
||||
parameters.pass = RenderPass::Pass3D;
|
||||
const auto debugGroup(parameters.encoder->createDebugGroup("common-3d"));
|
||||
parameters.pass = RenderPass::Pass3D;
|
||||
|
||||
if (!parameters.staticData.depthRenderbuffer ||
|
||||
parameters.staticData.depthRenderbuffer->getSize() != parameters.staticData.backendSize) {
|
||||
parameters.staticData.depthRenderbuffer =
|
||||
parameters.context.createRenderbuffer<gfx::RenderbufferPixelType::Depth>(
|
||||
parameters.staticData.backendSize);
|
||||
if (!parameters.staticData.depthRenderbuffer ||
|
||||
parameters.staticData.depthRenderbuffer->getSize() != parameters.staticData.backendSize) {
|
||||
parameters.staticData.depthRenderbuffer =
|
||||
parameters.context.createRenderbuffer<gfx::RenderbufferPixelType::Depth>(
|
||||
parameters.staticData.backendSize);
|
||||
}
|
||||
parameters.staticData.depthRenderbuffer->setShouldClear(true);
|
||||
}
|
||||
parameters.staticData.depthRenderbuffer->setShouldClear(true);
|
||||
};
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
const auto drawable3DPass = [&] {
|
||||
const auto debugGroup(parameters.encoder->createDebugGroup("drawables-3d"));
|
||||
assert(parameters.pass == RenderPass::Pass3D);
|
||||
parameters.currentLayer = 0;
|
||||
|
||||
// draw layer groups, opaque pass
|
||||
orchestrator.observeLayerGroups([&](LayerGroupBase& layerGroup) {
|
||||
layerGroup.render(orchestrator, parameters);
|
||||
parameters.currentLayer++;
|
||||
});
|
||||
};
|
||||
#endif // MLN_DRAWABLE_RENDERER
|
||||
|
||||
#if MLN_LEGACY_RENDERER
|
||||
const auto renderLayer3DPass = [&] {
|
||||
const auto debugGroup(parameters.encoder->createDebugGroup("3d"));
|
||||
int32_t i = static_cast<int32_t>(layerRenderItems.size()) - 1;
|
||||
for (auto it = layerRenderItems.begin(); it != layerRenderItems.end() && i >= 0; ++it, --i) {
|
||||
parameters.currentLayer = i;
|
||||
@@ -177,29 +196,33 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
renderItem.render(parameters);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif // MLN_LEGACY_RENDERER
|
||||
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
// draw render targets
|
||||
orchestrator.observeRenderTargets(
|
||||
[&](RenderTarget& renderTarget) { renderTarget.render(orchestrator, renderTree, parameters); });
|
||||
const auto drawableTargetsPass = [&] {
|
||||
// draw render targets
|
||||
orchestrator.observeRenderTargets(
|
||||
[&](RenderTarget& renderTarget) { renderTarget.render(orchestrator, renderTree, parameters); });
|
||||
};
|
||||
#endif
|
||||
|
||||
// - CLEAR
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Renders the backdrop of the OpenGL view. This also paints in areas where
|
||||
// we don't have any tiles whatsoever.
|
||||
{
|
||||
std::optional<Color> color;
|
||||
if (parameters.debugOptions & MapDebugOptions::Overdraw) {
|
||||
color = Color::black();
|
||||
} else if (!backend.contextIsShared()) {
|
||||
color = renderTreeParameters.backgroundColor;
|
||||
const auto commonClearPass = [&] {
|
||||
// - CLEAR
|
||||
// -------------------------------------------------------------------------------------
|
||||
// Renders the backdrop of the OpenGL view. This also paints in areas where
|
||||
// we don't have any tiles whatsoever.
|
||||
{
|
||||
std::optional<Color> color;
|
||||
if (parameters.debugOptions & MapDebugOptions::Overdraw) {
|
||||
color = Color::black();
|
||||
} else if (!backend.contextIsShared()) {
|
||||
color = renderTreeParameters.backgroundColor;
|
||||
}
|
||||
parameters.renderPass = parameters.encoder->createRenderPass(
|
||||
"main buffer", {parameters.backend.getDefaultRenderable(), color, 1.0f, 0});
|
||||
}
|
||||
parameters.renderPass = parameters.encoder->createRenderPass(
|
||||
"main buffer", {parameters.backend.getDefaultRenderable(), color, 1.0f, 0});
|
||||
}
|
||||
};
|
||||
|
||||
// Actually render the layers
|
||||
#if MLN_DRAWABLE_RENDERER
|
||||
@@ -274,9 +297,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
#endif // MLN_LEGACY_RENDERER
|
||||
|
||||
#if (MLN_DRAWABLE_RENDERER && !MLN_LEGACY_RENDERER)
|
||||
if (parameters.staticData.has3D) {
|
||||
common3DPass();
|
||||
drawable3DPass();
|
||||
}
|
||||
drawableTargetsPass();
|
||||
commonClearPass();
|
||||
drawableOpaquePass();
|
||||
drawableTranslucentPass();
|
||||
#elif (MLN_LEGACY_RENDERER && !MLN_DRAWABLE_RENDERER)
|
||||
if (parameters.staticData.has3D) {
|
||||
common3DPass();
|
||||
renderLayer3DPass();
|
||||
}
|
||||
commonClearPass();
|
||||
renderLayerOpaquePass();
|
||||
renderLayerTranslucentPass();
|
||||
#elif (MLN_DRAWABLE_RENDERER && MLN_LEGACY_RENDERER)
|
||||
@@ -289,44 +323,69 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
0.5f);
|
||||
platform::glEnable(GL_SCISSOR_TEST);
|
||||
#if MLN_RENDERER_QUAD_SPLIT_VIEW
|
||||
if (parameters.staticData.has3D) {
|
||||
common3DPass();
|
||||
drawable3DPass();
|
||||
renderLayer3DPass();
|
||||
parameters.clearStencil();
|
||||
}
|
||||
|
||||
// Drawable LayerGroups on the left
|
||||
// Opaque only on top
|
||||
platform::glScissor(0, 0, halfW, H);
|
||||
drawableTargetsPass();
|
||||
commonClearPass();
|
||||
drawableOpaquePass();
|
||||
|
||||
// Composite (Opaque+Translucent) on bottom
|
||||
platform::glScissor(0, 0, halfW, halfH);
|
||||
// Clipping masks were drawn only on the other side
|
||||
parameters.clearTileClippingMasks();
|
||||
drawableTranslucentPass();
|
||||
|
||||
// RenderLayers on the right
|
||||
// Opaque only on top
|
||||
platform::glScissor(halfW, 0, halfW, H);
|
||||
commonClearPass();
|
||||
// Clipping masks were drawn only on the other side
|
||||
parameters.clearTileClippingMasks();
|
||||
renderLayerOpaquePass();
|
||||
|
||||
// Composite (Opaque+Translucent) on bottom
|
||||
platform::glScissor(halfW, 0, halfW, halfH);
|
||||
parameters.clearTileClippingMasks();
|
||||
renderLayerTranslucentPass();
|
||||
#else
|
||||
#else // MLN_RENDERER_QUAD_SPLIT_VIEW
|
||||
if (parameters.staticData.has3D) {
|
||||
common3DPass();
|
||||
drawable3DPass();
|
||||
renderLayer3DPass();
|
||||
parameters.clearStencil();
|
||||
}
|
||||
|
||||
// Drawable LayerGroups on the left
|
||||
platform::glScissor(0, 0, halfW, H);
|
||||
drawableTargetsPass();
|
||||
commonClearPass();
|
||||
parameters.clearTileClippingMasks();
|
||||
drawableOpaquePass();
|
||||
drawableTranslucentPass();
|
||||
|
||||
// RenderLayers on the right
|
||||
platform::glScissor(halfW, 0, W, H);
|
||||
commonClearPass();
|
||||
parameters.clearTileClippingMasks();
|
||||
renderLayerOpaquePass();
|
||||
renderLayerTranslucentPass();
|
||||
#endif
|
||||
#endif // MLN_RENDERER_QUAD_SPLIT_VIEW
|
||||
// Reset viewport
|
||||
platform::glScissor(0, 0, W, H);
|
||||
platform::glDisable(GL_SCISSOR_TEST);
|
||||
#else // ifdef MLN_RENDERER_SPLIT_VIEW
|
||||
#else // if MLN_RENDERER_SPLIT_VIEW
|
||||
if (parameters.staticData.has3D) {
|
||||
common3DPass();
|
||||
renderLayer3DPass();
|
||||
drawable3DPass();
|
||||
parameters.clearStencil();
|
||||
}
|
||||
commonClearPass();
|
||||
// Do RenderLayers first, drawables last
|
||||
renderLayerOpaquePass();
|
||||
renderLayerTranslucentPass();
|
||||
|
||||
Reference in New Issue
Block a user