From a8e4e02e9441d4b57a070336f18c789ccdb98319 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 16 Jun 2026 23:02:05 +0200 Subject: [PATCH] Extract final canvas wrappers and preview mix pass --- docs/modernization/roadmap.md | 16 +- docs/modernization/tasks.md | 22 +- src/canvas.cpp | 402 ------------------ src/legacy_brush_preset_panel_ui.cpp | 28 ++ src/legacy_brush_preset_panel_ui.h | 1 + src/legacy_canvas_object_draw_services.cpp | 25 ++ src/legacy_canvas_projection_services.cpp | 55 +++ src/legacy_canvas_render_shell_services.cpp | 69 +++ src/legacy_canvas_stroke_live_services.cpp | 5 + src/legacy_canvas_stroke_runtime_services.cpp | 33 ++ ...gacy_node_stroke_preview_draw_services.cpp | 183 +++++++- ...legacy_node_stroke_preview_draw_services.h | 16 + src/node_panel_brush.cpp | 26 +- src/node_stroke_preview.cpp | 181 +------- 14 files changed, 458 insertions(+), 604 deletions(-) diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index 0990675e..74eb4732 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -79,13 +79,13 @@ What is still carrying too much live ownership: Current hotspot files: -- `src/canvas.cpp`: 368 lines +- `src/canvas.cpp`: 17 lines - `src/app_layout.cpp`: 125 lines - `src/canvas_modes.cpp`: 402 lines - `src/node.cpp`: 260 lines - `src/main.cpp`: 130 lines -- `src/node_panel_brush.cpp`: 255 lines -- `src/node_stroke_preview.cpp`: 490 lines +- `src/node_panel_brush.cpp`: 231 lines +- `src/node_stroke_preview.cpp`: 343 lines - `src/node_canvas.cpp`: 219 lines - `src/app.cpp`: 113 lines - `src/app_dialogs.cpp`: 168 lines @@ -262,6 +262,10 @@ Current architecture mismatches that must be treated as real blockers: pass planning, shader setup, and live render request assembly now also routes through `src/legacy_node_stroke_preview_runtime_services.*` instead of staying inline in `src/node_stroke_preview.cpp`, while + `NodeStrokePreview` remaining mix-pass planning and execution now also route + through `src/legacy_node_stroke_preview_draw_services.*`, which trims the + last dedicated mix-orchestration pocket from `src/node_stroke_preview.cpp`, + while `NodeCanvas::draw()` unmerged-pass blend-gate, layer-orientation, and callback-assembly setup now also route through `execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent @@ -320,7 +324,11 @@ Current architecture mismatches that must be treated as real blockers: panel UI pocket, while the retained `LegacyBrushPresetListServices` block now also lives in `src/legacy_brush_preset_list_services.*` instead of staying inline in `src/node_panel_brush.cpp`, which trims another retained - preset workflow pocket, while `NodeCanvas::handle_event()` now also routes + preset popup tail now also lives in `src/legacy_brush_preset_panel_ui.*` + instead of staying inline in `src/node_panel_brush.cpp`, which removes the + last inline brush-panel popup close handler from the live node. The + broader preset workflow pocket still remains, while `NodeCanvas::handle_event()` + now also routes through `execute_node_canvas_handle_event(...)`, which trims another coherent input-routing block from `src/node_canvas.cpp` even though the file is still a live canvas/controller shell, while `NodeCanvas` restore/clear context, diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index 01c8e30e..ca3d6224 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -36,8 +36,8 @@ Completed, blocked, and superseded task history moved to - `pp_legacy_paint_document`: 7 files, about 5709 lines - `pp_legacy_app`: 20 files, about 4368 lines - `pp_legacy_ui_core`: 20 files, about 3770 lines -- The biggest single-file choke points are still `src/canvas.cpp`, - `src/app_layout.cpp`, `src/canvas_modes.cpp`, `src/node.cpp`, +- The biggest single-file choke points are still `src/canvas_modes.cpp`, + `src/node.cpp`, `src/main.cpp`, `src/node_panel_brush.cpp`, `src/node_stroke_preview.cpp`, `src/node_canvas.cpp`, `src/app.cpp`, and `src/app_dialogs.cpp`. - The platform boundary is not finished: @@ -90,11 +90,16 @@ looks like a wrapper around the old renderer shell. Status: In Progress Why now: -`src/canvas.cpp` is still the biggest single architectural blocker at about -429 lines, with `src/canvas_modes.cpp` now materially thinner and the next -remaining render-shell pressure shifting toward preview/canvas nodes. +The live `Canvas` ownership boundary is still active, but `src/canvas.cpp` +itself is now down to a thin static singleton plus mode-table shell. The +remaining canvas pressure now sits in the extracted legacy canvas service +files and the preview/canvas node render paths rather than the old monolithic +translation unit. Current slice: +- The remaining `Canvas` member wrappers in `src/canvas.cpp` now live in the + extracted canvas service files, leaving `canvas.cpp` as the static singleton + and mode-table shell. - Canvas state-management helpers for picking, clear/clear-all, layer add/remove/order/lookups, animation frame control, resize, and snapshot save/restore now live in `src/legacy_canvas_state_services.cpp` instead of @@ -213,6 +218,9 @@ Current slice: `legacy_node_stroke_preview_execution_services.h`, which trims another coherent pass-setup block from `src/node_stroke_preview.cpp`, but broader preview-pass orchestration is still inline. +- `NodeStrokePreview` remaining mix-pass planning and execution now also route + through `legacy_node_stroke_preview_draw_services.*`, which trims the last + dedicated mix-orchestration pocket from `src/node_stroke_preview.cpp`. - `NodeStrokePreview::draw_stroke_immediate()` immediate preview pass sequencing now also routes through the private `execute_stroke_draw_immediate_pass_sequence(...)` helper, which removes @@ -1136,6 +1144,10 @@ Current slice: `src/node_panel_brush.cpp`, which materially thins another retained preset panel UI pocket even though cloud/package worker ownership remains the follow-up. +- `NodePanelBrushPreset` popup-close event handling now also lives in + `src/legacy_brush_preset_panel_ui.*` instead of staying inline in + `src/node_panel_brush.cpp`, which trims the remaining inline popup tail + from the live brush panel file. - The retained `LegacyBrushPresetListServices` block now also lives in `src/legacy_brush_preset_list_services.*` instead of staying inline in `src/node_panel_brush.cpp`, which trims another retained preset workflow diff --git a/src/canvas.cpp b/src/canvas.cpp index 41b76249..577728f7 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -1,256 +1,5 @@ #include "pch.h" -#include "log.h" #include "canvas.h" -#include "legacy_canvas_render_shell_services.h" -#include "legacy_ui_gl_dispatch.h" -#include "legacy_canvas_stroke_erase_services.h" -#include "legacy_gl_renderbuffer_dispatch.h" -#include "legacy_canvas_stroke_commit_services.h" -#include "legacy_canvas_stroke_composite_services.h" -#include "legacy_canvas_stroke_edge_services.h" -#include "legacy_canvas_stroke_execution_services.h" -#include "legacy_canvas_stroke_runtime_services.h" -#include "legacy_canvas_stroke_shader_services.h" -#include "legacy_canvas_object_draw_services.h" -#include "legacy_canvas_projection_services.h" -#include "legacy_canvas_stroke_services.h" -#include "legacy_ui_overlay_services.h" -#include "app_core/document_canvas.h" -#include "texture.h" -#include "node_progress_bar.h" -#include "paint_renderer/compositor.h" -#include "renderer_gl/opengl_capabilities.h" -#include "util.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __APPLE__ -#include -#endif - -namespace { - -GLint current_canvas_stroke_internal_format() -{ - const auto renderer_features = ShaderManager::render_device_features(); - if (renderer_features.float32_linear_filtering) - return static_cast(pp::renderer::gl::rgba32f_internal_format()); - if (renderer_features.float16_render_targets) - return static_cast(pp::renderer::gl::rgba16f_internal_format()); - return static_cast(pp::renderer::gl::rgba8_internal_format()); -} - -GLint rgba8_internal_format() -{ - return static_cast(pp::renderer::gl::rgba8_internal_format()); -} - -pp::renderer::RenderDeviceFeatures canvas_render_device_features() noexcept -{ - return ShaderManager::render_device_features(); -} - -pp::paint_renderer::CanvasStrokeRasterizationPlan canvas_stroke_rasterization_plan( - int width, - int height) noexcept -{ - return pp::panopainter::plan_legacy_canvas_stroke_rasterization( - canvas_render_device_features(), - width, - height); -} - -pp::paint_renderer::CanvasStrokeFeedbackPlan canvas_destination_feedback_plan( - int width, - int height) noexcept -{ - return canvas_stroke_rasterization_plan(width, height).feedback; -} - -pp::paint_renderer::CanvasStrokeMaterialPlan canvas_stroke_material_plan( - const Brush& brush, - bool destination_feedback_needed) noexcept -{ - return pp::panopainter::plan_legacy_canvas_stroke_material( - pp::paint_renderer::CanvasStrokeMaterialRequest { - .destination_feedback_needed = destination_feedback_needed, - .pattern_enabled = brush.m_pattern_enabled, - .pattern_eachsample = brush.m_pattern_eachsample, - .wet_blend = brush.m_tip_wet > 0.F, - .mix_blend = brush.m_tip_mix > 0.F, - .noise_enabled = brush.m_tip_noise > 0.F, - .dual_brush_enabled = brush.m_dual_enabled, - .dual_blend_mode = brush.m_dual_blend_mode, - .pattern_blend_mode = brush.m_pattern_blend_mode, - .dual_alpha = brush.m_dual_opacity, - }); -} - -pp::renderer::Extent2D canvas_stroke_extent(int width, int height) noexcept -{ - return pp::renderer::Extent2D { - .width = static_cast(std::max(width, 0)), - .height = static_cast(std::max(height, 0)), - }; -} - -pp::paint_renderer::CanvasBlendGatePlan draw_merge_blend_gate_plan( - int width, - int height, - const std::vector>& layers, - const Brush* brush) noexcept -{ - std::vector layer_blend_modes; - layer_blend_modes.reserve(layers.size()); - for (const auto& layer : layers) { - if (!layer) { - continue; - } - layer_blend_modes.push_back(layer->m_blend_mode); - } - - const auto plan = pp::paint_renderer::plan_canvas_blend_gate( - canvas_render_device_features(), - pp::paint_renderer::CanvasBlendGateRequest { - .extent = pp::renderer::Extent2D { - .width = static_cast(std::max(width, 0)), - .height = static_cast(std::max(height, 0)), - }, - .layer_blend_modes = layer_blend_modes, - .has_stroke_blend_mode = brush != nullptr, - .stroke_blend_mode = brush ? brush->m_blend_mode : 0, - }); - if (plan) { - return plan.value(); - } - - pp::paint_renderer::CanvasBlendGatePlan fallback; - fallback.shader_blend = true; - fallback.complex_blend = true; - fallback.compatibility_fallback = true; - return fallback; -} - -GLenum depth_test_state() -{ - return static_cast(pp::renderer::gl::depth_test_state()); -} - -GLenum scissor_test_state() -{ - return static_cast(pp::renderer::gl::scissor_test_state()); -} - -GLenum blend_state() -{ - return static_cast(pp::renderer::gl::blend_state()); -} - -GLint texture_filter_linear() -{ - return static_cast(pp::renderer::gl::linear_texture_filter()); -} - -GLint texture_filter_linear_mipmap_linear() -{ - return static_cast(pp::renderer::gl::linear_mipmap_linear_texture_filter()); -} - -GLint texture_filter_nearest() -{ - return static_cast(pp::renderer::gl::nearest_texture_filter()); -} - -GLint texture_wrap_repeat() -{ - return static_cast(pp::renderer::gl::repeat_texture_wrap()); -} - -GLint texture_wrap_clamp_to_border() -{ - return static_cast(pp::renderer::gl::clamp_to_border_texture_wrap()); -} - -pp::renderer::gl::OpenGlPixelFormat texture_format_for_image_channels(int channel_count) -{ - return pp::renderer::gl::texture_format_for_channel_count(static_cast(channel_count)); -} - -void set_active_texture_unit(std::uint32_t unit_index) -{ - pp::legacy::ui_gl::activate_texture_unit(unit_index, "Canvas"); -} - -void unbind_texture_2d() -{ - pp::legacy::ui_gl::unbind_texture_2d("Canvas"); -} - -void apply_canvas_viewport(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) -{ - pp::legacy::ui_gl::apply_viewport(x, y, width, height, "Canvas"); -} - -pp::renderer::gl::OpenGlViewportRect query_canvas_viewport() -{ - return pp::legacy::ui_gl::query_viewport_rect("Canvas"); -} - -std::array query_canvas_clear_color() -{ - return pp::legacy::ui_gl::query_clear_color("Canvas"); -} - -void apply_canvas_clear_color(std::array color) -{ - pp::legacy::ui_gl::set_clear_color(color, "Canvas"); -} - -void apply_canvas_scissor(std::int32_t x, std::int32_t y, std::int32_t width, std::int32_t height) -{ - pp::legacy::ui_gl::apply_scissor_rect(x, y, width, height, "Canvas"); -} - -void apply_canvas_capability(std::uint32_t state, bool enabled) -{ - pp::legacy::ui_gl::set_capability(state, enabled, "Canvas"); -} - -bool query_canvas_capability(std::uint32_t state) -{ - return pp::legacy::ui_gl::query_capability(state, "Canvas"); -} - -GLuint allocate_canvas_depth_renderbuffer(int width, int height) -{ - return static_cast(pp::legacy::gl_renderbuffer::allocate_depth_renderbuffer( - width, - height, - "OpenGL canvas depth renderbuffer allocation")); -} - -void attach_canvas_depth_renderbuffer(GLuint renderbuffer) -{ - pp::legacy::gl_renderbuffer::attach_depth_renderbuffer( - static_cast(renderbuffer), - "OpenGL canvas depth renderbuffer attachment"); -} - -void delete_canvas_renderbuffer(GLuint renderbuffer) -{ - pp::legacy::gl_renderbuffer::delete_renderbuffer( - static_cast(renderbuffer), - "OpenGL canvas renderbuffer delete"); -} - -} Canvas* Canvas::I; std::vector Canvas::modes[] = { @@ -267,154 +16,3 @@ std::vector Canvas::modes[] = { { new CanvasModeMaskLine, new CanvasModeBasicCamera }, // mask-poly { new CanvasModeFloodFill, new CanvasModeBasicCamera }, // flood-fill }; - -void Canvas::stroke_end() { pp::panopainter::legacy_canvas_stroke_end(*this); } -void Canvas::stroke_cancel() { pp::panopainter::legacy_canvas_stroke_cancel(*this); } -void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) -{ - pp::panopainter::legacy_canvas_stroke_draw_mix(*this, bb_min, bb_sz); -} - -std::array, 6> Canvas::stroke_draw_project(std::array& B, bool project_3d /*= false*/, glm::mat4 mv /*= glm::mat4(1)*/) const -{ - return pp::panopainter::legacy_canvas_stroke_draw_project(*this, B, project_3d, mv); -} - -void Canvas::draw_merge_temporary_paint_branch( - int layer_index, - int plane_index, - std::shared_ptr layer, - const Brush& brush, - const glm::mat4& ortho) -{ - pp::panopainter::legacy_canvas_draw_merge_temporary_paint_branch( - *this, - layer_index, - plane_index, - std::move(layer), - brush, - ortho); -} - -void Canvas::draw_merge_branch_orchestration( - int plane_index, - int layer_index, - const std::shared_ptr& layer, - const Brush& brush, - const glm::mat4& ortho, - bool use_blend, - bool copy_blend_destination) -{ - pp::panopainter::legacy_canvas_draw_merge_branch_orchestration( - *this, - plane_index, - layer_index, - layer, - brush, - ortho, - use_blend, - copy_blend_destination); -} - -void Canvas::draw_merge_final_plane_composite( - const glm::mat4& ortho, - bool draw_checkerboard) -{ - pp::panopainter::legacy_canvas_draw_merge_final_plane_composite( - *this, - ortho, - draw_checkerboard); -} - -void Canvas::stroke_draw() -{ - stroke_draw_live(); -} -bool Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir, - glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id) -{ - return pp::panopainter::legacy_canvas_point_trace(*this, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, out_plane_id); -} -/* -bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& hit_pos, glm::vec2& hit_fb_pos, int plane_id) -{ - auto ln = (loc / zw(m_box)) * 2.f - 1.f; - auto p = m_plane_unproject[plane_id] * glm::vec4(ln, 1, 1); - if (p.w <= 0) - { - - return true; - } - return false; -} -*/ -bool Canvas::point_trace_plane(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir, - glm::vec3& hit_pos, glm::vec3& hit_normal, glm::vec2& hit_fb_pos, int plane_id) -{ - return pp::panopainter::legacy_canvas_point_trace_plane(*this, loc, ray_origin, ray_dir, hit_pos, hit_normal, hit_fb_pos, plane_id); -} -void Canvas::point_unproject(glm::vec2 loc, glm::vec4 vp, glm::mat4 camera, glm::mat4 proj, - glm::vec3& out_origin, glm::vec3& out_dir) -{ - pp::panopainter::legacy_canvas_point_unproject(loc, vp, camera, proj, out_origin, out_dir); -} -void Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir) -{ - pp::panopainter::legacy_canvas_point_unproject(*this, loc, out_origin, out_dir); -} -glm::vec3 Canvas::point_trace(glm::vec2 loc) -{ - return pp::panopainter::legacy_canvas_point_trace(*this, loc); -} -void Canvas::stroke_commit_timelapse() -{ - pp::panopainter::legacy_canvas_stroke_commit_timelapse(*this); -} - -void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SIXPLETTE(true)*/) -{ - pp::panopainter::legacy_canvas_draw_merge(*this, draw_checkerboard, faces); -} - -void Canvas::stroke_update(glm::vec3 point, float pressure) { pp::panopainter::legacy_canvas_stroke_update(*this, point, pressure); } -void Canvas::stroke_start(glm::vec3 point, float pressure) { pp::panopainter::legacy_canvas_stroke_start(*this, point, pressure); } -void Canvas::destroy() -{ - pp::panopainter::legacy_canvas_destroy(*this); -} - -bool Canvas::create(int width, int height) -{ - return pp::panopainter::legacy_canvas_create(*this, width, height); -} - -void Canvas::clear_context() -{ - pp::panopainter::legacy_canvas_clear_context(*this); -} - -void Canvas::draw_objects_direct(std::function observer, Layer& layer, int frame) -{ - pp::panopainter::legacy_canvas_draw_objects_direct(*this, std::move(observer), layer, frame); -} - -void Canvas::draw_objects(std::function observer, Layer& layer, int frame, bool save_history) -{ - pp::panopainter::legacy_canvas_draw_objects(*this, std::move(observer), layer, frame, save_history); -} - -void Canvas::draw_objects(std::function observer, int frame, bool save_history) -{ - draw_objects(observer, layer(), frame, save_history); -} - -void Canvas::project2Dpoints(std::vector& vertices) -{ - pp::panopainter::legacy_canvas_project_2d_points(*this, vertices); -} - -glm::vec3 Canvas::project2Dpoint(glm::vec2 pt) -{ - return pp::panopainter::legacy_canvas_project_2d_point(*this, pt); -} - diff --git a/src/legacy_brush_preset_panel_ui.cpp b/src/legacy_brush_preset_panel_ui.cpp index bb5a8ba4..64ae90be 100644 --- a/src/legacy_brush_preset_panel_ui.cpp +++ b/src/legacy_brush_preset_panel_ui.cpp @@ -118,6 +118,34 @@ void LegacyBrushPresetPanelUi::init(NodePanelBrushPreset& owner) owner.m_notification->SetVisibility(owner.m_container->m_children.size() == 0); } +kEventResult LegacyBrushPresetPanelUi::handle_event(NodePanelBrushPreset& owner, Event* event) +{ + switch (event->m_type) + { + case kEventType::MouseLeave: + if (!owner.m_interacted) + break; + // else fall through + case kEventType::MouseUpL: + if (!owner.m_mouse_inside) + { + pp::panopainter::release_legacy_mouse_capture(owner); + if (owner.m_parent) + { + pp::panopainter::detach_legacy_node_from_parent(owner); + } + if (owner.on_popup_close) + { + owner.on_popup_close(&owner); + } + } + break; + default: + return kEventResult::Available; + } + return kEventResult::Consumed; +} + void LegacyBrushPresetPanelUi::handle_click(NodePanelBrushPreset& owner, Node* target) { const int idx = owner.m_container->get_child_index(target); diff --git a/src/legacy_brush_preset_panel_ui.h b/src/legacy_brush_preset_panel_ui.h index c3257d61..4a934afd 100644 --- a/src/legacy_brush_preset_panel_ui.h +++ b/src/legacy_brush_preset_panel_ui.h @@ -7,6 +7,7 @@ namespace pp::panopainter { class LegacyBrushPresetPanelUi final { public: static void init(NodePanelBrushPreset& owner); + static kEventResult handle_event(NodePanelBrushPreset& owner, Event* event); static void handle_click(NodePanelBrushPreset& owner, Node* target); static void add_brush(NodePanelBrushPreset& owner, std::shared_ptr brush); static void added(NodePanelBrushPreset& owner); diff --git a/src/legacy_canvas_object_draw_services.cpp b/src/legacy_canvas_object_draw_services.cpp index 821d7434..499b2138 100644 --- a/src/legacy_canvas_object_draw_services.cpp +++ b/src/legacy_canvas_object_draw_services.cpp @@ -219,3 +219,28 @@ void legacy_canvas_draw_objects( } } // namespace pp::panopainter + +void Canvas::draw_objects_direct( + std::function observer, + Layer& layer, + int frame) +{ + pp::panopainter::legacy_canvas_draw_objects_direct(*this, std::move(observer), layer, frame); +} + +void Canvas::draw_objects( + std::function observer, + Layer& layer, + int frame, + bool save_history) +{ + pp::panopainter::legacy_canvas_draw_objects(*this, std::move(observer), layer, frame, save_history); +} + +void Canvas::draw_objects( + std::function observer, + int frame, + bool save_history) +{ + draw_objects(std::move(observer), layer(), frame, save_history); +} diff --git a/src/legacy_canvas_projection_services.cpp b/src/legacy_canvas_projection_services.cpp index ed8587a3..9d7dcd4b 100644 --- a/src/legacy_canvas_projection_services.cpp +++ b/src/legacy_canvas_projection_services.cpp @@ -177,3 +177,58 @@ void legacy_canvas_set_camera(Canvas& canvas, const CameraData& camera) } } // namespace pp::panopainter + +bool Canvas::point_trace( + glm::vec2 loc, + glm::vec3& ray_origin, + glm::vec3& ray_dir, + glm::vec3& hit_pos, + glm::vec2& fb_pos, + glm::vec3& hit_normal, + int& out_plane_id) +{ + return pp::panopainter::legacy_canvas_point_trace(*this, loc, ray_origin, ray_dir, hit_pos, fb_pos, hit_normal, out_plane_id); +} + +bool Canvas::point_trace_plane( + glm::vec2 loc, + glm::vec3& ray_origin, + glm::vec3& ray_dir, + glm::vec3& hit_pos, + glm::vec3& hit_normal, + glm::vec2& hit_fb_pos, + int plane_id) +{ + return pp::panopainter::legacy_canvas_point_trace_plane(*this, loc, ray_origin, ray_dir, hit_pos, hit_normal, hit_fb_pos, plane_id); +} + +void Canvas::point_unproject( + glm::vec2 loc, + glm::vec4 vp, + glm::mat4 camera, + glm::mat4 proj, + glm::vec3& out_origin, + glm::vec3& out_dir) +{ + pp::panopainter::legacy_canvas_point_unproject(loc, vp, camera, proj, out_origin, out_dir); +} + +void Canvas::point_unproject(glm::vec2 loc, glm::vec3& out_origin, glm::vec3& out_dir) +{ + pp::panopainter::legacy_canvas_point_unproject(*this, loc, out_origin, out_dir); +} + +glm::vec3 Canvas::point_trace(glm::vec2 loc) +{ + return pp::panopainter::legacy_canvas_point_trace(*this, loc); +} + +void Canvas::project2Dpoints(std::vector& vertices) +{ + pp::panopainter::legacy_canvas_project_2d_points(*this, vertices); +} + +glm::vec3 Canvas::project2Dpoint(glm::vec2 pt) +{ + return pp::panopainter::legacy_canvas_project_2d_point(*this, pt); +} diff --git a/src/legacy_canvas_render_shell_services.cpp b/src/legacy_canvas_render_shell_services.cpp index 2320117d..65018e39 100644 --- a/src/legacy_canvas_render_shell_services.cpp +++ b/src/legacy_canvas_render_shell_services.cpp @@ -19,6 +19,7 @@ #include #include #include +#include namespace { @@ -725,3 +726,71 @@ void legacy_canvas_render_shell_set_camera(Canvas& canvas, const CameraData& cam } } // namespace pp::panopainter + +void Canvas::draw_merge_temporary_paint_branch( + int layer_index, + int plane_index, + std::shared_ptr layer, + const Brush& brush, + const glm::mat4& ortho) +{ + pp::panopainter::legacy_canvas_draw_merge_temporary_paint_branch( + *this, + layer_index, + plane_index, + std::move(layer), + brush, + ortho); +} + +void Canvas::draw_merge_branch_orchestration( + int plane_index, + int layer_index, + const std::shared_ptr& layer, + const Brush& brush, + const glm::mat4& ortho, + bool use_blend, + bool copy_blend_destination) +{ + pp::panopainter::legacy_canvas_draw_merge_branch_orchestration( + *this, + plane_index, + layer_index, + layer, + brush, + ortho, + use_blend, + copy_blend_destination); +} + +void Canvas::draw_merge_final_plane_composite( + const glm::mat4& ortho, + bool draw_checkerboard) +{ + pp::panopainter::legacy_canvas_draw_merge_final_plane_composite(*this, ortho, draw_checkerboard); +} + +void Canvas::stroke_commit_timelapse() +{ + pp::panopainter::legacy_canvas_stroke_commit_timelapse(*this); +} + +void Canvas::draw_merge(bool draw_checkerboard, std::array faces /*= SIXPLETTE(true)*/) +{ + pp::panopainter::legacy_canvas_draw_merge(*this, draw_checkerboard, faces); +} + +void Canvas::destroy() +{ + pp::panopainter::legacy_canvas_destroy(*this); +} + +bool Canvas::create(int width, int height) +{ + return pp::panopainter::legacy_canvas_create(*this, width, height); +} + +void Canvas::clear_context() +{ + pp::panopainter::legacy_canvas_clear_context(*this); +} diff --git a/src/legacy_canvas_stroke_live_services.cpp b/src/legacy_canvas_stroke_live_services.cpp index bcc9d66b..d449b817 100644 --- a/src/legacy_canvas_stroke_live_services.cpp +++ b/src/legacy_canvas_stroke_live_services.cpp @@ -612,3 +612,8 @@ void Canvas::stroke_draw_live() m_current_stroke = nullptr; } } + +void Canvas::stroke_draw() +{ + stroke_draw_live(); +} diff --git a/src/legacy_canvas_stroke_runtime_services.cpp b/src/legacy_canvas_stroke_runtime_services.cpp index 926dc7f8..21031f87 100644 --- a/src/legacy_canvas_stroke_runtime_services.cpp +++ b/src/legacy_canvas_stroke_runtime_services.cpp @@ -334,3 +334,36 @@ void legacy_canvas_stroke_start(Canvas& canvas, glm::vec3 point, float pressure) } } // namespace pp::panopainter + +void Canvas::stroke_end() +{ + pp::panopainter::legacy_canvas_stroke_end(*this); +} + +void Canvas::stroke_cancel() +{ + pp::panopainter::legacy_canvas_stroke_cancel(*this); +} + +void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) +{ + pp::panopainter::legacy_canvas_stroke_draw_mix(*this, bb_min, bb_sz); +} + +std::array, 6> Canvas::stroke_draw_project( + std::array& B, + bool project_3d /*= false*/, + glm::mat4 mv /*= glm::mat4(1)*/) const +{ + return pp::panopainter::legacy_canvas_stroke_draw_project(*this, B, project_3d, mv); +} + +void Canvas::stroke_update(glm::vec3 point, float pressure) +{ + pp::panopainter::legacy_canvas_stroke_update(*this, point, pressure); +} + +void Canvas::stroke_start(glm::vec3 point, float pressure) +{ + pp::panopainter::legacy_canvas_stroke_start(*this, point, pressure); +} diff --git a/src/legacy_node_stroke_preview_draw_services.cpp b/src/legacy_node_stroke_preview_draw_services.cpp index 2d472ae1..98fd9cc3 100644 --- a/src/legacy_node_stroke_preview_draw_services.cpp +++ b/src/legacy_node_stroke_preview_draw_services.cpp @@ -1,11 +1,192 @@ #include "pch.h" #include "legacy_node_stroke_preview_draw_services.h" +#include "legacy_canvas_stroke_composite_services.h" +#include "legacy_canvas_stroke_execution_services.h" +#include "legacy_ui_gl_dispatch.h" +#include "renderer_gl/opengl_capabilities.h" +#include "util.h" + +#include namespace pp::panopainter { namespace { +namespace stroke_preview_composite_slots { +constexpr std::uint32_t kBackground = 0U; +constexpr std::uint32_t kStroke = 1U; +constexpr std::uint32_t kDual = 3U; +constexpr std::uint32_t kPattern = 4U; +} + +pp::panopainter::LegacyStrokeCompositeUniforms make_stroke_preview_mix_composite_uniforms( + const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader_plan) noexcept +{ + return { + .resolution = shader_plan.resolution, + .pattern = { + .scale = shader_plan.pattern_scale, + .invert = shader_plan.pattern_invert, + .brightness = shader_plan.pattern_brightness, + .contrast = shader_plan.pattern_contrast, + .depth = shader_plan.pattern_depth, + .blend_mode = shader_plan.pattern_blend_mode, + .offset = shader_plan.pattern_offset, + }, + .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 = shader_plan.blend_mode, + .use_dual = shader_plan.use_dual, + .dual_blend_mode = shader_plan.dual_blend_mode, + .dual_alpha = shader_plan.dual_alpha, + .use_pattern = shader_plan.use_pattern, + }; +} + +pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_execution_request( + const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader, + RTT& mixer_rtt, + const Brush& brush, + Sampler& linear_sampler, + Texture2D& background_texture, + Texture2D& stroke_texture, + Texture2D& dual_texture, + std::span mix_planes, + std::function draw_mix) +{ + return pp::panopainter::make_legacy_canvas_stroke_mix_pass_request( + "NodeStrokePreview::stroke_draw_mix", + glm::vec2(static_cast(mixer_rtt.getWidth()), static_cast(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); + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview"); + background_texture.bind(); + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview"); + stroke_texture.bind(); + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview"); + dual_texture.bind(); + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kPattern, "NodeStrokePreview"); + brush.m_pattern_texture ? brush.m_pattern_texture->bind() : pp::legacy::ui_gl::unbind_texture_2d("NodeStrokePreview"); + }, + [] {}, + [&](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) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview"); + background_texture.bind(); + }, + [&](int) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview"); + stroke_texture.bind(); + }, + [&](int) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview"); + dual_texture.bind(); + }, + std::move(draw_mix), + [&](int) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kDual, "NodeStrokePreview"); + dual_texture.unbind(); + }, + [&](int) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kStroke, "NodeStrokePreview"); + stroke_texture.unbind(); + }, + [&](int) { + pp::legacy::ui_gl::activate_texture_unit(stroke_preview_composite_slots::kBackground, "NodeStrokePreview"); + background_texture.unbind(); + }); +} + +} // namespace + +bool execute_legacy_node_stroke_preview_mix_pass( + const LegacyNodeStrokePreviewMixPassExecutionRequest& request) +{ + if (!request.draw_mix) { + return false; + } + + const auto mix_pass = pp::panopainter::plan_legacy_node_stroke_preview_mix_pass( + pp::panopainter::LegacyNodeStrokePreviewMixPassRequest { + .resolution = request.preview_size, + .pattern_scale = request.brush.m_pattern_scale, + .pattern_flipx = request.brush.m_pattern_flipx, + .pattern_flipy = request.brush.m_pattern_flipy, + .pattern_invert = request.brush.m_pattern_invert, + .pattern_brightness = request.brush.m_pattern_brightness, + .pattern_contrast = request.brush.m_pattern_contrast, + .pattern_depth = request.brush.m_pattern_depth, + .pattern_rand_offset = request.brush.m_pattern_rand_offset, + .pattern_enabled = request.brush.m_pattern_enabled, + .pattern_eachsample = request.brush.m_pattern_eachsample, + .tip_wet = request.brush.m_tip_wet, + .tip_mix = request.brush.m_tip_mix, + .tip_noise = request.brush.m_tip_noise, + .dual_enabled = request.brush.m_dual_enabled, + .dual_blend_mode = request.brush.m_dual_blend_mode, + .pattern_blend_mode = request.brush.m_pattern_blend_mode, + .dual_opacity = request.brush.m_dual_opacity, + .blend_mode = request.brush.m_blend_mode, + }); + 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; + const auto mix_result = pp::panopainter::execute_legacy_canvas_stroke_mix_pass_with_setup( + [&] { + pp::legacy::ui_gl::apply_viewport( + 0, + 0, + request.mixer_rtt.getWidth(), + request.mixer_rtt.getHeight(), + "NodeStrokePreview"); + pp::legacy::ui_gl::set_capability(pp::renderer::gl::depth_test_state(), false, "NodeStrokePreview"); + pp::legacy::ui_gl::set_capability(pp::renderer::gl::scissor_test_state(), true, "NodeStrokePreview"); + pp::legacy::ui_gl::set_capability(pp::renderer::gl::blend_state(), false, "NodeStrokePreview"); + pp::legacy::ui_gl::apply_scissor_rect( + static_cast(request.bb_min.x), + static_cast(request.bb_min.y), + static_cast(request.bb_sz.x), + static_cast(request.bb_sz.y), + "NodeStrokePreview"); + gl.save(); + request.mixer_rtt.bindFramebuffer(); + }, + [&] { + request.mixer_rtt.unbindFramebuffer(); + gl.restore(); + }, + make_stroke_preview_mix_pass_execution_request( + mix_pass.shader, + request.mixer_rtt, + request.brush, + request.linear_sampler, + request.background_texture, + request.stroke_texture, + request.dual_texture, + mix_planes, + request.draw_mix)); + return mix_result.ok; +} + bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequest& request) { return request.bind_dual_pass_textures && @@ -18,8 +199,6 @@ bool has_valid_live_render_callbacks(const LegacyNodeStrokePreviewLiveRenderRequ request.draw_composite; } -} // namespace - bool execute_legacy_node_stroke_preview_live_render_passes( const LegacyNodeStrokePreviewLiveRenderRequest& request) { diff --git a/src/legacy_node_stroke_preview_draw_services.h b/src/legacy_node_stroke_preview_draw_services.h index 1c49eeaa..3e1dabc5 100644 --- a/src/legacy_node_stroke_preview_draw_services.h +++ b/src/legacy_node_stroke_preview_draw_services.h @@ -45,6 +45,22 @@ struct LegacyNodeStrokePreviewLiveRenderRequest { std::function draw_composite; }; +struct LegacyNodeStrokePreviewMixPassExecutionRequest { + const Brush& brush; + glm::vec2 preview_size {}; + RTT& mixer_rtt; + glm::vec2 bb_min {}; + glm::vec2 bb_sz {}; + Sampler& linear_sampler; + Texture2D& background_texture; + Texture2D& stroke_texture; + Texture2D& dual_texture; + std::function draw_mix; +}; + +[[nodiscard]] bool execute_legacy_node_stroke_preview_mix_pass( + const LegacyNodeStrokePreviewMixPassExecutionRequest& request); + [[nodiscard]] bool execute_legacy_node_stroke_preview_live_render_passes( const LegacyNodeStrokePreviewLiveRenderRequest& request); diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 2591a47c..91949688 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -213,31 +213,7 @@ void NodePanelBrushPreset::init() kEventResult NodePanelBrushPreset::handle_event(Event* e) { - switch (e->m_type) - { - case kEventType::MouseLeave: - if (!m_interacted) - break; - // else fall through - case kEventType::MouseUpL: - if (!m_mouse_inside) - { - pp::panopainter::release_legacy_mouse_capture(*this); - if (m_parent) - { - pp::panopainter::detach_legacy_node_from_parent(*this); - } - if (on_popup_close) - { - on_popup_close(this); - } - } - break; - default: - return kEventResult::Available; - break; - } - return kEventResult::Consumed; + return pp::panopainter::LegacyBrushPresetPanelUi::handle_event(*this, e); } void NodePanelBrushPreset::handle_click(Node* target) diff --git a/src/node_stroke_preview.cpp b/src/node_stroke_preview.cpp index ae831d92..d63b7093 100644 --- a/src/node_stroke_preview.cpp +++ b/src/node_stroke_preview.cpp @@ -7,7 +7,6 @@ #include "canvas.h" #include "app.h" #include "legacy_canvas_draw_merge_services.h" -#include "legacy_canvas_stroke_composite_services.h" #include "legacy_canvas_stroke_execution_services.h" #include "legacy_canvas_stroke_preview_services.h" #include "legacy_canvas_stroke_shader_services.h" @@ -69,13 +68,6 @@ void apply_stroke_preview_capability(std::uint32_t state, bool enabled) pp::legacy::ui_gl::set_capability(state, enabled, "NodeStrokePreview"); } -namespace stroke_preview_composite_slots { -constexpr std::uint32_t kBackground = 0U; -constexpr std::uint32_t kStroke = 1U; -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; @@ -84,122 +76,6 @@ constexpr std::uint32_t kMixer = 3U; constexpr std::uint32_t kReservedLinear = 4U; } -pp::panopainter::LegacyNodeStrokePreviewMixPassRequest make_stroke_preview_mix_pass_request( - const Brush& brush, - glm::vec2 resolution) noexcept -{ - return { - .resolution = resolution, - .pattern_scale = brush.m_pattern_scale, - .pattern_flipx = brush.m_pattern_flipx, - .pattern_flipy = brush.m_pattern_flipy, - .pattern_invert = brush.m_pattern_invert, - .pattern_brightness = brush.m_pattern_brightness, - .pattern_contrast = brush.m_pattern_contrast, - .pattern_depth = brush.m_pattern_depth, - .pattern_rand_offset = brush.m_pattern_rand_offset, - .pattern_enabled = brush.m_pattern_enabled, - .pattern_eachsample = brush.m_pattern_eachsample, - .tip_wet = brush.m_tip_wet, - .tip_mix = brush.m_tip_mix, - .tip_noise = brush.m_tip_noise, - .dual_enabled = brush.m_dual_enabled, - .dual_blend_mode = brush.m_dual_blend_mode, - .pattern_blend_mode = brush.m_pattern_blend_mode, - .dual_opacity = brush.m_dual_opacity, - .blend_mode = brush.m_blend_mode, - }; -} - -pp::panopainter::LegacyStrokeCompositeUniforms make_stroke_preview_mix_composite_uniforms( - const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader_plan) noexcept -{ - return { - .resolution = shader_plan.resolution, - .pattern = { - .scale = shader_plan.pattern_scale, - .invert = shader_plan.pattern_invert, - .brightness = shader_plan.pattern_brightness, - .contrast = shader_plan.pattern_contrast, - .depth = shader_plan.pattern_depth, - .blend_mode = shader_plan.pattern_blend_mode, - .offset = shader_plan.pattern_offset, - }, - .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 = shader_plan.blend_mode, - .use_dual = shader_plan.use_dual, - .dual_blend_mode = shader_plan.dual_blend_mode, - .dual_alpha = shader_plan.dual_alpha, - .use_pattern = shader_plan.use_pattern, - }; -} - -pp::panopainter::LegacyCanvasStrokeMixPassRequest make_stroke_preview_mix_pass_execution_request( - const pp::panopainter::LegacyNodeStrokePreviewMixPassPlan::ShaderPlan& shader, - RTT& mixer_rtt, - const Brush& brush, - Sampler& linear_sampler, - Texture2D& background_texture, - Texture2D& stroke_texture, - Texture2D& dual_texture, - std::span mix_planes, - std::function draw_mix) -{ - return pp::panopainter::make_legacy_canvas_stroke_mix_pass_request( - "NodeStrokePreview::stroke_draw_mix", - glm::vec2(static_cast(mixer_rtt.getWidth()), static_cast(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); - stroke_texture.bind(); - set_active_texture_unit(stroke_preview_composite_slots::kDual); - dual_texture.bind(); - set_active_texture_unit(stroke_preview_composite_slots::kPattern); - brush.m_pattern_texture ? brush.m_pattern_texture->bind() : unbind_texture_2d(); - }, - [] {}, - [&](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(); - }); -} - void bind_stroke_preview_live_samplers( Sampler& mipmap_sampler, Sampler& linear_sampler, @@ -308,49 +184,22 @@ void NodeStrokePreview::init_controls() void NodeStrokePreview::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz) { 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; - 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(bb_min.x), - static_cast(bb_min.y), - static_cast(bb_sz.x), - static_cast(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] { + const bool mix_ok = pp::panopainter::execute_legacy_node_stroke_preview_mix_pass( + pp::panopainter::LegacyNodeStrokePreviewMixPassExecutionRequest { + .brush = *b, + .preview_size = m_size, + .mixer_rtt = m_rtt_mixer, + .bb_min = bb_min, + .bb_sz = bb_sz, + .linear_sampler = m_sampler_linear, + .background_texture = m_tex_background, + .stroke_texture = m_tex, + .dual_texture = m_tex_dual, + .draw_mix = [this] { m_plane.draw_fill(); - })); - assert(mix_result.ok); + }, + }); + assert(mix_ok); } glm::vec4 NodeStrokePreview::stroke_draw_samples(