mirror of
https://github.com/virtcode/hypr-dynamic-cursors
synced 2025-09-19 16:13:21 +02:00
feat: basic inverted rendering
This commit is contained in:
parent
f83004ad07
commit
69e2583e57
7 changed files with 333 additions and 1 deletions
|
@ -10,6 +10,11 @@
|
||||||
#define CONFIG_THRESHOLD "threshold"
|
#define CONFIG_THRESHOLD "threshold"
|
||||||
#define CONFIG_HW_DEBUG "hw_debug"
|
#define CONFIG_HW_DEBUG "hw_debug"
|
||||||
|
|
||||||
|
#define CONFIG_INVERT "plugin:dynamic-cursors:invert"
|
||||||
|
#define CONFIG_INVERT_SHADER "plugin:dynamic-cursors:invert:shader"
|
||||||
|
#define CONFIG_INVERT_CHROMA "plugin:dynamic-cursors:invert:chroma"
|
||||||
|
#define CONFIG_INVERT_CHROMA_COLOR "plugin:dynamic-cursors:invert:chroma:color"
|
||||||
|
|
||||||
#define CONFIG_SHAKE "shake:enabled"
|
#define CONFIG_SHAKE "shake:enabled"
|
||||||
#define CONFIG_SHAKE_NEAREST "shake:nearest"
|
#define CONFIG_SHAKE_NEAREST "shake:nearest"
|
||||||
#define CONFIG_SHAKE_THRESHOLD "shake:threshold"
|
#define CONFIG_SHAKE_THRESHOLD "shake:threshold"
|
||||||
|
|
|
@ -54,7 +54,12 @@ Reimplements rendering of the software cursor.
|
||||||
Is also largely identical to hyprlands impl, but uses our custom rendering to rotate the cursor.
|
Is also largely identical to hyprlands impl, but uses our custom rendering to rotate the cursor.
|
||||||
*/
|
*/
|
||||||
void CDynamicCursors::renderSoftware(CPointerManager* pointers, SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
|
void CDynamicCursors::renderSoftware(CPointerManager* pointers, SP<CMonitor> pMonitor, timespec* now, CRegion& damage, std::optional<Vector2D> overridePos) {
|
||||||
|
<<<<<<< HEAD
|
||||||
static auto* const* PNEAREST = (Hyprlang::INT* const*) getConfig(CONFIG_SHAKE_NEAREST);
|
static auto* const* PNEAREST = (Hyprlang::INT* const*) getConfig(CONFIG_SHAKE_NEAREST);
|
||||||
|
=======
|
||||||
|
static auto* const* PNEAREST = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_SHAKE_NEAREST)->getDataStaticPtr();
|
||||||
|
static auto* const* PINVERT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_INVERT)->getDataStaticPtr();
|
||||||
|
>>>>>>> c8ae8fe (feat: basic inverted rendering)
|
||||||
|
|
||||||
if (!pointers->hasCursor())
|
if (!pointers->hasCursor())
|
||||||
return;
|
return;
|
||||||
|
@ -94,10 +99,17 @@ void CDynamicCursors::renderSoftware(CPointerManager* pointers, SP<CMonitor> pMo
|
||||||
box.rot = resultShown.rotation;
|
box.rot = resultShown.rotation;
|
||||||
|
|
||||||
// now pass the hotspot to rotate around
|
// now pass the hotspot to rotate around
|
||||||
|
<<<<<<< HEAD
|
||||||
renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, nullptr, 0, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST, resultShown.stretch.angle, resultShown.stretch.magnitude);
|
renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, nullptr, 0, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST, resultShown.stretch.angle, resultShown.stretch.magnitude);
|
||||||
|
|
||||||
if (pointers->currentCursorImage.surface)
|
if (pointers->currentCursorImage.surface)
|
||||||
pointers->currentCursorImage.surface->resource()->frame(now);
|
pointers->currentCursorImage.surface->resource()->frame(now);
|
||||||
|
=======
|
||||||
|
if (**PINVERT)
|
||||||
|
renderCursorTextureInternalWithDamageInverted(texture, &box, &damage, 1.F, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST);
|
||||||
|
else
|
||||||
|
renderCursorTextureInternalWithDamage(texture, &box, &damage, 1.F, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST);
|
||||||
|
>>>>>>> c8ae8fe (feat: basic inverted rendering)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -131,9 +143,16 @@ void CDynamicCursors::damageSoftware(CPointerManager* pointers) {
|
||||||
This function reimplements the hardware cursor buffer drawing.
|
This function reimplements the hardware cursor buffer drawing.
|
||||||
It is largely copied from hyprland, but adjusted to allow the cursor to be rotated.
|
It is largely copied from hyprland, but adjusted to allow the cursor to be rotated.
|
||||||
*/
|
*/
|
||||||
|
<<<<<<< HEAD
|
||||||
SP<Aquamarine::IBuffer> CDynamicCursors::renderHardware(CPointerManager* pointers, SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
|
SP<Aquamarine::IBuffer> CDynamicCursors::renderHardware(CPointerManager* pointers, SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
|
||||||
static auto* const* PHW_DEBUG = (Hyprlang::INT* const*) getConfig(CONFIG_HW_DEBUG);
|
static auto* const* PHW_DEBUG = (Hyprlang::INT* const*) getConfig(CONFIG_HW_DEBUG);
|
||||||
static auto* const* PNEAREST = (Hyprlang::INT* const*) getConfig(CONFIG_SHAKE_NEAREST);
|
static auto* const* PNEAREST = (Hyprlang::INT* const*) getConfig(CONFIG_SHAKE_NEAREST);
|
||||||
|
=======
|
||||||
|
wlr_buffer* CDynamicCursors::renderHardware(CPointerManager* pointers, SP<CPointerManager::SMonitorPointerState> state, SP<CTexture> texture) {
|
||||||
|
static auto* const* PHW_DEBUG= (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_HW_DEBUG)->getDataStaticPtr();
|
||||||
|
static auto* const* PNEAREST = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_SHAKE_NEAREST)->getDataStaticPtr();
|
||||||
|
static auto* const* PINVERT = (Hyprlang::INT* const*)HyprlandAPI::getConfigValue(PHANDLE, CONFIG_INVERT)->getDataStaticPtr();
|
||||||
|
>>>>>>> c8ae8fe (feat: basic inverted rendering)
|
||||||
|
|
||||||
auto output = state->monitor->output;
|
auto output = state->monitor->output;
|
||||||
|
|
||||||
|
@ -243,7 +262,14 @@ SP<Aquamarine::IBuffer> CDynamicCursors::renderHardware(CPointerManager* pointer
|
||||||
xbox.rot = resultShown.rotation;
|
xbox.rot = resultShown.rotation;
|
||||||
|
|
||||||
// use our custom draw function
|
// use our custom draw function
|
||||||
|
<<<<<<< HEAD
|
||||||
renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.waitTimeline, pointers->currentCursorImage.waitPoint, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST, resultShown.stretch.angle, resultShown.stretch.magnitude);
|
renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.waitTimeline, pointers->currentCursorImage.waitPoint, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST, resultShown.stretch.angle, resultShown.stretch.magnitude);
|
||||||
|
=======
|
||||||
|
if (**PINVERT)
|
||||||
|
renderCursorTextureInternalWithDamageInverted(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST);
|
||||||
|
else
|
||||||
|
renderCursorTextureInternalWithDamage(texture, &xbox, &damage, 1.F, pointers->currentCursorImage.hotspot * state->monitor->scale * zoom, zoom > 1 && **PNEAREST);
|
||||||
|
>>>>>>> c8ae8fe (feat: basic inverted rendering)
|
||||||
|
|
||||||
g_pHyprOpenGL->end();
|
g_pHyprOpenGL->end();
|
||||||
glFlush();
|
glFlush();
|
||||||
|
|
42
src/invert/shader.cpp
Normal file
42
src/invert/shader.cpp
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
#include "src/debug/Log.hpp"
|
||||||
|
|
||||||
|
#define private public
|
||||||
|
#include <hyprland/src/render/OpenGL.hpp>
|
||||||
|
#undef private
|
||||||
|
|
||||||
|
#include <hyprland/src/Compositor.hpp>
|
||||||
|
#include <hyprland/src/render/Shaders.hpp>
|
||||||
|
|
||||||
|
#include "shader.hpp"
|
||||||
|
|
||||||
|
void CInversionShader::compile(std::string vertex, std::string fragment) {
|
||||||
|
|
||||||
|
program = g_pHyprOpenGL->createProgram(vertex, fragment);
|
||||||
|
|
||||||
|
texAttrib = glGetAttribLocation(program, "texcoord");
|
||||||
|
posAttrib = glGetAttribLocation(program, "pos");
|
||||||
|
|
||||||
|
proj = glGetUniformLocation(program, "proj");
|
||||||
|
backgroundTex = glGetUniformLocation(program, "backgroundTex");
|
||||||
|
cursorTex = glGetUniformLocation(program, "cursorTex");
|
||||||
|
alpha = glGetUniformLocation(program, "alpha");
|
||||||
|
applyTint = glGetUniformLocation(program, "applyTint");
|
||||||
|
tint = glGetUniformLocation(program, "tint");
|
||||||
|
}
|
||||||
|
|
||||||
|
CInversionShader::~CInversionShader() {
|
||||||
|
glDeleteProgram(program);
|
||||||
|
program = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CShaders::CShaders() {
|
||||||
|
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)),
|
||||||
|
"Couldn't set current EGL!");
|
||||||
|
|
||||||
|
rgba.compile(VERTEX, RGBA);
|
||||||
|
ext.compile(VERTEX, EXT);
|
||||||
|
rgbx.compile(VERTEX, RGBX);
|
||||||
|
|
||||||
|
RASSERT(eglMakeCurrent(wlr_egl_get_display(g_pCompositor->m_sWLREGL), EGL_NO_SURFACE, EGL_NO_SURFACE, wlr_egl_get_context(g_pCompositor->m_sWLREGL)),
|
||||||
|
"Couldn't set current EGL!");
|
||||||
|
}
|
152
src/invert/shader.hpp
Normal file
152
src/invert/shader.hpp
Normal file
|
@ -0,0 +1,152 @@
|
||||||
|
#include <string>
|
||||||
|
#include <hyprland/src/render/Shader.hpp>
|
||||||
|
|
||||||
|
// we need our own shader class as we have two textures
|
||||||
|
class CInversionShader {
|
||||||
|
public:
|
||||||
|
GLuint program = 0;
|
||||||
|
GLint proj = -1;
|
||||||
|
GLint color = -1;
|
||||||
|
GLint alphaMatte = -1;
|
||||||
|
GLint cursorTex = -1;
|
||||||
|
GLint backgroundTex = -1;
|
||||||
|
GLint alpha = -1;
|
||||||
|
GLint posAttrib = -1;
|
||||||
|
GLint texAttrib = -1;
|
||||||
|
GLint matteTexAttrib = -1;
|
||||||
|
GLint discardOpaque = -1;
|
||||||
|
GLint discardAlpha = -1;
|
||||||
|
GLfloat discardAlphaValue = -1;
|
||||||
|
|
||||||
|
GLint applyTint = -1;
|
||||||
|
GLint tint = -1;
|
||||||
|
|
||||||
|
void compile(std::string vertex, std::string fragment);
|
||||||
|
~CInversionShader();
|
||||||
|
};
|
||||||
|
|
||||||
|
class CShaders {
|
||||||
|
public:
|
||||||
|
CInversionShader rgba;
|
||||||
|
CInversionShader rgbx;
|
||||||
|
CInversionShader ext;
|
||||||
|
|
||||||
|
CShaders();
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::unique_ptr<CShaders> g_pShaders;
|
||||||
|
|
||||||
|
inline const std::string VERTEX = R"#(
|
||||||
|
uniform mat3 proj;
|
||||||
|
|
||||||
|
attribute vec2 pos;
|
||||||
|
attribute vec2 texcoord;
|
||||||
|
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
varying vec2 v_screencord;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
gl_Position = vec4(proj * vec3(pos, 1.0), 1.0);
|
||||||
|
|
||||||
|
v_screencord = gl_Position.xy / 2.0 + vec2(0.5, 0.5); // transform to texture coords
|
||||||
|
v_texcoord = texcoord;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string RGBA = R"#(
|
||||||
|
precision highp float;
|
||||||
|
|
||||||
|
varying vec2 v_texcoord; // is in 0-1
|
||||||
|
varying vec2 v_screencord; // is in 0-1
|
||||||
|
|
||||||
|
uniform sampler2D cursorTex;
|
||||||
|
uniform sampler2D backgroundTex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 cursor = texture2D(cursorTex, v_texcoord);
|
||||||
|
|
||||||
|
// load and invert background
|
||||||
|
vec4 background = texture2D(backgroundTex, v_screencord);
|
||||||
|
background.rgb = vec3(1.0, 1.0, 1.0) - background.rgb;
|
||||||
|
background *= cursor[3]; // premultiplied alpha
|
||||||
|
|
||||||
|
// invert hue
|
||||||
|
//background.rgb = -background.rgb + dot(vec3(0.26312, 0.5283, 0.10488), background.rgb) * 2.0;
|
||||||
|
|
||||||
|
vec4 pixColor = cursor;
|
||||||
|
//if (cursor[3] != 1.0) pixColor = cursor;
|
||||||
|
//pixColor = vec4(v_screencord + vec2(1.0, 1.0) / 2.0, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec4 chroma = vec4(0.0, 0.0, 0.0, 1.0);
|
||||||
|
float diff = (abs(chroma.x - cursor.x) + abs(chroma.y - cursor.y) + abs(chroma.z - cursor.z) + abs(chroma.w - cursor.w)) / 4.0;
|
||||||
|
pixColor = background * (1.0 - diff) + cursor * diff;
|
||||||
|
|
||||||
|
if (applyTint == 1) {
|
||||||
|
pixColor[0] = pixColor[0] * tint[0];
|
||||||
|
pixColor[1] = pixColor[1] * tint[1];
|
||||||
|
pixColor[2] = pixColor[2] * tint[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string RGBX = R"#(
|
||||||
|
precision highp float;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
uniform sampler2D cursorTex;
|
||||||
|
uniform sampler2D backgroundTex;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
|
||||||
|
vec4 pixColor = vec4(texture2D(cursorTex, v_texcoord).rgb, 1.0);
|
||||||
|
|
||||||
|
if (applyTint == 1) {
|
||||||
|
pixColor[0] = pixColor[0] * tint[0];
|
||||||
|
pixColor[1] = pixColor[1] * tint[1];
|
||||||
|
pixColor[2] = pixColor[2] * tint[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
pixColor.r = 1.0;
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
}
|
||||||
|
)#";
|
||||||
|
|
||||||
|
inline const std::string EXT = R"#(
|
||||||
|
#extension GL_OES_EGL_image_external : require
|
||||||
|
|
||||||
|
precision highp float;
|
||||||
|
varying vec2 v_texcoord;
|
||||||
|
uniform samplerExternalOES texture0;
|
||||||
|
uniform samplerExternalOES texture1;
|
||||||
|
uniform float alpha;
|
||||||
|
|
||||||
|
uniform int applyTint;
|
||||||
|
uniform vec3 tint;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
|
||||||
|
vec4 pixColor = texture2D(texture0, v_texcoord);
|
||||||
|
|
||||||
|
if (applyTint == 1) {
|
||||||
|
pixColor[0] = pixColor[0] * tint[0];
|
||||||
|
pixColor[1] = pixColor[1] * tint[1];
|
||||||
|
pixColor[2] = pixColor[2] * tint[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
pixColor.r = 1.0;
|
||||||
|
|
||||||
|
gl_FragColor = pixColor * alpha;
|
||||||
|
}
|
||||||
|
)#";
|
|
@ -10,6 +10,7 @@
|
||||||
#include "cursor.hpp"
|
#include "cursor.hpp"
|
||||||
#include "config/config.hpp"
|
#include "config/config.hpp"
|
||||||
#include "src/debug/Log.hpp"
|
#include "src/debug/Log.hpp"
|
||||||
|
#include "invert/shader.hpp"
|
||||||
#include "src/managers/PointerManager.hpp"
|
#include "src/managers/PointerManager.hpp"
|
||||||
#include "src/version.h"
|
#include "src/version.h"
|
||||||
|
|
||||||
|
@ -112,6 +113,11 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||||
addConfig(CONFIG_SHAKE_THRESHOLD, 4.0f);
|
addConfig(CONFIG_SHAKE_THRESHOLD, 4.0f);
|
||||||
addConfig(CONFIG_SHAKE_FACTOR, 1.5f);
|
addConfig(CONFIG_SHAKE_FACTOR, 1.5f);
|
||||||
|
|
||||||
|
addConfig(CONFIG_INVERT, 0);
|
||||||
|
addConfig(CONFIG_INVERT_SHADER, "normal");
|
||||||
|
addConfig(CONFIG_INVERT_CHROMA, 0);
|
||||||
|
addConfig(CONFIG_INVERT_CHROMA_COLOR, 0xFF000000); // opaque black
|
||||||
|
|
||||||
addShapeConfig(CONFIG_TILT_FUNCTION, "negative_quadratic");
|
addShapeConfig(CONFIG_TILT_FUNCTION, "negative_quadratic");
|
||||||
addShapeConfig(CONFIG_TILT_LIMIT, 5000);
|
addShapeConfig(CONFIG_TILT_LIMIT, 5000);
|
||||||
|
|
||||||
|
@ -128,6 +134,7 @@ APICALL EXPORT PLUGIN_DESCRIPTION_INFO PLUGIN_INIT(HANDLE handle) {
|
||||||
|
|
||||||
// init things
|
// init things
|
||||||
g_pDynamicCursors = std::make_unique<CDynamicCursors>();
|
g_pDynamicCursors = std::make_unique<CDynamicCursors>();
|
||||||
|
g_pShaders = std::make_unique<CShaders>();
|
||||||
|
|
||||||
// try hooking
|
// try hooking
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#include <hyprland/src/config/ConfigValue.hpp>
|
#include <hyprland/src/config/ConfigValue.hpp>
|
||||||
|
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
#include "invert/shader.hpp"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is the projectBox method from hyprland, but with support for rotation around a point, the hotspot.
|
This is the projectBox method from hyprland, but with support for rotation around a point, the hotspot.
|
||||||
|
@ -156,3 +157,101 @@ void renderCursorTextureInternalWithDamage(SP<CTexture> tex, CBox* pBox, CRegion
|
||||||
|
|
||||||
glBindTexture(tex->m_iTarget, 0);
|
glBindTexture(tex->m_iTarget, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderCursorTextureInternalWithDamageInverted(SP<CTexture> tex, CBox* pBox, CRegion* damage, float alpha, SP<CSyncTimeline> waitTimeline, uint64_t waitPoint, Vector2D hotspot, bool nearest, float stretchAngle, Vector2D stretch, int mode, bool chroma, CColor chromaColor, Vector2D screenOffset) {
|
||||||
|
TRACY_GPU_ZONE("RenderDynamicCursor");
|
||||||
|
|
||||||
|
if (waitTimeline != nullptr) {
|
||||||
|
if (!g_pHyprOpenGL->waitForTimelinePoint(waitTimeline, waitPoint)) {
|
||||||
|
Debug::log(ERR, "renderTextureInternalWithDamage: failed to wait for explicit sync point {}", waitPoint);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
alpha = std::clamp(alpha, 0.f, 1.f);
|
||||||
|
|
||||||
|
if (damage->empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
CBox newBox = *pBox;
|
||||||
|
g_pHyprOpenGL->m_RenderData.renderModif.applyToBox(newBox);
|
||||||
|
|
||||||
|
// get transform
|
||||||
|
const auto TRANSFORM = wlTransformToHyprutils(invertTransform(!g_pHyprOpenGL->m_bEndFrame ? WL_OUTPUT_TRANSFORM_NORMAL : g_pHyprOpenGL->m_RenderData.pMonitor->transform));
|
||||||
|
float matrix[9];
|
||||||
|
projectCursorBox(matrix, newBox, TRANSFORM, newBox.rot, g_pHyprOpenGL->m_RenderData.monitorProjection.data(), hotspot, stretchAngle, stretch);
|
||||||
|
|
||||||
|
float glMatrix[9];
|
||||||
|
matrixMultiply(glMatrix, g_pHyprOpenGL->m_RenderData.projection, matrix);
|
||||||
|
|
||||||
|
CInversionShader* shader = nullptr;
|
||||||
|
|
||||||
|
switch (tex->m_iType) {
|
||||||
|
case TEXTURE_RGBA: shader = &g_pShaders->rgba; break;
|
||||||
|
case TEXTURE_RGBX: shader = &g_pShaders->rgbx; break;
|
||||||
|
case TEXTURE_EXTERNAL: shader = &g_pShaders->ext; break;
|
||||||
|
default: RASSERT(false, "tex->m_iTarget unsupported!");
|
||||||
|
}
|
||||||
|
|
||||||
|
glActiveTexture(GL_TEXTURE0);
|
||||||
|
glBindTexture(tex->m_iTarget, tex->m_iTexID);
|
||||||
|
|
||||||
|
if (g_pHyprOpenGL->m_RenderData.useNearestNeighbor || nearest) {
|
||||||
|
glTexParameteri(tex->m_iTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
||||||
|
glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
|
||||||
|
} else {
|
||||||
|
glTexParameteri(tex->m_iTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||||
|
glTexParameteri(tex->m_iTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
glUseProgram(shader->program);
|
||||||
|
|
||||||
|
#ifndef GLES2
|
||||||
|
glUniformMatrix3fv(shader->proj, 1, GL_TRUE, glMatrix);
|
||||||
|
#else
|
||||||
|
matrixTranspose(glMatrix, glMatrix);
|
||||||
|
glUniformMatrix3fv(shader->proj, 1, GL_FALSE, glMatrix);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
glUniform2f(shader->screenOffset, screenOffset.x, screenOffset.y);
|
||||||
|
glUniform1i(shader->backgroundTex, 0);
|
||||||
|
glUniform1i(shader->cursorTex, 1);
|
||||||
|
glUniform1f(shader->alpha, alpha);
|
||||||
|
|
||||||
|
glUniform1i(shader->mode, mode);
|
||||||
|
glUniform1i(shader->chroma, chroma);
|
||||||
|
glUniform4f(shader->chromaColor, chromaColor.r, chromaColor.g, chromaColor.b, chromaColor.a);
|
||||||
|
|
||||||
|
CBox transformedBox = newBox;
|
||||||
|
transformedBox.transform(wlTransformToHyprutils(invertTransform(g_pHyprOpenGL->m_RenderData.pMonitor->transform)), g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.x, g_pHyprOpenGL->m_RenderData.pMonitor->vecTransformedSize.y);
|
||||||
|
|
||||||
|
glUniform1i(shader->applyTint, 0);
|
||||||
|
|
||||||
|
glVertexAttribPointer(shader->posAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
glVertexAttribPointer(shader->texAttrib, 2, GL_FLOAT, GL_FALSE, 0, fullVerts);
|
||||||
|
|
||||||
|
glEnableVertexAttribArray(shader->posAttrib);
|
||||||
|
glEnableVertexAttribArray(shader->texAttrib);
|
||||||
|
|
||||||
|
if (g_pHyprOpenGL->m_RenderData.clipBox.width != 0 && g_pHyprOpenGL->m_RenderData.clipBox.height != 0) {
|
||||||
|
CRegion damageClip{g_pHyprOpenGL->m_RenderData.clipBox.x, g_pHyprOpenGL->m_RenderData.clipBox.y, g_pHyprOpenGL->m_RenderData.clipBox.width, g_pHyprOpenGL->m_RenderData.clipBox.height};
|
||||||
|
damageClip.intersect(*damage);
|
||||||
|
|
||||||
|
if (!damageClip.empty()) {
|
||||||
|
for (auto& RECT : damageClip.getRects()) {
|
||||||
|
g_pHyprOpenGL->scissor(&RECT);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (auto& RECT : damage->getRects()) {
|
||||||
|
g_pHyprOpenGL->scissor(&RECT);
|
||||||
|
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
glDisableVertexAttribArray(shader->posAttrib);
|
||||||
|
glDisableVertexAttribArray(shader->texAttrib);
|
||||||
|
|
||||||
|
glBindTexture(tex->m_iTarget, 0);
|
||||||
|
}
|
||||||
|
|
|
@ -2,3 +2,4 @@
|
||||||
#include <hyprland/src/helpers/math/Math.hpp>
|
#include <hyprland/src/helpers/math/Math.hpp>
|
||||||
|
|
||||||
void renderCursorTextureInternalWithDamage(SP<CTexture> tex, CBox* pBox, CRegion* damage, float alpha, SP<CSyncTimeline> waitTimeline, uint64_t waitPoint, Vector2D hotspot, bool nearest, float stretchAngle, Vector2D stretch);
|
void renderCursorTextureInternalWithDamage(SP<CTexture> tex, CBox* pBox, CRegion* damage, float alpha, SP<CSyncTimeline> waitTimeline, uint64_t waitPoint, Vector2D hotspot, bool nearest, float stretchAngle, Vector2D stretch);
|
||||||
|
void renderCursorTextureInternalWithDamageInverted(SP<CTexture> tex, CBox* pBox, CRegion* damage, float alpha, SP<CSyncTimeline> waitTimeline, uint64_t waitPoint, Vector2D hotspot, bool nearest, float stretchAngle, Vector2D stretch, int mode, bool chroma, CColor chromaColor, Vector2D screenOffset);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue