#include "pch.h" #include "legacy_node_canvas_state_services.h" #include "app.h" #include "app_core/canvas_tool_ui.h" #include "app_core/canvas_view.h" #include "log.h" #include "renderer_gl/opengl_capabilities.h" namespace pp::panopainter { namespace { pp::app::CanvasToolMode canvas_tool_mode(kCanvasMode mode) noexcept { switch (mode) { case kCanvasMode::Draw: return pp::app::CanvasToolMode::draw; case kCanvasMode::Erase: return pp::app::CanvasToolMode::erase; case kCanvasMode::Line: return pp::app::CanvasToolMode::line; case kCanvasMode::Camera: return pp::app::CanvasToolMode::camera; case kCanvasMode::Grid: return pp::app::CanvasToolMode::grid; case kCanvasMode::Copy: return pp::app::CanvasToolMode::copy; case kCanvasMode::Cut: return pp::app::CanvasToolMode::cut; case kCanvasMode::Fill: return pp::app::CanvasToolMode::fill; case kCanvasMode::MaskFree: return pp::app::CanvasToolMode::mask_free; case kCanvasMode::MaskLine: return pp::app::CanvasToolMode::mask_line; case kCanvasMode::FloodFill: return pp::app::CanvasToolMode::flood_fill; case kCanvasMode::COUNT: break; } return pp::app::CanvasToolMode::draw; } pp::app::CanvasCursorVisibilityMode canvas_cursor_visibility_mode(NodeCanvas::kCursorVisibility mode) noexcept { switch (mode) { case NodeCanvas::kCursorVisibility::Never: return pp::app::CanvasCursorVisibilityMode::never; case NodeCanvas::kCursorVisibility::SmallBrush: return pp::app::CanvasCursorVisibilityMode::small_brush; case NodeCanvas::kCursorVisibility::NotPainting: return pp::app::CanvasCursorVisibilityMode::not_painting; case NodeCanvas::kCursorVisibility::Always: return pp::app::CanvasCursorVisibilityMode::always; } return pp::app::CanvasCursorVisibilityMode::never; } } // namespace void restore_legacy_node_canvas_context(NodeCanvas& node_canvas) { static_cast(node_canvas).restore_context(); const int canvas_resolution = App::I->default_canvas_resolution(); node_canvas.m_canvas->create(canvas_resolution, canvas_resolution); node_canvas.m_sampler.create(); node_canvas.m_sampler.set_filter( pp::renderer::gl::linear_texture_filter(), pp::renderer::gl::nearest_texture_filter()); node_canvas.m_face_plane.create<1>(2, 2); node_canvas.m_canvas->snapshot_restore(); CanvasMode::node = &node_canvas; for (int i = 0; i < (int)kCanvasMode::COUNT; i++) for (auto m : Canvas::modes[i]) m->init(); } void clear_legacy_node_canvas_context(NodeCanvas& node_canvas) { static_cast(node_canvas).clear_context(); node_canvas.m_canvas->snapshot_save(); node_canvas.m_canvas->clear_context(); // TODO: clear CanvasMode objects } void handle_legacy_node_canvas_resize(NodeCanvas& node_canvas, glm::vec2 old_size, glm::vec2 new_size, float zoom) { (void)old_size; (void)zoom; if (new_size.x != node_canvas.m_canvas->m_width || new_size.y != node_canvas.m_canvas->m_height) { new_size = new_size * node_canvas.m_density; create_legacy_node_canvas_buffers(node_canvas); } } void reset_legacy_node_canvas_camera(NodeCanvas& node_canvas) { const auto state = pp::app::plan_canvas_camera_reset(); node_canvas.m_canvas->m_cam_rot = glm::mat4( state.rotation[0], state.rotation[1], state.rotation[2], state.rotation[3], state.rotation[4], state.rotation[5], state.rotation[6], state.rotation[7], state.rotation[8], state.rotation[9], state.rotation[10], state.rotation[11], state.rotation[12], state.rotation[13], state.rotation[14], state.rotation[15]); node_canvas.m_canvas->m_cam_pos = { state.position[0], state.position[1], state.position[2], }; node_canvas.m_canvas->m_cam_fov = state.field_of_view_degrees; node_canvas.m_canvas->m_pan = { state.pan[0], state.pan[1], }; } void create_legacy_node_canvas_buffers(NodeCanvas& node_canvas) { auto new_size = node_canvas.GetSize() * node_canvas.m_density; LOG("NodeCanvas::create_buffers size: %d x %d density %f", (int)new_size.x, (int)new_size.y, node_canvas.m_density); node_canvas.m_canvas->m_mixer.create((int)new_size.x * node_canvas.m_canvas->m_mixer_scale, (int)new_size.y * node_canvas.m_canvas->m_mixer_scale, -1, pp::renderer::gl::rgba8_internal_format()); node_canvas.m_blender_rtt.create((int)new_size.x, (int)new_size.y, -1, pp::renderer::gl::rgba8_internal_format()); node_canvas.m_cache_rtt.create((int)new_size.x, (int)new_size.y, -1, pp::renderer::gl::rgba8_internal_format()); node_canvas.m_rtt.create((int)new_size.x, (int)new_size.y, -1, pp::renderer::gl::rgba8_internal_format(), true); node_canvas.m_blender_bg.create((int)new_size.x, (int)new_size.y, pp::renderer::gl::rgba8_internal_format()); } void set_legacy_node_canvas_density(NodeCanvas& node_canvas, float density) { node_canvas.m_density = density; create_legacy_node_canvas_buffers(node_canvas); } void set_legacy_node_canvas_cursor_visibility(NodeCanvas& node_canvas, NodeCanvas::kCursorVisibility mode) { node_canvas.m_cursor_visibility = mode; } void update_legacy_node_canvas_cursor(NodeCanvas& node_canvas) { auto* pen_mode = node_canvas.m_canvas->get_mode(); const auto plan = pp::app::plan_canvas_cursor_visibility(pp::app::CanvasCursorVisibilityInput { .mode = canvas_tool_mode(node_canvas.m_canvas->m_current_mode), .visibility_mode = canvas_cursor_visibility_mode(node_canvas.m_cursor_visibility), .has_current_brush = node_canvas.m_canvas->m_current_brush != nullptr, .brush_tip_size = node_canvas.m_canvas->m_current_brush ? node_canvas.m_canvas->m_current_brush->m_tip_size : 0.0F, .pen_is_drawing = pen_mode && pen_mode->m_drawing, .alt_down = App::I && App::I->keys[(int)kKey::KeyAlt], .pen_is_resizing = pen_mode && pen_mode->m_resizing, .pen_is_picking = pen_mode && pen_mode->m_picking, }); if (!plan) { LOG("Canvas cursor visibility planning failed: %s", plan.status().message); App::I->show_cursor(); return; } plan.value().visible ? App::I->show_cursor() : App::I->hide_cursor(); } void tick_legacy_node_canvas_state(NodeCanvas& node_canvas, float dt) { node_canvas.m_outline_pan = glm::fract(node_canvas.m_outline_pan + dt * 0.01f); } void destroy_legacy_node_canvas_state(NodeCanvas& node_canvas) { node_canvas.m_blender_rtt.destroy(); node_canvas.m_cache_rtt.destroy(); node_canvas.m_rtt.destroy(); node_canvas.m_blender_bg.destroy(); node_canvas.m_face_plane.destroy(); node_canvas.m_line.destroy(); node_canvas.m_grid.destroy(); static_cast(node_canvas).destroy(); } } // namespace pp::panopainter