remove all async_start/end calls

This commit is contained in:
2019-07-08 16:57:30 +02:00
parent 0012e2ce9b
commit f7ead8e157
19 changed files with 531 additions and 721 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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