improve brush preview
This commit is contained in:
173
src/canvas.cpp
173
src/canvas.cpp
@@ -798,6 +798,9 @@ void Canvas::stroke_commit()
|
||||
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
|
||||
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
|
||||
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternScale, glm::vec2(b->m_pattern_scale));
|
||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].bind();
|
||||
@@ -1007,7 +1010,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[source_idx].m_blend_mode);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||
ShaderManager::u_int(kShaderUniform::UseDual, false);
|
||||
ShaderManager::u_int(kShaderUniform::UsePattern,false);
|
||||
ShaderManager::u_int(kShaderUniform::UsePattern, false);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].bind();
|
||||
@@ -2517,174 +2520,6 @@ void Canvas::set_camera(const CameraData& c)
|
||||
m_vp = c.m_vp;
|
||||
}
|
||||
|
||||
std::vector<vertex_t> Canvas::triangulate_simple(const std::vector<vertex_t>& vertices)
|
||||
{
|
||||
std::vector<vertex_t> ret;
|
||||
std::vector<p2t::Point> points(vertices.size());
|
||||
std::vector<p2t::Point*> points_ptr(vertices.size());
|
||||
for (size_t i = 0; i < vertices.size(); i++)
|
||||
{
|
||||
points[i] = { vertices[i].pos.x, vertices[i].pos.y };
|
||||
points_ptr[i] = &points[i];
|
||||
}
|
||||
|
||||
auto cdt = std::make_unique<p2t::CDT>(points_ptr);
|
||||
cdt->Triangulate();
|
||||
auto tr = cdt->GetTriangles();
|
||||
for (auto t : tr)
|
||||
{
|
||||
vertex_t vertex;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto index = std::distance(points.data(), t->GetPoint(i));
|
||||
ret.push_back(vertices[index]);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<vertex_t> Canvas::triangulate(const std::vector<glm::vec2>& points)
|
||||
{
|
||||
std::vector<vertex_t> tmp;
|
||||
for (auto pt : points)
|
||||
tmp.push_back(pt);
|
||||
return triangulate(tmp);
|
||||
}
|
||||
|
||||
std::vector<vertex_t> Canvas::triangulate(const std::vector<vertex_t>& points)
|
||||
{
|
||||
struct Segment
|
||||
{
|
||||
const vertex_t* a = nullptr;
|
||||
const vertex_t* b = nullptr;
|
||||
Segment* prev = nullptr;
|
||||
std::shared_ptr<Segment> next = nullptr;
|
||||
bool end = false;
|
||||
};
|
||||
std::vector<std::shared_ptr<vertex_t>> new_points;
|
||||
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->pos == other->a->pos || node->a->pos == other->b->pos ||
|
||||
node->b->pos == other->a->pos || node->b->pos == other->b->pos)
|
||||
{
|
||||
other = other->end ? nullptr : other->next;
|
||||
continue;
|
||||
}
|
||||
glm::vec2 s0a(node->a->pos);
|
||||
glm::vec2 s0b(node->b->pos);
|
||||
glm::vec2 s1a(other->a->pos);
|
||||
glm::vec2 s1b(other->b->pos);
|
||||
glm::vec2 hit_uv;
|
||||
glm::vec2 is;
|
||||
if (segments_intersect(s0a, s0b, s1a, s1b, is, hit_uv))
|
||||
{
|
||||
new_points.push_back(std::make_unique<vertex_t>());
|
||||
auto p = new_points.back().get();
|
||||
p->pos = glm::lerp(node->a->pos, node->b->pos, hit_uv.x);
|
||||
p->uvs = glm::lerp(node->a->uvs, node->b->uvs, hit_uv.x);
|
||||
p->uvs2 = glm::lerp(node->a->uvs2, node->b->uvs2, hit_uv.x);
|
||||
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<vertex_t> ret;
|
||||
for (auto poly : polys)
|
||||
{
|
||||
std::vector<const vertex_t*> outline;
|
||||
node = poly;
|
||||
while (node)
|
||||
{
|
||||
if (outline.empty() || // if empty insert right away
|
||||
outline.back() != node->a && // insert only if different than the last post
|
||||
(outline.front() != node->a || !node->end)) // if is the end check against the first one
|
||||
{
|
||||
outline.push_back(node->a);
|
||||
}
|
||||
auto current = node;
|
||||
node = node->end ? nullptr : node->next;
|
||||
current->next = nullptr;
|
||||
}
|
||||
|
||||
if (outline.size() > 2)
|
||||
{
|
||||
std::vector<p2t::Point> points(outline.size());
|
||||
std::vector<p2t::Point*> points_ptr(outline.size());
|
||||
for (size_t i = 0; i < outline.size(); i++)
|
||||
{
|
||||
points[i] = { outline[i]->pos.x, outline[i]->pos.y };
|
||||
points_ptr[i] = &points[i];
|
||||
}
|
||||
|
||||
p2t::CDT* cdt = new p2t::CDT(points_ptr); // TODO: remove duplicates
|
||||
cdt->Triangulate();
|
||||
auto tr = cdt->GetTriangles();
|
||||
for (auto t : tr)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
auto index = std::distance(points.data(), t->GetPoint(i));
|
||||
ret.push_back(*outline[index]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Layer::destroy()
|
||||
|
||||
Reference in New Issue
Block a user