Own brush workers and thin preview/platform seams

This commit is contained in:
2026-06-16 06:54:14 +02:00
parent a76560e3df
commit 56c4743e66
11 changed files with 415 additions and 180 deletions

View File

@@ -82,43 +82,6 @@ constexpr std::uint32_t kMixer = 3U;
constexpr std::uint32_t kReservedLinear = 4U;
}
struct StrokePreviewCompositePassInputs {
glm::vec2 resolution;
glm::vec2 pattern_scale;
const Brush& brush;
const pp::paint_renderer::CanvasStrokeCompositePassPlan& composite_pass;
Texture2D& background_texture;
Texture2D& stroke_texture;
Texture2D& dual_texture;
Sampler& linear_sampler;
Sampler& repeat_sampler;
std::function<void()> draw_composite;
StrokePreviewCompositePassInputs(
glm::vec2 resolution_in,
glm::vec2 pattern_scale_in,
const Brush& brush_in,
const pp::paint_renderer::CanvasStrokeCompositePassPlan& composite_pass_in,
Texture2D& background_texture_in,
Texture2D& stroke_texture_in,
Texture2D& dual_texture_in,
Sampler& linear_sampler_in,
Sampler& repeat_sampler_in,
std::function<void()> draw_composite_in)
: resolution(resolution_in)
, pattern_scale(pattern_scale_in)
, brush(brush_in)
, composite_pass(composite_pass_in)
, background_texture(background_texture_in)
, stroke_texture(stroke_texture_in)
, dual_texture(dual_texture_in)
, linear_sampler(linear_sampler_in)
, repeat_sampler(repeat_sampler_in)
, draw_composite(std::move(draw_composite_in))
{
}
};
pp::panopainter::LegacyNodeStrokePreviewMixPassRequest make_stroke_preview_mix_pass_request(
const Brush& brush,
glm::vec2 resolution) noexcept
@@ -232,65 +195,7 @@ pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_e
[&](int) {
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
background_texture.unbind();
});
}
void copy_stroke_preview_result_to_texture(Texture2D& texture, glm::vec2 size);
void execute_stroke_preview_final_composite_and_copy(
const StrokePreviewCompositePassInputs& inputs,
Texture2D& preview_texture,
glm::vec2 size)
{
pp::panopainter::execute_legacy_stroke_preview_final_composite(
[&] {
pp::panopainter::setup_legacy_stroke_composite_shader(
pp::panopainter::LegacyStrokeCompositeUniforms {
.resolution = inputs.resolution,
.pattern = {
.scale = inputs.pattern_scale,
.invert = static_cast<float>(inputs.brush.m_pattern_invert),
.brightness = inputs.brush.m_pattern_brightness,
.contrast = inputs.brush.m_pattern_contrast,
.depth = inputs.brush.m_pattern_depth,
.blend_mode = inputs.composite_pass.pattern_blend_mode,
.offset = glm::vec2(inputs.brush.m_pattern_rand_offset ? 0.5f : 0.0f),
},
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
.layer_alpha = 1.0f,
.alpha_lock = false,
.mask_enabled = false,
.use_fragcoord = false,
.blend_mode = inputs.brush.m_blend_mode,
.use_dual = inputs.composite_pass.use_dual,
.dual_blend_mode = inputs.composite_pass.dual_blend_mode,
.dual_alpha = inputs.composite_pass.dual_alpha,
.use_pattern = inputs.composite_pass.use_pattern,
});
},
[&] {
inputs.linear_sampler.bind(stroke_preview_composite_slots::kBackground);
inputs.linear_sampler.bind(stroke_preview_composite_slots::kStroke);
inputs.linear_sampler.bind(2U);
inputs.linear_sampler.bind(stroke_preview_composite_slots::kDual);
inputs.repeat_sampler.bind(stroke_preview_composite_slots::kPattern);
},
[&] {
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
inputs.background_texture.bind();
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
inputs.stroke_texture.bind();
set_active_texture_unit(stroke_preview_composite_slots::kDual);
inputs.dual_texture.bind();
set_active_texture_unit(stroke_preview_composite_slots::kPattern);
inputs.brush.m_pattern_texture ?
inputs.brush.m_pattern_texture->bind() :
unbind_texture_2d();
},
[&] {
inputs.draw_composite();
});
copy_stroke_preview_result_to_texture(preview_texture, size);
});
}
void copy_stroke_preview_framebuffer_to_texture(
@@ -500,22 +405,6 @@ void execute_stroke_preview_background_capture_pass(
assert(copy_status.ok());
}
void copy_stroke_preview_result_to_texture(Texture2D& preview_texture, glm::vec2 size)
{
const auto result = pp::paint_renderer::copy_stroke_preview_result_to_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::paint_renderer::StrokePreviewCopySize {
.width = static_cast<int>(size.x),
.height = static_cast<int>(size.y),
});
assert(result.ok());
}
}
std::atomic_int NodeStrokePreview::s_instances{ 0 };
@@ -841,22 +730,26 @@ void NodeStrokePreview::draw_stroke_immediate()
return false;
}
execute_stroke_preview_final_composite_and_copy(
StrokePreviewCompositePassInputs(
size,
glm::vec2(b->m_pattern_scale),
*b,
material.composite_pass,
m_tex_background,
m_tex,
m_tex_dual,
m_sampler_linear,
m_sampler_linear_repeat,
[&] {
m_plane.draw_fill();
}),
const bool final_composite_ok = pp::panopainter::execute_legacy_node_stroke_preview_final_composite(
size,
glm::vec2(b->m_pattern_scale),
*b,
material.composite_pass,
m_tex_background,
m_tex,
m_tex_dual,
m_tex_preview,
size);
m_sampler_linear,
m_sampler_linear_repeat,
[&] {
b->m_pattern_texture ? b->m_pattern_texture->bind() : unbind_texture_2d();
},
[&] {
m_plane.draw_fill();
});
if (!final_composite_ok) {
return false;
}
return true;
}();
assert(sequence_ok);