#include "pch.h" #include "log.h" #include "node_canvas.h" #define RES 2048 Node* NodeCanvas::clone_instantiate() const { return new NodeCanvas(); } void NodeCanvas::init() { m_mouse_ignore = false; m_canvas = std::make_unique(); m_canvas->create(RES, RES); m_sampler.create(GL_NEAREST); m_face_plane.create<1>(2, 2); m_line.create(); CanvasMode::node = this; CanvasMode::canvas = m_canvas.get(); for (int i = 0; i < (int)ui::Canvas::kCanvasMode::COUNT; i++) for (auto m : ui::Canvas::modes[i]) m->init(); } void NodeCanvas::restore_context() { Node::restore_context(); m_canvas->create(RES, RES); m_sampler.create(GL_NEAREST); m_face_plane.create<1>(2, 2); m_canvas->snapshot_restore(); CanvasMode::node = this; CanvasMode::canvas = m_canvas.get(); for (int i = 0; i < (int)ui::Canvas::kCanvasMode::COUNT; i++) for (auto m : ui::Canvas::modes[i]) m->init(); } void NodeCanvas::clear_context() { Node::clear_context(); m_canvas->snapshot_save(data_path); m_canvas->clear_context(); // TODO: clear CanvasMode objects } void NodeCanvas::draw() { using namespace ui; GLint vp[4]; GLfloat cc[4]; glGetIntegerv(GL_VIEWPORT, vp); glGetFloatv(GL_COLOR_CLEAR_VALUE, cc); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); float zoom = root()->m_zoom; auto box = m_clip * zoom; glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w); glViewport(c.x, c.y, c.z, c.w); //m_canvas->m_cam_rot = m_pan * 0.003f; glm::mat4 ortho_proj = glm::ortho(0.f, box.z, 0.f, box.w, -1000.f, 1000.f); glm::mat4 proj = glm::perspective(glm::radians(m_canvas->m_cam_fov), box.z / box.w, 0.1f, 1000.f); glm::mat4 camera = glm::eulerAngleXY(m_canvas->m_cam_rot.y, m_canvas->m_cam_rot.x) * glm::translate(m_canvas->m_cam_pos); m_canvas->m_mv = camera; m_canvas->m_proj = proj; m_canvas->m_box = box; // auto plane_mvp = proj * camera * transform * // glm::scale(glm::vec3(sz, 1)); m_sampler.bind(0); m_sampler.bind(1); m_sampler.bind(2); auto blend = glIsEnabled(GL_BLEND); auto depth = glIsEnabled(GL_DEPTH_TEST); glDisable(GL_BLEND); glDisable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); for (int plane_index = 0; plane_index < 6; plane_index++) { auto plane_mvp = proj * camera * glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); ui::ShaderManager::use(kShader::Checkerboard); ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); m_face_plane.draw_fill(); } glEnable(GL_BLEND); glEnable(GL_DEPTH_TEST); glClear(GL_DEPTH_BUFFER_BIT); for (size_t i = 0; i < m_canvas->m_order.size(); i++) { auto layer_index = m_canvas->m_order[i]; for (int plane_index = 0; plane_index < 6; plane_index++) { if (m_canvas->m_layers[layer_index].m_opacity == .0f) continue; int z = (int)m_canvas->m_order.size() - i; auto plane_mvp_z = proj * camera * glm::scale(glm::vec3(z + 1)) * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); if (m_canvas->m_state == ui::Canvas::kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { ui::ShaderManager::use(kShader::CompErase); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity); ui::ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[m_canvas->m_current_layer_idx].m_alpha_locked); ui::ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); m_canvas->m_smask.m_rtt[plane_index].bindTexture(); m_face_plane.draw_fill(); m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture(); } else if(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) { ui::ShaderManager::use(kShader::CompDraw); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); ui::ShaderManager::u_int(kShaderUniform::TexMask, 2); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_current_stroke->m_brush.m_tip_opacity); ui::ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[m_canvas->m_current_layer_idx].m_alpha_locked); ui::ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active); ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].bindTexture(); glActiveTexture(GL_TEXTURE2); m_canvas->m_smask.m_rtt[plane_index].bindTexture(); m_face_plane.draw_fill(); m_canvas->m_smask.m_rtt[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE1); m_canvas->m_tmp[plane_index].unbindTexture(); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture(); } else { ui::ShaderManager::use(kShader::TextureAlpha); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity); ui::ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index].m_hightlight); ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); glActiveTexture(GL_TEXTURE0); m_canvas->m_layers[layer_index].m_rtt[plane_index].bindTexture(); m_face_plane.draw_fill(); m_canvas->m_layers[layer_index].m_rtt[plane_index].unbindTexture(); } // if (m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) // { // glDisable(GL_BLEND); // ui::ShaderManager::use(kShader::TextureAlpha); // ui::ShaderManager::u_int(kShaderUniform::Tex, 0); // ui::ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index].m_opacity); // ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); // ui::ShaderManager::u_float(kShaderUniform::Alpha, 1); // m_canvas->m_tmp[plane_index].bindTexture(); // m_face_plane.draw_fill(); // m_canvas->m_tmp[plane_index].unbindTexture(); // glEnable(GL_BLEND); // } } } for (auto& mode : *m_canvas->m_mode) mode->on_Draw(ortho_proj, proj, camera); // keep drawing the grids if (m_canvas->m_state != ui::Canvas::kCanvasMode::Grid) for (auto& mode : ui::Canvas::modes[(int)ui::Canvas::kCanvasMode::Grid]) mode->on_Draw(ortho_proj, proj, camera); //ui::ShaderManager::use(kShader::Equirect); //ui::ShaderManager::u_mat4(kShaderUniform::MVP, glm::scale(glm::vec3(.5, .5, 1))); //ui::ShaderManager::u_int(kShaderUniform::Tex, 0); //glBindTexture(GL_TEXTURE_CUBE_MAP, m_canvas->cube_id); //m_face_plane.draw_fill(); //glBindTexture(GL_TEXTURE_CUBE_MAP, 0); // ui::ShaderManager::use(kShader::Color); // ui::ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera); // ui::ShaderManager::u_vec4(kShaderUniform::Col, { 1, 0, 0, 1 }); // static glm::vec4 AB[4]{ {-.75, 0, -1, 1},{ -.75, 0, 1, 1 } }; // m_line.update_vertices(AB); // m_line.draw_stroke(); blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND); depth ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST); m_sampler.unbind(); glViewport(vp[0], vp[1], vp[2], vp[3]); glClearColor(cc[0], cc[1], cc[2], cc[3]); } void NodeCanvas::handle_resize(glm::vec2 old_size, glm::vec2 new_size) { if (new_size.x > m_canvas->m_width) { // m_canvas->resize((int)new_size.x, (int)new_size.y); // m_canvas->clear(); } } kEventResult NodeCanvas::handle_event(Event* e) { static std::vector* old_mode = nullptr; Node::handle_event(e); MouseEvent* me = static_cast(e); KeyEvent* ke = static_cast(e); GestureEvent* ge = static_cast(e); auto loc = (me->m_pos - m_pos) * root()->m_zoom; switch (e->m_type) { case kEventType::MouseScroll: case kEventType::MouseDownL: case kEventType::MouseUpL: case kEventType::MouseDownR: case kEventType::MouseUpR: case kEventType::MouseMove: case kEventType::MouseCancel: if (!(m_canvas->m_touch_lock && me->m_source == kEventSource::Touch)) for (auto& mode : *m_canvas->m_mode) mode->on_MouseEvent(me, loc); break; case kEventType::KeyDown: // if (ke->m_key == kKey::KeyE) // m_canvas->m_state = ui::Canvas::kPenState::Erase; // if (ke->m_key == kKey::KeySpacebar) // m_canvas->m_alpha_lock = true; // if (ke->m_key == kKey::AndroidVolumeUp) // m_zoom_canvas *= 0.9f; // if (ke->m_key == kKey::AndroidVolumeDown) // m_zoom_canvas *= 1.1f; if (ke->m_key == kKey::AndroidBack) if (!ActionManager::empty()) ActionManager::undo(); break; case kEventType::KeyUp: // if (ke->m_key == kKey::KeyE) // m_canvas->m_state = ui::Canvas::kPenState::Draw; // if (ke->m_key == kKey::KeySpacebar) // m_canvas->m_alpha_lock = false; break; case kEventType::GestureStart: mouse_capture(); for (auto& mode : *m_canvas->m_mode) mode->on_GestureEvent(ge); break; case kEventType::GestureMove: for (auto& mode : *m_canvas->m_mode) mode->on_GestureEvent(ge); break; case kEventType::GestureEnd: mouse_release(); for (auto& mode : *m_canvas->m_mode) mode->on_GestureEvent(ge); break; default: return kEventResult::Available; break; } return kEventResult::Consumed; } void NodeCanvas::reset_camera() { m_canvas->m_cam_rot = {0, 0}; m_canvas->m_cam_pos = {0, 0, 0}; m_canvas->m_cam_fov = 85; m_canvas->m_pan = {0, 0}; }