implement layers merge down

This commit is contained in:
2017-08-10 09:18:56 +01:00
parent e134ba553d
commit 76b572831f
9 changed files with 158 additions and 8 deletions

View File

@@ -612,6 +612,89 @@ void ui::Canvas::layer_order(int idx, int pos)
{
std::swap(m_order[idx], m_order[pos]);
}
void ui::Canvas::layer_merge(int source_idx, int dest_idx)
{
m_dirty = false;
// 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);
// allocate action to add to history
auto action = new ActionStroke;
// prepare common states
glViewport(0, 0, m_width, m_height);
glDisable(GL_BLEND);
for (int i = 0; i < 6; i++)
{
if (!m_layers[source_idx].m_dirty_face[i])
continue; // no stroke on this face, skip it
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];
lbox.xy = glm::min(m_layers[source_idx].m_dirty_box[i].xy(), lbox.xy());
lbox.zw = glm::max(m_layers[source_idx].m_dirty_box[i].zw(), lbox.zw());
m_layers[dest_idx].m_dirty_face[i] = true;
// copy to tmp2 for layer blending
glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
m_tex2[i].unbind();
m_sampler.bind(0);
m_sampler_bg.bind(1);
{
ui::ShaderManager::use(kShader::CompDraw);
ui::ShaderManager::u_int(kShaderUniform::Tex, 0); // dest
ui::ShaderManager::u_int(kShaderUniform::TexStroke, 1); // source
ui::ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f));
glActiveTexture(GL_TEXTURE0);
m_tex2[i].bind();
glActiveTexture(GL_TEXTURE1);
m_layers[source_idx].m_rtt[i].bindTexture();
m_plane.draw_fill();
m_layers[source_idx].m_rtt[i].unbindTexture();
glActiveTexture(GL_TEXTURE0);
m_tex2[i].unbind();
}
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 ui::Canvas::resize(int width, int height)
{
m_width = width;