|
| 1 | +/* |
| 2 | + * FDPClient Hacked Client |
| 3 | + * A free open source mixin-based injection hacked client for Minecraft using Minecraft Forge. |
| 4 | + * https://github.com/SkidderMC/FDPClient/ |
| 5 | + */ |
| 6 | +package net.ccbluex.liquidbounce.utils.render |
| 7 | + |
| 8 | +import net.minecraft.client.renderer.GlStateManager |
| 9 | +import org.lwjgl.opengl.GL11.glColor4f |
| 10 | +import java.awt.Color |
| 11 | +import kotlin.math.max |
| 12 | +import kotlin.math.min |
| 13 | + |
| 14 | +/** |
| 15 | + * Color operations and conversions |
| 16 | + * |
| 17 | + * @author Zywl |
| 18 | + */ |
| 19 | +object RenderColor { |
| 20 | + |
| 21 | + /** |
| 22 | + * Sets OpenGL color from RGBA components. |
| 23 | + * |
| 24 | + * @param red Red component (0-255) |
| 25 | + * @param green Green component (0-255) |
| 26 | + * @param blue Blue component (0-255) |
| 27 | + * @param alpha Alpha component (0-255) |
| 28 | + */ |
| 29 | + @JvmStatic |
| 30 | + fun glColor(red: Int, green: Int, blue: Int, alpha: Int) { |
| 31 | + glColor4f(red / 255f, green / 255f, blue / 255f, alpha / 255f) |
| 32 | + } |
| 33 | + |
| 34 | + /** |
| 35 | + * Sets OpenGL color from hex color. |
| 36 | + * |
| 37 | + * @param hex ARGB color as integer |
| 38 | + */ |
| 39 | + @JvmStatic |
| 40 | + fun glHexColor(hex: Int) { |
| 41 | + val alpha = (hex shr 24 and 0xFF) / 255f |
| 42 | + val red = (hex shr 16 and 0xFF) / 255f |
| 43 | + val green = (hex shr 8 and 0xFF) / 255f |
| 44 | + val blue = (hex and 0xFF) / 255f |
| 45 | + |
| 46 | + GlStateManager.color(red, green, blue, alpha) |
| 47 | + } |
| 48 | + |
| 49 | + /** |
| 50 | + * Sets OpenGL color from Color object. |
| 51 | + * |
| 52 | + * @param color Color object |
| 53 | + */ |
| 54 | + @JvmStatic |
| 55 | + fun glColor(color: Color) { |
| 56 | + glColor(color.red, color.green, color.blue, color.alpha) |
| 57 | + } |
| 58 | + |
| 59 | + /** |
| 60 | + * Sets GlStateManager color from Color object. |
| 61 | + * |
| 62 | + * @param color Color object |
| 63 | + */ |
| 64 | + @JvmStatic |
| 65 | + fun glStateManagerColor(color: Color) { |
| 66 | + GlStateManager.color( |
| 67 | + color.red / 255f, |
| 68 | + color.green / 255f, |
| 69 | + color.blue / 255f, |
| 70 | + color.alpha / 255f |
| 71 | + ) |
| 72 | + } |
| 73 | + |
| 74 | + /** |
| 75 | + * Sets OpenGL color from hex integer (RGB or ARGB). |
| 76 | + * |
| 77 | + * @param hex Color as integer |
| 78 | + */ |
| 79 | + @JvmStatic |
| 80 | + fun glColor(hex: Int) { |
| 81 | + glColor( |
| 82 | + hex shr 16 and 0xFF, |
| 83 | + hex shr 8 and 0xFF, |
| 84 | + hex and 0xFF, |
| 85 | + hex shr 24 and 0xFF |
| 86 | + ) |
| 87 | + } |
| 88 | + |
| 89 | + /** |
| 90 | + * Sets OpenGL color from integer with custom alpha. |
| 91 | + * |
| 92 | + * @param color RGB color |
| 93 | + * @param alpha Alpha value (0.0 to 1.0) |
| 94 | + */ |
| 95 | + @JvmStatic |
| 96 | + fun color(color: Int, alpha: Float) { |
| 97 | + val r = (color shr 16 and 0xFF) / 255.0f |
| 98 | + val g = (color shr 8 and 0xFF) / 255.0f |
| 99 | + val b = (color and 0xFF) / 255.0f |
| 100 | + GlStateManager.color(r, g, b, alpha) |
| 101 | + } |
| 102 | + |
| 103 | + /** |
| 104 | + * Sets OpenGL color from integer (ARGB). |
| 105 | + * |
| 106 | + * @param color ARGB color |
| 107 | + */ |
| 108 | + @JvmStatic |
| 109 | + fun color(color: Int) { |
| 110 | + color(color, (color shr 24 and 0xFF) / 255.0f) |
| 111 | + } |
| 112 | + |
| 113 | + /** |
| 114 | + * Interpolates between two integer colors. |
| 115 | + * |
| 116 | + * @param color1 First color |
| 117 | + * @param color2 Second color |
| 118 | + * @param amount Interpolation amount (0.0 to 1.0) |
| 119 | + * @return Interpolated color |
| 120 | + */ |
| 121 | + @JvmStatic |
| 122 | + fun interpolateColor(color1: Int, color2: Int, amount: Float): Int { |
| 123 | + val amountClamped = amount.coerceIn(0f, 1f) |
| 124 | + val cColor1 = Color(color1, true) |
| 125 | + val cColor2 = Color(color2, true) |
| 126 | + return interpolateColorC(cColor1, cColor2, amountClamped).rgb |
| 127 | + } |
| 128 | + |
| 129 | + /** |
| 130 | + * Interpolates between two Color objects. |
| 131 | + * |
| 132 | + * @param color1 First color |
| 133 | + * @param color2 Second color |
| 134 | + * @param amount Interpolation amount (0.0 to 1.0) |
| 135 | + * @return Interpolated Color |
| 136 | + */ |
| 137 | + @JvmStatic |
| 138 | + fun interpolateColorC(color1: Color, color2: Color, amount: Float): Color { |
| 139 | + val amountClamped = amount.coerceIn(0f, 1f) |
| 140 | + return Color( |
| 141 | + interpolateInt(color1.red, color2.red, amountClamped), |
| 142 | + interpolateInt(color1.green, color2.green, amountClamped), |
| 143 | + interpolateInt(color1.blue, color2.blue, amountClamped), |
| 144 | + interpolateInt(color1.alpha, color2.alpha, amountClamped) |
| 145 | + ) |
| 146 | + } |
| 147 | + |
| 148 | + /** |
| 149 | + * Interpolates between two integers. |
| 150 | + * |
| 151 | + * @param oldValue Starting value |
| 152 | + * @param newValue Ending value |
| 153 | + * @param interpolationValue Interpolation amount (0.0 to 1.0) |
| 154 | + * @return Interpolated value |
| 155 | + */ |
| 156 | + @JvmStatic |
| 157 | + fun interpolateInt(oldValue: Int, newValue: Int, interpolationValue: Float): Int { |
| 158 | + return interpolateDouble(oldValue.toDouble(), newValue.toDouble(), interpolationValue.toDouble()).toInt() |
| 159 | + } |
| 160 | + |
| 161 | + /** |
| 162 | + * Interpolates between two double values. |
| 163 | + * |
| 164 | + * @param oldValue Starting value |
| 165 | + * @param newValue Ending value |
| 166 | + * @param interpolationValue Interpolation amount |
| 167 | + * @return Interpolated value |
| 168 | + */ |
| 169 | + @JvmStatic |
| 170 | + fun interpolateDouble(oldValue: Double, newValue: Double, interpolationValue: Double): Double { |
| 171 | + return oldValue + (newValue - oldValue) * interpolationValue |
| 172 | + } |
| 173 | + |
| 174 | + /** |
| 175 | + * Makes a color darker. |
| 176 | + * |
| 177 | + * @param color Original color |
| 178 | + * @param factor Darkening factor (0.0 to 1.0, lower = darker) |
| 179 | + * @return Darker color |
| 180 | + */ |
| 181 | + @JvmStatic |
| 182 | + fun darker(color: Color, factor: Float): Color { |
| 183 | + return Color( |
| 184 | + max((color.red * factor).toInt(), 0), |
| 185 | + max((color.green * factor).toInt(), 0), |
| 186 | + max((color.blue * factor).toInt(), 0), |
| 187 | + color.alpha |
| 188 | + ) |
| 189 | + } |
| 190 | + |
| 191 | + /** |
| 192 | + * Makes a color brighter. |
| 193 | + * |
| 194 | + * @param color Original color |
| 195 | + * @param factor Brightening factor (0.0 to 1.0, higher = brighter) |
| 196 | + * @return Brighter color |
| 197 | + */ |
| 198 | + @JvmStatic |
| 199 | + fun brighter(color: Color, factor: Float): Color { |
| 200 | + var r = color.red |
| 201 | + var g = color.green |
| 202 | + var b = color.blue |
| 203 | + val alpha = color.alpha |
| 204 | + |
| 205 | + val i = (1.0 / (1.0 - factor)).toInt() |
| 206 | + if (r == 0 && g == 0 && b == 0) { |
| 207 | + return Color(i, i, i, alpha) |
| 208 | + } |
| 209 | + |
| 210 | + if (r in 1 until i) r = i |
| 211 | + if (g in 1 until i) g = i |
| 212 | + if (b in 1 until i) b = i |
| 213 | + |
| 214 | + return Color( |
| 215 | + min((r / factor).toInt(), 255), |
| 216 | + min((g / factor).toInt(), 255), |
| 217 | + min((b / factor).toInt(), 255), |
| 218 | + alpha |
| 219 | + ) |
| 220 | + } |
| 221 | + |
| 222 | + /** |
| 223 | + * Applies opacity to a Color object. |
| 224 | + * |
| 225 | + * @param color Original color |
| 226 | + * @param opacity Opacity value (0.0 to 1.0) |
| 227 | + * @return Color with applied opacity |
| 228 | + */ |
| 229 | + @JvmStatic |
| 230 | + fun applyOpacity(color: Color, opacity: Float): Color { |
| 231 | + val opacityClamped = opacity.coerceIn(0f, 1f) |
| 232 | + return Color(color.red, color.green, color.blue, (color.alpha * opacityClamped).toInt()) |
| 233 | + } |
| 234 | + |
| 235 | + /** |
| 236 | + * Applies opacity to an integer color. |
| 237 | + * |
| 238 | + * @param color Original color as integer |
| 239 | + * @param opacity Opacity value (0.0 to 1.0) |
| 240 | + * @return Color with applied opacity |
| 241 | + */ |
| 242 | + @JvmStatic |
| 243 | + fun applyOpacity(color: Int, opacity: Float): Int { |
| 244 | + val opacityClamped = opacity.coerceIn(0f, 1f) |
| 245 | + val alpha = ((color shr 24 and 0xFF) * opacityClamped).toInt() |
| 246 | + return (alpha shl 24) or (color and 0x00FFFFFF) |
| 247 | + } |
| 248 | + |
| 249 | + /** |
| 250 | + * Resets OpenGL color to white. |
| 251 | + */ |
| 252 | + @JvmStatic |
| 253 | + fun resetColor() { |
| 254 | + GlStateManager.color(1f, 1f, 1f, 1f) |
| 255 | + } |
| 256 | + |
| 257 | + /** |
| 258 | + * Gets border color based on enchantment level. |
| 259 | + * |
| 260 | + * @param level Enchantment level |
| 261 | + * @return Border color |
| 262 | + */ |
| 263 | + @JvmStatic |
| 264 | + fun getBorderColor(level: Int): Int { |
| 265 | + return when { |
| 266 | + level == 2 -> 0x7055FF55 |
| 267 | + level == 3 -> 0x7000AAAA |
| 268 | + level == 4 -> 0x70AA0000 |
| 269 | + level >= 5 -> 0x70FFAA00 |
| 270 | + else -> 0x70FFFFFF |
| 271 | + } |
| 272 | + } |
| 273 | +} |
0 commit comments