diff --git a/data/layout.xml b/data/layout.xml
index cbbd31b..c4385af 100644
--- a/data/layout.xml
+++ b/data/layout.xml
@@ -251,11 +251,16 @@
-
+
-
+
+
+
+
+
+
@@ -280,7 +285,7 @@
-
+
@@ -730,6 +735,6 @@
-->
-
+
diff --git a/engine/app.cpp b/engine/app.cpp
index 54ed681..b209a13 100644
--- a/engine/app.cpp
+++ b/engine/app.cpp
@@ -259,8 +259,8 @@ void App::update(float dt)
stroke->update_controls();
auto pix = ui::Canvas::I->m_current_brush.m_tip_color;
auto hsv = convert_rgb2hsv(glm::vec3(pix[0], pix[1], pix[2]));
- color->m_hue->set_value(hsv.x);
- color->m_quad->set_value(hsv.y, 1.f - hsv.z);
+ color->m_hue->m_value.y = hsv.x;
+ color->m_quad->m_value = glm::vec2(hsv.y, 1.f - hsv.z);
auto observer = [this](Node* n)
{
diff --git a/engine/app_shaders.cpp b/engine/app_shaders.cpp
index 9a7ca53..e2e0e41 100644
--- a/engine/app_shaders.cpp
+++ b/engine/app_shaders.cpp
@@ -177,7 +177,7 @@ void App::initShaders()
"}";
static const char* shader_color_quad_f =
SHADER_VERSION
- "uniform mediump vec4 col;"
+ "uniform mediump vec4 col; // HSV\n"
"in mediump vec3 uv;"
"out mediump vec4 frag;"
"mediump vec3 rgb2hsv(mediump vec3 c) {"
@@ -194,8 +194,7 @@ void App::initShaders()
" return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);"
"}"
"void main() {"
- " mediump float hue = rgb2hsv(col.rgb).x;"
- " frag = vec4(hsv2rgb(vec3(hue, uv.x, 1.0 - uv.y)), 1.0);"
+ " frag = vec4(hsv2rgb(vec3(col.x, uv.x, 1.0 - uv.y)), 1.0);"
"}";
// COLOR TRI
static const char* shader_color_tri_f =
diff --git a/engine/node_color_quad.cpp b/engine/node_color_quad.cpp
index 875c979..ad9026a 100644
--- a/engine/node_color_quad.cpp
+++ b/engine/node_color_quad.cpp
@@ -29,7 +29,7 @@ void NodeColorQuad::set_value(float x, float y)
{
auto sz = m_size;
auto pos = glm::clamp(glm::vec2(x, y) * sz, { 0, 0 }, sz);
- m_picker->SetPosition(pos - m_picker->GetSize() * .5f);
+ //m_picker->SetPosition(pos - m_picker->GetSize() * .5f);
m_value = pos / glm::max({ 1,1 }, sz); // avoid div0
if (on_value_changed)
on_value_changed(this, m_value);
@@ -86,6 +86,11 @@ kEventResult NodeColorQuad::handle_event(Event* e)
void NodeColorQuad::draw()
{
m_picker->m_border_color = m_value.y > .5f ? glm::vec4(1) : glm::vec4(0, 0, 0, 1);
+
+ auto sz = m_size;
+ auto pos = glm::clamp(m_value * sz, { 0, 0 }, sz);
+ m_picker->SetPosition(pos - m_picker->GetSize() * .5f);
+
using namespace ui;
ui::ShaderManager::use(kShader::ColorQuad);
ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
diff --git a/engine/node_colorwheel.cpp b/engine/node_colorwheel.cpp
index 72f28e8..80ea4f8 100644
--- a/engine/node_colorwheel.cpp
+++ b/engine/node_colorwheel.cpp
@@ -1,6 +1,7 @@
#include "pch.h"
#include "node_colorwheel.h"
#include "shader.h"
+#include "log.h"
Node* NodeColorWheel::clone_instantiate() const
{
@@ -11,10 +12,12 @@ void NodeColorWheel::clone_finalize(Node* dest) const
{
NodeColorWheel* n = (NodeColorWheel*)dest;
n->init_controls();
+ n->m_mouse_ignore = false;
}
void NodeColorWheel::init()
{
+ m_mouse_ignore = false;
//init_template("color-picker");
init_controls();
}
@@ -26,7 +29,11 @@ void NodeColorWheel::init_controls()
void NodeColorWheel::loaded()
{
m_circle.create<64>(.5, .4, ui::Circle::kUVMapping::Tube);
- m_cur_hue.create<16>(.05);
+ m_cur_hue.create<16>(.05, 0.04);
+ m_cur_quad.create<16>(.04, 0.03, ui::Circle::kUVMapping::Tube);
+
+ float quad_scale = glm::sin(glm::radians(45.f)) * 0.8f;
+ m_quad.create<1>(quad_scale, quad_scale);
struct vertex_t { glm::vec4 pos; glm::vec2 uvs; glm::vec4 col; };
std::vector vertices;
@@ -58,20 +65,125 @@ void NodeColorWheel::draw()
glDisable(GL_BLEND);
ShaderManager::use(kShader::ColorHue);
- ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
+ ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp * glm::eulerAngleZ(glm::radians(-90.f)));
ShaderManager::u_int(kShaderUniform::Direction, 0); // set horizontal
m_circle.draw_fill();
- ShaderManager::use(kShader::ColorTri);
- ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
- ShaderManager::u_vec4(kShaderUniform::Col, {1, 0, 0, 1});
- GLenum type = GL_TRIANGLES;
- glBindVertexArray(arrays);
- glDrawArrays(type, 0, 3);
- glBindVertexArray(0);
+// ShaderManager::use(kShader::ColorTri);
+// ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
+// ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(m_hsv, 0.f));
+// GLenum type = GL_TRIANGLES;
+// glBindVertexArray(arrays);
+// glDrawArrays(type, 0, 3);
+// glBindVertexArray(0);
ShaderManager::use(kShader::Color);
- ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp * glm::eulerAngleZ(glm::radians(360.f * m_hsv.x)) * glm::translate(glm::vec3(.45,0,0)));
- ShaderManager::u_vec4(kShaderUniform::Col, {1, 1, 1, 1});
+ ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp * glm::eulerAngleZ(glm::radians(-360.f * m_hsv.x)) * glm::translate(glm::vec3(.45f,0.f,0.f)));
+ ShaderManager::u_vec4(kShaderUniform::Col, {convert_hsv2rgb({glm::fract(m_hsv.x + 0.5f), 1.f, 1.f}), 1.f});
m_cur_hue.draw_stroke();
+
+ ShaderManager::use(kShader::ColorQuad);
+ ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp);
+ ShaderManager::u_vec4(kShaderUniform::Col, glm::vec4(m_hsv, 0.f));
+ m_quad.draw_fill();
+
+ float quad_scale = glm::sin(glm::radians(45.f)) * 0.8f;
+ glm::vec3 pos = glm::vec3(glm::vec2(m_hsv.y, 1.f - m_hsv.z) - 0.5f, 0);
+ ShaderManager::use(kShader::Color);
+ ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp * glm::translate(pos * quad_scale));
+ ShaderManager::u_vec4(kShaderUniform::Col, {convert_hsv2rgb({glm::fract(m_hsv.x + 0.5f), 1.f, 1.f}), 1.f});
+ m_cur_quad.draw_fill();
+}
+
+glm::vec4 NodeColorWheel::get_quad_rect() const
+{
+ float quad_scale = glm::sin(glm::radians(45.f)) * 0.8f;
+ glm::vec2 size = m_size * quad_scale;
+ glm::vec2 pos = (m_size - size) * 0.5f;
+ return glm::vec4(pos, size);
+}
+
+bool NodeColorWheel::inside_quad(glm::vec2 pos, glm::vec2& out_coord) const
+{
+ auto r = get_quad_rect();
+ out_coord = (pos - xy(r)) / zw(r);
+ return point_in_rect(pos, r);
+}
+
+void NodeColorWheel::handle_color_change()
+{
+ if (on_value_changed)
+ on_value_changed(this, m_hsv);
+}
+
+kEventResult NodeColorWheel::handle_event(Event* e)
+{
+ Node::handle_event(e);
+ auto* me = static_cast(e);
+ switch (e->m_type)
+ {
+ case kEventType::MouseDownL:
+ {
+ m_old_value = m_hsv;
+ dragging = true;
+ mouse_capture();
+
+ auto pos = (me->m_pos - m_pos - GetSize() * 0.5f) / GetSize();
+ float l = glm::length(pos);
+
+ glm::vec2 quad_pos(0);
+ if (inside_quad(me->m_pos - m_pos, quad_pos))
+ {
+ mode = 2;
+ m_hsv.y = glm::clamp(quad_pos.x, 0.f, 1.f);
+ m_hsv.z = 1.f - glm::clamp(quad_pos.y, 0.f, 1.f);
+ handle_color_change();
+ }
+ else if (l >= 0.4f && l <= 0.5f)
+ {
+ mode = 1;
+ auto pos = glm::normalize(me->m_pos - m_pos - GetSize() * 0.5f);
+ m_hsv.x = (glm::atan(pos.y, -pos.x) + glm::pi()) / glm::two_pi();
+ handle_color_change();
+ }
+ else
+ {
+ mode = 0;
+ }
+ }
+ break;
+ case kEventType::MouseUpL:
+ mouse_release();
+ dragging = false;
+ break;
+ case kEventType::MouseMove:
+ if (dragging)
+ {
+ if (mode == 1)
+ {
+ auto pos = glm::normalize(me->m_pos - m_pos - GetSize() * 0.5f);
+ m_hsv.x = (glm::atan(pos.y, -pos.x) + glm::pi()) / glm::two_pi();
+ handle_color_change();
+ }
+ else if (mode == 2)
+ {
+ glm::vec2 quad_pos(0);
+ inside_quad(me->m_pos - m_pos, quad_pos);
+ m_hsv.y = glm::clamp(quad_pos.x, 0.f, 1.f);
+ m_hsv.z = 1.f - glm::clamp(quad_pos.y, 0.f, 1.f);
+ handle_color_change();
+ }
+ }
+ break;
+ case kEventType::MouseCancel:
+ mouse_release();
+ dragging = false;
+ m_hsv = m_old_value;
+ handle_color_change();
+ break;
+ default:
+ return kEventResult::Available;
+ break;
+ }
+ return kEventResult::Consumed;
}
diff --git a/engine/node_colorwheel.h b/engine/node_colorwheel.h
index 4cd182d..e9294ab 100644
--- a/engine/node_colorwheel.h
+++ b/engine/node_colorwheel.h
@@ -3,21 +3,33 @@
#include "node.h"
#include "shape.h"
#include "node_slider.h"
+#include "node_border.h"
class NodeColorWheel : public Node
{
public:
ui::Circle m_circle;
- ui::Circle m_cur_hue;
+ ui::Plane m_cur_hue;
+ ui::Circle m_cur_quad;
+ ui::Plane m_quad;
+ NodeBorder* m_color_cur;
glm::vec3 m_hsv;
GLuint m_tri_vbo;
GLuint m_tri_vao;
GLuint buffers;
GLuint arrays;
+ std::function on_value_changed;
+ int mode; // 1:hue 2:quad
+ bool dragging = false;
+ glm::vec3 m_old_value{0.f};
virtual Node* clone_instantiate() const override;
- virtual void clone_finalize(Node* dest) const;
+ virtual void clone_finalize(Node* dest) const override;
virtual void init() override;
virtual void loaded() override;
virtual void draw() override;
+ virtual kEventResult handle_event(Event* e) override;
void init_controls();
+ glm::vec4 get_quad_rect() const;
+ bool inside_quad(glm::vec2 pos, glm::vec2& out_coord) const;
+ void handle_color_change();
};
diff --git a/engine/node_dialog_picker.cpp b/engine/node_dialog_picker.cpp
index 543d291..27899e5 100644
--- a/engine/node_dialog_picker.cpp
+++ b/engine/node_dialog_picker.cpp
@@ -25,15 +25,20 @@ void NodeColorPicker::init()
void NodeColorPicker::draw()
{
NodeBorder::draw();
- glm::vec3 rgb = glm::vec3(ui::Canvas::I->m_current_brush.m_tip_color);
- glm::vec3 hsv = convert_rgb2hsv(rgb);
- m_slider_h->set_value(hsv.x);
- m_slider_s->set_value(hsv.y);
- m_slider_v->set_value(hsv.z);
- m_slider_r->set_value(rgb.x);
- m_slider_g->set_value(rgb.y);
- m_slider_b->set_value(rgb.z);
- m_wheel->m_hsv = hsv;
+// glm::vec3 rgb = glm::vec3(ui::Canvas::I->m_current_brush.m_tip_color);
+// glm::vec3 hsv = convert_rgb2hsv(rgb);
+// m_slider_h->m_value.x = hsv.x;
+// m_slider_s->m_value.x = hsv.y;
+// m_slider_v->m_value.x = hsv.z;
+// m_slider_r->m_value.x = rgb.x;
+// m_slider_g->m_value.x = rgb.y;
+// m_slider_b->m_value.x = rgb.z;
+// m_wheel->m_hsv = hsv;
+}
+
+void NodeColorPicker::handle_value_changed()
+{
+
}
void NodeColorPicker::init_controls()
@@ -45,12 +50,44 @@ void NodeColorPicker::init_controls()
m_slider_g = find("rgb-g");
m_slider_b = find("rgb-b");
m_wheel = find("wheel");
+ m_color_cur = find("color-cur");
+ m_color_old = find("color-old");
+ m_color_old1 = find("color-old1");
+ m_color_old2 = find("color-old2");
+ m_button_select = find("btn-select");
+
+ m_button_select->on_click = [this](Node*)
+ {
+ m_color_old2->m_color = m_color_old1->m_color;
+ m_color_old1->m_color = m_color_old->m_color;
+ m_color_old->m_color = m_color_cur->m_color;
+ };
+ m_wheel->on_value_changed = [this](Node*, glm::vec3 hsv)
+ {
+ m_slider_h->m_value.x = hsv.x;
+ m_slider_s->m_value.x = hsv.y;
+ m_slider_v->m_value.x = hsv.z;
+ glm::vec3 rgb = convert_hsv2rgb(hsv);
+ m_slider_r->m_value.x = rgb.x;
+ m_slider_g->m_value.x = rgb.y;
+ m_slider_b->m_value.x = rgb.z;
+ m_color_cur->m_color = {rgb,1};
+ };
+ auto hsv_setter = [this](Node* target, float v)
+ {
+ m_wheel->m_hsv = get_hsv();
+ glm::vec3 rgb = convert_hsv2rgb(get_hsv());
+ m_color_cur->m_color = {rgb,1};
+ };
+ m_slider_h->on_value_changed = hsv_setter;
+ m_slider_s->on_value_changed = hsv_setter;
+ m_slider_v->on_value_changed = hsv_setter;
}
-glm::vec4 NodeColorPicker::get_hsv() const
+glm::vec3 NodeColorPicker::get_hsv() const
{
float h = m_slider_h->get_value();
float s = m_slider_s->get_value();
float v = m_slider_v->get_value();
- return glm::vec4(h, s, v, 1.f);
+ return glm::vec3(h, s, v);
}
diff --git a/engine/node_dialog_picker.h b/engine/node_dialog_picker.h
index 040a8bf..97a2859 100644
--- a/engine/node_dialog_picker.h
+++ b/engine/node_dialog_picker.h
@@ -2,6 +2,7 @@
#include "node_border.h"
#include "node_slider.h"
#include "node_colorwheel.h"
+#include "node_button.h"
class NodeColorPicker : public NodeBorder
{
@@ -13,8 +14,13 @@ public:
NodeSliderH* m_slider_g;
NodeSliderH* m_slider_b;
NodeColorWheel* m_wheel;
- glm::vec4 m_rgb;
- glm::vec4 m_hsv;
+ NodeBorder* m_color_cur;
+ NodeBorder* m_color_old;
+ NodeBorder* m_color_old1;
+ NodeBorder* m_color_old2;
+ NodeButton* m_button_select;
+ glm::vec3 m_rgb;
+ glm::vec3 m_hsv;
virtual Node* clone_instantiate() const override;
//virtual void clone_copy(Node* dest) const override;
@@ -22,5 +28,6 @@ public:
virtual void init() override;
virtual void draw() override;
void init_controls();
- glm::vec4 get_hsv() const;
+ glm::vec3 get_hsv() const;
+ void handle_value_changed();
};
diff --git a/engine/node_slider.cpp b/engine/node_slider.cpp
index 9593138..58938b4 100644
--- a/engine/node_slider.cpp
+++ b/engine/node_slider.cpp
@@ -49,7 +49,7 @@ void NodeSliderH::set_value(float value)
float NodeSliderH::get_value()
{
- return glm::length(m_value);
+ return glm::length(m_value * m_mask);
}
void NodeSliderH::parse_attributes(kAttribute ka, const tinyxml2::XMLAttribute* attr)
diff --git a/engine/node_slider.h b/engine/node_slider.h
index 57d72b3..b2589b0 100644
--- a/engine/node_slider.h
+++ b/engine/node_slider.h
@@ -6,7 +6,7 @@ class NodeSliderH : public NodeBorder
bool dragging = false;
public:
glm::vec2 m_mask{ 1, 0 };
- glm::vec2 m_value;
+ glm::vec2 m_value{0};
glm::vec2 m_old_value;
std::function on_value_changed;
virtual Node* clone_instantiate() const override;
diff --git a/engine/pch.h b/engine/pch.h
index a6f7866..41c2419 100644
--- a/engine/pch.h
+++ b/engine/pch.h
@@ -102,6 +102,7 @@
#include
#include
#include
+#include
#include
#include
diff --git a/engine/shader.cpp b/engine/shader.cpp
index 98cf023..b76e02b 100644
--- a/engine/shader.cpp
+++ b/engine/shader.cpp
@@ -64,9 +64,15 @@ bool Shader::create(const char* vertex, const char* fragment)
glDeleteShader(vs);
glDeleteShader(fs);
- glBindAttribLocation(ps, 0, "pos");
- glBindAttribLocation(ps, 1, "uvs");
- glBindAttribLocation(ps, 2, "col");
+ glLinkProgram(ps);
+ if (glGetAttribLocation(ps, "pos") != -1)
+ glBindAttribLocation(ps, 0, "pos");
+
+ if (glGetAttribLocation(ps, "uvs") != -1)
+ glBindAttribLocation(ps, 1, "uvs");
+
+ if (glGetAttribLocation(ps, "col") != -1)
+ glBindAttribLocation(ps, 2, "col");
glLinkProgram(ps);
glGetProgramiv(ps, GL_LINK_STATUS, &status);