remove all async_start/end calls
This commit is contained in:
157
src/app.cpp
157
src/app.cpp
@@ -566,22 +566,87 @@ bool App::update_ui_observer(Node *n)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::update(float dt)
|
void App::draw(float dt)
|
||||||
{
|
{
|
||||||
static std::mutex mutex;
|
|
||||||
static float rec_timer = 0.f;
|
|
||||||
static float reload_timer = 0.f;
|
|
||||||
|
|
||||||
// avoid multiple threads to update the scene
|
|
||||||
std::lock_guard<std::mutex> lock(mutex);
|
|
||||||
|
|
||||||
static std::mutex m;
|
|
||||||
std::lock_guard<std::mutex> _lock(m);
|
|
||||||
|
|
||||||
// update offscreen stuff
|
// update offscreen stuff
|
||||||
if (canvas && canvas->m_canvas)
|
if (canvas && canvas->m_canvas)
|
||||||
canvas->m_canvas->stroke_draw();
|
canvas->m_canvas->stroke_draw();
|
||||||
|
|
||||||
|
auto observer = std::bind(&App::update_ui_observer, this, std::placeholders::_1);
|
||||||
|
|
||||||
|
if (vr_active && ui_visible)
|
||||||
|
{
|
||||||
|
uirtt.bindFramebuffer();
|
||||||
|
uirtt.clear();
|
||||||
|
glViewport(0, 0, uirtt.getWidth(), uirtt.getHeight());
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
for (int i = 1; i < layout[main_id]->m_children.size(); i++)
|
||||||
|
layout[main_id]->m_children[i]->watch(observer);
|
||||||
|
//msgbox->watch(observer);
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
uirtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vr_only)
|
||||||
|
{
|
||||||
|
#if __IOS__
|
||||||
|
[ios_view->glview bindDrawable];
|
||||||
|
#else
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
#endif
|
||||||
|
glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
for (int i = 0; i < layout[main_id]->m_children.size(); i++)
|
||||||
|
layout[main_id]->m_children[i]->watch(observer);
|
||||||
|
//msgbox->watch(observer);
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec_running)
|
||||||
|
{
|
||||||
|
static float rec_timer = 0.f;
|
||||||
|
rec_timer += dt;
|
||||||
|
if (rec_timer > 1.f && canvas->m_canvas->m_dirty_stroke)
|
||||||
|
{
|
||||||
|
canvas->m_canvas->m_dirty_stroke = false;
|
||||||
|
|
||||||
|
LOG("rec tick");
|
||||||
|
rec_timer = 0.f;
|
||||||
|
|
||||||
|
auto data = new uint8_t[width * height * 4];
|
||||||
|
#if __IOS__
|
||||||
|
[ios_view->glview bindDrawable];
|
||||||
|
#else
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
GLint dfbo, rfbo;
|
||||||
|
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &rfbo);
|
||||||
|
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &dfbo);
|
||||||
|
if (dfbo != rfbo)
|
||||||
|
LOG("DIFFERENT FB");
|
||||||
|
|
||||||
|
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(rec_mutex);
|
||||||
|
rec_frames.emplace_back(data);
|
||||||
|
rec_cv.notify_all();
|
||||||
|
}
|
||||||
|
update_rec_frames();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
redraw = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void App::update(float dt)
|
||||||
|
{
|
||||||
|
static std::mutex mutex;
|
||||||
|
static float reload_timer = 0.f;
|
||||||
|
|
||||||
|
// avoid multiple threads to update the scene
|
||||||
|
//std::lock_guard<std::mutex> lock(mutex);
|
||||||
|
|
||||||
if (!(redraw || animate))
|
if (!(redraw || animate))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -620,71 +685,6 @@ void App::update(float dt)
|
|||||||
layout[main_id]->find<NodeButtonCustom>("btn-mask-line")->set_active(mode == kCanvasMode::MaskLine);
|
layout[main_id]->find<NodeButtonCustom>("btn-mask-line")->set_active(mode == kCanvasMode::MaskLine);
|
||||||
layout[main_id]->find<NodeButtonCustom>("btn-bucket")->set_active(mode == kCanvasMode::FloodFill);
|
layout[main_id]->find<NodeButtonCustom>("btn-bucket")->set_active(mode == kCanvasMode::FloodFill);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto observer = std::bind(&App::update_ui_observer, this, std::placeholders::_1);
|
|
||||||
|
|
||||||
if (vr_active && ui_visible)
|
|
||||||
{
|
|
||||||
uirtt.bindFramebuffer();
|
|
||||||
uirtt.clear();
|
|
||||||
glViewport(0, 0, uirtt.getWidth(), uirtt.getHeight());
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
for (int i = 1; i < layout[main_id]->m_children.size(); i++)
|
|
||||||
layout[main_id]->m_children[i]->watch(observer);
|
|
||||||
//msgbox->watch(observer);
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
uirtt.unbindFramebuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vr_only)
|
|
||||||
{
|
|
||||||
#if __IOS__
|
|
||||||
[ios_view->glview bindDrawable];
|
|
||||||
#else
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
#endif
|
|
||||||
glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height);
|
|
||||||
glEnable(GL_SCISSOR_TEST);
|
|
||||||
for (int i = 0; i < layout[main_id]->m_children.size(); i++)
|
|
||||||
layout[main_id]->m_children[i]->watch(observer);
|
|
||||||
//msgbox->watch(observer);
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rec_running)
|
|
||||||
{
|
|
||||||
rec_timer += dt;
|
|
||||||
if (rec_timer > 1.f && canvas->m_canvas->m_dirty_stroke)
|
|
||||||
{
|
|
||||||
canvas->m_canvas->m_dirty_stroke = false;
|
|
||||||
|
|
||||||
LOG("rec tick");
|
|
||||||
rec_timer = 0.f;
|
|
||||||
|
|
||||||
auto data = new uint8_t[width * height * 4];
|
|
||||||
#if __IOS__
|
|
||||||
[ios_view->glview bindDrawable];
|
|
||||||
#else
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GLint dfbo, rfbo;
|
|
||||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &rfbo);
|
|
||||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &dfbo);
|
|
||||||
if (dfbo != rfbo)
|
|
||||||
LOG("DIFFERENT FB");
|
|
||||||
|
|
||||||
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
|
||||||
{
|
|
||||||
std::lock_guard<std::mutex> lock(rec_mutex);
|
|
||||||
rec_frames.emplace_back(data);
|
|
||||||
rec_cv.notify_all();
|
|
||||||
}
|
|
||||||
update_rec_frames();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
redraw = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::terminate()
|
void App::terminate()
|
||||||
@@ -803,9 +803,7 @@ void App::rec_stop()
|
|||||||
rec_cv.notify_all();
|
rec_cv.notify_all();
|
||||||
if (rec_thread.joinable())
|
if (rec_thread.joinable())
|
||||||
rec_thread.join();
|
rec_thread.join();
|
||||||
async_start();
|
|
||||||
update_rec_frames();
|
update_rec_frames();
|
||||||
async_end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,7 +819,6 @@ void App::rec_export(std::string path)
|
|||||||
auto pb = layout[main_id]->add_child<NodeProgressBar>();
|
auto pb = layout[main_id]->add_child<NodeProgressBar>();
|
||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Exporting MP4 movie");
|
pb->m_title->set_text("Exporting MP4 movie");
|
||||||
async_update();
|
|
||||||
|
|
||||||
#if defined(__IOS__) || defined(__OSX__)
|
#if defined(__IOS__) || defined(__OSX__)
|
||||||
NSString* mov_path = [NSString stringWithFormat:@"%s/out.mp4", rec_path.c_str()];
|
NSString* mov_path = [NSString stringWithFormat:@"%s/out.mp4", rec_path.c_str()];
|
||||||
@@ -978,8 +975,6 @@ void App::rec_export(std::string path)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
async_update();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::rec_loop()
|
void App::rec_loop()
|
||||||
|
|||||||
@@ -165,6 +165,7 @@ public:
|
|||||||
void terminate();
|
void terminate();
|
||||||
void clear();
|
void clear();
|
||||||
void tick(float dt);
|
void tick(float dt);
|
||||||
|
void draw(float dt);
|
||||||
void update(float dt);
|
void update(float dt);
|
||||||
bool update_ui_observer(Node* n);
|
bool update_ui_observer(Node* n);
|
||||||
bool vr_start();
|
bool vr_start();
|
||||||
|
|||||||
@@ -22,24 +22,18 @@ void App::cloud_upload()
|
|||||||
{
|
{
|
||||||
auto upload_thread = [this] {
|
auto upload_thread = [this] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
|
|
||||||
if (Canvas::I->m_unsaved)
|
if (Canvas::I->m_unsaved)
|
||||||
{
|
{
|
||||||
Canvas::I->project_save_thread(doc_path);
|
Canvas::I->project_save_thread(doc_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
async_start();
|
|
||||||
auto pb = show_progress("Uploading");
|
auto pb = show_progress("Uploading");
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
|
|
||||||
upload(doc_path, doc_filename, [this,pb](float p){
|
upload(doc_path, doc_filename, [this,pb](float p){
|
||||||
async_start();
|
|
||||||
pb->m_progress->SetWidthP(p * 100.f);
|
pb->m_progress->SetWidthP(p * 100.f);
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async_start();
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
auto msgbox = new NodeMessageBox();
|
auto msgbox = new NodeMessageBox();
|
||||||
msgbox->m_manager = &layout;
|
msgbox->m_manager = &layout;
|
||||||
@@ -48,8 +42,6 @@ void App::cloud_upload()
|
|||||||
msgbox->m_message->set_text("This document has been succesfully uploaded.");
|
msgbox->m_message->set_text("This document has been succesfully uploaded.");
|
||||||
layout[main_id]->add_child(msgbox);
|
layout[main_id]->add_child(msgbox);
|
||||||
layout[main_id]->update();
|
layout[main_id]->update();
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auto m = layout[main_id]->add_child<NodeMessageBox>();
|
auto m = layout[main_id]->add_child<NodeMessageBox>();
|
||||||
@@ -59,14 +51,10 @@ void App::cloud_upload()
|
|||||||
m->btn_cancel->m_text->set_text("No");
|
m->btn_cancel->m_text->set_text("No");
|
||||||
m->btn_ok->on_click = [this, m, upload_thread](Node*) {
|
m->btn_ok->on_click = [this, m, upload_thread](Node*) {
|
||||||
std::thread(upload_thread).detach();
|
std::thread(upload_thread).detach();
|
||||||
async_start();
|
|
||||||
m->destroy();
|
m->destroy();
|
||||||
async_end();
|
|
||||||
};
|
};
|
||||||
m->btn_cancel->on_click = [this, m, upload_thread](Node*) {
|
m->btn_cancel->on_click = [this, m, upload_thread](Node*) {
|
||||||
async_start();
|
|
||||||
m->destroy();
|
m->destroy();
|
||||||
async_end();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -76,16 +64,14 @@ void App::cloud_upload_all()
|
|||||||
{
|
{
|
||||||
std::thread([this] {
|
std::thread([this] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
|
|
||||||
auto names = Asset::list_files(data_path, ".*\\.ppi");
|
auto names = Asset::list_files(data_path, ".*\\.ppi");
|
||||||
|
|
||||||
gl_state gl;
|
gl_state gl;
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
std::shared_ptr<NodeProgressBar> pb;
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
{
|
||||||
async_start();
|
|
||||||
pb = show_progress("Export Pano Image");
|
pb = show_progress("Export Pano Image");
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
@@ -102,21 +88,13 @@ void App::cloud_upload_all()
|
|||||||
|
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
{
|
||||||
async_start();
|
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
gl.save();
|
|
||||||
async_redraw();
|
|
||||||
gl.restore();
|
|
||||||
async_end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
{
|
||||||
async_start();
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
}
|
}
|
||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
@@ -143,38 +121,28 @@ void App::cloud_browse()
|
|||||||
dialog->destroy();
|
dialog->destroy();
|
||||||
std::thread([this, dialog] {
|
std::thread([this, dialog] {
|
||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
async_start();
|
|
||||||
auto* m = layout[main_id]->add_child<NodeMessageBox>();
|
auto* m = layout[main_id]->add_child<NodeMessageBox>();
|
||||||
m->m_title->set_text("Downloading");
|
m->m_title->set_text("Downloading");
|
||||||
m->m_message->set_text("Download in progress");
|
m->m_message->set_text("Download in progress");
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
std::string url = "https://panopainter.com/cloud/cloud-dwl.php?file=" + dialog->selected_file;
|
std::string url = "https://panopainter.com/cloud/cloud-dwl.php?file=" + dialog->selected_file;
|
||||||
download(url, dialog->selected_path, [this,m](float p){
|
download(url, dialog->selected_path, [this,m](float p){
|
||||||
static char progress[256];
|
static char progress[256];
|
||||||
sprintf(progress, "Download in progress %.2f%%", p * 100.f);
|
sprintf(progress, "Download in progress %.2f%%", p * 100.f);
|
||||||
async_start();
|
|
||||||
m->m_message->set_text(progress);
|
m->m_message->set_text(progress);
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
async_start();
|
|
||||||
canvas->reset_camera();
|
canvas->reset_camera();
|
||||||
layers->clear();
|
layers->clear();
|
||||||
async_end();
|
|
||||||
|
|
||||||
canvas->m_canvas->project_open_thread(dialog->selected_path);
|
canvas->m_canvas->project_open_thread(dialog->selected_path);
|
||||||
|
|
||||||
async_start();
|
|
||||||
doc_name = dialog->selected_name;
|
doc_name = dialog->selected_name;
|
||||||
title_update();
|
title_update();
|
||||||
for (auto& l : canvas->m_canvas->m_layers)
|
for (auto& l : canvas->m_canvas->m_layers)
|
||||||
layers->add_layer(l->m_name.c_str(), false);
|
layers->add_layer(l->m_name.c_str(), false);
|
||||||
ActionManager::clear();
|
ActionManager::clear();
|
||||||
m->destroy();
|
m->destroy();
|
||||||
async_redraw();
|
|
||||||
async_end();
|
|
||||||
}).detach();
|
}).detach();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1099,6 +1099,8 @@ void App::brush_update()
|
|||||||
{
|
{
|
||||||
// brushes->select_brush(canvas->m_brush->id);
|
// brushes->select_brush(canvas->m_brush->id);
|
||||||
// stroke->set_params(canvas->m_brush);
|
// stroke->set_params(canvas->m_brush);
|
||||||
|
render_task_async([this]
|
||||||
|
{
|
||||||
stroke->update_controls();
|
stroke->update_controls();
|
||||||
quick->m_slider_flow->set_value(stroke->m_tip_flow->get_value());
|
quick->m_slider_flow->set_value(stroke->m_tip_flow->get_value());
|
||||||
quick->m_slider_size->set_value(stroke->m_tip_size->get_value());
|
quick->m_slider_size->set_value(stroke->m_tip_size->get_value());
|
||||||
@@ -1109,6 +1111,7 @@ void App::brush_update()
|
|||||||
floating_picker->set_color(Canvas::I->m_current_brush->m_tip_color);
|
floating_picker->set_color(Canvas::I->m_current_brush->m_tip_color);
|
||||||
if (floating_color)
|
if (floating_color)
|
||||||
floating_color->set_color(Canvas::I->m_current_brush->m_tip_color);
|
floating_color->set_color(Canvas::I->m_current_brush->m_tip_color);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::init_menu_layer()
|
void App::init_menu_layer()
|
||||||
|
|||||||
292
src/canvas.cpp
292
src/canvas.cpp
@@ -179,6 +179,8 @@ void Canvas::stroke_cancel()
|
|||||||
}
|
}
|
||||||
void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||||
{
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
|
||||||
gl_state gl;
|
gl_state gl;
|
||||||
gl.save();
|
gl.save();
|
||||||
|
|
||||||
@@ -321,6 +323,8 @@ std::array<std::vector<vertex_t>, 6> Canvas::stroke_draw_project(std::array<vert
|
|||||||
|
|
||||||
glm::vec4 Canvas::stroke_draw_samples(int i, std::vector<vertex_t>& P)
|
glm::vec4 Canvas::stroke_draw_samples(int i, std::vector<vertex_t>& P)
|
||||||
{
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
{
|
{
|
||||||
glActiveTexture(GL_TEXTURE1);
|
glActiveTexture(GL_TEXTURE1);
|
||||||
@@ -454,6 +458,8 @@ std::vector<Canvas::StrokeFrame> Canvas::stroke_draw_compute(Stroke& stroke) con
|
|||||||
|
|
||||||
void Canvas::stroke_draw()
|
void Canvas::stroke_draw()
|
||||||
{
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
|
||||||
if (!(m_current_stroke && m_current_stroke->has_sample()))
|
if (!(m_current_stroke && m_current_stroke->has_sample()))
|
||||||
{
|
{
|
||||||
//stroke_draw_mix({ 0,0 }, { m_mixer.getWidth(), m_mixer.getHeight() });
|
//stroke_draw_mix({ 0,0 }, { m_mixer.getWidth(), m_mixer.getHeight() });
|
||||||
@@ -690,6 +696,8 @@ glm::vec3 Canvas::point_trace(glm::vec2 loc)
|
|||||||
}
|
}
|
||||||
void Canvas::stroke_commit()
|
void Canvas::stroke_commit()
|
||||||
{
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
|
||||||
if (!m_dirty || m_layers.empty())
|
if (!m_dirty || m_layers.empty())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -866,8 +874,8 @@ void Canvas::stroke_commit()
|
|||||||
|
|
||||||
void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
||||||
{
|
{
|
||||||
gl_state gl;
|
assert(App::I.is_render_thread());
|
||||||
gl.save();
|
|
||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
auto ortho = glm::ortho<float>(-0.5f, 0.5f, -0.5f, 0.5f, -1.f, 1.f);
|
auto ortho = glm::ortho<float>(-0.5f, 0.5f, -0.5f, 0.5f, -1.f, 1.f);
|
||||||
const auto& b = m_current_stroke->m_brush;
|
const auto& b = m_current_stroke->m_brush;
|
||||||
@@ -1112,8 +1120,6 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
|||||||
|
|
||||||
m_layers_merge.m_rtt[plane_index].unbindFramebuffer();
|
m_layers_merge.m_rtt[plane_index].unbindFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
gl.restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::stroke_update(glm::vec3 point, float pressure)
|
void Canvas::stroke_update(glm::vec3 point, float pressure)
|
||||||
@@ -1124,6 +1130,8 @@ void Canvas::stroke_update(glm::vec3 point, float pressure)
|
|||||||
}
|
}
|
||||||
void Canvas::stroke_start(glm::vec3 point, float pressure)
|
void Canvas::stroke_start(glm::vec3 point, float pressure)
|
||||||
{
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
|
||||||
// need to commit this now before starting a new stroke
|
// need to commit this now before starting a new stroke
|
||||||
if (m_current_stroke && m_commit_delayed)
|
if (m_current_stroke && m_commit_delayed)
|
||||||
{
|
{
|
||||||
@@ -1221,16 +1229,8 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
{
|
{
|
||||||
m_dirty = false;
|
m_dirty = false;
|
||||||
|
|
||||||
// save viewport and clear color states
|
App::I.render_task([&]
|
||||||
GLint vp[4];
|
{
|
||||||
GLfloat cc[4];
|
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
|
||||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
|
||||||
GLboolean blend = glIsEnabled(GL_BLEND);
|
|
||||||
|
|
||||||
// allocate action to add to history
|
|
||||||
auto action = new ActionStroke;
|
|
||||||
|
|
||||||
// prepare common states
|
// prepare common states
|
||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
@@ -1242,17 +1242,6 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
|
|
||||||
m_layers[dest_idx]->m_rtt[i].bindFramebuffer();
|
m_layers[dest_idx]->m_rtt[i].bindFramebuffer();
|
||||||
|
|
||||||
/*
|
|
||||||
// save image before commit
|
|
||||||
glm::vec2 box_sz = m_dirty_box[i].zw() - m_dirty_box[i].xy();
|
|
||||||
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
|
||||||
glReadPixels(m_dirty_box[i].x, m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
|
||||||
|
|
||||||
action->m_box[i] = m_dirty_box[i];
|
|
||||||
action->m_old_box[i] = m_layers[m_current_layer_idx]->m_dirty_box[i];
|
|
||||||
action->m_old_dirty[i] = m_layers[m_current_layer_idx]->m_dirty_face[i];
|
|
||||||
*/
|
|
||||||
|
|
||||||
auto& lbox = m_layers[dest_idx]->m_dirty_box[i];
|
auto& lbox = m_layers[dest_idx]->m_dirty_box[i];
|
||||||
lbox = glm::vec4(
|
lbox = glm::vec4(
|
||||||
glm::min(xy(m_layers[source_idx]->m_dirty_box[i]), xy(lbox)),
|
glm::min(xy(m_layers[source_idx]->m_dirty_box[i]), xy(lbox)),
|
||||||
@@ -1294,20 +1283,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
|
|
||||||
m_layers[dest_idx]->m_rtt[i].unbindFramebuffer();
|
m_layers[dest_idx]->m_rtt[i].unbindFramebuffer();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
// restore viewport and clear color states
|
|
||||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
/*
|
|
||||||
// save history
|
|
||||||
action->m_layer_idx = m_current_layer_idx;
|
|
||||||
action->m_canvas = this;
|
|
||||||
action->m_stroke = std::move(m_current_stroke);
|
|
||||||
ActionManager::add(action);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, FloodData& plane_data,
|
void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, FloodData& plane_data,
|
||||||
@@ -1611,26 +1587,25 @@ void Canvas::clear_context()
|
|||||||
|
|
||||||
void Canvas::import_equirectangular(std::string file_path, std::shared_ptr<Layer> layer /*= nullptr*/)
|
void Canvas::import_equirectangular(std::string file_path, std::shared_ptr<Layer> layer /*= nullptr*/)
|
||||||
{
|
{
|
||||||
std::thread t(&Canvas::import_equirectangular_thread, this, file_path, layer);
|
if (App::I.check_license())
|
||||||
|
{
|
||||||
|
std::thread t([=] {
|
||||||
|
BT_SetTerminate();
|
||||||
|
import_equirectangular_thread(file_path, layer);
|
||||||
|
});
|
||||||
t.detach();
|
t.detach();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::import_equirectangular_thread(std::string file_path, std::shared_ptr<Layer> layer /*= nullptr*/)
|
void Canvas::import_equirectangular_thread(std::string file_path, std::shared_ptr<Layer> layer /*= nullptr*/)
|
||||||
{
|
{
|
||||||
BT_SetTerminate();
|
|
||||||
|
|
||||||
Image img;
|
Image img;
|
||||||
if (!img.load_file(file_path))
|
if (!img.load_file(file_path))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
|
|
||||||
if (!layer)
|
if (!layer)
|
||||||
layer = m_layers[m_current_layer_idx];
|
layer = m_layers[m_current_layer_idx];
|
||||||
|
|
||||||
gl_state gl;
|
|
||||||
gl.save();
|
|
||||||
|
|
||||||
auto a = new ActionImportEquirect;
|
auto a = new ActionImportEquirect;
|
||||||
a->m_layer = layer;
|
a->m_layer = layer;
|
||||||
a->m_snap = std::make_shared<Layer::Snapshot>(layer->snapshot());
|
a->m_snap = std::make_shared<Layer::Snapshot>(layer->snapshot());
|
||||||
@@ -1642,14 +1617,15 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
|
|||||||
if (img.width == img.height / 6)
|
if (img.width == img.height / 6)
|
||||||
{
|
{
|
||||||
Texture2D tex;
|
Texture2D tex;
|
||||||
static GLint indices[] = { 5, 0, 4, 1, 2, 3 };
|
static const GLint indices[] = { 5, 0, 4, 1, 2, 3 };
|
||||||
static GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
static const GLint formats[] = { GL_RED, GL_RG, GL_RGB, GL_RGBA };
|
||||||
static GLint iformats[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
|
static const GLint iformats[] = { GL_R8, GL_RG8, GL_RGB8, GL_RGBA8 };
|
||||||
tex.create(img.width, img.width, iformats[img.comp - 1], formats[img.comp - 1]);
|
tex.create(img.width, img.width, iformats[img.comp - 1], formats[img.comp - 1]);
|
||||||
int stride = img.width * img.width * img.comp;
|
int stride = img.width * img.width * img.comp;
|
||||||
Plane plane;
|
Plane plane;
|
||||||
plane.create<1>(2, 2);
|
plane.create<1>(2, 2);
|
||||||
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
|
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
tex.update(img.m_data.get() + indices[i] * stride);
|
tex.update(img.m_data.get() + indices[i] * stride);
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -1661,15 +1637,16 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
|
|||||||
tex.unbind();
|
tex.unbind();
|
||||||
m_sampler.unbind();
|
m_sampler.unbind();
|
||||||
});
|
});
|
||||||
|
plane.destroy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Texture2D tex;
|
Texture2D tex;
|
||||||
tex.load_file(file_path);
|
tex.load_file(file_path);
|
||||||
Sphere sphere;
|
Sphere sphere;
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
sphere.create<64, 64>(2.f);
|
sphere.create<64, 64>(2.f);
|
||||||
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
|
draw_objects([&](const glm::mat4& camera, const glm::mat4& proj, int i) {
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
tex.bind();
|
tex.bind();
|
||||||
@@ -1681,15 +1658,13 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
|
|||||||
tex.unbind();
|
tex.unbind();
|
||||||
m_sampler.unbind();
|
m_sampler.unbind();
|
||||||
});
|
});
|
||||||
|
sphere.destroy();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
layer->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height);
|
layer->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height);
|
||||||
layer->m_dirty_face[i] = true;
|
layer->m_dirty_face[i] = true;
|
||||||
}
|
}
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::export_equirectangular(std::string file_path, std::function<void()> on_complete)
|
void Canvas::export_equirectangular(std::string file_path, std::function<void()> on_complete)
|
||||||
@@ -1708,10 +1683,6 @@ void Canvas::export_equirectangular(std::string file_path, std::function<void()>
|
|||||||
|
|
||||||
void Canvas::export_equirectangular_thread(std::string file_path)
|
void Canvas::export_equirectangular_thread(std::string file_path)
|
||||||
{
|
{
|
||||||
gl_state gl;
|
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
|
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
std::shared_ptr<NodeProgressBar> pb;
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
@@ -1723,28 +1694,12 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Export Pano Image");
|
pb->m_title->set_text("Export Pano Image");
|
||||||
App::I.layout[App::I.main_id]->add_child(pb);
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
App::I.async_update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// save viewport and clear color states
|
|
||||||
GLint vp[4];
|
|
||||||
GLfloat cc[4];
|
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
|
||||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
|
||||||
GLboolean blend = glIsEnabled(GL_BLEND);
|
|
||||||
|
|
||||||
// prepare common states
|
|
||||||
glViewport(0, 0, m_width, m_height);
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
RTT m_latlong;
|
RTT m_latlong;
|
||||||
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
|
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
|
||||||
|
|
||||||
GLuint cube_id;
|
GLuint cube_id;
|
||||||
glGenTextures(1, &cube_id);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
|
||||||
for (GLuint i = 0; i < 6; i++)
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
|
||||||
static int faces[]{
|
static int faces[]{
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
|
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
|
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
|
||||||
@@ -1754,6 +1709,17 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
||||||
};
|
};
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
|
glGenTextures(1, &cube_id);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
||||||
|
for (GLuint i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8,
|
||||||
|
m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
int total = 6 + 2;
|
int total = 6 + 2;
|
||||||
|
|
||||||
@@ -1761,6 +1727,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
face.create(m_width, m_height);
|
face.create(m_width, m_height);
|
||||||
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
App::I.render_task([&]
|
||||||
{
|
{
|
||||||
// prepare common states
|
// prepare common states
|
||||||
glViewport(0, 0, m_width, m_height);
|
glViewport(0, 0, m_width, m_height);
|
||||||
@@ -1833,6 +1801,7 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
});
|
||||||
|
|
||||||
progress++;
|
progress++;
|
||||||
float p = (float)progress / total * 100.f;
|
float p = (float)progress / total * 100.f;
|
||||||
@@ -1841,9 +1810,6 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1859,6 +1825,8 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
// int ret = stbi_write_png(name, m_tmp[i].getWidth(), m_tmp[i].getHeight(), 4, data.get(), m_tmp[i].stride());
|
// int ret = stbi_write_png(name, m_tmp[i].getWidth(), m_tmp[i].getHeight(), 4, data.get(), m_tmp[i].stride());
|
||||||
//}
|
//}
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
glDisable(GL_BLEND);
|
glDisable(GL_BLEND);
|
||||||
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
|
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
@@ -1872,22 +1840,17 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
m_sampler_mask.unbind();
|
m_sampler_mask.unbind();
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
m_latlong.unbindFramebuffer();
|
m_latlong.unbindFramebuffer();
|
||||||
{
|
});
|
||||||
|
|
||||||
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
||||||
m_latlong.readTextureData(latlong_data.get());
|
m_latlong.readTextureData(latlong_data.get());
|
||||||
|
|
||||||
{
|
|
||||||
progress++;
|
progress++;
|
||||||
float p = (float)progress / total * 100.f;
|
LOG("progress: %f", (float)progress / total * 100.f);
|
||||||
LOG("progress: %f", p);
|
|
||||||
|
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP((float)progress / total * 100.f);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG("writing %s", file_path.c_str());
|
LOG("writing %s", file_path.c_str());
|
||||||
@@ -1901,18 +1864,12 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
stbi_write_png(file_path.c_str(), m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), 0);
|
stbi_write_png(file_path.c_str(), m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
|
||||||
progress++;
|
progress++;
|
||||||
float p = (float)progress / total * 100.f;
|
LOG("progress: %f", (float)progress / total * 100.f);
|
||||||
LOG("progress: %f", p);
|
|
||||||
|
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP((float)progress / total * 100.f);
|
||||||
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());
|
//int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
||||||
@@ -1930,23 +1887,17 @@ void Canvas::export_equirectangular_thread(std::string file_path)
|
|||||||
}
|
}
|
||||||
}];
|
}];
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
glDeleteTextures(1, &cube_id);
|
App::I.render_task_async([id=cube_id]
|
||||||
|
{
|
||||||
|
glDeleteTextures(1, &id);
|
||||||
|
});
|
||||||
m_latlong.destroy();
|
m_latlong.destroy();
|
||||||
|
|
||||||
// restore viewport and clear color states
|
|
||||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
App::I.async_update();
|
|
||||||
}
|
}
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::inject_xmp(std::string jpg_path)
|
void Canvas::inject_xmp(std::string jpg_path)
|
||||||
@@ -2002,7 +1953,6 @@ void Canvas::export_depth(std::string file_name, std::function<void()> on_comple
|
|||||||
if (App::I.check_license())
|
if (App::I.check_license())
|
||||||
{
|
{
|
||||||
std::thread t([=] {
|
std::thread t([=] {
|
||||||
BT_SetTerminate();
|
|
||||||
export_depth_thread(file_name);
|
export_depth_thread(file_name);
|
||||||
if (on_complete)
|
if (on_complete)
|
||||||
on_complete();
|
on_complete();
|
||||||
@@ -2013,24 +1963,21 @@ void Canvas::export_depth(std::string file_name, std::function<void()> on_comple
|
|||||||
|
|
||||||
void Canvas::export_depth_thread(std::string file_name)
|
void Canvas::export_depth_thread(std::string file_name)
|
||||||
{
|
{
|
||||||
App::I.async_start();
|
|
||||||
gl_state gl;
|
|
||||||
gl.save();
|
|
||||||
|
|
||||||
draw_merge();
|
|
||||||
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
|
||||||
|
|
||||||
RTT rtt;
|
RTT rtt;
|
||||||
rtt.create(1024, 1024);
|
rtt.create(1024, 1024);
|
||||||
rtt.bindFramebuffer();
|
|
||||||
rtt.clear({ 0, 0, 0, 1 });
|
|
||||||
|
|
||||||
glViewport(0, 0, rtt.getWidth(), rtt.getHeight());
|
|
||||||
glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)rtt.getWidth() / (float)rtt.getHeight(), 0.1f, 100.f);
|
glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)rtt.getWidth() / (float)rtt.getHeight(), 0.1f, 100.f);
|
||||||
glm::mat4 camera = m_cam_rot;
|
glm::mat4 camera = m_cam_rot;
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
|
draw_merge();
|
||||||
|
|
||||||
|
rtt.bindFramebuffer();
|
||||||
|
rtt.clear({ 0, 0, 0, 1 });
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glViewport(0, 0, rtt.getWidth(), rtt.getHeight());
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
auto plane_mvp_z = proj * camera *
|
auto plane_mvp_z = proj * camera *
|
||||||
@@ -2059,6 +2006,8 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
|
rtt.unbindFramebuffer();
|
||||||
|
});
|
||||||
|
|
||||||
uint8_t* rgba_data = rtt.readTextureData();
|
uint8_t* rgba_data = rtt.readTextureData();
|
||||||
stbi_flip_vertically_on_write(true);
|
stbi_flip_vertically_on_write(true);
|
||||||
@@ -2066,7 +2015,13 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
stbi_write_jpg(path_rgba.c_str(), rtt.getWidth(), rtt.getHeight(), 4, rgba_data, 100);
|
stbi_write_jpg(path_rgba.c_str(), rtt.getWidth(), rtt.getHeight(), 4, rgba_data, 100);
|
||||||
delete rgba_data;
|
delete rgba_data;
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
|
rtt.bindFramebuffer();
|
||||||
rtt.clear({ 0, 0, 0, 1 });
|
rtt.clear({ 0, 0, 0, 1 });
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
glViewport(0, 0, rtt.getWidth(), rtt.getHeight());
|
||||||
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
||||||
{
|
{
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
@@ -2094,6 +2049,8 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
rtt.unbindFramebuffer();
|
||||||
|
});
|
||||||
|
|
||||||
uint8_t* depth_data = rtt.readTextureData();
|
uint8_t* depth_data = rtt.readTextureData();
|
||||||
std::string path_depth = App::I.work_path + "/" + file_name + "_depth.png";
|
std::string path_depth = App::I.work_path + "/" + file_name + "_depth.png";
|
||||||
@@ -2101,11 +2058,7 @@ void Canvas::export_depth_thread(std::string file_name)
|
|||||||
delete depth_data;
|
delete depth_data;
|
||||||
stbi_flip_vertically_on_write(false);
|
stbi_flip_vertically_on_write(false);
|
||||||
|
|
||||||
rtt.unbindFramebuffer();
|
|
||||||
rtt.destroy();
|
rtt.destroy();
|
||||||
|
|
||||||
gl.restore();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::export_layers(std::string file_name, std::function<void()> on_complete)
|
void Canvas::export_layers(std::string file_name, std::function<void()> on_complete)
|
||||||
@@ -2124,16 +2077,6 @@ void Canvas::export_layers(std::string file_name, std::function<void()> on_compl
|
|||||||
|
|
||||||
void Canvas::export_layers_thread(std::string file_name)
|
void Canvas::export_layers_thread(std::string file_name)
|
||||||
{
|
{
|
||||||
App::I.async_start();
|
|
||||||
|
|
||||||
// save viewport and clear color states
|
|
||||||
GLint vp[4];
|
|
||||||
GLfloat cc[4];
|
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
|
||||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
|
||||||
GLboolean blend = glIsEnabled(GL_BLEND);
|
|
||||||
|
|
||||||
gl_state gl;
|
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
std::shared_ptr<NodeProgressBar> pb;
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
@@ -2145,22 +2088,14 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Export Pano Layers");
|
pb->m_title->set_text("Export Pano Layers");
|
||||||
App::I.layout[App::I.main_id]->add_child(pb);
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
App::I.async_update();
|
|
||||||
}
|
}
|
||||||
int progress = 0;
|
int progress = 0;
|
||||||
int total = (int)(m_layers.size() + 1) * 6;
|
int total = (int)(m_layers.size() + 1) * 6;
|
||||||
|
|
||||||
// prepare common states
|
|
||||||
glViewport(0, 0, m_width, m_height);
|
|
||||||
|
|
||||||
RTT m_latlong;
|
RTT m_latlong;
|
||||||
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
|
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
|
||||||
|
|
||||||
GLuint cube_id;
|
GLuint cube_id;
|
||||||
glGenTextures(1, &cube_id);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
|
||||||
for (GLuint i = 0; i < 6; i++)
|
|
||||||
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
|
||||||
int faces[]{
|
int faces[]{
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
|
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
|
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
|
||||||
@@ -2169,14 +2104,23 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // top
|
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // top
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // bottom
|
||||||
};
|
};
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
|
glGenTextures(1, &cube_id);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
||||||
|
for (GLuint i = 0; i < 6; i++)
|
||||||
|
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGBA8, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
|
||||||
|
});
|
||||||
|
|
||||||
int seq = 0;
|
int seq = 0;
|
||||||
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
||||||
{
|
{
|
||||||
glViewport(0, 0, m_width, m_height);
|
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
App::I.render_task([&]
|
||||||
{
|
{
|
||||||
glEnable(GL_BLEND);
|
glEnable(GL_BLEND);
|
||||||
|
glViewport(0, 0, m_width, m_height);
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
|
|
||||||
//if (seq == 0)
|
//if (seq == 0)
|
||||||
@@ -2212,6 +2156,7 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
|
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
|
});
|
||||||
|
|
||||||
progress++;
|
progress++;
|
||||||
float p = (float)progress / total * 100.f;
|
float p = (float)progress / total * 100.f;
|
||||||
@@ -2220,13 +2165,11 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
|
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
m_latlong.bindFramebuffer();
|
m_latlong.bindFramebuffer();
|
||||||
@@ -2241,6 +2184,8 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
m_sampler_mask.unbind();
|
m_sampler_mask.unbind();
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
||||||
m_latlong.unbindFramebuffer();
|
m_latlong.unbindFramebuffer();
|
||||||
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
||||||
m_latlong.readTextureData(latlong_data.get());
|
m_latlong.readTextureData(latlong_data.get());
|
||||||
@@ -2248,9 +2193,7 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
sprintf(name, "%s/%s-layer-%02d.png", App::I.work_path.c_str(), file_name.c_str(), seq);
|
sprintf(name, "%s/%s-layer-%02d.png", App::I.work_path.c_str(), file_name.c_str(), seq);
|
||||||
seq++;
|
seq++;
|
||||||
LOG("writing %s", name);
|
LOG("writing %s", name);
|
||||||
App::I.async_end();
|
|
||||||
int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
||||||
App::I.async_start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
progress++;
|
progress++;
|
||||||
@@ -2260,28 +2203,19 @@ void Canvas::export_layers_thread(std::string file_name)
|
|||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
glDeleteTextures(1, &cube_id);
|
glDeleteTextures(1, &cube_id);
|
||||||
m_latlong.destroy();
|
m_latlong.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
App::I.async_update();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// restore viewport and clear color states
|
|
||||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::export_cubes()
|
void Canvas::export_cubes()
|
||||||
@@ -2401,8 +2335,6 @@ void Canvas::project_save(std::string file_path, std::function<void(bool)> on_co
|
|||||||
|
|
||||||
bool Canvas::project_save_thread(std::string file_path)
|
bool Canvas::project_save_thread(std::string file_path)
|
||||||
{
|
{
|
||||||
gl_state gl;
|
|
||||||
|
|
||||||
// already saved, nothing to do
|
// already saved, nothing to do
|
||||||
if (!m_unsaved && file_path == App::I.doc_path)
|
if (!m_unsaved && file_path == App::I.doc_path)
|
||||||
{
|
{
|
||||||
@@ -2453,7 +2385,6 @@ bool Canvas::project_save_thread(std::string file_path)
|
|||||||
fwrite(&ppi_header, sizeof(PPIHeader), 1, fp);
|
fwrite(&ppi_header, sizeof(PPIHeader), 1, fp);
|
||||||
|
|
||||||
// load thumbnail
|
// load thumbnail
|
||||||
App::I.async_start();
|
|
||||||
Image thumb = thumbnail_generate(ppi_header.thumb_header.width, ppi_header.thumb_header.height);
|
Image thumb = thumbnail_generate(ppi_header.thumb_header.width, ppi_header.thumb_header.height);
|
||||||
auto pb = std::make_shared<NodeProgressBar>();
|
auto pb = std::make_shared<NodeProgressBar>();
|
||||||
pb->m_manager = &App::I.layout;
|
pb->m_manager = &App::I.layout;
|
||||||
@@ -2463,8 +2394,6 @@ bool Canvas::project_save_thread(std::string file_path)
|
|||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Saving Pano Project");
|
pb->m_title->set_text("Saving Pano Project");
|
||||||
App::I.layout[App::I.main_id]->add_child(pb);
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
|
|
||||||
thumb.flip();
|
thumb.flip();
|
||||||
fwrite(thumb.data(), thumb.size(), 1, fp);
|
fwrite(thumb.data(), thumb.size(), 1, fp);
|
||||||
@@ -2497,10 +2426,7 @@ bool Canvas::project_save_thread(std::string file_path)
|
|||||||
fwrite(&m_layers[i]->m_visible, sizeof(bool), 1, fp);
|
fwrite(&m_layers[i]->m_visible, sizeof(bool), 1, fp);
|
||||||
}
|
}
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
auto snap = m_layers[i]->snapshot();
|
auto snap = m_layers[i]->snapshot();
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
int has_data = snap.m_dirty_face[plane_index] ? 1 : 0;
|
||||||
@@ -2527,11 +2453,8 @@ bool Canvas::project_save_thread(std::string file_path)
|
|||||||
}
|
}
|
||||||
progress++;
|
progress++;
|
||||||
float p = (float)progress / total * 100.f;
|
float p = (float)progress / total * 100.f;
|
||||||
App::I.async_start();
|
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
LOG("progress: %f", p);
|
LOG("progress: %f", p);
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -2571,11 +2494,8 @@ bool Canvas::project_save_thread(std::string file_path)
|
|||||||
m_newdoc = false;
|
m_newdoc = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
App::I.title_update();
|
App::I.title_update();
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -2609,11 +2529,9 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
gl_state gl;
|
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
std::shared_ptr<NodeProgressBar> pb;
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
App::I.async_start();
|
|
||||||
pb = std::make_shared<NodeProgressBar>();
|
pb = std::make_shared<NodeProgressBar>();
|
||||||
pb->m_manager = &App::I.layout;
|
pb->m_manager = &App::I.layout;
|
||||||
pb->init();
|
pb->init();
|
||||||
@@ -2622,10 +2540,6 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Opening Pano Project");
|
pb->m_title->set_text("Opening Pano Project");
|
||||||
App::I.layout[App::I.main_id]->add_child(pb);
|
App::I.layout[App::I.main_id]->add_child(pb);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// skip thumbnail
|
// skip thumbnail
|
||||||
@@ -2648,13 +2562,11 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
int progress = 0;
|
int progress = 0;
|
||||||
int total = n_layers * 6;
|
int total = n_layers * 6;
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
l->destroy();
|
l->destroy();
|
||||||
m_layers.clear();
|
m_layers.clear();
|
||||||
//clear_all();
|
//clear_all();
|
||||||
resize(m_width, m_height);
|
resize(m_width, m_height);
|
||||||
App::I.async_end();
|
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Layer>> tmp_layers(n_layers);
|
std::vector<std::shared_ptr<Layer>> tmp_layers(n_layers);
|
||||||
|
|
||||||
@@ -2713,20 +2625,12 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
|
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
App::I.async_start();
|
|
||||||
pb->m_progress->SetWidthP(p);
|
pb->m_progress->SetWidthP(p);
|
||||||
gl.save();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
layer->create(m_width, m_height, name.c_str());
|
layer->create(m_width, m_height, name.c_str());
|
||||||
layer->clear({ 0, 0, 0, 0 });
|
|
||||||
layer->restore(snap);
|
layer->restore(snap);
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::swap(tmp_layers, m_layers);
|
std::swap(tmp_layers, m_layers);
|
||||||
@@ -2749,20 +2653,8 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
m_newdoc = false;
|
m_newdoc = false;
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
{
|
{
|
||||||
App::I.async_start();
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
gl.save();
|
|
||||||
draw_merge();
|
|
||||||
App::I.async_update();
|
|
||||||
gl.restore();
|
|
||||||
App::I.title_update();
|
App::I.title_update();
|
||||||
App::I.async_end();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
App::I.async_start();
|
|
||||||
draw_merge();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,10 +33,13 @@ void ActionStroke::undo()
|
|||||||
|
|
||||||
glm::vec2 box_sz = zw(m_box[i]) - xy(m_box[i]);
|
glm::vec2 box_sz = zw(m_box[i]) - xy(m_box[i]);
|
||||||
if (box_sz.x > 0 && box_sz.y > 0 && box_sz.x <= m_canvas->m_layers[m_layer_idx]->w && box_sz.y <= m_canvas->m_layers[m_layer_idx]->h)
|
if (box_sz.x > 0 && box_sz.y > 0 && box_sz.x <= m_canvas->m_layers[m_layer_idx]->w && box_sz.y <= m_canvas->m_layers[m_layer_idx]->h)
|
||||||
|
{
|
||||||
|
App::I.render_task([&]
|
||||||
{
|
{
|
||||||
m_canvas->m_layers[m_layer_idx]->m_rtt[i].bindTexture();
|
m_canvas->m_layers[m_layer_idx]->m_rtt[i].bindTexture();
|
||||||
glTexSubImage2D(GL_TEXTURE_2D, 0, (int)m_box[i].x, (int)m_box[i].y, (int)box_sz.x, (int)box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image[i].get());
|
glTexSubImage2D(GL_TEXTURE_2D, 0, (int)m_box[i].x, (int)m_box[i].y, (int)box_sz.x, (int)box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, m_image[i].get());
|
||||||
m_canvas->m_layers[m_layer_idx]->m_rtt[i].unbindTexture();
|
m_canvas->m_layers[m_layer_idx]->m_rtt[i].unbindTexture();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -66,7 +69,6 @@ Action* ActionStroke::get_redo()
|
|||||||
if (!layer->m_dirty_face[i] && !m_image[i])
|
if (!layer->m_dirty_face[i] && !m_image[i])
|
||||||
continue; // no stroke on this face, skip it
|
continue; // no stroke on this face, skip it
|
||||||
|
|
||||||
layer->m_rtt[i].bindFramebuffer();
|
|
||||||
|
|
||||||
auto box = clear_layer ? glm::ivec4(layer->m_dirty_box[i]) : m_box[i];
|
auto box = clear_layer ? glm::ivec4(layer->m_dirty_box[i]) : m_box[i];
|
||||||
|
|
||||||
@@ -76,7 +78,12 @@ Action* ActionStroke::get_redo()
|
|||||||
if (box_sz.x > 0 && box_sz.y > 0 && box_sz.x <= layer->w && box_sz.y <= layer->h)
|
if (box_sz.x > 0 && box_sz.y > 0 && box_sz.x <= layer->w && box_sz.y <= layer->h)
|
||||||
{
|
{
|
||||||
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
action->m_image[i] = std::make_unique<uint8_t[]>(box_sz.x * box_sz.y * 4);
|
||||||
|
App::I.render_task([&]
|
||||||
|
{
|
||||||
|
layer->m_rtt[i].bindFramebuffer();
|
||||||
glReadPixels(box_or.x, box_or.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
glReadPixels(box_or.x, box_or.y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
||||||
|
layer->m_rtt[i].unbindFramebuffer();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -86,8 +93,6 @@ Action* ActionStroke::get_redo()
|
|||||||
action->m_box[i] = box;
|
action->m_box[i] = box;
|
||||||
action->m_old_box[i] = layer->m_dirty_box[i];
|
action->m_old_box[i] = layer->m_dirty_box[i];
|
||||||
action->m_old_dirty[i] = layer->m_dirty_face[i];
|
action->m_old_dirty[i] = layer->m_dirty_face[i];
|
||||||
|
|
||||||
layer->m_rtt[i].unbindFramebuffer();
|
|
||||||
}
|
}
|
||||||
// save history
|
// save history
|
||||||
action->m_layer_idx = m_layer_idx;
|
action->m_layer_idx = m_layer_idx;
|
||||||
|
|||||||
@@ -135,7 +135,10 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Canvas::I->stroke_start({ loc, 0 }, me->m_pressure);
|
App::I.render_task_async([loc, pr=me->m_pressure]
|
||||||
|
{
|
||||||
|
Canvas::I->stroke_start({ loc, 0 }, pr);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
m_dragging = true;
|
m_dragging = true;
|
||||||
node->mouse_capture();
|
node->mouse_capture();
|
||||||
@@ -144,7 +147,10 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
if (m_dragging && !m_picking)
|
if (m_dragging && !m_picking)
|
||||||
{
|
{
|
||||||
node->mouse_release();
|
node->mouse_release();
|
||||||
|
App::I.render_task_async([]
|
||||||
|
{
|
||||||
Canvas::I->stroke_end();
|
Canvas::I->stroke_end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (m_dragging && m_picking)
|
if (m_dragging && m_picking)
|
||||||
{
|
{
|
||||||
@@ -178,7 +184,12 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
break;
|
break;
|
||||||
case kEventType::MouseMove:
|
case kEventType::MouseMove:
|
||||||
if (m_dragging && !m_picking && !m_resizing)
|
if (m_dragging && !m_picking && !m_resizing)
|
||||||
Canvas::I->stroke_update({ loc, 0 }, me->m_pressure);
|
{
|
||||||
|
App::I.render_task_async([loc, pr=me->m_pressure]
|
||||||
|
{
|
||||||
|
Canvas::I->stroke_update({ loc, 0 }, pr);
|
||||||
|
});
|
||||||
|
}
|
||||||
if (m_dragging && m_picking)
|
if (m_dragging && m_picking)
|
||||||
{
|
{
|
||||||
glm::vec4 pix = Canvas::I->pick_get(loc);
|
glm::vec4 pix = Canvas::I->pick_get(loc);
|
||||||
@@ -196,8 +207,11 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
break;
|
break;
|
||||||
case kEventType::MouseCancel:
|
case kEventType::MouseCancel:
|
||||||
if (m_dragging)
|
if (m_dragging)
|
||||||
|
{
|
||||||
|
App::I.render_task_async([]
|
||||||
{
|
{
|
||||||
Canvas::I->stroke_cancel();
|
Canvas::I->stroke_cancel();
|
||||||
|
});
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
node->mouse_release();
|
node->mouse_release();
|
||||||
}
|
}
|
||||||
@@ -298,11 +312,14 @@ void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
|||||||
case kEventType::MouseUpL:
|
case kEventType::MouseUpL:
|
||||||
node->mouse_release();
|
node->mouse_release();
|
||||||
if (m_dragging)
|
if (m_dragging)
|
||||||
|
{
|
||||||
|
App::I.render_task_async([=]
|
||||||
{
|
{
|
||||||
Canvas::I->stroke_start({ m_drag_start, 0 }, 1.f);
|
Canvas::I->stroke_start({ m_drag_start, 0 }, 1.f);
|
||||||
Canvas::I->stroke_update({ m_drag_pos, 0 }, 1.f);
|
Canvas::I->stroke_update({ m_drag_pos, 0 }, 1.f);
|
||||||
Canvas::I->stroke_draw();
|
Canvas::I->stroke_draw();
|
||||||
Canvas::I->stroke_end();
|
Canvas::I->stroke_end();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
break;
|
break;
|
||||||
|
|||||||
34
src/main.cpp
34
src/main.cpp
@@ -811,7 +811,7 @@ void render_thread_main()
|
|||||||
async_lock();
|
async_lock();
|
||||||
while (!working_list.empty())
|
while (!working_list.empty())
|
||||||
{
|
{
|
||||||
//LOG("render task %d", count);
|
LOG("render task %d", count);
|
||||||
count++;
|
count++;
|
||||||
working_list.front()();
|
working_list.front()();
|
||||||
working_list.pop_front();
|
working_list.pop_front();
|
||||||
@@ -1133,11 +1133,12 @@ int main(int argc, char** argv)
|
|||||||
|
|
||||||
if (App::I.redraw)
|
if (App::I.redraw)
|
||||||
{
|
{
|
||||||
|
App::I.update(frame_timer);
|
||||||
render_task([frame_timer]
|
render_task([frame_timer]
|
||||||
{
|
{
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
App::I.clear();
|
App::I.clear();
|
||||||
App::I.update(frame_timer);
|
App::I.draw(frame_timer);
|
||||||
SwapBuffers(hDC);
|
SwapBuffers(hDC);
|
||||||
});
|
});
|
||||||
frame_timer = 0;
|
frame_timer = 0;
|
||||||
@@ -1244,39 +1245,28 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
|
|||||||
BT_SetTerminate();
|
BT_SetTerminate();
|
||||||
break;
|
break;
|
||||||
case WM_CLOSE:
|
case WM_CLOSE:
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(task_mutex);
|
||||||
|
tasklist.emplace_back([=] {
|
||||||
if (App::I.request_close())
|
if (App::I.request_close())
|
||||||
{
|
{
|
||||||
running = 0;
|
destroy_window();
|
||||||
ui_render_cv.notify_all();
|
|
||||||
if (ui_renderer.joinable())
|
|
||||||
ui_renderer.join();
|
|
||||||
if (hmd_renderer.joinable())
|
|
||||||
hmd_renderer.join();
|
|
||||||
App::I.terminate();
|
|
||||||
PostQuitMessage(0);
|
|
||||||
render_running = false;
|
|
||||||
if (render_thread.joinable())
|
|
||||||
render_thread.join();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
return 1;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case WM_SIZE:
|
case WM_SIZE:
|
||||||
{
|
{
|
||||||
auto w = (float)LOWORD(lp);
|
auto w = (float)LOWORD(lp);
|
||||||
auto h = (float)HIWORD(lp);
|
auto h = (float)HIWORD(lp);
|
||||||
if (h != 0 && running == 1)
|
if (h != 0 && running == 1)
|
||||||
{
|
{
|
||||||
App::I.render_task([=]
|
std::lock_guard<std::mutex> lock(task_mutex);
|
||||||
|
tasklist.emplace_back([=]
|
||||||
{
|
{
|
||||||
App::I.resize(w, h);
|
App::I.resize(w, h);
|
||||||
App::I.clear();
|
|
||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
App::I.update(0.f);
|
|
||||||
SwapBuffers(hDC);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
15
src/node.cpp
15
src/node.cpp
@@ -42,21 +42,6 @@ void Node::app_redraw()
|
|||||||
App::I.redraw = true;
|
App::I.redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::async_start()
|
|
||||||
{
|
|
||||||
App::I.async_start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::async_update()
|
|
||||||
{
|
|
||||||
App::I.async_update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::async_end()
|
|
||||||
{
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Node::watch(std::function<bool(Node*)> observer)
|
void Node::watch(std::function<bool(Node*)> observer)
|
||||||
{
|
{
|
||||||
bool cont = observer(this);
|
bool cont = observer(this);
|
||||||
|
|||||||
@@ -266,9 +266,6 @@ public:
|
|||||||
const Node* init_template(const char* id);
|
const Node* init_template(const char* id);
|
||||||
void tick(float dt);
|
void tick(float dt);
|
||||||
void app_redraw();
|
void app_redraw();
|
||||||
void async_start();
|
|
||||||
void async_update();
|
|
||||||
void async_end();
|
|
||||||
void add_child(Node* n);
|
void add_child(Node* n);
|
||||||
void add_child(Node* n, int index);
|
void add_child(Node* n, int index);
|
||||||
void add_child(std::shared_ptr<Node> n);
|
void add_child(std::shared_ptr<Node> n);
|
||||||
|
|||||||
@@ -80,7 +80,6 @@ void NodeDialogBrowse::init_controls()
|
|||||||
btn_path->on_click = [this](Node*){
|
btn_path->on_click = [this](Node*){
|
||||||
App::I.pick_dir([this](std::string path){
|
App::I.pick_dir([this](std::string path){
|
||||||
LOG("change working path to %s", path.c_str());
|
LOG("change working path to %s", path.c_str());
|
||||||
async_start();
|
|
||||||
App::I.work_path = path;
|
App::I.work_path = path;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
||||||
@@ -91,8 +90,6 @@ void NodeDialogBrowse::init_controls()
|
|||||||
search_paths = {path};
|
search_paths = {path};
|
||||||
clear_list();
|
clear_list();
|
||||||
init_list();
|
init_list();
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
working_path = find<NodeText>("path");
|
working_path = find<NodeText>("path");
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
std::string res;
|
std::string res;
|
||||||
if (curl)
|
if (curl)
|
||||||
{
|
{
|
||||||
async_start();
|
|
||||||
auto* align = container->add_child<Node>();
|
auto* align = container->add_child<Node>();
|
||||||
align->SetWidthP(100.f);
|
align->SetWidthP(100.f);
|
||||||
align->SetHeightP(100.f);
|
align->SetHeightP(100.f);
|
||||||
@@ -64,8 +63,6 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
auto* text = align->add_child<NodeText>();
|
auto* text = align->add_child<NodeText>();
|
||||||
text->set_font(kFont::Arial_30);
|
text->set_font(kFont::Arial_30);
|
||||||
text->set_text("Connecting to the server...");
|
text->set_text("Connecting to the server...");
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
|
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &res);
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
|
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, curl_data_handler);
|
||||||
@@ -78,16 +75,11 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
if (err != CURLE_OK)
|
if (err != CURLE_OK)
|
||||||
{
|
{
|
||||||
LOG("connection error: %d", err);
|
LOG("connection error: %d", err);
|
||||||
async_start();
|
|
||||||
text->set_text("Could not connect to the server");
|
text->set_text("Could not connect to the server");
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
async_start();
|
|
||||||
align->destroy();
|
align->destroy();
|
||||||
async_end();
|
|
||||||
|
|
||||||
LOG("CLOUD LIST: %s", res.c_str());
|
LOG("CLOUD LIST: %s", res.c_str());
|
||||||
|
|
||||||
@@ -95,7 +87,6 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
std::vector<NodeDialogCloudItem*> nodes;
|
std::vector<NodeDialogCloudItem*> nodes;
|
||||||
|
|
||||||
// create slots with name
|
// create slots with name
|
||||||
App::I.async_start();
|
|
||||||
for (const auto& n : names)
|
for (const auto& n : names)
|
||||||
{
|
{
|
||||||
auto node = new NodeDialogCloudItem;
|
auto node = new NodeDialogCloudItem;
|
||||||
@@ -117,8 +108,6 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
};
|
};
|
||||||
nodes.push_back(node);
|
nodes.push_back(node);
|
||||||
}
|
}
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
|
|
||||||
// load the icons
|
// load the icons
|
||||||
for (int i = 0; i < names.size(); i++)
|
for (int i = 0; i < names.size(); i++)
|
||||||
@@ -149,12 +138,9 @@ void NodeDialogCloud::load_thumbs_thread()
|
|||||||
thumb.create(width, height);
|
thumb.create(width, height);
|
||||||
thumb.copy_from((uint8_t*)rgb.data());
|
thumb.copy_from((uint8_t*)rgb.data());
|
||||||
|
|
||||||
App::I.async_start();
|
|
||||||
auto image_tex = node->find<NodeImageTexture>("thumb-tex");
|
auto image_tex = node->find<NodeImageTexture>("thumb-tex");
|
||||||
image_tex->tex.destroy();
|
image_tex->tex.destroy();
|
||||||
image_tex->tex.create(thumb);
|
image_tex->tex.create(thumb);
|
||||||
App::I.async_update();
|
|
||||||
App::I.async_end();
|
|
||||||
}
|
}
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,7 +200,6 @@ void NodeDialogSave::init_controls()
|
|||||||
btn_path->on_click = [this](Node*){
|
btn_path->on_click = [this](Node*){
|
||||||
App::I.pick_dir([this](std::string path){
|
App::I.pick_dir([this](std::string path){
|
||||||
LOG("change working path to %s", path.c_str());
|
LOG("change working path to %s", path.c_str());
|
||||||
async_start();
|
|
||||||
App::I.work_path = path;
|
App::I.work_path = path;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
||||||
@@ -208,8 +207,6 @@ void NodeDialogSave::init_controls()
|
|||||||
realpath(path.c_str(), path_buffer);
|
realpath(path.c_str(), path_buffer);
|
||||||
#endif
|
#endif
|
||||||
working_path->set_text_format("Working dir: %s", path_buffer);
|
working_path->set_text_format("Working dir: %s", path_buffer);
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
working_path = find<NodeText>("path");
|
working_path = find<NodeText>("path");
|
||||||
@@ -264,7 +261,6 @@ void NodeDialogNewDoc::init_controls()
|
|||||||
btn_path->on_click = [this](Node*){
|
btn_path->on_click = [this](Node*){
|
||||||
App::I.pick_dir([this](std::string path){
|
App::I.pick_dir([this](std::string path){
|
||||||
LOG("change working path to %s", path.c_str());
|
LOG("change working path to %s", path.c_str());
|
||||||
async_start();
|
|
||||||
App::I.work_path = path;
|
App::I.work_path = path;
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
GetFullPathNameA(path.c_str(), sizeof(path_buffer), path_buffer, nullptr);
|
||||||
@@ -272,8 +268,6 @@ void NodeDialogNewDoc::init_controls()
|
|||||||
realpath(path.c_str(), path_buffer);
|
realpath(path.c_str(), path_buffer);
|
||||||
#endif
|
#endif
|
||||||
working_path->set_text_format("Working dir: %s", path_buffer);
|
working_path->set_text_format("Working dir: %s", path_buffer);
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
working_path = find<NodeText>("path");
|
working_path = find<NodeText>("path");
|
||||||
|
|||||||
@@ -102,7 +102,6 @@ void NodePanelBrush::init()
|
|||||||
//auto po2 = img.resize_power2();
|
//auto po2 = img.resize_power2();
|
||||||
img.save(path_high);
|
img.save(path_high);
|
||||||
|
|
||||||
async_start();
|
|
||||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||||
m_container->add_child(brush);
|
m_container->add_child(brush);
|
||||||
brush->init();
|
brush->init();
|
||||||
@@ -114,8 +113,6 @@ void NodePanelBrush::init()
|
|||||||
brush->brush_name = name;
|
brush->brush_name = name;
|
||||||
brush->m_user_brush = true;
|
brush->m_user_brush = true;
|
||||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, this, std::placeholders::_1);
|
||||||
app_redraw();
|
|
||||||
async_end();
|
|
||||||
save();
|
save();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -78,7 +78,6 @@ void NodePanelGrid::init_controls()
|
|||||||
m_hm_load->on_click = [this](Node*) {
|
m_hm_load->on_click = [this](Node*) {
|
||||||
App::I.pick_image([this](std::string path) {
|
App::I.pick_image([this](std::string path) {
|
||||||
Image img;
|
Image img;
|
||||||
async_start();
|
|
||||||
if (img.load_file(path))
|
if (img.load_file(path))
|
||||||
{
|
{
|
||||||
m_file_path = path;
|
m_file_path = path;
|
||||||
@@ -93,8 +92,6 @@ void NodePanelGrid::init_controls()
|
|||||||
m_groud_opacity->set_value(1.f);
|
m_groud_opacity->set_value(1.f);
|
||||||
m_rt_dirty = true;
|
m_rt_dirty = true;
|
||||||
}
|
}
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -380,7 +377,6 @@ void NodePanelGrid::bake_uvs()
|
|||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text("Lightmap Rendering");
|
pb->m_title->set_text("Lightmap Rendering");
|
||||||
pb->btn_cancel->destroy();
|
pb->btn_cancel->destroy();
|
||||||
async_update();
|
|
||||||
|
|
||||||
if (m_rt_dirty)
|
if (m_rt_dirty)
|
||||||
{
|
{
|
||||||
@@ -462,7 +458,6 @@ void NodePanelGrid::bake_uvs()
|
|||||||
while (pb_value < fb.getHeight())
|
while (pb_value < fb.getHeight())
|
||||||
{
|
{
|
||||||
pb->m_progress->SetWidthP((float)pb_value / (float)fb.getHeight() * 100.f);
|
pb->m_progress->SetWidthP((float)pb_value / (float)fb.getHeight() * 100.f);
|
||||||
async_update();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
worker.join();
|
worker.join();
|
||||||
|
|||||||
@@ -42,11 +42,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
if (!str_iequals(ext, "abr") || !Asset::exist(path))
|
if (!str_iequals(ext, "abr") || !Asset::exist(path))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
async_start();
|
|
||||||
auto pb = App::I.show_progress("Importing ABR");
|
auto pb = App::I.show_progress("Importing ABR");
|
||||||
app_redraw();
|
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
|
|
||||||
abr.open(path);
|
abr.open(path);
|
||||||
|
|
||||||
@@ -68,7 +64,6 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
auto thumb = padded.resize(64, 64);
|
auto thumb = padded.resize(64, 64);
|
||||||
thumb.save(path_thumb);
|
thumb.save(path_thumb);
|
||||||
|
|
||||||
async_start();
|
|
||||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||||
m_brush_popup->m_container->add_child(brush);
|
m_brush_popup->m_container->add_child(brush);
|
||||||
brush->init();
|
brush->init();
|
||||||
@@ -83,9 +78,6 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
float prog = (float)count / (float)tot;
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
pb->m_progress->SetWidthP(prog * 100.f);
|
||||||
app_redraw();
|
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
m_brush_popup->save();
|
m_brush_popup->save();
|
||||||
|
|
||||||
@@ -101,7 +93,6 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
auto thumb = patt.second->resize(64, 64);
|
auto thumb = patt.second->resize(64, 64);
|
||||||
thumb.save(path_thumb);
|
thumb.save(path_thumb);
|
||||||
|
|
||||||
async_start();
|
|
||||||
NodeButtonBrush* brush = new NodeButtonBrush;
|
NodeButtonBrush* brush = new NodeButtonBrush;
|
||||||
m_pattern_popup->m_container->add_child(brush);
|
m_pattern_popup->m_container->add_child(brush);
|
||||||
brush->init();
|
brush->init();
|
||||||
@@ -116,16 +107,12 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
float prog = (float)count / (float)tot;
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
pb->m_progress->SetWidthP(prog * 100.f);
|
||||||
app_redraw();
|
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
});
|
});
|
||||||
m_pattern_popup->save();
|
m_pattern_popup->save();
|
||||||
|
|
||||||
auto brushes = abr.compute_brushes(App::I.data_path);
|
auto brushes = abr.compute_brushes(App::I.data_path);
|
||||||
for (const auto& pr : brushes)
|
for (const auto& pr : brushes)
|
||||||
{
|
{
|
||||||
async_start();
|
|
||||||
if (pr->valid())
|
if (pr->valid())
|
||||||
{
|
{
|
||||||
LOG("add preset %s", pr->m_name.c_str());
|
LOG("add preset %s", pr->m_name.c_str());
|
||||||
@@ -134,17 +121,10 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
float prog = (float)count / (float)tot;
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
pb->m_progress->SetWidthP(prog * 100.f);
|
||||||
app_redraw();
|
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async_start();
|
|
||||||
App::I.presets->save();
|
App::I.presets->save();
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
app_redraw();
|
|
||||||
async_update();
|
|
||||||
async_end();
|
|
||||||
//save();
|
//save();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -264,6 +264,7 @@ void NodeStrokePreview::draw_stroke_immediate()
|
|||||||
glm::mat4 ortho_proj = glm::ortho<float>(0, size.x, 0, size.y, -1, 1);
|
glm::mat4 ortho_proj = glm::ortho<float>(0, size.x, 0, size.y, -1, 1);
|
||||||
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
|
glViewport(0, 0, m_rtt.getWidth(), m_rtt.getHeight());
|
||||||
m_rtt.bindFramebuffer();
|
m_rtt.bindFramebuffer();
|
||||||
|
m_rtt.clear();
|
||||||
m_sampler_mipmap.bind(0);
|
m_sampler_mipmap.bind(0);
|
||||||
m_sampler_linear.bind(1);
|
m_sampler_linear.bind(1);
|
||||||
m_sampler_linear_repeat.bind(2);
|
m_sampler_linear_repeat.bind(2);
|
||||||
|
|||||||
41
src/util.cpp
41
src/util.cpp
@@ -2,6 +2,7 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include <poly2tri.h>
|
#include <poly2tri.h>
|
||||||
|
#include "app.h"
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
std::vector<vertex_t> poly_remove_duplicate<vertex_t>(const std::vector<vertex_t>& v, const float tollerance)
|
std::vector<vertex_t> poly_remove_duplicate<vertex_t>(const std::vector<vertex_t>& v, const float tollerance)
|
||||||
@@ -714,3 +715,43 @@ void parallel_for(size_t nb_elements, std::function<void(size_t i)> functor, boo
|
|||||||
if (use_threads)
|
if (use_threads)
|
||||||
std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
|
std::for_each(my_threads.begin(), my_threads.end(), std::mem_fn(&std::thread::join));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void gl_state::save()
|
||||||
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
blend = glIsEnabled(GL_BLEND);
|
||||||
|
depth_test = glIsEnabled(GL_DEPTH_TEST);
|
||||||
|
scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
||||||
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
|
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
||||||
|
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
|
||||||
|
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb);
|
||||||
|
glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &cube);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
glGetIntegerv(GL_TEXTURE_BINDING_2D, tex + i);
|
||||||
|
glGetIntegerv(GL_SAMPLER_BINDING, sampler + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void gl_state::restore()
|
||||||
|
{
|
||||||
|
assert(App::I.is_render_thread());
|
||||||
|
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
||||||
|
depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
||||||
|
scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
||||||
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
|
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
||||||
|
glUseProgram(program);
|
||||||
|
for (int i = 0; i < 10; ++i)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE0 + i);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex[i]);
|
||||||
|
glBindSampler(i, sampler[i]);
|
||||||
|
}
|
||||||
|
glActiveTexture(active_tex);
|
||||||
|
glBindTexture(GL_TEXTURE_CUBE_MAP, cube);
|
||||||
|
}
|
||||||
|
|||||||
38
src/util.h
38
src/util.h
@@ -251,40 +251,6 @@ struct gl_state
|
|||||||
GLint fb;
|
GLint fb;
|
||||||
GLint active_tex;
|
GLint active_tex;
|
||||||
GLfloat line_width;
|
GLfloat line_width;
|
||||||
void save()
|
void save();
|
||||||
{
|
void restore();
|
||||||
blend = glIsEnabled(GL_BLEND);
|
|
||||||
depth_test = glIsEnabled(GL_DEPTH_TEST);
|
|
||||||
scissor_test = glIsEnabled(GL_SCISSOR_TEST);
|
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
|
||||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
|
||||||
glGetIntegerv(GL_CURRENT_PROGRAM, &program);
|
|
||||||
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &fb);
|
|
||||||
glGetIntegerv(GL_ACTIVE_TEXTURE, &active_tex);
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_CUBE_MAP, &cube);
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
|
||||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, tex + i);
|
|
||||||
glGetIntegerv(GL_SAMPLER_BINDING, sampler + i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void restore()
|
|
||||||
{
|
|
||||||
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
|
|
||||||
depth_test ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
|
|
||||||
scissor_test ? glEnable(GL_SCISSOR_TEST) : glDisable(GL_SCISSOR_TEST);
|
|
||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
|
||||||
glBindFramebuffer(GL_FRAMEBUFFER, fb);
|
|
||||||
glUseProgram(program);
|
|
||||||
for (int i = 0; i < 10; ++i)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE0 + i);
|
|
||||||
glBindTexture(GL_TEXTURE_2D, tex[i]);
|
|
||||||
glBindSampler(i, sampler[i]);
|
|
||||||
}
|
|
||||||
glActiveTexture(active_tex);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user