Reduce retained stroke preview helper surface
This commit is contained in:
131
src/canvas.cpp
131
src/canvas.cpp
@@ -1741,18 +1741,79 @@ void Canvas::stroke_draw_dual_pass(
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyCanvasStrokeMainPassExecutionRequest Canvas::make_stroke_draw_main_pass_request(
|
||||
const Brush& brush,
|
||||
std::function<void()> bind_samplers,
|
||||
std::function<void()> bind_textures,
|
||||
std::function<void()> execute_frame_pass,
|
||||
std::function<void()> unbind_textures,
|
||||
std::function<void()> unbind_samplers)
|
||||
{
|
||||
constexpr std::array main_pass_texture_bindings {
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||
.slot = 0,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination,
|
||||
.slot = 1,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::pattern,
|
||||
.slot = 2,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||
.slot = 3,
|
||||
},
|
||||
};
|
||||
constexpr std::array main_pass_texture_unbindings {
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||
.slot = 3,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::stroke_destination,
|
||||
.slot = 1,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||
.slot = 0,
|
||||
},
|
||||
};
|
||||
const auto main_pass_texture_dispatch = pp::panopainter::make_legacy_canvas_stroke_main_pass_texture_dispatch(
|
||||
[&](int texture_slot) {
|
||||
set_active_texture_unit(texture_slot);
|
||||
},
|
||||
[&] {
|
||||
brush.m_tip_texture->bind();
|
||||
},
|
||||
[&] {
|
||||
brush.m_tip_texture->unbind();
|
||||
},
|
||||
[&] {
|
||||
brush.m_pattern_texture ?
|
||||
brush.m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
},
|
||||
[&] {
|
||||
m_mixer.bindTexture();
|
||||
},
|
||||
[&] {
|
||||
m_mixer.unbindTexture();
|
||||
});
|
||||
|
||||
return pp::panopainter::make_legacy_canvas_stroke_main_pass_execution_request(
|
||||
"Canvas::stroke_draw",
|
||||
std::move(bind_samplers),
|
||||
std::move(bind_textures),
|
||||
[&] {
|
||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_bindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
std::move(execute_frame_pass),
|
||||
std::move(unbind_textures),
|
||||
[&] {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_unbindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
std::move(unbind_samplers));
|
||||
}
|
||||
|
||||
@@ -1872,20 +1933,6 @@ void Canvas::stroke_draw()
|
||||
});
|
||||
|
||||
// DRAW MAIN BRUSH
|
||||
constexpr std::array main_pass_texture_bindings {
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||
.slot = 0,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::pattern,
|
||||
.slot = 2,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||
.slot = 3,
|
||||
},
|
||||
};
|
||||
constexpr std::array live_pass_sampler_bindings {
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||
@@ -1904,16 +1951,6 @@ void Canvas::stroke_draw()
|
||||
.slot = 3,
|
||||
},
|
||||
};
|
||||
constexpr std::array main_pass_texture_unbindings {
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::mixer,
|
||||
.slot = 3,
|
||||
},
|
||||
pp::panopainter::LegacyCanvasStrokeTextureBinding {
|
||||
.input = pp::panopainter::LegacyCanvasStrokeTextureInput::brush_tip,
|
||||
.slot = 0,
|
||||
},
|
||||
};
|
||||
const pp::panopainter::LegacyCanvasStrokeSamplerDispatch live_pass_sampler_dispatch =
|
||||
pp::panopainter::make_legacy_canvas_stroke_live_pass_sampler_dispatch(
|
||||
[&](int slot) {
|
||||
@@ -1937,30 +1974,9 @@ void Canvas::stroke_draw()
|
||||
[&](int slot) {
|
||||
m_sampler.bind(slot);
|
||||
},
|
||||
[&] {
|
||||
m_sampler.unbind();
|
||||
});
|
||||
const auto main_pass_texture_dispatch = pp::panopainter::make_legacy_canvas_stroke_main_pass_texture_dispatch(
|
||||
[&](int texture_slot) {
|
||||
set_active_texture_unit(texture_slot);
|
||||
},
|
||||
[&] {
|
||||
brush->m_tip_texture->bind();
|
||||
},
|
||||
[&] {
|
||||
brush->m_tip_texture->unbind();
|
||||
},
|
||||
[&] {
|
||||
brush->m_pattern_texture ?
|
||||
brush->m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
},
|
||||
[&] {
|
||||
m_mixer.bindTexture();
|
||||
},
|
||||
[&] {
|
||||
m_mixer.unbindTexture();
|
||||
});
|
||||
[&] {
|
||||
m_sampler.unbind();
|
||||
});
|
||||
auto frames = stroke_draw_compute(*m_current_stroke);
|
||||
|
||||
std::array<glm::vec4, 6> box_face = SIXPLETTE(glm::vec4(m_size, 0, 0));
|
||||
@@ -1970,16 +1986,12 @@ void Canvas::stroke_draw()
|
||||
[[maybe_unused]] const auto main_pass_result =
|
||||
pp::panopainter::execute_legacy_canvas_stroke_main_pass(
|
||||
make_stroke_draw_main_pass_request(
|
||||
*brush,
|
||||
[&] {
|
||||
pp::panopainter::bind_legacy_canvas_stroke_sampler_inputs(
|
||||
live_pass_sampler_bindings,
|
||||
live_pass_sampler_dispatch);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::bind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_bindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::execute_legacy_canvas_stroke_main_pass_frame_callbacks(
|
||||
frames,
|
||||
@@ -2010,11 +2022,6 @@ void Canvas::stroke_draw()
|
||||
},
|
||||
m_tmp);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_texture_inputs(
|
||||
main_pass_texture_unbindings,
|
||||
main_pass_texture_dispatch);
|
||||
},
|
||||
[&] {
|
||||
pp::panopainter::unbind_legacy_canvas_stroke_sampler_inputs(
|
||||
live_pass_sampler_bindings,
|
||||
|
||||
@@ -295,10 +295,9 @@ private:
|
||||
bool uses_pattern,
|
||||
bool copy_stroke_destination);
|
||||
pp::panopainter::LegacyCanvasStrokeMainPassExecutionRequest make_stroke_draw_main_pass_request(
|
||||
const Brush& brush,
|
||||
std::function<void()> bind_samplers,
|
||||
std::function<void()> bind_textures,
|
||||
std::function<void()> execute_frame_pass,
|
||||
std::function<void()> unbind_textures,
|
||||
std::function<void()> unbind_samplers);
|
||||
pp::panopainter::LegacyCanvasStrokeDualPassRequest make_stroke_draw_dual_pass_request(
|
||||
const std::vector<StrokeFrame>& frames_dual,
|
||||
|
||||
@@ -5,11 +5,6 @@
|
||||
|
||||
namespace pp::panopainter {
|
||||
|
||||
struct LegacyStrokePreviewCopySize {
|
||||
int width = 0;
|
||||
int height = 0;
|
||||
};
|
||||
|
||||
struct LegacyVrColorUniforms {
|
||||
glm::vec4 color { 1.0f };
|
||||
glm::mat4 mvp { 1.0f };
|
||||
@@ -40,24 +35,6 @@ inline void setup_legacy_vr_stroke_preview_shader(const LegacyVrStrokePreviewUni
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, uniforms.mvp);
|
||||
}
|
||||
|
||||
template <
|
||||
typename SetupCheckerboard,
|
||||
typename DrawPlane,
|
||||
typename BindBackgroundTexture,
|
||||
typename CopyFramebufferToTexture>
|
||||
void execute_legacy_stroke_preview_background_capture(
|
||||
SetupCheckerboard&& setup_checkerboard,
|
||||
DrawPlane&& draw_plane,
|
||||
BindBackgroundTexture&& bind_background_texture,
|
||||
CopyFramebufferToTexture&& copy_framebuffer_to_texture,
|
||||
LegacyStrokePreviewCopySize copy_size)
|
||||
{
|
||||
setup_checkerboard();
|
||||
draw_plane();
|
||||
bind_background_texture();
|
||||
copy_framebuffer_to_texture(0, 0, 0, 0, copy_size.width, copy_size.height);
|
||||
}
|
||||
|
||||
template <
|
||||
typename SetupCompositeShader,
|
||||
typename BindCompositeSamplers,
|
||||
@@ -100,14 +77,4 @@ void execute_legacy_stroke_preview_live_pass(
|
||||
copy_preview_result();
|
||||
}
|
||||
|
||||
template <typename BindPreviewTexture, typename CopyFramebufferToTexture>
|
||||
void copy_legacy_stroke_preview_texture(
|
||||
BindPreviewTexture&& bind_preview_texture,
|
||||
CopyFramebufferToTexture&& copy_framebuffer_to_texture,
|
||||
LegacyStrokePreviewCopySize copy_size)
|
||||
{
|
||||
bind_preview_texture();
|
||||
copy_framebuffer_to_texture(0, 0, 0, 0, copy_size.width, copy_size.height);
|
||||
}
|
||||
|
||||
} // namespace pp::panopainter
|
||||
|
||||
@@ -92,24 +92,6 @@ struct LegacyNodeStrokePreviewMixPassRequest {
|
||||
int blend_mode = 0;
|
||||
};
|
||||
|
||||
struct LegacyNodeStrokePreviewMixExecutionRequest {
|
||||
LegacyNodeStrokePreviewMixPassPlan::ShaderPlan shader {};
|
||||
int mixer_width = 0;
|
||||
int mixer_height = 0;
|
||||
int scissor_x = 0;
|
||||
int scissor_y = 0;
|
||||
int scissor_width = 0;
|
||||
int scissor_height = 0;
|
||||
std::function<void()> save_state;
|
||||
std::function<void(const LegacyNodeStrokePreviewMixPassPlan::ShaderPlan&)> setup_mix_shader;
|
||||
std::function<void()> bind_mixer_framebuffer;
|
||||
std::function<void(int, int, int, int, int, int)> configure_mix_target_state;
|
||||
std::function<void()> bind_mix_inputs;
|
||||
std::function<void()> draw_mix;
|
||||
std::function<void()> unbind_mixer_framebuffer;
|
||||
std::function<void()> restore_state;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline LegacyNodeStrokePreviewMixPassPlan plan_legacy_node_stroke_preview_mix_pass(
|
||||
const LegacyNodeStrokePreviewMixPassRequest& request) noexcept
|
||||
{
|
||||
@@ -153,80 +135,6 @@ struct LegacyNodeStrokePreviewMixExecutionRequest {
|
||||
return plan;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline bool execute_legacy_node_stroke_preview_mix_pass(
|
||||
const LegacyNodeStrokePreviewMixExecutionRequest& request)
|
||||
{
|
||||
if (request.mixer_width <= 0 ||
|
||||
request.mixer_height <= 0 ||
|
||||
!request.save_state ||
|
||||
!request.setup_mix_shader ||
|
||||
!request.bind_mixer_framebuffer ||
|
||||
!request.configure_mix_target_state ||
|
||||
!request.bind_mix_inputs ||
|
||||
!request.draw_mix ||
|
||||
!request.unbind_mixer_framebuffer ||
|
||||
!request.restore_state) {
|
||||
return false;
|
||||
}
|
||||
|
||||
request.save_state();
|
||||
request.setup_mix_shader(request.shader);
|
||||
request.bind_mixer_framebuffer();
|
||||
request.configure_mix_target_state(
|
||||
request.mixer_width,
|
||||
request.mixer_height,
|
||||
request.scissor_x,
|
||||
request.scissor_y,
|
||||
request.scissor_width,
|
||||
request.scissor_height);
|
||||
request.bind_mix_inputs();
|
||||
request.draw_mix();
|
||||
request.unbind_mixer_framebuffer();
|
||||
request.restore_state();
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LegacyNodeStrokePreviewPassSequenceRequest {
|
||||
bool dual_pass_enabled = false;
|
||||
std::function<void()> prepare_dual_pass;
|
||||
std::function<void()> execute_dual_pass;
|
||||
std::function<void()> capture_background;
|
||||
std::function<void()> prepare_main_pass;
|
||||
std::function<void()> execute_main_pass;
|
||||
std::function<void()> finish_main_pass;
|
||||
std::function<void()> execute_final_composite;
|
||||
std::function<void()> copy_preview_result;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline bool execute_legacy_node_stroke_preview_pass_sequence(
|
||||
const LegacyNodeStrokePreviewPassSequenceRequest& request)
|
||||
{
|
||||
if (!request.capture_background ||
|
||||
!request.prepare_main_pass ||
|
||||
!request.execute_main_pass ||
|
||||
!request.finish_main_pass ||
|
||||
!request.execute_final_composite ||
|
||||
!request.copy_preview_result) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (request.dual_pass_enabled) {
|
||||
if (!request.prepare_dual_pass || !request.execute_dual_pass) {
|
||||
return false;
|
||||
}
|
||||
request.prepare_dual_pass();
|
||||
request.execute_dual_pass();
|
||||
}
|
||||
|
||||
request.capture_background();
|
||||
request.prepare_main_pass();
|
||||
request.execute_main_pass();
|
||||
request.finish_main_pass();
|
||||
request.execute_final_composite();
|
||||
request.copy_preview_result();
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LegacyNodeStrokePreviewPassOrchestrationPlan {
|
||||
pp::paint_renderer::CanvasStrokeFeedbackPlan feedback {};
|
||||
pp::paint_renderer::CanvasStrokeMaterialPlan material {};
|
||||
@@ -244,69 +152,6 @@ struct LegacyNodeStrokePreviewMainPassTextureDispatch {
|
||||
std::function<void()> bind_mixer;
|
||||
};
|
||||
|
||||
struct LegacyNodeStrokePreviewFinalCompositeRequest {
|
||||
glm::vec2 resolution {};
|
||||
glm::vec2 pattern_scale {};
|
||||
const Brush* brush = nullptr;
|
||||
const pp::paint_renderer::CanvasStrokeCompositePassPlan* composite_pass = nullptr;
|
||||
std::function<void()> setup_composite_shader;
|
||||
std::function<void()> bind_composite_samplers;
|
||||
std::function<void()> bind_composite_inputs;
|
||||
std::function<void()> draw_composite;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline bool execute_legacy_node_stroke_preview_final_composite(
|
||||
const LegacyNodeStrokePreviewFinalCompositeRequest& request)
|
||||
{
|
||||
if (!request.brush ||
|
||||
!request.composite_pass ||
|
||||
!request.setup_composite_shader ||
|
||||
!request.bind_composite_samplers ||
|
||||
!request.bind_composite_inputs ||
|
||||
!request.draw_composite) {
|
||||
return false;
|
||||
}
|
||||
|
||||
pp::panopainter::execute_legacy_stroke_preview_final_composite(
|
||||
[&] {
|
||||
request.setup_composite_shader();
|
||||
},
|
||||
[&] {
|
||||
request.bind_composite_samplers();
|
||||
},
|
||||
[&] {
|
||||
request.bind_composite_inputs();
|
||||
},
|
||||
[&] {
|
||||
request.draw_composite();
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
struct LegacyNodeStrokePreviewCopyResultRequest {
|
||||
Texture2D* preview_texture = nullptr;
|
||||
glm::vec2 size {};
|
||||
std::function<void(int, int, int, int, int, int)> copy_framebuffer_to_texture;
|
||||
};
|
||||
|
||||
[[nodiscard]] inline bool copy_legacy_node_stroke_preview_result(
|
||||
const LegacyNodeStrokePreviewCopyResultRequest& request)
|
||||
{
|
||||
if (!request.preview_texture || !request.copy_framebuffer_to_texture) {
|
||||
return false;
|
||||
}
|
||||
pp::panopainter::copy_legacy_stroke_preview_texture(
|
||||
[&] {
|
||||
request.preview_texture->bind();
|
||||
},
|
||||
request.copy_framebuffer_to_texture,
|
||||
pp::panopainter::LegacyStrokePreviewCopySize {
|
||||
.width = static_cast<int>(request.size.x),
|
||||
.height = static_cast<int>(request.size.y),
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline LegacyNodeStrokePreviewMainPassTextureDispatch make_legacy_node_stroke_preview_main_pass_texture_dispatch(
|
||||
std::function<void(int)> activate_texture_unit,
|
||||
std::function<void()> bind_brush_tip,
|
||||
|
||||
@@ -173,7 +173,7 @@ pp::panopainter::LegacyStrokeCompositeUniforms make_stroke_preview_mix_composite
|
||||
};
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest make_stroke_preview_mix_execution_request(
|
||||
pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_execution_request(
|
||||
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader,
|
||||
RTT& mixer_rtt,
|
||||
const Brush& brush,
|
||||
@@ -181,39 +181,18 @@ pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest make_stroke_preview_
|
||||
Texture2D& background_texture,
|
||||
Texture2D& stroke_texture,
|
||||
Texture2D& dual_texture,
|
||||
gl_state& gl,
|
||||
const glm::vec2& bb_min,
|
||||
const glm::vec2& bb_sz,
|
||||
std::span<const pp::panopainter::LegacyCanvasStrokeMixPassPlane> mix_planes,
|
||||
std::function<void()> draw_mix)
|
||||
{
|
||||
return pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest {
|
||||
.shader = shader,
|
||||
.mixer_width = mixer_rtt.getWidth(),
|
||||
.mixer_height = mixer_rtt.getHeight(),
|
||||
.scissor_x = static_cast<int>(bb_min.x),
|
||||
.scissor_y = static_cast<int>(bb_min.y),
|
||||
.scissor_width = static_cast<int>(bb_sz.x),
|
||||
.scissor_height = static_cast<int>(bb_sz.y),
|
||||
.save_state = [&] { gl.save(); },
|
||||
.setup_mix_shader = [&](const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader_plan) {
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
make_stroke_preview_mix_composite_uniforms(shader_plan));
|
||||
},
|
||||
.bind_mixer_framebuffer = [&] { mixer_rtt.bindFramebuffer(); },
|
||||
.configure_mix_target_state = [&](int mixer_width,
|
||||
int mixer_height,
|
||||
int scissor_x,
|
||||
int scissor_y,
|
||||
int scissor_width,
|
||||
int scissor_height) {
|
||||
apply_stroke_preview_viewport(0, 0, mixer_width, mixer_height);
|
||||
apply_stroke_preview_capability(pp::renderer::gl::depth_test_state(), false);
|
||||
apply_stroke_preview_capability(pp::renderer::gl::scissor_test_state(), true);
|
||||
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
||||
apply_stroke_preview_scissor(scissor_x, scissor_y, scissor_width, scissor_height);
|
||||
},
|
||||
.bind_mix_inputs = [&] {
|
||||
return pp::panopainter::make_legacy_canvas_stroke_mix_pass_request(
|
||||
"NodeStrokePreview::stroke_draw_mix",
|
||||
glm::vec2(static_cast<float>(mixer_rtt.getWidth()), static_cast<float>(mixer_rtt.getHeight())),
|
||||
mix_planes,
|
||||
[&] {
|
||||
linear_sampler.bind(stroke_preview_composite_slots::kBackground);
|
||||
linear_sampler.bind(stroke_preview_composite_slots::kStroke);
|
||||
linear_sampler.bind(stroke_preview_composite_slots::kDual);
|
||||
linear_sampler.bind(stroke_preview_composite_slots::kPattern);
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
||||
background_texture.bind();
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
||||
@@ -223,21 +202,48 @@ pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest make_stroke_preview_
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kPattern);
|
||||
brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d();
|
||||
},
|
||||
.draw_mix = std::move(draw_mix),
|
||||
.unbind_mixer_framebuffer = [&] { mixer_rtt.unbindFramebuffer(); },
|
||||
.restore_state = [&] { gl.restore(); },
|
||||
};
|
||||
[] {},
|
||||
[&](int, const glm::mat4& plane_mvp) {
|
||||
auto uniforms = make_stroke_preview_mix_composite_uniforms(shader);
|
||||
uniforms.mvp = plane_mvp;
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(uniforms);
|
||||
},
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
||||
background_texture.bind();
|
||||
},
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
||||
stroke_texture.bind();
|
||||
},
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
||||
dual_texture.bind();
|
||||
},
|
||||
std::move(draw_mix),
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kDual);
|
||||
dual_texture.unbind();
|
||||
},
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
||||
stroke_texture.unbind();
|
||||
},
|
||||
[&](int) {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
||||
background_texture.unbind();
|
||||
});
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewFinalCompositeRequest make_stroke_preview_final_composite_request(
|
||||
const StrokePreviewCompositePassInputs& inputs)
|
||||
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)
|
||||
{
|
||||
return pp::panopainter::LegacyNodeStrokePreviewFinalCompositeRequest {
|
||||
.resolution = inputs.resolution,
|
||||
.pattern_scale = inputs.pattern_scale,
|
||||
.brush = &inputs.brush,
|
||||
.composite_pass = &inputs.composite_pass,
|
||||
.setup_composite_shader = [&] {
|
||||
pp::panopainter::execute_legacy_stroke_preview_final_composite(
|
||||
[&] {
|
||||
pp::panopainter::setup_legacy_stroke_composite_shader(
|
||||
pp::panopainter::LegacyStrokeCompositeUniforms {
|
||||
.resolution = inputs.resolution,
|
||||
@@ -262,14 +268,14 @@ pp::panopainter::LegacyNodeStrokePreviewFinalCompositeRequest make_stroke_previe
|
||||
.use_pattern = inputs.composite_pass.use_pattern,
|
||||
});
|
||||
},
|
||||
.bind_composite_samplers = [&] {
|
||||
[&] {
|
||||
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);
|
||||
},
|
||||
.bind_composite_inputs = [&] {
|
||||
[&] {
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kBackground);
|
||||
inputs.background_texture.bind();
|
||||
set_active_texture_unit(stroke_preview_composite_slots::kStroke);
|
||||
@@ -281,28 +287,9 @@ pp::panopainter::LegacyNodeStrokePreviewFinalCompositeRequest make_stroke_previe
|
||||
inputs.brush.m_pattern_texture->bind() :
|
||||
unbind_texture_2d();
|
||||
},
|
||||
.draw_composite = [&] {
|
||||
[&] {
|
||||
inputs.draw_composite();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
void execute_stroke_preview_final_composite_pass(const StrokePreviewCompositePassInputs& inputs)
|
||||
{
|
||||
[[maybe_unused]] const bool composite_ok =
|
||||
pp::panopainter::execute_legacy_node_stroke_preview_final_composite(
|
||||
make_stroke_preview_final_composite_request(inputs));
|
||||
assert(composite_ok);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
execute_stroke_preview_final_composite_pass(inputs);
|
||||
});
|
||||
copy_stroke_preview_result_to_texture(preview_texture, size);
|
||||
}
|
||||
|
||||
@@ -486,18 +473,14 @@ void execute_stroke_preview_background_capture_pass(
|
||||
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();
|
||||
},
|
||||
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();
|
||||
const auto copy_status = pp::paint_renderer::copy_stroke_preview_result_to_texture(
|
||||
[&] {
|
||||
background_texture.bind();
|
||||
},
|
||||
@@ -510,30 +493,27 @@ void execute_stroke_preview_background_capture_pass(
|
||||
int height) {
|
||||
copy_framebuffer_to_texture_2d(src_x, src_y, dst_x, dst_y, width, height);
|
||||
},
|
||||
pp::panopainter::LegacyStrokePreviewCopySize {
|
||||
pp::paint_renderer::StrokePreviewCopySize {
|
||||
.width = static_cast<int>(size.x),
|
||||
.height = static_cast<int>(size.y),
|
||||
});
|
||||
assert(copy_status.ok());
|
||||
}
|
||||
|
||||
void copy_stroke_preview_result_to_texture(Texture2D& preview_texture, glm::vec2 size)
|
||||
{
|
||||
[[maybe_unused]] const bool copy_ok =
|
||||
pp::panopainter::copy_legacy_node_stroke_preview_result(
|
||||
pp::panopainter::LegacyNodeStrokePreviewCopyResultRequest {
|
||||
.preview_texture = &preview_texture,
|
||||
.size = size,
|
||||
.copy_framebuffer_to_texture = [](
|
||||
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);
|
||||
},
|
||||
});
|
||||
assert(copy_ok);
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -617,14 +597,47 @@ void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2
|
||||
const auto& b = m_brush;
|
||||
const auto mix_pass = pp::panopainter::plan_legacy_node_stroke_preview_mix_pass(
|
||||
make_stroke_preview_mix_pass_request(*b, m_size));
|
||||
const auto mix_planes = std::array {
|
||||
pp::panopainter::LegacyCanvasStrokeMixPassPlane {
|
||||
.index = 0,
|
||||
.visible = true,
|
||||
.has_target = true,
|
||||
.opacity = 1.0f,
|
||||
.mvp = glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f),
|
||||
},
|
||||
};
|
||||
gl_state gl;
|
||||
[[maybe_unused]] const bool mix_ok = pp::panopainter::execute_legacy_node_stroke_preview_mix_pass(
|
||||
make_stroke_draw_mix_execution_request(
|
||||
mix_pass,
|
||||
gl,
|
||||
bb_min,
|
||||
bb_sz));
|
||||
assert(mix_ok);
|
||||
const auto mix_result = pp::panopainter::execute_legacy_canvas_stroke_mix_pass_with_setup(
|
||||
[&] {
|
||||
apply_stroke_preview_viewport(0, 0, m_rtt_mixer.getWidth(), m_rtt_mixer.getHeight());
|
||||
apply_stroke_preview_capability(pp::renderer::gl::depth_test_state(), false);
|
||||
apply_stroke_preview_capability(pp::renderer::gl::scissor_test_state(), true);
|
||||
apply_stroke_preview_capability(pp::renderer::gl::blend_state(), false);
|
||||
apply_stroke_preview_scissor(
|
||||
static_cast<std::int32_t>(bb_min.x),
|
||||
static_cast<std::int32_t>(bb_min.y),
|
||||
static_cast<std::int32_t>(bb_sz.x),
|
||||
static_cast<std::int32_t>(bb_sz.y));
|
||||
gl.save();
|
||||
m_rtt_mixer.bindFramebuffer();
|
||||
},
|
||||
[&] {
|
||||
m_rtt_mixer.unbindFramebuffer();
|
||||
gl.restore();
|
||||
},
|
||||
make_stroke_preview_mix_pass_execution_request(
|
||||
mix_pass.shader,
|
||||
m_rtt_mixer,
|
||||
*m_brush,
|
||||
m_sampler_linear,
|
||||
m_tex_background,
|
||||
m_tex,
|
||||
m_tex_dual,
|
||||
mix_planes,
|
||||
[this] {
|
||||
m_plane.draw_fill();
|
||||
}));
|
||||
assert(mix_result.ok);
|
||||
}
|
||||
|
||||
glm::vec4 NodeStrokePreview::stroke_draw_samples(
|
||||
@@ -792,16 +805,60 @@ void NodeStrokePreview::draw_stroke_immediate()
|
||||
const auto& material = pass_orchestration.material;
|
||||
pp::panopainter::setup_legacy_stroke_shader(pass_orchestration.stroke_shader);
|
||||
|
||||
const bool sequence_ok = pp::panopainter::execute_legacy_node_stroke_preview_pass_sequence(
|
||||
make_stroke_draw_immediate_pass_sequence_request(
|
||||
m_stroke,
|
||||
m_dual_stroke,
|
||||
*b,
|
||||
pass_orchestration,
|
||||
dual_brush,
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
size));
|
||||
const bool sequence_ok = [&] {
|
||||
if (pass_orchestration.material.dual_pass.enabled) {
|
||||
pp::panopainter::setup_legacy_stroke_dual_shader(
|
||||
pass_orchestration.material.dual_pass.uses_pattern);
|
||||
bind_stroke_preview_dual_pass_textures(*dual_brush);
|
||||
execute_stroke_draw_immediate_dual_pass(
|
||||
m_dual_stroke,
|
||||
*b,
|
||||
pass_orchestration,
|
||||
std::move(dual_brush),
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
size);
|
||||
}
|
||||
|
||||
execute_stroke_preview_background_capture_pass(
|
||||
size,
|
||||
pass_orchestration.background_colorize,
|
||||
m_tex_background,
|
||||
[&] {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
|
||||
[[maybe_unused]] const bool main_live_ok =
|
||||
pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass(
|
||||
make_stroke_draw_immediate_main_live_pass_request(
|
||||
m_stroke,
|
||||
*b,
|
||||
pass_orchestration,
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
size));
|
||||
if (!main_live_ok) {
|
||||
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();
|
||||
}),
|
||||
m_tex_preview,
|
||||
size);
|
||||
return true;
|
||||
}();
|
||||
assert(sequence_ok);
|
||||
|
||||
m_rtt.unbindFramebuffer();
|
||||
@@ -913,79 +970,6 @@ void NodeStrokePreview::execute_stroke_draw_immediate_dual_pass(
|
||||
});
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest
|
||||
NodeStrokePreview::make_stroke_draw_immediate_pass_sequence_request(
|
||||
Stroke& stroke,
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
bool copy_stroke_destination,
|
||||
float zoom,
|
||||
const glm::vec2& size)
|
||||
{
|
||||
const auto& material = pass_orchestration.material;
|
||||
return pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest {
|
||||
.dual_pass_enabled = material.dual_pass.enabled,
|
||||
.prepare_dual_pass = [&] {
|
||||
pp::panopainter::setup_legacy_stroke_dual_shader(material.dual_pass.uses_pattern);
|
||||
bind_stroke_preview_dual_pass_textures(*dual_brush);
|
||||
},
|
||||
.execute_dual_pass = [&] {
|
||||
execute_stroke_draw_immediate_dual_pass(
|
||||
dual_stroke,
|
||||
brush,
|
||||
pass_orchestration,
|
||||
dual_brush,
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
size);
|
||||
},
|
||||
.capture_background = [&] {
|
||||
execute_stroke_preview_background_capture_pass(
|
||||
size,
|
||||
pass_orchestration.background_colorize,
|
||||
m_tex_background,
|
||||
[&] {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
},
|
||||
.prepare_main_pass = [&] {},
|
||||
.execute_main_pass = [&] {
|
||||
[[maybe_unused]] const bool main_live_ok =
|
||||
pp::panopainter::execute_legacy_node_stroke_preview_main_live_pass(
|
||||
make_stroke_draw_immediate_main_live_pass_request(
|
||||
stroke,
|
||||
brush,
|
||||
pass_orchestration,
|
||||
copy_stroke_destination,
|
||||
zoom,
|
||||
size));
|
||||
},
|
||||
.finish_main_pass = [&] {},
|
||||
.execute_final_composite = [&] {
|
||||
std::function<void()> draw_composite = [&] {
|
||||
m_plane.draw_fill();
|
||||
};
|
||||
execute_stroke_preview_final_composite_and_copy(
|
||||
StrokePreviewCompositePassInputs(
|
||||
size,
|
||||
glm::vec2(brush.m_pattern_scale),
|
||||
brush,
|
||||
material.composite_pass,
|
||||
m_tex_background,
|
||||
m_tex,
|
||||
m_tex_dual,
|
||||
m_sampler_linear,
|
||||
m_sampler_linear_repeat,
|
||||
std::move(draw_composite)),
|
||||
m_tex_preview,
|
||||
size);
|
||||
},
|
||||
.copy_preview_result = [&] {},
|
||||
};
|
||||
}
|
||||
|
||||
void NodeStrokePreview::execute_stroke_draw_immediate_main_live_sample_pass(
|
||||
const Brush& brush,
|
||||
bool copy_stroke_destination,
|
||||
@@ -1004,29 +988,6 @@ void NodeStrokePreview::execute_stroke_draw_immediate_main_live_sample_pass(
|
||||
});
|
||||
}
|
||||
|
||||
pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest
|
||||
NodeStrokePreview::make_stroke_draw_mix_execution_request(
|
||||
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan& mix_pass,
|
||||
gl_state& gl,
|
||||
const glm::vec2& bb_min,
|
||||
const glm::vec2& bb_sz)
|
||||
{
|
||||
return make_stroke_preview_mix_execution_request(
|
||||
mix_pass.shader,
|
||||
m_rtt_mixer,
|
||||
*m_brush,
|
||||
m_sampler_linear,
|
||||
m_tex_background,
|
||||
m_tex,
|
||||
m_tex_dual,
|
||||
gl,
|
||||
bb_min,
|
||||
bb_sz,
|
||||
[this] {
|
||||
m_plane.draw_fill();
|
||||
});
|
||||
}
|
||||
|
||||
Image NodeStrokePreview::render_to_image()
|
||||
{
|
||||
std::lock_guard<std::mutex> _lock(s_render_mutex);
|
||||
|
||||
@@ -74,20 +74,6 @@ public:
|
||||
bool copy_stroke_destination,
|
||||
float zoom,
|
||||
const glm::vec2& size);
|
||||
pp::panopainter::LegacyNodeStrokePreviewPassSequenceRequest make_stroke_draw_immediate_pass_sequence_request(
|
||||
Stroke& stroke,
|
||||
Stroke& dual_stroke,
|
||||
const Brush& brush,
|
||||
const pp::panopainter::LegacyNodeStrokePreviewPassOrchestrationPlan& pass_orchestration,
|
||||
std::shared_ptr<Brush> dual_brush,
|
||||
bool copy_stroke_destination,
|
||||
float zoom,
|
||||
const glm::vec2& size);
|
||||
pp::panopainter::LegacyNodeStrokePreviewMixExecutionRequest make_stroke_draw_mix_execution_request(
|
||||
const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan& mix_pass,
|
||||
gl_state& gl,
|
||||
const glm::vec2& bb_min,
|
||||
const glm::vec2& bb_sz);
|
||||
void draw_stroke();
|
||||
void draw_stroke_immediate();
|
||||
Image render_to_image();
|
||||
|
||||
Reference in New Issue
Block a user