diff --git a/android/CMakeLists.txt b/android/CMakeLists.txt index 28382c2..5369c84 100644 --- a/android/CMakeLists.txt +++ b/android/CMakeLists.txt @@ -39,7 +39,7 @@ add_library( ../engine/app.cpp ../engine/brush.cpp ../engine/canvas.cpp - ../engine/canvas_mode.cpp + ../engine/canvas_modes.cpp ../engine/log.cpp ../engine/action.cpp ) diff --git a/engine.vcxproj b/engine.vcxproj index e2dca01..cde0bda 100644 --- a/engine.vcxproj +++ b/engine.vcxproj @@ -156,6 +156,7 @@ + @@ -199,6 +200,7 @@ + diff --git a/engine.vcxproj.filters b/engine.vcxproj.filters index 02e11e9..87a6cc2 100644 --- a/engine.vcxproj.filters +++ b/engine.vcxproj.filters @@ -78,6 +78,9 @@ Source Files + + Source Files + @@ -134,5 +137,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/engine/canvas.cpp b/engine/canvas.cpp index 1e7023c..90844a2 100644 --- a/engine/canvas.cpp +++ b/engine/canvas.cpp @@ -7,6 +7,7 @@ std::vector ui::Canvas::modes[] = { { new CanvasModePen, new CanvasModeBasicCamera }, { new CanvasModePen, new CanvasModeBasicCamera }, { new CanvasModeLine, new CanvasModeBasicCamera }, + { new CanvasModeCamera, new CanvasModeBasicCamera }, }; glm::vec3 ui::Canvas::m_plane_origin[6] = { { 0, 0,-1}, // front @@ -47,9 +48,18 @@ void ui::Canvas::clear(const glm::vec4& c/*={0,0,0,1}*/) } void ui::Canvas::stroke_end() { - stroke_commit(); - m_current_stroke = nullptr; - m_show_tmp = false; + if (!m_current_stroke) + return; + if (m_current_stroke->has_sample()) + { + m_commit_delayed = true; + } + else + { + stroke_commit(); + m_current_stroke = nullptr; + m_show_tmp = false; + } } void ui::Canvas::stroke_draw() { @@ -146,7 +156,7 @@ void ui::Canvas::stroke_draw() { glm::mat4 plane_camera = glm::lookAt(m_plane_origin[i], m_plane_normal[i], m_plane_tangent[i]); glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1); - if (glm::abs(plane_local.x) < 1.f && glm::abs(plane_local.y) < 1.f) + if (glm::abs(plane_local.x) < 1.5f && glm::abs(plane_local.y) < 1.5f) { fb_pos.x = -(plane_local.x * 0.5f - 0.5f) * m_width; fb_pos.y = (plane_local.y * 0.5f + 0.5f) * m_height; @@ -234,6 +244,13 @@ void ui::Canvas::stroke_draw() glViewport(vp[0], vp[1], vp[2], vp[3]); glClearColor(cc[0], cc[1], cc[2], cc[3]); + if (m_commit_delayed) + { + stroke_commit(); + m_current_stroke = nullptr; + m_show_tmp = false; + m_commit_delayed = false; + } } void ui::Canvas::stroke_commit() { diff --git a/engine/canvas.h b/engine/canvas.h index 6af5f90..40f1c29 100644 --- a/engine/canvas.h +++ b/engine/canvas.h @@ -39,6 +39,7 @@ class Canvas Plane m_plane_brush; BrushMesh m_mesh; bool m_dirty = false; + bool m_commit_delayed = false; public: static Canvas* I; bool m_alpha_lock = false; @@ -67,9 +68,10 @@ public: Sampler m_sampler_bg; Sampler m_sampler_mask; glm::vec2 m_cam_rot; + glm::vec3 m_cam_pos; float m_cam_fov = 85; - enum class kCanvasMode { Draw, Erase, Line, Camera }; + enum class kCanvasMode { Draw, Erase, Line, Camera, COUNT }; kCanvasMode m_state{ kCanvasMode::Draw }; static std::vector modes[]; std::vector* m_mode; diff --git a/engine/canvas_modes.cpp b/engine/canvas_modes.cpp index 5108e0c..44466af 100644 --- a/engine/canvas_modes.cpp +++ b/engine/canvas_modes.cpp @@ -3,6 +3,7 @@ #include "canvas_modes.h" #include "layout.h" #include "canvas.h" +#include "shader.h" NodeCanvas* CanvasMode::node; ui::Canvas* CanvasMode::canvas; @@ -98,19 +99,24 @@ void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) switch (me->m_type) { case kEventType::MouseDownL: - if (m_stage == 0) + node->mouse_capture(); + m_dragging = true; + m_drag_start = loc; + m_drag_pos = loc; + break; + case kEventType::MouseUpL: + node->mouse_release(); + if (m_dragging) { - canvas->stroke_start(loc, 1.f, node->m_brush); - node->mouse_capture(); - m_stage = 1; - } - else - { - canvas->stroke_update(loc, 1.f); - //canvas->stroke_end(); - node->mouse_release(); - m_stage = 0; + canvas->stroke_start(m_drag_start, 1.f, node->m_brush); + canvas->stroke_update(m_drag_pos, 1.f); + canvas->stroke_end(); } + m_dragging = false; + break; + case kEventType::MouseMove: + if (m_dragging) + m_drag_pos = loc; break; case kEventType::MouseCancel: node->mouse_release(); @@ -119,3 +125,56 @@ void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc) break; } } + +void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) +{ + if (m_dragging) + { + ui::ShaderManager::use(ui::kShader::Color); + ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho); + ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, node->m_brush.m_tip_color); + static glm::vec4 AB[2]; + AB[0] = { m_drag_start, 0, 1 }; + AB[1] = { m_drag_pos, 0, 1 }; + AB[0].y = canvas->m_box.w - AB[0].y - 1; // invert Y + AB[1].y = canvas->m_box.w - AB[1].y - 1; // invert Y + m_line.update_vertices(AB); + m_line.draw_stroke(); + } +} + +void CanvasModeLine::init() +{ + m_line.create(); +} + +//////////////////////////////////////////////////////////////////// + +void CanvasModeCamera::on_MouseEvent(MouseEvent* me, glm::vec2& loc) +{ + switch (me->m_type) + { + case kEventType::MouseDownR: + canvas->m_cam_pos = { 0, 0, 0 }; + break; + case kEventType::MouseDownL: + m_dragging = true; + m_drag_start = me->m_pos; + m_pos_start = canvas->m_cam_pos.xy; + node->mouse_capture(); + break; + case kEventType::MouseUpL: + m_dragging = false; + node->mouse_release(); + break; + case kEventType::MouseMove: + if (m_dragging) + canvas->m_cam_pos.xy = m_pos_start + (me->m_pos - m_drag_start) * glm::vec2(1, -1) * 0.01f; + break; + case kEventType::MouseCancel: + node->mouse_release(); + break; + default: + break; + } +} diff --git a/engine/canvas_modes.h b/engine/canvas_modes.h index 924142e..b0c2dbd 100644 --- a/engine/canvas_modes.h +++ b/engine/canvas_modes.h @@ -1,5 +1,6 @@ #pragma once #include "event.h" +#include "shape.h" NS_START class Canvas; @@ -13,6 +14,8 @@ public: virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) {} virtual void on_KeyEvent(KeyEvent* ke) {} virtual void on_GestureEvent(GestureEvent* ge) {} + virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) {} + virtual void init() {} }; class CanvasModeBasicCamera : public CanvasMode @@ -43,7 +46,22 @@ public: class CanvasModeLine : public CanvasMode { - int m_stage{0}; + ui::LineSegment m_line; + bool m_dragging = false; + glm::vec2 m_drag_start; + glm::vec2 m_drag_pos; +public: + virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; + virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override; + virtual void init() override; +}; + +class CanvasModeCamera : public CanvasMode +{ + bool m_dragging = false; + glm::vec2 m_drag_start; + glm::vec2 m_pos_start; + ui::Plane m_face_plane; public: virtual void on_MouseEvent(MouseEvent* me, glm::vec2& loc) override; }; diff --git a/engine/layout.h b/engine/layout.h index 606d42d..59464fa 100644 --- a/engine/layout.h +++ b/engine/layout.h @@ -1973,6 +1973,7 @@ public: ui::Brush m_brush; Sampler m_sampler; ui::Plane m_face_plane; + ui::LineSegment m_line; virtual Node* clone_instantiate() const override { return new NodeCanvas(); } virtual void init() override { @@ -1980,9 +1981,13 @@ public: m_canvas = std::make_unique(); 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(); m_canvas->create(1024, 1024); m_sampler.create(); m_face_plane.create<1>(2, 2); + m_line.create(); } virtual void restore_context() override { @@ -2015,9 +2020,10 @@ public: //m_canvas->m_cam_rot = m_pan * 0.003f; - //glm::mat4 proj = glm::ortho(0.f, box.z, 0.f, box.w, -1000.f, 1000.f); + 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::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; @@ -2033,7 +2039,7 @@ public: glEnable(GL_BLEND); for (int plane_index = 0; plane_index < 6; plane_index++) { - auto plane_mvp = proj * camera * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); + auto plane_mvp = proj * camera * glm::scale(glm::vec3(m_canvas->m_order.size())) * 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); @@ -2041,9 +2047,11 @@ public: ui::ShaderManager::use(kShader::TextureAlpha); ui::ShaderManager::u_int(kShaderUniform::Tex, 0); - ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); for (auto layer_index : m_canvas->m_order) { + int z = m_canvas->m_order.size() - layer_index; + auto plane_mvp_z = proj * camera * glm::scale(glm::vec3(z)) * m_canvas->m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); + ui::ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z); if (!(m_canvas->m_state == ui::Canvas::kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)) { @@ -2063,12 +2071,22 @@ public: } } + for (auto& mode : *m_canvas->m_mode) + 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); m_sampler.unbind(); diff --git a/engine/shape.cpp b/engine/shape.cpp index f278fca..440ba25 100644 --- a/engine/shape.cpp +++ b/engine/shape.cpp @@ -381,3 +381,28 @@ void Slice9::create_impl(float w, float h, float r, float tr, GLushort *idx, Sha *idx++ = 12; // D *idx++ = 0; // A } +void ui::LineSegment::create_impl(GLushort* idx, vertex_t* vertices) +{ + count[0] = 2; + count[1] = 2; + ioff[0] = (GLvoid*)0; + ioff[1] = (GLvoid*)0; + vertices[0] = { { 0, 0, 0, 1 }, { 0, 0 } }; // A + vertices[1] = { { 0, 0, 0, 1 }, { 0, 1 } }; // B + idx[0] = 0; + idx[1] = 1; +} +void ui::LineSegment::update_vertices(const glm::vec4 data[2]) +{ + static vertex_t vertices[2]; + vertices[0] = { data[0], { 0, 0 } }; // A + vertices[1] = { data[1], { 0, 1 } }; // B + glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); + static GLushort idx[4] { 0, 1 }; + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(idx), idx, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} diff --git a/engine/shape.h b/engine/shape.h index ab93ceb..2c27463 100644 --- a/engine/shape.h +++ b/engine/shape.h @@ -47,6 +47,20 @@ protected: } }; +class LineSegment : public Shape +{ + void create_impl(GLushort* idx, vertex_t* vertices); +public: + bool create() + { + static GLushort idx[2]; + static vertex_t vertices[2]; + create_impl(idx, vertices); + return create_buffers(idx, vertices, sizeof(idx), sizeof(vertices)); + } + void update_vertices(const glm::vec4 data[2]); +}; + class Plane : public Shape { void create_impl(float w, float h, int div, GLushort* idx, vertex_t* vertices);