mirror of
https://git.allpurposem.at/mat/WiggleWobble.git
synced 2025-12-23 13:01:28 +01:00
feat: use renderpasses to draw window to a separate FB
Gotta figure out coordinates though :)
This commit is contained in:
parent
81723f4cca
commit
cb7425cea0
108
src/main.cpp
108
src/main.cpp
@ -1,19 +1,20 @@
|
||||
#include "globals.hpp"
|
||||
#include "src/helpers/math/Math.hpp"
|
||||
|
||||
#include <hyprgraphics/color/Color.hpp>
|
||||
// version.hpp will be generated by meson
|
||||
#include "src/plugins/PluginAPI.hpp"
|
||||
#include "src/render/Framebuffer.hpp"
|
||||
#include "src/render/Shader.hpp"
|
||||
#include "src/render/OpenGL.hpp"
|
||||
#include "src/render/pass/PassElement.hpp"
|
||||
#include "src/render/pass/RectPassElement.hpp"
|
||||
#include "version.hpp"
|
||||
|
||||
#include <hyprland/src/Compositor.hpp>
|
||||
#include <hyprland/src/desktop/Window.hpp>
|
||||
#include <hyprland/src/render/Renderer.hpp>
|
||||
#include <hyprutils/math/Box.hpp>
|
||||
#include <hyprutils/math/Region.hpp>
|
||||
#include <map>
|
||||
#include <optional>
|
||||
#include <unistd.h>
|
||||
|
||||
// Do NOT change this function.
|
||||
@ -21,27 +22,76 @@ APICALL EXPORT std::string PLUGIN_API_VERSION() {
|
||||
return HYPRLAND_API_VERSION;
|
||||
}
|
||||
|
||||
class CBindOwnFramebuffer final: public IPassElement {
|
||||
class CBindOwnFramebufferPassElement final: public IPassElement {
|
||||
public:
|
||||
explicit CBindOwnFramebuffer(CFramebuffer m_framebuffer) :
|
||||
m_framebuffer(std::move(m_framebuffer)) {}
|
||||
explicit CBindOwnFramebufferPassElement(CFramebuffer* pFramebuffer) :
|
||||
m_pFramebuffer {pFramebuffer} {}
|
||||
|
||||
void draw(const CRegion& damage);
|
||||
void draw(const CRegion& damage) override {
|
||||
m_pFramebuffer->bind();
|
||||
g_pHyprOpenGL->clear(CHyprColor(0, 0, 0, 0));
|
||||
g_pHyprOpenGL->m_renderData.currentFB = m_pFramebuffer;
|
||||
|
||||
bool needsLiveBlur() {
|
||||
std::println("BindOwnFramebufferPassElement");
|
||||
}
|
||||
|
||||
bool needsLiveBlur() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool needsPrecomputeBlur() {
|
||||
bool needsPrecomputeBlur() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* passName() {
|
||||
const char* passName() override {
|
||||
return "BIND_OWN_FRAMEBUFFER";
|
||||
}
|
||||
|
||||
std::optional<CBox> boundingBox() override {
|
||||
return g_pHyprOpenGL->m_renderData.pMonitor->logicalBox();
|
||||
}
|
||||
|
||||
private:
|
||||
CFramebuffer m_framebuffer;
|
||||
CFramebuffer* m_pFramebuffer;
|
||||
};
|
||||
|
||||
class CRenderWobblyWindowPassElement final: public IPassElement {
|
||||
public:
|
||||
explicit CRenderWobblyWindowPassElement(CFramebuffer* pOldFramebuffer, PHLWINDOWREF pWindow) :
|
||||
m_pOldFramebuffer {pOldFramebuffer},
|
||||
m_pWindow {pWindow} {}
|
||||
|
||||
void draw(const CRegion& damage) override {
|
||||
auto* const pWindowFB = g_pHyprOpenGL->m_renderData.currentFB;
|
||||
pWindowFB->getTexture()->bind();
|
||||
|
||||
m_pOldFramebuffer->bind();
|
||||
g_pHyprOpenGL->m_renderData.currentFB = m_pOldFramebuffer;
|
||||
g_pHyprOpenGL
|
||||
->renderTexture(pWindowFB->getTexture(), m_pWindow->getFullWindowBoundingBox(), 1.0f);
|
||||
|
||||
std::println("RenderWobblyWindowPassElement");
|
||||
}
|
||||
|
||||
bool needsLiveBlur() override {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool needsPrecomputeBlur() override {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* passName() override {
|
||||
return "RENDER_WOBBLY_WINDOW";
|
||||
}
|
||||
|
||||
std::optional<CBox> boundingBox() override {
|
||||
return g_pHyprOpenGL->m_renderData.pMonitor->logicalBox();
|
||||
}
|
||||
|
||||
private:
|
||||
CFramebuffer* m_pOldFramebuffer;
|
||||
PHLWINDOWREF m_pWindow;
|
||||
};
|
||||
|
||||
void onNewWindow(std::any data) {
|
||||
@ -49,6 +99,8 @@ void onNewWindow(std::any data) {
|
||||
auto PWINDOW = std::any_cast<PHLWINDOW>(data);
|
||||
}
|
||||
|
||||
inline std::map<PHLWINDOWREF, CFramebuffer> g_windowFramebuffers;
|
||||
|
||||
static SP<HOOK_CALLBACK_FN> g_openWindow = nullptr;
|
||||
inline CFunctionHook* g_pRenderWindowHook = nullptr;
|
||||
|
||||
@ -73,17 +125,29 @@ void hkRenderWindow(
|
||||
bool ignorePosition = false,
|
||||
bool standalone = false
|
||||
) {
|
||||
std::println("renderWindow hooked!");
|
||||
CHyprRenderer* pRenderer = (CHyprRenderer*)thisptr;
|
||||
|
||||
CBox monbox =
|
||||
{pWindow->m_position.x, pWindow->m_position.y, pWindow->m_size.x, pWindow->m_size.y};
|
||||
const bool shouldWobble = [&]() -> bool {
|
||||
if (mode == RENDER_PASS_MAIN) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// test that it works
|
||||
CRectPassElement::SRectData data;
|
||||
data.color = CHyprColor(1, 0, 0, 0.2f);
|
||||
data.box = monbox;
|
||||
pRenderer->m_renderPass.add(makeUnique<CRectPassElement>(data));
|
||||
return false;
|
||||
}();
|
||||
|
||||
auto* const pOldFramebuffer = g_pHyprOpenGL->m_renderData.currentFB;
|
||||
|
||||
if (shouldWobble) {
|
||||
PHLWINDOWREF ref {pWindow};
|
||||
if (!g_windowFramebuffers.contains(ref)) {
|
||||
g_windowFramebuffers[ref] = CFramebuffer {};
|
||||
g_windowFramebuffers[ref].alloc(pWindow->m_size.x, pWindow->m_size.y);
|
||||
}
|
||||
|
||||
pRenderer->m_renderPass.add(
|
||||
makeUnique<CBindOwnFramebufferPassElement>(&g_windowFramebuffers.at(ref))
|
||||
);
|
||||
}
|
||||
|
||||
// then call the original...
|
||||
(*(origRenderWindow)g_pRenderWindowHook->m_original)(
|
||||
@ -96,6 +160,12 @@ void hkRenderWindow(
|
||||
ignorePosition,
|
||||
standalone
|
||||
);
|
||||
|
||||
if (shouldWobble) {
|
||||
pRenderer->m_renderPass.add(
|
||||
makeUnique<CRenderWobblyWindowPassElement>(pOldFramebuffer, pWindow)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user