[PlutoLib/PlutoShader] The initial implementation of the color API
This commit is contained in:
parent
ffa84ff1f4
commit
3bc8b5335c
|
@ -5,6 +5,8 @@
|
|||
* Rethink the class loader system.
|
||||
* `[PlutoLib]` Redo the resource system
|
||||
* `[PlutoLib]` Create a new Color API and port renderer code to it
|
||||
* `[PlutoGUI]` FontRenderer code will not receive these changes
|
||||
as it is awaiting a rewrite anyway
|
||||
|
||||
## Features targeted for 20.2.0.0-alpha.4
|
||||
* The stage subsystem
|
||||
|
@ -38,6 +40,11 @@
|
|||
instances
|
||||
* Allow stages to be inherited from, creating a stack-like structure
|
||||
* `[PlutoAudio]` Integrate the Audio API with the Stage API
|
||||
* `[PlutoGUI]` Initial implementation of the new font renderer
|
||||
* Full rewrite
|
||||
* High quality font rendering
|
||||
* Subpixel rendering support [?]
|
||||
* Possibly a new system for bitmap fonts
|
||||
* Improve upon the support of thread-local Pluto instances
|
||||
* The long term goal is to allow an unlimited amount of Pluto applications at any given time
|
||||
|
||||
|
|
10
README.md
10
README.md
|
@ -45,18 +45,18 @@ See `NEXT_RELEASE_DRAFT.md` for details.
|
|||
### Very high priority
|
||||
[ *Implemented in the current release.* ]
|
||||
* Rewrite the ModLoader
|
||||
* Finish PlutoCommandParser
|
||||
* Streamline PlutoLib, remove bad APIs and improve code quality
|
||||
* The stage system and automated asset loading
|
||||
|
||||
### High priority
|
||||
[ *Implemented in the next release.* ]
|
||||
* Rewrite PlutoGUI
|
||||
* Finish PlutoAudio
|
||||
* Depends on the stage system
|
||||
* The stage system and automated asset loading
|
||||
* Finish PlutoCommandParser
|
||||
|
||||
### Normal priority
|
||||
[ *Planned for an upcoming release.* ]
|
||||
* Rewrite PlutoGUI
|
||||
* The collision system for PlutoStatic
|
||||
* Improve image loading capabilities, possibly rewrite PlutoLib#TPL
|
||||
|
||||
|
@ -66,3 +66,7 @@ See `NEXT_RELEASE_DRAFT.md` for details.
|
|||
* Alternatively, if this deems too difficult to implement,
|
||||
prohibit the creation of more than instance per VM to avoid issues
|
||||
* A networking API
|
||||
* Expand upon the Color API
|
||||
* Color mixing and blending
|
||||
* Color transformation
|
||||
* High-performance serialization
|
|
@ -5,11 +5,17 @@
|
|||
* `[PlutoLib]` Added the `@ConstantExpression` annotation
|
||||
* `[PlutoLib]` The `RAID#getIDOf` method now returns `OptionalInt` to avoid NPEs
|
||||
* `[PlutoLib]` The transitive dependency JOML is now provided by `PlutoLib` instead of `PlutoStatic`
|
||||
* `[PlutoLib]` Created a simple Color API
|
||||
* `[PlutoShader]` Added the 8-bit RGBA `Color` class as a counterpart to AWT's `Color` class
|
||||
* `[PlutoShader]` Added the `RGBA` and `RGB` single precision float color objects
|
||||
* `[PlutoShader]` Added the respective `IRGBA` and `IRGB` read-only interfaces
|
||||
* `[PlutoShader]` Added the `HSBA` and `HSB` single precision float color objects
|
||||
* `[PlutoShader]` Added methods to convert between HSBA, RGBA, HSB and RGB
|
||||
* `[PlutoShader]` Added the `UniformRGBA` and `UniformRGB` shader uniform types
|
||||
|
||||
Awaiting implementation:
|
||||
* `[PlutoLib]` Moved `cz.tefek.pluto.io.pluto.pp` to `cz.tefek.pluto.io.plutopackage`
|
||||
* `[PlutoLib]` Completely reworked the module system
|
||||
* `[PlutoLib]` Created a simple Color API
|
||||
|
||||
## 20.2.0.0-alpha.2
|
||||
* `build.gradle` Extracted the version numbers into separate variables
|
||||
|
|
|
@ -0,0 +1,446 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public final class Color
|
||||
{
|
||||
// Black and white
|
||||
public static Color WHITE = new Color(255, 255, 255);
|
||||
public static Color BLACK = new Color(0, 0, 0);
|
||||
|
||||
// Shades of gray
|
||||
public static Color VERY_DARK_GRAY = new Color(40, 40, 40);
|
||||
public static Color DARK_GRAY = new Color(85, 85, 85);
|
||||
public static Color GRAY = new Color(128, 128, 128);
|
||||
public static Color SILVER = new Color(192, 192, 192);
|
||||
public static Color LIGHT_GRAY = new Color(212, 212, 212);
|
||||
|
||||
// Basic colors
|
||||
public static Color RED = new Color(255, 0, 0);
|
||||
public static Color GREEN = new Color(0, 255, 0);
|
||||
public static Color BLUE = new Color(0, 0, 255);
|
||||
public static Color YELLOW = new Color(255, 255, 0);
|
||||
|
||||
|
||||
public static Color TRANSPARENT = new Color(0, 0, 0, 0);
|
||||
public static Color TRANSPARENT_WHITE = new Color(255, 255, 255, 0);
|
||||
|
||||
public static Color AMBER = new Color(255, 190, 0);
|
||||
public static Color AMETHYST = new Color(153, 102, 204);
|
||||
public static Color APRICOT = new Color(235, 147, 115);
|
||||
public static Color AZURE = new Color(0, 57, 169);
|
||||
public static Color BROWN = new Color(150, 75, 0);
|
||||
public static Color COBALT = new Color(0, 71, 171);
|
||||
public static Color COPPER = new Color(184, 115, 51);
|
||||
public static Color CORAL_RED = new Color(255, 50, 60);
|
||||
public static Color CORNFLOWER_BLUE = new Color(112, 112, 255);
|
||||
public static Color CRIMSON = new Color(220, 26, 64);
|
||||
public static Color CYAN = new Color(0, 188, 212);
|
||||
public static Color DARK_BROWN = new Color(66, 33, 0);
|
||||
public static Color DARK_GREEN = new Color(0, 150, 0);
|
||||
public static Color LIGHT_AZURE = new Color(0, 128, 255);
|
||||
public static Color LIME = new Color(191, 255, 0);
|
||||
public static Color MAGENTA = new Color(255, 0, 255);
|
||||
public static Color MALACHITE = new Color(11, 218, 81);
|
||||
public static Color NAVY_BLUE = new Color(0, 0, 128);
|
||||
public static Color OBSIDIAN = new Color(16, 18, 29);
|
||||
public static Color ORANGE = new Color(255, 102, 0);
|
||||
public static Color ORANGE_RED = new Color(255, 55, 0);
|
||||
public static Color PEAR = new Color(209, 226, 49);
|
||||
public static Color PINK = new Color(253, 109, 134);
|
||||
public static Color PUMPKIN_ORANGE = new Color(255, 117, 0);
|
||||
public static Color SAPPHIRE = new Color(47, 81, 158);
|
||||
public static Color TEAL = new Color(0, 140, 140);
|
||||
public static Color TURQUOISE = new Color(10, 255, 141);
|
||||
|
||||
|
||||
public static Color PASTEL_PINK = new Color(255, 192, 203);
|
||||
public static Color PASTEL_LIME = new Color(221, 255, 192);
|
||||
public static Color PASTEL_YELLOW = new Color(252, 255, 192);
|
||||
public static Color PASTEL_CYAN = new Color(192, 255, 234);
|
||||
public static Color PASTEL_BLUE = new Color(192, 199, 255);
|
||||
public static Color PASTEL_VIOLET = new Color(192, 199, 255);
|
||||
|
||||
public int red;
|
||||
public int green;
|
||||
public int blue;
|
||||
public int alpha = 255;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public Color(int red, int green, int blue, int alpha)
|
||||
{
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
this.alpha = alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public Color(int red, int green, int blue)
|
||||
{
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public static Color from(@Nonnull IRGBA colorComponents)
|
||||
{
|
||||
return new Color(Math.round(colorComponents.red() * 255),
|
||||
Math.round(colorComponents.green() * 255),
|
||||
Math.round(colorComponents.blue() * 255),
|
||||
Math.round(colorComponents.alpha() * 255));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public static Color from(@Nonnull IRGB colorComponents)
|
||||
{
|
||||
return new Color(Math.round(colorComponents.red() * 255),
|
||||
Math.round(colorComponents.green() * 255),
|
||||
Math.round(colorComponents.blue() * 255));
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public static Color from(int color, @Nonnull EnumColorFormat colorFormat)
|
||||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case CF_INT_BGR:
|
||||
return new Color(color & 0xff, (color >> 8) & 0xff, (color >> 16) & 0xff);
|
||||
case CF_INT_RGB:
|
||||
return new Color((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
|
||||
case CF_INT_ABGR:
|
||||
return new Color(color & 0xff, (color >> 8) & 0xff, (color >> 16) & 0xff, (color >> 24) & 0xff);
|
||||
case CF_INT_ARGB:
|
||||
return new Color((color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff, (color >> 24) & 0xff);
|
||||
case CF_INT_BGRA:
|
||||
return new Color((color >> 8) & 0xff, (color >> 16) & 0xff, (color >> 24) & 0xff, color & 0xff);
|
||||
case CF_INT_RGBA:
|
||||
return new Color((color >> 24) & 0xff, (color >> 16) & 0xff, (color >> 8) & 0xff, color & 0xff);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Use the from(byte[], int, ColorFormat) for byte color formats!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public static Color from(@Nonnull byte[] color, @Nonnull EnumColorFormat colorFormat)
|
||||
{
|
||||
return from(color, 0, colorFormat);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public static Color from(@Nonnull byte[] color, int offset, @Nonnull EnumColorFormat colorFormat)
|
||||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case CF_3BYTE_BGR:
|
||||
return new Color(color[offset + 2] & 0xFF, color[offset + 1] & 0xFF, color[offset] & 0xFF);
|
||||
case CF_3BYTE_RGB:
|
||||
return new Color(color[offset] & 0xFF, color[offset + 1] & 0xFF, color[offset + 2] & 0xFF);
|
||||
case CF_4BYTE_ABGR:
|
||||
return new Color(color[offset + 3] & 0xFF, color[offset + 2] & 0xFF, color[offset + 1] & 0xFF, color[offset] & 0xFF);
|
||||
case CF_4BYTE_ARGB:
|
||||
return new Color(color[offset + 1] & 0xFF, color[offset + 2] & 0xFF, color[offset + 3] & 0xFF, color[offset] & 0xFF);
|
||||
case CF_4BYTE_BGRA:
|
||||
return new Color(color[offset + 2] & 0xFF, color[offset + 1] & 0xFF, color[offset] & 0xFF, color[offset + 3] & 0xFF);
|
||||
case CF_4BYTE_RGBA:
|
||||
return new Color(color[offset] & 0xFF, color[offset + 1] & 0xFF, color[offset + 2] & 0xFF, color[offset + 3] & 0xFF);
|
||||
default:
|
||||
throw new UnsupportedOperationException("Use the from(int, ColorFormat) for int color formats!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getIntRGBA()
|
||||
{
|
||||
return get(EnumColorFormat.CF_INT_RGBA);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getIntARGB()
|
||||
{
|
||||
return get(EnumColorFormat.CF_INT_ARGB);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int get(@Nonnull EnumColorFormat colorFormat)
|
||||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case CF_INT_BGR:
|
||||
return (this.blue << 16) | (this.green << 8) | this.red;
|
||||
case CF_INT_RGB:
|
||||
return (this.red << 16) | (this.green << 8) | this.blue;
|
||||
case CF_INT_ABGR:
|
||||
return (this.alpha << 24) | (this.blue << 16) | (this.green << 8) | this.red;
|
||||
case CF_INT_ARGB:
|
||||
return (this.alpha << 24) | (this.red << 16) | (this.green << 8) | this.blue;
|
||||
case CF_INT_BGRA:
|
||||
return (this.blue << 24) | (this.green << 16) | (this.red << 8) | this.alpha;
|
||||
case CF_INT_RGBA:
|
||||
return (this.red << 24) | (this.green << 16) | (this.blue << 8) | this.alpha;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Use the get(ColorFormat, byte[], int) for byte color formats!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void get(@Nonnull EnumColorFormat colorFormat, @Nonnull byte[] dataOut)
|
||||
{
|
||||
get(colorFormat, dataOut, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void get(@Nonnull EnumColorFormat colorFormat, @Nonnull byte[] dataOut, int offset)
|
||||
{
|
||||
switch (colorFormat)
|
||||
{
|
||||
case CF_3BYTE_BGR:
|
||||
dataOut[offset++] = (byte) this.blue;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset] = (byte) this.red;
|
||||
break;
|
||||
case CF_3BYTE_RGB:
|
||||
dataOut[offset++] = (byte) this.red;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset] = (byte) this.blue;
|
||||
break;
|
||||
case CF_4BYTE_ABGR:
|
||||
dataOut[offset++] = (byte) this.alpha;
|
||||
dataOut[offset++] = (byte) this.blue;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset] = (byte) this.red;
|
||||
break;
|
||||
case CF_4BYTE_ARGB:
|
||||
dataOut[offset++] = (byte) this.alpha;
|
||||
dataOut[offset++] = (byte) this.red;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset] = (byte) this.blue;
|
||||
break;
|
||||
case CF_4BYTE_BGRA:
|
||||
dataOut[offset++] = (byte) this.blue;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset++] = (byte) this.red;
|
||||
dataOut[offset] = (byte) this.alpha;
|
||||
break;
|
||||
case CF_4BYTE_RGBA:
|
||||
dataOut[offset++] = (byte) this.red;
|
||||
dataOut[offset++] = (byte) this.green;
|
||||
dataOut[offset++] = (byte) this.blue;
|
||||
dataOut[offset] = (byte) this.alpha;
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Use the get(ColorFormat) for int color formats!");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getRed()
|
||||
{
|
||||
return this.red;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getGreen()
|
||||
{
|
||||
return this.green;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getBlue()
|
||||
{
|
||||
return this.blue;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public int getAlpha()
|
||||
{
|
||||
return this.alpha;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGB getFloatComponentsRGB()
|
||||
{
|
||||
return new RGB(this.red / 255.0f, this.green / 255.0f, this.blue / 255.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGBA getFloatComponentsRGBA()
|
||||
{
|
||||
return new RGBA(this.red / 255.0f, this.green / 255.0f, this.blue / 255.0f, this.alpha / 255.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSB getFloatComponentsHSB()
|
||||
{
|
||||
return this.getFloatComponentsRGB().toHSB();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSBA getFloatComponentsHSBA()
|
||||
{
|
||||
return this.getFloatComponentsRGBA().toHSBA();
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void storeFloatComponentsRGBA(@Nonnull RGBA target)
|
||||
{
|
||||
storeFloatComponentsRGB(target);
|
||||
target.a = this.alpha / 255.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void storeFloatComponentsRGB(@Nonnull RGB target)
|
||||
{
|
||||
target.r = this.red / 255.0f;
|
||||
target.g = this.green / 255.0f;
|
||||
target.b = this.blue / 255.0f;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void storeFloatComponentsHSBA(@Nonnull HSBA target)
|
||||
{
|
||||
var hsb = this.getFloatComponentsHSBA();
|
||||
|
||||
target.h = hsb.h;
|
||||
target.s = hsb.s;
|
||||
target.b = hsb.b;
|
||||
target.a = hsb.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void storeFloatComponentsHSB(@Nonnull HSB target)
|
||||
{
|
||||
var hsb = this.getFloatComponentsHSB();
|
||||
|
||||
target.h = hsb.h;
|
||||
target.s = hsb.s;
|
||||
target.b = hsb.b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public enum EnumColorFormat
|
||||
{
|
||||
/**
|
||||
* 8-bit RGBA stored in a big-endian 32-bit integer
|
||||
*/
|
||||
CF_INT_RGBA(4),
|
||||
/**
|
||||
* 8-bit BGRA stored in a big-endian 32-bit integer
|
||||
*/
|
||||
CF_INT_BGRA(4),
|
||||
|
||||
/**
|
||||
* 8-bit ARGB stored in a big-endian 32-bit integer
|
||||
*/
|
||||
CF_INT_ARGB(4),
|
||||
/**
|
||||
* 8-bit ABGR stored in a big-endian 32-bit integer
|
||||
*/
|
||||
CF_INT_ABGR(4),
|
||||
|
||||
/**
|
||||
* 8-bit RGB stored in a big-endian 32-bit integer, the highest 8-bits are unused
|
||||
*/
|
||||
CF_INT_RGB(4),
|
||||
/**
|
||||
* 8-bit RGB stored in a big-endian 32-bit integer, the highest 8-bits are unused
|
||||
*/
|
||||
CF_INT_BGR(4),
|
||||
|
||||
/**
|
||||
* 8-bit RGBA, one byte per color component
|
||||
*/
|
||||
CF_4BYTE_RGBA(4),
|
||||
/**
|
||||
* 8-bit BGRA, one byte per color component
|
||||
*/
|
||||
CF_4BYTE_BGRA(4),
|
||||
|
||||
/**
|
||||
* 8-bit ARGB, one byte per color component
|
||||
*/
|
||||
CF_4BYTE_ARGB(4),
|
||||
/**
|
||||
* 8-bit ABGR, one byte per color component
|
||||
*/
|
||||
CF_4BYTE_ABGR(4),
|
||||
|
||||
/**
|
||||
* 8-bit RGB, one byte per color component
|
||||
*/
|
||||
CF_3BYTE_RGB(3),
|
||||
/**
|
||||
* 8-bit BGR, one byte per color component
|
||||
*/
|
||||
CF_3BYTE_BGR(3);
|
||||
|
||||
private final int size;
|
||||
|
||||
EnumColorFormat(int size)
|
||||
{
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the size in bytes.
|
||||
*
|
||||
* @return The size of the color format, in bytes
|
||||
*/
|
||||
public int getSize()
|
||||
{
|
||||
return this.size;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class HSB
|
||||
{
|
||||
/**
|
||||
* Hue [0°..360°]
|
||||
* */
|
||||
protected float h;
|
||||
|
||||
/**
|
||||
* Saturation [0..1]
|
||||
* */
|
||||
protected float s;
|
||||
private final static Range<Float> SATURATION_RANGE = Range.between(0.0f, 1.0f);
|
||||
|
||||
/**
|
||||
* Value/Brightness [0..1]
|
||||
* */
|
||||
protected float b;
|
||||
private final static Range<Float> BRIGHTNESS_RANGE = Range.between(0.0f, 1.0f);
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSB(float hue, float saturation, float brightness)
|
||||
{
|
||||
this.h = (360.0f + hue % 360.0f) % 360.0f;
|
||||
this.s = SATURATION_RANGE.fit(saturation);
|
||||
this.b = BRIGHTNESS_RANGE.fit(brightness);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGB toRGB()
|
||||
{
|
||||
return this.toRGBA(1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGB toRGBA()
|
||||
{
|
||||
return this.toRGBA(1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGBA toRGBA(float alpha)
|
||||
{
|
||||
float h6 = this.h / 60.0f;
|
||||
|
||||
int hueSide = (int) h6;
|
||||
|
||||
// The color component furthest on the hue wheel
|
||||
float p = this.b * (1 - this.s);
|
||||
|
||||
float hueFractCCW = h6 - hueSide;
|
||||
// The second nearest color component on the hue wheel - counter-clockwise
|
||||
float q = this.b * (1 - hueFractCCW * this.s);
|
||||
|
||||
float hueFractCW = 1 - hueFractCCW;
|
||||
// The second nearest color component on the hue wheel - clockwise
|
||||
float t = this.b * (1 - hueFractCW * this.s);
|
||||
|
||||
switch (hueSide % 6)
|
||||
{
|
||||
case 1: // Hues 60°-119° -- Green is the brightest color, no blue is present at max saturation
|
||||
return new RGBA(q, this.b, p, alpha);
|
||||
|
||||
case 2: // Hues 120°-179° -- Green is the brightest color, no red is present at max saturation
|
||||
return new RGBA(p, this.b, t, alpha);
|
||||
|
||||
case 3: // Hues 180°-239° -- Blue is the brightest color, no red is present at max saturation
|
||||
return new RGBA(p, q, this.b, alpha);
|
||||
|
||||
case 4: // Hues 240°-299° -- Blue is the brightest color, no green is present at max saturation
|
||||
return new RGBA(t, p, this.b, alpha);
|
||||
|
||||
case 5: // Hues 300°-359° -- Red is the brightest color, no green is present at max saturation
|
||||
return new RGBA(this.b, p, q, alpha);
|
||||
|
||||
case 0: // Hues 0°-59° -- Red is the brightest color, no blue is present at max saturation
|
||||
return new RGBA(this.b, t, p, alpha);
|
||||
|
||||
default:
|
||||
throw new IllegalStateException("This HSB object's hue is negative - this is not legal.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float hue()
|
||||
{
|
||||
return this.h;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float saturation()
|
||||
{
|
||||
return this.s;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float brightness()
|
||||
{
|
||||
return this.b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
import org.apache.commons.lang3.Range;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class HSBA extends HSB
|
||||
{
|
||||
protected float a;
|
||||
private final static Range<Float> ALPHA_RANGE = Range.between(0.0f, 1.0f);
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSBA(float hue, float saturation, float lightness, float alpha)
|
||||
{
|
||||
super(hue, saturation, lightness);
|
||||
|
||||
this.a = ALPHA_RANGE.fit(alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float alpha()
|
||||
{
|
||||
return this.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
@Override
|
||||
public RGB toRGBA()
|
||||
{
|
||||
return this.toRGBA(this.a);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
/**
|
||||
* An interface for single precision RGB color objects.
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public interface IRGB
|
||||
{
|
||||
/**
|
||||
* Returns the red color component.
|
||||
*
|
||||
* @return The red component, in range 0..1
|
||||
*/
|
||||
float red();
|
||||
|
||||
/**
|
||||
* Returns the green color component.
|
||||
*
|
||||
* @return The green component, in range 0..1
|
||||
*/
|
||||
float green();
|
||||
|
||||
/**
|
||||
* Returns the blue color component.
|
||||
*
|
||||
* @return The blue color component, in range 0..1
|
||||
*/
|
||||
float blue();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
/**
|
||||
* An interface for single precision RGBA color objects.
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public interface IRGBA extends IRGB
|
||||
{
|
||||
/**
|
||||
* Returns the alpha color component.
|
||||
*
|
||||
* @return The alpha component, in range 0..1
|
||||
*/
|
||||
float alpha();
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
import org.apache.commons.lang3.math.NumberUtils;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class RGB implements IRGB
|
||||
{
|
||||
protected float r;
|
||||
protected float g;
|
||||
protected float b;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGB(float r, float g, float b)
|
||||
{
|
||||
this.r = r;
|
||||
this.g = g;
|
||||
this.b = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSBA toHSB()
|
||||
{
|
||||
return this.toHSBA(1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSBA toHSBA()
|
||||
{
|
||||
return this.toHSBA(1.0f);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public HSBA toHSBA(float alpha)
|
||||
{
|
||||
float brightness = NumberUtils.max(this.r, this.g, this.b);
|
||||
float min = NumberUtils.min(this.r, this.g, this.b);
|
||||
|
||||
if (brightness == 0)
|
||||
return new HSBA(0, 0, 0, alpha);
|
||||
|
||||
float chroma = brightness - min;
|
||||
|
||||
if (chroma == 0)
|
||||
return new HSBA(0, 0, brightness, alpha);
|
||||
|
||||
float saturation = chroma / brightness;
|
||||
float hue;
|
||||
|
||||
if (brightness == this.r)
|
||||
if (this.g < this.b)
|
||||
hue = (this.g - this.b) / chroma + 6;
|
||||
else
|
||||
hue = (this.g - this.b) / chroma;
|
||||
else if (brightness == this.g)
|
||||
hue = (this.b - this.r) / chroma + 2;
|
||||
else
|
||||
hue = (this.r - this.g) / chroma + 4;
|
||||
|
||||
hue *= 60;
|
||||
|
||||
return new HSBA(hue, saturation, brightness, alpha);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float red()
|
||||
{
|
||||
return this.r;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float green()
|
||||
{
|
||||
return this.g;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float blue()
|
||||
{
|
||||
return this.b;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package cz.tefek.pluto.util.color;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class RGBA extends RGB implements IRGBA
|
||||
{
|
||||
protected float a;
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public RGBA(float r, float g, float b, float a)
|
||||
{
|
||||
super(r, g, b);
|
||||
this.a = a;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public float alpha()
|
||||
{
|
||||
return this.a;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
@Override
|
||||
public HSBA toHSBA()
|
||||
{
|
||||
return this.toHSBA(this.a);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package cz.tefek.pluto.engine.shader.uniform;
|
||||
|
||||
import org.lwjgl.opengl.GL33;
|
||||
|
||||
import cz.tefek.pluto.util.color.IRGB;
|
||||
import cz.tefek.pluto.util.color.IRGBA;
|
||||
|
||||
/**
|
||||
* A uniform allowing loading RGBA color data into shader uniforms.
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class UniformRGB extends UniformBase
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of the {@link UniformRGB} uniform
|
||||
* with the specified shader location.
|
||||
*
|
||||
* @param location The location within the shader
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public UniformRGB(int location)
|
||||
{
|
||||
super(location);
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* Loads the {@link IRGB} color components into the shader uniform.
|
||||
*
|
||||
* @param value The {@link IRGB} color object
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void load(IRGB value)
|
||||
{
|
||||
GL33.glUniform3f(this.location, value.red(), value.green(), value.blue());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the RGB color components into the shader uniform.
|
||||
*
|
||||
* @param r The red color component, in range [0..1]
|
||||
* @param g The green color component, in range [0..1]
|
||||
* @param b The blue color component, in range [0..1]
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void load(float r, float g, float b)
|
||||
{
|
||||
GL33.glUniform3f(this.location, r, g, b);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package cz.tefek.pluto.engine.shader.uniform;
|
||||
|
||||
import org.lwjgl.opengl.GL33;
|
||||
|
||||
import cz.tefek.pluto.util.color.IRGBA;
|
||||
|
||||
/**
|
||||
* A uniform allowing loading RGBA color data into shader uniforms.
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public class UniformRGBA extends UniformBase
|
||||
{
|
||||
/**
|
||||
* Creates a new instance of the {@link UniformRGBA} uniform
|
||||
* with the specified shader location.
|
||||
*
|
||||
* @param location The location within the shader
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public UniformRGBA(int location)
|
||||
{
|
||||
super(location);
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the {@link IRGBA} color components into the shader uniform.
|
||||
*
|
||||
* @param value The {@link IRGBA} color object
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void load(IRGBA value)
|
||||
{
|
||||
GL33.glUniform4f(this.location, value.red(), value.green(), value.blue(), value.alpha());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the RGBA color components into the shader uniform.
|
||||
*
|
||||
* @param r The red color component, in range [0..1]
|
||||
* @param g The green color component, in range [0..1]
|
||||
* @param b The blue color component, in range [0..1]
|
||||
* @param a The alpha component, in range [0..1]
|
||||
*
|
||||
* @since 20.2.0.0-alpha.3
|
||||
* @author 493msi
|
||||
*/
|
||||
public void load(float r, float g, float b, float a)
|
||||
{
|
||||
GL33.glUniform4f(this.location, r, g, b, a);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue