Narrow retained canvas stroke execution helpers
This commit is contained in:
268
src/canvas.cpp
268
src/canvas.cpp
@@ -753,45 +753,41 @@ void Canvas::stroke_draw()
|
||||
{
|
||||
set_active_texture_unit(1);
|
||||
}
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!box_dirty[i])
|
||||
continue;
|
||||
const auto pad_region = pp::panopainter::plan_legacy_canvas_stroke_pad_region(
|
||||
pp::panopainter::LegacyCanvasStrokePadRegionRequest {
|
||||
.extent = stroke_extent,
|
||||
.pass_dirty_box = box_face[i],
|
||||
});
|
||||
if (!pad_region.has_pixels)
|
||||
continue;
|
||||
// B(xw)--(zw)C box
|
||||
// | // | coordinates
|
||||
// A(xy)--(zy)D mapping
|
||||
std::array<vertex_t, 6> pad_quad = {
|
||||
vertex_t({pad_region.ndc_quad[0].x, pad_region.ndc_quad[0].y}), // A
|
||||
vertex_t({pad_region.ndc_quad[1].x, pad_region.ndc_quad[1].y}), // B
|
||||
vertex_t({pad_region.ndc_quad[2].x, pad_region.ndc_quad[2].y}), // C
|
||||
vertex_t({pad_region.ndc_quad[3].x, pad_region.ndc_quad[3].y}), // A
|
||||
vertex_t({pad_region.ndc_quad[4].x, pad_region.ndc_quad[4].y}), // C
|
||||
vertex_t({pad_region.ndc_quad[5].x, pad_region.ndc_quad[5].y}), // D
|
||||
};
|
||||
m_brush_shape.update_vertices(pad_quad.data(), pad_quad.size());
|
||||
const std::array<pp::panopainter::LegacyCanvasStrokePadFace, 6> pad_faces = {
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 0, .dirty = box_dirty[0], .pass_dirty_box = box_face[0] },
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 1, .dirty = box_dirty[1], .pass_dirty_box = box_face[1] },
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 2, .dirty = box_dirty[2], .pass_dirty_box = box_face[2] },
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 3, .dirty = box_dirty[3], .pass_dirty_box = box_face[3] },
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 4, .dirty = box_dirty[4], .pass_dirty_box = box_face[4] },
|
||||
pp::panopainter::LegacyCanvasStrokePadFace { .index = 5, .dirty = box_dirty[5], .pass_dirty_box = box_face[5] },
|
||||
};
|
||||
[[maybe_unused]] const auto pad_result = pp::panopainter::execute_legacy_canvas_stroke_pad_faces(
|
||||
pp::panopainter::LegacyCanvasStrokePadExecutionRequest {
|
||||
.context = "Canvas::stroke_draw",
|
||||
.extent = stroke_extent,
|
||||
.faces = pad_faces,
|
||||
.execute_face =
|
||||
[&](int face_index,
|
||||
const pp::panopainter::LegacyCanvasStrokePadRegionResult& pad_region,
|
||||
std::span<vertex_t> pad_quad) {
|
||||
m_brush_shape.update_vertices(pad_quad.data(), pad_quad.size());
|
||||
|
||||
m_tmp[i].bindFramebuffer();
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
m_tex[i].bind();
|
||||
copy_framebuffer_to_texture_2d(
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.width,
|
||||
pad_region.copy_region.height);
|
||||
}
|
||||
m_brush_shape.draw_fill();
|
||||
m_tmp[i].unbindFramebuffer();
|
||||
}
|
||||
m_tmp[face_index].bindFramebuffer();
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
m_tex[face_index].bind();
|
||||
copy_framebuffer_to_texture_2d(
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.x,
|
||||
pad_region.copy_region.y,
|
||||
pad_region.copy_region.width,
|
||||
pad_region.copy_region.height);
|
||||
}
|
||||
m_brush_shape.draw_fill();
|
||||
m_tmp[face_index].unbindFramebuffer();
|
||||
},
|
||||
});
|
||||
if (copy_stroke_destination)
|
||||
{
|
||||
unbind_texture_2d();
|
||||
@@ -1047,104 +1043,128 @@ void Canvas::stroke_commit()
|
||||
m_tex2[i].unbind();
|
||||
},
|
||||
.bind_commit_inputs = [&](int i) {
|
||||
m_tmp[i].bindTexture();
|
||||
set_active_texture_unit(1);
|
||||
m_tex2[i].bind();
|
||||
m_sampler.bind(0);
|
||||
m_sampler_nearest.bind(1);
|
||||
m_sampler.bind(2);
|
||||
m_sampler.bind(3);
|
||||
m_sampler_stencil.bind(4);
|
||||
},
|
||||
.execute_erase_composite = [&](int i) {
|
||||
pp::panopainter::setup_legacy_stroke_erase_shader(
|
||||
pp::panopainter::LegacyStrokeEraseUniforms {
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.texture_slot = 0,
|
||||
.stroke_texture_slot = 1,
|
||||
.mask_texture_slot = 2,
|
||||
.alpha = 1.0f,
|
||||
.mask_enabled = m_smask_active,
|
||||
pp::panopainter::bind_legacy_canvas_stroke_commit_inputs(
|
||||
sequence,
|
||||
[&](int texture_slot) {
|
||||
set_active_texture_unit(texture_slot);
|
||||
},
|
||||
[&](pp::paint_renderer::CanvasStrokeCommitTextureRole role) {
|
||||
switch (role) {
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::layer_scratch:
|
||||
m_tex2[i].bind();
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::stroke:
|
||||
m_tmp[i].bindTexture();
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::selection_mask:
|
||||
m_smask.rtt(i).bindTexture();
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::dual_stroke:
|
||||
m_tmp_dual[i].bindTexture();
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::pattern:
|
||||
b->m_pattern_texture ? b->m_pattern_texture->bind() : unbind_texture_2d();
|
||||
break;
|
||||
}
|
||||
},
|
||||
[&](pp::paint_renderer::CanvasStrokeCommitTextureRole role, int texture_slot) {
|
||||
switch (role) {
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::layer_scratch:
|
||||
m_sampler.bind(texture_slot);
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::stroke:
|
||||
m_sampler_nearest.bind(texture_slot);
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::selection_mask:
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::dual_stroke:
|
||||
m_sampler.bind(texture_slot);
|
||||
break;
|
||||
case pp::paint_renderer::CanvasStrokeCommitTextureRole::pattern:
|
||||
m_sampler_stencil.bind(texture_slot);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
set_active_texture_unit(0);
|
||||
m_tex2[i].bind();
|
||||
set_active_texture_unit(1);
|
||||
m_tmp[i].bindTexture();
|
||||
set_active_texture_unit(2);
|
||||
m_smask.rtt(i).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_smask.rtt(i).unbindTexture();
|
||||
set_active_texture_unit(1);
|
||||
m_tmp[i].unbindTexture();
|
||||
set_active_texture_unit(0);
|
||||
m_tex2[i].unbind();
|
||||
},
|
||||
.execute_paint_composite = [&](int i) {
|
||||
.execute_erase_composite = [&](int) {
|
||||
pp::panopainter::execute_legacy_canvas_stroke_commit_erase(
|
||||
[&]() {
|
||||
pp::panopainter::setup_legacy_stroke_erase_shader(
|
||||
pp::panopainter::LegacyStrokeEraseUniforms {
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.texture_slot = 0,
|
||||
.stroke_texture_slot = 1,
|
||||
.mask_texture_slot = 2,
|
||||
.alpha = 1.0f,
|
||||
.mask_enabled = m_smask_active,
|
||||
});
|
||||
},
|
||||
[&]() {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
.execute_paint_composite = [&](int) {
|
||||
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
||||
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = m_size,
|
||||
.pattern = {
|
||||
.scale = patt_scale,
|
||||
.invert = static_cast<float>(b->m_pattern_invert),
|
||||
.brightness = b->m_pattern_brightness,
|
||||
.contrast = b->m_pattern_contrast,
|
||||
.depth = b->m_pattern_depth,
|
||||
.blend_mode = b->m_pattern_blend_mode,
|
||||
.offset = m_pattern_offset,
|
||||
},
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.layer_alpha = 1.0f,
|
||||
.alpha_lock = m_layers[m_current_layer_idx]->m_alpha_locked,
|
||||
.mask_enabled = m_smask_active,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = b->m_blend_mode,
|
||||
.use_dual = stroke_material.composite_pass.use_dual,
|
||||
.dual_blend_mode = stroke_material.composite_pass.dual_blend_mode,
|
||||
.dual_alpha = stroke_material.composite_pass.dual_alpha,
|
||||
.use_pattern = stroke_material.composite_pass.use_pattern,
|
||||
pp::panopainter::execute_legacy_canvas_stroke_commit_paint(
|
||||
[&]() {
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = m_size,
|
||||
.pattern = {
|
||||
.scale = patt_scale,
|
||||
.invert = static_cast<float>(b->m_pattern_invert),
|
||||
.brightness = b->m_pattern_brightness,
|
||||
.contrast = b->m_pattern_contrast,
|
||||
.depth = b->m_pattern_depth,
|
||||
.blend_mode = b->m_pattern_blend_mode,
|
||||
.offset = m_pattern_offset,
|
||||
},
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
.layer_alpha = 1.0f,
|
||||
.alpha_lock = m_layers[m_current_layer_idx]->m_alpha_locked,
|
||||
.mask_enabled = m_smask_active,
|
||||
.use_fragcoord = false,
|
||||
.blend_mode = b->m_blend_mode,
|
||||
.use_dual = stroke_material.composite_pass.use_dual,
|
||||
.dual_blend_mode = stroke_material.composite_pass.dual_blend_mode,
|
||||
.dual_alpha = stroke_material.composite_pass.dual_alpha,
|
||||
.use_pattern = stroke_material.composite_pass.use_pattern,
|
||||
});
|
||||
},
|
||||
[&]() {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
|
||||
set_active_texture_unit(0);
|
||||
m_tex2[i].bind();
|
||||
set_active_texture_unit(1);
|
||||
m_tmp[i].bindTexture();
|
||||
set_active_texture_unit(2);
|
||||
m_smask.rtt(i).bindTexture();
|
||||
set_active_texture_unit(3);
|
||||
if (stroke_material.composite_pass.use_dual)
|
||||
m_tmp_dual[i].bindTexture();
|
||||
set_active_texture_unit(4);
|
||||
b->m_pattern_texture ?
|
||||
b->m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
m_plane.draw_fill();
|
||||
set_active_texture_unit(3);
|
||||
if (stroke_material.composite_pass.use_dual)
|
||||
m_tmp_dual[i].unbindTexture();
|
||||
set_active_texture_unit(2);
|
||||
m_smask.rtt(i).unbindTexture();
|
||||
set_active_texture_unit(1);
|
||||
m_tmp[i].unbindTexture();
|
||||
set_active_texture_unit(0);
|
||||
m_tex2[i].unbind();
|
||||
},
|
||||
.copy_committed_to_dilate_source = [&](int i) {
|
||||
// Dilate borders to avoid interpolation bleeding
|
||||
pp::panopainter::setup_legacy_stroke_dilate_shader(
|
||||
pp::panopainter::LegacyStrokeDilateUniforms {
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
pp::panopainter::copy_legacy_canvas_stroke_commit_to_dilate_source(
|
||||
sequence,
|
||||
[&]() {
|
||||
// Dilate borders to avoid interpolation bleeding
|
||||
pp::panopainter::setup_legacy_stroke_dilate_shader(
|
||||
pp::panopainter::LegacyStrokeDilateUniforms {
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
});
|
||||
},
|
||||
[&](int texture_slot) {
|
||||
set_active_texture_unit(texture_slot);
|
||||
},
|
||||
[&]() {
|
||||
m_tex2[i].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::LegacyCanvasStrokeCommitCopyExtent {
|
||||
.width = m_width,
|
||||
.height = m_height,
|
||||
});
|
||||
set_active_texture_unit(0);
|
||||
m_tex2[i].bind();
|
||||
copy_framebuffer_to_texture_2d(0, 0, 0, 0, m_width, m_height);
|
||||
},
|
||||
.execute_commit_dilate = [&](int) {
|
||||
m_plane.draw_fill();
|
||||
pp::panopainter::execute_legacy_canvas_stroke_commit_dilate([&]() {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
.unbind_layer_framebuffer = [&](int i) {
|
||||
m_layers[m_current_layer_idx]->rtt(i).unbindFramebuffer();
|
||||
|
||||
Reference in New Issue
Block a user