package dwarf.gfx; import dwarf.util.Vector3; /** * A simple wrapper round the values required for a mutable colour class. * * @author Matthew 'siD' Van der Bijl * * @see java.lang.Object * @see java.lang.Cloneable * @see dwarf.gfx.Colours */ @SuppressWarnings("serial") public class Colour extends java.lang.Object implements Cloneable, Colours { /** * the colour the colour to be inputed. In the default sRGB space. * * @param colour the colour to be inputed */ public static void setColour(Colour colour) { Colour.setColour(colour.getRed(), colour.getGreen(), colour.getBlue(), colour.getAlpha()); } /** * @param colour (RBG) */ public static void setColour(dwarf.util.Vector3 colour) { Colour.setColour(new Colour(colour.getX(), colour.getY(), colour.getZ(), 1)); } /** * @param red the red component of the colour * @param green the green component of the colour * @param blue the blue component of the colour */ public static void setColour(double red, double green, double blue) { Colour.setColour(red, green, blue, 1); } public static void setColour(java.awt.Color colour) { Colour.setColour(colour.getRed(), colour.getGreen(), colour.getBlue(), colour.getAlpha()); } /** * @param red the red component of the colour * @param green the green component of the colour * @param blue the blue component of the colour * @param alpha the alpha component of the colour */ public static void setColour(double red, double green, double blue, float alpha) { org.lwjgl.opengl.GL11.glColor4d(red, green, blue, alpha); } /** * the red component of the colour. */ private double red; /** * the green component of the colour. */ private double green; /** * the blue component of the colour. */ private double blue; /** * the alpha value of the colour. */ private float alpha; /** * Default constructor. */ public Colour() { this(0, 0, 0, 1); } public Colour(Colour colour) { this(colour.getRed(), colour.getGreen(), colour.getBlue(), colour.getAlpha()); } public Colour(dwarf.util.Vector3 colour) { this(colour.getX(), colour.getY(), colour.getZ()); } public Colour(Vector3 colour, float alpha) { this(colour.getX(), colour.getY(), colour.getZ(), alpha); } public Colour(double red, double green, double blue) { this(red, green, blue, 1); } public Colour(double red, double green, double blue, float alpha) { super(); this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } public Colour(java.awt.Color colour) { this(colour.getRed(), colour.getGreen(), colour.getBlue(), colour.getAlpha()); } /** * Create a colour from an evil integer packed 0xAARRGGBB. If AA is * specified as zero then it will be interpreted as unspecified and hence a * value of 255 will be recorded. * * @param value The value to interpret for the colour */ public Colour(int value) { this.red = (((value & 0x00FF0000) >> 0x10) / 255.0f); this.green = (((value & 0x0000FF00) >> 0x8) / 255.0f); this.blue = ((value & 0x000000FF) / 255.0f); this.alpha = ((value & 0xFF000000) >> 0x18) / 255.0f; if (alpha < 0) { alpha += 0x100; } if (alpha == 0) { alpha = 0xff; } } /** * Decode a number in a string and process it as a colour reference. * * @param nm The number string to decode * @return The color generated from the number read */ public static Colour decode(String nm) { return new Colour(Integer.decode(nm)); } /** * Bind this colour to the GL context. */ public void bind() { org.lwjgl.opengl.GL11.glColor4d(red, green, blue, alpha); } /** * Returns a string representation of the object. * <p> * In general, the toString method returns a string that "textually * represents" this object. The result should be a concise but informative * representation that is easy for a person to read. It is recommended that * all subclasses override this method.</p> * * @return a textually representation of this object */ @Override public String toString() { return "Colour[" + getRed() + ", " + getGreen() + ", " + getBlue() + ", " + getAlpha() + "]"; } public Colour get() { return this; } /** * Make a brighter instance of this colour. * * @return returns a brighter colour */ public Colour brighter() { return brighter(0.2f); } public double getRedByte() { return this.red * 0xff; } public double getGreenByte() { return this.green * 0xff; } public double getBlueByte() { return this.blue * 0xff; } public float getAlphaByte() { return this.alpha * 0xff; } /** * Make a brighter instance of this colour. * * @param scale what the colour is to be scaled by * @return a scales up colour */ public Colour brighter(double scale) { return new Colour(this.getRed() * scale + 1, this.getGreen() * scale + 1, this.getBlue() * scale + 1, this.getAlpha()); } /** * Scale the components of the colour by the given value. * * @param value The value to scale by */ public void scale(float value) { this.red = (this.getRed() * value); this.green = (this.getGreen() * value); this.blue = (this.getBlue() * value); this.alpha *= value; } public void setRed(float r) { this.red = r; } public void setGreen(float g) { this.green = g; } public void setBlue(float b) { this.blue = b; } public void setAlpha(float a) { this.alpha = a; } public double getRed() { return this.red; } public double getGreen() { return this.green; } public double getBlue() { return this.blue; } public float getAlpha() { return this.alpha; } public void realse() { org.lwjgl.opengl.GL11.glColor4d(0xff, 0xff, 0xff, 1); } /** * Returns true if the <code>this</code> is equal to the argument and false * otherwise. Consequently, if both argument are null, true is returned, * false is returned. Otherwise, equality is determined by using the equals * method of the first argument. * * @param obj the <code>Object</code> to be tested * @see java.lang.Object#equals(java.lang.Object) * * @return true if the argument is equal to <code>this</code> other and * false otherwise */ @Override public boolean equals(Object obj) { return (obj != null) && (obj instanceof Colour) && (((Colour) obj).getRed() == this.getRed()) && (((Colour) obj).getGreen() == this.getGreen()) && (((Colour) obj).getBlue() == this.getBlue()) && (((Colour) obj).getAlpha() == this.getAlpha()); } /** * Class Object is the root of the class hierarchy. Every class has Object * as a superclass. All objects, including arrays, implement the methods of * this class. * * @return a hash code value for this object. * @see java.lang.Object#equals(java.lang.Object) */ @Override public int hashCode() { int hash = 5; hash = (int) (79 * hash + this.red); hash = (int) (79 * hash + this.green); hash = (int) (79 * hash + this.blue); hash = 79 * hash + Float.floatToIntBits(this.alpha); return hash; } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readABGR(java.nio.ByteBuffer src) { this.setAlpha(src.get()); this.setBlue(src.get()); this.setGreen(src.get()); this.setRed(src.get()); } public void writeRGBA(java.nio.ByteBuffer dest) { dest.put((byte) this.getRed()); dest.put((byte) this.getGreen()); dest.put((byte) this.getBlue()); dest.put((byte) this.getAlpha()); } public void writeRGB(java.nio.ByteBuffer dest) { dest.put((byte) this.getRed()); dest.put((byte) this.getGreen()); dest.put((byte) this.getBlue()); } public void writeABGR(java.nio.ByteBuffer dest) { dest.put((byte) this.getAlpha()); dest.put((byte) this.getBlue()); dest.put((byte) this.getGreen()); dest.put((byte) this.getRed()); } public void writeARGB(java.nio.ByteBuffer dest) { dest.put((byte) this.getAlpha()); dest.put((byte) this.getRed()); dest.put((byte) this.getGreen()); dest.put((byte) this.getBlue()); } public void writeBGR(java.nio.ByteBuffer dest) { dest.put((byte) this.getBlue()); dest.put((byte) this.getGreen()); dest.put((byte) this.getRed()); } public void writeBGRA(java.nio.ByteBuffer dest) { dest.put((byte) this.getBlue()); dest.put((byte) this.getGreen()); dest.put((byte) this.getRed()); dest.put((byte) this.getAlpha()); } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readRGBA(java.nio.ByteBuffer src) { this.setRed(src.get()); this.setGreen(src.get()); this.setBlue(src.get()); this.setAlpha(src.get()); } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readRGB(java.nio.ByteBuffer src) { this.setRed(src.get()); this.setGreen(src.get()); this.setBlue(src.get()); } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readARGB(java.nio.ByteBuffer src) { this.setAlpha(src.get()); this.setRed(src.get()); this.setGreen(src.get()); this.setBlue(src.get()); } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readBGRA(java.nio.ByteBuffer src) { this.setBlue(src.get()); this.setGreen(src.get()); this.setRed(src.get()); this.setAlpha(src.get()); } /** * Read a color from a byte buffer * * @param src The source buffer */ public void readBGR(java.nio.ByteBuffer src) { this.setBlue(src.get()); this.setGreen(src.get()); this.setRed(src.get()); } /** * RGB to HSB conversion, pinched from java.awt.Colour. The HSB value is * returned in dest[] if dest[] is supplied. Values range from 0..1 * * @param dest Destination floats, or null * @return dest, or a new float array */ public double[] toHSB(double dest[]) { double r = getRed(); double g = getGreen(); double b = getBlue(); if (dest == null) { dest = new double[3]; } double l = r <= g ? g : r; if (b > l) { l = b; } double i1 = r >= g ? g : r; if (b < i1) { i1 = b; } double brightness = l / 255F; double saturation; if (l != 0) { saturation = (l - i1) / l; } else { saturation = 0.0F; } double hue; if (saturation == 0.0F) { hue = 0.0F; } else { double f3 = (l - r) / (l - i1); double f4 = (l - g) / (l - i1); double f5 = (l - b) / (l - i1); if (r == l) { hue = f5 - f4; } else if (g == l) { hue = (2.0F + f3) - f5; } else { hue = (4F + f4) - f3; } hue /= 6F; if (hue < 0.0F) { hue++; } } dest[0] = hue; dest[1] = saturation; dest[2] = brightness; return dest; } /** * HSB to RGB conversion, pinched from java.awt.Colour. * * @see java.awt.Color * * @param hue (0..1.0f) * @param saturation (0..1.0f) * @param brightness (0..1.0f) */ public void fromHSB(float hue, float saturation, float brightness) { if (saturation == 0.0F) { this.setRed(brightness * 255F + 0.5F); this.setGreen(brightness * 255F + 0.5F); this.setBlue((brightness * 255F + 0.5F)); } else { float f3 = (hue - (float) Math.floor(hue)) * 6F; float f4 = f3 - (float) Math.floor(f3); float f5 = brightness * (1.0F - saturation); float f6 = brightness * (1.0F - saturation * f4); float f7 = brightness * (1.0F - saturation * (1.0F - f4)); switch ((int) f3) { case 0: this.setRed(brightness * 255F + 0.5F); this.setGreen(f7 * 255F + 0.5F); this.setBlue(f5 * 255F + 0.5F); break; case 1: this.setRed((f6 * 255F + 0.5F)); this.setGreen(brightness * 255F + 0.5F); this.setBlue(f5 * 255F + 0.5F); break; case 2: this.setRed(f5 * 255F + 0.5F); this.setGreen(brightness * 255F + 0.5F); this.setBlue(f7 * 255F + 0.5F); break; case 3: this.setRed(f5 * 255F + 0.5F); this.setGreen(f6 * 255F + 0.5F); this.setBlue(brightness * 255F + 0.5F); break; case 4: this.setRed(f7 * 255F + 0.5F); this.setGreen(f5 * 255F + 0.5F); this.setBlue(brightness * 255F + 0.5F); break; case 5: this.setRed(brightness * 255F + 0.5F); this.setGreen(f5 * 255F + 0.5F); this.setBlue(f6 * 255F + 0.5F); break; } } } @Override public Colour clone() throws CloneNotSupportedException { return new Colour(this); } public dwarf.util.Vector3 toVector3() { return new dwarf.util.Vector3( this.getRed(), this.getGreen(), this.getBlue() ); } public void set(Colour colour) { this.red = colour.getRed(); this.green = colour.getGreen(); this.blue = colour.getBlue(); this.alpha = colour.getAlpha(); } public void set(dwarf.util.Vector3 colour) { this.red = colour.getX(); this.green = colour.getY(); this.blue = colour.getZ(); } public void set(dwarf.util.Vector3 colour, float alpha) { this.red = colour.getX(); this.green = colour.getY(); this.blue = colour.getZ(); this.alpha = alpha; } public void set(float red, float green, float blue) { this.red = red; this.green = green; this.blue = blue; this.alpha = 1; } public void set(float red, float green, float blue, float alpha) { this.red = red; this.green = green; this.blue = blue; this.alpha = alpha; } public void set(java.awt.Color colour) { this.red = colour.getRed(); this.green = colour.getGreen(); this.blue = colour.getBlue(); this.alpha = colour.getAlpha(); } public java.awt.Color toColor() { return new java.awt.Color((float) red, (float) green, (float) blue, alpha); } }