disable exceptions in visual studio, use xK notation for resolution, upgrade up to 32K resolution, mask resolution not doubled anymore, transform interactive controls to move, scale and rotate the selection

This commit is contained in:
2018-11-22 19:07:14 +01:00
parent 6f9b1b1c23
commit 86656cc7e3
12 changed files with 218 additions and 146 deletions

View File

@@ -114,6 +114,7 @@
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
@@ -155,6 +156,7 @@
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<ExceptionHandling>false</ExceptionHandling>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>

View File

@@ -419,11 +419,11 @@
<text text="Resize Document Resolution" font-face="arial" font-size="11"></text>
</border>
<border width="500" color="0 0 0 .9" pad="10" dir="col">
<text text="This action is permanent and cannot be undone.\nAll of the history will be cleared.\nResolution is measured in pixels per each face of the cube.\nThe output equirectangular will be Resolution x 4 times.\nExample: 1024px will generate a 4096x2048 equirectangular image." font-face="arial" font-size="11" margin="0 5 10 5"/>
<text text="This action is permanent and cannot be undone.\nAll of the history will be cleared." font-face="arial" font-size="11" margin="0 5 10 5"/>
<border dir="row" align="center" height="30" color=".2 .2 .2 1">
<node grow="1"><text id="current-res" text="Current: 1024px" font-face="arial" font-size="11" margin="0 5 0 5"/></node>
<node grow="1"><text id="current-res" text="Current: 2K" font-face="arial" font-size="11" margin="0 5 0 5"/></node>
<text text="New Resolution:" font-face="arial" font-size="11" margin="0 5 0 5"/>
<combobox id="resolution" width="100" height="30" text="1024" combo-list="512px,1024px,1536px,2048px" default="1"/>
<combobox id="resolution" width="100" height="30" text="2K" combo-list="2K,4K,6K,8K,16K,32K" default="1"/>
</border>
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">
<button id="btn-ok" text="Resize" width="70" height="30" margin="0 10 0 0"/>
@@ -560,11 +560,11 @@
<text text="Create New Pano Project" font-face="arial" font-size="11"></text>
</border>
<border width="500" color="0 0 0 .9" pad="10" dir="col">
<text text="Note: resolution is measured in pixels per each face of the cube.\nThe output equirectangular will be Resolution x 4 times.\nExample: 1024px will generate a 4096x2048 equirectangular image." font-face="arial" font-size="11" margin="0 5 10 5"/>
<text text="Note: resolution is measured in K-pixels, so a 2K document produces\na 2048x1024 equirectangular output." font-face="arial" font-size="11" margin="0 5 10 5"/>
<border dir="row" align="center" height="30" color=".2 .2 .2 1">
<text text="Project name: " font-face="arial" font-size="11" margin="0 5 0 5"/>
<text-input id="txt-input" align="center" pad="5" grow="1" height="30" color=".3"/>
<combobox id="resolution" width="100" height="30" text="1024" combo-list="512px,1024px,1536px,2048px" default="1"/>
<combobox id="resolution" width="100" height="30" text="2K" combo-list="2K,4K,6K,8K,16K,32K" default="1"/>
</border>
<text os="win,osx" id="path" text="Workind dir: path" text-wrap-width="470" font-face="arial" font-size="11" margin="10 5 10 5"/>
<node height="40" grow="1" dir="row" align="flex-end" justify="flex-end">

View File

@@ -606,6 +606,21 @@ void App::update_rec_frames()
}
}
int App::res_from_index(int i)
{
return res_map[i];
}
int App::res_to_index(int res)
{
return std::distance(res_map.begin(), std::find(res_map.begin(), res_map.end(), res));
}
std::string App::res_to_string(int res)
{
return res_map_str[res_to_index(res)];
}
void App::rec_clear()
{
rec_stop();

View File

@@ -71,6 +71,8 @@ public:
Node* current_panel = nullptr;
NodeScroll* panels;
const uint16_t main_id = const_hash("main");
const std::array<int, 6> res_map{ 512, 1024, 1536, 2048, 4096, 8192 };
const std::array<std::string, 6> res_map_str{ "2K", "4K", "6K", "8K", "16K", "32K" };
std::string doc_name = "no-name";
std::string doc_path;
std::string doc_dir;
@@ -192,6 +194,9 @@ public:
void title_update();
void update_memory_usage(size_t bytes);
void update_rec_frames();
int res_from_index(int i);
int res_to_index(int res);
std::string res_to_string(int res);
void cmd_convert(std::string pano_path, std::string out_path);
};

View File

@@ -99,7 +99,7 @@ void App::dialog_newdoc()
}
auto action = [this, dialog, name, path] {
std::array<int, 4> resolutions{ 512, 1024, 1536, 2048 };
std::array<int, 6> resolutions{ 512, 1024, 1536, 2048, 4096, 8192 };
int res = resolutions[dialog->m_resolution->m_current_index];
doc_name = name;
doc_path = path;

View File

@@ -14,7 +14,7 @@ static glm::vec4 color_button_hlight{ 1, .0, .0, 1 };
void App::title_update()
{
static char str[256];
snprintf(str, 256, "Panodoc: %s%s (%dpx)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", canvas->m_canvas->m_width);
snprintf(str, 256, "Panodoc: %s%s (%s)", doc_name.c_str(), canvas->m_canvas->m_unsaved ? "*" : "", res_to_string(canvas->m_canvas->m_width).c_str());
if (auto docname = layout[main_id]->find<NodeText>("txt-docname"))
docname->set_text(str);
}

View File

@@ -78,7 +78,7 @@ bool ui::BrushMesh::create()
if (!(buffers[0] && buffers[1] && buffers[2]))
return false;
static instance_t inst{ glm::mat4(), .1f };
static instance_t inst{ glm::mat4(1), .1f };
glBindBuffer(GL_ARRAY_BUFFER, buffers[2]);
glBufferData(GL_ARRAY_BUFFER, sizeof(instance_t), &inst, GL_STATIC_DRAW);

View File

@@ -1010,7 +1010,7 @@ void ui::Canvas::resize(int width, int height)
}
for (auto& l : m_layers)
l.resize(width, height);
m_smask.create(width*2, height*2, "mask");
m_smask.create(width, height, "mask");
m_unsaved = true;
}
bool ui::Canvas::create(int width, int height)
@@ -1046,7 +1046,7 @@ bool ui::Canvas::create(int width, int height)
{
l.create(width, height, "");
}
m_smask.create(width*2, height*2, "mask");
m_smask.create(width, height, "mask");
//m_smask.clear({1, 1, 1, 1});
m_unsaved = true;
return true;

View File

@@ -449,7 +449,7 @@ void CanvasModeMaskFree::init()
void CanvasModeMaskFree::leave()
{
// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(), std::placeholders::_1, std::placeholders::_2));
// canvas->draw_objects(std::bind(&CanvasModeFill::on_Draw, this, glm::mat4(1), std::placeholders::_1, std::placeholders::_2));
// m_points.clear();
}
@@ -843,65 +843,91 @@ void CanvasModeTransform::init()
{
m_sphere.create(1.f, glm::radians(-10.f), glm::radians(10.f), glm::radians(-10.f), glm::radians(10.f), 1.f);
m_circle.create<16>(1.f);
m_shape.create();
for (int i = 0; i < 6; i++)
m_shape[i].create();
m_xform = glm::mat4(1);
m_xform_local = glm::mat4(1);
}
void CanvasModeTransform::enter()
{
auto m = static_cast<CanvasModeMaskFree*>(canvas->modes[(int)ui::Canvas::kCanvasMode::MaskFree][0]);
int plane = 0;
auto face = canvas->face_to_shape2D(plane);
auto shape2d = poly_intersect(m->m_points2d, face);
std::vector<vertex_t> shape3d;
shape3d.reserve(shape2d.size());
glm::vec2 bb_min(canvas->m_size);
glm::vec2 bb_max(0, 0);
glm::vec2 midpoint(0);
for (auto p2d : shape2d)
{
//p2d.y = canvas->m_box.w - p2d.y - 1;
auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f) * glm::vec2(1, -1);
auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = (-xy(p3d_plane) / p3d_plane.z)/* * glm::vec2(-1, 1)*/;
auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * canvas->m_size;
auto p3d_world = canvas->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1);
bb_min = glm::min(bb_min, p2d_plane_raster);
bb_max = glm::max(bb_max, p2d_plane_raster);
//p2d.y = canvas->m_box.w - p2d.y - 1;
midpoint += p2d;
glm::vec3 pt_o, pt_d;
canvas->point_unproject(p2d, pt_o, pt_d);
canvas->m_smask_active = false;
auto points = std::move(m->m_points2d);
vertex_t v;
v.pos = glm::vec4(xyz(p3d_world), 1);
v.uvs = p2d_plane_raster;
shape3d.push_back(v);
glm::vec2 bb_min(FLT_MAX);
glm::vec2 bb_max(-FLT_MAX);
for (auto p2d : points)
{
bb_min = glm::min(bb_min, p2d);
bb_max = glm::max(bb_max, p2d);
}
auto bb_sz = bb_max - bb_min;
auto bb_center = (bb_min + bb_max) * 0.5f;
midpoint = midpoint / (float)shape2d.size();
auto center3d = canvas->point_trace(midpoint);
glm::vec2 midpoint = (bb_min + bb_max) * 0.5f;
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
m_xform = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up));
for (auto& v : shape3d)
{
v.uvs = (v.uvs - bb_min) / bb_sz;
v.pos = m_xform * v.pos;
}
auto center_mat = glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up));
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(midpoint), xyz(cam_up)));
m_xform_local = glm::mat4(1);
corners.clear();
corners.emplace_back(bb_min, 0);
corners.emplace_back(bb_max, 0);
corners.emplace_back(bb_max.x, bb_min.y, 0);
corners.emplace_back(bb_min.x, bb_max.y, 0);
corners.emplace_back(midpoint, 0);
corners.emplace_back(midpoint + (bb_max-bb_min) * glm::vec2(0.75f, 0), 0);
for (auto& c : corners)
c = center_mat * glm::vec4(canvas->point_trace(c), 1);
shape3d = canvas->triangulate(shape3d);
m_shape.update_vertices(shape3d.data(), shape3d.size());
for (int plane = 0; plane < 6; plane++)
{
auto face = canvas->face_to_shape2D(plane);
auto shape2d = poly_intersect(points, face);
if (shape2d.size() < 3)
{
m_shape[plane].update_vertices(nullptr, 0);
continue;
}
std::vector<vertex_t> shape3d;
shape3d.reserve(shape2d.size());
glm::vec2 bb_min(canvas->m_size);
glm::vec2 bb_max(0, 0);
for (auto p2d : shape2d)
{
p2d.y = canvas->m_box.w - p2d.y - 1;
auto p2d_clip = ((p2d / zw(canvas->m_box)) * 2.f - 1.f);
auto p3d_plane = canvas->m_plane_unproject[plane] * glm::vec4(p2d_clip, 0, 1);
auto p2d_plane = (-xy(p3d_plane) / p3d_plane.z);
auto p2d_plane_raster = (p2d_plane * 0.5f + 0.5f) * canvas->m_size;
auto p3d_world = canvas->m_plane_transform[plane] * glm::vec4(p2d_plane, -1, 1);
bb_min = glm::min(bb_min, p2d_plane_raster);
bb_max = glm::max(bb_max, p2d_plane_raster);
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer();
m_tex.create(bb_sz.x, bb_sz.y);
m_tex.bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_tex.unbind();
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer();
//glm::vec3 pt_o, pt_d;
//canvas->point_unproject(p2d, pt_o, pt_d);
vertex_t v;
v.pos = glm::vec4(xyz(p3d_world), 1);
v.uvs = p2d_plane_raster;
shape3d.push_back(v);
}
auto bb_sz = bb_max - bb_min;
auto bb_center = (bb_min + bb_max) * 0.5f;
auto center3d = canvas->point_trace(midpoint);
for (auto& v : shape3d)
{
v.uvs = (v.uvs - bb_min) / bb_sz;
v.pos = center_mat * v.pos;
}
shape3d = canvas->triangulate(shape3d);
m_shape[plane].update_vertices(shape3d.data(), shape3d.size());
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].bindFramebuffer();
m_tex[plane].create(bb_sz.x, bb_sz.y);
m_tex[plane].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
m_tex[plane].unbind();
canvas->m_layers[canvas->m_current_layer_idx].m_rtt[plane].unbindFramebuffer();
}
}
void CanvasModeTransform::leave()
@@ -926,18 +952,21 @@ void CanvasModeTransform::leave()
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), canvas->m_plane_origin[i], canvas->m_plane_tangent[i]);
layer.m_rtt[i].bindFramebuffer();
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape.draw_fill();
for (int j = 0; j < 6; j++)
{
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape[j].draw_fill();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform);
m_tex.bind();
canvas->m_sampler.bind(0);
m_shape.draw_fill();
m_tex.unbind();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * plane_camera * m_xform * m_xform_local);
m_tex[j].bind();
canvas->m_sampler.bind(0);
m_shape[j].draw_fill();
m_tex[j].unbind();
}
layer.m_rtt[i].unbindFramebuffer();
}
@@ -971,34 +1000,42 @@ void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj,
auto face = canvas->face_to_shape2D(0);
auto shape = poly_intersect(m->m_points2d, face);
// for (auto pt : shape)
// {
// pt.y = canvas->m_box.w - pt.y - 1;
// ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho * glm::translate(glm::vec3(pt, 0)) * glm::scale(glm::vec3(5.f)));
// ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, 1 });
// m_circle.draw_fill();
// }
//ui::ShaderManager::use(ui::kShader::UVs);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape.draw_fill();
glEnable(GL_BLEND);
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform);
glActiveTexture(GL_TEXTURE0);
m_tex.bind();
canvas->m_sampler.bind(0);
m_shape.draw_fill();
m_tex.unbind();
for (int i = 0; i < 6; i++)
{
//ui::ShaderManager::use(ui::kShader::UVs);
ui::ShaderManager::use(ui::kShader::Color);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform * m_xform_local);
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 1, 1, .1 });
m_shape[i].draw_fill();
ui::ShaderManager::use(ui::kShader::Texture);
ui::ShaderManager::u_int(ui::kShaderUniform::Tex, 0);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, proj * camera * m_xform * m_xform_local);
glActiveTexture(GL_TEXTURE0);
m_tex[i].bind();
canvas->m_sampler.bind(0);
m_shape[i].draw_fill();
m_tex[i].unbind();
}
auto m2d = canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
auto c2d = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
ui::ShaderManager::u_mat4(ui::kShaderUniform::MVP, ortho * glm::translate(glm::vec3(c2d, 0)) * glm::scale(glm::vec3(10.f)));
ui::ShaderManager::u_vec4(ui::kShaderUniform::Col, { 0, 0, 0, i == corner_hl ? 1.f : .5f });
m_circle.draw_fill();
}
if (depth) glEnable(GL_DEPTH_TEST);
}
void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
{
auto m2d = glm::scale(glm::vec3(1, -1, 1)) * canvas->m_proj * canvas->m_mv * m_xform * m_xform_local;
switch (me->m_type)
{
case kEventType::MouseDownR:
@@ -1009,21 +1046,57 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
m_dragging = false;
break;
case kEventType::MouseDownL:
m_dragging = true;
m_drag_start = loc;
m_drag_xform = m_xform;
//m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), { 0, 1, 0 }));
if (corner_hl != -1)
{
m_dragging = true;
m_drag_start = loc;
m_drag_xform = m_xform;
m_drag_xform_local = m_xform_local;
m_drag_corner = corner_hl;
m_drag_corners2d = corners2d;
if (m_drag_corner < 4)
{
m_drag_diag = glm::distance(corners2d[4], corners2d[m_drag_corner]);
}
}
break;
case kEventType::MouseMove:
{
corner_hl = -1;
corners2d.resize(corners.size());
for (int i = 0; i < corners.size(); i++)
{
auto c = m2d * glm::vec4(corners[i], 1);
corners2d[i] = ((xy(c) / c.z) * 0.5f + 0.5f) * zw(canvas->m_box);
float d = glm::distance(corners2d[i], loc);
if (d < 10)
corner_hl = i;
}
if (m_dragging)
{
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
//auto diff = glm::radians(loc - m_drag_start) * 0.1f;
//auto m = glm::eulerAngleXY(-diff.y, -diff.x);
//m_xform = m * m_drag_xform;
auto cam_up = glm::inverse(canvas->m_mv) * glm::vec4(0, 1, 0, 1);
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up)));
if (m_drag_corner > -1 && m_drag_corner < 4)
{
auto diag = glm::distance(corners2d[4], loc);
auto scale = diag / m_drag_diag;
m_xform_local = m_drag_xform_local * glm::scale(glm::vec3(scale, scale, 1));
}
if (m_drag_corner == 4)
{
m_xform = glm::inverse(glm::lookAt({ 0, 0, 0 }, canvas->point_trace(loc), xyz(cam_up)));
}
if (m_drag_corner == 5)
{
auto a = glm::normalize(m_drag_corners2d[m_drag_corner] - m_drag_corners2d[4]);
auto b = glm::normalize(loc - m_drag_corners2d[4]);
auto angle = glm::orientedAngle(a, b);
m_xform_local = m_drag_xform_local * glm::eulerAngleZ(-angle);
}
}
/*
{
auto p2d = loc;
//p2d.y = canvas->m_box.w - p2d.y - 1;
@@ -1034,39 +1107,7 @@ void CanvasModeTransform::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
int x = 0;
LOG("pt %f %f %f %f", p2d_plane.x, p2d_plane.y, p2d_plane.z, p2d_plane.w);
}
auto m = glm::lookAt(glm::vec3(0), m_origin, { 0, 1, 0 });
m_center_point = m * glm::vec4(canvas->project2Dpoint(loc), 1);
float r = glm::length(m_center_point);
float lat = glm::acos(m_center_point.z / r);
float lon = glm::atan(m_center_point.y, m_center_point.x);
m_center_point_uv = { lat, lon };
//LOG("pt lat-lon %f %f", lat, lon);
auto face = canvas->face_to_shape2D(0);
if (face.size() > 2)
{
std::vector<vertex_t> quad{
vertex_t{{200, 200}, {0, 0}},
vertex_t{{200, 400}, {0, 1}},
vertex_t{{400, 400}, {1, 1}},
vertex_t{{400, 200}, {1, 0}},
};
auto poly = poly_intersect(quad, face);
m_points2d.clear();
if (!poly.empty())
{
std::vector<std::shared_ptr<p2t::Point>> points;
for (auto& v : poly)
{
v.pos.y = canvas->m_box.w - v.pos.y - 1;
m_points2d.push_back(v.pos);
points.push_back(std::make_shared<p2t::Point>(v.pos.x, v.pos.y));
}
auto vert = canvas->triangulate(poly);
//m_shape.update_vertices(vert.data(), vert.size());
}
}
*/
}
break;

View File

@@ -21,6 +21,8 @@ public:
virtual void init() {}
virtual void enter() {}
virtual void leave() {}
CanvasMode() = default;
virtual ~CanvasMode() = default;
};
class CanvasModeBasicCamera : public CanvasMode
@@ -146,26 +148,34 @@ public:
class CanvasModeTransform : public CanvasMode
{
ui::DynamicShape m_shape;
ui::Sphere m_sphere;
ui::Circle m_circle;
Texture2D m_tex;
ui::DynamicShape m_shape[6]{};
ui::Sphere m_sphere{};
ui::Circle m_circle{};
Texture2D m_tex[6]{};
glm::vec3 m_origin{0, 0, 1 };
glm::vec3 m_center_point;
glm::vec2 m_center_point_uv;
glm::mat4 m_xform;
std::vector<glm::vec3> corners{};
std::vector<glm::vec2> corners2d{};
int corner_hl = -1;
glm::vec3 m_center_point{};
glm::vec2 m_center_point_uv{};
glm::mat4 m_xform{};
glm::mat4 m_xform_local{};
int m_counter = 0;
bool m_dragging = false;
glm::vec2 m_drag_start;
glm::mat4 m_drag_xform;
std::vector<vertex_t> m_points;
std::vector<glm::vec2> m_points2d;
std::map<int, int> m_dirty_planes;
int m_drag_corner = -1;
float m_drag_diag = 0;
std::vector<glm::vec2> m_drag_corners2d{};
glm::vec2 m_drag_start{};
glm::mat4 m_drag_xform{};
glm::mat4 m_drag_xform_local{};
std::vector<vertex_t> m_points{};
std::vector<glm::vec2> m_points2d{};
std::map<int, int> m_dirty_planes{};
bool m_active_tool = false;
public:
CanvasModeTransform() = default;
virtual void on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera) override;;
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 on_MouseEvent(MouseEvent* me, glm::vec2& loc) override;
virtual void init() override;;
virtual void enter() override;
virtual void leave() override;

View File

@@ -34,7 +34,7 @@ void NodeDialogResize::init_controls()
text = find<NodeText>("current-res");
resolution = ui::Canvas::I->m_width;
static char txt[128];
sprintf(txt, "Current: %dpx", resolution);
sprintf(txt, "Current: %s", App::I.res_to_string(resolution));
text->set_text(txt);
btn_cancel->on_click = [this](Node*) {
destroy();
@@ -50,5 +50,5 @@ void NodeDialogResize::loaded()
int NodeDialogResize::get_resolution()
{
return combo ? res_map[combo->m_current_index] : 512;
return combo ? App::I.res_from_index(combo->m_current_index) : 512;
}

View File

@@ -7,7 +7,6 @@
class NodeDialogResize : public NodeBorder
{
public:
const std::array<int, 4> res_map{512, 1024, 1536, 2048};
NodeButton* btn_cancel;
NodeButton* btn_ok;
NodeComboBox* combo;