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);