diff --git a/include/mbgl/gfx/drawable.hpp b/include/mbgl/gfx/drawable.hpp index 20eebfa61..1d26fcee5 100644 --- a/include/mbgl/gfx/drawable.hpp +++ b/include/mbgl/gfx/drawable.hpp @@ -15,6 +15,8 @@ class PaintParameters; namespace gfx { +enum class DepthMaskType : bool; + class DrawableTweaker; class ShaderProgramBase; using ShaderProgramBasePtr = std::shared_ptr; @@ -47,6 +49,9 @@ public: mat4 getMatrix() const { return matrix; } void setMatrix(mat4 value) { matrix = value; } + + DepthMaskType getDepthType() const { return depthType; } + void setDepthType(DepthMaskType value) { depthType = value; } /// Get the number of vertexes std::size_t getVertexCount() const { return getVertexAttributes().getMaxCount(); } @@ -72,6 +77,7 @@ protected: mat4 matrix; //= matrix::identity4(); std::optional tileID; DrawPriority drawPriority = 0; + DepthMaskType depthType;// = DepthMaskType::ReadOnly; std::vector tweakers; }; diff --git a/include/mbgl/gfx/drawable_builder.hpp b/include/mbgl/gfx/drawable_builder.hpp index fd9516f9d..567c74220 100644 --- a/include/mbgl/gfx/drawable_builder.hpp +++ b/include/mbgl/gfx/drawable_builder.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include #include #include @@ -59,6 +60,9 @@ public: const Color& getColor() const; void setColor(const Color& value); + DepthMaskType getDepthType() const { return depthType; } + void setDepthType(DepthMaskType value) { depthType = value; } + /// Which shader to use when rendering emitted drawables const gfx::ShaderProgramBasePtr& getShader() const { return shader; } void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); } @@ -88,14 +92,11 @@ protected: protected: DrawPriority drawPriority = 0; - + DepthMaskType depthType = DepthMaskType::ReadOnly; gfx::ShaderProgramBasePtr shader; - mat4 matrix; - DrawablePtr currentDrawable; std::vector drawables; - std::vector tweakers; struct Impl; diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index b23654fbc..b580e0352 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -11,6 +11,7 @@ namespace mbgl { +class PaintParameters; class ProgramParameters; namespace gfx { @@ -90,7 +91,7 @@ public: public: /// Activate the shader, vertex attributes, etc., specified by the drawable - virtual bool setupDraw(const gfx::Drawable&) = 0; + virtual bool setupDraw(const PaintParameters&, const gfx::Drawable&) = 0; }; } // namespace gfx diff --git a/src/mbgl/gfx/drawable.cpp b/src/mbgl/gfx/drawable.cpp index 5fe8edd11..1fc6e5c2a 100644 --- a/src/mbgl/gfx/drawable.cpp +++ b/src/mbgl/gfx/drawable.cpp @@ -1,11 +1,13 @@ #include +#include #include namespace mbgl { namespace gfx { Drawable::Drawable() : - matrix(matrix::identity4()) + matrix(matrix::identity4()), + depthType(DepthMaskType::ReadOnly) { } diff --git a/src/mbgl/gfx/drawable_builder.cpp b/src/mbgl/gfx/drawable_builder.cpp index 57289dbd8..4424aa515 100644 --- a/src/mbgl/gfx/drawable_builder.cpp +++ b/src/mbgl/gfx/drawable_builder.cpp @@ -28,6 +28,7 @@ void DrawableBuilder::flush() { if (!impl->vertices.empty()) { auto draw = getCurrentDrawable(/*createIfNone=*/true); currentDrawable->setDrawPriority(drawPriority); + currentDrawable->setDepthType(depthType); currentDrawable->setShader(shader); currentDrawable->setMatrix(matrix); currentDrawable->setVertexAttributes(getVertexAttributes()); diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index e9658dfb8..d16e8832f 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -10,13 +10,12 @@ #include #include #include +#include #include #include #include #include -#include - #include #include @@ -449,7 +448,7 @@ void Context::setDirtyState() { globalVertexArrayState.setDirty(); } -bool Context::setupDraw(const gfx::Drawable& drawable) { +bool Context::setupDraw(const PaintParameters& parameters, const gfx::Drawable& drawable) { if (const auto &shader = drawable.getShader()) { const auto& shaderGL = static_cast(*shader); if (shaderGL.getGLProgramID() != program.getCurrentValue()) { @@ -459,7 +458,7 @@ bool Context::setupDraw(const gfx::Drawable& drawable) { program = value::Program::Default; } - //setDepthMode(...); + setDepthMode(parameters.depthModeForSublayer(0, drawable.getDepthType())); setStencilMode(gfx::StencilMode::disabled()); setColorMode(gfx::ColorMode::alphaBlended()); setCullFaceMode(gfx::CullFaceMode::disabled()); diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 9b473c5b0..e5b943781 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -104,7 +104,7 @@ public: void setCleanupOnDestruction(bool cleanup) { cleanupOnDestruction = cleanup; } - bool setupDraw(const gfx::Drawable&) override; + bool setupDraw(const PaintParameters&, const gfx::Drawable&) override; private: RendererBackend& backend; diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 999149c2c..fb329408d 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace mbgl { namespace gl { @@ -20,13 +21,22 @@ void DrawableGLBuilder::init() { posAttr->set(index++, gfx::VertexAttribute::int2{vert.a1[0], vert.a1[1]}); } } + if (auto colorAttr = attrs.getOrAdd("a_color")) { + std::size_t index = 0; + for (const auto& color : impl->colors) { + const auto comp = util::convert(color.toArray()); + const auto norm = gfx::VertexAttribute::float4{comp[0]/255.f,comp[1]/255.f,comp[2]/255.f,comp[3]}; + colorAttr->set(index++, norm); + } + } constexpr auto indexOffset = 0; const auto indexCount = impl->indexes.elements(); drawableGL.setIndexData(impl->indexes.vector(), indexOffset, indexCount); - + impl->indexes.clear(); impl->vertices.clear(); + impl->colors.clear(); } } // namespace gl diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index 1375fbb6f..2551a40be 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -70,40 +70,35 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { gl::Context& glContext = static_cast(*context); -// "layout (location = 0) in vec2 a_pos;\nuniform mat4 u_matrix;\n\nvoid main() {\n - // gl_Position = u_matrix * vec4(a_pos, 0, 1);\n}\n", fragment = "uniform vec4 u_color;\nuniform float u_opacity;\n\nvoid main() {\n fragColor = u_color * u_opacity;\n\n#ifdef OVERDRAW_INSPECTOR\n fragColor = vec4(1.0);\n#endif\n}\n" - auto shader = shaders.get(shaderName); if (!shader) { constexpr auto vert = R"(#version 300 es precision highp float; - layout (location = 0) in vec2 a_pos; uniform mat4 u_matrix; + layout (location = 0) in vec2 a_pos; + layout (location = 1) in vec4 a_color; + out vec4 v_color; void main() { + v_color = a_color; gl_Position = u_matrix * vec4(a_pos, 0, 1); })"; constexpr auto frag = R"(#version 300 es precision highp float; - in vec4 pos; - out vec4 color; + in vec4 v_color; + out vec4 fragColor; + void main() { - color = vec4(0.5,0.0,0.0,0.5); + fragColor = v_color; })"; try { // Compile shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag); if (shader) { - // Set uniforms - //shader->setUniform("a", 0, 3.21f); - //shader->setUniform("b", 0, 4.32f); - // Set default values - //shader->setAttribute("d", 0, 12.3f); - //shader->setAttribute("e", 0, 123); - //shader->setAttribute("f", 0, gfx::VertexAttribute::matf2{ 1.0f, 2.0f, 3.0f, 4.0f }); + //shader->setAttribute("a_color", gfx::VertexAttribute::matf4{ 1.0f, 1.0f, 1.0f, 1.0f }); // Add to the registry if (!shaders.registerShader(shader, shaderName)) { diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index 645b8ceda..be3dca1ec 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include @@ -138,7 +139,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( /*out*/ std::unique_ptr& outBuffer) { AttributeBindingArray bindings; - bindings.reserve(defaults.size()); + bindings.resize(defaults.size()); constexpr std::size_t align = 16; constexpr std::uint8_t padding = 0; @@ -147,41 +148,55 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings( allData.reserve(defaults.getTotalSize() * vertexCount); // For each attribute in the program, with the corresponding default and optional override... - defaults.resolve(overrides, [&](const std::string& /*name*/, + defaults.resolve(overrides, [&](const std::string& name, const gfx::VertexAttribute& defaultAttr, const gfx::VertexAttribute* overrideAttr)->void { - + const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr; const auto& effectiveGL = static_cast(effectiveAttr); const auto& defaultGL = static_cast(defaultAttr); + const auto stride = defaultAttr.getStride(); const auto offset = static_cast(allData.size()); - bindings.emplace_back(gfx::AttributeBinding{ - /*.attribute = */ gfx::AttributeDescriptor{ defaultAttr.getDataType(), offset }, - /*.vertexStride = */ static_cast(defaultAttr.getStride()), - /*.vertexBufferResource = */nullptr, // buffer pointer established later - /*.vertexOffset = */ static_cast(defaultGL.getIndex()) - }); - + // Get the raw data for the values in the desired format const auto& rawData = effectiveGL.getRaw(defaultGL.getGLType()); - if (rawData.size() == defaultAttr.getStride()) { + + if (rawData.size() == stride * vertexCount) { + // The override provided a value for each vertex, append it as-is + allData.insert(allData.end(), rawData.begin(), rawData.end()); + } else if (rawData.size() == stride) { + // We only have one value, append a copy for each vertex for (std::size_t i = 0; i < vertexCount; ++i) { - allData.insert(allData.begin(), rawData.begin(), rawData.end()); + allData.insert(allData.end(), rawData.begin(), rawData.end()); } - } else if (rawData.size() == defaultAttr.getStride() * vertexCount) { - allData.insert(allData.begin(), rawData.begin(), rawData.end()); } else { - // TODO: log? throw? - allData.insert(allData.begin(), defaultAttr.getStride() * vertexCount, 0); + // something else, the binding is invalid + // TODO: throw? + Log::Warning(Event::General, + "Got " + util::toString(rawData.size()) + " bytes for attribute '" + name + + "' (" + util::toString(defaultGL.getIndex()) + "), expected " + + util::toString(stride) + " or " + util::toString(stride * vertexCount)); + return; } + bindings[defaultGL.getIndex()] = { + /*.attribute = */ { defaultAttr.getDataType(), offset }, + /*.vertexStride = */ static_cast(stride), + /*.vertexBufferResource = */nullptr, // buffer pointer established later + /*.vertexOffset = */ 0, + }; + pad(allData, align, padding); }); - auto vertBuf = createVertexBufferResource(&allData[0], allData.size(), usage); + auto vertBuf = createVertexBufferResource(allData.data(), allData.size(), usage); - // Assign to each element - std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); }); + // Go back and fill in the newly-allocated buffer in each binding that was generated + std::for_each(bindings.begin(), bindings.end(), [&](auto& b) { + if (b) { + b->vertexBufferResource = vertBuf.get(); + } + }); outBuffer = std::move(vertBuf); return bindings; diff --git a/src/mbgl/renderer/render_orchestrator.cpp b/src/mbgl/renderer/render_orchestrator.cpp index 9adcab92f..d8ed70fd1 100644 --- a/src/mbgl/renderer/render_orchestrator.cpp +++ b/src/mbgl/renderer/render_orchestrator.cpp @@ -770,18 +770,20 @@ void RenderOrchestrator::removeDrawable(const util::SimpleIdentity& drawableId) drawables.erase(drawableId); } -void RenderOrchestrator::updateLayers(PaintParameters& parameters) { +void RenderOrchestrator::updateLayers(gfx::ShaderRegistry& shaders, + const TransformState& state, + const PropertyEvaluationParameters& evalParameters) { std::vector> changes; for (auto& kv : layersRemoved) { - kv.second->layerRemoved(parameters, changes); + kv.second->layerRemoved(changes); } for (auto& kv : layersAdded) { - kv.second->layerAdded(parameters, changes); + kv.second->layerAdded(shaders, state, evalParameters, changes); } for (auto& impl : *layerImpls) { - impl->update(parameters, changes); + impl->update(state, evalParameters, changes); } addChanges(changes); diff --git a/src/mbgl/renderer/render_orchestrator.hpp b/src/mbgl/renderer/render_orchestrator.hpp index fede95068..f9aa1a307 100644 --- a/src/mbgl/renderer/render_orchestrator.hpp +++ b/src/mbgl/renderer/render_orchestrator.hpp @@ -36,6 +36,8 @@ class RenderTree; namespace gfx { class Drawable; + class ShaderRegistry; + using DrawablePtr = std::shared_ptr; } // namespace gfx @@ -97,10 +99,14 @@ public: void addDrawable(gfx::DrawablePtr); void removeDrawable(const util::SimpleIdentity& drawableId); - void updateLayers(PaintParameters&); + void updateLayers(gfx::ShaderRegistry&, + const TransformState&, + const PropertyEvaluationParameters&); void processChanges(); + const ZoomHistory& getZoomHistory() const { return zoomHistory; } + private: bool isLoaded() const; bool hasTransitions(TimePoint) const; diff --git a/src/mbgl/renderer/renderer.cpp b/src/mbgl/renderer/renderer.cpp index b35f9d6c3..05c5ba05e 100644 --- a/src/mbgl/renderer/renderer.cpp +++ b/src/mbgl/renderer/renderer.cpp @@ -2,7 +2,9 @@ #include #include +#include #include +#include #include #include @@ -29,6 +31,24 @@ void Renderer::render(const std::shared_ptr& updateParameters) assert(updateParameters); if (auto renderTree = impl->orchestrator.createRenderTree(updateParameters)) { renderTree->prepare(); + + const bool isMapModeContinuous = updateParameters->mode == MapMode::Continuous; + const auto transitionOptions = isMapModeContinuous ? updateParameters->transitionOptions : style::TransitionOptions(); + //const TransitionParameters transitionParameters{updateParameters->timePoint, transitionOptions}; + const auto defDuration = isMapModeContinuous ? util::DEFAULT_TRANSITION_DURATION : Duration::zero(); + const PropertyEvaluationParameters evalParameters { + impl->orchestrator.getZoomHistory(), + updateParameters->timePoint, + transitionOptions.duration.value_or(defDuration), + }; + + const auto& renderTreeParameters = renderTree->getParameters(); + const auto& state = renderTreeParameters.transformParams.state; + + if (impl->staticData && impl->staticData->shaders) { + impl->orchestrator.updateLayers(*impl->staticData->shaders, state, evalParameters); + } + impl->render(*renderTree); } } diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index d69403509..7f06920b5 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -81,8 +81,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) { renderTree.getLineAtlas(), renderTree.getPatternAtlas()}; - orchestrator.updateLayers(parameters); - parameters.symbolFadeChange = renderTreeParameters.symbolFadeChange; parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff; const auto& sourceRenderItems = renderTree.getSourceRenderItems(); @@ -195,6 +193,39 @@ void Renderer::Impl::render(const RenderTree& renderTree) { "main buffer", {parameters.backend.getDefaultRenderable(), color, 1.0f, 0}); } + // Draw Drawables + { + // TODO: figure out how to make drawables participate in the depth system + // Maybe make it a function mapping draw priority to the depth range (always (0,1)?) + parameters.pass = RenderPass::Opaque; + parameters.currentLayer = parameters.opaquePassCutoff; + parameters.depthRangeSize = 1 - (1 + 2) * parameters.numSublayers * parameters.depthEpsilon; + const auto debugGroup(parameters.renderPass->createDebugGroup("drawables")); + + for (const auto &pair : orchestrator.getDrawables()) { + const auto& drawable = *pair.second; + + if (!context.setupDraw(parameters, drawable)) { + continue; + } + + mat4 matrix = drawable.getMatrix(); + if (drawable.getTileID()) { + const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); + const auto tileMat = parameters.matrixForTile(tileID); + matrix::multiply(matrix, drawable.getMatrix(), tileMat); + matrix = tileMat; + } + + if (auto& shader = drawable.getShader()) { + shader->setUniform("u_matrix", 0, util::convert(matrix)); + shader->updateUniforms(); + } + + drawable.draw(parameters); + } + } + // Actually render the layers parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon; @@ -210,6 +241,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) { for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) { parameters.currentLayer = i; const RenderItem& renderItem = it->get(); + if (renderItem.getName() == "background") { // Replaced by drawables, above + continue; + } if (renderItem.hasRenderPass(parameters.pass)) { const auto layerDebugGroup(parameters.renderPass->createDebugGroup(renderItem.getName().c_str())); renderItem.render(parameters); @@ -234,32 +268,6 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } - // Draw Drawables - { - for (const auto &pair : orchestrator.getDrawables()) { - const auto& drawable = *pair.second; - - if (!context.setupDraw(drawable)) { - continue; - } - - mat4 matrix = drawable.getMatrix(); - if (drawable.getTileID()) { - const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped(); - const auto tileMat = parameters.matrixForTile(tileID); - matrix::multiply(matrix, drawable.getMatrix(), tileMat); - matrix = tileMat; - } - - if (auto& shader = drawable.getShader()) { - shader->setUniform("u_matrix", 0, util::convert(matrix)); - shader->updateUniforms(); - } - - drawable.draw(parameters); - } - } - // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { diff --git a/src/mbgl/shaders/gl/shader_program_gl.cpp b/src/mbgl/shaders/gl/shader_program_gl.cpp index ad6ad51b1..d534d8467 100644 --- a/src/mbgl/shaders/gl/shader_program_gl.cpp +++ b/src/mbgl/shaders/gl/shader_program_gl.cpp @@ -103,7 +103,7 @@ std::shared_ptr ShaderProgramGL::create( std::string_view vertexSource, std::string_view fragmentSource) noexcept(false) { - const auto firstAttrib = "pos"; + const auto firstAttrib = "a_pos"; // throws on compile error auto vertProg = context.createShader(ShaderType::Vertex, std::initializer_list{vertexSource.data()}); diff --git a/src/mbgl/style/layer_impl.hpp b/src/mbgl/style/layer_impl.hpp index 493920c45..bee08c6de 100644 --- a/src/mbgl/style/layer_impl.hpp +++ b/src/mbgl/style/layer_impl.hpp @@ -16,10 +16,16 @@ namespace mbgl { class ChangeRequest; class PaintParameters; +class PropertyEvaluationParameters; +class TransformState; using UniqueChangeRequest = std::unique_ptr; using UniqueChangeRequestVec = std::vector; +namespace gfx { +class ShaderRegistry; +} // namespace gfx + namespace style { /** @@ -56,10 +62,15 @@ public: virtual void populateFontStack(std::set& fontStack) const; /// Generate any changes needed by the layer - virtual void update(PaintParameters&, UniqueChangeRequestVec&) const { } + virtual void update(const TransformState&, + const PropertyEvaluationParameters&, + UniqueChangeRequestVec&) const { } - virtual void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const { } - virtual void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const { } + virtual void layerAdded(gfx::ShaderRegistry&, + const TransformState&, + const PropertyEvaluationParameters&, + UniqueChangeRequestVec&) const { } + virtual void layerRemoved(UniqueChangeRequestVec&) const { } std::string id; std::string source; diff --git a/src/mbgl/style/layers/background_layer_impl.cpp b/src/mbgl/style/layers/background_layer_impl.cpp index 9871ebfc1..7b1d9da2e 100644 --- a/src/mbgl/style/layers/background_layer_impl.cpp +++ b/src/mbgl/style/layers/background_layer_impl.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -29,19 +30,22 @@ bool BackgroundLayer::Impl::hasLayoutDifference(const Layer::Impl&) const { constexpr auto shaderName = "background_generic"; -void BackgroundLayer::Impl::layerAdded(PaintParameters& parameters, UniqueChangeRequestVec& changes) const { +void BackgroundLayer::Impl::layerAdded(gfx::ShaderRegistry& shaders, + const TransformState& state, + const PropertyEvaluationParameters& evalParameters, + UniqueChangeRequestVec& changes) const { { std::unique_lock guard(mutex); if (!shader) { - shader = parameters.shaders.get(shaderName); + shader = shaders.get(shaderName); } } // Add all the tiles - update(parameters, changes); + update(state, evalParameters, changes); } -void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVec& changes) const { +void BackgroundLayer::Impl::layerRemoved(UniqueChangeRequestVec& changes) const { // Remove everything decltype(tileDrawables) localDrawables; { @@ -55,20 +59,43 @@ void BackgroundLayer::Impl::layerRemoved(PaintParameters&, UniqueChangeRequestVe } } -void BackgroundLayer::Impl::update(PaintParameters& parameters, UniqueChangeRequestVec& changes) const { +void BackgroundLayer::Impl::update(const TransformState& state, + const PropertyEvaluationParameters& evalParameters, + UniqueChangeRequestVec& changes) const { std::unique_lock guard(mutex); - std::unique_ptr builder = std::make_unique(); // from GL-specific code via virtual method on ...Context? - builder->setShader(shader); - builder->addTweaker(std::make_shared()); // generally shared across drawables + const auto uneval = paint.untransitioned(); + const auto eval = uneval.evaluate(evalParameters); - const auto zoom = parameters.state.getIntegerZoom(); - const auto tileCover = util::tileCover(parameters.state, zoom); + //const auto passes = eval.get() == 0.0f + // ? RenderPass::None + // : (!uneval.get().isUndefined() + // || eval.get() < 1.0f + // || eval.get().a < 1.0f) + // ? RenderPass::Translucent + // : RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render() + + //unevaluated.hasTransition(); + //getCrossfade(evaluatedProperties).t != 1; + + std::optional color; + if (eval.get().from.empty()) { + const auto opacity = eval.get(); + if (opacity > 0.0f) { + color = eval.get() * eval.get(); + } + } + + const auto zoom = state.getIntegerZoom(); + const auto tileCover = util::tileCover(state, zoom); // Drawables per overscaled or canonical tile? //const UnwrappedTileID unwrappedTileID = tileID.toUnwrapped(); - std::unordered_set newTileIDs(tileCover.begin(), tileCover.end()); + // Put the tile cover into a searchable form. + // TODO: Likely better to sort and `std::binary_search` the vector. + // If it's returned in a well-defined order, we might not even need to sort. + const std::unordered_set newTileIDs(tileCover.begin(), tileCover.end()); // For each existing tile drawable... for (auto iter = tileDrawables.begin(); iter != tileDrawables.end(); ) { @@ -85,28 +112,39 @@ void BackgroundLayer::Impl::update(PaintParameters& parameters, UniqueChangeRequ } } + if (!color) { + return; + } + + std::unique_ptr builder; + // For each tile in the cover set, add a tile drawable if one doesn't already exist. // We currently assume only one drawable per tile. for (const auto& tileID : tileCover) { const auto result = tileDrawables.insert(std::make_pair(tileID, gfx::DrawablePtr())); if (!result.second) { // Already present - // TODO: Update matrix uniform here or in the tweaker? + // TODO: Update matrix here or in the tweaker? continue; } + // We actually need to build things, so set up a builder if we haven't already + if (!builder) { + builder = std::make_unique(); // from GL-specific code via virtual method on ...Context? + builder->setShader(shader); + builder->addTweaker(std::make_shared()); // generally shared across drawables + builder->setColor(*color); + builder->setDepthType(gfx::DepthMaskType::ReadWrite); + } + // Tile coordinates are fixed... builder->addQuad(0, 0, util::EXTENT, util::EXTENT); - // ... they're placed with the matrix in the uniforms + // ... they're placed with the matrix in the uniforms, which changes with the view builder->setMatrix(/*parameters.matrixForTile(tileID.toUnwrapped())*/ matrix::identity4()); - //builder->setUniform("u_matrix", matrix); builder->flush(); - // TODO: Store Tile ID with drawable? - // Drawables aren't always tile-specific, but it may be needed sometimes. - auto drawables = builder->clearDrawables(); if (!drawables.empty()) { auto& drawable = drawables[0]; diff --git a/src/mbgl/style/layers/background_layer_impl.hpp b/src/mbgl/style/layers/background_layer_impl.hpp index a7bf6931d..1408f7adb 100644 --- a/src/mbgl/style/layers/background_layer_impl.hpp +++ b/src/mbgl/style/layers/background_layer_impl.hpp @@ -14,6 +14,8 @@ namespace gfx { class Drawable; class ShaderProgramBase; +class ShaderRegistry; + using DrawablePtr = std::shared_ptr; using ShaderProgramBasePtr = std::shared_ptr; @@ -29,11 +31,16 @@ public: bool hasLayoutDifference(const Layer::Impl&) const override; void stringifyLayout(rapidjson::Writer&) const override; - void layerAdded(PaintParameters&, UniqueChangeRequestVec&) const override; - void layerRemoved(PaintParameters&, UniqueChangeRequestVec&) const override; + void layerAdded(gfx::ShaderRegistry&, + const TransformState&, + const PropertyEvaluationParameters&, + UniqueChangeRequestVec&) const override; + void layerRemoved(UniqueChangeRequestVec&) const override; /// Generate any changes needed by the layer - void update(PaintParameters&, UniqueChangeRequestVec&) const override; + void update(const TransformState&, + const PropertyEvaluationParameters&, + UniqueChangeRequestVec&) const override; private: mutable std::mutex mutex;