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