gpu: Use premultiplied alpha
This commit is contained in:
@@ -1199,7 +1199,7 @@ public class GpuPlugin extends Plugin implements DrawCallbacks
|
||||
interfaceBuffer.put(pixels);
|
||||
vertexBuffer.flip();
|
||||
|
||||
gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.glBlendFunc(gl.GL_ONE, gl.GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.glBindTexture(gl.GL_TEXTURE_2D, interfaceTexture);
|
||||
|
||||
if (canvasWidth != lastCanvasWidth || canvasHeight != lastCanvasHeight)
|
||||
|
||||
@@ -26,7 +26,9 @@ package net.runelite.mixins;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.color.ColorSpace;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.awt.image.DataBufferInt;
|
||||
import java.awt.image.DirectColorModel;
|
||||
import java.awt.image.Raster;
|
||||
@@ -64,9 +66,11 @@ public abstract class RSMainBufferProviderMixin implements RSMainBufferProvider
|
||||
// we need to make our own buffered image for the client with the alpha channel enabled in order to
|
||||
// have alphas for the overlays applied correctly
|
||||
DataBufferInt dataBufferInt = new DataBufferInt(pixels, pixels.length);
|
||||
DirectColorModel directColorModel = new DirectColorModel(32, 0xff0000, 0xff00, 0xff, 0xff000000);
|
||||
DirectColorModel directColorModel = new DirectColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
|
||||
32, 0xff0000, 0xff00, 0xff, 0xff000000,
|
||||
true, DataBuffer.TYPE_INT);
|
||||
WritableRaster writableRaster = Raster.createWritableRaster(directColorModel.createCompatibleSampleModel(width, height), dataBufferInt, null);
|
||||
BufferedImage bufferedImage = new BufferedImage(directColorModel, writableRaster, false, new Hashtable());
|
||||
BufferedImage bufferedImage = new BufferedImage(directColorModel, writableRaster, true, new Hashtable());
|
||||
|
||||
setImage(bufferedImage);
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public abstract class Rasterizer2DMixin implements RSClient
|
||||
private static RSClient client;
|
||||
|
||||
@Inject
|
||||
private static void drawAlpha(int[] pixels, int index, int value, int color, int alpha)
|
||||
private static void drawAlpha(int[] pixels, int index, int value, int alpha)
|
||||
{
|
||||
if (!client.isGpu() || pixels != client.getBufferProvider().getPixels())
|
||||
{
|
||||
@@ -46,44 +46,9 @@ public abstract class Rasterizer2DMixin implements RSClient
|
||||
return;
|
||||
}
|
||||
|
||||
if (alpha == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int prevColor = pixels[index];
|
||||
|
||||
if ((prevColor & 0xFF000000) == 0 || alpha == 255)
|
||||
{
|
||||
// No transparency, so we can cheat to save CPU resources
|
||||
pixels[index] = (color & 0xFFFFFF) | (alpha << 24);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((prevColor & 0xFF000000) == 0xFF000000)
|
||||
{
|
||||
// When the background is opaque, the result will also be opaque,
|
||||
// so we can simply use the value calculated by Jagex.
|
||||
pixels[index] = value | 0xFF000000;
|
||||
return;
|
||||
}
|
||||
|
||||
int prevAlpha = (prevColor >>> 24) * (255 - alpha) >>> 8;
|
||||
int finalAlpha = alpha + prevAlpha;
|
||||
|
||||
// Scale alphas so (relativeAlpha >>> 8) is approximately equal to (alpha / finalAlpha).
|
||||
// Avoiding extra divisions increase performance by quite a bit.
|
||||
// And with divisions we get a problems if dividing a number where
|
||||
// the last bit is 1 (as it will become negative).
|
||||
int relativeAlpha1 = (alpha << 8) / finalAlpha;
|
||||
int relativeAlpha2 = (prevAlpha << 8) / finalAlpha;
|
||||
|
||||
// Red and blue are calculated at the same time to save CPU cycles
|
||||
int finalColor =
|
||||
(((color & 0xFF00FF) * relativeAlpha1 + (prevColor & 0xFF00FF) * relativeAlpha2 & 0xFF00FF00) |
|
||||
((color & 0x00FF00) * relativeAlpha1 + (prevColor & 0x00FF00) * relativeAlpha2 & 0x00FF0000)) >>> 8;
|
||||
|
||||
pixels[index] = finalColor | (finalAlpha << 24);
|
||||
// (int) x * 0x8081 >>> 23 is equivalent to (short) x / 255
|
||||
int outAlpha = alpha + ((pixels[index] >>> 24) * (255 - alpha) * 0x8081 >>> 23);
|
||||
pixels[index] = value & 0x00FFFFFF | outAlpha << 24;
|
||||
}
|
||||
|
||||
@Copy("drawGradientAlpha")
|
||||
@@ -158,7 +123,7 @@ public abstract class Rasterizer2DMixin implements RSClient
|
||||
{
|
||||
int var20 = pixels[var11];
|
||||
var20 = ((var20 & 16711935) * var17 >> 8 & 16711935) + (var17 * (var20 & 65280) >> 8 & 65280);
|
||||
drawAlpha(pixels, var11++, var18 + var20, var16, var15);
|
||||
drawAlpha(pixels, var11++, var18 + var20, var15);
|
||||
}
|
||||
|
||||
var11 += var10;
|
||||
@@ -267,7 +232,7 @@ public abstract class Rasterizer2DMixin implements RSClient
|
||||
int var21 = 255 - var20;
|
||||
int var22 = pixels[var14];
|
||||
int var23 = ((var19 & 16711935) * var20 + (var22 & 16711935) * var21 & -16711936) + (var20 * (var19 & 65280) + var21 * (var22 & 65280) & 16711680) >> 8;
|
||||
drawAlpha(pixels, var14++, var23, var19, var20);
|
||||
drawAlpha(pixels, var14++, var23, var20);
|
||||
}
|
||||
|
||||
var14 += var11;
|
||||
|
||||
Reference in New Issue
Block a user