View Javadoc
1   package org.newdawn.slick;
2   
3   import java.io.Serializable;
4   import java.nio.FloatBuffer;
5   
6   import org.newdawn.slick.opengl.renderer.Renderer;
7   import org.newdawn.slick.opengl.renderer.SGL;
8   
9   import javax.annotation.Nonnull;
10  
11  /**
12   * A simple wrapper round the values required for a colour
13   * 
14   * @author Kevin Glass
15   */
16  public class Color implements Serializable {
17      /** The version ID for this class  */
18      private static final long serialVersionUID = 1393939L;
19  
20      /** The renderer to use for all GL operations */
21      private final transient SGL GL = Renderer.get();
22  
23      /** The fixed color transparent */
24      public static final Color transparent = new Color(0.0f,0.0f,0.0f,0.0f);
25      /** The fixed colour white */
26      public static final Color white = new Color(1.0f,1.0f,1.0f,1.0f);
27      /** The fixed colour yellow */
28      public static final Color yellow = new Color(1.0f,1.0f,0,1.0f);
29      /** The fixed colour red */
30      public static final Color red = new Color(1.0f,0,0,1.0f);
31      /** The fixed colour blue */
32      public static final Color blue = new Color(0,0,1.0f,1.0f);
33      /** The fixed colour green */
34      public static final Color green = new Color(0,1.0f,0,1.0f);
35      /** The fixed colour black */
36      public static final Color black = new Color(0,0,0,1.0f);
37      /** The fixed colour gray */
38      public static final Color gray = new Color(0.5f,0.5f,0.5f,1.0f);
39      /** The fixed colour cyan */
40      public static final Color cyan = new Color(0,1.0f,1.0f,1.0f);
41      /** The fixed colour dark gray */
42      public static final Color darkGray = new Color(0.3f,0.3f,0.3f,1.0f);
43      /** The fixed colour light gray */
44      public static final Color lightGray = new Color(0.7f,0.7f,0.7f,1.0f);
45      /** The fixed colour dark pink */
46      public final static Color pink      = new Color(255, 175, 175, 255);
47      /** The fixed colour dark orange */
48      public final static Color orange     = new Color(255, 200, 0, 255);
49      /** The fixed colour dark magenta */
50      public final static Color magenta    = new Color(255, 0, 255, 255);
51      
52      /** The red component of the colour */
53      public float r;
54      /** The green component of the colour */
55      public float g;
56      /** The blue component of the colour */
57      public float b;
58      /** The alpha component of the colour */
59      public float a = 1.0f;
60  
61      /**
62       * Copy constructor
63       *
64       * @param color The color to copy into the new instance
65       */
66      public Color(@Nonnull Color color) {
67          r = color.r;
68          g = color.g;
69          b = color.b;
70          a = color.a;
71      }
72  
73      /**
74       * Create a component based on the first 4 elements of a float buffer
75       *
76       * @param buffer The buffer to read the color from
77       */
78      public Color(@Nonnull FloatBuffer buffer) {
79          this.r = buffer.get();
80          this.g = buffer.get();
81          this.b = buffer.get();
82          this.a = buffer.get();
83      }
84  
85      /**
86       * Create a 3 component colour
87       *
88       * @param r The red component of the colour (0.0 -> 1.0)
89       * @param g The green component of the colour (0.0 -> 1.0)
90       * @param b The blue component of the colour (0.0 -> 1.0)
91       */
92      public Color(float r,float g,float b) {
93          this.r = r;
94          this.g = g;
95          this.b = b;
96          this.a = 1;
97      }
98  
99      /**
100      * Create a 4 component colour
101      *
102      * @param r The red component of the colour (0.0 -> 1.0)
103      * @param g The green component of the colour (0.0 -> 1.0)
104      * @param b The blue component of the colour (0.0 -> 1.0)
105      * @param a The alpha component of the colour (0.0 -> 1.0)
106      */
107     public Color(float r,float g,float b,float a) {
108         this.r = Math.min(r, 1);
109         this.g = Math.min(g, 1);
110         this.b = Math.min(b, 1);
111         this.a = Math.min(a, 1);
112     }
113 
114     /**
115      * Create a 3 component colour
116      *
117      * @param r The red component of the colour (0 -> 255)
118      * @param g The green component of the colour (0 -> 255)
119      * @param b The blue component of the colour (0 -> 255)
120      */
121     public Color(int r,int g,int b) {
122         this.r = r / 255.0f;
123         this.g = g / 255.0f;
124         this.b = b / 255.0f;
125         this.a = 1;
126     }
127 
128     /**
129      * Create a 4 component colour
130      *
131      * @param r The red component of the colour (0 -> 255)
132      * @param g The green component of the colour (0 -> 255)
133      * @param b The blue component of the colour (0 -> 255)
134      * @param a The alpha component of the colour (0 -> 255)
135      */
136     public Color(int r,int g,int b,int a) {
137         this.r = r / 255.0f;
138         this.g = g / 255.0f;
139         this.b = b / 255.0f;
140         this.a = a / 255.0f;
141     }
142 
143     /**
144      * Create a colour from an evil integer packed 0xAARRGGBB. If AA
145      * is specified as zero then it will be interpreted as unspecified
146      * and hence a value of 255 will be recorded.
147      *
148      * @param value The value to interpret for the colour
149      */
150     private Color(int value) {
151         int r = (value & 0x00FF0000) >> 16;
152         int g = (value & 0x0000FF00) >> 8;
153         int b =    (value & 0x000000FF);
154         int a = (value & 0xFF000000) >> 24;
155 
156         if (a < 0) {
157             a += 256;
158         }
159         if (a == 0) {
160             a = 255;
161         }
162 
163         this.r = r / 255.0f;
164         this.g = g / 255.0f;
165         this.b = b / 255.0f;
166         this.a = a / 255.0f;
167     }
168 
169     /**
170      * Decode a number in a string and process it as a colour
171      * reference.
172      *
173      * @param nm The number string to decode
174      * @return The color generated from the number read
175      */
176     @Nonnull
177     public static Color decode(String nm) {
178         return new Color(Integer.decode(nm));
179     }
180 
181     /**
182      * Bind this colour to the GL context
183      */
184     public void bind() {
185         GL.glColor4f(r,g,b,a);
186     }
187 
188     /**
189      * @see java.lang.Object#hashCode()
190      */
191     public int hashCode() {
192         return ((int) (r+g+b+a)*255);
193     }
194 
195     /**
196      * @see java.lang.Object#equals(java.lang.Object)
197      */
198     public boolean equals(Object other) {
199         if (other instanceof Color) {
200             Color o = (Color) other;
201             return ((o.r == r) && (o.g == g) && (o.b == b) && (o.a == a));
202         }
203 
204         return false;
205     }
206 
207     /**
208      * @see java.lang.Object#toString()
209      */
210     @Nonnull
211     public String toString() {
212         return "Color ("+r+","+g+","+b+","+a+")";
213     }
214 
215     /**
216      * Make a darker instance of this colour
217      *
218      * @return The darker version of this colour
219      */
220     @Nonnull
221     public Color darker() {
222         return darker(0.5f);
223     }
224 
225     /**
226      * Make a darker instance of this colour
227      *
228      * @param scale The scale down of RGB (i.e. if you supply 0.03 the colour will be darkened by 3%)
229      * @return The darker version of this colour
230      */
231     @Nonnull Color darker(float scale) {
232         scale = 1 - scale;
233         Color temp = new Color(r * scale,g * scale,b * scale,a);
234 
235         return temp;
236     }
237 
238     /**
239      * Make a brighter instance of this colour
240      *
241      * @return The brighter version of this colour
242      */
243     @Nonnull
244     public Color brighter() {
245         return brighter(0.2f);
246     }
247 
248     /**
249      * Get the red byte component of this colour
250      *
251      * @return The red component (range 0-255)
252      */
253     public int getRed() {
254         return (int) (r * 255);
255     }
256 
257     /**
258      * Get the green byte component of this colour
259      *
260      * @return The green component (range 0-255)
261      */
262     public int getGreen() {
263         return (int) (g * 255);
264     }
265 
266     /**
267      * Get the blue byte component of this colour
268      *
269      * @return The blue component (range 0-255)
270      */
271     public int getBlue() {
272         return (int) (b * 255);
273     }
274 
275     /**
276      * Get the alpha byte component of this colour
277      *
278      * @return The alpha component (range 0-255)
279      */
280     public int getAlpha() {
281         return (int) (a * 255);
282     }
283 
284     /**
285      * Get the red byte component of this colour
286      *
287      * @return The red component (range 0-255)
288      */
289     public int getRedByte() {
290         return (int) (r * 255);
291     }
292 
293     /**
294      * Get the green byte component of this colour
295      *
296      * @return The green component (range 0-255)
297      */
298     public int getGreenByte() {
299         return (int) (g * 255);
300     }
301 
302     /**
303      * Get the blue byte component of this colour
304      *
305      * @return The blue component (range 0-255)
306      */
307     public int getBlueByte() {
308         return (int) (b * 255);
309     }
310 
311     /**
312      * Get the alpha byte component of this colour
313      *
314      * @return The alpha component (range 0-255)
315      */
316     public int getAlphaByte() {
317         return (int) (a * 255);
318     }
319 
320     /**
321      * Make a brighter instance of this colour
322      *
323      * @param scale The scale up of RGB (i.e. iy 0.03 the colour will be brightened by 3%)
324      * @return The brighter version of this colour
325      */
326     @Nonnull
327     Color brighter(float scale) {
328         scale += 1;
329         Color temp = new Color(r * scale,g * scale,b * scale,a);
330 
331         return temp;
332     }
333 
334     /**
335      * Multiply this color by another
336      *
337      * @param c the other color
338      * @return product of the two colors
339      */
340     @Nonnull
341     public Color multiply(@Nonnull Color c) {
342         return new Color(r * c.r, g * c.g, b * c.b, a * c.a);
343     }
344 
345     /**
346      * Add another colour to this one
347      *
348      * @param c The colour to add
349      */
350     public void add(@Nonnull Color c) {
351         r += c.r;
352         g += c.g;
353         b += c.b;
354         a += c.a;
355     }
356 
357     /**
358      * Scale the components of the colour by the given value
359      *
360      * @param value The value to scale by
361      */
362     public void scale(float value) {
363         r *= value;
364         g *= value;
365         b *= value;
366         a *= value;
367     }
368 
369     /**
370      * Add another colour to this one
371      *
372      * @param c The colour to add
373      * @return The copy which has had the color added to it
374      */
375     @Nonnull
376     public Color addToCopy(@Nonnull Color c) {
377         Color copy = new Color(r,g,b,a);
378         copy.r += c.r;
379         copy.g += c.g;
380         copy.b += c.b;
381         copy.a += c.a;
382 
383         return copy;
384     }
385 
386     /**
387      * Scale the components of the colour by the given value
388      *
389      * @param value The value to scale by
390      * @return The copy which has been scaled
391      */
392     @Nonnull
393     public Color scaleCopy(float value) {
394         Color copy = new Color(r,g,b,a);
395         copy.r *= value;
396         copy.g *= value;
397         copy.b *= value;
398         copy.a *= value;
399 
400         return copy;
401     }
402 }