canvas pan/zoom, project into canvas using inverse transform, implement eraser (early prototype)
This commit is contained in:
@@ -1101,6 +1101,13 @@ public:
|
||||
}
|
||||
void set_value(float value)
|
||||
{
|
||||
m_value = glm::vec2(value) * m_mask;
|
||||
if (on_value_changed)
|
||||
on_value_changed(this, glm::length(m_value));
|
||||
}
|
||||
float get_value()
|
||||
{
|
||||
return glm::length(m_value);
|
||||
}
|
||||
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||
{
|
||||
@@ -1183,6 +1190,10 @@ public:
|
||||
on_hue_changed(this, m_color);
|
||||
};
|
||||
}
|
||||
glm::vec4 get_hue()
|
||||
{
|
||||
return m_color;
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
using namespace ui;
|
||||
@@ -1605,6 +1616,15 @@ public:
|
||||
m_picker->m_color = glm::vec4(0);
|
||||
add_child(m_picker);
|
||||
}
|
||||
void set_value(float x, float y)
|
||||
{
|
||||
auto sz = GetSize();
|
||||
auto pos = glm::clamp(glm::vec2(x, y) * sz, { 0, 0 }, sz);
|
||||
m_picker->SetPosition(pos.x, pos.y);
|
||||
m_value = pos / glm::max({ 1,1 }, sz); // avoid div0
|
||||
if (on_value_changed)
|
||||
on_value_changed(this, m_value);
|
||||
}
|
||||
virtual kEventResult handle_event(Event* e) override
|
||||
{
|
||||
NodeBorder::handle_event(e);
|
||||
@@ -1692,6 +1712,7 @@ public:
|
||||
if (on_color_changed)
|
||||
on_color_changed(this, m_color);
|
||||
};
|
||||
m_hue->set_value(0);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1754,7 +1775,7 @@ public:
|
||||
if (true)
|
||||
{
|
||||
m_mesh.shader.use();
|
||||
m_mesh.shader.u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||
m_mesh.shader.u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 });
|
||||
m_mesh.shader.u_int(kShaderUniform::Tex, 0);
|
||||
m_mesh.draw(samples, proj);
|
||||
}
|
||||
@@ -1876,6 +1897,7 @@ class NodeCanvas : public Node
|
||||
glm::vec2 m_dragR_start;
|
||||
glm::vec2 m_pan_start;
|
||||
glm::vec2 m_pan;
|
||||
float m_zoom_canvas = 1.f;
|
||||
public:
|
||||
std::unique_ptr<ui::Canvas> m_canvas;
|
||||
ui::Brush m_brush;
|
||||
@@ -1889,16 +1911,10 @@ public:
|
||||
m_canvas->layer_add("asd");
|
||||
m_canvas->clear();
|
||||
m_sampler.create();
|
||||
// SetPositioning(YGPositionTypeAbsolute);
|
||||
// SetPosition(100, 100);
|
||||
// SetSize({ 512, 512 });
|
||||
}
|
||||
virtual void draw() override
|
||||
{
|
||||
using namespace ui;
|
||||
//glm::mat4 cam = glm::lookAt(glm::vec3(sinf(angle) * 10, 0, -10), glm::vec3(0, 0, 0), glm::vec3(0, -1, 0));
|
||||
//glm::mat4 proj = glm::perspective<float>(glm::radians(45.f), m_clip.z / m_clip.w, .1f, 100);
|
||||
|
||||
GLint vp[4];
|
||||
GLfloat cc[4];
|
||||
glGetIntegerv(GL_VIEWPORT, vp);
|
||||
@@ -1912,26 +1928,32 @@ public:
|
||||
glViewport(c.x, c.y, c.z, c.w);
|
||||
|
||||
glm::vec2 sz = { m_canvas->m_width, m_canvas->m_height };
|
||||
auto mvp = glm::ortho(0.f, box.z, 0.f, box.w, -1.f, 1.f) *
|
||||
//glm::translate(glm::vec3((m_size - sz) * 0.5f, 0)) * // center
|
||||
glm::translate(glm::vec3(m_pan, 0)) * // corner
|
||||
glm::scale(glm::vec3(sz * zoom, 1)) *
|
||||
glm::translate(glm::vec3(.5f, .5f, 0.f)); // pivot
|
||||
m_canvas->m_mvp = glm::ortho(0.f, box.z, 0.f, box.w, -1.f, 1.f) *
|
||||
glm::translate(glm::vec3(m_pan + m_size * 0.5f, 0)) * // pan
|
||||
glm::scale(glm::vec3(zoom * m_zoom_canvas, zoom * m_zoom_canvas, 1)) *
|
||||
glm::translate(glm::vec3(-sz/2.f, 0));
|
||||
|
||||
auto plane_mvp = glm::ortho(0.f, box.z, 0.f, box.w, -1.f, 1.f) *
|
||||
glm::translate(glm::vec3(m_pan + m_size * 0.5f, 0)) * // pan
|
||||
glm::scale(glm::vec3(sz * zoom * m_zoom_canvas, 1));
|
||||
|
||||
m_sampler.bind(0);
|
||||
ui::ShaderManager::use(kShader::TextureAlpha);
|
||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||
|
||||
auto blend = glIsEnabled(GL_BLEND);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
for (int i = 0; i < m_canvas->m_layers.size(); i++)
|
||||
{
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[i].m_opacity);
|
||||
m_canvas->m_layers[i].m_rtt.bindTexture();
|
||||
NodeBorder::m_plane.draw_fill();
|
||||
m_canvas->m_layers[i].m_rtt.unbindTexture();
|
||||
if (!(m_canvas->m_erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == i))
|
||||
{
|
||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[i].m_opacity);
|
||||
m_canvas->m_layers[i].m_rtt.bindTexture();
|
||||
NodeBorder::m_plane.draw_fill();
|
||||
m_canvas->m_layers[i].m_rtt.unbindTexture();
|
||||
}
|
||||
if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == i)
|
||||
{
|
||||
glEnable(GL_BLEND);
|
||||
@@ -1959,8 +1981,12 @@ public:
|
||||
{
|
||||
Node::handle_event(e);
|
||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||
KeyEvent* ke = static_cast<KeyEvent*>(e);
|
||||
auto loc = me->m_pos - m_pos;
|
||||
auto cur = glm::vec2(loc.x, m_canvas->m_height - loc.y - 1);
|
||||
auto clip_space = glm::vec2(loc.x, m_size.y - loc.y - 1.f) / m_size * 2.f - 1.f;
|
||||
auto fb_space = glm::inverse(m_canvas->m_mvp) * glm::vec4(clip_space, 0, 1);
|
||||
auto cur = fb_space.xy();
|
||||
|
||||
switch (e->m_type)
|
||||
{
|
||||
case kEventType::MouseDownL:
|
||||
@@ -1991,6 +2017,16 @@ public:
|
||||
if (m_draggingR)
|
||||
m_pan = m_pan_start + (me->m_pos - m_dragR_start) * glm::vec2(1, -1);
|
||||
break;
|
||||
case kEventType::MouseScroll:
|
||||
m_zoom_canvas += me->m_scroll_delta * 0.1f;
|
||||
break;
|
||||
case kEventType::KeyDown:
|
||||
if (ke->m_key == 'E')
|
||||
m_canvas->m_erase = true;
|
||||
break;
|
||||
case kEventType::KeyUp:
|
||||
if (ke->m_key == 'E')
|
||||
m_canvas->m_erase = false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user