Share retained stroke preview binding helpers

This commit is contained in:
2026-06-13 10:27:50 +02:00
parent ddadaa0405
commit 3f071620dc
4 changed files with 145 additions and 67 deletions

View File

@@ -103,6 +103,14 @@ constexpr std::uint32_t kDual = 3U;
constexpr std::uint32_t kPattern = 4U;
}
namespace stroke_preview_live_slots {
constexpr std::uint32_t kTip = 0U;
constexpr std::uint32_t kDestination = 1U;
constexpr std::uint32_t kPattern = 2U;
constexpr std::uint32_t kMixer = 3U;
constexpr std::uint32_t kReservedLinear = 4U;
}
struct StrokePreviewCompositePassInputs {
glm::vec2 resolution;
glm::vec2 pattern_scale;
@@ -203,6 +211,110 @@ void copy_stroke_preview_framebuffer_to_texture(
static_cast<int>(size.y));
}
void bind_stroke_preview_live_samplers(
Sampler& mipmap_sampler,
Sampler& linear_sampler,
Sampler& repeat_sampler)
{
mipmap_sampler.bind(stroke_preview_live_slots::kTip);
linear_sampler.bind(stroke_preview_live_slots::kDestination);
repeat_sampler.bind(stroke_preview_live_slots::kPattern);
linear_sampler.bind(stroke_preview_live_slots::kMixer);
linear_sampler.bind(stroke_preview_live_slots::kReservedLinear);
}
void bind_stroke_preview_dual_pass_textures(const Brush& dual_brush)
{
set_active_texture_unit(stroke_preview_live_slots::kTip);
dual_brush.m_tip_texture ?
dual_brush.m_tip_texture->bind() :
unbind_texture_2d();
}
void bind_stroke_preview_main_pass_textures(
const Brush& brush,
Texture2D& stroke_destination_texture,
RTT& mixer_rtt,
bool copy_stroke_destination,
bool uses_mixer)
{
set_active_texture_unit(stroke_preview_live_slots::kTip);
brush.m_tip_texture ?
brush.m_tip_texture->bind() :
unbind_texture_2d();
if (copy_stroke_destination)
{
set_active_texture_unit(stroke_preview_live_slots::kDestination);
stroke_destination_texture.bind();
}
set_active_texture_unit(stroke_preview_live_slots::kPattern);
brush.m_pattern_texture ?
brush.m_pattern_texture->bind() :
unbind_texture_2d();
set_active_texture_unit(stroke_preview_live_slots::kMixer);
uses_mixer ? mixer_rtt.bindTexture() : unbind_texture_2d();
}
void execute_stroke_preview_background_capture_pass(
glm::vec2 size,
bool colorize,
Texture2D& background_texture,
const std::function<void()>& draw_checkerboard)
{
pp::panopainter::execute_legacy_stroke_preview_background_capture(
[&] {
const float aspect = size.x / size.y;
pp::panopainter::setup_legacy_canvas_draw_merge_checkerboard_shader(
pp::panopainter::LegacyCanvasDrawMergeCheckerboardUniforms {
.mvp = glm::ortho(-.5f, .5f, -.5f / aspect, .5f / aspect, -1.f, 1.f),
.colorize = colorize,
});
},
[&] {
draw_checkerboard();
},
[&] {
background_texture.bind();
},
[](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
},
pp::panopainter::LegacyStrokePreviewCopySize {
.width = static_cast<int>(size.x),
.height = static_cast<int>(size.y),
});
}
void copy_stroke_preview_result_to_texture(Texture2D& preview_texture, glm::vec2 size)
{
pp::panopainter::copy_legacy_stroke_preview_texture(
[&] {
preview_texture.bind();
},
[](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
},
pp::panopainter::LegacyStrokePreviewCopySize {
.width = static_cast<int>(size.x),
.height = static_cast<int>(size.y),
});
}
template <typename ClearTarget, typename ComputeFrames, typename BeforeFrame, typename DrawSample>
void execute_stroke_preview_live_pass(
Texture2D& output_texture,
@@ -471,11 +583,10 @@ void NodeStrokePreview::draw_stroke_immediate()
apply_stroke_preview_viewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
m_rtt.bindFramebuffer();
m_rtt.clear();
m_sampler_mipmap.bind(0);
m_sampler_linear.bind(1);
m_sampler_linear_repeat.bind(2);
m_sampler_linear.bind(3);
m_sampler_linear.bind(4);
bind_stroke_preview_live_samplers(
m_sampler_mipmap,
m_sampler_linear,
m_sampler_linear_repeat);
const auto& b = m_brush;
@@ -581,10 +692,7 @@ void NodeStrokePreview::draw_stroke_immediate()
if (material.dual_pass.enabled)
{
pp::panopainter::setup_legacy_stroke_dual_shader(material.dual_pass.uses_pattern);
set_active_texture_unit(0U);
dual_brush->m_tip_texture ?
dual_brush->m_tip_texture->bind() :
unbind_texture_2d();
bind_stroke_preview_dual_pass_textures(*dual_brush);
execute_stroke_preview_live_pass(
m_tex_dual,
size,
@@ -605,35 +713,12 @@ void NodeStrokePreview::draw_stroke_immediate()
// CHEKCERBOARD
pp::panopainter::execute_legacy_stroke_preview_background_capture(
[&] {
// copy background color to tex2
const float aspect = size.x / size.y;
pp::panopainter::setup_legacy_canvas_draw_merge_checkerboard_shader(
pp::panopainter::LegacyCanvasDrawMergeCheckerboardUniforms {
.mvp = glm::ortho(-.5f, .5f, -.5f / aspect, .5f / aspect, -1.f, 1.f),
.colorize = b->m_tip_mix > 0.f || b->m_blend_mode != 0,
});
},
execute_stroke_preview_background_capture_pass(
size,
b->m_tip_mix > 0.f || b->m_blend_mode != 0,
m_tex_background,
[&] {
m_plane.draw_fill();
},
[&] {
//m_rtt.clear({ .3f, .3f, .3f, 1.f });
m_tex_background.bind();
},
[](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
},
pp::panopainter::LegacyStrokePreviewCopySize {
.width = static_cast<int>(size.x),
.height = static_cast<int>(size.y),
});
// DRAW MAIN BRUSH
@@ -645,19 +730,12 @@ void NodeStrokePreview::draw_stroke_immediate()
b->m_tip_wet,
b->m_tip_noise);
set_active_texture_unit(0U);
b->m_tip_texture->bind();
if (copy_stroke_destination)
{
set_active_texture_unit(1U);
m_tex.bind(); // tmp swap for blending
}
set_active_texture_unit(2U);
b->m_pattern_texture ?
b->m_pattern_texture->bind() :
unbind_texture_2d();
set_active_texture_unit(3U);
preview_composite_plan.uses_mixer ? m_rtt_mixer.bindTexture() : unbind_texture_2d();
bind_stroke_preview_main_pass_textures(
*b,
m_tex,
m_rtt_mixer,
copy_stroke_destination,
preview_composite_plan.uses_mixer);
execute_stroke_preview_live_pass(
m_tex,
size,
@@ -682,7 +760,7 @@ void NodeStrokePreview::draw_stroke_immediate()
[&](auto& frame, Texture2D& blend_texture, bool copy_destination) {
/*auto rect =*/ stroke_draw_samples(frame.shapes, blend_texture, copy_destination);
});
set_active_texture_unit(3U);
set_active_texture_unit(stroke_preview_live_slots::kMixer);
m_rtt_mixer.unbindTexture();
// COMPOSITE
@@ -704,23 +782,7 @@ void NodeStrokePreview::draw_stroke_immediate()
});
// copy the result to the actual preview
pp::panopainter::copy_legacy_stroke_preview_texture(
[&] {
m_tex_preview.bind();
},
[](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
},
pp::panopainter::LegacyStrokePreviewCopySize {
.width = static_cast<int>(size.x),
.height = static_cast<int>(size.y),
});
copy_stroke_preview_result_to_texture(m_tex_preview, size);
m_rtt.unbindFramebuffer();