add history to layer create, delete, move, rename, and merge

This commit is contained in:
2019-06-18 17:39:35 +02:00
parent c48a6da8a6
commit 9ee4bc42b9
12 changed files with 259 additions and 137 deletions

View File

@@ -92,14 +92,14 @@ void Canvas::pick_update(int plane)
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
glActiveTexture(GL_TEXTURE0);
m_sampler.bind(0);
for (auto layer_index : m_order)
for (auto& l : m_layers)
{
if (!m_layers[layer_index]->m_visible || m_layers[layer_index]->m_opacity == 0.f)
if (!l->m_visible || l->m_opacity == 0.f)
continue;
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
m_layers[layer_index]->m_rtt[i].bindTexture();
ShaderManager::u_float(kShaderUniform::Alpha, l->m_opacity);
l->m_rtt[i].bindTexture();
m_plane.draw_fill();
m_layers[layer_index]->m_rtt[i].unbindTexture();
l->m_rtt[i].unbindTexture();
}
m_sampler.unbind();
@@ -905,10 +905,9 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
// check if any layer use blend, otherwise draw directly on main framebuffer
bool use_blend = false;
for (size_t i = 0; i < m_order.size(); i++)
for (auto& l : m_layers)
{
auto layer_index = m_order[i];
use_blend |= m_layers[layer_index]->m_blend_mode != 0;
use_blend |= l->m_blend_mode != 0;
}
// if not using shader blend, use gl rasterizer blend
@@ -935,7 +934,7 @@ void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
glEnable(GL_BLEND);
}
for (int layer_index : m_order)
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
if (!(m_show_tmp && m_current_layer_idx == layer_index) &&
(!m_layers[layer_index]->m_visible ||
@@ -1223,37 +1222,31 @@ void Canvas::stroke_start(glm::vec3 point, float pressure)
}
m_show_tmp = true;
}
void Canvas::layer_add(std::string name, std::unique_ptr<Layer> layer /*= nullptr*/, int index /*= 0*/)
void Canvas::layer_add(std::string name, std::shared_ptr<Layer> layer /*= nullptr*/, int index /*= 0*/)
{
LOG("canvas layer_add %s", name.c_str());
int idx = (int)m_layers.size();
if (layer)
{
m_layers.push_back(std::move(layer));
m_layers.insert(m_layers.begin() + index, layer);
}
else
{
m_layers.push_back(std::make_unique<Layer>());
m_layers.back()->create(m_width, m_height, name);
m_layers.insert(m_layers.begin() + index, std::make_unique<Layer>());
m_layers[index]->create(m_width, m_height, name);
}
m_order.push_back(idx);
m_current_layer_idx = idx;
m_current_layer_idx = index;
}
void Canvas::layer_remove(int idx) // m_order index
{
LOG("canvas layer_remove %d", idx);
int n = m_order[idx];
for (auto& i : m_order)
if (i > n)
i--;
//m_layers[n]->destroy();
m_layers.erase(m_layers.begin() + n);
m_order.erase(m_order.begin() + idx);
m_current_layer_idx = m_order[std::min<int>((int)m_layers.size() - 1, idx)];
m_layers.erase(m_layers.begin() + idx);
m_current_layer_idx = std::min<int>((int)m_layers.size() - 1, idx);
}
void Canvas::layer_order(int idx, int pos) // m_order index
{
std::swap(m_order[idx], m_order[pos]);
std::swap(m_layers[idx], m_layers[pos]);
}
void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
{
@@ -1635,7 +1628,7 @@ void Canvas::export_equirectangular_thread(std::string file_path)
}
m_sampler_bg.bind(0); // nearest
m_sampler_mask.bind(1); // linear
for (auto layer_index : m_order)
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
if (!m_layers[layer_index]->m_visible ||
m_layers[layer_index]->m_opacity == 0.f ||
@@ -1918,9 +1911,8 @@ void Canvas::export_depth_thread(std::string file_name)
delete rgba_data;
rtt.clear({ 0, 0, 0, 1 });
for (size_t i = 0; i < m_order.size(); i++)
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
auto layer_index = m_order[i];
for (int plane_index = 0; plane_index < 6; plane_index++)
{
if ((!m_layers[layer_index]->m_visible ||
@@ -1937,7 +1929,7 @@ void Canvas::export_depth_thread(std::string file_name)
m_sampler_linear.bind(1);
ShaderManager::use(kShader::TextureColorize);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_vec4(kShaderUniform::Col, { glm::vec3((float)(i + 1) / (float)(m_order.size() + 1)), 1.f });
ShaderManager::u_vec4(kShaderUniform::Col, { glm::vec3((float)(layer_index + 1) / (float)(m_layers.size() + 1)), 1.f });
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
glActiveTexture(GL_TEXTURE0);
@@ -2000,7 +1992,7 @@ void Canvas::export_layers_thread(std::string file_name)
App::I.async_update();
}
int progress = 0;
int total = (int)(m_order.size() + 1) * 6;
int total = (int)(m_layers.size() + 1) * 6;
// prepare common states
glViewport(0, 0, m_width, m_height);
@@ -2023,7 +2015,7 @@ void Canvas::export_layers_thread(std::string file_name)
};
int seq = 0;
for (auto layer_index : m_order)
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++)
@@ -2150,11 +2142,11 @@ void Canvas::export_cubes()
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_order.size(); layer++)
{
for (int layer = 0; layer < m_layers.size(); layer++)
{
for (int plane = 0; plane < 6; plane++)
{
auto& l = m_layers[m_order[layer]];
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();
@@ -2332,7 +2324,7 @@ bool Canvas::project_save_thread(std::string file_path)
for (int i = 0; i < (int)m_layers.size(); i++)
{
int n_order = m_order[i];
int n_order = i;
fwrite(&n_order, sizeof(int), 1, fp);
float layer_alpha = m_layers[i]->m_opacity;
@@ -2504,13 +2496,11 @@ bool Canvas::project_open_thread(std::string file_path)
for (auto& l : m_layers)
l->destroy();
m_layers.clear();
m_order.clear();
//clear_all();
resize(m_width, m_height);
App::I.async_end();
std::vector<int> tmp_order;
std::vector<std::unique_ptr<Layer>> tmp_layers;
std::vector<std::shared_ptr<Layer>> tmp_layers;
for (int i = 0; i < n_layers; i++)
{
@@ -2580,11 +2570,9 @@ bool Canvas::project_open_thread(std::string file_path)
tmp_layers.back()->create(m_width, m_height, name.c_str());
tmp_layers.back()->clear({ 0, 0, 0, 0 });
tmp_layers.back()->restore(snap);
tmp_order.push_back(n_order);
App::I.async_end();
}
std::swap(tmp_order, m_order);
std::swap(tmp_layers, m_layers);
fclose(fp);
@@ -2665,7 +2653,7 @@ Image Canvas::thumbnail_generate(int w, int h)
}
m_sampler_bg.bind(0); // nearest
m_sampler_mask.bind(1); // linear
for (auto layer_index : m_order)
for (int layer_index = 0; layer_index < m_layers.size(); layer_index++)
{
if (!m_layers[layer_index]->m_visible ||
m_layers[layer_index]->m_opacity == 0.f ||
@@ -3080,7 +3068,7 @@ void Layer::restore(const Snapshot& snap)
}
}
Layer::Snapshot Layer::snapshot()
Layer::Snapshot Layer::snapshot(glm::vec4 dirty_box[6] /*= nullptr*/, bool dirty_face[6] /*= nullptr*/)
{
Snapshot snap;
static int counter = 0;
@@ -3088,18 +3076,18 @@ Layer::Snapshot Layer::snapshot()
//glBindFramebuffer(GL_FRAMEBUFFER, 0);
for (int i = 0; i < 6; i++)
{
snap.m_dirty_box[i] = m_dirty_box[i];
snap.m_dirty_face[i] = m_dirty_face[i];
snap.m_dirty_box[i] = dirty_box ? dirty_box[i] : m_dirty_box[i];
snap.m_dirty_face[i] = dirty_face ? dirty_face[i] : m_dirty_face[i];
if (!m_dirty_face[i])
if (!snap.m_dirty_face[i])
continue;
snap.image[i] = std::make_unique<uint8_t[]>(m_rtt[i].bytes());
//glReadBuffer(GL_BACK);
m_rtt[i].bindFramebuffer();
glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]);
glReadPixels(m_dirty_box[i].x, m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
glm::vec2 box_sz = zw(snap.m_dirty_box[i]) - xy(snap.m_dirty_box[i]);
glReadPixels(snap.m_dirty_box[i].x, snap.m_dirty_box[i].y, box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, snap.image[i].get());
m_rtt[i].unbindFramebuffer();
//glReadBuffer(GL_NONE);
}