Merge branch 'master'
This commit is contained in:
@@ -1483,6 +1483,9 @@ Here's a list of what's available in this release.
|
|||||||
<button-custom id="file-submenu-export-layers" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
<button-custom id="file-submenu-export-layers" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||||
<text text="Separate Layers" grow="1" margin="0 0 0 5"/>
|
<text text="Separate Layers" grow="1" margin="0 0 0 5"/>
|
||||||
</button-custom>
|
</button-custom>
|
||||||
|
<button-custom id="file-submenu-export-cube" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||||
|
<text text="Cube Faces" grow="1" margin="0 0 0 5"/>
|
||||||
|
</button-custom>
|
||||||
<button-custom id="file-submenu-export-depth" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
<button-custom id="file-submenu-export-depth" height="40" align="center" color=".2" pad="0 0 0 10" dir="row">
|
||||||
<text text="3D View + Depth" grow="1" margin="0 0 0 5"/>
|
<text text="3D View + Depth" grow="1" margin="0 0 0 5"/>
|
||||||
</button-custom>
|
</button-custom>
|
||||||
|
|||||||
@@ -495,7 +495,7 @@ bool App::update_ui_observer(Node *n)
|
|||||||
n->handle_on_screen(false, true);
|
n->handle_on_screen(false, true);
|
||||||
n->m_on_screen = true;
|
n->m_on_screen = true;
|
||||||
}
|
}
|
||||||
glm::ivec4 c = glm::vec4(box.x, (height / zoom - box.y - box.w), box.z, box.w) * zoom;
|
glm::ivec4 c = glm::vec4(box.x - 1, (height / zoom - box.y - box.w - 1), box.z + 2, box.w + 2) * zoom;
|
||||||
glScissor(floorf(c.x + off_x), floorf(c.y + off_y), ceilf(c.z), ceilf(c.w));
|
glScissor(floorf(c.x + off_x), floorf(c.y + off_y), ceilf(c.z), ceilf(c.w));
|
||||||
n->draw();
|
n->draw();
|
||||||
return true;
|
return true;
|
||||||
@@ -532,7 +532,7 @@ void App::draw(float dt)
|
|||||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||||
#endif
|
#endif
|
||||||
glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height);
|
glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height);
|
||||||
//glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
for (int i = 0; i < layout[main_id]->m_children.size(); i++)
|
for (int i = 0; i < layout[main_id]->m_children.size(); i++)
|
||||||
layout[main_id]->m_children[i]->watch(observer);
|
layout[main_id]->m_children[i]->watch(observer);
|
||||||
//msgbox->watch(observer);
|
//msgbox->watch(observer);
|
||||||
|
|||||||
29
src/app.h
29
src/app.h
@@ -205,7 +205,7 @@ public:
|
|||||||
bool key_char(char key);
|
bool key_char(char key);
|
||||||
void toggle_ui();
|
void toggle_ui();
|
||||||
void set_stylus();
|
void set_stylus();
|
||||||
NodeMessageBox* message_box(const std::string& title, const std::string& text, bool cancel_button = false);
|
std::shared_ptr<NodeMessageBox> message_box(const std::string& title, const std::string& text, bool cancel_button = false);
|
||||||
|
|
||||||
void rec_clear();
|
void rec_clear();
|
||||||
void rec_loop();
|
void rec_loop();
|
||||||
@@ -232,7 +232,7 @@ public:
|
|||||||
void dialog_export(std::string ext);
|
void dialog_export(std::string ext);
|
||||||
void dialog_export_layers();
|
void dialog_export_layers();
|
||||||
void dialog_export_depth();
|
void dialog_export_depth();
|
||||||
void dialog_export_cubes();
|
void dialog_export_cube_faces();
|
||||||
void dialog_layer_rename();
|
void dialog_layer_rename();
|
||||||
void dialog_resize();
|
void dialog_resize();
|
||||||
|
|
||||||
@@ -243,7 +243,7 @@ public:
|
|||||||
void download(std::string url, std::string dest_filepath, std::function<void(float)> progress = nullptr);
|
void download(std::string url, std::string dest_filepath, std::function<void(float)> progress = nullptr);
|
||||||
bool check_license();
|
bool check_license();
|
||||||
|
|
||||||
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title);
|
std::shared_ptr<NodeProgressBar> show_progress(const std::string& title, int total = 0);
|
||||||
|
|
||||||
void brush_update(bool update_color, bool update_brush);
|
void brush_update(bool update_color, bool update_brush);
|
||||||
void title_update();
|
void title_update();
|
||||||
@@ -284,8 +284,8 @@ public:
|
|||||||
|
|
||||||
// don't capture a reference to this ptr as the object may be destroyed
|
// don't capture a reference to this ptr as the object may be destroyed
|
||||||
// by the time the task is executed
|
// by the time the task is executed
|
||||||
template<typename T, typename R = void>
|
template<typename T>
|
||||||
std::future<R> render_task_async(T task, bool unique = false)
|
std::future<void> render_task_async(T task, bool unique = false)
|
||||||
{
|
{
|
||||||
AppTask pt(task);
|
AppTask pt(task);
|
||||||
auto f = pt.get_future();
|
auto f = pt.get_future();
|
||||||
@@ -308,8 +308,8 @@ public:
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename R = void>
|
template<typename T>
|
||||||
R render_task(T task)
|
void render_task(T task)
|
||||||
{
|
{
|
||||||
AppTask pt(task);
|
AppTask pt(task);
|
||||||
auto f = pt.get_future();
|
auto f = pt.get_future();
|
||||||
@@ -325,7 +325,8 @@ public:
|
|||||||
}
|
}
|
||||||
render_cv.notify_all();
|
render_cv.notify_all();
|
||||||
}
|
}
|
||||||
return render_running ? f.get() : R();
|
if (render_running)
|
||||||
|
f.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void render_sync()
|
void render_sync()
|
||||||
@@ -354,8 +355,8 @@ public:
|
|||||||
|
|
||||||
// don't capture a reference to this ptr as the object may be destroyed
|
// don't capture a reference to this ptr as the object may be destroyed
|
||||||
// by the time the task is executed
|
// by the time the task is executed
|
||||||
template<typename T, typename R = void>
|
template<typename T>
|
||||||
std::future<R> ui_task_async(T task, bool unique = false)
|
std::future<void> ui_task_async(T task, bool unique = false)
|
||||||
{
|
{
|
||||||
AppTask pt(task);
|
AppTask pt(task);
|
||||||
auto f = pt.get_future();
|
auto f = pt.get_future();
|
||||||
@@ -378,8 +379,8 @@ public:
|
|||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename R = void>
|
template<typename T>
|
||||||
R ui_task(T task)
|
void ui_task(T task)
|
||||||
{
|
{
|
||||||
AppTask pt(task);
|
AppTask pt(task);
|
||||||
auto f = pt.get_future();
|
auto f = pt.get_future();
|
||||||
@@ -395,7 +396,9 @@ public:
|
|||||||
}
|
}
|
||||||
ui_cv.notify_all();
|
ui_cv.notify_all();
|
||||||
}
|
}
|
||||||
return ui_running ? f.get() : R();
|
if (ui_running)
|
||||||
|
f.get();
|
||||||
|
redraw = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ui_sync()
|
void ui_sync()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void App::cloud_upload()
|
|||||||
auto pb = show_progress("Uploading");
|
auto pb = show_progress("Uploading");
|
||||||
|
|
||||||
upload(doc_path, doc_filename, [this,pb](float p){
|
upload(doc_path, doc_filename, [this,pb](float p){
|
||||||
pb->m_progress->SetWidthP(p * 100.f);
|
pb->set_progress(p);
|
||||||
});
|
});
|
||||||
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
@@ -70,32 +70,20 @@ void App::cloud_upload_all()
|
|||||||
gl_state gl;
|
gl_state gl;
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
std::shared_ptr<NodeProgressBar> pb;
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
pb = show_progress("Export Pano Image", names.size());
|
||||||
pb = show_progress("Export Pano Image");
|
|
||||||
}
|
|
||||||
|
|
||||||
int progress = 0;
|
|
||||||
int total = (int)names.size();
|
|
||||||
|
|
||||||
for (const auto& n : names)
|
for (const auto& n : names)
|
||||||
{
|
{
|
||||||
std::string path = data_path + "/" + n;
|
std::string path = data_path + "/" + n;
|
||||||
upload(path);
|
upload(path);
|
||||||
|
|
||||||
progress++;
|
|
||||||
float p = (float)progress / total * 100.f;
|
|
||||||
LOG("progress: %f", p);
|
|
||||||
|
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
pb->increment();
|
||||||
pb->m_progress->SetWidthP(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (layout.m_loaded)
|
if (layout.m_loaded)
|
||||||
{
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
}
|
|
||||||
}).detach();
|
}).detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
#include "oculus_vr.h"
|
#include "oculus_vr.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title)
|
std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title, int total /*= 0*/)
|
||||||
{
|
{
|
||||||
auto pb = std::make_shared<NodeProgressBar>();
|
auto pb = std::make_shared<NodeProgressBar>();
|
||||||
pb->m_manager = &layout;
|
pb->m_manager = &layout;
|
||||||
@@ -22,18 +22,25 @@ std::shared_ptr<NodeProgressBar> App::show_progress(const std::string& title)
|
|||||||
pb->loaded();
|
pb->loaded();
|
||||||
pb->m_progress->SetWidthP(0);
|
pb->m_progress->SetWidthP(0);
|
||||||
pb->m_title->set_text(title.c_str());
|
pb->m_title->set_text(title.c_str());
|
||||||
|
pb->m_total = total;
|
||||||
|
pb->m_count = 0;
|
||||||
layout[main_id]->add_child(pb);
|
layout[main_id]->add_child(pb);
|
||||||
return pb;
|
return pb;
|
||||||
}
|
}
|
||||||
|
|
||||||
NodeMessageBox* App::message_box(const std::string &title, const std::string& text, bool cancel_button)
|
std::shared_ptr<NodeMessageBox> App::message_box(const std::string &title, const std::string& text, bool cancel_button)
|
||||||
{
|
{
|
||||||
auto* m = layout[main_id]->add_child<NodeMessageBox>();
|
auto m = std::make_shared<NodeMessageBox>();
|
||||||
|
m->m_manager = &layout;
|
||||||
|
m->init();
|
||||||
|
m->create();
|
||||||
|
m->loaded();
|
||||||
m->m_title->set_text(title.c_str());
|
m->m_title->set_text(title.c_str());
|
||||||
m->m_message->set_text(text.c_str());
|
m->m_message->set_text(text.c_str());
|
||||||
m->btn_ok->m_text->set_text("Ok");
|
m->btn_ok->m_text->set_text("Ok");
|
||||||
if (!cancel_button)
|
if (!cancel_button)
|
||||||
m->btn_cancel->destroy();
|
m->btn_cancel->destroy();
|
||||||
|
layout[main_id]->add_child(m);
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -501,11 +508,19 @@ void App::dialog_resize()
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void App::dialog_export_cubes()
|
void App::dialog_export_cube_faces()
|
||||||
{
|
{
|
||||||
if (canvas)
|
if (canvas)
|
||||||
{
|
{
|
||||||
canvas->m_canvas->export_cubes();
|
canvas->m_canvas->export_cube_faces(doc_name, [this] {
|
||||||
|
#if defined(__IOS__)
|
||||||
|
message_box("Export Cube Faces", "Image and depth exported to Files/PanoPainter");
|
||||||
|
#elif defined(__OSX__)
|
||||||
|
message_box("Export Cube Faces", "Image and depth exported to Pictures/PanoPainter folder");
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
message_box("Export Cube Faces", "Image and depth exported to " + work_path);
|
||||||
|
#endif
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -636,6 +636,13 @@ void App::init_menu_file()
|
|||||||
popup->mouse_release();
|
popup->mouse_release();
|
||||||
popup->destroy();
|
popup->destroy();
|
||||||
};
|
};
|
||||||
|
subpopup->find<NodeButtonCustom>("file-submenu-export-cube")->on_click = [this, subpopup, popup](Node*) {
|
||||||
|
dialog_export_cube_faces();
|
||||||
|
subpopup->mouse_release();
|
||||||
|
subpopup->destroy();
|
||||||
|
popup->mouse_release();
|
||||||
|
popup->destroy();
|
||||||
|
};
|
||||||
subpopup->find<NodeButtonCustom>("file-submenu-export-depth")->on_click = [this, subpopup, popup](Node*) {
|
subpopup->find<NodeButtonCustom>("file-submenu-export-depth")->on_click = [this, subpopup, popup](Node*) {
|
||||||
dialog_export_depth();
|
dialog_export_depth();
|
||||||
subpopup->mouse_release();
|
subpopup->mouse_release();
|
||||||
@@ -655,12 +662,6 @@ void App::init_menu_file()
|
|||||||
dialog_resize();
|
dialog_resize();
|
||||||
popup->mouse_release();
|
popup->mouse_release();
|
||||||
popup->destroy();
|
popup->destroy();
|
||||||
};
|
|
||||||
if (auto b = popup->find<NodeButtonCustom>("file-export-cubes"))
|
|
||||||
b->on_click = [this, popup](Node*) {
|
|
||||||
dialog_export_cubes();
|
|
||||||
popup->mouse_release();
|
|
||||||
popup->destroy();
|
|
||||||
};
|
};
|
||||||
if (auto b = popup->find<NodeButtonCustom>("file-cloud-upload"))
|
if (auto b = popup->find<NodeButtonCustom>("file-cloud-upload"))
|
||||||
b->on_click = [this, popup](Node*) {
|
b->on_click = [this, popup](Node*) {
|
||||||
|
|||||||
194
src/canvas.cpp
194
src/canvas.cpp
@@ -1921,183 +1921,69 @@ 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)
|
||||||
{
|
{
|
||||||
std::shared_ptr<NodeProgressBar> pb;
|
auto pb = App::I->show_progress("Export Layers", m_layers.size());
|
||||||
if (App::I->layout.m_loaded)
|
for (int i = 0; i < m_layers.size(); i++)
|
||||||
{
|
{
|
||||||
pb = std::make_shared<NodeProgressBar>();
|
auto l = m_layers[i];
|
||||||
pb->m_manager = &App::I->layout;
|
Image img = l->gen_equirect().get_image();
|
||||||
pb->init();
|
img.save_png(fmt::format("{}/{}-layer{:02d}-{}.png", App::I->work_path, file_name, i, l->m_name));
|
||||||
pb->create();
|
pb->increment();
|
||||||
pb->loaded();
|
|
||||||
pb->m_progress->SetWidthP(0);
|
|
||||||
pb->m_title->set_text("Export Pano Layers");
|
|
||||||
App::I->layout[App::I->main_id]->add_child(pb);
|
|
||||||
}
|
}
|
||||||
int progress = 0;
|
|
||||||
int total = (int)(m_layers.size() + 1) * 6;
|
|
||||||
|
|
||||||
RTT m_latlong;
|
|
||||||
m_latlong.create(m_width * 4, m_height * 2); // NOTE: w and h must be equal to make sense
|
|
||||||
|
|
||||||
GLuint cube_id;
|
|
||||||
int faces[]{
|
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // front
|
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // right
|
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // back
|
|
||||||
GL_TEXTURE_CUBE_MAP_POSITIVE_X, // left
|
|
||||||
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // top
|
|
||||||
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;
|
|
||||||
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
App::I->render_task([&]
|
|
||||||
{
|
|
||||||
// copy layer to cubemap
|
|
||||||
m_layers[layer_index]->m_rtt[i].bindFramebuffer();
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
|
||||||
glCopyTexImage2D(faces[i], 0, GL_RGBA8, 0, 0, m_width, m_height, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
|
||||||
m_layers[layer_index]->m_rtt[i].unbindFramebuffer();
|
|
||||||
});
|
|
||||||
|
|
||||||
progress++;
|
|
||||||
float p = (float)progress / total * 100.f;
|
|
||||||
LOG("progress: %f", p);
|
|
||||||
|
|
||||||
if (App::I->layout.m_loaded)
|
|
||||||
{
|
|
||||||
pb->m_progress->SetWidthP(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
App::I->render_task([&]
|
|
||||||
{
|
|
||||||
glViewport(0, 0, m_latlong.getWidth(), m_latlong.getHeight());
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_latlong.bindFramebuffer();
|
|
||||||
m_latlong.clear({ 1, 1, 1, 0 });
|
|
||||||
ShaderManager::use(kShader::Equirect);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, cube_id);
|
|
||||||
glDisable(GL_BLEND);
|
|
||||||
m_sampler_linear.bind(0);
|
|
||||||
m_plane.draw_fill();
|
|
||||||
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);
|
|
||||||
m_latlong.unbindFramebuffer();
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
|
||||||
auto latlong_data = std::make_unique<uint8_t[]>(m_latlong.bytes());
|
|
||||||
m_latlong.readTextureData(latlong_data.get());
|
|
||||||
static char name[128];
|
|
||||||
sprintf(name, "%s/%s-layer-%02d.png", App::I->work_path.c_str(), file_name.c_str(), seq);
|
|
||||||
seq++;
|
|
||||||
LOG("writing %s", name);
|
|
||||||
int ret = stbi_write_png(name, m_latlong.getWidth(), m_latlong.getHeight(), 4, latlong_data.get(), m_latlong.stride());
|
|
||||||
}
|
|
||||||
|
|
||||||
progress++;
|
|
||||||
float p = (float)progress / total * 100.f;
|
|
||||||
LOG("progress: %f", p);
|
|
||||||
|
|
||||||
if (App::I->layout.m_loaded)
|
|
||||||
{
|
|
||||||
pb->m_progress->SetWidthP(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
App::I->render_task([&]
|
|
||||||
{
|
|
||||||
glDeleteTextures(1, &cube_id);
|
|
||||||
m_latlong.destroy();
|
|
||||||
});
|
|
||||||
|
|
||||||
if (App::I->layout.m_loaded)
|
|
||||||
{
|
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Canvas::export_cube_faces(std::string file_name, std::function<void()> on_complete)
|
||||||
|
{
|
||||||
|
if (App::I->check_license())
|
||||||
|
{
|
||||||
|
std::thread t([=] {
|
||||||
|
BT_SetTerminate();
|
||||||
|
export_cube_faces_thread(file_name);
|
||||||
|
if (on_complete)
|
||||||
|
on_complete();
|
||||||
|
});
|
||||||
|
t.detach();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::export_cubes()
|
void Canvas::export_cube_faces_thread(std::string file_name)
|
||||||
{
|
{
|
||||||
if (!App::I->check_license())
|
|
||||||
return;
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
NSMutableArray* files = [NSMutableArray array];
|
NSMutableArray* files = [NSMutableArray array];
|
||||||
#endif
|
#endif
|
||||||
std::array<std::string, 6> names {
|
static std::array<const char*, 6> plane_names{ "front", "right", "back", "left", "top", "bottom" };
|
||||||
"pz", "px", "nz", "nx",
|
|
||||||
"py", "ny"
|
|
||||||
};
|
|
||||||
const int stride = m_width * 4;
|
|
||||||
auto buffer = std::make_unique<uint8_t[]>(m_width * m_height * 4);
|
|
||||||
auto flipped = std::make_unique<uint8_t[]>(m_width * m_height * 4);
|
|
||||||
for (int layer = 0; layer < m_layers.size(); layer++)
|
|
||||||
{
|
|
||||||
for (int plane = 0; plane < 6; plane++)
|
|
||||||
{
|
|
||||||
auto& l = m_layers[layer];
|
|
||||||
l->m_rtt[plane].bindFramebuffer();
|
|
||||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, buffer.get());
|
|
||||||
l->m_rtt[plane].unbindFramebuffer();
|
|
||||||
|
|
||||||
if (plane < 4)
|
auto pb = App::I->show_progress("Export Cube Faces", 7);
|
||||||
{
|
|
||||||
for (int y = 0; y < m_height; y++)
|
|
||||||
{
|
|
||||||
int y_rev = m_height - y - 1;
|
|
||||||
std::copy_n(buffer.get() + y * stride, stride, flipped.get() + y_rev * stride);
|
|
||||||
}
|
|
||||||
std::swap(buffer, flipped);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (int y = 0; y < m_height; y++)
|
|
||||||
{
|
|
||||||
auto src = (glm::u8vec4*)(buffer.get() + y * stride);
|
|
||||||
auto dst = (glm::u8vec4*)(flipped.get() + y * stride);
|
|
||||||
for (int x = 0; x < m_width; x++)
|
|
||||||
{
|
|
||||||
int x_rev = m_width - x - 1;
|
|
||||||
dst[x_rev] = src[x];
|
|
||||||
}
|
|
||||||
//std::copy_backward(src + stride, src, dst + stride);
|
|
||||||
}
|
|
||||||
std::swap(buffer, flipped);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char name[128];
|
App::I->render_task([this] {
|
||||||
sprintf(name, "%s-%02d-%d.png", App::I->work_path.c_str(), layer, plane);
|
draw_merge(false);
|
||||||
int ret = stbi_write_png(name, m_width, m_height, 4, buffer.get(), 0);
|
});
|
||||||
|
pb->increment();
|
||||||
|
|
||||||
|
for (int i = 0; i < 6; i++)
|
||||||
|
{
|
||||||
|
Image face = m_layers_merge.m_rtt[i].get_image();
|
||||||
|
std::string path = fmt::format("{}/{}-{}.png", App::I->work_path, file_name, plane_names[i]);
|
||||||
|
face.save_png(path);
|
||||||
|
pb->increment();
|
||||||
|
|
||||||
#ifdef __IOS__
|
#ifdef __IOS__
|
||||||
save_image_library(name);
|
save_image_library(path);
|
||||||
#endif
|
#endif
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
[files addObject:[NSString stringWithUTF8String : name]];
|
[files addObject : [NSString stringWithUTF8String:path.c_str()] ];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
pb->destroy();
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
static char name[128];
|
static char name[128];
|
||||||
sprintf(name, "%s.zip", App::I->work_path.c_str());
|
sprintf(name, "%s.zip", App::I->work_path.c_str());
|
||||||
auto zip_path = [NSString stringWithUTF8String : name];
|
auto zip_path = [NSString stringWithUTF8String:name];
|
||||||
//[SSZipArchive createZipFileAtPath:zip_path withFilesAtPaths:files];
|
//[SSZipArchive createZipFileAtPath:zip_path withFilesAtPaths:files];
|
||||||
for (NSString* f : files)
|
//for (NSString* f : files)
|
||||||
[[NSFileManager defaultManager] removeItemAtPath:f error:nil];
|
// [[NSFileManager defaultManager] removeItemAtPath:f error:nil];
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,8 @@ public:
|
|||||||
void export_layers_thread(std::string file_name);
|
void export_layers_thread(std::string file_name);
|
||||||
void export_depth(std::string file_name, std::function<void()> on_complete = nullptr);
|
void export_depth(std::string file_name, std::function<void()> on_complete = nullptr);
|
||||||
void export_depth_thread(std::string file_name);
|
void export_depth_thread(std::string file_name);
|
||||||
void export_cubes();
|
void export_cube_faces(std::string file_name, std::function<void()> on_complete);
|
||||||
|
void export_cube_faces_thread(std::string file_name);
|
||||||
void project_save(std::function<void(bool)> on_complete = nullptr);
|
void project_save(std::function<void(bool)> on_complete = nullptr);
|
||||||
void project_save(std::string file_path, std::function<void(bool)> on_complete = nullptr);
|
void project_save(std::string file_path, std::function<void(bool)> on_complete = nullptr);
|
||||||
bool project_save_thread(std::string file_path, bool show_progress);
|
bool project_save_thread(std::string file_path, bool show_progress);
|
||||||
|
|||||||
28
src/node.cpp
28
src/node.cpp
@@ -40,7 +40,7 @@
|
|||||||
void Node::app_redraw()
|
void Node::app_redraw()
|
||||||
{
|
{
|
||||||
App::I->redraw = true;
|
App::I->redraw = true;
|
||||||
App::I->ui_cv.notify_all();
|
App::I->render_cv.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::watch(std::function<bool(Node*)> observer)
|
void Node::watch(std::function<bool(Node*)> observer)
|
||||||
@@ -82,11 +82,11 @@ kEventResult Node::on_event(Event* e)
|
|||||||
{
|
{
|
||||||
kEventResult ret = kEventResult::Available;
|
kEventResult ret = kEventResult::Available;
|
||||||
|
|
||||||
if (current_mouse_capture && current_mouse_capture != this)
|
if (current_mouse_capture && current_mouse_capture.get() != this)
|
||||||
{
|
{
|
||||||
if (e->m_cat == kEventCategory::MouseEvent &&
|
if (e->m_cat == kEventCategory::MouseEvent &&
|
||||||
child_mouse_focus != current_mouse_capture &&
|
child_mouse_focus != current_mouse_capture &&
|
||||||
is_child(current_mouse_capture))
|
is_child(current_mouse_capture.get()))
|
||||||
{
|
{
|
||||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||||
if (child_mouse_focus)
|
if (child_mouse_focus)
|
||||||
@@ -115,7 +115,7 @@ kEventResult Node::on_event(Event* e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
skip_children |= (e->m_cat == kEventCategory::MouseEvent || e->m_cat == kEventCategory::GestureEvent) &&
|
skip_children |= (e->m_cat == kEventCategory::MouseEvent || e->m_cat == kEventCategory::GestureEvent) &&
|
||||||
(m_mouse_captured) && (root()->current_mouse_capture == this) && m_capture_children; // <-- THIS IS WRONG "!m_capture_children" is correct, but it breaks everything if changed
|
(m_mouse_captured) && (root()->current_mouse_capture.get() == this) && m_capture_children; // <-- THIS IS WRONG "!m_capture_children" is correct, but it breaks everything if changed
|
||||||
|
|
||||||
if (!m_display || glm::any(glm::lessThanEqual(zw(m_clip), { 0, 0 })))
|
if (!m_display || glm::any(glm::lessThanEqual(zw(m_clip), { 0, 0 })))
|
||||||
return kEventResult::Available;
|
return kEventResult::Available;
|
||||||
@@ -134,7 +134,7 @@ kEventResult Node::on_event(Event* e)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus != it->get())
|
if (e->m_cat == kEventCategory::MouseEvent && child_mouse_focus.get() != it->get())
|
||||||
{
|
{
|
||||||
MouseEvent* me = static_cast<MouseEvent*>(e);
|
MouseEvent* me = static_cast<MouseEvent*>(e);
|
||||||
if (child_mouse_focus)
|
if (child_mouse_focus)
|
||||||
@@ -147,7 +147,7 @@ kEventResult Node::on_event(Event* e)
|
|||||||
MouseEvent e2 = *me;
|
MouseEvent e2 = *me;
|
||||||
e2.m_type = kEventType::MouseFocus;
|
e2.m_type = kEventType::MouseFocus;
|
||||||
(*it)->handle_event(&e2);
|
(*it)->handle_event(&e2);
|
||||||
child_mouse_focus = it->get();
|
child_mouse_focus = *it;
|
||||||
child_mouse_focus->m_mouse_focus = true;
|
child_mouse_focus->m_mouse_focus = true;
|
||||||
}
|
}
|
||||||
ret = kEventResult::Consumed;
|
ret = kEventResult::Consumed;
|
||||||
@@ -401,7 +401,7 @@ void Node::remove_child(Node* n)
|
|||||||
YGNodeRemoveChild(y_node, n->y_node);
|
YGNodeRemoveChild(y_node, n->y_node);
|
||||||
on_child_removed(n);
|
on_child_removed(n);
|
||||||
m_children.erase(i);
|
m_children.erase(i);
|
||||||
if (child_mouse_focus == n)
|
if (child_mouse_focus.get() == n)
|
||||||
child_mouse_focus = nullptr;
|
child_mouse_focus = nullptr;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -542,7 +542,8 @@ void Node::mouse_capture()
|
|||||||
auto& s = root()->m_capture_stack;
|
auto& s = root()->m_capture_stack;
|
||||||
|
|
||||||
// already owner of capture
|
// already owner of capture
|
||||||
if (c == this || std::find(s.begin(), s.end(), this) != s.end())
|
if (c.get() == this || std::find_if(s.begin(), s.end(),
|
||||||
|
[this](const auto& a) { return a.get() == this; }) != s.end())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (c)
|
if (c)
|
||||||
@@ -570,7 +571,7 @@ void Node::mouse_capture()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// make current
|
// make current
|
||||||
c = this;
|
c = shared_from_this();
|
||||||
m_mouse_captured = true;
|
m_mouse_captured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -582,8 +583,9 @@ void Node::mouse_release()
|
|||||||
auto& c = root()->current_mouse_capture;
|
auto& c = root()->current_mouse_capture;
|
||||||
auto& s = root()->m_capture_stack;
|
auto& s = root()->m_capture_stack;
|
||||||
|
|
||||||
s.erase(std::remove(s.begin(), s.end(), this), s.end());
|
s.erase(std::remove_if(s.begin(), s.end(),
|
||||||
if (c == this)
|
[this](const auto& a) { return a.get() == this; }), s.end());
|
||||||
|
if (c.get() == this)
|
||||||
{
|
{
|
||||||
if (s.empty())
|
if (s.empty())
|
||||||
{
|
{
|
||||||
@@ -604,7 +606,7 @@ void Node::key_capture()
|
|||||||
if (!m_parent)
|
if (!m_parent)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
root()->current_key_capture = this;
|
root()->current_key_capture = shared_from_this();
|
||||||
m_key_captured = true;
|
m_key_captured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1376,8 +1378,6 @@ void Node::clone_copy(Node* dest) const
|
|||||||
dest->m_pos_offset = m_pos_offset;
|
dest->m_pos_offset = m_pos_offset;
|
||||||
dest->m_pos_offset_childred = m_pos_offset_childred;
|
dest->m_pos_offset_childred = m_pos_offset_childred;
|
||||||
dest->m_clip_uncut = m_clip_uncut;
|
dest->m_clip_uncut = m_clip_uncut;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Node::clone_children(Node* dest) const
|
void Node::clone_children(Node* dest) const
|
||||||
|
|||||||
@@ -103,9 +103,9 @@ public:
|
|||||||
uint16_t m_nodeID;
|
uint16_t m_nodeID;
|
||||||
std::string m_nodeID_s;
|
std::string m_nodeID_s;
|
||||||
std::vector<std::shared_ptr<Node>> m_children;
|
std::vector<std::shared_ptr<Node>> m_children;
|
||||||
Node* current_mouse_capture = nullptr;
|
std::shared_ptr<Node> current_mouse_capture = nullptr;
|
||||||
Node* current_key_capture = nullptr;
|
std::shared_ptr<Node> current_key_capture = nullptr;
|
||||||
Node* child_mouse_focus = nullptr;
|
std::shared_ptr<Node> child_mouse_focus = nullptr;
|
||||||
bool m_mouse_captured = false;
|
bool m_mouse_captured = false;
|
||||||
bool m_key_captured = false;
|
bool m_key_captured = false;
|
||||||
|
|
||||||
@@ -117,7 +117,7 @@ public:
|
|||||||
bool m_force_mouse_capture = false;
|
bool m_force_mouse_capture = false;
|
||||||
bool m_capture_children = true; // wether to capture children events when xx_capture() is used
|
bool m_capture_children = true; // wether to capture children events when xx_capture() is used
|
||||||
bool m_destroyed = false;
|
bool m_destroyed = false;
|
||||||
std::vector<Node*> m_capture_stack;
|
std::vector<std::shared_ptr<Node>> m_capture_stack;
|
||||||
|
|
||||||
bool m_mouse_ignore = true;
|
bool m_mouse_ignore = true;
|
||||||
float m_zoom = 1.f;
|
float m_zoom = 1.f;
|
||||||
|
|||||||
@@ -63,6 +63,14 @@ void NodeCanvas::clear_context()
|
|||||||
|
|
||||||
void NodeCanvas::draw()
|
void NodeCanvas::draw()
|
||||||
{
|
{
|
||||||
|
// sanity checks
|
||||||
|
float zoom = root()->m_zoom;
|
||||||
|
if (zoom == 0.f)
|
||||||
|
zoom = 1.f;
|
||||||
|
auto box = m_clip * zoom;
|
||||||
|
if (box.z == 0 || box.w == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
GLint vp[4];
|
GLint vp[4];
|
||||||
GLfloat cc[4];
|
GLfloat cc[4];
|
||||||
glGetIntegerv(GL_VIEWPORT, vp);
|
glGetIntegerv(GL_VIEWPORT, vp);
|
||||||
@@ -73,8 +81,6 @@ void NodeCanvas::draw()
|
|||||||
|
|
||||||
glDisable(GL_SCISSOR_TEST);
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
float zoom = root()->m_zoom;
|
|
||||||
auto box = m_clip * zoom;
|
|
||||||
glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
glm::ivec4 c = (glm::ivec4)glm::vec4(box.x, (int)(vp[3] - box.y - box.w), box.z, box.w);
|
||||||
|
|
||||||
//m_canvas->m_cam_rot = m_pan * 0.003f;
|
//m_canvas->m_cam_rot = m_pan * 0.003f;
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ void NodeComboBox::loaded()
|
|||||||
m_current_index = index;
|
m_current_index = index;
|
||||||
m_selected_child_index = popup->get_child_index(target);
|
m_selected_child_index = popup->get_child_index(target);
|
||||||
m_text->set_text(m_items[index].c_str());
|
m_text->set_text(m_items[index].c_str());
|
||||||
popup->mouse_release();
|
|
||||||
popup->destroy();
|
|
||||||
if (on_select)
|
if (on_select)
|
||||||
on_select(btn, index);
|
on_select(btn, index);
|
||||||
|
popup->mouse_release();
|
||||||
|
popup->destroy();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -442,8 +442,7 @@ void NodePanelBrushPreset::init()
|
|||||||
if (!m_current)
|
if (!m_current)
|
||||||
return;
|
return;
|
||||||
int index = m_container->get_child_index(m_current);
|
int index = m_container->get_child_index(m_current);
|
||||||
m_current->destroy_immediate();
|
m_current->destroy();
|
||||||
m_container->remove_child(m_current);
|
|
||||||
if (m_container->m_children.empty())
|
if (m_container->m_children.empty())
|
||||||
{
|
{
|
||||||
m_current = nullptr;
|
m_current = nullptr;
|
||||||
|
|||||||
@@ -467,7 +467,7 @@ 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->set_progress((float)pb_value / (float)fb.getHeight());
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||||
}
|
}
|
||||||
worker.join();
|
worker.join();
|
||||||
|
|||||||
@@ -76,8 +76,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
brush->m_user_brush = true;
|
brush->m_user_brush = true;
|
||||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_brush_popup, std::placeholders::_1);
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_brush_popup, std::placeholders::_1);
|
||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
pb->set_progress((float)count / (float)tot);
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
|
||||||
});
|
});
|
||||||
m_brush_popup->save();
|
m_brush_popup->save();
|
||||||
|
|
||||||
@@ -105,8 +104,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
brush->m_user_brush = true;
|
brush->m_user_brush = true;
|
||||||
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_pattern_popup, std::placeholders::_1);
|
brush->on_click = std::bind(&NodePanelBrush::handle_click, m_pattern_popup, std::placeholders::_1);
|
||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
pb->set_progress((float)count / (float)tot);
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
|
||||||
});
|
});
|
||||||
m_pattern_popup->save();
|
m_pattern_popup->save();
|
||||||
|
|
||||||
@@ -119,8 +117,7 @@ bool NodePanelStroke::import_abr(const std::string& path)
|
|||||||
App::I->presets->add_brush(pr);
|
App::I->presets->add_brush(pr);
|
||||||
}
|
}
|
||||||
count++;
|
count++;
|
||||||
float prog = (float)count / (float)tot;
|
pb->set_progress((float)count / (float)tot);
|
||||||
pb->m_progress->SetWidthP(prog * 100.f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
App::I->presets->save();
|
App::I->presets->save();
|
||||||
|
|||||||
@@ -20,5 +20,17 @@ void NodeProgressBar::init()
|
|||||||
btn_cancel->on_click = [&](Node*) { destroy(); };
|
btn_cancel->on_click = [&](Node*) { destroy(); };
|
||||||
m_progress = find<NodeBorder>("progress");
|
m_progress = find<NodeBorder>("progress");
|
||||||
|
|
||||||
m_progress->SetWidthP(10);
|
m_progress->SetWidthP(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeProgressBar::increment() noexcept
|
||||||
|
{
|
||||||
|
m_count++;
|
||||||
|
if (m_total != 0)
|
||||||
|
m_progress->SetWidthP(((float)m_count / m_total) * 100.f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NodeProgressBar::set_progress(float p) noexcept
|
||||||
|
{
|
||||||
|
m_progress->SetWidthP(p * 100.f);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,11 @@ public:
|
|||||||
NodeButton* btn_cancel;
|
NodeButton* btn_cancel;
|
||||||
NodeText* m_title;
|
NodeText* m_title;
|
||||||
NodeBorder* m_progress;
|
NodeBorder* m_progress;
|
||||||
|
int m_total = 0;
|
||||||
|
int m_count = 0;
|
||||||
virtual Node* clone_instantiate() const override;
|
virtual Node* clone_instantiate() const override;
|
||||||
virtual void init() override;
|
virtual void init() override;
|
||||||
|
void increment() noexcept;
|
||||||
|
// set progress where p [0, 1]
|
||||||
|
void set_progress(float p) noexcept;
|
||||||
};
|
};
|
||||||
|
|||||||
16
src/rtt.cpp
16
src/rtt.cpp
@@ -274,7 +274,7 @@ void RTT::clear_mask(glm::bool4 mask, glm::vec4 color)
|
|||||||
glColorMask(old_mask[0], old_mask[1], old_mask[2], old_mask[3]);
|
glColorMask(old_mask[0], old_mask[1], old_mask[2], old_mask[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::ivec4 RTT::calc_bounds()
|
glm::ivec4 RTT::calc_bounds() const noexcept
|
||||||
{
|
{
|
||||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(readTextureData()));
|
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(readTextureData()));
|
||||||
glm::ivec2 bbmin(w, h);
|
glm::ivec2 bbmin(w, h);
|
||||||
@@ -293,7 +293,7 @@ glm::ivec4 RTT::calc_bounds()
|
|||||||
return { bbmin, bbmax };
|
return { bbmin, bbmax };
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RTT::readTextureData(uint8_t* buffer)
|
uint8_t* RTT::readTextureData(uint8_t* buffer) const noexcept
|
||||||
{
|
{
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
buffer = createBuffer();
|
buffer = createBuffer();
|
||||||
@@ -308,7 +308,7 @@ uint8_t* RTT::readTextureData(uint8_t* buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
float* RTT::readTextureDataFloat(float* buffer)
|
float* RTT::readTextureDataFloat(float* buffer) const noexcept
|
||||||
{
|
{
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
buffer = createBufferFloat();
|
buffer = createBufferFloat();
|
||||||
@@ -323,12 +323,12 @@ float* RTT::readTextureDataFloat(float* buffer)
|
|||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t* RTT::createBuffer()
|
uint8_t* RTT::createBuffer() const noexcept
|
||||||
{
|
{
|
||||||
return new uint8_t[w * h * 4];
|
return new uint8_t[w * h * 4];
|
||||||
}
|
}
|
||||||
|
|
||||||
float * RTT::createBufferFloat()
|
float * RTT::createBufferFloat() const noexcept
|
||||||
{
|
{
|
||||||
return new float[w * h * 4];
|
return new float[w * h * 4];
|
||||||
}
|
}
|
||||||
@@ -345,4 +345,10 @@ void RTT::unbindTexture()
|
|||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image RTT::get_image() const noexcept
|
||||||
|
{
|
||||||
|
Image ret;
|
||||||
|
ret.create(w, h, readTextureData());
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
26
src/rtt.h
26
src/rtt.h
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
#include "image.h"
|
||||||
|
|
||||||
class RTT
|
class RTT
|
||||||
{
|
{
|
||||||
@@ -28,20 +29,21 @@ public:
|
|||||||
bool recreate() { return create(w, h); }
|
bool recreate() { return create(w, h); }
|
||||||
void clear(glm::vec4 color = glm::vec4(0));
|
void clear(glm::vec4 color = glm::vec4(0));
|
||||||
void clear_mask(glm::bool4 mask, glm::vec4 color = glm::vec4(0));
|
void clear_mask(glm::bool4 mask, glm::vec4 color = glm::vec4(0));
|
||||||
glm::ivec4 calc_bounds();
|
glm::ivec4 calc_bounds() const noexcept;
|
||||||
uint8_t* readTextureData(uint8_t* buffer = nullptr);
|
uint8_t* readTextureData(uint8_t* buffer = nullptr) const noexcept;
|
||||||
float* readTextureDataFloat(float* buffer = nullptr);
|
float* readTextureDataFloat(float* buffer = nullptr) const noexcept;
|
||||||
uint8_t* createBuffer();
|
uint8_t* createBuffer() const noexcept;
|
||||||
float* createBufferFloat();
|
float* createBufferFloat() const noexcept;
|
||||||
void bindFramebuffer();
|
void bindFramebuffer();
|
||||||
void unbindFramebuffer();
|
void unbindFramebuffer();
|
||||||
void bindTexture();
|
void bindTexture();
|
||||||
void unbindTexture();
|
void unbindTexture();
|
||||||
GLuint getTextureID() const { return texID; }
|
GLuint getTextureID() const noexcept { return texID; }
|
||||||
int getWidth() const { return w; }
|
int getWidth() const noexcept { return w; }
|
||||||
int getHeight() const { return h; }
|
int getHeight() const noexcept { return h; }
|
||||||
glm::ivec2 getSize() const { return { w, h }; }
|
glm::ivec2 getSize() const noexcept { return { w, h }; }
|
||||||
int bytes() const { return w * h * 4; }
|
int bytes() const noexcept { return w * h * 4; }
|
||||||
int stride() const { return w * 4; }
|
int stride() const noexcept { return w * 4; }
|
||||||
GLuint getFBO() const { return fboID; }
|
GLuint getFBO() const noexcept { return fboID; }
|
||||||
|
Image get_image() const noexcept;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user