Created
September 29, 2021 18:25
-
-
Save hsdk123/7f66ecf92d8f51ffaa3e4ac241d4682f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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