Skip to content

Instantly share code, notes, and snippets.

@hsdk123
Created September 29, 2021 18:25
Show Gist options
  • Save hsdk123/7f66ecf92d8f51ffaa3e4ac241d4682f to your computer and use it in GitHub Desktop.
Save hsdk123/7f66ecf92d8f51ffaa3e4ac241d4682f to your computer and use it in GitHub Desktop.
bool lvn::Texture::overlayTexture(const std::vector<OverlayInfo>& infos)
{
using namespace std;
const auto canvas_texture_size = getSize();
struct SettingsUnlock {
SettingsUnlock() {
_original_image_quality = CoreHelper::SysVars().imageDefaultQuality.getCurVal();
}
~SettingsUnlock() {
// set rendering back to rendermgr render texture
CRenderMgr::GetInstance().BindForRendering();
CoreHelper::SysVars().imageDefaultQuality.PushNewVal(_original_image_quality);
}
int _original_image_quality = 0;
};
std::unique_ptr<SettingsUnlock> buffer_unlock;
std::unique_ptr<Magnum::GL::Texture2D> rendertex;
std::unique_ptr<Magnum::GL::Framebuffer> frame_buffer;
std::unique_ptr<Magnum::GL::Mesh> _mesh;
CoreMath::TransformMatrix rendertex_mat;
const auto use_cpu = false;
if (!use_cpu)
{
rendertex = std::make_unique<Magnum::GL::Texture2D>();
rendertex->setStorage(1, Magnum::GL::TextureFormat::RGBA8 /*normalized unsigned byte*/, { canvas_texture_size.x, canvas_texture_size.y });
const auto view = CoreMath::TransformMatrix::lookAt(
{ canvas_texture_size.x / 2.f, canvas_texture_size.y / 2.f, 0.f }, /*eye*/
{ canvas_texture_size.x / 2.f, canvas_texture_size.y / 2.f, 1.f }, /*target direction*/
{ 0.f, -1.f, 0.f } /*up*/).invertedRigid();
rendertex_mat = CoreMath::TransformMatrix::orthographicProjection({ canvas_texture_size.x * 1.f, canvas_texture_size.y * 1.f }, -100.f, 100.f) * view;
frame_buffer = std::make_unique<Magnum::GL::Framebuffer>(Magnum::Range2Di{ {}, { canvas_texture_size.x, canvas_texture_size.y } });
frame_buffer->attachTexture(Magnum::GL::Framebuffer::ColorAttachment{ 0 }, *rendertex, 0);
// auto release frame_buffer bind on destroy
{
buffer_unlock = std::make_unique<SettingsUnlock>();
CoreHelper::SysVars().imageDefaultQuality.PushNewVal(static_cast<int>(/*smooth:*/false));
frame_buffer->
clearColor(
0 /*same as ColourAttachment id when creating render texture*/,
Magnum::Color4{ 0.f, 0.f, 0.f, 0.f })
.bind();
}
// create mesh
{
using namespace Magnum;
using namespace Math::Literals;
struct TriangleVertex {
Vector3 position;
Vector2 textureCoordinates;
};
//const auto width = 1, height = 1;
const auto width = canvas_texture_size.x * 1.f, height = canvas_texture_size.y * 1.f;
const auto inverted_x = false, inverted_y = false;
const TriangleVertex data[]{
{{0.f, 0.f, 0.f}, {!inverted_x ? 0.0f : 1.f, !inverted_y ? 1.0f : 0.f}}, /* Left top vertex, uv */
{{0.f, height, 0.f}, {!inverted_x ? 0.0f : 1.f, !inverted_y ? 0.0f : 1.f}}, /* Left bottom vertex, uv */
{{width, 0.f, 0.f}, {!inverted_x ? 1.0f : 0.f, !inverted_y ? 1.0f : 0.f}}, /* Right top vertex, uv*/
{{width, height, 0.f}, {!inverted_x ? 1.0f : 0.f, !inverted_y ? 0.0f : 1.f}}, /* Right bottom vertex, uv */
};
GL::Buffer buffer;
buffer.setData(data, GL::BufferUsage::StaticDraw);
_mesh = std::make_unique<Magnum::GL::Mesh>(Magnum::GL::MeshPrimitive::TriangleStrip);
_mesh->
setCount(4)
.addVertexBuffer(std::move(buffer), 0,
Shaders::Flat3D::Position{},
Shaders::Flat3D::TextureCoordinates{});
}
// draw first texture
{
{
auto& shader = *(std::static_pointer_cast<Magnum::Shaders::Flat3D>(CShaderMgr::GetInstance().loadShader(L"vn_magnum_flat3d_tex")));
{
shader
.bindTexture(*(static_cast<Magnum::GL::Texture2D*>(this->getTextureToRender())))
.setColor(Magnum::Color4(1.f, 1.f, 1.f, 1.f))
.setTransformationProjectionMatrix(/*world:*/rendertex_mat
///*local:*/ * CoreMath::TransformMatrix::scaling({ canvas_texture_size.x * 1.f, canvas_texture_size.y * 1.f, 1.f })
);
}
//CRenderMgr::GetInstance().ApplyBlendMode(BlendMode::BlendAlpha); // completely overwrite buffer.
CRenderMgr::GetInstance().ApplyBlendMode(BlendMode::BlendOverwrite); // completely overwrite buffer.
//CRenderMgr::GetInstance().ApplyBlendMode(BlendMode(
// /*rgbSourceFactor*/ BlendMode::Factor::One, /*rgbDestinationFactor*/ BlendMode::Factor::OneMinusSrcAlpha, BlendMode::Equation::Add,
// /*alphaSourceFactor*/ BlendMode::Factor::One, /*alphaDestinationFactor*/ BlendMode::Factor::OneMinusSrcAlpha, BlendMode::Equation::Add
//)); // completely overwrite buffer.
shader.draw(*_mesh);
}
// for all future texture overlays
{
CRenderMgr::GetInstance().ApplyBlendMode(BlendMode(
/*rgbSourceFactor*/ BlendMode::Factor::SourceAlpha, /*rgbDestinationFactor*/ BlendMode::Factor::OneMinusSourceAlpha, BlendMode::Equation::Add,
/*alphaSourceFactor*/ BlendMode::Factor::One, /*alphaDestinationFactor*/ BlendMode::Factor::OneMinusSourceAlpha, BlendMode::Equation::Add
)); // completely overwrite buffer.
}
}
}
for (const auto& info : infos)
{
const auto add_texture_name = NHelper::EvalLvnPath(NConstants::imageDir.first, info.texture_filepath);
const auto add_texture = CTextureMgr::GetInstance().GetResource(add_texture_name, StreamLifetime::temporary);
if (!add_texture) {
CLogMgr::GetInstance().LogError(L"[overlayTexture] could not fetch: {}", add_texture_name);
return false;
}
// clear unneeded data
add_texture->getTextureToRender();
const auto add_texture_offset_x = info.relative_position.x;
const auto add_texture_offset_y = info.relative_position.y;
const auto add_texture_size = add_texture->getSize();
if (!use_cpu)
{
{
auto& shader = *(std::static_pointer_cast<Magnum::Shaders::Flat3D>(CShaderMgr::GetInstance().loadShader(L"vn_magnum_flat3d_tex")));
{
shader
.bindTexture(*(static_cast<Magnum::GL::Texture2D*>(add_texture->getTextureToRender())))
.setColor(Magnum::Color4(1.f, 1.f, 1.f, 1.f))
.setTransformationProjectionMatrix(/*world:*/rendertex_mat
/*local:*/ * CoreMath::TransformMatrix::translation({ add_texture_offset_x * 1.f, add_texture_offset_y * 1.f, 0.f })
//* CoreMath::TransformMatrix::scaling({ add_texture_size.x * 1.f, add_texture_size.y * 1.f, 1.f })
);
}
//CRenderMgr::GetInstance().ApplyBlendMode(BlendMode::BlendAlpha);
shader.draw(*_mesh);
}
//SaveScreenshot(*frame_buffer);
}
}
if (!use_cpu)
{
const auto& image_size = frame_buffer->viewport();
Magnum::Image2D image(Magnum::PixelFormat::RGBA8Unorm /* normalized unsigned byte: must match frame buffer settings */);
frame_buffer->read(image_size, image);
SUCCESS_CHECK_RETURN_X_IF_FAILED(loadFromData(std::move(image)), false);
}
// finish + clean up texture data (release since now finished use)
getTextureToRender();
_pixels = {};
return true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment