Fix 3D stencil mode incrementing for each drawable (#1345)
This commit is contained in:
committed by
Bart Louwers
parent
4eef2e3529
commit
f88884bc20
@@ -46,7 +46,10 @@ void DrawableGL::draw(PaintParameters& parameters) const {
|
||||
// force disable depth test for debugging
|
||||
// context.setDepthMode({gfx::DepthFunctionType::Always, gfx::DepthMaskType::ReadOnly, {0,1}});
|
||||
|
||||
context.setStencilMode(makeStencilMode(parameters));
|
||||
// For 3D mode, stenciling is handled by the layer group
|
||||
if (!is3D) {
|
||||
context.setStencilMode(makeStencilMode(parameters));
|
||||
}
|
||||
|
||||
context.setColorMode(getColorMode());
|
||||
context.setCullFaceMode(getCullFaceMode());
|
||||
@@ -211,9 +214,7 @@ gfx::ColorMode DrawableGL::makeColorMode(PaintParameters& parameters) const {
|
||||
|
||||
gfx::StencilMode DrawableGL::makeStencilMode(PaintParameters& parameters) const {
|
||||
if (enableStencil) {
|
||||
if (is3D) {
|
||||
return parameters.stencilModeFor3D();
|
||||
} else if (tileID) {
|
||||
if (!is3D && tileID) {
|
||||
return parameters.stencilModeForClipping(tileID->toUnwrapped());
|
||||
}
|
||||
assert(false);
|
||||
|
||||
@@ -46,6 +46,14 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
|
||||
return;
|
||||
}
|
||||
|
||||
auto& context = static_cast<gl::Context&>(parameters.context);
|
||||
|
||||
// `stencilModeFor3D` uses a different stencil mask value each time its called, so if the
|
||||
// drawables in this layer use 3D stencil mode, we need to set it up here so that all the
|
||||
// drawables end up using the same mode value.
|
||||
bool stencil3d = false;
|
||||
gfx::StencilMode stencilMode3d;
|
||||
|
||||
if (getDrawableCount()) {
|
||||
#if !defined(NDEBUG)
|
||||
const auto label_clip = getName() + (getName().empty() ? "" : "-") + "tile-clip-masks";
|
||||
@@ -55,12 +63,23 @@ 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.getIs3D() && drawable.getEnableStencil() && drawable.getTileID() &&
|
||||
drawable.hasRenderPass(parameters.pass)) {
|
||||
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
|
||||
if (drawable.getEnabled() && drawable.getEnableStencil() && drawable.hasRenderPass(parameters.pass)) {
|
||||
if (drawable.getIs3D()) {
|
||||
stencil3d = true;
|
||||
}
|
||||
if (!stencil3d && drawable.getTileID()) {
|
||||
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
|
||||
}
|
||||
}
|
||||
});
|
||||
parameters.renderTileClippingMasks(tileIDs);
|
||||
|
||||
// If we're doing 3D stenciling, set up the single-value stencil mask.
|
||||
// If we're doing 2D stenciling, render each tile with a different value.
|
||||
if (stencil3d) {
|
||||
stencilMode3d = parameters.stencilModeFor3D();
|
||||
} else {
|
||||
parameters.renderTileClippingMasks(tileIDs);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
@@ -86,6 +105,10 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
|
||||
tweaker->execute(drawable, parameters);
|
||||
}
|
||||
|
||||
if (stencil3d) {
|
||||
context.setStencilMode(drawable.getEnableStencil() ? stencilMode3d : gfx::StencilMode::disabled());
|
||||
}
|
||||
|
||||
drawable.draw(parameters);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user