#include "pch.h" #include "log.h" #include "node_stroke_preview.h" #include "texture.h" #include "shader.h" #include "bezier.h" Node* NodeStrokePreview::clone_instantiate() const { return new NodeStrokePreview(); } void NodeStrokePreview::clone_copy(Node* dest) const { NodeBorder::clone_copy(dest); } void NodeStrokePreview::clone_children(Node* dest) const { // stop children cloning } void NodeStrokePreview::clone_finalize(Node* dest) const { NodeStrokePreview* n = (NodeStrokePreview*)dest; n->init_controls(); } void NodeStrokePreview::init_controls() { m_mesh.create(); m_sampler.create(); m_sampler_brush.create(); m_sampler_brush.set_filter(GL_LINEAR_MIPMAP_LINEAR, GL_LINEAR); TextureManager::load("data/thumbs/Round-Hard.png"); m_brush.m_tex_id = const_hash("data/thumbs/Round-Hard.png"); } void NodeStrokePreview::restore_context() { NodeBorder::restore_context(); init_controls(); if (m_size.x > 0 && m_size.y > 0) m_rtt.create(m_size.x, m_size.y); draw_stroke(); } void NodeStrokePreview::clear_context() { NodeBorder::clear_context(); m_rtt.destroy(); } void NodeStrokePreview::draw_stroke() { m_rtt.bindFramebuffer(); { using namespace ui; GLint vp[4]; GLfloat cc[4]; glGetIntegerv(GL_VIEWPORT, vp); glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); glClearColor(1, 1, 1, 1); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight()); glEnable(GL_BLEND); glm::mat4 proj = glm::ortho(0, (float)m_rtt.getWidth(), 0, (float)m_rtt.getHeight(), -1, 1); auto b = m_brush; m_stroke.reset(); m_stroke.start(b); if (!m_stroke.m_keypoints.empty()) m_stroke.m_prev_sample.origin = m_stroke.m_keypoints[0].pos; auto samples = m_stroke.compute_samples(); auto& tex = TextureManager::get(m_brush.m_tex_id); tex.bind(); m_sampler_brush.bind(0); if (true) { m_mesh.shader.use(); m_mesh.shader.u_vec4(kShaderUniform::Col, { 0, 0, 0, 1 }); m_mesh.shader.u_int(kShaderUniform::Tex, 0); m_mesh.draw(samples, proj); } //else //{ // ShaderManager::use("stroke"); // ShaderManager::u_vec4(kShaderUniform::Col, m_brush.m_tip_color); // ShaderManager::u_int(kShaderUniform::Tex, 0); // for (const auto& s : samples) // { // auto mvp = proj * // glm::translate(glm::vec3(s.pos, 0)) * // glm::scale(glm::vec3(s.size, s.size, 1)) * // glm::eulerAngleZ(s.angle); // ShaderManager::u_mat4(kShaderUniform::MVP, mvp); // ShaderManager::u_float(kShaderUniform::Alpha, s.flow); // m_plane.draw_fill(); // } //} m_sampler_brush.unbind(); tex.unbind(); glDisable(GL_BLEND); glViewport(vp[0], vp[1], vp[2], vp[3]); glClearColor(cc[0], cc[1], cc[2], cc[3]); } m_rtt.unbindFramebuffer(); } void NodeStrokePreview::draw() { using namespace ui; ui::ShaderManager::use(kShader::Texture); ui::ShaderManager::u_mat4(kShaderUniform::MVP, m_mvp); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); m_rtt.bindTexture(); m_sampler.bind(0); m_plane.draw_fill(); m_sampler.unbind(); m_rtt.unbindTexture(); } void NodeStrokePreview::handle_resize(glm::vec2 old_size, glm::vec2 new_size) { float pad = 30.f; new_size *= root()->m_zoom; float w = new_size.x; float h = new_size.y; std::vector kp = { { pad, pad },{ pad, h - pad },{ w - pad, pad },{ w - pad, h - pad } }; m_stroke.reset(); m_stroke.start(m_brush); for (int i = 0; i < 20; i++) m_stroke.add_point(BezierCurve::Bezier2D(kp, i / 20.f), 1.f); m_rtt.destroy(); m_rtt.create((int)new_size.x, (int)new_size.y); draw_stroke(); }