canvas pan/zoom, project into canvas using inverse transform, implement eraser (early prototype)
This commit is contained in:
@@ -195,6 +195,22 @@ void App::initShaders()
|
|||||||
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
" mediump vec3 rgb = mix(bg.rgb, fg.rgb, fg.a / alpha_tot);\n"
|
||||||
" frag = vec4(rgb, alpha_tot);\n"
|
" frag = vec4(rgb, alpha_tot);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
// ERASER
|
||||||
|
static const char* shader_stroke_erase_f =
|
||||||
|
SHADER_VERSION
|
||||||
|
"uniform mediump sampler2D tex;\n"
|
||||||
|
"uniform mediump sampler2D tex_bg;\n"
|
||||||
|
"uniform mediump vec4 col;\n"
|
||||||
|
"uniform mediump vec2 resolution;\n"
|
||||||
|
"uniform mediump float alpha;\n"
|
||||||
|
"in mediump vec2 uv;\n"
|
||||||
|
"out mediump vec4 frag;\n"
|
||||||
|
"void main(){\n"
|
||||||
|
" mediump vec2 uv2 = gl_FragCoord.st / resolution;\n"
|
||||||
|
" mediump float brush_alpha = ( 1.0 - texture(tex, uv).r ) * alpha;\n"
|
||||||
|
" mediump vec4 bg = texture(tex_bg, uv2);\n"
|
||||||
|
" frag = vec4(bg.rgb, bg.a - bg.a * brush_alpha);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
// STROKE LAYER BLEND
|
// STROKE LAYER BLEND
|
||||||
static const char* shader_stroke_layer_v =
|
static const char* shader_stroke_layer_v =
|
||||||
@@ -243,6 +259,8 @@ void App::initShaders()
|
|||||||
LOG("Failed to create shader Atlas");
|
LOG("Failed to create shader Atlas");
|
||||||
if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f))
|
if (!ShaderManager::create(kShader::Stroke, shader_stroke_v, shader_stroke_f))
|
||||||
LOG("Failed to create shader Stroke");
|
LOG("Failed to create shader Stroke");
|
||||||
|
if (!ShaderManager::create(kShader::StrokeErase, shader_stroke_v, shader_stroke_erase_f))
|
||||||
|
LOG("Failed to create shader StrokeErase");
|
||||||
if (!ShaderManager::create(kShader::StrokeLayer, shader_stroke_layer_v, shader_stroke_layer_f))
|
if (!ShaderManager::create(kShader::StrokeLayer, shader_stroke_layer_v, shader_stroke_layer_f))
|
||||||
LOG("Failed to create shader StrokeLayer");
|
LOG("Failed to create shader StrokeLayer");
|
||||||
LOG("shaders initialized");
|
LOG("shaders initialized");
|
||||||
@@ -311,7 +329,11 @@ void App::initLayout()
|
|||||||
stroke->loaded();
|
stroke->loaded();
|
||||||
|
|
||||||
if (canvas)
|
if (canvas)
|
||||||
|
{
|
||||||
|
stroke->m_canvas->m_brush.m_tip_color = color->m_color;
|
||||||
|
stroke->m_canvas->draw_stroke();
|
||||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||||
|
}
|
||||||
|
|
||||||
brushes->on_brush_changed = [this](Node* target, int index) {
|
brushes->on_brush_changed = [this](Node* target, int index) {
|
||||||
auto tid = brushes->get_texture_id(index);
|
auto tid = brushes->get_texture_id(index);
|
||||||
@@ -324,7 +346,7 @@ void App::initLayout()
|
|||||||
|
|
||||||
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
color->on_color_changed = [this](Node* target, glm::vec4 color) {
|
||||||
stroke->m_canvas->m_brush.m_tip_color = color;
|
stroke->m_canvas->m_brush.m_tip_color = color;
|
||||||
stroke->m_canvas->draw_stroke();
|
// stroke->m_canvas->draw_stroke();
|
||||||
if (canvas)
|
if (canvas)
|
||||||
canvas->m_brush = stroke->m_canvas->m_brush;
|
canvas->m_brush = stroke->m_canvas->m_brush;
|
||||||
if (on_color_change)
|
if (on_color_change)
|
||||||
@@ -359,61 +381,25 @@ void App::initLayout()
|
|||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
||||||
{
|
{
|
||||||
button->on_click = [this](Node*) {
|
button->on_click = [this](Node*) {
|
||||||
panels->remove_all_children();
|
panels->get_child_index(stroke.get()) == -1 ? panels->add_child(stroke) : panels->remove_child(stroke.get());
|
||||||
if (current_panel != stroke.get())
|
|
||||||
{
|
|
||||||
panels->add_child(std::static_pointer_cast<Node>(stroke));
|
|
||||||
current_panel = stroke.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current_panel = nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-brush"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-brush"))
|
||||||
{
|
{
|
||||||
button->on_click = [this](Node*) {
|
button->on_click = [this](Node*) {
|
||||||
panels->remove_all_children();
|
panels->get_child_index(brushes.get()) == -1 ? panels->add_child(brushes) : panels->remove_child(brushes.get());
|
||||||
if (current_panel != brushes.get())
|
|
||||||
{
|
|
||||||
panels->add_child(std::static_pointer_cast<Node>(brushes));
|
|
||||||
current_panel = brushes.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current_panel = nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-color"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-color"))
|
||||||
{
|
{
|
||||||
button->on_click = [this](Node*) {
|
button->on_click = [this](Node*) {
|
||||||
panels->remove_all_children();
|
panels->get_child_index(color.get()) == -1 ? panels->add_child(color) : panels->remove_child(color.get());
|
||||||
if (current_panel != color.get())
|
|
||||||
{
|
|
||||||
panels->add_child(std::static_pointer_cast<Node>(color));
|
|
||||||
current_panel = color.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current_panel = nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-layer"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-layer"))
|
||||||
{
|
{
|
||||||
button->on_click = [this](Node*) {
|
button->on_click = [this](Node*) {
|
||||||
panels->remove_all_children();
|
panels->get_child_index(layers.get()) == -1 ? panels->add_child(layers) : panels->remove_child(layers.get());
|
||||||
if (current_panel != layers.get())
|
|
||||||
{
|
|
||||||
panels->add_child(std::static_pointer_cast<Node>(layers));
|
|
||||||
current_panel = layers.get();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
current_panel = nullptr;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -428,13 +414,14 @@ void App::initLayout()
|
|||||||
button->m_text->set_text(canvas->m_canvas->m_use_instanced ? "INST" : "NORM");
|
button->m_text->set_text(canvas->m_canvas->m_use_instanced ? "INST" : "NORM");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
button->m_text->set_text("NORM");
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-close"))
|
||||||
{
|
{
|
||||||
button->on_click = [this](Node*) {
|
button->on_click = [this](Node*) {
|
||||||
//exit(0);
|
//exit(0);
|
||||||
if (canvas)
|
if (canvas)
|
||||||
canvas->m_canvas->clear();
|
canvas->m_canvas->clear({ 0, 0, 0, 0 });
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
if (auto* button = layout[main_id]->find<NodeButton>("btn-popup"))
|
||||||
@@ -536,7 +523,7 @@ void App::init()
|
|||||||
LOG("OPENGL: %.*s", length, message);
|
LOG("OPENGL: %.*s", length, message);
|
||||||
FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE));
|
FlushConsoleInputBuffer(GetStdHandle(STD_OUTPUT_HANDLE));
|
||||||
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes);
|
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), info.wAttributes);
|
||||||
__debugbreak();
|
//__debugbreak();
|
||||||
}
|
}
|
||||||
}, nullptr);
|
}, nullptr);
|
||||||
glEnable(GL_DEBUG_OUTPUT);
|
glEnable(GL_DEBUG_OUTPUT);
|
||||||
|
|||||||
@@ -57,8 +57,16 @@ void ui::Canvas::stroke_draw()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
ShaderManager::use(ui::kShader::Stroke);
|
if (m_erase)
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
{
|
||||||
|
ShaderManager::use(ui::kShader::StrokeErase);
|
||||||
|
//ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShaderManager::use(ui::kShader::Stroke);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color);
|
||||||
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
ShaderManager::u_int(kShaderUniform::Tex, 0); // brush
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
ShaderManager::u_int(kShaderUniform::TexBG, 1); // bg
|
||||||
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
ShaderManager::u_vec2(kShaderUniform::Resolution, { m_width, m_height });
|
||||||
@@ -69,10 +77,6 @@ void ui::Canvas::stroke_draw()
|
|||||||
glm::scale(glm::vec3(s.size, s.size, 1)) *
|
glm::scale(glm::vec3(s.size, s.size, 1)) *
|
||||||
glm::eulerAngleZ(s.angle);
|
glm::eulerAngleZ(s.angle);
|
||||||
|
|
||||||
//ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
|
||||||
//ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
|
|
||||||
//m_plane.draw_fill();
|
|
||||||
|
|
||||||
glm::vec4 P[4] {
|
glm::vec4 P[4] {
|
||||||
mvp * glm::vec4(glm::vec2(-.5f, -.5f), 0, 1.f), // A - bottom-left
|
mvp * glm::vec4(glm::vec2(-.5f, -.5f), 0, 1.f), // A - bottom-left
|
||||||
mvp * glm::vec4(glm::vec2(-.5f, +.5f), 0, 1.f), // B - top-left
|
mvp * glm::vec4(glm::vec2(-.5f, +.5f), 0, 1.f), // B - top-left
|
||||||
@@ -104,7 +108,6 @@ void ui::Canvas::stroke_draw()
|
|||||||
tex_pos.x, tex_pos.y,
|
tex_pos.x, tex_pos.y,
|
||||||
tex_pos.x, tex_pos.y,
|
tex_pos.x, tex_pos.y,
|
||||||
tex_sz.x, tex_sz.y);
|
tex_sz.x, tex_sz.y);
|
||||||
// glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 10, 10, 10, 10, 200, 200);
|
|
||||||
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
|
ShaderManager::u_float(kShaderUniform::Alpha, s.flow);
|
||||||
@@ -153,10 +156,17 @@ void ui::Canvas::stroke_commit()
|
|||||||
m_tex2.bind();
|
m_tex2.bind();
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler_bg.bind(1);
|
m_sampler_bg.bind(1);
|
||||||
ShaderManager::use(ui::kShader::StrokeLayer);
|
if (m_erase)
|
||||||
|
{
|
||||||
|
ShaderManager::use(ui::kShader::Texture);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShaderManager::use(ui::kShader::StrokeLayer);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 1);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
||||||
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_current_stroke->m_brush.m_tip_opacity);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
||||||
m_plane.draw_fill();
|
m_plane.draw_fill();
|
||||||
m_sampler.unbind();
|
m_sampler.unbind();
|
||||||
@@ -183,9 +193,20 @@ void ui::Canvas::stroke_start(glm::vec2 point, float pressure, const ui::Brush&
|
|||||||
m_strokes.back().add_point(point, pressure);
|
m_strokes.back().add_point(point, pressure);
|
||||||
m_current_stroke = &m_strokes.back();
|
m_current_stroke = &m_strokes.back();
|
||||||
|
|
||||||
m_tmp.bindFramebuffer();
|
if (m_erase)
|
||||||
m_tmp.clear({ 0, 0, 0, 0 });
|
{
|
||||||
m_tmp.unbindFramebuffer();
|
m_layers[m_current_layer_idx].m_rtt.bindFramebuffer();
|
||||||
|
m_tmp.bindTexture();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||||
|
m_tmp.unbindTexture();
|
||||||
|
m_layers[m_current_layer_idx].m_rtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_tmp.bindFramebuffer();
|
||||||
|
m_tmp.clear({ 0, 0, 0, 0 });
|
||||||
|
m_tmp.unbindFramebuffer();
|
||||||
|
}
|
||||||
m_show_tmp = true;
|
m_show_tmp = true;
|
||||||
}
|
}
|
||||||
void ui::Canvas::layer_add(std::string name)
|
void ui::Canvas::layer_add(std::string name)
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class Canvas
|
|||||||
BrushMesh m_mesh;
|
BrushMesh m_mesh;
|
||||||
bool m_dirty = false;
|
bool m_dirty = false;
|
||||||
public:
|
public:
|
||||||
|
bool m_erase = false;
|
||||||
|
glm::mat4 m_mvp;
|
||||||
int m_width;
|
int m_width;
|
||||||
int m_height;
|
int m_height;
|
||||||
bool m_use_instanced = false;
|
bool m_use_instanced = false;
|
||||||
@@ -36,7 +38,7 @@ public:
|
|||||||
void stroke_draw();
|
void stroke_draw();
|
||||||
void stroke_end();
|
void stroke_end();
|
||||||
void stroke_commit();
|
void stroke_commit();
|
||||||
void clear(const glm::vec4& color = { 0, 0, 0, 1 });
|
void clear(const glm::vec4& color = { 1, 1, 1, 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
NS_END
|
NS_END
|
||||||
|
|||||||
@@ -69,6 +69,8 @@ kEventResult Node::on_event(Event* e)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if (handle_event(e) == kEventResult::Consumed)
|
||||||
|
return kEventResult::Consumed;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1101,6 +1101,13 @@ public:
|
|||||||
}
|
}
|
||||||
void set_value(float value)
|
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
|
virtual void parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr) override
|
||||||
{
|
{
|
||||||
@@ -1183,6 +1190,10 @@ public:
|
|||||||
on_hue_changed(this, m_color);
|
on_hue_changed(this, m_color);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
glm::vec4 get_hue()
|
||||||
|
{
|
||||||
|
return m_color;
|
||||||
|
}
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
using namespace ui;
|
using namespace ui;
|
||||||
@@ -1605,6 +1616,15 @@ public:
|
|||||||
m_picker->m_color = glm::vec4(0);
|
m_picker->m_color = glm::vec4(0);
|
||||||
add_child(m_picker);
|
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
|
virtual kEventResult handle_event(Event* e) override
|
||||||
{
|
{
|
||||||
NodeBorder::handle_event(e);
|
NodeBorder::handle_event(e);
|
||||||
@@ -1692,6 +1712,7 @@ public:
|
|||||||
if (on_color_changed)
|
if (on_color_changed)
|
||||||
on_color_changed(this, m_color);
|
on_color_changed(this, m_color);
|
||||||
};
|
};
|
||||||
|
m_hue->set_value(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1754,7 +1775,7 @@ public:
|
|||||||
if (true)
|
if (true)
|
||||||
{
|
{
|
||||||
m_mesh.shader.use();
|
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.shader.u_int(kShaderUniform::Tex, 0);
|
||||||
m_mesh.draw(samples, proj);
|
m_mesh.draw(samples, proj);
|
||||||
}
|
}
|
||||||
@@ -1876,6 +1897,7 @@ class NodeCanvas : public Node
|
|||||||
glm::vec2 m_dragR_start;
|
glm::vec2 m_dragR_start;
|
||||||
glm::vec2 m_pan_start;
|
glm::vec2 m_pan_start;
|
||||||
glm::vec2 m_pan;
|
glm::vec2 m_pan;
|
||||||
|
float m_zoom_canvas = 1.f;
|
||||||
public:
|
public:
|
||||||
std::unique_ptr<ui::Canvas> m_canvas;
|
std::unique_ptr<ui::Canvas> m_canvas;
|
||||||
ui::Brush m_brush;
|
ui::Brush m_brush;
|
||||||
@@ -1889,16 +1911,10 @@ public:
|
|||||||
m_canvas->layer_add("asd");
|
m_canvas->layer_add("asd");
|
||||||
m_canvas->clear();
|
m_canvas->clear();
|
||||||
m_sampler.create();
|
m_sampler.create();
|
||||||
// SetPositioning(YGPositionTypeAbsolute);
|
|
||||||
// SetPosition(100, 100);
|
|
||||||
// SetSize({ 512, 512 });
|
|
||||||
}
|
}
|
||||||
virtual void draw() override
|
virtual void draw() override
|
||||||
{
|
{
|
||||||
using namespace ui;
|
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];
|
GLint vp[4];
|
||||||
GLfloat cc[4];
|
GLfloat cc[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
@@ -1912,26 +1928,32 @@ public:
|
|||||||
glViewport(c.x, c.y, c.z, c.w);
|
glViewport(c.x, c.y, c.z, c.w);
|
||||||
|
|
||||||
glm::vec2 sz = { m_canvas->m_width, m_canvas->m_height };
|
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) *
|
m_canvas->m_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 + m_size * 0.5f, 0)) * // pan
|
||||||
glm::translate(glm::vec3(m_pan, 0)) * // corner
|
glm::scale(glm::vec3(zoom * m_zoom_canvas, zoom * m_zoom_canvas, 1)) *
|
||||||
glm::scale(glm::vec3(sz * zoom, 1)) *
|
glm::translate(glm::vec3(-sz/2.f, 0));
|
||||||
glm::translate(glm::vec3(.5f, .5f, 0.f)); // pivot
|
|
||||||
|
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);
|
m_sampler.bind(0);
|
||||||
ui::ShaderManager::use(kShader::TextureAlpha);
|
ui::ShaderManager::use(kShader::TextureAlpha);
|
||||||
ui::ShaderManager::u_int(kShaderUniform::Tex, 0);
|
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);
|
auto blend = glIsEnabled(GL_BLEND);
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
for (int i = 0; i < m_canvas->m_layers.size(); i++)
|
for (int i = 0; i < m_canvas->m_layers.size(); i++)
|
||||||
{
|
{
|
||||||
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[i].m_opacity);
|
if (!(m_canvas->m_erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == i))
|
||||||
m_canvas->m_layers[i].m_rtt.bindTexture();
|
{
|
||||||
NodeBorder::m_plane.draw_fill();
|
ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[i].m_opacity);
|
||||||
m_canvas->m_layers[i].m_rtt.unbindTexture();
|
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)
|
if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == i)
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
@@ -1959,8 +1981,12 @@ public:
|
|||||||
{
|
{
|
||||||
Node::handle_event(e);
|
Node::handle_event(e);
|
||||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||||
|
KeyEvent* ke = static_cast<KeyEvent*>(e);
|
||||||
auto loc = me->m_pos - m_pos;
|
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)
|
switch (e->m_type)
|
||||||
{
|
{
|
||||||
case kEventType::MouseDownL:
|
case kEventType::MouseDownL:
|
||||||
@@ -1991,6 +2017,16 @@ public:
|
|||||||
if (m_draggingR)
|
if (m_draggingR)
|
||||||
m_pan = m_pan_start + (me->m_pos - m_dragR_start) * glm::vec2(1, -1);
|
m_pan = m_pan_start + (me->m_pos - m_dragR_start) * glm::vec2(1, -1);
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ enum class kShader : uint16_t
|
|||||||
Font = const_hash("font"),
|
Font = const_hash("font"),
|
||||||
Atlas = const_hash("atlas"),
|
Atlas = const_hash("atlas"),
|
||||||
Stroke = const_hash("stroke"),
|
Stroke = const_hash("stroke"),
|
||||||
|
StrokeErase = const_hash("stroke-erase"),
|
||||||
StrokeLayer = const_hash("stroke-layer"),
|
StrokeLayer = const_hash("stroke-layer"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user