add wet parameter, fix selection mask modes
This commit is contained in:
@@ -153,6 +153,7 @@
|
||||
<node height="20" justify="center"><text text="Angle" font-face="arial" font-size="11"/></node>
|
||||
<node height="20" justify="center"><text text="Mixer" font-face="arial" font-size="11"/></node>
|
||||
<node height="20" justify="center"><text text="Stencil" font-face="arial" font-size="11"/></node>
|
||||
<node height="20" justify="center"><text text="Wet" font-face="arial" font-size="11"/></node>
|
||||
</node>
|
||||
<border dir="col" align="center" grow="1" width="1">
|
||||
<node height="20" pad="1" width="100%" dir="row">
|
||||
@@ -177,6 +178,7 @@
|
||||
</node>
|
||||
<node height="20" pad="1" width="100%"><slider-h id="tip-mix"/></node>
|
||||
<node height="20" pad="1" width="100%"><slider-h id="tip-stencil"/></node>
|
||||
<node height="20" pad="1" width="100%"><slider-h id="tip-wet"/></node>
|
||||
</border>
|
||||
</node>
|
||||
|
||||
@@ -272,7 +274,7 @@
|
||||
</border>
|
||||
<border width="400" color="0 0 0 .9" pad="10" dir="col">
|
||||
<node dir="row">
|
||||
<scroll id="files-list" dir="col" flood-events="1" grow="1" height="150" margin="0 10 0 0" pad="0 20 0 0" color=".2 .2 .2 1"/>
|
||||
<scroll id="files-list" dir="col" flood-events="1" grow="1" height="250" margin="0 10 0 0" pad="0 20 0 0" color=".2 .2 .2 1"/>
|
||||
<!--
|
||||
<node dir="col" grow="1" margin="0 0 0 10">
|
||||
<border height="20" align="center" justify="center" color=".2 .2 .2 1"><text id="info-title" text="Title" font-face="arial" font-size="11"/></border>
|
||||
|
||||
@@ -323,7 +323,7 @@ void App::init_toolbar_draw()
|
||||
{
|
||||
button->on_click = [this, button](Node*) {
|
||||
select_button(layout[main_id], button);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::Fill);
|
||||
Canvas::set_mode(Canvas::kCanvasMode::MaskLine);
|
||||
};
|
||||
}
|
||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-bucket"))
|
||||
|
||||
@@ -249,6 +249,7 @@ void App::initShaders()
|
||||
"uniform mediump float alpha;\n"
|
||||
"uniform mediump vec2 stencil_offset;\n"
|
||||
"uniform mediump float stencil_alpha;\n"
|
||||
"uniform mediump float wet;\n"
|
||||
"in mediump vec2 uv;\n"
|
||||
"in mediump float q;\n"
|
||||
#ifdef __IOS__
|
||||
@@ -270,7 +271,9 @@ void App::initShaders()
|
||||
" mediump float contribution = max((1.0 - bg.a) * fg.a, 1.0/255.0) * stencil;\n"
|
||||
" mediump float alpha_tot = bg.a + contribution;"
|
||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||
" frag = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\n"
|
||||
" mediump vec4 frag_wet = vec4(rgb, mix(bg.a, max(bg.a, fg.a * stencil), fg.a));\n"
|
||||
" mediump vec4 frag_dry = vec4(rgb, clamp(alpha_tot, 0.0, 1.0));\n"
|
||||
" frag = mix(frag_dry, frag_wet, wet);\n"
|
||||
"}\n";
|
||||
|
||||
static const char* shader_checkerboard_v =
|
||||
|
||||
@@ -17,6 +17,7 @@ public:
|
||||
float m_tip_opacity = 0;
|
||||
float m_tip_angle = 0;
|
||||
float m_tip_stencil = 0;
|
||||
float m_tip_wet = 0;
|
||||
bool m_tip_angle_follow = false;
|
||||
bool m_tip_flow_pressure = false;
|
||||
bool m_tip_size_pressure = false;
|
||||
|
||||
@@ -20,7 +20,7 @@ std::vector<CanvasMode*> ui::Canvas::modes[] = {
|
||||
{ new CanvasModeGrid, new CanvasModeBasicCamera },
|
||||
{ new CanvasModeFill, new CanvasModeBasicCamera },
|
||||
{ new CanvasModeMaskFree, new CanvasModeBasicCamera },
|
||||
{ new CanvasModeMaskFree, new CanvasModeBasicCamera },
|
||||
{ new CanvasModeMaskLine, new CanvasModeBasicCamera },
|
||||
};
|
||||
glm::vec3 ui::Canvas::m_plane_origin[6] = {
|
||||
{ 0, 0,-1}, // front
|
||||
@@ -246,6 +246,7 @@ void ui::Canvas::stroke_draw()
|
||||
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
||||
//ShaderManager::u_vec2(kShaderUniform::StencilOffset, glm::vec2((rand()%1000)*0.001f, (rand()%1000)*0.001f));
|
||||
ShaderManager::u_float(kShaderUniform::StencilAlpha, m_brush.m_tip_stencil);
|
||||
ShaderManager::u_float(kShaderUniform::Wet, m_brush.m_tip_wet);
|
||||
for (const auto& s : samples)
|
||||
{
|
||||
glm::vec2 dx(s.size * 0.5f, 0), dy(0, s.size * 0.5f);
|
||||
@@ -1458,6 +1459,140 @@ void ui::Canvas::draw_objects(std::function<void(const glm::mat4& camera, const
|
||||
draw_objects(observer, m_layers[m_current_layer_idx]);
|
||||
}
|
||||
|
||||
void ui::Canvas::project2Dpoints(std::vector<ui::Shape::vertex_t>& vertices)
|
||||
{
|
||||
for (auto& p : vertices)
|
||||
{
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 hit_fb;
|
||||
int plane_id;
|
||||
if (point_trace(p.pos, ro, rd, hit_o, hit_fb, hit_d, plane_id))
|
||||
p.pos = glm::vec4(hit_o, 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ui::Shape::vertex_t> ui::Canvas::triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points)
|
||||
{
|
||||
struct Segment
|
||||
{
|
||||
std::shared_ptr<p2t::Point> a = nullptr;
|
||||
std::shared_ptr<p2t::Point> b = nullptr;
|
||||
Segment* prev = nullptr;
|
||||
std::shared_ptr<Segment> next = nullptr;
|
||||
bool end = false;
|
||||
};
|
||||
|
||||
std::shared_ptr<Segment> root = std::make_shared<Segment>();
|
||||
std::shared_ptr<Segment> node = root;
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
node->a = points[i];
|
||||
if (i == points.size() - 1)
|
||||
{
|
||||
node->b = points[0];
|
||||
node->next = root;
|
||||
node->end = true;
|
||||
root->prev = node.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
node->b = points[i + 1];
|
||||
node->next = std::make_shared<Segment>();
|
||||
node->next->prev = node.get();
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
node = root;
|
||||
std::stack<std::shared_ptr<Segment>> todo;
|
||||
std::vector<std::shared_ptr<Segment>> polys;
|
||||
todo.push(root);
|
||||
while (!todo.empty())
|
||||
{
|
||||
node = todo.top();
|
||||
todo.pop();
|
||||
polys.push_back(node);
|
||||
while (node)
|
||||
{
|
||||
std::shared_ptr<Segment> other = node->next;
|
||||
while (other)
|
||||
{
|
||||
if (*node->a == *other->a || *node->a == *other->b ||
|
||||
*node->b == *other->a || *node->b == *other->b)
|
||||
{
|
||||
other = other->end ? nullptr : other->next;
|
||||
continue;
|
||||
}
|
||||
glm::vec2 s0a(node->a->x, node->a->y);
|
||||
glm::vec2 s0b(node->b->x, node->b->y);
|
||||
glm::vec2 s1a(other->a->x, other->a->y);
|
||||
glm::vec2 s1b(other->b->x, other->b->y);
|
||||
glm::vec2 is;
|
||||
if (segments_intersect(s0a, s0b, s1a, s1b, is))
|
||||
{
|
||||
auto p = std::make_shared<p2t::Point>(is.x, is.y);
|
||||
auto poly_root = std::make_shared<Segment>();
|
||||
poly_root->a = p;
|
||||
poly_root->b = node->b;
|
||||
poly_root->next = node->next;
|
||||
todo.push(poly_root);
|
||||
other->a = p;
|
||||
node->b = p;
|
||||
auto poly_end = std::make_shared<Segment>();
|
||||
poly_end->a = other->prev->b;
|
||||
poly_end->b = p;
|
||||
poly_end->end = true;
|
||||
poly_end->prev = other->prev;
|
||||
other->prev->next = poly_end;
|
||||
other->prev = node.get();
|
||||
node->next = other;
|
||||
break;
|
||||
}
|
||||
other = other->end ? nullptr : other->next;
|
||||
}
|
||||
node = node->end ? nullptr : node->next;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ui::Shape::vertex_t> vertices;
|
||||
for (auto poly : polys)
|
||||
{
|
||||
std::vector<p2t::Point*> outline;
|
||||
node = poly;
|
||||
while (node)
|
||||
{
|
||||
outline.push_back(new p2t::Point(*node->a));
|
||||
auto current = node;
|
||||
node = node->end ? nullptr : node->next;
|
||||
current->next = nullptr;
|
||||
}
|
||||
LOG("poly %ld", outline.size());
|
||||
|
||||
if (outline.size() > 2)
|
||||
{
|
||||
p2t::CDT* cdt = new p2t::CDT(outline);
|
||||
cdt->Triangulate();
|
||||
auto tr = cdt->GetTriangles();
|
||||
for (auto t : tr)
|
||||
{
|
||||
ui::Shape::vertex_t vertex;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto p = t->GetPoint(i);
|
||||
vertex.pos = glm::vec4(p->x, p->y, 0, 1);
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
|
||||
delete cdt;
|
||||
}
|
||||
for (auto p : outline)
|
||||
delete p;
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ui::Layer::destroy()
|
||||
|
||||
@@ -148,6 +148,8 @@ public:
|
||||
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id);
|
||||
bool 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);
|
||||
std::vector<ui::Shape::vertex_t> triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points);
|
||||
void project2Dpoints(std::vector<ui::Shape::vertex_t>& vertices);
|
||||
};
|
||||
|
||||
class ActionStroke : public Action
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "shader.h"
|
||||
#include "node_canvas.h"
|
||||
#include "app.h"
|
||||
#include "util.h"
|
||||
|
||||
NodeCanvas* CanvasMode::node;
|
||||
ui::Canvas* CanvasMode::canvas;
|
||||
@@ -378,145 +379,6 @@ void CanvasModeMaskFree::leave()
|
||||
// m_points.clear();
|
||||
}
|
||||
|
||||
int SegmentCount = 0;
|
||||
std::vector<ui::Shape::vertex_t> CanvasModeMaskFree::triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points)
|
||||
{
|
||||
struct Segment
|
||||
{
|
||||
std::shared_ptr<p2t::Point> a = nullptr;
|
||||
std::shared_ptr<p2t::Point> b = nullptr;
|
||||
Segment* prev = nullptr;
|
||||
std::shared_ptr<Segment> next = nullptr;
|
||||
bool end = false;
|
||||
Segment()
|
||||
{
|
||||
SegmentCount++;
|
||||
}
|
||||
~Segment()
|
||||
{
|
||||
SegmentCount--;
|
||||
}
|
||||
};
|
||||
|
||||
std::shared_ptr<Segment> root = std::make_shared<Segment>();
|
||||
std::shared_ptr<Segment> node = root;
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
node->a = points[i];
|
||||
if (i == points.size() - 1)
|
||||
{
|
||||
node->b = points[0];
|
||||
node->next = root;
|
||||
node->end = true;
|
||||
root->prev = node.get();
|
||||
}
|
||||
else
|
||||
{
|
||||
node->b = points[i + 1];
|
||||
node->next = std::make_shared<Segment>();
|
||||
node->next->prev = node.get();
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
node = root;
|
||||
std::stack<std::shared_ptr<Segment>> todo;
|
||||
std::vector<std::shared_ptr<Segment>> polys;
|
||||
todo.push(root);
|
||||
while (!todo.empty())
|
||||
{
|
||||
node = todo.top();
|
||||
todo.pop();
|
||||
polys.push_back(node);
|
||||
while (node)
|
||||
{
|
||||
std::shared_ptr<Segment> other = node->next;
|
||||
while (other)
|
||||
{
|
||||
if (*node->a == *other->a || *node->a == *other->b ||
|
||||
*node->b == *other->a || *node->b == *other->b)
|
||||
{
|
||||
other = other->end ? nullptr : other->next;
|
||||
continue;
|
||||
}
|
||||
glm::vec2 s0a(node->a->x, node->a->y);
|
||||
glm::vec2 s0b(node->b->x, node->b->y);
|
||||
glm::vec2 s1a(other->a->x, other->a->y);
|
||||
glm::vec2 s1b(other->b->x, other->b->y);
|
||||
glm::vec2 is;
|
||||
if (segments_intersect(s0a, s0b, s1a, s1b, is))
|
||||
{
|
||||
auto p = std::make_shared<p2t::Point>(is.x, is.y);
|
||||
auto poly_root = std::make_shared<Segment>();
|
||||
poly_root->a = p;
|
||||
poly_root->b = node->b;
|
||||
poly_root->next = node->next;
|
||||
todo.push(poly_root);
|
||||
other->a = p;
|
||||
node->b = p;
|
||||
auto poly_end = std::make_shared<Segment>();
|
||||
poly_end->a = other->prev->b;
|
||||
poly_end->b = p;
|
||||
poly_end->end = true;
|
||||
poly_end->prev = other->prev;
|
||||
other->prev->next = poly_end;
|
||||
other->prev = node.get();
|
||||
node->next = other;
|
||||
break;
|
||||
}
|
||||
other = other->end ? nullptr : other->next;
|
||||
}
|
||||
node = node->end ? nullptr : node->next;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<ui::Shape::vertex_t> vertices;
|
||||
for (auto poly : polys)
|
||||
{
|
||||
std::vector<p2t::Point*> outline;
|
||||
node = poly;
|
||||
while (node)
|
||||
{
|
||||
outline.push_back(new p2t::Point(*node->a));
|
||||
auto current = node;
|
||||
node = node->end ? nullptr : node->next;
|
||||
current->next = nullptr;
|
||||
}
|
||||
LOG("poly %ld", outline.size());
|
||||
|
||||
if (outline.size() > 2)
|
||||
{
|
||||
p2t::CDT* cdt = new p2t::CDT(outline);
|
||||
cdt->Triangulate();
|
||||
auto tr = cdt->GetTriangles();
|
||||
for (auto t : tr)
|
||||
{
|
||||
ui::Shape::vertex_t vertex;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto p = t->GetPoint(i);
|
||||
|
||||
glm::vec3 ro, rd, hit_o, hit_d;
|
||||
glm::vec2 hit_fb;
|
||||
int plane_id;
|
||||
if (canvas->point_trace({p->x, p->y}, ro, rd, hit_o, hit_fb, hit_d, plane_id))
|
||||
{
|
||||
m_dirty_planes[plane_id]++;
|
||||
vertex.pos = glm::vec4(hit_o, 1);
|
||||
vertices.push_back(vertex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
delete cdt;
|
||||
}
|
||||
for (auto p : outline)
|
||||
delete p;
|
||||
}
|
||||
|
||||
return vertices;
|
||||
}
|
||||
|
||||
void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
{
|
||||
static glm::vec2 oldpos;
|
||||
@@ -551,8 +413,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
std::vector<std::shared_ptr<p2t::Point>> points;
|
||||
for (int i = 0; i < (int)m_points2d.size() - 1; i++)
|
||||
points.emplace_back(std::make_shared<p2t::Point>(m_points2d[i].x, m_points2d[i].y));
|
||||
auto v = triangulate(points);
|
||||
LOG("leaked segments: %d", SegmentCount);
|
||||
auto v = canvas->triangulate(points);
|
||||
canvas->project2Dpoints(v);
|
||||
LOG("%d points", (int)v.size());
|
||||
|
||||
m_shape.update_vertices(v.data(), (int)v.size());
|
||||
@@ -567,7 +429,14 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
m_shape.draw_fill();
|
||||
};
|
||||
canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask);
|
||||
m_points.clear();
|
||||
|
||||
//m_points.clear();
|
||||
// close the path
|
||||
m_points.push_back(m_points[m_points.size() - 2]);
|
||||
m_points.push_back(m_points.front());
|
||||
canvas->project2Dpoints(m_points);
|
||||
// reset m_shape to contour rendering
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -593,7 +462,7 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
oldvec = v;
|
||||
if (acc > 0.001) // angle change tollerance
|
||||
{
|
||||
LOG("d=%f acc=%f", d, acc);
|
||||
//LOG("d=%f acc=%f", d, acc);
|
||||
acc = 0;
|
||||
|
||||
m_points2d.push_back(loc);
|
||||
@@ -630,14 +499,157 @@ void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
|
||||
{
|
||||
if (!m_points.empty())
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
|
||||
if (m_dragging)
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
//m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
|
||||
m_shape.draw_stroke();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
m_shape.draw_stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CanvasModeMaskLine::init()
|
||||
{
|
||||
m_shape.create();
|
||||
}
|
||||
|
||||
void CanvasModeMaskLine::leave()
|
||||
{
|
||||
if (m_points2d.size() > 3)
|
||||
{
|
||||
std::vector<std::shared_ptr<p2t::Point>> points;
|
||||
for (int i = 0; i < (int)m_points2d.size(); i++)
|
||||
points.emplace_back(std::make_shared<p2t::Point>(m_points2d[i].x, m_points2d[i].y));
|
||||
auto v = canvas->triangulate(points);
|
||||
canvas->project2Dpoints(v);
|
||||
LOG("%d points", (int)v.size());
|
||||
|
||||
m_shape.update_vertices(v.data(), (int)v.size());
|
||||
|
||||
if (!m_points.empty())
|
||||
{
|
||||
auto drawer = [this](const glm::mat4& camera, const glm::mat4& proj) {
|
||||
//glEnable(GL_BLEND);
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, {1, 1, 1, 1});
|
||||
m_shape.draw_fill();
|
||||
};
|
||||
canvas->draw_objects(std::bind(drawer, std::placeholders::_1, std::placeholders::_2), canvas->m_smask);
|
||||
|
||||
//m_points.clear();
|
||||
// close the path
|
||||
m_points.push_back(m_points.back());
|
||||
m_points.push_back(m_points.back());
|
||||
m_points.push_back(m_points.front());
|
||||
canvas->project2Dpoints(m_points);
|
||||
// reset m_shape to contour rendering
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas->m_smask_active = false;
|
||||
}
|
||||
m_active_tool = false;
|
||||
}
|
||||
|
||||
void CanvasModeMaskLine::enter()
|
||||
{
|
||||
m_points2d.clear();
|
||||
m_points.clear();
|
||||
canvas->m_smask.clear({0, 0, 0, 0});
|
||||
canvas->m_smask_active = true;
|
||||
m_active_tool = true;
|
||||
}
|
||||
|
||||
void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
{
|
||||
switch (me->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
{
|
||||
node->mouse_capture();
|
||||
m_dragging = true;
|
||||
m_points2d.push_back(loc);
|
||||
ui::Shape::vertex_t vert;
|
||||
vert.pos = glm::vec4(loc, 0, 1);
|
||||
m_points.push_back(vert);
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
break;
|
||||
}
|
||||
case kEventType::MouseUpL:
|
||||
node->mouse_release();
|
||||
m_dragging = false;
|
||||
if (m_points.size() > 1)
|
||||
{
|
||||
m_points.push_back(m_points.back());
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
break;
|
||||
case kEventType::MouseMove:
|
||||
{
|
||||
if (m_dragging)
|
||||
{
|
||||
m_points.back().pos = glm::vec4(loc, 0, 1);
|
||||
m_points2d.back() = loc;
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kEventType::MouseCancel:
|
||||
if (m_dragging)
|
||||
{
|
||||
m_points.pop_back();
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
m_dragging = false;
|
||||
node->mouse_release();
|
||||
if (m_points.size() < 4)
|
||||
{
|
||||
m_points.clear();
|
||||
m_shape.update_vertices(m_points.data(), (int)m_points.size());
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CanvasModeMaskLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
|
||||
{
|
||||
if (!m_points.empty())
|
||||
{
|
||||
if (m_active_tool)
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, glm::scale(glm::vec3(1,-1,1)) * ortho);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
//m_dragging ? m_shape.draw_stroke() : m_shape.draw_fill();
|
||||
m_shape.draw_stroke();
|
||||
}
|
||||
else
|
||||
{
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
m_shape.draw_stroke();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CanvasModeFill::init()
|
||||
@@ -743,6 +755,6 @@ void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, cons
|
||||
ui::ShaderManager::use(ui::kShader::Color);
|
||||
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera);
|
||||
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, .25 });
|
||||
m_shape.draw_fill();
|
||||
m_dragging ? m_shape.draw_fill() : m_shape.draw_stroke();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -116,5 +116,20 @@ public:
|
||||
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
|
||||
virtual void init() override;
|
||||
virtual void leave() override;
|
||||
std::vector<ui::Shape::vertex_t> triangulate(const std::vector<std::shared_ptr<p2t::Point>>& points);
|
||||
};
|
||||
|
||||
class CanvasModeMaskLine : public CanvasMode
|
||||
{
|
||||
ui::DynamicShape m_shape;
|
||||
bool m_dragging = false;
|
||||
std::vector<ui::Shape::vertex_t> m_points;
|
||||
std::vector<glm::vec2> m_points2d;
|
||||
std::map<int, int> m_dirty_planes;
|
||||
bool m_active_tool = false;
|
||||
public:
|
||||
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;
|
||||
virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
|
||||
virtual void init() override;
|
||||
virtual void enter() override;
|
||||
virtual void leave() override;
|
||||
};
|
||||
|
||||
@@ -202,6 +202,7 @@ void NodeCanvas::draw()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
if (m_canvas->m_smask_active && !m_canvas->m_show_tmp)
|
||||
{
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
@@ -209,7 +210,6 @@ void NodeCanvas::draw()
|
||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||
{
|
||||
auto plane_mvp = proj * camera *
|
||||
// glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) *
|
||||
m_canvas->m_plane_transform[plane_index] *
|
||||
glm::translate(glm::vec3(0, 0, -1));
|
||||
|
||||
@@ -224,10 +224,17 @@ void NodeCanvas::draw()
|
||||
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
for (auto& mode : *m_canvas->m_mode)
|
||||
mode->on_Draw(ortho_proj, proj, camera);
|
||||
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
if (m_canvas->m_smask_active)
|
||||
{
|
||||
m_canvas->modes[(int)Canvas::kCanvasMode::MaskFree][0]->on_Draw(ortho_proj, proj, camera);
|
||||
m_canvas->modes[(int)Canvas::kCanvasMode::MaskLine][0]->on_Draw(ortho_proj, proj, camera);
|
||||
}
|
||||
|
||||
// keep drawing the grids
|
||||
if (m_canvas->m_state != ui::Canvas::kCanvasMode::Grid)
|
||||
for (auto& mode : ui::Canvas::modes[(int)ui::Canvas::kCanvasMode::Grid])
|
||||
|
||||
@@ -48,6 +48,7 @@ void NodePanelStroke::init_controls()
|
||||
init_slider(m_tip_opacity, "tip-opacity", &ui::Brush::m_tip_opacity);
|
||||
init_slider(m_tip_angle, "tip-angle", &ui::Brush::m_tip_angle);
|
||||
init_slider(m_tip_stencil, "tip-stencil", &ui::Brush::m_tip_stencil);
|
||||
init_slider(m_tip_wet, "tip-wet", &ui::Brush::m_tip_wet);
|
||||
init_slider(m_jitter_scale, "jitter-scale", &ui::Brush::m_jitter_scale);
|
||||
init_slider(m_jitter_angle, "jitter-angle", &ui::Brush::m_jitter_angle);
|
||||
init_slider(m_jitter_spread, "jitter-spread", &ui::Brush::m_jitter_spread);
|
||||
|
||||
@@ -15,6 +15,7 @@ public:
|
||||
NodeSliderH* m_tip_opacity;
|
||||
NodeSliderH* m_tip_angle;
|
||||
NodeSliderH* m_tip_stencil;
|
||||
NodeSliderH* m_tip_wet;
|
||||
NodeSliderH* m_jitter_scale;
|
||||
NodeSliderH* m_jitter_angle;
|
||||
NodeSliderH* m_jitter_spread;
|
||||
|
||||
@@ -14,6 +14,7 @@ enum class kShaderUniform : uint16_t
|
||||
TexStencil= const_hash("tex_stencil"),
|
||||
StencilOffset = const_hash("stencil_offset"),
|
||||
StencilAlpha = const_hash("stencil_alpha"),
|
||||
Wet = const_hash("wet"),
|
||||
Lock = const_hash("lock"),
|
||||
Col = const_hash("col"),
|
||||
Tof = const_hash("tof"),
|
||||
|
||||
Reference in New Issue
Block a user