From 9a82d57ed566a16fc6a98de9abfe438eb1a27fbc Mon Sep 17 00:00:00 2001 From: omigamedev Date: Tue, 9 Jul 2019 08:01:24 +0200 Subject: [PATCH] encapsulate in render_task canvas mode operations --- src/canvas_modes.cpp | 158 +++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 80 deletions(-) diff --git a/src/canvas_modes.cpp b/src/canvas_modes.cpp index 6535b8f..41228c5 100644 --- a/src/canvas_modes.cpp +++ b/src/canvas_modes.cpp @@ -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(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 poly2d; static std::vector 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(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);