added camera pan for parallax and improved line drawing with preview line
This commit is contained in:
@@ -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
|
||||
)
|
||||
|
||||
@@ -156,6 +156,7 @@
|
||||
<ClCompile Include="engine\bezier.cpp" />
|
||||
<ClCompile Include="engine\brush.cpp" />
|
||||
<ClCompile Include="engine\canvas.cpp" />
|
||||
<ClCompile Include="engine\canvas_modes.cpp" />
|
||||
<ClCompile Include="engine\event.cpp" />
|
||||
<ClCompile Include="engine\font.cpp" />
|
||||
<ClCompile Include="engine\image.cpp" />
|
||||
@@ -199,6 +200,7 @@
|
||||
<ClInclude Include="engine\bezier.h" />
|
||||
<ClInclude Include="engine\brush.h" />
|
||||
<ClInclude Include="engine\canvas.h" />
|
||||
<ClInclude Include="engine\canvas_modes.h" />
|
||||
<ClInclude Include="engine\event.h" />
|
||||
<ClInclude Include="engine\font.h" />
|
||||
<ClInclude Include="engine\image.h" />
|
||||
|
||||
@@ -78,6 +78,9 @@
|
||||
<ClCompile Include="engine\event.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="engine\canvas_modes.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="engine\app.h">
|
||||
@@ -134,5 +137,8 @@
|
||||
<ClInclude Include="engine\keymap.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="engine\canvas_modes.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -7,6 +7,7 @@ std::vector<CanvasMode*> 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()
|
||||
{
|
||||
|
||||
@@ -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<CanvasMode*> modes[];
|
||||
std::vector<CanvasMode*>* m_mode;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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<ui::Canvas>();
|
||||
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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user