render merged layers cache
This commit is contained in:
@@ -203,29 +203,34 @@ void App::init_sidebar()
|
|||||||
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
|
layers->on_layer_opacity_changed = [this](Node*, int idx, float value) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_opacity = value;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_opacity = value;
|
||||||
canvas->m_canvas->m_unsaved = true;
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
canvas->m_canvas->draw_merge();
|
||||||
title_update();
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
|
layers->on_layer_visibility_changed = [this](Node*, int idx, bool visible) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_visible = visible;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_visible = visible;
|
||||||
canvas->m_canvas->m_unsaved = true;
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
canvas->m_canvas->draw_merge();
|
||||||
title_update();
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_alpha_lock_changed = [this](Node*, int idx, bool locked) {
|
layers->on_layer_alpha_lock_changed = [this](Node*, int idx, bool locked) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_alpha_locked = locked;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_alpha_locked = locked;
|
||||||
canvas->m_canvas->m_unsaved = true;
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
canvas->m_canvas->draw_merge();
|
||||||
title_update();
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_blend_mode_changed = [this](Node*, int idx, int mode) {
|
layers->on_layer_blend_mode_changed = [this](Node*, int idx, int mode) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_blend_mode = mode;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_blend_mode = mode;
|
||||||
canvas->m_canvas->m_unsaved = true;
|
canvas->m_canvas->m_unsaved = true;
|
||||||
|
canvas->m_canvas->draw_merge();
|
||||||
title_update();
|
title_update();
|
||||||
};
|
};
|
||||||
|
|
||||||
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
|
layers->on_layer_highlight_changed = [this](Node*, int idx, bool highlight) {
|
||||||
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_hightlight = highlight;
|
canvas->m_canvas->m_layers[canvas->m_canvas->m_order[idx]]->m_hightlight = highlight;
|
||||||
|
canvas->m_canvas->draw_merge();
|
||||||
};
|
};
|
||||||
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
if (auto* button = layout[main_id]->find<NodeButtonCustom>("btn-stroke"))
|
||||||
{
|
{
|
||||||
|
|||||||
301
src/canvas.cpp
301
src/canvas.cpp
@@ -143,11 +143,13 @@ void Canvas::clear(const glm::vec4& c/*={0,0,0,1}*/)
|
|||||||
snap_history({ 0, 1, 2, 3, 4, 5 });
|
snap_history({ 0, 1, 2, 3, 4, 5 });
|
||||||
m_layers[m_current_layer_idx]->clear(c);
|
m_layers[m_current_layer_idx]->clear(c);
|
||||||
m_unsaved = true;
|
m_unsaved = true;
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::clear_all()
|
void Canvas::clear_all()
|
||||||
{
|
{
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
l->clear({0, 0, 0, 0});
|
l->clear({0, 0, 0, 0});
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::snap_history(const std::vector<int>& planes)
|
void Canvas::snap_history(const std::vector<int>& planes)
|
||||||
{
|
{
|
||||||
@@ -196,9 +198,9 @@ void Canvas::stroke_end()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
m_show_tmp = false;
|
||||||
stroke_commit();
|
stroke_commit();
|
||||||
m_current_stroke = nullptr;
|
m_current_stroke = nullptr;
|
||||||
m_show_tmp = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void Canvas::stroke_cancel()
|
void Canvas::stroke_cancel()
|
||||||
@@ -465,6 +467,7 @@ void Canvas::stroke_draw()
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
std::array<bool, 6> merge_faces;
|
||||||
|
|
||||||
GLint vp[4];
|
GLint vp[4];
|
||||||
GLfloat cc[4];
|
GLfloat cc[4];
|
||||||
@@ -538,6 +541,7 @@ void Canvas::stroke_draw()
|
|||||||
if (P.size() < 3)
|
if (P.size() < 3)
|
||||||
continue;
|
continue;
|
||||||
m_dirty_face[i] = true;
|
m_dirty_face[i] = true;
|
||||||
|
merge_faces[i] = true;
|
||||||
m_tmp[i].bindFramebuffer();
|
m_tmp[i].bindFramebuffer();
|
||||||
auto rect = stroke_draw_samples(i, P);
|
auto rect = stroke_draw_samples(i, P);
|
||||||
m_tmp[i].unbindFramebuffer();
|
m_tmp[i].unbindFramebuffer();
|
||||||
@@ -594,11 +598,13 @@ void Canvas::stroke_draw()
|
|||||||
|
|
||||||
if (m_commit_delayed)
|
if (m_commit_delayed)
|
||||||
{
|
{
|
||||||
stroke_commit();
|
|
||||||
m_current_stroke = nullptr;
|
|
||||||
m_show_tmp = false;
|
m_show_tmp = false;
|
||||||
m_commit_delayed = false;
|
m_commit_delayed = false;
|
||||||
|
stroke_commit();
|
||||||
|
m_current_stroke = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_merge(merge_faces);
|
||||||
}
|
}
|
||||||
bool Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
bool Canvas::point_trace(glm::vec2 loc, glm::vec3& ray_origin, glm::vec3& ray_dir,
|
||||||
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id)
|
glm::vec3& hit_pos, glm::vec2& fb_pos, glm::vec3& hit_normal, int& out_plane_id)
|
||||||
@@ -864,7 +870,248 @@ void Canvas::stroke_commit()
|
|||||||
action->m_canvas = this;
|
action->m_canvas = this;
|
||||||
//action->m_stroke = std::move(m_current_stroke);
|
//action->m_stroke = std::move(m_current_stroke);
|
||||||
ActionManager::add(action);
|
ActionManager::add(action);
|
||||||
|
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Canvas::draw_merge(std::array<bool, 6> faces /*= SIXPLETTE(false)*/)
|
||||||
|
{
|
||||||
|
gl_state gl;
|
||||||
|
gl.save();
|
||||||
|
glViewport(0, 0, m_width, m_height);
|
||||||
|
auto ortho = glm::ortho<float>(-0.5f, 0.5f, -0.5f, 0.5f, -1.f, 1.f);
|
||||||
|
const auto& b = m_current_stroke->m_brush;
|
||||||
|
|
||||||
|
// 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++)
|
||||||
|
{
|
||||||
|
auto layer_index = m_order[i];
|
||||||
|
use_blend |= m_layers[layer_index]->m_blend_mode != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not using shader blend, use gl rasterizer blend
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
|
{
|
||||||
|
if (!faces[plane_index])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
m_layers_merge.m_rtt[plane_index].bindFramebuffer();
|
||||||
|
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
glDisable(GL_BLEND);
|
||||||
|
m_layers_merge.m_rtt[plane_index].clear();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ShaderManager::use(kShader::Checkerboard);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int layer_index : m_order)
|
||||||
|
{
|
||||||
|
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]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_merge_rtt.bindFramebuffer();
|
||||||
|
m_merge_rtt.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_current_stroke && m_current_mode == kCanvasMode::Erase && m_show_tmp && m_current_layer_idx == layer_index)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
ShaderManager::use(kShader::CompErase);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_box) / zoom);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
|
//ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index]->m_alpha_locked);
|
||||||
|
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();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tmp[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_smask.m_rtt[plane_index].bindTexture();
|
||||||
|
m_plane.draw_fill();
|
||||||
|
m_smask.m_rtt[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tmp[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
else if (m_current_stroke && m_show_tmp && m_current_layer_idx == layer_index)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
|
||||||
|
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
||||||
|
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||||
|
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::CompDraw);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexDual, 3);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Lock, m_layers[layer_index]->m_alpha_locked);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Mask, m_smask_active);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UseFragcoord, false);
|
||||||
|
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
|
||||||
|
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::PatternScale, patt_scale);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||||
|
ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||||
|
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tmp[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_smask.m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
if (b->m_dual_enabled)
|
||||||
|
m_tmp_dual[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
b->m_pattern_texture ?
|
||||||
|
b->m_pattern_texture->bind() :
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
if (b->m_dual_enabled)
|
||||||
|
m_tmp_dual[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_smask.m_rtt[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_tmp[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_sampler_linear.bind(1);
|
||||||
|
ShaderManager::use(kShader::TextureAlphaSep);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index]->m_opacity);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Highlight, m_layers[layer_index]->m_hightlight);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
|
|
||||||
|
m_plane.draw_fill();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_merge_rtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the blended
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_sampler_linear.bind(1);
|
||||||
|
m_sampler.bind(2);
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_layers[layer_index]->m_blend_mode);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_merge_rtt.bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_merge_rtt.bindTexture();
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_merge_tex.bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_plane.draw_fill();
|
||||||
|
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_merge_tex.unbind();
|
||||||
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_merge_rtt.unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_merge_rtt.unbindTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_merge_tex.bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height);
|
||||||
|
|
||||||
|
// draw the grid behind the layers using a temporary copy
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
//draw the grid
|
||||||
|
ShaderManager::use(kShader::Checkerboard);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
|
||||||
|
// draw the layers
|
||||||
|
m_sampler.bind(0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_merge_tex.bind();
|
||||||
|
ShaderManager::use(kShader::Texture);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, ortho);
|
||||||
|
m_plane.draw_fill();
|
||||||
|
m_merge_tex.unbind();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_layers_merge.m_rtt[plane_index].unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
gl.restore();
|
||||||
|
}
|
||||||
|
|
||||||
void Canvas::stroke_update(glm::vec3 point, float pressure)
|
void Canvas::stroke_update(glm::vec3 point, float pressure)
|
||||||
{
|
{
|
||||||
m_current_stroke->add_point(point, pressure);
|
m_current_stroke->add_point(point, pressure);
|
||||||
@@ -876,11 +1123,11 @@ void Canvas::stroke_start(glm::vec3 point, float pressure)
|
|||||||
// need to commit this now before starting a new stroke
|
// need to commit this now before starting a new stroke
|
||||||
if (m_current_stroke && m_commit_delayed)
|
if (m_current_stroke && m_commit_delayed)
|
||||||
{
|
{
|
||||||
|
m_show_tmp = false;
|
||||||
|
m_commit_delayed = false;
|
||||||
stroke_commit();
|
stroke_commit();
|
||||||
m_current_stroke = nullptr;
|
m_current_stroke = nullptr;
|
||||||
m_dual_stroke = nullptr;
|
m_dual_stroke = nullptr;
|
||||||
m_show_tmp = false;
|
|
||||||
m_commit_delayed = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pattern_offset = m_current_brush->m_pattern_rand_offset ?
|
m_pattern_offset = m_current_brush->m_pattern_rand_offset ?
|
||||||
@@ -947,6 +1194,7 @@ void Canvas::layer_add(std::string name)
|
|||||||
m_layers.back()->create(m_width, m_height, name);
|
m_layers.back()->create(m_width, m_height, name);
|
||||||
m_order.push_back(idx);
|
m_order.push_back(idx);
|
||||||
m_current_layer_idx = idx;
|
m_current_layer_idx = idx;
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::layer_remove(int idx) // m_order index
|
void Canvas::layer_remove(int idx) // m_order index
|
||||||
{
|
{
|
||||||
@@ -958,10 +1206,12 @@ void Canvas::layer_remove(int idx) // m_order index
|
|||||||
m_layers.erase(m_layers.begin() + n);
|
m_layers.erase(m_layers.begin() + n);
|
||||||
m_order.erase(m_order.begin() + idx);
|
m_order.erase(m_order.begin() + idx);
|
||||||
m_current_layer_idx = m_order[std::min<int>((int)m_layers.size() - 1, idx)];
|
m_current_layer_idx = m_order[std::min<int>((int)m_layers.size() - 1, idx)];
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::layer_order(int idx, int pos) // m_order index
|
void Canvas::layer_order(int idx, int pos) // m_order index
|
||||||
{
|
{
|
||||||
std::swap(m_order[idx], m_order[pos]);
|
std::swap(m_order[idx], m_order[pos]);
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
||||||
{
|
{
|
||||||
@@ -1054,6 +1304,7 @@ void Canvas::layer_merge(int source_idx, int dest_idx) // m_layer index
|
|||||||
action->m_stroke = std::move(m_current_stroke);
|
action->m_stroke = std::move(m_current_stroke);
|
||||||
ActionManager::add(action);
|
ActionManager::add(action);
|
||||||
*/
|
*/
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
void Canvas::resize(int width, int height)
|
void Canvas::resize(int width, int height)
|
||||||
{
|
{
|
||||||
@@ -1073,9 +1324,12 @@ void Canvas::resize(int width, int height)
|
|||||||
#endif
|
#endif
|
||||||
m_tex2[i].create(width, height, GL_RGBA8);
|
m_tex2[i].create(width, height, GL_RGBA8);
|
||||||
}
|
}
|
||||||
|
m_layers_merge.resize(width, height);
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
l->resize(width, height);
|
l->resize(width, height);
|
||||||
m_smask.create(width, height, "mask");
|
m_smask.create(width, height, "mask");
|
||||||
|
m_merge_rtt.create(width, height);
|
||||||
|
m_merge_tex.create(width, height);
|
||||||
m_unsaved = true;
|
m_unsaved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1088,10 +1342,13 @@ void Canvas::destroy()
|
|||||||
m_tex[i].destroy();
|
m_tex[i].destroy();
|
||||||
m_tex2[i].destroy();
|
m_tex2[i].destroy();
|
||||||
}
|
}
|
||||||
|
m_layers_merge.destroy();
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
l->destroy();
|
l->destroy();
|
||||||
m_smask.destroy();
|
m_smask.destroy();
|
||||||
m_mixer.destroy();
|
m_mixer.destroy();
|
||||||
|
m_merge_rtt.destroy();
|
||||||
|
m_merge_tex.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Canvas::create(int width, int height)
|
bool Canvas::create(int width, int height)
|
||||||
@@ -1105,15 +1362,18 @@ bool Canvas::create(int width, int height)
|
|||||||
m_tmp[i].create(width, height, -1, GL_RGBA8);
|
m_tmp[i].create(width, height, -1, GL_RGBA8);
|
||||||
m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
|
m_tmp_dual[i].create(width, height, -1, GL_RGBA8);
|
||||||
m_tex[i].create(width, height, GL_RGBA8);
|
m_tex[i].create(width, height, GL_RGBA8);
|
||||||
m_sampler_brush.create();
|
|
||||||
#else
|
#else
|
||||||
m_tmp[i].create(width, height, -1, GL_RGBA32F);
|
m_tmp[i].create(width, height, -1, GL_RGBA32F);
|
||||||
m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
|
m_tmp_dual[i].create(width, height, -1, GL_RGBA32F);
|
||||||
m_tex[i].create(width, height, GL_RGBA32F);
|
m_tex[i].create(width, height, GL_RGBA32F);
|
||||||
m_sampler_brush.create(GL_LINEAR, GL_CLAMP_TO_BORDER);
|
|
||||||
#endif
|
#endif
|
||||||
m_tex2[i].create(width, height, GL_RGBA8);
|
m_tex2[i].create(width, height, GL_RGBA8);
|
||||||
}
|
}
|
||||||
|
#if defined(__IOS__) || defined(__ANDROID__)
|
||||||
|
m_sampler_brush.create();
|
||||||
|
#else
|
||||||
|
m_sampler_brush.create(GL_LINEAR, GL_CLAMP_TO_BORDER);
|
||||||
|
#endif
|
||||||
m_sampler.create(GL_NEAREST);
|
m_sampler.create(GL_NEAREST);
|
||||||
m_sampler.create(GL_LINEAR);
|
m_sampler.create(GL_LINEAR);
|
||||||
m_sampler_nearest.create(GL_NEAREST);
|
m_sampler_nearest.create(GL_NEAREST);
|
||||||
@@ -1129,11 +1389,15 @@ bool Canvas::create(int width, int height)
|
|||||||
m_brush_shape.create();
|
m_brush_shape.create();
|
||||||
m_mesh.create();
|
m_mesh.create();
|
||||||
m_brush_mix.create(8, 8);
|
m_brush_mix.create(8, 8);
|
||||||
|
m_layers_merge.create(width, height, "merge");
|
||||||
for (auto& l : m_layers)
|
for (auto& l : m_layers)
|
||||||
l->create(width, height, "");
|
l->create(width, height, "");
|
||||||
m_smask.create(width, height, "mask");
|
m_smask.create(width, height, "mask");
|
||||||
//m_smask.clear({1, 1, 1, 1});
|
//m_smask.clear({1, 1, 1, 1});
|
||||||
|
m_merge_rtt.create(width, height);
|
||||||
|
m_merge_tex.create(width, height);
|
||||||
m_unsaved = true;
|
m_unsaved = true;
|
||||||
|
draw_merge();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2198,6 +2462,17 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
fclose(fp);
|
fclose(fp);
|
||||||
LOG("project restore from %s", file_path.c_str());
|
LOG("project restore from %s", file_path.c_str());
|
||||||
|
|
||||||
|
m_current_layer_idx = 0;
|
||||||
|
m_current_stroke = nullptr;
|
||||||
|
m_dual_stroke = nullptr;
|
||||||
|
m_show_tmp = false;
|
||||||
|
m_smask_active = false;
|
||||||
|
m_smask_mode = 0;
|
||||||
|
m_dirty = false;
|
||||||
|
m_commit_delayed = false;
|
||||||
|
m_dirty_stroke = false;
|
||||||
|
memset(m_dirty_face, 0, sizeof(bool) * 6);
|
||||||
|
memset(m_pick_ready, 0, sizeof(bool) * 6);
|
||||||
m_unsaved = false;
|
m_unsaved = false;
|
||||||
m_newdoc = false;
|
m_newdoc = false;
|
||||||
if (App::I.layout.m_loaded)
|
if (App::I.layout.m_loaded)
|
||||||
@@ -2205,11 +2480,18 @@ bool Canvas::project_open_thread(std::string file_path)
|
|||||||
App::I.async_start();
|
App::I.async_start();
|
||||||
pb->destroy();
|
pb->destroy();
|
||||||
gl.save();
|
gl.save();
|
||||||
|
draw_merge();
|
||||||
App::I.async_update();
|
App::I.async_update();
|
||||||
gl.restore();
|
gl.restore();
|
||||||
App::I.title_update();
|
App::I.title_update();
|
||||||
App::I.async_end();
|
App::I.async_end();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
App::I.async_start();
|
||||||
|
draw_merge();
|
||||||
|
App::I.async_end();
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2393,6 +2675,8 @@ void Canvas::draw_objects_direct(std::function<void(const glm::mat4& camera, con
|
|||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer)
|
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer, Layer& layer)
|
||||||
@@ -2483,6 +2767,8 @@ void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm:
|
|||||||
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
glViewport(vp[0], vp[1], vp[2], vp[3]);
|
||||||
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
glClearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
|
||||||
|
draw_merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer)
|
void Canvas::draw_objects(std::function<void(const glm::mat4& camera, const glm::mat4& proj, int i)> observer)
|
||||||
@@ -2794,6 +3080,7 @@ void ActionStroke::undo()
|
|||||||
LOG("undo invalid box size (%d, %d)", (int)box_sz.x, (int)box_sz.y);
|
LOG("undo invalid box size (%d, %d)", (int)box_sz.x, (int)box_sz.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
m_canvas->draw_merge();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t ActionStroke::memory()
|
size_t ActionStroke::memory()
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ public:
|
|||||||
std::unique_ptr<Stroke> m_dual_stroke;
|
std::unique_ptr<Stroke> m_dual_stroke;
|
||||||
bool m_show_tmp = false;
|
bool m_show_tmp = false;
|
||||||
std::vector<std::unique_ptr<Layer>> m_layers;
|
std::vector<std::unique_ptr<Layer>> m_layers;
|
||||||
|
Layer m_layers_merge;
|
||||||
std::vector<int> m_order;
|
std::vector<int> m_order;
|
||||||
std::vector<glm::vec2> m_plane_shape[6]; // screen space projection of the plane
|
std::vector<glm::vec2> m_plane_shape[6]; // screen space projection of the plane
|
||||||
glm::mat4 m_plane_unproject[6] = SIXPLETTE(glm::mat4(1));
|
glm::mat4 m_plane_unproject[6] = SIXPLETTE(glm::mat4(1));
|
||||||
@@ -184,6 +185,8 @@ public:
|
|||||||
Texture2D m_brush_mix;
|
Texture2D m_brush_mix;
|
||||||
Texture2D m_tex[6];
|
Texture2D m_tex[6];
|
||||||
Texture2D m_tex2[6];
|
Texture2D m_tex2[6];
|
||||||
|
RTT m_merge_rtt;
|
||||||
|
Texture2D m_merge_tex;
|
||||||
bool m_pick_ready[6];
|
bool m_pick_ready[6];
|
||||||
std::unique_ptr<glm::u8vec4[]> m_pick_data[6] = SIXPLETTE(nullptr);
|
std::unique_ptr<glm::u8vec4[]> m_pick_data[6] = SIXPLETTE(nullptr);
|
||||||
static glm::vec3 m_plane_origin[6];
|
static glm::vec3 m_plane_origin[6];
|
||||||
@@ -247,6 +250,7 @@ public:
|
|||||||
void stroke_end();
|
void stroke_end();
|
||||||
void stroke_cancel();
|
void stroke_cancel();
|
||||||
void stroke_commit();
|
void stroke_commit();
|
||||||
|
void draw_merge(std::array<bool, 6> faces = SIXPLETTE(true));
|
||||||
void clear(const glm::vec4& color = { 1, 1, 1, 0 });
|
void clear(const glm::vec4& color = { 1, 1, 1, 0 });
|
||||||
void clear_all();
|
void clear_all();
|
||||||
void pick_start();
|
void pick_start();
|
||||||
|
|||||||
@@ -81,10 +81,6 @@ void NodeCanvas::draw()
|
|||||||
m_canvas->m_box = box;
|
m_canvas->m_box = box;
|
||||||
m_canvas->m_vp = c;
|
m_canvas->m_vp = c;
|
||||||
|
|
||||||
// auto plane_mvp = proj * camera * transform *
|
|
||||||
// glm::scale(glm::vec3(sz, 1));
|
|
||||||
|
|
||||||
|
|
||||||
m_sampler.bind(0);
|
m_sampler.bind(0);
|
||||||
m_sampler.bind(1);
|
m_sampler.bind(1);
|
||||||
m_sampler.bind(2);
|
m_sampler.bind(2);
|
||||||
@@ -114,21 +110,11 @@ void NodeCanvas::draw()
|
|||||||
m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index);
|
m_canvas->m_plane_shape[plane_index] = m_canvas->face_to_shape2D(plane_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if any layer use blend, otherwise draw directly on main framebuffer
|
bool draw_merged = !(m_canvas->m_current_mode == kCanvasMode::Camera);
|
||||||
bool use_blend = false;
|
|
||||||
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
|
|
||||||
{
|
|
||||||
auto layer_index = m_canvas->m_order[i];
|
|
||||||
use_blend |= m_canvas->m_layers[layer_index]->m_blend_mode != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_blend)
|
if (draw_merged)
|
||||||
{
|
|
||||||
m_cache_rtt.bindFramebuffer();
|
|
||||||
m_cache_rtt.clear({ 1, 1, 1, 0 });
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
|
glDisable(GL_BLEND);
|
||||||
// draw the grid
|
// draw the grid
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
{
|
{
|
||||||
@@ -141,243 +127,303 @@ void NodeCanvas::draw()
|
|||||||
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if not using shader blend, use gl rasterizer blend
|
int z = 1;
|
||||||
use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND);
|
auto plane_mvp_z = proj * camera *
|
||||||
glDisable(GL_DEPTH_TEST);
|
//glm::scale(glm::vec3(z + 1)) *
|
||||||
|
//glm::eulerAngleYXZ(yaw, pitch, roll) *
|
||||||
const auto& b = m_canvas->m_current_stroke->m_brush;
|
|
||||||
|
|
||||||
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
|
|
||||||
{
|
|
||||||
auto layer_index = m_canvas->m_order[i];
|
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
|
||||||
{
|
|
||||||
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]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (use_blend)
|
|
||||||
{
|
|
||||||
m_blender_rtt.bindFramebuffer();
|
|
||||||
m_blender_rtt.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
int z = (int)(m_canvas->m_order.size() - i);
|
|
||||||
auto plane_mvp_z = proj * camera *
|
|
||||||
glm::scale(glm::vec3(z + 1)) *
|
|
||||||
glm::eulerAngleYXZ(yaw, pitch, roll) *
|
|
||||||
m_canvas->m_plane_transform[plane_index] *
|
|
||||||
glm::translate(glm::vec3(0, 0, -1));
|
|
||||||
|
|
||||||
if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
|
||||||
{
|
|
||||||
m_sampler.bind(0);
|
|
||||||
ShaderManager::use(kShader::CompErase);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
|
||||||
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
|
||||||
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked);
|
|
||||||
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();
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_tmp[plane_index].bindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
|
||||||
m_face_plane.draw_fill();
|
|
||||||
m_canvas->m_smask.m_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();
|
|
||||||
}
|
|
||||||
else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
|
||||||
{
|
|
||||||
m_sampler.bind(0);
|
|
||||||
|
|
||||||
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
|
||||||
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
|
||||||
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
|
||||||
|
|
||||||
ShaderManager::use(kShader::CompDraw);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexDual, 3);
|
|
||||||
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
|
||||||
ShaderManager::u_int(kShaderUniform::UseFragcoord, false);
|
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
|
||||||
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
|
|
||||||
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
|
|
||||||
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
|
|
||||||
ShaderManager::u_vec2(kShaderUniform::PatternScale, patt_scale);
|
|
||||||
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
|
||||||
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
|
||||||
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
|
||||||
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
|
||||||
ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode);
|
|
||||||
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
|
||||||
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers[layer_index]->m_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();
|
|
||||||
glActiveTexture(GL_TEXTURE3);
|
|
||||||
if (b->m_dual_enabled)
|
|
||||||
m_canvas->m_tmp_dual[plane_index].bindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE4);
|
|
||||||
b->m_pattern_texture ?
|
|
||||||
b->m_pattern_texture->bind() :
|
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
|
||||||
m_face_plane.draw_fill();
|
|
||||||
glActiveTexture(GL_TEXTURE3);
|
|
||||||
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();
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_tmp[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_sampler.bind(0);
|
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
ShaderManager::use(kShader::TextureAlphaSep);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_blend)
|
|
||||||
{
|
|
||||||
m_blender_rtt.unbindFramebuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the blended
|
|
||||||
if (use_blend)
|
|
||||||
{
|
|
||||||
m_sampler.bind(0);
|
|
||||||
m_sampler_linear.bind(1);
|
|
||||||
m_sampler.bind(2);
|
|
||||||
|
|
||||||
ShaderManager::use(kShader::TextureBlend);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
|
||||||
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
|
||||||
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode);
|
|
||||||
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
|
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_blender_rtt.bindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_blender_rtt.bindTexture();
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
m_blender_bg.bind();
|
|
||||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
|
|
||||||
m_blender_bg.size().x, m_blender_bg.size().y);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_face_plane.draw_fill();
|
|
||||||
|
|
||||||
if (!ShaderManager::ext_framebuffer_fetch)
|
|
||||||
{
|
|
||||||
glActiveTexture(GL_TEXTURE2);
|
|
||||||
m_blender_bg.unbind();
|
|
||||||
}
|
|
||||||
glActiveTexture(GL_TEXTURE1);
|
|
||||||
m_blender_rtt.unbindTexture();
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
|
||||||
m_blender_rtt.unbindTexture();
|
|
||||||
}
|
|
||||||
|
|
||||||
#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;
|
|
||||||
glm::vec2 bbmin = xy(bb);
|
|
||||||
glm::vec2 bbsz = zw(bb) - xy(bb);
|
|
||||||
ShaderManager::use(kShader::Color);
|
|
||||||
ShaderManager::u_vec4(kShaderUniform::Col, { 1, 0, 0, 1 });
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z
|
|
||||||
* glm::translate(glm::vec3(bbmin * 2.f, 0))
|
|
||||||
* glm::translate(glm::vec3(-1, -1, 0))
|
|
||||||
* glm::scale(glm::vec3(bbsz, 1))
|
|
||||||
* glm::translate(glm::vec3(1, 1, 0))
|
|
||||||
);
|
|
||||||
m_face_plane.draw_stroke();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (use_blend)
|
|
||||||
{
|
|
||||||
m_cache_rtt.unbindFramebuffer();
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw the grid behind the layers using a temporary copy
|
|
||||||
if (use_blend)
|
|
||||||
{
|
|
||||||
glEnable(GL_BLEND);
|
|
||||||
|
|
||||||
//draw the grid
|
|
||||||
for (int plane_index = 0; plane_index < 6; plane_index++)
|
|
||||||
{
|
|
||||||
auto plane_mvp = proj * camera *
|
|
||||||
glm::scale(glm::vec3(m_canvas->m_order.size() + 500.f)) *
|
|
||||||
m_canvas->m_plane_transform[plane_index] *
|
m_canvas->m_plane_transform[plane_index] *
|
||||||
glm::translate(glm::vec3(0, 0, -1.f));
|
glm::translate(glm::vec3(0, 0, -1));
|
||||||
|
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_sampler_linear.bind(1);
|
||||||
|
ShaderManager::use(kShader::TextureAlphaSep);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Highlight, false);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_layers_merge.m_rtt[plane_index].bindTexture();
|
||||||
|
|
||||||
ShaderManager::use(kShader::Checkerboard);
|
|
||||||
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
|
||||||
m_face_plane.draw_fill();
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers_merge.m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// check if any layer use blend, otherwise draw directly on main framebuffer
|
||||||
|
bool use_blend = false;
|
||||||
|
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
|
||||||
|
{
|
||||||
|
auto layer_index = m_canvas->m_order[i];
|
||||||
|
use_blend |= m_canvas->m_layers[layer_index]->m_blend_mode != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the layers
|
if (use_blend)
|
||||||
m_sampler.bind(0);
|
{
|
||||||
glActiveTexture(GL_TEXTURE0);
|
m_cache_rtt.bindFramebuffer();
|
||||||
m_cache_rtt.bindTexture();
|
m_cache_rtt.clear({ 1, 1, 1, 0 });
|
||||||
ShaderManager::use(kShader::Texture);
|
}
|
||||||
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
else
|
||||||
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho<float>(-1, 1, -1, 1));
|
{
|
||||||
m_face_plane.draw_fill();
|
// draw the grid
|
||||||
m_cache_rtt.unbindTexture();
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
|
{
|
||||||
|
auto plane_mvp = proj * camera *
|
||||||
|
glm::scale(glm::vec3(m_canvas->m_order.size() + 500)) *
|
||||||
|
m_canvas->m_plane_transform[plane_index] *
|
||||||
|
glm::translate(glm::vec3(0, 0, -1));
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::Checkerboard);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if not using shader blend, use gl rasterizer blend
|
||||||
|
use_blend ? glDisable(GL_BLEND) : glEnable(GL_BLEND);
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
const auto& b = m_canvas->m_current_stroke->m_brush;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < m_canvas->m_order.size(); i++)
|
||||||
|
{
|
||||||
|
auto layer_index = m_canvas->m_order[i];
|
||||||
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
|
{
|
||||||
|
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]))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_blender_rtt.bindFramebuffer();
|
||||||
|
m_blender_rtt.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
int z = (int)(m_canvas->m_order.size() - i);
|
||||||
|
auto plane_mvp_z = proj * camera *
|
||||||
|
glm::scale(glm::vec3(z + 1)) *
|
||||||
|
glm::eulerAngleYXZ(yaw, pitch, roll) *
|
||||||
|
m_canvas->m_plane_transform[plane_index] *
|
||||||
|
glm::translate(glm::vec3(0, 0, -1));
|
||||||
|
|
||||||
|
if (m_canvas->m_current_stroke && m_canvas->m_current_mode == kCanvasMode::Erase && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
ShaderManager::use(kShader::CompErase);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
//ShaderManager::u_vec2(kShaderUniform::Resolution, zw(m_canvas->m_box) / zoom);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
||||||
|
//ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked);
|
||||||
|
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();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_tmp[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_canvas->m_smask.m_rtt[plane_index].bindTexture();
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
m_canvas->m_smask.m_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();
|
||||||
|
}
|
||||||
|
else if(m_canvas->m_current_stroke && m_canvas->m_show_tmp && m_canvas->m_current_layer_idx == layer_index)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
|
||||||
|
glm::vec2 patt_scale = glm::vec2(b->m_pattern_scale);
|
||||||
|
if (b->m_pattern_flipx) patt_scale.x *= -1.f;
|
||||||
|
if (b->m_pattern_flipy) patt_scale.y *= -1.f;
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::CompDraw);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexMask, 2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexDual, 3);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexPattern, 4);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Lock, m_canvas->m_layers[layer_index]->m_alpha_locked);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Mask, m_canvas->m_smask_active);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UseFragcoord, false);
|
||||||
|
ShaderManager::u_int(kShaderUniform::BlendMode, b->m_blend_mode);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UseDual, b->m_dual_enabled);
|
||||||
|
ShaderManager::u_int(kShaderUniform::DualBlendMode, b->m_dual_blend_mode);
|
||||||
|
ShaderManager::u_int(kShaderUniform::UsePattern, b->m_pattern_enabled && !b->m_pattern_eachsample);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::PatternScale, patt_scale);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternInvert, b->m_pattern_invert);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternBright, b->m_pattern_brightness);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternContrast, b->m_pattern_contrast);
|
||||||
|
ShaderManager::u_float(kShaderUniform::PatternDepth, b->m_pattern_depth);
|
||||||
|
ShaderManager::u_int(kShaderUniform::PatternBlendMode, b->m_pattern_blend_mode);
|
||||||
|
ShaderManager::u_vec2(kShaderUniform::PatternOffset, Canvas::I->m_pattern_offset);
|
||||||
|
ShaderManager::u_float(kShaderUniform::DualAlpha, b->m_dual_opacity);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers[layer_index]->m_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();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
if (b->m_dual_enabled)
|
||||||
|
m_canvas->m_tmp_dual[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE4);
|
||||||
|
b->m_pattern_texture ?
|
||||||
|
b->m_pattern_texture->bind() :
|
||||||
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
glActiveTexture(GL_TEXTURE3);
|
||||||
|
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();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_tmp[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_sampler_linear.bind(1);
|
||||||
|
ShaderManager::use(kShader::TextureAlphaSep);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, m_canvas->m_layers[layer_index]->m_opacity);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Highlight, m_canvas->m_layers[layer_index]->m_hightlight);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z);
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].bindTexture();
|
||||||
|
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_canvas->m_layers[layer_index]->m_rtt[plane_index].unbindTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_blender_rtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the blended
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_sampler.bind(0);
|
||||||
|
m_sampler_linear.bind(1);
|
||||||
|
m_sampler.bind(2);
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::TextureBlend);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexA, 1);
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
ShaderManager::u_int(kShaderUniform::TexBG, 2);
|
||||||
|
ShaderManager::u_int(kShaderUniform::BlendMode, m_canvas->m_layers[layer_index]->m_blend_mode);
|
||||||
|
ShaderManager::u_float(kShaderUniform::Alpha, 1.f);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1, 1, -1, 1));
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_blender_rtt.bindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_blender_rtt.bindTexture();
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_blender_bg.bind();
|
||||||
|
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0,
|
||||||
|
m_blender_bg.size().x, m_blender_bg.size().y);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
|
||||||
|
if (!ShaderManager::ext_framebuffer_fetch)
|
||||||
|
{
|
||||||
|
glActiveTexture(GL_TEXTURE2);
|
||||||
|
m_blender_bg.unbind();
|
||||||
|
}
|
||||||
|
glActiveTexture(GL_TEXTURE1);
|
||||||
|
m_blender_rtt.unbindTexture();
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_blender_rtt.unbindTexture();
|
||||||
|
}
|
||||||
|
|
||||||
|
#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;
|
||||||
|
glm::vec2 bbmin = xy(bb);
|
||||||
|
glm::vec2 bbsz = zw(bb) - xy(bb);
|
||||||
|
ShaderManager::use(kShader::Color);
|
||||||
|
ShaderManager::u_vec4(kShaderUniform::Col, { 1, 0, 0, 1 });
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp_z
|
||||||
|
* glm::translate(glm::vec3(bbmin * 2.f, 0))
|
||||||
|
* glm::translate(glm::vec3(-1, -1, 0))
|
||||||
|
* glm::scale(glm::vec3(bbsz, 1))
|
||||||
|
* glm::translate(glm::vec3(1, 1, 0))
|
||||||
|
);
|
||||||
|
m_face_plane.draw_stroke();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
m_cache_rtt.unbindFramebuffer();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the grid behind the layers using a temporary copy
|
||||||
|
if (use_blend)
|
||||||
|
{
|
||||||
|
glEnable(GL_BLEND);
|
||||||
|
|
||||||
|
//draw the grid
|
||||||
|
for (int plane_index = 0; plane_index < 6; plane_index++)
|
||||||
|
{
|
||||||
|
auto plane_mvp = proj * camera *
|
||||||
|
glm::scale(glm::vec3(m_canvas->m_order.size() + 500.f)) *
|
||||||
|
m_canvas->m_plane_transform[plane_index] *
|
||||||
|
glm::translate(glm::vec3(0, 0, -1.f));
|
||||||
|
|
||||||
|
ShaderManager::use(kShader::Checkerboard);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Colorize, false);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp);
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw the layers
|
||||||
|
m_sampler.bind(0);
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
m_cache_rtt.bindTexture();
|
||||||
|
ShaderManager::use(kShader::Texture);
|
||||||
|
ShaderManager::u_int(kShaderUniform::Tex, 0);
|
||||||
|
ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho<float>(-1, 1, -1, 1));
|
||||||
|
m_face_plane.draw_fill();
|
||||||
|
m_cache_rtt.unbindTexture();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glDisable(GL_DEPTH_TEST);
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|||||||
Reference in New Issue
Block a user