Make stencil mode selection more explicit to fix 3D mode with no stenciling (#1369)

This commit is contained in:
Tim Sylvester
2023-07-13 12:34:14 -07:00
committed by Bart Louwers
parent 4a4389ab9b
commit 996b388601

View File

@@ -51,6 +51,8 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
// `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.
// 2D and 3D features in the same layer group is not supported.
bool features3d = false;
bool stencil3d = false;
gfx::StencilMode stencilMode3d;
@@ -63,21 +65,27 @@ 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.getEnableStencil() && drawable.hasRenderPass(parameters.pass)) {
if (drawable.getIs3D()) {
if (!drawable.getEnabled() || !drawable.hasRenderPass(parameters.pass)) {
return;
}
if (drawable.getIs3D()) {
features3d = true;
if (drawable.getEnableStencil()) {
stencil3d = true;
}
if (!stencil3d && drawable.getTileID()) {
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
}
}
if (!features3d && drawable.getEnableStencil() && drawable.getTileID()) {
tileIDs.emplace(drawable.getTileID()->toUnwrapped());
}
});
// 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 {
// If we're doing 3D stenciling and have any features
// to draw, set up the single-value stencil mask.
// If we're doing 2D stenciling and have any drawables with tile IDs,
// render each tile into the stencil buffer with a different value.
if (features3d) {
stencilMode3d = stencil3d ? parameters.stencilModeFor3D() : gfx::StencilMode::disabled();
} else if (!tileIDs.empty()) {
parameters.renderTileClippingMasks(tileIDs);
}
}
@@ -105,7 +113,10 @@ void TileLayerGroupGL::render(RenderOrchestrator&, PaintParameters& parameters)
tweaker->execute(drawable, parameters);
}
if (stencil3d) {
// For layer groups with 3D features, enable either the single-value
// stencil mode for features with stencil enabled or disable stenciling.
// 2D drawables will set their own stencil mode within `draw`.
if (features3d) {
context.setStencilMode(drawable.getEnableStencil() ? stencilMode3d : gfx::StencilMode::disabled());
}