From a5002a4e3ea46bae19f474e5906caedb022fce45 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 16 Jun 2026 18:43:14 +0200 Subject: [PATCH] Extract canvas object draw and brush panel services --- cmake/PanoPainterSources.cmake | 4 + docs/modernization/roadmap.md | 20 +- docs/modernization/tasks.md | 17 +- src/canvas.cpp | 142 +------------ src/legacy_brush_panel_services.cpp | 166 ++++++++++++++++ src/legacy_brush_panel_services.h | 26 +++ src/legacy_canvas_object_draw_services.cpp | 221 +++++++++++++++++++++ src/legacy_canvas_object_draw_services.h | 22 ++ src/node_canvas.cpp | 34 ++-- src/node_panel_brush.cpp | 131 +----------- 10 files changed, 504 insertions(+), 279 deletions(-) create mode 100644 src/legacy_brush_panel_services.cpp create mode 100644 src/legacy_brush_panel_services.h create mode 100644 src/legacy_canvas_object_draw_services.cpp create mode 100644 src/legacy_canvas_object_draw_services.h diff --git a/cmake/PanoPainterSources.cmake b/cmake/PanoPainterSources.cmake index d4bb392c..b2f5079d 100644 --- a/cmake/PanoPainterSources.cmake +++ b/cmake/PanoPainterSources.cmake @@ -23,6 +23,8 @@ set(PP_LEGACY_PAINT_DOCUMENT_SOURCES src/canvas_actions.cpp src/canvas_layer.cpp src/legacy_canvas_document_io_services.cpp + src/legacy_canvas_object_draw_services.cpp + src/legacy_canvas_object_draw_services.h src/legacy_canvas_projection_services.cpp src/legacy_canvas_projection_services.h src/legacy_canvas_state_services.cpp @@ -143,6 +145,8 @@ set(PP_PANOPAINTER_APP_SOURCES set(PP_PANOPAINTER_UI_SOURCES src/legacy_brush_ui_services.cpp src/legacy_brush_ui_services.h + src/legacy_brush_panel_services.cpp + src/legacy_brush_panel_services.h src/legacy_document_animation_services.cpp src/legacy_document_animation_services.h src/legacy_grid_ui_services.cpp diff --git a/docs/modernization/roadmap.md b/docs/modernization/roadmap.md index ac59b1aa..623a0813 100644 --- a/docs/modernization/roadmap.md +++ b/docs/modernization/roadmap.md @@ -79,14 +79,14 @@ What is still carrying too much live ownership: Current hotspot files: -- `src/canvas.cpp`: 2728 lines +- `src/canvas.cpp`: 2592 lines - `src/app_layout.cpp`: 125 lines -- `src/canvas_modes.cpp`: 1710 lines +- `src/canvas_modes.cpp`: 1626 lines - `src/node.cpp`: 1368 lines - `src/main.cpp`: 271 lines -- `src/node_panel_brush.cpp`: 1207 lines +- `src/node_panel_brush.cpp`: 1094 lines - `src/node_stroke_preview.cpp`: 910 lines -- `src/node_canvas.cpp`: 864 lines +- `src/node_canvas.cpp`: 872 lines - `src/app.cpp`: 575 lines - `src/app_dialogs.cpp`: 168 lines @@ -244,6 +244,18 @@ Current architecture mismatches that must be treated as real blockers: callback-assembly setup now also route through `execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent unmerged draw shell from the live node even though the file itself remains + large, while `NodeCanvas::draw()` merged-pass callback wiring and pass setup + now also route through `execute_node_canvas_draw_merged_pass(...)`, which + trims another coherent merged draw shell from the live node even though the + broader draw loop still remains inline, + while `Canvas::draw_objects_direct(...)` and `Canvas::draw_objects(...)` now + route through `src/legacy_canvas_object_draw_services.*` instead of staying + inline in `src/canvas.cpp`, which trims another coherent object-draw and + viewport-state execution family from the live canvas shell, + while `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now + routes through `src/legacy_brush_panel_services.*` instead of staying inline + in `src/node_panel_brush.cpp`, which trims another retained brush-workflow + pocket from the live UI node even though the broader panel still remains large, while shared canvas-mode GL wrappers plus the `CanvasModeBasicCamera` and `CanvasModeCamera` input handlers now also route through `src/legacy_canvas_mode_helpers.*` instead of staying inline in diff --git a/docs/modernization/tasks.md b/docs/modernization/tasks.md index e93f402d..7aef0f95 100644 --- a/docs/modernization/tasks.md +++ b/docs/modernization/tasks.md @@ -91,7 +91,7 @@ Status: In Progress Why now: `src/canvas.cpp` is still the biggest single architectural blocker at about -2728 lines. +2592 lines. Current slice: - Canvas state-management helpers for picking, clear/clear-all, layer @@ -108,6 +108,10 @@ Current slice: `src/legacy_canvas_projection_services.*` instead of staying inline in `src/canvas.cpp`, which trims another coherent non-UI state/query pocket from the live canvas shell. +- `Canvas::draw_objects_direct(...)` and `Canvas::draw_objects(...)` now also + live in `src/legacy_canvas_object_draw_services.*` instead of staying inline + in `src/canvas.cpp`, which trims another coherent object-draw and + viewport-state execution pocket from the live canvas shell. - Shared canvas-mode GL wrappers plus the `CanvasModeBasicCamera` and `CanvasModeCamera` input handlers now also live in `src/legacy_canvas_mode_helpers.*` instead of staying inline in @@ -263,6 +267,10 @@ Current slice: through `execute_node_canvas_draw_unmerged_pass(...)`, which trims another coherent unmerged draw-orchestration block from the live node even though the file size remains roughly flat. +- `NodeCanvas::draw()` merged-pass callback wiring and pass setup now also + route through `execute_node_canvas_draw_merged_pass(...)`, which trims + another coherent merged draw-orchestration block from the live node even + though the broader draw loop still remains inline. Write scope: - `src/node_stroke_preview.cpp` @@ -970,6 +978,13 @@ Why now: Cloud browse/download/upload and brush package import/export still close over retained nodes, worker threads, and direct UI ownership. +Current slice: +- `NodePanelBrush` save/restore/scan/reload/find/get-path ownership now routes + through `src/legacy_brush_panel_services.*` instead of staying inline in + `src/node_panel_brush.cpp`, which trims a coherent retained brush-workflow + pocket from the live UI node even though cloud and package-worker ownership + still remain separate follow-up work. + Write scope: - `src/legacy_cloud_services.*` - `src/node_dialog_cloud.*` diff --git a/src/canvas.cpp b/src/canvas.cpp index c04e8013..945f523f 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -10,6 +10,7 @@ #include "legacy_canvas_stroke_edge_services.h" #include "legacy_canvas_stroke_execution_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_gl_dispatch.h" @@ -2531,149 +2532,12 @@ void Canvas::clear_context() void Canvas::draw_objects_direct(std::function observer, Layer& layer, int frame) { - App::I->render_task([&] - { - // save viewport and clear color states - const auto vp = query_canvas_viewport(); - const auto cc = query_canvas_clear_color(); - auto blend = query_canvas_capability(blend_state()); - - // prepare common states - apply_canvas_viewport(0, 0, layer.w, layer.h); - apply_canvas_capability(blend_state(), false); - - GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h); - - glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f); - for (int i = 0; i < 6; i++) - { - glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]); - layer.rtt(i, frame).bindFramebuffer(); - attach_canvas_depth_renderbuffer(rboID); - - observer(plane_camera, proj, i); - - attach_canvas_depth_renderbuffer(0); - layer.rtt(i, frame).unbindFramebuffer(); - - layer.face(i, frame) = true; - layer.box(i, frame) = { 0, 0, layer.w, layer.h }; - } - - delete_canvas_renderbuffer(rboID); - - // restore viewport and clear color states - blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false); - apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height); - apply_canvas_clear_color(cc); - set_active_texture_unit(0); - }); + 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) { - App::I->render_task([&] - { - // save viewport and clear color states - const auto vp = query_canvas_viewport(); - const auto cc = query_canvas_clear_color(); - auto blend = query_canvas_capability(blend_state()); - - // prepare common states - apply_canvas_viewport(0, 0, layer.w, layer.h); - apply_canvas_capability(blend_state(), false); - - GLuint rboID = allocate_canvas_depth_renderbuffer(layer.w, layer.h); - - RTT rtt; - rtt.create(layer.w, layer.h); - rtt.bindFramebuffer(); - attach_canvas_depth_renderbuffer(rboID); - rtt.unbindFramebuffer(); - - // allocate action to add to history - ActionStroke* action; - - if (save_history) - { - action = new ActionStroke; - action->was_saved = !m_unsaved; - } - - glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f); - for (int i = 0; i < 6; i++) - { - glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]); - rtt.bindFramebuffer(); - rtt.clear({ 1, 1, 1, 0 }); - observer(plane_camera, proj, i); - rtt.unbindFramebuffer(); - - glm::vec4 bounds = rtt.calc_bounds(); - - layer.rtt(i, frame).bindFramebuffer(); - - glm::vec2 box_sz = zw(bounds) - xy(bounds); - bool has_data = box_sz.x > 0 && box_sz.y > 0; - - if (save_history) - { - // save image before commit - if (has_data) - { - action->m_image[i] = std::make_unique(box_sz.x * box_sz.y * 4); - layer.rtt(i, frame).readPixelsRgba8( - static_cast(bounds.x), - static_cast(bounds.y), - static_cast(box_sz.x), - static_cast(box_sz.y), - action->m_image[i].get()); - action->m_box[i] = bounds; - } - action->m_old_box[i] = layer.box(i, frame); - action->m_old_dirty[i] = layer.face(i, frame); - } - - // draw the tmp layer into the actual layer - if (has_data) - { - pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader( - pp::panopainter::LegacyCanvasDrawMergeTextureUniforms { - .mvp = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f), - .texture_slot = 0, - }); - set_active_texture_unit(0); - m_sampler_nearest.bind(0); - rtt.bindTexture(); - m_plane.draw_fill(); - rtt.unbindTexture(); - - layer.face(i, frame) = true; - layer.box(i, frame) = { glm::min(xy(layer.box(i, frame)), xy(bounds)), glm::max(zw(layer.box(i, frame)), zw(bounds)) }; - } - - layer.rtt(i, frame).unbindFramebuffer(); - } - - if (save_history) - { - // save history - action->m_layer_idx = m_current_layer_idx; - action->m_frame_idx = frame; - action->m_canvas = this; - //action->m_stroke = std::move(m_current_stroke); - ActionManager::add(action); - } - - delete_canvas_renderbuffer(rboID); - rtt.destroy(); - - // restore viewport and clear color states - blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false); - apply_canvas_viewport(vp.x, vp.y, vp.width, vp.height); - apply_canvas_clear_color(cc); - set_active_texture_unit(0); - }); + 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) diff --git a/src/legacy_brush_panel_services.cpp b/src/legacy_brush_panel_services.cpp new file mode 100644 index 00000000..00d60a77 --- /dev/null +++ b/src/legacy_brush_panel_services.cpp @@ -0,0 +1,166 @@ +#include "pch.h" + +#include "legacy_brush_panel_services.h" + +#include "app.h" +#include "asset.h" +#include "node_panel_brush.h" + +#include +#include +#include + +namespace pp::panopainter { + +LegacyBrushPanelServices::LegacyBrushPanelServices(NodePanelBrush& panel) noexcept + : panel_(panel) +{ +} + +int LegacyBrushPanelServices::find_brush(const std::string& name) const +{ + for (int i = 0; i < panel_.m_container->m_children.size(); i++) { + auto* b = static_cast(panel_.m_container->m_children[i].get()); + if (b->brush_name.find(name) != std::string::npos) { + return i; + } + } + return -1; +} + +std::string LegacyBrushPanelServices::get_texture_path(int index) const +{ + if (index < 0 || index >= panel_.m_container->m_children.size()) { + return ""; + } + return static_cast(panel_.m_container->m_children[index].get())->high_path; +} + +std::string LegacyBrushPanelServices::get_thumb_path(int index) const +{ + if (index < 0 || index >= panel_.m_container->m_children.size()) { + return ""; + } + return static_cast(panel_.m_container->m_children[index].get())->thumb_path; +} + +bool LegacyBrushPanelServices::save() +{ + std::ofstream f(App::I->data_path + "/settings/" + panel_.m_dir_name + ".bin", std::ios::binary); + if (f.good()) { + BinaryStreamWriter sw; + sw.init(); + sw.wstring_raw("PPVR"); // magic code + sw.wu16(0); // version major + sw.wu16(1); // minor + sw.wu32((int)panel_.m_container->m_children.size()); // number of items + for (const auto& child : panel_.m_container->m_children) { + auto b = std::static_pointer_cast(child); + sw << *b; + } + f.write((char*)sw.m_data.data(), sw.m_data.size()); + f.close(); + App::I->flush_platform_storage(); + return true; + } + return false; +} + +bool LegacyBrushPanelServices::restore() +{ + Asset f; + auto path = App::I->data_path + "/settings/" + panel_.m_dir_name + ".bin"; + if (f.open(path.c_str())) { + f.read_all(); + + if (f.m_len == 0) { + return false; + } + + BinaryStreamReader sr; + sr.init(f.m_data, f.m_len); + + if (sr.rstring(4) != "PPVR") { + LOG("PPVR tag not found") + return false; + } + auto vmaj = sr.ru16(); + auto vmin = sr.ru16(); + if (vmaj != 0 && vmin != 1) { + LOG("unrecognised version %d.%d", vmaj, vmin); + return false; + } + + auto count = sr.ru32(); + + for (int k = 0; k < count; k++) { + auto b = std::make_shared(); + if (!b->read(sr)) { + LOG("error deserializing the button brush"); + return false; + } + + if (Asset::exist(b->high_path)) { + panel_.m_container->add_child(b); + b->init(); + b->create(); + b->loaded(); + b->set_icon(b->thumb_path.c_str()); + b->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1); + } + } + return true; + } + return false; +} + +void LegacyBrushPanelServices::clear() +{ + panel_.m_container->remove_all_children(); +} + +void LegacyBrushPanelServices::scan() +{ + auto icons = Asset::list_files("data/" + panel_.m_dir_name, ".*\\.png$"); + for (auto& i : icons) { + std::string path = "data/" + panel_.m_dir_name + "/thumbs/" + i; + std::string path_hi = "data/" + panel_.m_dir_name + "/" + i; + NodeButtonBrush* brush = new NodeButtonBrush; + panel_.m_container->add_child(brush); + brush->init(); + brush->create(); + brush->loaded(); + brush->set_icon(path.c_str()); + brush->thumb_path = path; + brush->high_path = path_hi; + brush->brush_name = i; + brush->m_user_brush = false; // system brush, cannot be deleted from file + brush->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1); + } + + auto custom_icons = Asset::list_files(App::I->data_path + "/" + panel_.m_dir_name, ".*\\.png$"); + for (auto& i : custom_icons) { + std::string path_thumb = App::I->data_path + "/" + panel_.m_dir_name + "/thumbs/" + i; + std::string path_high = App::I->data_path + "/" + panel_.m_dir_name + "/" + i; + NodeButtonBrush* brush = new NodeButtonBrush; + panel_.m_container->add_child(brush); + brush->init(); + brush->create(); + brush->loaded(); + brush->set_icon(path_thumb.c_str()); + brush->thumb_path = path_thumb; + brush->high_path = path_high; + brush->brush_name = i; + brush->m_user_brush = true; + brush->on_click = std::bind(&NodePanelBrush::handle_click, &panel_, std::placeholders::_1); + } +} + +void LegacyBrushPanelServices::reload() +{ + clear(); + scan(); + save(); +} + +} // namespace pp::panopainter diff --git a/src/legacy_brush_panel_services.h b/src/legacy_brush_panel_services.h new file mode 100644 index 00000000..9e719ef9 --- /dev/null +++ b/src/legacy_brush_panel_services.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +class NodePanelBrush; + +namespace pp::panopainter { + +class LegacyBrushPanelServices final { +public: + explicit LegacyBrushPanelServices(NodePanelBrush& panel) noexcept; + + int find_brush(const std::string& name) const; + std::string get_texture_path(int index) const; + std::string get_thumb_path(int index) const; + bool save(); + bool restore(); + void clear(); + void scan(); + void reload(); + +private: + NodePanelBrush& panel_; +}; + +} // namespace pp::panopainter diff --git a/src/legacy_canvas_object_draw_services.cpp b/src/legacy_canvas_object_draw_services.cpp new file mode 100644 index 00000000..821d7434 --- /dev/null +++ b/src/legacy_canvas_object_draw_services.cpp @@ -0,0 +1,221 @@ +#include "pch.h" + +#include "legacy_canvas_object_draw_services.h" + +#include "app.h" +#include "canvas.h" +#include "legacy_canvas_draw_merge_services.h" +#include "legacy_gl_renderbuffer_dispatch.h" +#include "legacy_ui_gl_dispatch.h" +#include "renderer_gl/opengl_capabilities.h" + +namespace pp::panopainter { + +namespace { + +GLenum blend_state() +{ + return static_cast(pp::renderer::gl::blend_state()); +} + +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_capability(std::uint32_t state, bool enabled) +{ + pp::legacy::ui_gl::set_capability(state, enabled, "Canvas"); +} + +void set_active_texture_unit(std::uint32_t unit_index) +{ + pp::legacy::ui_gl::activate_texture_unit(unit_index, "Canvas"); +} + +struct LegacyCanvasObjectDrawState { + pp::renderer::gl::OpenGlViewportRect viewport; + std::array clear_color; + bool blend = false; +}; + +LegacyCanvasObjectDrawState capture_legacy_canvas_object_draw_state() +{ + return { + .viewport = query_canvas_viewport(), + .clear_color = query_canvas_clear_color(), + .blend = pp::legacy::ui_gl::query_capability(blend_state(), "Canvas"), + }; +} + +void restore_legacy_canvas_object_draw_state(const LegacyCanvasObjectDrawState& state) +{ + state.blend ? apply_canvas_capability(blend_state(), true) : apply_canvas_capability(blend_state(), false); + apply_canvas_viewport(state.viewport.x, state.viewport.y, state.viewport.width, state.viewport.height); + apply_canvas_clear_color(state.clear_color); + set_active_texture_unit(0); +} + +template +void execute_legacy_canvas_object_draw_task(Layer& layer, Execute&& execute) +{ + const auto state = capture_legacy_canvas_object_draw_state(); + + apply_canvas_viewport(0, 0, layer.w, layer.h); + apply_canvas_capability(blend_state(), false); + + GLuint rboID = pp::legacy::gl_renderbuffer::allocate_depth_renderbuffer(layer.w, layer.h, "Canvas"); + execute(rboID); + pp::legacy::gl_renderbuffer::delete_renderbuffer(rboID, "Canvas"); + + restore_legacy_canvas_object_draw_state(state); +} + +void execute_legacy_canvas_object_draw_face( + Canvas& canvas, + Layer& layer, + int frame, + int face_index, + RTT& rtt, + ActionStroke* action, + bool save_history, + const std::function& observer) +{ + rtt.bindFramebuffer(); + rtt.clear({ 1, 1, 1, 0 }); + glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f); + glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas.m_plane_origin[face_index], canvas.m_plane_tangent[face_index]); + observer(plane_camera, proj, face_index); + rtt.unbindFramebuffer(); + + glm::vec4 bounds = rtt.calc_bounds(); + + layer.rtt(face_index, frame).bindFramebuffer(); + + glm::vec2 box_sz = zw(bounds) - xy(bounds); + bool has_data = box_sz.x > 0 && box_sz.y > 0; + + if (save_history) + { + if (has_data) + { + action->m_image[face_index] = std::make_unique(box_sz.x * box_sz.y * 4); + layer.rtt(face_index, frame).readPixelsRgba8( + static_cast(bounds.x), + static_cast(bounds.y), + static_cast(box_sz.x), + static_cast(box_sz.y), + action->m_image[face_index].get()); + action->m_box[face_index] = bounds; + } + action->m_old_box[face_index] = layer.box(face_index, frame); + action->m_old_dirty[face_index] = layer.face(face_index, frame); + } + + if (has_data) + { + pp::panopainter::setup_legacy_canvas_draw_merge_texture_shader( + pp::panopainter::LegacyCanvasDrawMergeTextureUniforms { + .mvp = glm::ortho(-0.5f, 0.5f, -0.5f, 0.5f), + .texture_slot = 0, + }); + set_active_texture_unit(0); + canvas.m_sampler_nearest.bind(0); + rtt.bindTexture(); + canvas.m_plane.draw_fill(); + rtt.unbindTexture(); + + layer.face(face_index, frame) = true; + layer.box(face_index, frame) = { glm::min(xy(layer.box(face_index, frame)), xy(bounds)), glm::max(zw(layer.box(face_index, frame)), zw(bounds)) }; + } + + layer.rtt(face_index, frame).unbindFramebuffer(); +} + +} // namespace + +void legacy_canvas_draw_objects_direct( + Canvas& canvas, + std::function observer, + Layer& layer, + int frame) +{ + App::I->render_task([&] + { + execute_legacy_canvas_object_draw_task(layer, [&](GLuint rboID) + { + glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f); + for (int i = 0; i < 6; i++) + { + glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas.m_plane_origin[i], canvas.m_plane_tangent[i]); + layer.rtt(i, frame).bindFramebuffer(); + pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(rboID, "Canvas"); + + observer(plane_camera, proj, i); + + pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(0, "Canvas"); + layer.rtt(i, frame).unbindFramebuffer(); + + layer.face(i, frame) = true; + layer.box(i, frame) = { 0, 0, layer.w, layer.h }; + } + }); + }); +} + +void legacy_canvas_draw_objects( + Canvas& canvas, + std::function observer, + Layer& layer, + int frame, + bool save_history) +{ + App::I->render_task([&] + { + execute_legacy_canvas_object_draw_task(layer, [&](GLuint rboID) + { + RTT rtt; + rtt.create(layer.w, layer.h); + rtt.bindFramebuffer(); + pp::legacy::gl_renderbuffer::attach_depth_renderbuffer(rboID, "Canvas"); + rtt.unbindFramebuffer(); + + ActionStroke* action = nullptr; + if (save_history) + { + action = new ActionStroke; + action->was_saved = !canvas.m_unsaved; + } + + for (int i = 0; i < 6; i++) + execute_legacy_canvas_object_draw_face(canvas, layer, frame, i, rtt, action, save_history, observer); + + if (save_history) + { + action->m_layer_idx = canvas.m_current_layer_idx; + action->m_frame_idx = frame; + action->m_canvas = &canvas; + ActionManager::add(action); + } + + rtt.destroy(); + }); + }); +} + +} // namespace pp::panopainter diff --git a/src/legacy_canvas_object_draw_services.h b/src/legacy_canvas_object_draw_services.h new file mode 100644 index 00000000..e6f038fa --- /dev/null +++ b/src/legacy_canvas_object_draw_services.h @@ -0,0 +1,22 @@ +#pragma once + +#include "canvas.h" + +#include + +namespace pp::panopainter { + +void legacy_canvas_draw_objects_direct( + Canvas& canvas, + std::function observer, + Layer& layer, + int frame); + +void legacy_canvas_draw_objects( + Canvas& canvas, + std::function observer, + Layer& layer, + int frame, + bool save_history); + +} // namespace pp::panopainter diff --git a/src/node_canvas.cpp b/src/node_canvas.cpp index 1a733bf1..e3e0fe92 100644 --- a/src/node_canvas.cpp +++ b/src/node_canvas.cpp @@ -443,6 +443,26 @@ void execute_node_canvas_draw_unmerged_pass( }, [&](const char* message) { LOG("NodeCanvas onion frame range failed: %s", message); + }); +} + +void execute_node_canvas_draw_merged_pass( + NodeCanvas& node_canvas, + const glm::mat4& proj, + const glm::mat4& camera) +{ + pp::panopainter::execute_legacy_canvas_draw_merged_pass( + node_canvas, + proj, + camera, + [&](auto state, bool enabled) { + apply_node_canvas_capability(state, enabled); + }, + [](int unit) { + set_active_texture_unit(unit); + }, + [&] { + node_canvas.m_face_plane.draw_fill(); }); } @@ -662,19 +682,7 @@ void NodeCanvas::draw() apply_node_canvas_viewport(c.x + App::I->off_x, c.y + App::I->off_y, c.z, c.w); }, [&] { - pp::panopainter::execute_legacy_canvas_draw_merged_pass( - *this, - proj, - camera, - [&](auto state, bool enabled) { - apply_node_canvas_capability(state, enabled); - }, - [](int unit) { - set_active_texture_unit(unit); - }, - [&] { - m_face_plane.draw_fill(); - }); + execute_node_canvas_draw_merged_pass(*this, proj, camera); }, [&] { execute_node_canvas_draw_unmerged_pass(*this, proj, camera, c, yaw, pitch, roll); diff --git a/src/node_panel_brush.cpp b/src/node_panel_brush.cpp index 94be778d..7a31638a 100644 --- a/src/node_panel_brush.cpp +++ b/src/node_panel_brush.cpp @@ -1,6 +1,7 @@ #include "pch.h" #include "log.h" #include "node_panel_brush.h" +#include "legacy_brush_panel_services.h" #include "assets/brush_package.h" #include "app_core/brush_ui.h" #include "legacy_brush_ui_services.h" @@ -208,156 +209,42 @@ void NodePanelBrush::handle_click(Node* target) int NodePanelBrush::find_brush(const std::string & name) const { - for (int i = 0; i < m_container->m_children.size(); i++) - { - NodeButtonBrush* b = (NodeButtonBrush*)m_container->m_children[i].get(); - if (b->brush_name.find(name) != std::string::npos) - return i; - } - return -1; + return pp::panopainter::LegacyBrushPanelServices(const_cast(*this)).find_brush(name); } std::string NodePanelBrush::get_texture_path(int index) const { - if (index < 0 || index >= m_container->m_children.size()) - return ""; - return ((NodeButtonBrush*)m_container->m_children[index].get())->high_path; + return pp::panopainter::LegacyBrushPanelServices(const_cast(*this)).get_texture_path(index); } std::string NodePanelBrush::get_thumb_path(int index) const { - if (index < 0 || index >= m_container->m_children.size()) - return ""; - return ((NodeButtonBrush*)m_container->m_children[index].get())->thumb_path; + return pp::panopainter::LegacyBrushPanelServices(const_cast(*this)).get_thumb_path(index); } bool NodePanelBrush::save() { - std::ofstream f(App::I->data_path + "/settings/" + m_dir_name + ".bin", std::ios::binary); - if (f.good()) - { - BinaryStreamWriter sw; - sw.init(); - sw.wstring_raw("PPVR"); // magic code - sw.wu16(0); // version major - sw.wu16(1); // minor - sw.wu32((int)m_container->m_children.size()); // number of items - for (const auto& child : m_container->m_children) - { - auto b = std::static_pointer_cast(child); - sw << *b; - } - f.write((char*)sw.m_data.data(), sw.m_data.size()); - f.close(); - App::I->flush_platform_storage(); - return true; - } - return false; + return pp::panopainter::LegacyBrushPanelServices(*this).save(); } bool NodePanelBrush::restore() { - Asset f; - auto path = App::I->data_path + "/settings/" + m_dir_name + ".bin"; - if (f.open(path.c_str())) - { - f.read_all(); - - if (f.m_len == 0) - return false; - - BinaryStreamReader sr; - sr.init(f.m_data, f.m_len); - - // sanity checks - if (sr.rstring(4) != "PPVR") - { - LOG("PPVR tag not found") - return false; - } - auto vmaj = sr.ru16(); - auto vmin = sr.ru16(); - if (vmaj != 0 && vmin != 1) - { - LOG("unrecognised version %d.%d", vmaj, vmin); - return false; - } - - auto count = sr.ru32(); - - for (int k = 0; k < count; k++) - { - auto b = std::make_shared(); - if (!b->read(sr)) - { - LOG("error deserializing the button brush"); - return false; - } - - if (Asset::exist(b->high_path)) - { - m_container->add_child(b); - b->init(); - b->create(); - b->loaded(); - b->set_icon(b->thumb_path.c_str()); - b->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1); - } - } - return true; - } - return false; + return pp::panopainter::LegacyBrushPanelServices(*this).restore(); } void NodePanelBrush::clear() { - m_container->remove_all_children(); + pp::panopainter::LegacyBrushPanelServices(*this).clear(); } void NodePanelBrush::scan() { - auto icons = Asset::list_files("data/" + m_dir_name, ".*\\.png$"); - for (auto& i : icons) - { - std::string path = "data/" + m_dir_name + "/thumbs/" + i; - std::string path_hi = "data/" + m_dir_name + "/" + i; - NodeButtonBrush* brush = new NodeButtonBrush; - m_container->add_child(brush); - brush->init(); - brush->create(); - brush->loaded(); - brush->set_icon(path.c_str()); - brush->thumb_path = path; - brush->high_path = path_hi; - brush->brush_name = i; - brush->m_user_brush = false; // system brush, cannot be deleted from file - brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1); - } - - auto custom_icons = Asset::list_files(App::I->data_path + "/" + m_dir_name, ".*\\.png$"); - for (auto& i : custom_icons) - { - std::string path_thumb = App::I->data_path + "/" + m_dir_name + "/thumbs/" + i; - std::string path_high = App::I->data_path + "/" + m_dir_name + "/" + i; - NodeButtonBrush* brush = new NodeButtonBrush; - m_container->add_child(brush); - brush->init(); - brush->create(); - brush->loaded(); - brush->set_icon(path_thumb.c_str()); - brush->thumb_path = path_thumb; - brush->high_path = path_high; - brush->brush_name = i; - brush->m_user_brush = true; - brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1); - } + pp::panopainter::LegacyBrushPanelServices(*this).scan(); } void NodePanelBrush::reload() { - clear(); - scan(); - save(); + pp::panopainter::LegacyBrushPanelServices(*this).reload(); } void NodePanelBrush::added(Node* parent)