added camera pan for parallax and improved line drawing with preview line

This commit is contained in:
2017-05-06 23:22:34 +01:00
parent 427dd66976
commit f800df6cf5
10 changed files with 183 additions and 22 deletions

View File

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

View File

@@ -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" />

View File

@@ -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>

View File

@@ -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()
{

View File

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

View File

@@ -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;
}
}

View File

@@ -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;
};

View File

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

View File

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

View File

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