17
17
import net .minecraftforge .api .distmarker .OnlyIn ;
18
18
import org .apache .logging .log4j .LogManager ;
19
19
import org .apache .logging .log4j .Logger ;
20
+ import org .lwjgl .opengl .GL11 ;
20
21
22
+ // Cheers to TheGreyGhost on Minecraft Forge Forums for help with this one!
21
23
@ OnlyIn (Dist .CLIENT )
22
24
public class LayeredColorMaskTextureCustom extends Texture {
23
25
private static final Logger LOGGER = LogManager .getLogger ();
@@ -34,34 +36,35 @@ public LayeredColorMaskTextureCustom(ResourceLocation textureLocationIn, List<St
34
36
public void loadTexture (IResourceManager manager ) throws IOException {
35
37
try (
36
38
IResource iresource = manager .getResource (this .textureLocation );
37
- NativeImage nativeimage = NativeImage .read (iresource .getInputStream ());
38
- NativeImage nativeimage1 = new NativeImage (nativeimage .getWidth (), nativeimage .getHeight (), false );
39
+ NativeImage baseElytra = NativeImage .read (iresource .getInputStream ());
40
+ NativeImage overlaidElytra = new NativeImage (baseElytra .getWidth (), baseElytra .getHeight (), false );
39
41
) {
40
- nativeimage1 .copyImageData (nativeimage );
42
+ overlaidElytra .copyImageData (baseElytra );
41
43
42
44
for (int i = 0 ; i < 17 && i < this .listTextures .size () && i < this .listDyeColors .size (); ++i ) {
43
- String s = this .listTextures .get (i );
44
- if (s != null ) {
45
+ String bannerTextureRL = this .listTextures .get (i );
46
+ if (bannerTextureRL != null ) {
45
47
try (
46
- NativeImage nativeimage2 = net .minecraftforge .client .MinecraftForgeClient .getImageLayer (new ResourceLocation (s ), manager );
48
+ NativeImage bannerLayer = net .minecraftforge .client .MinecraftForgeClient .getImageLayer (new ResourceLocation (bannerTextureRL ), manager );
47
49
) {
48
- int swappedColorValue = this .listDyeColors .get (i ).getSwappedColorValue ();
49
- if (nativeimage2 .getWidth () == nativeimage1 .getWidth () && nativeimage2 .getHeight () == nativeimage1 .getHeight ()) {
50
- for (int height = 0 ; height < nativeimage2 .getHeight (); ++height ) {
51
- for (int width = 0 ; width < nativeimage2 .getWidth (); ++width ) {
50
+ int bannerLayerColour = this .listDyeColors .get (i ).getSwappedColorValue ();
51
+ if (bannerLayer .getWidth () == overlaidElytra .getWidth () && bannerLayer .getHeight () == overlaidElytra .getHeight ()) {
52
+ for (int height = 0 ; height < bannerLayer .getHeight (); ++height ) {
53
+ for (int width = 0 ; width < bannerLayer .getWidth (); ++width ) {
52
54
53
- int pixelRGBA = nativeimage2 .getPixelRGBA (width , height );
55
+ int alphaBanner = bannerLayer .getPixelRGBA (width , height ) & 0xff ; // extract the red channel, could have used green or blue also.
56
+ int alphaElytra = baseElytra .getPixelLuminanceOrAlpha (width , height ) & 0xff ;
57
+ // algorithm is:
58
+ // if elytra pixel is transparent, do nothing
59
+ // otherwise:
60
+ // the banner blend layer is a greyscale which is converted to a transparency:
61
+ // blend the banner's colour into elytra pixel using the banner blend transparency
54
62
55
- if (nativeimage2 .getPixelLuminanceOrAlpha (width , height ) == 0 ) {
56
-
57
- int color = (pixelRGBA & 255 ) << 24 & -16777216 ;
58
-
59
- nativeimage1 .setPixelRGBA (width , height , color );
60
- } else if ((pixelRGBA & -16777216 ) != 0 ) {
61
- int shiftedPixelRGBA = (pixelRGBA & 255 ) << 24 & -16777216 ;
62
- int pixelRGBA1 = nativeimage .getPixelRGBA (width , height );
63
- int multipliedColor = MathHelper .multiplyColor (pixelRGBA1 , swappedColorValue ) & 16777215 ;
64
- nativeimage1 .blendPixel (width , height , shiftedPixelRGBA | multipliedColor );
63
+ if (alphaElytra != 0 && alphaBanner != 0 ) {
64
+ int elytraPixelRGBA = baseElytra .getPixelRGBA (width , height );
65
+ int multipliedColorRGB = MathHelper .multiplyColor (elytraPixelRGBA , bannerLayerColour ) & 0xFFFFFF ;
66
+ int multipliedColorRGBA = multipliedColorRGB | (alphaBanner << 24 );
67
+ overlaidElytra .blendPixel (width , height , multipliedColorRGBA );
65
68
}
66
69
67
70
}
@@ -71,13 +74,12 @@ public void loadTexture(IResourceManager manager) throws IOException {
71
74
}
72
75
}
73
76
74
- TextureUtil .prepareImage (this .getGlTextureId (), nativeimage1 .getWidth (), nativeimage1 .getHeight ());
75
- GlStateManager .pixelTransfer (3357 , Float .MAX_VALUE );
76
- nativeimage1 .uploadTextureSub (0 , 0 , 0 , false );
77
- GlStateManager .pixelTransfer (3357 , 0.0F );
77
+ TextureUtil .prepareImage (this .getGlTextureId (), overlaidElytra .getWidth (), overlaidElytra .getHeight ());
78
+ GlStateManager .pixelTransfer (GL11 .GL_ALPHA_BIAS , 0.0F );
79
+ overlaidElytra .uploadTextureSub (0 , 0 , 0 , false );
78
80
} catch (IOException ioexception ) {
79
81
LOGGER .error ("Couldn't load layered color mask image" , (Throwable ) ioexception );
80
82
}
81
83
82
84
}
83
- }
85
+ }
0 commit comments