remove direct use of rtt and dirty area from the layer
This commit is contained in:
@@ -179,11 +179,11 @@ void App::init_sidebar()
|
||||
auto& src = Canvas::I->m_layers[source_index];
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!src->m_dirty_face[i])
|
||||
if (!src->face(i))
|
||||
continue;
|
||||
dst->m_rtt[i].copy(src->m_rtt[i]);
|
||||
dst->m_dirty_face[i] = src->m_dirty_face[i];
|
||||
dst->m_dirty_box[i] = src->m_dirty_box[i];
|
||||
dst->rtt(i).copy(src->rtt(i));
|
||||
dst->face(i) = src->face(i);
|
||||
dst->box(i) = src->box(i);
|
||||
dst->m_opacity = src->m_opacity;
|
||||
dst->m_blend_mode = src->m_blend_mode;
|
||||
dst->m_alpha_locked = src->m_alpha_locked;
|
||||
|
||||
@@ -211,7 +211,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
if (!(canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index) &&
|
||||
(!canvas->m_canvas->m_layers[layer_index]->m_visible ||
|
||||
canvas->m_canvas->m_layers[layer_index]->m_opacity == .0f ||
|
||||
!canvas->m_canvas->m_layers[layer_index]->m_dirty_face[plane_index]))
|
||||
!canvas->m_canvas->m_layers[layer_index]->face(plane_index)))
|
||||
continue;
|
||||
|
||||
int z = (int)(canvas->m_canvas->m_layers.size() - i);
|
||||
@@ -236,17 +236,17 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
ShaderManager::u_int(kShaderUniform::Mask, canvas->m_canvas->m_smask_active);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
canvas->m_canvas->m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||
canvas->m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
canvas->m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
canvas->m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else if (canvas->m_canvas->m_show_tmp && canvas->m_canvas->m_current_layer_idx == layer_index)
|
||||
{
|
||||
@@ -287,11 +287,11 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
canvas->m_canvas->m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
canvas->m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||
canvas->m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
if (b->m_dual_enabled)
|
||||
canvas->m_canvas->m_tmp_dual[plane_index].bindTexture();
|
||||
@@ -304,11 +304,11 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
if (b->m_dual_enabled)
|
||||
canvas->m_canvas->m_tmp_dual[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
canvas->m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
canvas->m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
canvas->m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -320,9 +320,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
canvas->m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
canvas->m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
315
src/canvas.cpp
315
src/canvas.cpp
@@ -81,11 +81,11 @@ void Canvas::pick_update(int plane)
|
||||
draw_merge(true, faces);
|
||||
|
||||
int i = plane;
|
||||
m_layers_merge.m_rtt[i].bindFramebuffer();
|
||||
m_layers_merge.rtt(i).bindFramebuffer();
|
||||
if (!m_pick_data[plane])
|
||||
m_pick_data[plane] = std::make_unique<glm::u8vec4[]>(m_width * m_height);
|
||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_pick_data[plane].get());
|
||||
m_layers_merge.m_rtt[i].unbindFramebuffer();
|
||||
m_layers_merge.rtt(i).unbindFramebuffer();
|
||||
});
|
||||
|
||||
m_pick_ready[plane] = true;
|
||||
@@ -168,7 +168,7 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||
{
|
||||
if (!m_layers[layer_index]->m_visible ||
|
||||
m_layers[layer_index]->m_opacity == .0f ||
|
||||
!m_layers[layer_index]->m_dirty_face[plane_index])
|
||||
!m_layers[layer_index]->face(plane_index))
|
||||
continue;
|
||||
|
||||
//glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)m_mixer.getWidth() / m_mixer.getHeight(), 0.1f, 1000.f);
|
||||
@@ -198,17 +198,17 @@ void Canvas::stroke_draw_mix(const glm::vec2& bb_min, const glm::vec2& bb_sz)
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_smask.rtt(plane_index).bindTexture();
|
||||
m_node->m_face_plane.draw_fill();
|
||||
m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
m_sampler.unbind();
|
||||
m_mixer.unbindFramebuffer();
|
||||
@@ -766,7 +766,7 @@ void Canvas::stroke_commit()
|
||||
if (!m_dirty_face[i])
|
||||
continue; // no stroke on this face, skip it
|
||||
|
||||
m_layers[m_current_layer_idx]->m_rtt[i].bindFramebuffer();
|
||||
m_layers[m_current_layer_idx]->rtt(i).bindFramebuffer();
|
||||
|
||||
// save image before commit
|
||||
glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]);
|
||||
@@ -774,18 +774,18 @@ void Canvas::stroke_commit()
|
||||
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];
|
||||
action->m_old_box[i] = m_layers[m_current_layer_idx]->box(i);
|
||||
action->m_old_dirty[i] = m_layers[m_current_layer_idx]->face(i);
|
||||
|
||||
if (!m_layers[m_current_layer_idx]->m_alpha_locked)
|
||||
{
|
||||
auto& lbox = m_layers[m_current_layer_idx]->m_dirty_box[i];
|
||||
auto& lbox = m_layers[m_current_layer_idx]->box(i);
|
||||
lbox = glm::vec4(
|
||||
glm::min(xy(m_dirty_box[i]), xy(lbox)),
|
||||
glm::max(zw(m_dirty_box[i]), zw(lbox))
|
||||
);
|
||||
}
|
||||
m_layers[m_current_layer_idx]->m_dirty_face[i] = true;
|
||||
m_layers[m_current_layer_idx]->face(i) = true;
|
||||
|
||||
// copy to tmp2 for layer blending
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -816,9 +816,9 @@ void Canvas::stroke_commit()
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[i].bindTexture();
|
||||
m_smask.rtt(i).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_smask.m_rtt[i].unbindTexture();
|
||||
m_smask.rtt(i).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -860,7 +860,7 @@ void Canvas::stroke_commit()
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[i].bindTexture();
|
||||
m_smask.rtt(i).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
if (b->m_dual_enabled)
|
||||
m_tmp_dual[i].bindTexture();
|
||||
@@ -873,7 +873,7 @@ void Canvas::stroke_commit()
|
||||
if (b->m_dual_enabled)
|
||||
m_tmp_dual[i].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[i].unbindTexture();
|
||||
m_smask.rtt(i).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[i].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -904,7 +904,7 @@ void Canvas::stroke_commit()
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||
m_plane.draw_fill();
|
||||
|
||||
m_layers[m_current_layer_idx]->m_rtt[i].unbindFramebuffer();
|
||||
m_layers[m_current_layer_idx]->rtt(i).unbindFramebuffer();
|
||||
}
|
||||
|
||||
// restore viewport and clear color states
|
||||
@@ -945,13 +945,13 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
if (!faces[plane_index])
|
||||
continue;
|
||||
|
||||
m_layers_merge.m_rtt[plane_index].bindFramebuffer();
|
||||
m_layers_merge.m_rtt[plane_index].clear({ 1, 1, 1, 0 });
|
||||
m_layers_merge.rtt(plane_index).bindFramebuffer();
|
||||
m_layers_merge.rtt(plane_index).clear({ 1, 1, 1, 0 });
|
||||
|
||||
if (use_blend)
|
||||
{
|
||||
glDisable(GL_BLEND);
|
||||
m_layers_merge.m_rtt[plane_index].clear();
|
||||
m_layers_merge.rtt(plane_index).clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -970,7 +970,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
if (!(m_show_tmp && m_current_layer_idx == layer_index) &&
|
||||
(!m_layers[layer_index]->m_visible ||
|
||||
m_layers[layer_index]->m_opacity == .0f ||
|
||||
!m_layers[layer_index]->m_dirty_face[plane_index]))
|
||||
!m_layers[layer_index]->face(plane_index)))
|
||||
continue;
|
||||
|
||||
if (use_blend)
|
||||
@@ -995,17 +995,17 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_smask.rtt(plane_index).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else if (m_current_stroke && m_show_tmp && m_current_layer_idx == layer_index)
|
||||
{
|
||||
@@ -1045,11 +1045,11 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_smask.rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
if (b->m_dual_enabled)
|
||||
m_tmp_dual[plane_index].bindTexture();
|
||||
@@ -1062,11 +1062,11 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
if (b->m_dual_enabled)
|
||||
m_tmp_dual[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1078,9 +1078,9 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
|
||||
if (use_blend)
|
||||
@@ -1155,7 +1155,7 @@ void Canvas::draw_merge(bool draw_checkerboard, std::array<bool, 6> faces /*= SI
|
||||
m_merge_tex.unbind();
|
||||
}
|
||||
|
||||
m_layers_merge.m_rtt[plane_index].unbindFramebuffer();
|
||||
m_layers_merge.rtt(plane_index).unbindFramebuffer();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1275,17 +1275,17 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!m_layers[source_idx]->m_dirty_face[i])
|
||||
if (!m_layers[source_idx]->face(i))
|
||||
continue; // no stroke on this face, skip it
|
||||
|
||||
m_layers[dest_idx]->m_rtt[i].bindFramebuffer();
|
||||
m_layers[dest_idx]->rtt(i).bindFramebuffer();
|
||||
|
||||
auto& lbox = m_layers[dest_idx]->m_dirty_box[i];
|
||||
auto& lbox = m_layers[dest_idx]->box(i);
|
||||
lbox = glm::vec4(
|
||||
glm::min(xy(m_layers[source_idx]->m_dirty_box[i]), xy(lbox)),
|
||||
glm::max(zw(m_layers[source_idx]->m_dirty_box[i]), zw(lbox))
|
||||
glm::min(xy(m_layers[source_idx]->box(i)), xy(lbox)),
|
||||
glm::max(zw(m_layers[source_idx]->box(i)), zw(lbox))
|
||||
);
|
||||
m_layers[dest_idx]->m_dirty_face[i] = true;
|
||||
m_layers[dest_idx]->face(i) = true;
|
||||
|
||||
// copy to tmp2 for layer blending
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
@@ -1312,14 +1312,14 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].bind();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_layers[source_idx]->m_rtt[i].bindTexture();
|
||||
m_layers[source_idx]->rtt(i).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_layers[source_idx]->m_rtt[i].unbindTexture();
|
||||
m_layers[source_idx]->rtt(i).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_tex2[i].unbind();
|
||||
}
|
||||
|
||||
m_layers[dest_idx]->m_rtt[i].unbindFramebuffer();
|
||||
m_layers[dest_idx]->rtt(i).unbindFramebuffer();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1346,14 +1346,14 @@ void Canvas::flood_fill(int layer, int plane, std::vector<glm::ivec2> pos, Flood
|
||||
|
||||
LOG("flood_fill plane %d", plane);
|
||||
|
||||
auto& rtt = m_layers[layer]->m_rtt[plane];
|
||||
auto& rtt = m_layers[layer]->rtt(plane);
|
||||
auto sz = rtt.getSize();
|
||||
|
||||
if (!plane_data.mask[plane])
|
||||
{
|
||||
plane_data.mask[plane] = std::make_unique<bool[]>((size_t)sz.x * sz.y);
|
||||
plane_data.rgb[plane] = std::unique_ptr<glm::u8vec4[]>(
|
||||
reinterpret_cast<glm::u8vec4*>(m_layers[layer]->m_rtt[plane].readTextureData()));
|
||||
reinterpret_cast<glm::u8vec4*>(m_layers[layer]->rtt(plane).readTextureData()));
|
||||
plane_data.bb[plane] = { sz.x, sz.y, 0, 0 };
|
||||
plane_data.dirty[plane] = false;
|
||||
plane_data.layer = m_layers[layer];
|
||||
@@ -1488,7 +1488,7 @@ void Canvas::FloodData::apply()
|
||||
{
|
||||
if (!dirty[plane])
|
||||
continue;
|
||||
auto& rtt = layer->m_rtt[plane];
|
||||
auto& rtt = layer->rtt(plane);
|
||||
App::I->render_task([&]
|
||||
{
|
||||
rtt.bindTexture();
|
||||
@@ -1496,8 +1496,8 @@ void Canvas::FloodData::apply()
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, rgb[plane].get());
|
||||
rtt.unbindTexture();
|
||||
});
|
||||
layer->m_dirty_face[plane] = true;
|
||||
layer->m_dirty_box[plane] = box_union(layer->m_dirty_box[plane], bb[plane]);
|
||||
layer->face(plane) = true;
|
||||
layer->box(plane) = box_union(layer->box(plane), bb[plane]);
|
||||
}
|
||||
Canvas::I->m_unsaved = true;
|
||||
}
|
||||
@@ -1713,8 +1713,8 @@ void Canvas::import_equirectangular_thread(std::string file_path, std::shared_pt
|
||||
}
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
layer->m_dirty_box[i] = glm::vec4(0, 0, m_width, m_height);
|
||||
layer->m_dirty_face[i] = true;
|
||||
layer->box(i) = glm::vec4(0, 0, m_width, m_height);
|
||||
layer->face(i) = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1852,9 +1852,9 @@ void Canvas::export_depth_thread(std::string file_name)
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||
m_layers_merge.rtt(plane_index).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||
m_layers_merge.rtt(plane_index).unbindTexture();
|
||||
}
|
||||
rtt.unbindFramebuffer();
|
||||
});
|
||||
@@ -1878,7 +1878,7 @@ void Canvas::export_depth_thread(std::string file_name)
|
||||
{
|
||||
if ((!m_layers[layer_index]->m_visible ||
|
||||
m_layers[layer_index]->m_opacity == .0f ||
|
||||
!m_layers[layer_index]->m_dirty_face[plane_index]))
|
||||
!m_layers[layer_index]->face(plane_index)))
|
||||
continue;
|
||||
|
||||
auto plane_mvp_z = proj * camera *
|
||||
@@ -1893,9 +1893,9 @@ void Canvas::export_depth_thread(std::string file_name)
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
m_plane.draw_fill();
|
||||
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
}
|
||||
rtt.unbindFramebuffer();
|
||||
@@ -1967,7 +1967,7 @@ void Canvas::export_cube_faces_thread(std::string file_name)
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Image face = m_layers_merge.m_rtt[i].get_image();
|
||||
Image face = m_layers_merge.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();
|
||||
@@ -2405,7 +2405,7 @@ Image Canvas::thumbnail_generate(int w, int h)
|
||||
{
|
||||
if (!m_layers[layer_index]->m_visible ||
|
||||
m_layers[layer_index]->m_opacity == 0.f ||
|
||||
!m_layers[layer_index]->m_dirty_face[i])
|
||||
!m_layers[layer_index]->face(i))
|
||||
continue;
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
{
|
||||
@@ -2415,9 +2415,9 @@ Image Canvas::thumbnail_generate(int w, int h)
|
||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode);
|
||||
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_layers[layer_index]->m_rtt[i].bindTexture();
|
||||
m_layers[layer_index]->rtt(i).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_layers[layer_index]->m_rtt[i].unbindTexture();
|
||||
m_layers[layer_index]->rtt(i).unbindTexture();
|
||||
}
|
||||
|
||||
if (!ShaderManager::ext_framebuffer_fetch)
|
||||
@@ -2517,16 +2517,16 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
glm::mat4 plane_camera = glm::lookAt(glm::vec3(0), m_plane_origin[i], m_plane_tangent[i]);
|
||||
layer.m_rtt[i].bindFramebuffer();
|
||||
layer.rtt(i).bindFramebuffer();
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboID);
|
||||
|
||||
observer(plane_camera, proj, i);
|
||||
|
||||
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
|
||||
layer.m_rtt[i].unbindFramebuffer();
|
||||
layer.rtt(i).unbindFramebuffer();
|
||||
|
||||
layer.m_dirty_face[i] = true;
|
||||
layer.m_dirty_box[i] = { 0, 0, layer.w, layer.h };
|
||||
layer.face(i) = true;
|
||||
layer.box(i) = { 0, 0, layer.w, layer.h };
|
||||
}
|
||||
|
||||
glDeleteRenderbuffers(1, &rboID);
|
||||
@@ -2581,7 +2581,7 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
||||
|
||||
glm::vec4 bounds = rtt.calc_bounds();
|
||||
|
||||
layer.m_rtt[i].bindFramebuffer();
|
||||
layer.rtt(i).bindFramebuffer();
|
||||
|
||||
// save image before commit
|
||||
glm::vec2 box_sz = zw(bounds) - xy(bounds);
|
||||
@@ -2593,8 +2593,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
||||
action->m_box[i] = bounds;
|
||||
}
|
||||
|
||||
action->m_old_box[i] = layer.m_dirty_box[i];
|
||||
action->m_old_dirty[i] = layer.m_dirty_face[i];
|
||||
action->m_old_box[i] = layer.box(i);
|
||||
action->m_old_dirty[i] = layer.face(i);
|
||||
|
||||
// draw the tmp layer into the actual layer
|
||||
if (has_data)
|
||||
@@ -2608,11 +2608,11 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
||||
m_plane.draw_fill();
|
||||
rtt.unbindTexture();
|
||||
|
||||
layer.m_dirty_face[i] = true;
|
||||
layer.m_dirty_box[i] = { glm::min(xy(layer.m_dirty_box[i]), xy(bounds)), glm::max(zw(layer.m_dirty_box[i]), zw(bounds)) };
|
||||
layer.face(i) = true;
|
||||
layer.box(i) = { glm::min(xy(layer.box(i)), xy(bounds)), glm::max(zw(layer.box(i)), zw(bounds)) };
|
||||
}
|
||||
|
||||
layer.m_rtt[i].unbindFramebuffer();
|
||||
layer.rtt(i).unbindFramebuffer();
|
||||
}
|
||||
|
||||
// save history
|
||||
@@ -2733,184 +2733,3 @@ void Canvas::set_camera(const CameraData& c)
|
||||
m_proj = c.m_proj;
|
||||
m_vp = c.m_vp;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Layer::destroy()
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
m_rtt[i].destroy();
|
||||
}
|
||||
|
||||
void Layer::optimize()
|
||||
{
|
||||
int saved_bytes = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!m_dirty_face[i])
|
||||
continue;
|
||||
|
||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(m_rtt[i].readTextureData()));
|
||||
glm::ivec2 bbmin(w,h);
|
||||
glm::ivec2 bbmax(0);
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
if (data[x + y * w].a > 0)
|
||||
{
|
||||
bbmin = glm::min(bbmin, { x, y });
|
||||
bbmax = glm::max(bbmax, { x + 1, y + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
glm::vec2 bbsz = bbmax - bbmin;
|
||||
glm::vec2 old_size = zw(m_dirty_box[i]) - xy(m_dirty_box[i]);
|
||||
glm::vec2 diff;
|
||||
if (bbsz.x <= 0 || bbmax.y <= 0)
|
||||
{
|
||||
m_dirty_face[i] = false;
|
||||
m_dirty_box[i] = glm::vec4(0);
|
||||
diff = old_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dirty_box[i] = { bbmin, bbmax };
|
||||
|
||||
diff = old_size - bbsz;
|
||||
}
|
||||
saved_bytes += (int)(diff.x * diff.y * 4);
|
||||
}
|
||||
LOG("optimized %d bytes", saved_bytes);
|
||||
}
|
||||
|
||||
void Layer::restore(const Snapshot& snap)
|
||||
{
|
||||
clear({ 0, 0, 0, 0 });
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0)
|
||||
{
|
||||
m_dirty_box[i] = glm::vec4(snap.width, snap.height, 0, 0);
|
||||
m_dirty_face[i] = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
m_dirty_box[i] = snap.m_dirty_box[i];
|
||||
m_dirty_face[i] = snap.m_dirty_face[i];
|
||||
|
||||
// TODO: this should not be recreated here!
|
||||
// Sorry I messed up with this,
|
||||
// it's just a quick fix DON'T SHIP!!
|
||||
//m_rtt[i].recreate();
|
||||
|
||||
App::I->render_task_async([this,i,&snap]
|
||||
{
|
||||
m_rtt[i].bindTexture();
|
||||
glm::vec2 box_sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]);
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
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());
|
||||
m_rtt[i].unbindTexture();
|
||||
LOG("restore face %d - %d bytes (%dx%d)", i,
|
||||
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
}
|
||||
|
||||
Layer::Snapshot Layer::snapshot(std::array<glm::vec4, 6> * dirty_box /*= nullptr*/, std::array<bool, 6> * dirty_face /*= nullptr*/)
|
||||
{
|
||||
Snapshot snap;
|
||||
snap.width = w;
|
||||
snap.height = h;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : m_dirty_box[i];
|
||||
snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : m_dirty_face[i];
|
||||
|
||||
if (!snap.m_dirty_face[i])
|
||||
continue;
|
||||
|
||||
snap.image[i] = std::make_unique<uint8_t[]>(m_rtt[i].bytes());
|
||||
|
||||
App::I->render_task_async([this,i,&snap]
|
||||
{
|
||||
m_rtt[i].bindFramebuffer();
|
||||
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();
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
return snap;
|
||||
}
|
||||
|
||||
void Layer::clear(const glm::vec4& c)
|
||||
{
|
||||
App::I->render_task([&]
|
||||
{
|
||||
// push clear color state
|
||||
GLfloat cc[4];
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
||||
glClearColor(c.r, c.g, c.b, c.a);
|
||||
|
||||
bool erase = (c.a == 0.f);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_rtt[i].bindFramebuffer();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
m_rtt[i].unbindFramebuffer();
|
||||
|
||||
if (erase)
|
||||
{
|
||||
m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box
|
||||
m_dirty_face[i] = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dirty_box[i] = glm::vec4(0, 0, w, h); // reset bounding box
|
||||
m_dirty_face[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
// restore clear color state
|
||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||
});
|
||||
}
|
||||
|
||||
bool Layer::create(int width, int height, std::string name)
|
||||
{
|
||||
m_name = name;
|
||||
w = width;
|
||||
h = height;
|
||||
App::I->render_task([&]
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_rtt[i].create(width, height);
|
||||
m_rtt[i].bindFramebuffer();
|
||||
m_rtt[i].clear();
|
||||
m_rtt[i].unbindFramebuffer();
|
||||
m_dirty_box[i] = glm::vec4(w, h, 0, 0); // reset bounding box
|
||||
m_dirty_face[i] = false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void Layer::resize(int width, int height)
|
||||
{
|
||||
glm::vec2 ratio = glm::vec2(width, height) / glm::vec2(w, h);
|
||||
w = width;
|
||||
h = height;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_rtt[i].resize(width, height);
|
||||
m_dirty_box[i] = m_dirty_box[i] * glm::vec4(ratio, ratio);
|
||||
//m_dirty_face[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,13 +127,13 @@ public:
|
||||
Texture2D m_tex2[6];
|
||||
RTT m_merge_rtt;
|
||||
Texture2D m_merge_tex;
|
||||
bool m_pick_ready[6];
|
||||
bool m_pick_ready[6] = SIXPLETTE(false);
|
||||
std::unique_ptr<glm::u8vec4[]> m_pick_data[6] = SIXPLETTE(nullptr);
|
||||
static glm::vec3 m_plane_origin[6];
|
||||
static glm::vec3 m_plane_normal[6];
|
||||
static glm::vec3 m_plane_tangent[6];
|
||||
static glm::mat4 m_plane_transform[6];
|
||||
glm::vec2 m_pattern_offset;
|
||||
glm::vec2 m_pattern_offset{ 0 };
|
||||
Sampler m_sampler;
|
||||
Sampler m_sampler_nearest;
|
||||
Sampler m_sampler_linear;
|
||||
@@ -145,7 +145,7 @@ public:
|
||||
float m_cam_fov = 85.f;
|
||||
const float m_cam_fov_min = 5.f;
|
||||
const float m_cam_fov_max = 150.f;
|
||||
glm::vec2 m_cur_pos;
|
||||
glm::vec2 m_cur_pos{ 0 };
|
||||
|
||||
std::shared_ptr<Brush> m_current_brush;
|
||||
|
||||
|
||||
@@ -17,18 +17,18 @@ void ActionStroke::undo()
|
||||
|
||||
LOG("undo box %d dirty=%s [%d,%d,%d,%d] to dirty=%s [%d,%d,%d,%d]",
|
||||
i,
|
||||
m_canvas->m_layers[m_layer_idx]->m_dirty_face[i] ? "true" : "false",
|
||||
(int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].x,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].y,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].z,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->m_dirty_box[i].w,
|
||||
m_canvas->m_layers[m_layer_idx]->face(i) ? "true" : "false",
|
||||
(int)m_canvas->m_layers[m_layer_idx]->box(i).x,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->box(i).y,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->box(i).z,
|
||||
(int)m_canvas->m_layers[m_layer_idx]->box(i).w,
|
||||
m_old_dirty[i] ? "true" : "false",
|
||||
(int)m_old_box[i].x,
|
||||
(int)m_old_box[i].y,
|
||||
(int)m_old_box[i].z,
|
||||
(int)m_old_box[i].w);
|
||||
m_canvas->m_layers[m_layer_idx]->m_dirty_box[i] = m_old_box[i];
|
||||
m_canvas->m_layers[m_layer_idx]->m_dirty_face[i] = m_old_dirty[i];
|
||||
m_canvas->m_layers[m_layer_idx]->box(i) = m_old_box[i];
|
||||
m_canvas->m_layers[m_layer_idx]->face(i) = m_old_dirty[i];
|
||||
|
||||
|
||||
glm::vec2 box_sz = zw(m_box[i]) - xy(m_box[i]);
|
||||
@@ -36,9 +36,9 @@ void ActionStroke::undo()
|
||||
{
|
||||
App::I->render_task([&]
|
||||
{
|
||||
m_canvas->m_layers[m_layer_idx]->m_rtt[i].bindTexture();
|
||||
m_canvas->m_layers[m_layer_idx]->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());
|
||||
m_canvas->m_layers[m_layer_idx]->m_rtt[i].unbindTexture();
|
||||
m_canvas->m_layers[m_layer_idx]->rtt(i).unbindTexture();
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -65,11 +65,11 @@ Action* ActionStroke::get_redo()
|
||||
auto& layer = m_canvas->m_layers[m_layer_idx];
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!layer->m_dirty_face[i] && !m_image[i])
|
||||
if (!layer->face(i) && !m_image[i])
|
||||
continue; // no stroke on this face, skip it
|
||||
|
||||
|
||||
auto box = clear_layer ? glm::ivec4(layer->m_dirty_box[i]) : m_box[i];
|
||||
auto box = clear_layer ? glm::ivec4(layer->box(i)) : m_box[i];
|
||||
|
||||
// save image before commit
|
||||
glm::vec2 box_or = xy(box);
|
||||
@@ -79,9 +79,9 @@ Action* ActionStroke::get_redo()
|
||||
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();
|
||||
layer->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());
|
||||
layer->m_rtt[i].unbindFramebuffer();
|
||||
layer->rtt(i).unbindFramebuffer();
|
||||
});
|
||||
}
|
||||
else
|
||||
@@ -90,8 +90,8 @@ Action* ActionStroke::get_redo()
|
||||
}
|
||||
|
||||
action->m_box[i] = box;
|
||||
action->m_old_box[i] = layer->m_dirty_box[i];
|
||||
action->m_old_dirty[i] = layer->m_dirty_face[i];
|
||||
action->m_old_box[i] = layer->box(i);
|
||||
action->m_old_dirty[i] = layer->face(i);
|
||||
}
|
||||
// save history
|
||||
action->m_layer_idx = m_layer_idx;
|
||||
|
||||
@@ -5,6 +5,26 @@
|
||||
|
||||
uint32_t Layer::s_count = 0;
|
||||
|
||||
RTT& Layer::rtt(int i)
|
||||
{
|
||||
return m_frames[m_frame_index].m_rtt[i];
|
||||
}
|
||||
|
||||
glm::vec4& Layer::box(int i)
|
||||
{
|
||||
return m_frames[m_frame_index].m_dirty_box[i];
|
||||
}
|
||||
|
||||
bool& Layer::face(int i)
|
||||
{
|
||||
return m_frames[m_frame_index].m_dirty_face[i];
|
||||
}
|
||||
|
||||
LayerFrame& Layer::frame()
|
||||
{
|
||||
return m_frames[m_frame_index];
|
||||
}
|
||||
|
||||
TextureCube Layer::gen_cube()
|
||||
{
|
||||
TextureCube ret;
|
||||
@@ -14,9 +34,9 @@ TextureCube Layer::gen_cube()
|
||||
ret.bind();
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
m_rtt[i].bindFramebuffer();
|
||||
rtt(i).bindFramebuffer();
|
||||
glCopyTexSubImage2D(TextureCube::m_faces_map[i], 0, 0, 0, 0, 0, w, w);
|
||||
m_rtt[i].unbindFramebuffer();
|
||||
rtt(i).unbindFramebuffer();
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
@@ -69,6 +89,189 @@ Texture2D Layer::gen_equirect()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Layer::destroy()
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
rtt(i).destroy();
|
||||
}
|
||||
|
||||
void Layer::optimize()
|
||||
{
|
||||
int saved_bytes = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!face(i))
|
||||
continue;
|
||||
|
||||
auto data = std::unique_ptr<glm::u8vec4[]>(reinterpret_cast<glm::u8vec4*>(rtt(i).readTextureData()));
|
||||
glm::ivec2 bbmin(w, h);
|
||||
glm::ivec2 bbmax(0);
|
||||
for (int y = 0; y < h; y++)
|
||||
{
|
||||
for (int x = 0; x < w; x++)
|
||||
{
|
||||
if (data[x + y * w].a > 0)
|
||||
{
|
||||
bbmin = glm::min(bbmin, { x, y });
|
||||
bbmax = glm::max(bbmax, { x + 1, y + 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
glm::vec2 bbsz = bbmax - bbmin;
|
||||
glm::vec2 old_size = zw(box(i)) - xy(box(i));
|
||||
glm::vec2 diff;
|
||||
if (bbsz.x <= 0 || bbmax.y <= 0)
|
||||
{
|
||||
face(i) = false;
|
||||
box(i) = glm::vec4(0);
|
||||
diff = old_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
box(i) = { bbmin, bbmax };
|
||||
|
||||
diff = old_size - bbsz;
|
||||
}
|
||||
saved_bytes += (int)(diff.x * diff.y * 4);
|
||||
}
|
||||
LOG("optimized %d bytes", saved_bytes);
|
||||
}
|
||||
|
||||
void Layer::restore(const Snapshot& snap)
|
||||
{
|
||||
clear({ 0, 0, 0, 0 });
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (snap.image[i] == nullptr || snap.m_dirty_face[i] == false || box_area(snap.m_dirty_box[i]) <= 0)
|
||||
{
|
||||
box(i) = glm::vec4(snap.width, snap.height, 0, 0);
|
||||
face(i) = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
box(i) = snap.m_dirty_box[i];
|
||||
face(i) = snap.m_dirty_face[i];
|
||||
|
||||
// TODO: this should not be recreated here!
|
||||
// Sorry I messed up with this,
|
||||
// it's just a quick fix DON'T SHIP!!
|
||||
//m_rtt[i].recreate();
|
||||
|
||||
App::I->render_task_async([this, i, &snap]
|
||||
{
|
||||
rtt(i).bindTexture();
|
||||
glm::vec2 box_sz = zw(box(i)) - xy(box(i));
|
||||
glTexSubImage2D(GL_TEXTURE_2D, 0,
|
||||
box(i).x, box(i).y,
|
||||
box_sz.x, box_sz.y, GL_RGBA, GL_UNSIGNED_BYTE,
|
||||
snap.image[i].get());
|
||||
rtt(i).unbindTexture();
|
||||
LOG("restore face %d - %d bytes (%dx%d)", i,
|
||||
(int)box_sz.x * (int)box_sz.y * 4, (int)box_sz.x, (int)box_sz.y);
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
}
|
||||
|
||||
Layer::Snapshot Layer::snapshot(std::array<glm::vec4, 6>* dirty_box /*= nullptr*/, std::array<bool, 6>* dirty_face /*= nullptr*/)
|
||||
{
|
||||
Snapshot snap;
|
||||
snap.width = w;
|
||||
snap.height = h;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
snap.m_dirty_box[i] = dirty_box ? dirty_box->at(i) : box(i);
|
||||
snap.m_dirty_face[i] = dirty_face ? dirty_face->at(i) : face(i);
|
||||
|
||||
if (!snap.m_dirty_face[i])
|
||||
continue;
|
||||
|
||||
snap.image[i] = std::make_unique<uint8_t[]>(rtt(i).bytes());
|
||||
|
||||
App::I->render_task_async([this, i, &snap]
|
||||
{
|
||||
rtt(i).bindFramebuffer();
|
||||
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());
|
||||
rtt(i).unbindFramebuffer();
|
||||
});
|
||||
}
|
||||
App::I->render_sync();
|
||||
return snap;
|
||||
}
|
||||
|
||||
void Layer::clear(const glm::vec4& c)
|
||||
{
|
||||
App::I->render_task([&]
|
||||
{
|
||||
// push clear color state
|
||||
GLfloat cc[4];
|
||||
glGetFloatv(GL_COLOR_CLEAR_VALUE, cc);
|
||||
glClearColor(c.r, c.g, c.b, c.a);
|
||||
|
||||
bool erase = (c.a == 0.f);
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
rtt(i).bindFramebuffer();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
rtt(i).unbindFramebuffer();
|
||||
|
||||
if (erase)
|
||||
{
|
||||
box(i) = glm::vec4(w, h, 0, 0); // reset bounding box
|
||||
face(i) = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
box(i) = glm::vec4(0, 0, w, h); // reset bounding box
|
||||
face(i) = true;
|
||||
}
|
||||
}
|
||||
|
||||
// restore clear color state
|
||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||
});
|
||||
}
|
||||
|
||||
bool Layer::create(int width, int height, std::string name)
|
||||
{
|
||||
m_name = name;
|
||||
w = width;
|
||||
h = height;
|
||||
if (m_frames.empty())
|
||||
m_frames.emplace_back();
|
||||
App::I->render_task([&]
|
||||
{
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
rtt(i).create(width, height);
|
||||
rtt(i).bindFramebuffer();
|
||||
rtt(i).clear();
|
||||
rtt(i).unbindFramebuffer();
|
||||
box(i) = glm::vec4(w, h, 0, 0); // reset bounding box
|
||||
face(i) = false;
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Layer::add_frame()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void Layer::resize(int width, int height)
|
||||
{
|
||||
w = width;
|
||||
h = height;
|
||||
for (auto& frame : m_frames)
|
||||
frame.resize(width, height);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Layer::Snapshot::create(int w, int h)
|
||||
{
|
||||
width = w;
|
||||
@@ -129,3 +332,30 @@ int Layer::Snapshot::memsize() const
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool LayerFrame::create(int width, int height, int duration /*= 1*/)
|
||||
{
|
||||
for (auto& rtt : m_rtt)
|
||||
if (!rtt.create(width, height))
|
||||
return false;
|
||||
m_duration = duration;
|
||||
w = width;
|
||||
h = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LayerFrame::resize(int width, int height)
|
||||
{
|
||||
glm::vec2 ratio = glm::vec2(width, height) / glm::vec2(w, h);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
if (!m_rtt[i].resize(width, height))
|
||||
return false;
|
||||
m_dirty_box[i] = m_dirty_box[i] * glm::vec4(ratio, ratio);
|
||||
}
|
||||
w = width;
|
||||
h = height;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,9 +3,16 @@
|
||||
#include "log.h"
|
||||
#include "texture.h"
|
||||
|
||||
class LayerFrame
|
||||
struct LayerFrame
|
||||
{
|
||||
|
||||
std::array<RTT, 6> m_rtt;
|
||||
std::array<glm::vec4, 6> m_dirty_box = SIXPLETTE(glm::vec4(0));
|
||||
std::array<bool, 6> m_dirty_face = SIXPLETTE(false);
|
||||
int m_duration = 1;
|
||||
int w = 0, h = 0;
|
||||
LayerFrame() = default;
|
||||
bool create(int width, int height, int duration = 1);
|
||||
bool resize(int width, int height);
|
||||
};
|
||||
|
||||
class Layer
|
||||
@@ -14,11 +21,9 @@ class Layer
|
||||
public:
|
||||
Layer() { id = s_count++; }
|
||||
Layer(const Layer&) = delete;
|
||||
~Layer() { LOG("LAYER AUTO DESTROY"); destroy(); }
|
||||
uint32_t id;
|
||||
RTT m_rtt[6];
|
||||
std::array<glm::vec4, 6> m_dirty_box = SIXPLETTE(glm::vec4(0));
|
||||
std::array<bool, 6> m_dirty_face = SIXPLETTE(false);
|
||||
std::vector<LayerFrame> m_frames;
|
||||
int m_frame_index = 0;
|
||||
bool m_visible = true;
|
||||
bool m_alpha_locked = false;
|
||||
float m_opacity = 1.f;
|
||||
@@ -39,8 +44,13 @@ public:
|
||||
void optimize();
|
||||
int memsize() const;
|
||||
};
|
||||
RTT& rtt(int i);
|
||||
glm::vec4& box(int i);
|
||||
bool& face(int i);
|
||||
LayerFrame& frame();
|
||||
void resize(int width, int height);
|
||||
bool create(int width, int height, std::string name);
|
||||
bool add_frame();
|
||||
void clear(const glm::vec4& c);
|
||||
Snapshot snapshot(std::array<glm::vec4, 6>* dirty_box = nullptr, std::array<bool, 6>* dirty_face = nullptr);
|
||||
TextureCube gen_cube();
|
||||
|
||||
@@ -1243,12 +1243,12 @@ void CanvasModeTransform::enter(kCanvasMode prev)
|
||||
App::I->render_task([&]
|
||||
{
|
||||
m_shape[plane].update_vertices(shape3d.data(), (int)shape3d.size());
|
||||
Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->m_rtt[plane].bindFramebuffer();
|
||||
Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->rtt(plane).bindFramebuffer();
|
||||
m_tex[plane].create(bb_sz.x, bb_sz.y);
|
||||
m_tex[plane].bind();
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
|
||||
m_tex[plane].unbind();
|
||||
Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->m_rtt[plane].unbindFramebuffer();
|
||||
Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->rtt(plane).unbindFramebuffer();
|
||||
});
|
||||
|
||||
m_commit_on_leave = true;
|
||||
@@ -1293,13 +1293,13 @@ void CanvasModeTransform::enter(kCanvasMode prev)
|
||||
|
||||
action->m_image[i] = std::make_unique<uint8_t[]>(bb_sz.x * bb_sz.y * 4);
|
||||
action->m_box[i] = { bb_min, bb_max };
|
||||
action->m_old_box[i] = layer->m_dirty_box[i];
|
||||
action->m_old_dirty[i] = layer->m_dirty_face[i];
|
||||
action->m_old_box[i] = layer->box(i);
|
||||
action->m_old_dirty[i] = layer->face(i);
|
||||
|
||||
layer->m_dirty_face[i] = true;
|
||||
layer->m_dirty_box[i] = {
|
||||
glm::min(xy(layer->m_dirty_box[i]), bb_min),
|
||||
glm::max(zw(layer->m_dirty_box[i]), bb_max),
|
||||
layer->face(i) = true;
|
||||
layer->box(i) = {
|
||||
glm::min(xy(layer->box(i)), bb_min),
|
||||
glm::max(zw(layer->box(i)), bb_max),
|
||||
};
|
||||
|
||||
App::I->render_task([&]
|
||||
@@ -1311,12 +1311,12 @@ void CanvasModeTransform::enter(kCanvasMode prev)
|
||||
ShaderManager::use(kShader::Color);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
|
||||
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 0 });
|
||||
layer->m_rtt[i].bindFramebuffer();
|
||||
layer->rtt(i).bindFramebuffer();
|
||||
// copy framebuffer to action data
|
||||
glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
||||
for (int j = 0; j < 6; j++)
|
||||
m_shape[j].draw_fill();
|
||||
layer->m_rtt[i].unbindFramebuffer();
|
||||
layer->rtt(i).unbindFramebuffer();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1391,23 +1391,23 @@ void CanvasModeTransform::leave(kCanvasMode next)
|
||||
|
||||
action->m_image[i] = std::make_unique<uint8_t[]>(bb_sz.x * bb_sz.y * 4);
|
||||
action->m_box[i] = { bb_min, bb_max };
|
||||
action->m_old_box[i] = layer->m_dirty_box[i];
|
||||
action->m_old_dirty[i] = layer->m_dirty_face[i];
|
||||
action->m_old_box[i] = layer->box(i);
|
||||
action->m_old_dirty[i] = layer->face(i);
|
||||
|
||||
layer->m_dirty_face[i] = true;
|
||||
layer->m_dirty_box[i] = {
|
||||
glm::min(xy(layer->m_dirty_box[i]), bb_min),
|
||||
glm::max(zw(layer->m_dirty_box[i]), bb_max),
|
||||
layer->face(i) = true;
|
||||
layer->box(i) = {
|
||||
glm::min(xy(layer->box(i)), bb_min),
|
||||
glm::max(zw(layer->box(i)), bb_max),
|
||||
};
|
||||
|
||||
App::I->render_task([&]
|
||||
{
|
||||
layer->m_rtt[i].bindFramebuffer();
|
||||
layer->rtt(i).bindFramebuffer();
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_BLEND);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glViewport(0, 0, layer->m_rtt[i].getWidth(), layer->m_rtt[i].getHeight());
|
||||
glViewport(0, 0, layer->rtt(i).getWidth(), layer->rtt(i).getHeight());
|
||||
|
||||
// save fb content for history
|
||||
glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
|
||||
@@ -1437,7 +1437,7 @@ void CanvasModeTransform::leave(kCanvasMode next)
|
||||
m_shape[j].draw_fill();
|
||||
m_tex[j].unbind();
|
||||
}
|
||||
layer->m_rtt[i].unbindFramebuffer();
|
||||
layer->rtt(i).unbindFramebuffer();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1674,8 +1674,8 @@ void CanvasModeFloodFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
|
||||
a->m_layer_index = Canvas::I->m_current_layer_idx;
|
||||
a->m_threshold = m_tool->get_threshold();
|
||||
a->m_plane = plane;
|
||||
a->m_dirty_box = plane_data.layer->m_dirty_box;
|
||||
a->m_dirty_face = plane_data.layer->m_dirty_face;
|
||||
a->m_dirty_box = plane_data.layer->frame().m_dirty_box;
|
||||
a->m_dirty_face = plane_data.layer->frame().m_dirty_face;
|
||||
ActionManager::add(a);
|
||||
|
||||
plane_data.apply();
|
||||
|
||||
@@ -164,9 +164,9 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_layers_merge.rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_layers_merge.rtt(plane_index).unbindTexture();
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -217,7 +217,7 @@ void NodeCanvas::draw()
|
||||
if (!(m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index) &&
|
||||
(!m_canvas->m_layers[layer_index]->m_visible ||
|
||||
m_canvas->m_layers[layer_index]->m_opacity == .0f ||
|
||||
!m_canvas->m_layers[layer_index]->m_dirty_face[plane_index]))
|
||||
!m_canvas->m_layers[layer_index]->face(plane_index)))
|
||||
continue;
|
||||
|
||||
if (use_blend)
|
||||
@@ -249,17 +249,17 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_canvas->m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||
{
|
||||
@@ -299,11 +299,11 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_canvas->m_tmp[plane_index].bindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
if (b->m_dual_enabled)
|
||||
m_canvas->m_tmp_dual[plane_index].bindTexture();
|
||||
@@ -316,11 +316,11 @@ void NodeCanvas::draw()
|
||||
if (b->m_dual_enabled)
|
||||
m_canvas->m_tmp_dual[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE2);
|
||||
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE1);
|
||||
m_canvas->m_tmp[plane_index].unbindTexture();
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -332,9 +332,9 @@ void NodeCanvas::draw()
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_layers[layer_index]->rtt(plane_index).unbindTexture();
|
||||
}
|
||||
|
||||
if (use_blend)
|
||||
@@ -380,7 +380,7 @@ void NodeCanvas::draw()
|
||||
#ifdef _DEBUG
|
||||
// draw dirty area
|
||||
{
|
||||
auto bb = m_canvas->m_layers[layer_index]->m_dirty_box[plane_index] / (float)m_canvas->m_layers[layer_index]->w;
|
||||
auto bb = m_canvas->m_layers[layer_index]->box(plane_index) / (float)m_canvas->m_layers[layer_index]->w;
|
||||
glm::vec2 bbmin = xy(bb);
|
||||
glm::vec2 bbsz = zw(bb) - xy(bb);
|
||||
ShaderManager::use(kShader::Color);
|
||||
@@ -463,9 +463,9 @@ void NodeCanvas::draw()
|
||||
glm::translate(glm::vec3(0, 0, -1.f));
|
||||
|
||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).bindTexture();
|
||||
m_face_plane.draw_fill();
|
||||
m_canvas->m_smask.m_rtt[plane_index].unbindTexture();
|
||||
m_canvas->m_smask.rtt(plane_index).unbindTexture();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -402,12 +402,12 @@ void NodePanelLayer::merge(int src_index, int dst_index, bool create_history)
|
||||
a->m_direction = ActionLayerMerge::Direction::Undo;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
a->m_dirty_box[i] = Canvas::I->m_layers[dst_index]->m_dirty_box[i];
|
||||
a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->m_dirty_face[i];
|
||||
a->m_dirty_box[i] = Canvas::I->m_layers[dst_index]->box(i);
|
||||
a->m_dirty_face[i] = Canvas::I->m_layers[dst_index]->face(i);
|
||||
}
|
||||
a->m_snap = std::make_shared<Layer::Snapshot>();
|
||||
*a->m_snap = Canvas::I->m_layers[dst_index]->snapshot(
|
||||
&Canvas::I->m_layers[src_index]->m_dirty_box, &Canvas::I->m_layers[src_index]->m_dirty_face);
|
||||
&Canvas::I->m_layers[src_index]->frame().m_dirty_box, &Canvas::I->m_layers[src_index]->frame().m_dirty_face);
|
||||
a->m_layer = Canvas::I->m_layers[src_index];
|
||||
a->m_layer_node = std::static_pointer_cast<NodeLayer>(m_layers_container->m_children[src_index]);
|
||||
a->m_layer_node->m_selected = false;
|
||||
@@ -491,8 +491,8 @@ void ActionLayerMerge::undo()
|
||||
Canvas::I->m_layers[m_dst_index]->restore(*m_snap);
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Canvas::I->m_layers[m_dst_index]->m_dirty_box[i] = m_dirty_box[i];
|
||||
Canvas::I->m_layers[m_dst_index]->m_dirty_face[i] = m_dirty_face[i];
|
||||
Canvas::I->m_layers[m_dst_index]->box(i) = m_dirty_box[i];
|
||||
Canvas::I->m_layers[m_dst_index]->face(i) = m_dirty_face[i];
|
||||
}
|
||||
auto name = m_layer->m_name;
|
||||
m_panel->add_layer(name.c_str(), false, true, m_layer, m_layer_node, m_src_index);
|
||||
|
||||
15
src/rtt.cpp
15
src/rtt.cpp
@@ -35,8 +35,9 @@ RTT::~RTT()
|
||||
LOG("RTT not destroyed");
|
||||
}
|
||||
|
||||
void RTT::resize(int width, int height)
|
||||
bool RTT::resize(int width, int height)
|
||||
{
|
||||
bool ret = false;
|
||||
RTT new_rtt;
|
||||
|
||||
App::I->render_task([&]
|
||||
@@ -44,7 +45,12 @@ void RTT::resize(int width, int height)
|
||||
glGetIntegerv(GL_DRAW_FRAMEBUFFER_BINDING, &oldDFboID);
|
||||
glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, &oldRFboID);
|
||||
|
||||
new_rtt.create(width, height, -1, int_fmt, rboID != 0);
|
||||
ret = new_rtt.create(width, height, -1, int_fmt, rboID != 0);
|
||||
if (!ret)
|
||||
{
|
||||
LOG("failed to resize rtt from %dx%d to %dx%d", w, h, width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, new_rtt.fboID);
|
||||
glBindFramebuffer(GL_READ_FRAMEBUFFER, fboID);
|
||||
@@ -55,6 +61,9 @@ void RTT::resize(int width, int height)
|
||||
|
||||
destroy();
|
||||
});
|
||||
|
||||
if (!ret)
|
||||
return false;
|
||||
|
||||
oldRFboID = 0;
|
||||
oldDFboID = 0;
|
||||
@@ -64,6 +73,8 @@ void RTT::resize(int width, int height)
|
||||
int_fmt = new_rtt.int_fmt;
|
||||
w = new_rtt.w;
|
||||
h = new_rtt.h;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void RTT::destroy()
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
void copy(const RTT& source);
|
||||
// copy a region
|
||||
void copy(const RTT& source, const glm::vec4& rect);
|
||||
void resize(int width, int height);
|
||||
bool resize(int width, int height);
|
||||
bool create(int width, int height, int tex = -1, GLint internal_format = GL_RGBA8, bool depth_buffer = false);
|
||||
bool recreate() { return create(w, h); }
|
||||
void clear(glm::vec4 color = glm::vec4(0));
|
||||
|
||||
Reference in New Issue
Block a user