Fix ui::painter_impl stencil implementation + support 255 recursive stencil levels
This commit is contained in:
parent
399250fe19
commit
484a5809ef
1 changed files with 17 additions and 16 deletions
|
|
@ -4,6 +4,7 @@
|
||||||
#include <psemek/gfx/mesh.hpp>
|
#include <psemek/gfx/mesh.hpp>
|
||||||
|
|
||||||
#include <psemek/util/overload.hpp>
|
#include <psemek/util/overload.hpp>
|
||||||
|
#include <psemek/util/to_string.hpp>
|
||||||
#include <psemek/log/log.hpp>
|
#include <psemek/log/log.hpp>
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
@ -218,7 +219,7 @@ void main()
|
||||||
gfx::mesh textured_mesh;
|
gfx::mesh textured_mesh;
|
||||||
|
|
||||||
int stencil_level = 0;
|
int stencil_level = 0;
|
||||||
static constexpr int max_stencil_level = 8;
|
static constexpr int max_stencil_level = 255;
|
||||||
std::vector<geom::box<float, 2>> stencil_bbox;
|
std::vector<geom::box<float, 2>> stencil_bbox;
|
||||||
|
|
||||||
geom::box<float, 2> draw_bbox;
|
geom::box<float, 2> draw_bbox;
|
||||||
|
|
@ -389,7 +390,7 @@ void main()
|
||||||
void painter_impl::begin_stencil()
|
void painter_impl::begin_stencil()
|
||||||
{
|
{
|
||||||
if (impl().stencil_level == impl().max_stencil_level)
|
if (impl().stencil_level == impl().max_stencil_level)
|
||||||
throw std::runtime_error("Only 8 recursive stencil levels are supported");
|
throw std::runtime_error(util::to_string("Only ", impl().max_stencil_level, " recursive stencil levels are supported"));
|
||||||
|
|
||||||
auto & batch = impl().batch<stencil_batch>({});
|
auto & batch = impl().batch<stencil_batch>({});
|
||||||
if (impl().stencil_level == 0)
|
if (impl().stencil_level == 0)
|
||||||
|
|
@ -398,12 +399,12 @@ void main()
|
||||||
batch.enable_depth = false;
|
batch.enable_depth = false;
|
||||||
|
|
||||||
batch.func = gl::EQUAL;
|
batch.func = gl::EQUAL;
|
||||||
batch.ref = 2 * (1 << impl().stencil_level) - 1;
|
batch.ref = impl().stencil_level;
|
||||||
batch.mask = (1 << impl().stencil_level) - 1;
|
batch.mask = -1;
|
||||||
|
|
||||||
batch.sfail = gl::KEEP;
|
batch.sfail = gl::KEEP;
|
||||||
batch.dfail = gl::KEEP;
|
batch.dfail = gl::KEEP;
|
||||||
batch.dpass = gl::REPLACE;
|
batch.dpass = gl::INCR;
|
||||||
|
|
||||||
++impl().stencil_level;
|
++impl().stencil_level;
|
||||||
impl().draw_bbox = {};
|
impl().draw_bbox = {};
|
||||||
|
|
@ -416,8 +417,8 @@ void main()
|
||||||
batch.enable_depth = true;
|
batch.enable_depth = true;
|
||||||
|
|
||||||
batch.func = gl::EQUAL;
|
batch.func = gl::EQUAL;
|
||||||
batch.ref = (1 << impl().stencil_level) - 1;
|
batch.ref = impl().stencil_level;
|
||||||
batch.mask = (1 << impl().stencil_level) - 1;
|
batch.mask = -1;
|
||||||
|
|
||||||
batch.sfail = gl::KEEP;
|
batch.sfail = gl::KEEP;
|
||||||
batch.dfail = gl::KEEP;
|
batch.dfail = gl::KEEP;
|
||||||
|
|
@ -428,14 +429,16 @@ void main()
|
||||||
|
|
||||||
void painter_impl::end_stencil()
|
void painter_impl::end_stencil()
|
||||||
{
|
{
|
||||||
|
--impl().stencil_level;
|
||||||
|
|
||||||
{
|
{
|
||||||
auto & clear_batch = impl().batch<stencil_batch>({});
|
auto & clear_batch = impl().batch<stencil_batch>({});
|
||||||
clear_batch.enable_color = false;
|
clear_batch.enable_color = false;
|
||||||
clear_batch.enable_depth = false;
|
clear_batch.enable_depth = false;
|
||||||
|
|
||||||
clear_batch.func = gl::EQUAL;
|
clear_batch.func = gl::GEQUAL;
|
||||||
clear_batch.ref = (1 << impl().stencil_level) / 2 - 1;
|
clear_batch.ref = impl().stencil_level;
|
||||||
clear_batch.mask = (1 << impl().stencil_level) / 2 - 1;
|
clear_batch.mask = -1;
|
||||||
|
|
||||||
clear_batch.sfail = gl::KEEP;
|
clear_batch.sfail = gl::KEEP;
|
||||||
clear_batch.dfail = gl::KEEP;
|
clear_batch.dfail = gl::KEEP;
|
||||||
|
|
@ -446,22 +449,20 @@ void main()
|
||||||
|
|
||||||
{
|
{
|
||||||
auto & batch = impl().batch<stencil_batch>({});
|
auto & batch = impl().batch<stencil_batch>({});
|
||||||
if (impl().stencil_level == 1)
|
if (impl().stencil_level == 0)
|
||||||
batch.enable_stencil = false;
|
batch.enable_stencil = false;
|
||||||
batch.enable_color = true;
|
batch.enable_color = true;
|
||||||
batch.enable_depth = true;
|
batch.enable_depth = true;
|
||||||
|
|
||||||
batch.func = gl::NEVER;
|
batch.func = gl::EQUAL;
|
||||||
batch.ref = 0;
|
batch.ref = impl().stencil_level;
|
||||||
batch.mask = 0;
|
batch.mask = -1;
|
||||||
|
|
||||||
batch.sfail = gl::KEEP;
|
batch.sfail = gl::KEEP;
|
||||||
batch.dfail = gl::KEEP;
|
batch.dfail = gl::KEEP;
|
||||||
batch.dpass = gl::KEEP;
|
batch.dpass = gl::KEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
--impl().stencil_level;
|
|
||||||
|
|
||||||
impl().stencil_bbox.pop_back();
|
impl().stencil_bbox.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue