132 lines
3.0 KiB
C++
132 lines
3.0 KiB
C++
#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<uint8_t[]>(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<glm::u8vec4*>(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;
|
|
}
|