diff --git a/runelite-api/src/main/java/net/runelite/api/hooks/DrawCallbacks.java b/runelite-api/src/main/java/net/runelite/api/hooks/DrawCallbacks.java index 989cc45dd2..7cf7469f37 100644 --- a/runelite-api/src/main/java/net/runelite/api/hooks/DrawCallbacks.java +++ b/runelite-api/src/main/java/net/runelite/api/hooks/DrawCallbacks.java @@ -43,7 +43,12 @@ public interface DrawCallbacks SceneTileModel model, int tileZ, int tileX, int tileY, int zoom, int centerX, int centerY); - void draw(); + /** + * Called when a frame should be drawn. + * + * @param overlayColor Color of full-viewport overlays, if any + */ + void draw(int overlayColor); boolean drawFace(Model model, int face); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java index 2d3b0c78d4..e82373edd5 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/gpu/GpuPlugin.java @@ -264,6 +264,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks private int uniTexSamplingMode; private int uniTexSourceDimensions; private int uniTexTargetDimensions; + private int uniUiAlphaOverlay; private int uniTextures; private int uniTextureOffsets; private int uniBlockSmall; @@ -545,6 +546,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks uniTexTargetDimensions = gl.glGetUniformLocation(glUiProgram, "targetDimensions"); uniTexSourceDimensions = gl.glGetUniformLocation(glUiProgram, "sourceDimensions"); uniUiColorBlindMode = gl.glGetUniformLocation(glUiProgram, "colorBlindMode"); + uniUiAlphaOverlay = gl.glGetUniformLocation(glUiProgram, "alphaOverlay"); uniTextures = gl.glGetUniformLocation(glProgram, "textures"); uniTextureOffsets = gl.glGetUniformLocation(glProgram, "textureOffsets"); @@ -855,9 +857,9 @@ public class GpuPlugin extends Plugin implements DrawCallbacks } @Override - public void draw() + public void draw(int overlayColor) { - invokeOnMainThread(this::drawFrame); + invokeOnMainThread(() -> drawFrame(overlayColor)); } private void resize(int canvasWidth, int canvasHeight, int viewportWidth, int viewportHeight) @@ -883,7 +885,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks } } - private void drawFrame() + private void drawFrame(int overlayColor) { if (jawtWindow.getAWTComponent() != client.getCanvas()) { @@ -1208,7 +1210,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks tempUvOffset = 0; // Texture on UI - drawUi(canvasHeight, canvasWidth); + drawUi(overlayColor, canvasHeight, canvasWidth); glDrawable.swapBuffers(); @@ -1226,7 +1228,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks }; } - private void drawUi(final int canvasHeight, final int canvasWidth) + private void drawUi(final int overlayColor, final int canvasHeight, final int canvasWidth) { final BufferProvider bufferProvider = client.getBufferProvider(); final int[] pixels = bufferProvider.getPixels(); @@ -1254,6 +1256,12 @@ public class GpuPlugin extends Plugin implements DrawCallbacks gl.glUniform1i(uniTexSamplingMode, uiScalingMode.getMode()); gl.glUniform2i(uniTexSourceDimensions, canvasWidth, canvasHeight); gl.glUniform1i(uniUiColorBlindMode, config.colorBlindMode().ordinal()); + gl.glUniform4f(uniUiAlphaOverlay, + (overlayColor >> 16 & 0xFF) / 255f, + (overlayColor >> 8 & 0xFF) / 255f, + (overlayColor & 0xFF) / 255f, + (overlayColor >>> 24) / 255f + ); if (client.isStretchedEnabled()) { diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/gpu/fragui.glsl b/runelite-client/src/main/resources/net/runelite/client/plugins/gpu/fragui.glsl index e522d34400..5a54522f83 100644 --- a/runelite-client/src/main/resources/net/runelite/client/plugins/gpu/fragui.glsl +++ b/runelite-client/src/main/resources/net/runelite/client/plugins/gpu/fragui.glsl @@ -34,6 +34,7 @@ uniform int samplingMode; uniform ivec2 sourceDimensions; uniform ivec2 targetDimensions; uniform int colorBlindMode; +uniform vec4 alphaOverlay; #include scale/bicubic.glsl #include scale/xbr_lv2_frag.glsl @@ -44,6 +45,13 @@ in XBRTable xbrTable; out vec4 FragColor; +vec4 alphaBlend(vec4 src, vec4 dst) { + return vec4( + src.rgb + dst.rgb * (1.0f - src.a), + src.a + dst.a * (1.0f - src.a) + ); +} + void main() { vec4 c; @@ -51,14 +59,17 @@ void main() { case SAMPLING_CATROM: case SAMPLING_MITCHELL: c = textureCubic(tex, TexCoord, samplingMode); + c = alphaBlend(c, alphaOverlay); c.rgb = colorblind(colorBlindMode, c.rgb); break; case SAMPLING_XBR: c = textureXBR(tex, TexCoord, xbrTable, ceil(1.0 * targetDimensions.x / sourceDimensions.x)); + c = alphaBlend(c, alphaOverlay); c.rgb = colorblind(colorBlindMode, c.rgb); break; default: // NEAREST or LINEAR, which uses GL_TEXTURE_MIN_FILTER/GL_TEXTURE_MAG_FILTER to affect sampling c = texture(tex, TexCoord); + c = alphaBlend(c, alphaOverlay); c.rgb = colorblind(colorBlindMode, c.rgb); }