diff --git a/engine.vcxproj b/engine.vcxproj
index 0981fa3..79859e0 100644
--- a/engine.vcxproj
+++ b/engine.vcxproj
@@ -170,6 +170,7 @@
+
diff --git a/engine.vcxproj.filters b/engine.vcxproj.filters
index 9be1bad..8e1b527 100644
--- a/engine.vcxproj.filters
+++ b/engine.vcxproj.filters
@@ -225,6 +225,9 @@
Source Files\ui
+
+ Source Files
+
diff --git a/engine/app.h b/engine/app.h
index 1b228ca..c455d4a 100644
--- a/engine/app.h
+++ b/engine/app.h
@@ -127,4 +127,6 @@ public:
void dialog_export();
void dialog_layer_rename();
void brush_update();
+
+ void cmd_convert(std::string pano_path, std::string out_path);
};
diff --git a/engine/app_commands.cpp b/engine/app_commands.cpp
new file mode 100644
index 0000000..4b36728
--- /dev/null
+++ b/engine/app_commands.cpp
@@ -0,0 +1,16 @@
+#include "pch.h"
+#include "app.h"
+#include "canvas.h"
+
+void App::cmd_convert(std::string pano_path, std::string out_path)
+{
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_PROGRAM_POINT_SIZE);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glBlendEquation(GL_FUNC_ADD);
+
+ ui::Canvas* canvas = new ui::Canvas;
+ canvas->create(CANVAS_RES, CANVAS_RES);
+ canvas->project_open_thread(pano_path);
+ canvas->export_equirectangular_thread(out_path);
+}
diff --git a/engine/app_dialogs.cpp b/engine/app_dialogs.cpp
index 61875a8..ba10df2 100644
--- a/engine/app_dialogs.cpp
+++ b/engine/app_dialogs.cpp
@@ -144,7 +144,7 @@ void App::dialog_export()
{
if (canvas)
{
- canvas->m_canvas->export_equirectangular(data_path);
+ canvas->m_canvas->export_equirectangular(data_path + "/" + doc_name + ".jpg");
}
}
diff --git a/engine/canvas.cpp b/engine/canvas.cpp
index 8f8e411..6971350 100644
--- a/engine/canvas.cpp
+++ b/engine/canvas.cpp
@@ -790,15 +790,20 @@ void ui::Canvas::export_equirectangular_thread(std::string data_path)
gl_state gl;
App::I.async_start();
- auto pb = std::make_shared();
- pb->m_manager = &App::I.layout;
- pb->init();
- pb->create();
- pb->loaded();
- pb->m_progress->SetWidthP(0);
- pb->m_title->set_text("Export Pano Image");
- App::I.layout[App::I.main_id]->add_child(pb);
- App::I.async_update();
+
+ std::shared_ptr pb;
+ if (App::I.layout.m_loaded)
+ {
+ pb = std::make_shared();
+ pb->m_manager = &App::I.layout;
+ pb->init();
+ pb->create();
+ pb->loaded();
+ pb->m_progress->SetWidthP(0);
+ pb->m_title->set_text("Export Pano Image");
+ App::I.layout[App::I.main_id]->add_child(pb);
+ App::I.async_update();
+ }
// save viewport and clear color states
GLint vp[4];
@@ -861,11 +866,15 @@ void ui::Canvas::export_equirectangular_thread(std::string data_path)
progress++;
float p = (float)progress / total * 100.f;
- pb->m_progress->SetWidthP(p);
LOG("progress: %f", p);
- gl.save();
- App::I.async_update();
- gl.restore();
+
+ if (App::I.layout.m_loaded)
+ {
+ pb->m_progress->SetWidthP(p);
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ }
}
//auto data = std::make_unique(m_tmp[0].bytes());
@@ -898,15 +907,19 @@ void ui::Canvas::export_equirectangular_thread(std::string data_path)
{
progress++;
float p = (float)progress / total * 100.f;
- pb->m_progress->SetWidthP(p);
LOG("progress: %f", p);
- gl.save();
- App::I.async_update();
- gl.restore();
+
+ if (App::I.layout.m_loaded)
+ {
+ pb->m_progress->SetWidthP(p);
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ }
}
static char name[128];
- sprintf(name, "%s/latlong.jpg", data_path.c_str());
+ sprintf(name, "%s", data_path.c_str());
LOG("writing %s", name);
jpge::params params;
params.m_quality = 100;
@@ -916,11 +929,15 @@ void ui::Canvas::export_equirectangular_thread(std::string data_path)
{
progress++;
float p = (float)progress / total * 100.f;
- pb->m_progress->SetWidthP(p);
LOG("progress: %f", p);
- gl.save();
- App::I.async_update();
- gl.restore();
+
+ if (App::I.layout.m_loaded)
+ {
+ pb->m_progress->SetWidthP(p);
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ }
}
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
@@ -949,8 +966,11 @@ void ui::Canvas::export_equirectangular_thread(std::string data_path)
glClearColor(cc[0], cc[1], cc[2], cc[3]);
glActiveTexture(GL_TEXTURE0);
- pb->destroy();
- App::I.async_update();
+ if (App::I.layout.m_loaded)
+ {
+ pb->destroy();
+ App::I.async_update();
+ }
App::I.async_end();
}
@@ -1242,19 +1262,23 @@ void ui::Canvas::project_open_thread(std::string data_path)
}
gl_state gl;
- App::I.async_start();
- auto pb = std::make_shared();
- pb->m_manager = &App::I.layout;
- pb->init();
- pb->create();
- pb->loaded();
- pb->m_progress->SetWidthP(0);
- pb->m_title->set_text("Opening Pano Project");
- App::I.layout[App::I.main_id]->add_child(pb);
- gl.save();
- App::I.async_update();
- gl.restore();
- App::I.async_end();
+ std::shared_ptr pb;
+ if (App::I.layout.m_loaded)
+ {
+ App::I.async_start();
+ pb = std::make_shared();
+ pb->m_manager = &App::I.layout;
+ pb->init();
+ pb->create();
+ pb->loaded();
+ pb->m_progress->SetWidthP(0);
+ pb->m_title->set_text("Opening Pano Project");
+ App::I.layout[App::I.main_id]->add_child(pb);
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ App::I.async_end();
+ }
LOG("skip thumb");
// skip thumbnail
@@ -1315,15 +1339,20 @@ void ui::Canvas::project_open_thread(std::string data_path)
std::copy(rgba, rgba + (imgw*imgh * 4), snap.image[plane_index].get());
delete rgba;
}
+
progress++;
float p = (float)progress / total * 100.f;
LOG("progress: %f", p);
- App::I.async_start();
- pb->m_progress->SetWidthP(p);
- gl.save();
- App::I.async_update();
- gl.restore();
- App::I.async_end();
+
+ if (App::I.layout.m_loaded)
+ {
+ App::I.async_start();
+ pb->m_progress->SetWidthP(p);
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ App::I.async_end();
+ }
}
App::I.async_start();
@@ -1333,14 +1362,19 @@ void ui::Canvas::project_open_thread(std::string data_path)
m_order.push_back(n_order);
App::I.async_end();
}
+
fclose(fp);
LOG("project restore from %s", data_path.c_str());
- App::I.async_start();
- pb->destroy();
- gl.save();
- App::I.async_update();
- gl.restore();
- App::I.async_end();
+
+ if (App::I.layout.m_loaded)
+ {
+ App::I.async_start();
+ pb->destroy();
+ gl.save();
+ App::I.async_update();
+ gl.restore();
+ App::I.async_end();
+ }
}
ui::Image ui::Canvas::thumbnail_generate(int w, int h)
diff --git a/engine/canvas.h b/engine/canvas.h
index 87b686b..901a3b0 100644
--- a/engine/canvas.h
+++ b/engine/canvas.h
@@ -9,6 +9,8 @@
NS_START
+#define CANVAS_RES 2048
+
class Layer
{
public:
diff --git a/engine/main.cpp b/engine/main.cpp
index 9846bd7..a64d219 100644
--- a/engine/main.cpp
+++ b/engine/main.cpp
@@ -333,10 +333,23 @@ int main(int argc, char** argv)
}
else
{
- // If not supported, go fuck yourself we are not gonna use that shit
+ // If not supported, go fuck yourself we are not gonna support your shitty device
return -1; // A negative number because you are a negative one
}
+ if (argc > 1)
+ {
+ switch (const_hash(argv[1]))
+ {
+ case const_hash("convert"):
+ App::I.initShaders();
+ App::I.cmd_convert(argv[2], argv[3]);
+ return 0;
+ default:
+ break;
+ }
+ }
+
App::I.init();
ShowWindow(hWnd, SW_NORMAL);
@@ -402,7 +415,6 @@ int main(int argc, char** argv)
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
- async_locker lock;
static bool leftDown = false;
static DWORD lastTime;
static POINT lastPoint;
@@ -420,6 +432,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
auto h = (float)HIWORD(lp);
if (h != 0)
{
+ async_locker lock;
App::I.resize(w, h);
App::I.clear();
App::I.redraw = true;
@@ -439,18 +452,25 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
break;
case WM_SYSKEYDOWN:
case WM_KEYDOWN:
+ async_lock();
keys[wp] = true;
App::I.key_down(convert_key((int)wp));
+ async_unlock();
break;
case WM_SYSKEYUP:
case WM_KEYUP:
+ async_lock();
keys[wp] = false;
App::I.key_up(convert_key((int)wp));
+ async_unlock();
break;
case WM_CHAR:
+ async_lock();
App::I.key_char((int)wp);
+ async_unlock();
break;
case WM_MOUSEMOVE:
+ async_lock();
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
if (0 && leftDown)
{
@@ -500,32 +520,42 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{
App::I.mouse_move((float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), WacomTablet::I.get_pressure(), kEventSource::Mouse);
}
+ async_unlock();
break;
case WM_LBUTTONDOWN:
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
+ async_lock();
leftDown = true;
SetCapture(hWnd);
lastTime = GetMessageTime();
lastPoint = { GET_X_LPARAM(lp), GET_Y_LPARAM(lp) };
App::I.mouse_down(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), WacomTablet::I.get_pressure(), kEventSource::Mouse);
+ async_unlock();
break;
case WM_LBUTTONUP:
+ async_lock();
WacomTablet::I.reset_pressure();
//TODO: find a way to check if event is mouse/stylus. For now use Mouse for all
App::I.mouse_up(0, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
ReleaseCapture();
leftDown = false;
+ async_unlock();
break;
case WM_RBUTTONDOWN:
+ async_lock();
App::I.mouse_down(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), 1.f, kEventSource::Mouse);
SetCapture(hWnd);
+ async_unlock();
break;
case WM_RBUTTONUP:
+ async_lock();
App::I.mouse_up(1, (float)GET_X_LPARAM(lp), (float)GET_Y_LPARAM(lp), kEventSource::Mouse);
ReleaseCapture();
+ async_unlock();
break;
case WM_MOUSEWHEEL:
{
+ async_locker lock;
POINT pt;
pt.x = GET_X_LPARAM(lp);
pt.y = GET_Y_LPARAM(lp);
diff --git a/engine/node_canvas.cpp b/engine/node_canvas.cpp
index a2b7c8d..8ae512a 100644
--- a/engine/node_canvas.cpp
+++ b/engine/node_canvas.cpp
@@ -2,8 +2,6 @@
#include "log.h"
#include "node_canvas.h"
-#define RES 2048
-
Node* NodeCanvas::clone_instantiate() const
{
return new NodeCanvas();
@@ -13,7 +11,7 @@ void NodeCanvas::init()
{
m_mouse_ignore = false;
m_canvas = std::make_unique();
- m_canvas->create(RES, RES);
+ m_canvas->create(CANVAS_RES, CANVAS_RES);
m_sampler.create(GL_NEAREST);
m_sampler_linear.create(GL_LINEAR);
m_sampler_stencil.create(GL_LINEAR, GL_REPEAT);
@@ -29,7 +27,7 @@ void NodeCanvas::init()
void NodeCanvas::restore_context()
{
Node::restore_context();
- m_canvas->create(RES, RES);
+ m_canvas->create(CANVAS_RES, CANVAS_RES);
m_sampler.create(GL_NEAREST);
m_face_plane.create<1>(2, 2);
m_canvas->snapshot_restore();