Drawable Renderer (#1570), Apply render pass to drawables
This commit is contained in:
committed by
Bart Louwers
parent
610fb7d63c
commit
b052cb904e
@@ -13,6 +13,7 @@ namespace mbgl {
|
||||
|
||||
class Color;
|
||||
class PaintParameters;
|
||||
enum class RenderPass : uint8_t;
|
||||
|
||||
namespace gfx {
|
||||
|
||||
@@ -45,6 +46,17 @@ public:
|
||||
const gfx::ShaderProgramBasePtr& getShader() const { return shader; }
|
||||
void setShader(gfx::ShaderProgramBasePtr value) { shader = std::move(value); }
|
||||
|
||||
/// The pass on which we'll be rendered
|
||||
mbgl::RenderPass getRenderPass() const { return renderPass; }
|
||||
void setRenderPass(mbgl::RenderPass value) { renderPass = value; }
|
||||
|
||||
/// Test whether to draw this drawable in a given render pass.
|
||||
/// If multiple render pass bits are set, all must be present.
|
||||
bool hasRenderPass(mbgl::RenderPass value) const {
|
||||
using T = std::underlying_type<mbgl::RenderPass>::type;
|
||||
return (static_cast<T>(renderPass) & static_cast<T>(value)) == static_cast<T>(value);
|
||||
}
|
||||
|
||||
/// not used for anything yet
|
||||
DrawPriority getDrawPriority() const { return drawPriority; }
|
||||
void setDrawPriority(DrawPriority value) { drawPriority = value; }
|
||||
@@ -89,6 +101,7 @@ protected:
|
||||
std::string name;
|
||||
util::SimpleIdentity uniqueID;
|
||||
gfx::ShaderProgramBasePtr shader;
|
||||
mbgl::RenderPass renderPass;
|
||||
mat4 matrix; //= matrix::identity4();
|
||||
std::optional<OverscaledTileID> tileID;
|
||||
DrawPriority drawPriority = 0;
|
||||
|
||||
@@ -49,6 +49,10 @@ public:
|
||||
/// Get the ID of the drawable we're currently working on, if any
|
||||
util::SimpleIdentity getDrawableId();
|
||||
|
||||
/// The pass on which we'll be rendered
|
||||
mbgl::RenderPass getRenderPass() const { return renderPass; }
|
||||
void setRenderPass(mbgl::RenderPass value) { renderPass = value; }
|
||||
|
||||
/// The draw priority assigned to generated drawables
|
||||
DrawPriority getDrawPriority() const;
|
||||
void setDrawPriority(DrawPriority);
|
||||
@@ -118,6 +122,7 @@ protected:
|
||||
protected:
|
||||
std::string name;
|
||||
std::string drawableName;
|
||||
mbgl::RenderPass renderPass;
|
||||
DrawPriority drawPriority = 0;
|
||||
int32_t layerIndex = -1;
|
||||
DepthMaskType depthType = DepthMaskType::ReadOnly;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <mbgl/gfx/drawable.hpp>
|
||||
#include <mbgl/gfx/types.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/util/mat4.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
@@ -7,6 +8,7 @@ namespace gfx {
|
||||
|
||||
Drawable::Drawable(std::string name_)
|
||||
: name(name_),
|
||||
renderPass(RenderPass::Opaque),
|
||||
matrix(matrix::identity4()),
|
||||
depthType(DepthMaskType::ReadOnly) {}
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
#include <mbgl/gfx/drawable_builder.hpp>
|
||||
#include <mbgl/gfx/drawable_builder_impl.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
|
||||
namespace mbgl {
|
||||
namespace gfx {
|
||||
|
||||
DrawableBuilder::DrawableBuilder(std::string name_)
|
||||
: name(std::move(name_)),
|
||||
renderPass(RenderPass::Opaque),
|
||||
impl(std::make_unique<Impl>()) {}
|
||||
|
||||
DrawableBuilder::~DrawableBuilder() = default;
|
||||
@@ -27,6 +29,7 @@ DrawablePtr DrawableBuilder::getCurrentDrawable(bool createIfNone) {
|
||||
void DrawableBuilder::flush() {
|
||||
if (!impl->vertices.empty()) {
|
||||
auto draw = getCurrentDrawable(/*createIfNone=*/true);
|
||||
currentDrawable->setRenderPass(renderPass);
|
||||
currentDrawable->setDrawPriority(drawPriority);
|
||||
currentDrawable->setLayerIndex(layerIndex);
|
||||
currentDrawable->setDepthType(depthType);
|
||||
|
||||
@@ -8,11 +8,12 @@
|
||||
#include <mbgl/style/layer_properties.hpp>
|
||||
#include <mbgl/renderer/bucket.hpp>
|
||||
#include <mbgl/renderer/change_request.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/paint_parameters.hpp>
|
||||
#include <mbgl/renderer/pattern_atlas.hpp>
|
||||
#include <mbgl/renderer/image_manager.hpp>
|
||||
#include <mbgl/renderer/render_pass.hpp>
|
||||
#include <mbgl/renderer/render_static_data.hpp>
|
||||
#include <mbgl/renderer/upload_parameters.hpp>
|
||||
#include <mbgl/programs/programs.hpp>
|
||||
#include <mbgl/shaders/shader_program_base.hpp>
|
||||
#include <mbgl/util/tile_cover.hpp>
|
||||
@@ -223,13 +224,13 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
const auto& evaluated = getEvaluated<BackgroundLayerProperties>(evaluatedProperties);
|
||||
|
||||
// TODO: If background is solid, we can skip drawables and rely on the clear color
|
||||
// const auto passes = eval.get<style::BackgroundOpacity>() == 0.0f
|
||||
// ? RenderPass::None
|
||||
// : (!uneval.get<style::BackgroundPattern>().isUndefined()
|
||||
// || eval.get<style::BackgroundOpacity>() < 1.0f
|
||||
// || eval.get<style::BackgroundColor>().a < 1.0f)
|
||||
// ? RenderPass::Translucent
|
||||
// : RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render()
|
||||
const auto passes = evaluated.get<style::BackgroundOpacity>() == 0.0f
|
||||
? RenderPass::None
|
||||
: (!unevaluated.get<style::BackgroundPattern>().isUndefined()
|
||||
|| evaluated.get<style::BackgroundOpacity>() < 1.0f
|
||||
|| evaluated.get<style::BackgroundColor>().a < 1.0f)
|
||||
? RenderPass::Translucent
|
||||
: RenderPass::Opaque | RenderPass::Translucent; // evaluated based on opaquePassCutoff in render()
|
||||
|
||||
// unevaluated.hasTransition();
|
||||
// getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
|
||||
@@ -289,6 +290,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
if (layerChange) {
|
||||
drawable->setLayerIndex(layerIndex);
|
||||
}
|
||||
// TODO: does render pass change dynamically?
|
||||
}
|
||||
|
||||
std::unique_ptr<gfx::DrawableBuilder> builder;
|
||||
@@ -306,6 +308,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
|
||||
// We actually need to build things, so set up a builder if we haven't already
|
||||
if (!builder) {
|
||||
builder = context.createDrawableBuilder("background");
|
||||
builder->setRenderPass(passes);
|
||||
builder->setShader(shader);
|
||||
builder->addTweaker(context.createDrawableTweaker());
|
||||
builder->setColor(*color);
|
||||
|
||||
@@ -444,18 +444,24 @@ void RenderFillLayer::update(const int32_t layerIndex,
|
||||
}
|
||||
|
||||
auto& bucket = static_cast<FillBucket&>(*renderData->bucket);
|
||||
// const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
|
||||
const auto& evaluated = getEvaluated<FillLayerProperties>(renderData->layerProperties);
|
||||
|
||||
if (!builder) {
|
||||
builder = context.createDrawableBuilder("fill");
|
||||
builder->setShader(shader);
|
||||
builder->addTweaker(context.createDrawableTweaker());
|
||||
// builder->setColor(color);
|
||||
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerDrawable);
|
||||
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
|
||||
builder->setLayerIndex(layerIndex);
|
||||
}
|
||||
|
||||
const auto fillRenderPass = (evaluated.get<FillColor>().constantOr(Color()).a >= 1.0f &&
|
||||
evaluated.get<FillOpacity>().constantOr(0) >= 1.0f
|
||||
/* && parameters.currentLayer >= parameters.opaquePassCutoff*/)
|
||||
? RenderPass::Opaque
|
||||
: RenderPass::Translucent;
|
||||
builder->setRenderPass(fillRenderPass);
|
||||
|
||||
const std::vector<gfx::VertexVector<gfx::detail::VertexType<gfx::AttributeType<int16_t, 2>>>::Vertex>&
|
||||
verts = bucket.vertices.vector();
|
||||
std::vector<std::array<int16_t, 2>> rawVerts(verts.size());
|
||||
|
||||
@@ -202,11 +202,9 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
}
|
||||
|
||||
// Draw Drawables
|
||||
{
|
||||
const auto drawDrawables = [&](const mbgl::RenderPass renderPass){
|
||||
// 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"));
|
||||
|
||||
@@ -218,6 +216,12 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
for (const auto& drawPtr : drawables) {
|
||||
auto& drawable = *drawPtr;
|
||||
|
||||
if (!drawable.hasRenderPass(renderPass)) {
|
||||
continue;
|
||||
}
|
||||
if (drawable.hasRenderPass(RenderPass::Opaque) && parameters.currentLayer >= parameters.opaquePassCutoff) {
|
||||
continue;
|
||||
}
|
||||
if (!context.setupDraw(parameters, drawable)) {
|
||||
continue;
|
||||
}
|
||||
@@ -237,16 +241,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
|
||||
drawable.draw(parameters);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
parameters.pass = RenderPass::Opaque;
|
||||
parameters.currentLayer = 0;
|
||||
parameters.opaquePassCutoff = 1;
|
||||
drawDrawables(parameters.pass);
|
||||
|
||||
// Actually render the layers
|
||||
|
||||
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
|
||||
parameters.depthRangeSize = 1 - (layerRenderItems.size() + 2) * parameters.numSublayers * parameters.depthEpsilon;
|
||||
|
||||
// - OPAQUE PASS -------------------------------------------------------------------------------
|
||||
// Render everything top-to-bottom by using reverse iterators. Render opaque objects first.
|
||||
{
|
||||
parameters.pass = RenderPass::Opaque;
|
||||
const auto debugGroup(parameters.renderPass->createDebugGroup("opaque"));
|
||||
|
||||
uint32_t i = 0;
|
||||
@@ -263,10 +271,16 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
|
||||
}
|
||||
}
|
||||
|
||||
parameters.pass = RenderPass::Translucent;
|
||||
parameters.currentLayer = 1;
|
||||
parameters.opaquePassCutoff = 1;
|
||||
drawDrawables(parameters.pass);
|
||||
|
||||
parameters.opaquePassCutoff = renderTreeParameters.opaquePassCutOff;
|
||||
|
||||
// - TRANSLUCENT PASS --------------------------------------------------------------------------
|
||||
// Make a second pass, rendering translucent objects. This time, we render bottom-to-top.
|
||||
{
|
||||
parameters.pass = RenderPass::Translucent;
|
||||
const auto debugGroup(parameters.renderPass->createDebugGroup("translucent"));
|
||||
|
||||
int32_t i = static_cast<int32_t>(layerRenderItems.size()) - 1;
|
||||
|
||||
Reference in New Issue
Block a user