#include "pch.h" #include "node_colorwheel.h" #include "shader.h" #include "log.h" Node* NodeColorWheel::clone_instantiate() const { return new NodeColorWheel; } 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(); } void NodeColorWheel::init_controls() { } void NodeColorWheel::loaded() { m_circle.create<64>(.5, .4, ui::Circle::kUVMapping::Tube); 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; float l = 0.4; vertices.push_back({{glm::cos(4.f/3.f*glm::pi())*l,glm::sin(4.f/3.f*glm::pi())*l,0,1},{1,-1},{1,1,1,1}}); vertices.push_back({{glm::cos(2.f/3.f*glm::pi())*l,glm::sin(2.f/3.f*glm::pi())*l,0,1},{0,0},{0,0,0,1}}); vertices.push_back({{l,0,0,1},{1,1},{1,0,0,1}}); glGenBuffers(1, &buffers); glBindBuffer(GL_ARRAY_BUFFER, buffers); glBufferData(GL_ARRAY_BUFFER, vertices.size()*sizeof(vertex_t), vertices.data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenVertexArrays(1, &arrays); glBindVertexArray(arrays); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glBindBuffer(GL_ARRAY_BUFFER, buffers); glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)0); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, uvs)); glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(vertex_t), (GLvoid*)offsetof(vertex_t, col)); glBindVertexArray(0); } void NodeColorWheel::draw() { using namespace ui; glDisable(GL_BLEND); ShaderManager::use(kShader::ColorHue); 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, 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(.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; }