316 lines
12 KiB
C++
316 lines
12 KiB
C++
#include "pch.h"
|
|
|
|
#include "canvas_modes.h"
|
|
|
|
#include "app.h"
|
|
#include "canvas.h"
|
|
#include "legacy_canvas_mode_helpers.h"
|
|
#include "legacy_canvas_stroke_preview_services.h"
|
|
#include "legacy_ui_overlay_services.h"
|
|
#include "legacy_ui_gl_dispatch.h"
|
|
#include "renderer_gl/opengl_capabilities.h"
|
|
|
|
using pp::legacy_canvas_mode::apply_canvas_mode_capability;
|
|
using pp::legacy_canvas_mode::query_canvas_mode_capability;
|
|
using pp::legacy_canvas_mode::read_canvas_mode_pixel;
|
|
using pp::legacy_canvas_mode::set_canvas_mode_active_texture_unit;
|
|
|
|
void CanvasModePen::on_GestureEvent(GestureEvent* ge)
|
|
{
|
|
m_draw_tip = false;
|
|
}
|
|
|
|
void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|
{
|
|
m_draw_tip = App::I->draws_canvas_tip_for_input(me->m_source, me->m_type);
|
|
m_draw_outline = true;
|
|
|
|
if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch)
|
|
return;
|
|
|
|
me->m_pressure = App::I->adjust_canvas_input_pressure(me->m_pressure);
|
|
|
|
switch (me->m_type)
|
|
{
|
|
case kEventType::MouseDownL:
|
|
if (!App::I->keys[(int)kKey::KeySpacebar])
|
|
{
|
|
if (App::I->keys[(int)kKey::KeyAlt] || m_picking)
|
|
{
|
|
m_picking = true;
|
|
Canvas::I->pick_start();
|
|
glm::vec4 pix = Canvas::I->pick_get(loc);
|
|
Canvas::I->m_current_brush->m_tip_color = pix;
|
|
App::I->brush_update(true, false);
|
|
}
|
|
else
|
|
{
|
|
App::I->render_task_async([loc, pr = me->m_pressure]
|
|
{
|
|
Canvas::I->stroke_start({ loc, 0 }, pr);
|
|
});
|
|
m_drawing = true;
|
|
}
|
|
m_dragging = true;
|
|
node->mouse_capture();
|
|
}
|
|
break;
|
|
case kEventType::MouseUpL:
|
|
if (m_dragging && !m_picking)
|
|
{
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
App::I->render_task_async([] {
|
|
Canvas::I->stroke_end();
|
|
});
|
|
}
|
|
if (m_dragging && m_picking)
|
|
{
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
glm::vec4 pix = Canvas::I->pick_get(loc);
|
|
Canvas::I->m_current_brush->m_tip_color = pix;
|
|
App::I->brush_update(true, false);
|
|
Canvas::I->pick_end();
|
|
}
|
|
m_drawing = false;
|
|
m_dragging = false;
|
|
m_picking = false;
|
|
break;
|
|
case kEventType::MouseDownR:
|
|
if (App::I->keys[(int)kKey::KeyAlt])
|
|
{
|
|
m_resizing = true;
|
|
m_dragging = true;
|
|
m_size_pos_start = m_cur_pos;
|
|
auto curve = App::I->stroke->m_curves[App::I->stroke->m_tip_size];
|
|
m_size_value_start = curve.to_slider(Canvas::I->m_current_brush->m_tip_size);
|
|
node->mouse_capture();
|
|
}
|
|
break;
|
|
case kEventType::MouseUpR:
|
|
if (m_dragging && m_resizing)
|
|
{
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
m_dragging = false;
|
|
m_resizing = false;
|
|
}
|
|
break;
|
|
case kEventType::MouseMove:
|
|
if (m_dragging && !m_picking && !m_resizing)
|
|
{
|
|
App::I->render_task_async([loc, pr=me->m_pressure]
|
|
{
|
|
Canvas::I->stroke_update({ loc, 0 }, pr);
|
|
});
|
|
}
|
|
if (m_dragging && m_picking)
|
|
{
|
|
glm::vec4 pix = Canvas::I->pick_get(loc);
|
|
Canvas::I->m_current_brush->m_tip_color = pix;
|
|
App::I->brush_update(true, false);
|
|
}
|
|
if (m_dragging && m_resizing)
|
|
{
|
|
auto diff = m_cur_pos - m_size_pos_start;
|
|
auto curve = App::I->stroke->m_curves[App::I->stroke->m_tip_size];
|
|
Canvas::I->m_current_brush->m_tip_size = glm::max(curve.to_value(m_size_value_start + diff.x * 0.001f), 0.001f);
|
|
App::I->brush_update(true, true);
|
|
}
|
|
m_cur_pos = loc;
|
|
break;
|
|
case kEventType::MouseCancel:
|
|
if (m_dragging)
|
|
{
|
|
App::I->render_task_async([] {
|
|
Canvas::I->stroke_cancel();
|
|
});
|
|
m_dragging = false;
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
}
|
|
if (m_picking)
|
|
m_picking = false;
|
|
if (m_resizing)
|
|
m_resizing = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
|
{
|
|
if (m_draw_tip)
|
|
{
|
|
const auto& brush = Canvas::I->m_current_brush;
|
|
auto pos = m_resizing ? m_size_pos_start : m_cur_pos;
|
|
//if (App::I->keys[(int)kKey::KeyAlt] && !m_resizing)
|
|
// pos.x = pos.x - brush->m_tip_size * .5f;
|
|
float tip_scale_fix = 1.f / glm::tan(glm::radians(Canvas::I->m_cam_fov * 0.5f));
|
|
float tip_angle = brush->m_tip_angle * (float)(M_PI * 2.0);
|
|
glm::vec2 tip_scale = App::I->zoom * brush->m_tip_scale *
|
|
glm::vec2(brush->m_tip_size * tip_scale_fix) *
|
|
glm::vec2(brush->m_tip_flipx ? -1 : 1, brush->m_tip_flipy ? -1.f : 1.f) *
|
|
glm::vec2((brush->m_tip_aspect <= 0.5 ? brush->m_tip_aspect * 2.f : 1.f),
|
|
(brush->m_tip_aspect > 0.5 ? 1.f - (brush->m_tip_aspect - .5f) * 2.f : 1.f));
|
|
glm::vec2 tip_offset = glm::vec2(0);
|
|
auto tip_color = glm::vec4(glm::vec3(brush->m_tip_color), 1.f);
|
|
if (Canvas::I->m_current_stroke)
|
|
{
|
|
const auto& s = Canvas::I->m_current_stroke->m_prev_sample;
|
|
if (s.size > 0.f)
|
|
{
|
|
tip_scale = App::I->zoom * (brush->m_tip_size * tip_scale_fix) * s.scale;
|
|
tip_angle = s.angle;
|
|
tip_offset = s.pos - s.origin;
|
|
tip_color = glm::vec4(s.col, s.flow);
|
|
}
|
|
}
|
|
glm::u8vec4 pixel;
|
|
std::int32_t fb_width = static_cast<std::int32_t>(App::I->width);
|
|
std::int32_t fb_height = static_cast<std::int32_t>(App::I->height);
|
|
if (node->m_density != 1.f)
|
|
{
|
|
fb_width = node->m_rtt.getWidth();
|
|
fb_height = node->m_rtt.getHeight();
|
|
}
|
|
read_canvas_mode_pixel(
|
|
static_cast<std::int32_t>((pos.x / App::I->width) * fb_width),
|
|
static_cast<std::int32_t>(((App::I->height - pos.y - 1) / App::I->height) * fb_height),
|
|
pixel);
|
|
bool outline = glm::min(tip_scale.x, tip_scale.y) < 20 || m_resizing ? false : m_draw_outline;
|
|
pp::panopainter::setup_legacy_vr_stroke_preview_shader({
|
|
.texture_slot = 0,
|
|
.alpha = brush->m_tip_flow * brush->m_tip_opacity,
|
|
.draw_outline = outline,
|
|
.color = outline ? glm::vec4(1.f - glm::vec3(pixel) / 255.f, 1.f) : tip_color,
|
|
.mvp = glm::scale(glm::vec3(1, -1, 1)) *
|
|
ortho *
|
|
glm::translate(glm::vec3(pos + tip_offset, 0)) *
|
|
glm::eulerAngleZ(tip_angle) *
|
|
glm::scale(glm::vec3(tip_scale, 1)),
|
|
});
|
|
const bool blend = query_canvas_mode_capability(pp::renderer::gl::blend_state());
|
|
apply_canvas_mode_capability(pp::renderer::gl::blend_state(), true);
|
|
set_canvas_mode_active_texture_unit(0);
|
|
auto& tex = *brush->m_tip_texture;
|
|
tex.bind();
|
|
Canvas::I->m_sampler_brush.bind(0);
|
|
Canvas::I->m_plane.draw_fill();
|
|
tex.unbind();
|
|
if (!blend) apply_canvas_mode_capability(pp::renderer::gl::blend_state(), false);
|
|
}
|
|
}
|
|
|
|
void CanvasModePen::leave(kCanvasMode next)
|
|
{
|
|
}
|
|
|
|
void CanvasModePen::enter(kCanvasMode prev)
|
|
{
|
|
m_cur_pos = Canvas::I->m_cur_pos;
|
|
}
|
|
|
|
void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|
{
|
|
m_draw_tip = App::I->draws_canvas_tip_for_input(me->m_source, me->m_type);
|
|
if (Canvas::I->m_touch_lock && me->m_source == kEventSource::Touch)
|
|
return;
|
|
switch (me->m_type)
|
|
{
|
|
case kEventType::MouseDownL:
|
|
node->mouse_capture();
|
|
m_dragging = true;
|
|
m_drag_start = loc;
|
|
m_drag_pos = loc;
|
|
break;
|
|
case kEventType::MouseUpL:
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
if (m_dragging)
|
|
{
|
|
App::I->render_task_async([=]
|
|
{
|
|
Canvas::I->stroke_start({ m_drag_start, 0 }, 1.f);
|
|
Canvas::I->stroke_update({ m_drag_pos, 0 }, 1.f);
|
|
Canvas::I->stroke_draw();
|
|
Canvas::I->stroke_end();
|
|
});
|
|
}
|
|
m_dragging = false;
|
|
break;
|
|
case kEventType::MouseMove:
|
|
if (m_dragging)
|
|
m_drag_pos = loc;
|
|
m_cur_pos = loc;
|
|
break;
|
|
case kEventType::MouseCancel:
|
|
pp::panopainter::release_legacy_mouse_capture(*node);
|
|
m_dragging = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
|
{
|
|
if (m_dragging)
|
|
{
|
|
pp::panopainter::setup_legacy_vr_color_shader({
|
|
.color = Canvas::I->m_current_brush->m_tip_color,
|
|
.mvp = ortho,
|
|
});
|
|
static glm::vec4 AB[2];
|
|
AB[0] = { m_drag_start, 0, 1 };
|
|
AB[1] = { m_drag_pos, 0, 1 };
|
|
AB[0].y = Canvas::I->m_box.w - AB[0].y - 1; // invert Y
|
|
AB[1].y = Canvas::I->m_box.w - AB[1].y - 1; // invert Y
|
|
m_line.update_vertices(AB);
|
|
m_line.draw_stroke();
|
|
}
|
|
else if (m_draw_tip)
|
|
{
|
|
const auto& brush = Canvas::I->m_current_brush;
|
|
float tip_scale_fix = 1.f / glm::tan(glm::radians(Canvas::I->m_cam_fov * 0.5f));
|
|
float tip_angle = brush->m_tip_angle * (float)(M_PI * 2.0);
|
|
glm::vec2 tip_scale = App::I->zoom * brush->m_tip_scale *
|
|
glm::vec2(brush->m_tip_size * tip_scale_fix) *
|
|
glm::vec2(brush->m_tip_flipx ? -1 : 1, brush->m_tip_flipy ? -1.f : 1.f) *
|
|
glm::vec2((brush->m_tip_aspect <= 0.5 ? brush->m_tip_aspect * 2.f : 1.f),
|
|
(brush->m_tip_aspect > 0.5 ? 1.f - (brush->m_tip_aspect - .5f) * 2.f : 1.f));
|
|
auto tip_color = glm::vec4(glm::vec3(brush->m_tip_color), 1.f);
|
|
pp::panopainter::setup_legacy_vr_stroke_preview_shader({
|
|
.texture_slot = 0,
|
|
.alpha = brush->m_tip_flow * brush->m_tip_opacity,
|
|
.draw_outline = false,
|
|
.color = tip_color,
|
|
.mvp = glm::scale(glm::vec3(1, -1, 1)) *
|
|
ortho *
|
|
glm::translate(glm::vec3(m_cur_pos, 0)) *
|
|
glm::eulerAngleZ(tip_angle) *
|
|
glm::scale(glm::vec3(tip_scale, 1)),
|
|
});
|
|
const bool blend = query_canvas_mode_capability(pp::renderer::gl::blend_state());
|
|
apply_canvas_mode_capability(pp::renderer::gl::blend_state(), true);
|
|
set_canvas_mode_active_texture_unit(0);
|
|
auto& tex = *brush->m_tip_texture;
|
|
tex.bind();
|
|
Canvas::I->m_sampler_brush.bind(0);
|
|
Canvas::I->m_plane.draw_fill();
|
|
tex.unbind();
|
|
if (!blend) apply_canvas_mode_capability(pp::renderer::gl::blend_state(), false);
|
|
}
|
|
}
|
|
|
|
void CanvasModeLine::init()
|
|
{
|
|
m_line.create();
|
|
}
|
|
|
|
void CanvasModeLine::enter(kCanvasMode prev)
|
|
{
|
|
m_cur_pos = Canvas::I->m_cur_pos;
|
|
}
|
|
|
|
void CanvasModeLine::leave(kCanvasMode next)
|
|
{
|
|
}
|