encapsulate in render_task canvas mode operations

This commit is contained in:
2019-07-09 08:01:24 +02:00
parent cb6744be44
commit 9a82d57ed5

View File

@@ -228,6 +228,7 @@ void CanvasModePen::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModePen::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
if (m_draw_tip)
{
const auto& brush = Canvas::I->m_current_brush;
@@ -339,6 +340,8 @@ void CanvasModeLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
if (m_dragging)
{
ShaderManager::use(kShader::Color);
@@ -516,6 +519,8 @@ void CanvasModeGrid::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeGrid::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
const glm::vec4 blue(0, 0, 1, 1);
const glm::vec4 red(1, 0, 0, 1);
for (int i = 0; i < m_lines.size(); i++)
@@ -744,6 +749,8 @@ void CanvasModeMaskFree::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeMaskFree::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
bool depth = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
if (m_points.size() > 3)
@@ -903,6 +910,8 @@ void CanvasModeMaskLine::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeMaskLine::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
if (m_points.size() > 1)
{
if (m_active_tool)
@@ -1025,6 +1034,8 @@ void CanvasModeFill::on_MouseEvent(MouseEvent* me, glm::vec2& loc)
void CanvasModeFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
if (!m_points.empty())
{
ShaderManager::use(kShader::Color);
@@ -1202,14 +1213,17 @@ void CanvasModeTransform::enter(kCanvasMode prev)
}
auto shape3d = triangulate(m_points_face[plane]);
m_shape[plane].update_vertices(shape3d.data(), (int)shape3d.size());
Canvas::I->m_layers[Canvas::I->m_current_layer_idx]->m_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();
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();
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();
});
m_commit_on_leave = true;
}
@@ -1218,20 +1232,7 @@ void CanvasModeTransform::enter(kCanvasMode prev)
{
auto& layer = Canvas::I->m_layers[Canvas::I->m_current_layer_idx];
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
glViewport(0, 0, layer->w, layer->h);
bool depth = glIsEnabled(GL_DEPTH_TEST);
bool blend = glIsEnabled(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
ShaderManager::use(kShader::Color);
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 0 });
auto action = new ActionStroke;
action->was_saved = !Canvas::I->m_unsaved;
@@ -1240,9 +1241,6 @@ void CanvasModeTransform::enter(kCanvasMode prev)
{
auto plane_camera = glm::lookAt(glm::vec3(0), Canvas::I->m_plane_origin[i], Canvas::I->m_plane_tangent[i]);
auto mvp = proj * plane_camera * m_xform * m_xform_local;
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
layer->m_rtt[i].bindFramebuffer();
glm::vec2 bb_min(Canvas::I->m_size);
glm::vec2 bb_max(0, 0);
@@ -1265,13 +1263,9 @@ void CanvasModeTransform::enter(kCanvasMode prev)
auto bb_sz = bb_max - bb_min;
if (bb_sz.x <= 0.f || bb_sz.y <= 0.f)
{
layer->m_rtt[i].unbindFramebuffer();
continue;
}
action->m_image[i] = std::make_unique<uint8_t[]>(bb_sz.x * bb_sz.y * 4);
glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
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];
@@ -1282,15 +1276,23 @@ void CanvasModeTransform::enter(kCanvasMode prev)
glm::max(zw(layer->m_dirty_box[i]), bb_max),
};
for (int j = 0; j < 6; j++)
m_shape[j].draw_fill();
layer->m_rtt[i].unbindFramebuffer();
App::I.render_task([&]
{
glViewport(0, 0, layer->w, layer->h);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
ShaderManager::use(kShader::Color);
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
ShaderManager::u_vec4(kShaderUniform::Col, { 0, 0, 0, 0 });
layer->m_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();
});
}
depth ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
glViewport(vp[0], vp[1], vp[2], vp[3]);
action->m_layer_idx = Canvas::I->m_current_layer_idx;
action->m_canvas = Canvas::I;
@@ -1310,32 +1312,7 @@ void CanvasModeTransform::leave(kCanvasMode next)
auto& layer = Canvas::I->m_layers[Canvas::I->m_current_layer_idx];
GLint vp[4];
glGetIntegerv(GL_VIEWPORT, vp);
glViewport(0, 0, layer->w, layer->h);
bool depth = glIsEnabled(GL_DEPTH_TEST);
bool blend = glIsEnabled(GL_BLEND);
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glm::mat4 proj = glm::perspective(glm::radians(90.f), 1.f, .01f, 1000.f);
ShaderManager::use(kShader::CompDraw);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::UseFragcoord, true);
ShaderManager::u_int(kShaderUniform::Lock, false);
ShaderManager::u_int(kShaderUniform::Mask, false);
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
ShaderManager::u_int(kShaderUniform::BlendMode, 0);
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern, false);
Canvas::I->m_sampler_bg.bind(1);
Canvas::I->m_sampler_bg.bind(0);
auto action = new ActionStroke;
action->was_saved = !Canvas::I->m_unsaved;
@@ -1345,9 +1322,7 @@ void CanvasModeTransform::leave(kCanvasMode next)
auto plane_camera = glm::lookAt(glm::vec3(0), Canvas::I->m_plane_origin[i], Canvas::I->m_plane_tangent[i]);
auto mv = plane_camera * m_xform * m_xform_local;
auto mvp = proj * mv;
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
layer->m_rtt[i].bindFramebuffer();
std::vector<glm::vec2> poly2d;
static std::vector<glm::vec2> face_corners{ {1,1}, {-1,1}, {-1,-1}, {1,-1} };
@@ -1386,13 +1361,9 @@ void CanvasModeTransform::leave(kCanvasMode next)
auto bb_sz = bb_max - bb_min;
if (clipped.empty() || bb_sz.x <= 0.f || bb_sz.y <= 0.f)
{
layer->m_rtt[i].unbindFramebuffer();
continue;
}
action->m_image[i] = std::make_unique<uint8_t[]>(bb_sz.x * bb_sz.y * 4);
glReadPixels(bb_min.x, bb_min.y, bb_sz.x, bb_sz.y, GL_RGBA, GL_UNSIGNED_BYTE, action->m_image[i].get());
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];
@@ -1403,23 +1374,46 @@ void CanvasModeTransform::leave(kCanvasMode next)
glm::max(zw(layer->m_dirty_box[i]), bb_max),
};
glActiveTexture(GL_TEXTURE0);
Canvas::I->m_tex2[i].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, bb_min.x, bb_min.y, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
glActiveTexture(GL_TEXTURE1);
for (int j = 0; j < 6; j++)
App::I.render_task([&]
{
m_tex[j].bind();
m_shape[j].draw_fill();
m_tex[j].unbind();
}
layer->m_rtt[i].bindFramebuffer();
layer->m_rtt[i].unbindFramebuffer();
glDisable(GL_DEPTH_TEST);
glDisable(GL_BLEND);
glActiveTexture(GL_TEXTURE0);
glViewport(0, 0, layer->m_rtt[i].getWidth(), layer->m_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());
// copy fb content to texture for blending
glActiveTexture(GL_TEXTURE0);
Canvas::I->m_tex2[i].bind();
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, bb_min.x, bb_min.y, bb_min.x, bb_min.y, bb_sz.x, bb_sz.y);
// slot for m_tex
glActiveTexture(GL_TEXTURE1);
for (int j = 0; j < 6; j++)
{
ShaderManager::use(kShader::CompDraw);
ShaderManager::u_mat4(kShaderUniform::MVP, mvp);
ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_int(kShaderUniform::TexStroke, 1);
ShaderManager::u_float(kShaderUniform::Alpha, 1);
ShaderManager::u_int(kShaderUniform::UseFragcoord, true);
ShaderManager::u_int(kShaderUniform::Lock, false);
ShaderManager::u_int(kShaderUniform::Mask, false);
ShaderManager::u_vec2(kShaderUniform::Resolution, Canvas::I->m_size);
ShaderManager::u_int(kShaderUniform::BlendMode, 0);
ShaderManager::u_int(kShaderUniform::UseDual, false);
ShaderManager::u_int(kShaderUniform::UsePattern, false);
Canvas::I->m_sampler_bg.bind(1);
Canvas::I->m_sampler_bg.bind(0);
m_tex[j].bind();
m_shape[j].draw_fill();
m_tex[j].unbind();
}
layer->m_rtt[i].unbindFramebuffer();
});
}
depth ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);
blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);
glViewport(vp[0], vp[1], vp[2], vp[3]);
action->m_layer_idx = Canvas::I->m_current_layer_idx;
action->m_canvas = Canvas::I;
@@ -1432,6 +1426,8 @@ void CanvasModeTransform::leave(kCanvasMode next)
void CanvasModeTransform::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
bool depth = glIsEnabled(GL_DEPTH_TEST);
glDisable(GL_DEPTH_TEST);
@@ -1673,6 +1669,8 @@ void CanvasModeFloodFill::init()
void CanvasModeFloodFill::on_Draw(const glm::mat4& ortho, const glm::mat4& proj, const glm::mat4& camera)
{
assert(App::I.is_render_thread());
if (m_draw_tip)
{
ShaderManager::use(kShader::Texture);