#include "pch.h" #include "canvas_layer.h" #include "app.h" #include "rtt.h" uint32_t Layer::s_count = 0; TextureCube Layer::gen_cube() { TextureCube ret; App::I->render_task([&] { ret.create(w); ret.bind(); for (int i = 0; i < 6; i++) { m_rtt[i].bindFramebuffer(); glCopyTexSubImage2D(TextureCube::m_faces_map[i], 0, 0, 0, 0, 0, w, w); m_rtt[i].unbindFramebuffer(); } }); return ret; } Texture2D Layer::gen_equirect() { Texture2D ret; App::I->render_task([&] { gl_state gl; gl.save(); TextureCube cube; RTT latlong; cube = gen_cube(); latlong.create(w * 4, h * 2); ret.create(w * 4, h * 2); glDisable(GL_BLEND); latlong.bindFramebuffer(); latlong.clear({ 0, 1, 1, 1 }); glViewport(0, 0, latlong.getWidth(), latlong.getHeight()); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_CUBE_MAP, cube.m_cubetex_id); ShaderManager::use(kShader::Equirect); ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-.5f, .5f, -.5f, .5f, -1.f, 1.f)); ShaderManager::u_int(kShaderUniform::Tex, 0); Canvas::I->m_sampler.bind(0); Canvas::I->m_plane.draw_fill(); ret.bind(); glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, latlong.getWidth(), latlong.getHeight()); latlong.unbindFramebuffer(); latlong.destroy(); cube.destroy(); gl.restore(); }); return ret; } void Layer::Snapshot::create(int w, int h) { width = w; height = h; for (int i = 0; i < 6; i++) { m_dirty_face[i] = false; m_dirty_box[i] = glm::vec4(width, height, 0, 0); image[i] = std::make_unique(w * h * 4); std::fill_n(image[i].get(), w * h * 4, 0); } } void Layer::Snapshot::clear() { for (int i = 0; i < 6; i++) { m_dirty_face[i] = false; m_dirty_box[i] = glm::vec4(width, height, 0, 0); std::fill_n(image[i].get(), width * height * 4, 0); } } void Layer::Snapshot::optimize() { for (int i = 0; i < 6; i++) { if (!m_dirty_face[i] || !image[i]) continue; auto data = reinterpret_cast(image[i].get()); glm::ivec2 bbmin(width, height); glm::ivec2 bbmax(0); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (data[x + y * width].a > 0) { bbmin = glm::min(bbmin, { x, y }); bbmax = glm::max(bbmax, { x + 1, y + 1 }); } } } //glm::vec2 bbsz = bbmax - bbmin; } } int Layer::Snapshot::memsize() const { int ret = 0; for (int i = 0; i < 6; i++) { if (m_dirty_face[i]) { glm::vec2 sz = zw(m_dirty_box[i]) - xy(m_dirty_box[i]); ret += sz.x * sz.y * 4; } } return ret; }