Share retained stroke preview sample helper

This commit is contained in:
2026-06-13 10:36:07 +02:00
parent 323abdea57
commit 24c0452229
4 changed files with 109 additions and 42 deletions

View File

@@ -258,6 +258,93 @@ void bind_stroke_preview_main_pass_textures(
uses_mixer ? mixer_rtt.bindTexture() : unbind_texture_2d();
}
void bind_stroke_preview_destination_texture(Texture2D& texture)
{
set_active_texture_unit(stroke_preview_live_slots::kDestination);
texture.bind();
}
void unbind_stroke_preview_destination_texture(Texture2D& texture)
{
set_active_texture_unit(stroke_preview_live_slots::kDestination);
texture.unbind();
}
void copy_stroke_preview_destination_texture_region(
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);
}
std::array<pp::paint_renderer::CanvasStrokePoint, 4> make_stroke_preview_sample_points(
const std::array<vertex_t, 4>& vertices)
{
return {
pp::paint_renderer::CanvasStrokePoint { .x = vertices[0].pos.x, .y = vertices[0].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = vertices[1].pos.x, .y = vertices[1].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = vertices[2].pos.x, .y = vertices[2].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = vertices[3].pos.x, .y = vertices[3].pos.y },
};
}
void upload_stroke_preview_brush_vertices(DynamicShape& brush_shape, std::span<const vertex_t> vertices)
{
brush_shape.update_vertices(
const_cast<vertex_t*>(vertices.data()),
static_cast<int>(vertices.size()));
}
glm::vec4 execute_stroke_preview_sample_pass(
std::array<vertex_t, 4>& vertices,
glm::vec2 target_size,
Texture2D& blend_texture,
DynamicShape& brush_shape,
bool copy_stroke_destination)
{
const auto sample_points = make_stroke_preview_sample_points(vertices);
const auto result = pp::panopainter::execute_legacy_canvas_stroke_sample(
pp::panopainter::LegacyStrokeSampleExecutionRequest {
.context = "NodeStrokePreview::stroke_draw_samples",
.target_size = target_size,
.vertices = vertices,
.sample_points = sample_points,
.copy_stroke_destination = copy_stroke_destination,
.bind_destination_texture = [&] {
bind_stroke_preview_destination_texture(blend_texture);
},
.copy_framebuffer_to_destination_texture = [](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
copy_stroke_preview_destination_texture_region(
src_x,
src_y,
dst_x,
dst_y,
width,
height);
},
.unbind_destination_texture = [&] {
unbind_stroke_preview_destination_texture(blend_texture);
},
.upload_brush_vertices = [&](std::span<const vertex_t> brush_vertices) {
upload_stroke_preview_brush_vertices(brush_shape, brush_vertices);
},
.draw_brush_shape = [&] {
brush_shape.draw_fill();
},
});
return result.dirty_bounds;
}
void execute_stroke_preview_background_capture_pass(
glm::vec2 size,
bool colorize,
@@ -486,48 +573,12 @@ glm::vec4 NodeStrokePreview::stroke_draw_samples(
bool copy_stroke_destination)
{
const glm::vec2 size = { m_rtt.getWidth(), m_rtt.getHeight() };
const std::array<pp::paint_renderer::CanvasStrokePoint, 4> sample_points {
pp::paint_renderer::CanvasStrokePoint { .x = P[0].pos.x, .y = P[0].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = P[1].pos.x, .y = P[1].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = P[2].pos.x, .y = P[2].pos.y },
pp::paint_renderer::CanvasStrokePoint { .x = P[3].pos.x, .y = P[3].pos.y },
};
const auto result = pp::panopainter::execute_legacy_canvas_stroke_sample(
pp::panopainter::LegacyStrokeSampleExecutionRequest {
.context = "NodeStrokePreview::stroke_draw_samples",
.target_size = size,
.vertices = P,
.sample_points = sample_points,
.copy_stroke_destination = copy_stroke_destination,
.bind_destination_texture = [&] {
set_active_texture_unit(1U);
blend_tex.bind(); // bg, copy of framebuffer (copied before drawing)
},
.copy_framebuffer_to_destination_texture = [](
int src_x,
int src_y,
int dst_x,
int dst_y,
int width,
int height) {
// this is also used by the mixer
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
},
.unbind_destination_texture = [&] {
set_active_texture_unit(1U);
blend_tex.unbind();
},
.upload_brush_vertices = [&](std::span<const vertex_t> vertices) {
m_brush_shape.update_vertices(
const_cast<vertex_t*>(vertices.data()),
static_cast<int>(vertices.size()));
},
.draw_brush_shape = [&] {
m_brush_shape.draw_fill();
},
});
return result.dirty_bounds;
return execute_stroke_preview_sample_pass(
P,
size,
blend_tex,
m_brush_shape,
copy_stroke_destination);
}
std::vector<NodeStrokePreview::StrokeFrame> NodeStrokePreview::stroke_draw_compute(Stroke& stroke, float zoom) const