From 352511a9200efb2445a2606db142d8b25779c03c Mon Sep 17 00:00:00 2001 From: omigamedev Date: Mon, 7 Jan 2019 16:17:13 +0100 Subject: [PATCH] Update thumbnail generation to implement blending --- src/canvas.cpp | 74 +++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 16 deletions(-) diff --git a/src/canvas.cpp b/src/canvas.cpp index 59d8bfd..fcd32b8 100644 --- a/src/canvas.cpp +++ b/src/canvas.cpp @@ -2,6 +2,7 @@ #include "log.h" #include "canvas.h" #include "app.h" +#include "texture.h" #include "node_progress_bar.h" #include @@ -1291,6 +1292,7 @@ void Canvas::export_equirectangular_thread(std::string file_path) ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); m_tmp[i].bindFramebuffer(); + // clear transparent not to mess with blending modes m_tmp[i].clear({ 1, 1, 1, 0 }); glActiveTexture(GL_TEXTURE2); @@ -1300,7 +1302,9 @@ void Canvas::export_equirectangular_thread(std::string file_path) m_sampler_bg.bind(2); for (auto layer_index : m_order) { - if (!m_layers[layer_index].m_visible || m_layers[layer_index].m_opacity == 0.f) + if (!m_layers[layer_index].m_visible || + m_layers[layer_index].m_opacity == 0.f || + !m_layers[layer_index].m_dirty_face) continue; glActiveTexture(GL_TEXTURE2); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height); @@ -1318,6 +1322,7 @@ void Canvas::export_equirectangular_thread(std::string file_path) glActiveTexture(GL_TEXTURE2); face.unbind(); + // now blend with the background glEnable(GL_BLEND); ShaderManager::use(kShader::Texture); ShaderManager::u_int(kShaderUniform::Tex, 0); @@ -1325,6 +1330,7 @@ void Canvas::export_equirectangular_thread(std::string file_path) m_sampler_mask.bind(0); // linear glActiveTexture(GL_TEXTURE0); face.bind(); + // copy the framebuffer before clearing to white glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, m_width, m_height); m_tmp[i].clear({ 1, 1, 1, 1 }); m_plane.draw_fill(); @@ -2047,7 +2053,6 @@ bool Canvas::project_open_thread(std::string file_path) Image Canvas::thumbnail_generate(int w, int h) { - // save viewport and clear color states GLint vp[4]; GLfloat cc[4]; @@ -2061,33 +2066,69 @@ Image Canvas::thumbnail_generate(int w, int h) RTT fb; fb.create(w, h); fb.bindFramebuffer(); - fb.clear({ 1, 1, 1, 1 }); Plane m_face_plane; m_face_plane.create<1>(2, 2); + Texture2D blendtex; + blendtex.create(w, h); // recalculate because of different aspect ratio than the m_proj matrix glm::mat4 proj = glm::perspective(glm::radians(m_cam_fov), (float)w / (float)h, 0.1f, 1000.f); - glEnable(GL_BLEND); - for (int plane_index = 0; plane_index < 6; plane_index++) + fb.clear({ 1, 1, 1, 0 }); + for (int i = 0; i < 6; i++) { - auto plane_mvp = proj * m_mv * m_plane_transform[plane_index] * glm::translate(glm::vec3(0, 0, -1)); + glDisable(GL_BLEND); + auto plane_mvp = proj * m_mv * m_plane_transform[i] * glm::translate(glm::vec3(0, 0, -1)); + ShaderManager::use(kShader::TextureBlend); + ShaderManager::u_int(kShaderUniform::Tex, 0); + ShaderManager::u_int(kShaderUniform::TexA, 1); + ShaderManager::u_int(kShaderUniform::TexBG, 2); + ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); + glActiveTexture(GL_TEXTURE2); + blendtex.bind(); + m_sampler_bg.bind(0); // nearest + m_sampler_mask.bind(1); // linear + m_sampler_bg.bind(2); + for (auto layer_index : m_order) + { + if (!m_layers[layer_index].m_visible || + m_layers[layer_index].m_opacity == 0.f || + !m_layers[layer_index].m_dirty_face) + continue; + glActiveTexture(GL_TEXTURE2); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, 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(); + glActiveTexture(GL_TEXTURE1); + m_layers[layer_index].m_rtt[i].bindTexture(); + m_face_plane.draw_fill(); + m_layers[layer_index].m_rtt[i].unbindTexture(); + glActiveTexture(GL_TEXTURE0); + m_layers[layer_index].m_rtt[i].unbindTexture(); + } + + // copy the framebuffer before clearing to white + glActiveTexture(GL_TEXTURE2); + glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, w, h); + + // draw the grid ShaderManager::use(kShader::Checkerboard); ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); m_face_plane.draw_fill(); - ShaderManager::use(kShader::TextureAlpha); + // now blend with the background + glEnable(GL_BLEND); + ShaderManager::use(kShader::Texture); ShaderManager::u_int(kShaderUniform::Tex, 0); - ShaderManager::u_int(kShaderUniform::Highlight, false); - ShaderManager::u_mat4(kShaderUniform::MVP, plane_mvp); - for (auto layer_index : m_order) - { - ShaderManager::u_float(kShaderUniform::Alpha, m_layers[layer_index].m_opacity); - m_layers[layer_index].m_rtt[plane_index].bindTexture(); - m_face_plane.draw_fill(); - m_layers[layer_index].m_rtt[plane_index].unbindTexture(); - } + ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); + m_sampler_mask.bind(0); // linear + glActiveTexture(GL_TEXTURE0); + blendtex.bind(); + m_plane.draw_fill(); + blendtex.unbind(); } fb.unbindFramebuffer(); @@ -2098,6 +2139,7 @@ Image Canvas::thumbnail_generate(int w, int h) fb.readTextureData((uint8_t*)image.data()); fb.destroy(); + blendtex.destroy(); // restore viewport and clear color states blend ? glEnable(GL_BLEND) : glDisable(GL_BLEND);