Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Scavenger on Wed 11/09/2013 23:38:19

Title: Quickly Converting HSV to RGB?
Post by: Scavenger on Wed 11/09/2013 23:38:19
I'm trying to code a dynamic colour thing in AGS, so that I can change the colours of particular palette slots to emulate some neat effects. One of these is a shifting rainbow effect - going through hues smoothly and wrapping around. I would easily be able to do this kind of thing if I did it in HSV rather than RGB, as HSV has direct control over what a colour looks like, not it's light components.

Unfortunately, I'm at a bit of a loss figuring out how to do HSV to RGB at all. I'm looking at the formula to convert between the two colour systems, and I don't understand it. I've tried to convert the formula to AGSScript, but... it has syntax I'm not familiar with. Such as "C = V x SHSV". I'm not entirely sure what I'm doing.

Any suggestions for converting between colour formats?
Title: Re: Quickly Converting HSV to RGB?
Post by: Calin Leafshade on Thu 12/09/2013 00:25:22
You might find these easier to convert.

theres no weird syntax here, just normal C.

Code (c) Select

void RGBtoHSV( float r, float g, float b, float *h, float *s, float *v)
{
float min, max, delta;
min = MIN( r, g, b );
max = MAX( r, g, b );
*v = max; // v
delta = max - min;
if( max != 0 )
*s = delta / max; // s
else {
// r = g = b = 0 // s = 0, v is undefined
*s = 0;
*h = -1;
return;
}
if( r == max )
*h = ( g - b ) / delta; // between yellow & magenta
else if( g == max )
*h = 2 + ( b - r ) / delta; // between cyan & yellow
else
*h = 4 + ( r - g ) / delta; // between magenta & cyan
*h *= 60; // degrees
if( *h < 0 )
*h += 360;
}
void HSVtoRGB( float *r, float *g, float *b, float h, float s, float v )
{
int i;
float f, p, q, t;
if( s == 0 ) {
// achromatic (grey)
*r = *g = *b = v;
return;
}
h /= 60; // sector 0 to 5
i = floor( h );
f = h - i; // factorial part of h
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i ) {
case 0:
*r = v;
*g = t;
*b = p;
break;
case 1:
*r = q;
*g = v;
*b = p;
break;
case 2:
*r = p;
*g = v;
*b = t;
break;
case 3:
*r = p;
*g = q;
*b = v;
break;
case 4:
*r = t;
*g = p;
*b = v;
break;
default: // case 5:
*r = v;
*g = p;
*b = q;
break;
}
}
Title: Re: Quickly Converting HSV to RGB?
Post by: Khris on Thu 12/09/2013 00:36:54
Try this:
Code (ags) Select
int GetColorFromHSV(int hue, float sat, float val) {
  float c = sat * val;
  float h1 = IntToFloat(hue)/60.0;
  float h2 = h1;
  while (h2 >= 2.0) h2 -= 2.0;
  float bet = h2 - 1.0;
  if (bet < 0.0) bet = -bet;
  float x = c * (1.0 - bet);
  float rr[6], gg[6], bb[6];
  rr[0] = c; rr[1] = x;                       rr[4] = x; rr[5] = c;
  gg[0] = x; gg[1] = c; gg[2] = c; gg[3] = x;
                        bb[2] = x; bb[3] = c; bb[4] = c; bb[5] = x;
  float r1 = rr[FloatToInt(h1)];
  float g1 = gg[FloatToInt(h1)];
  float b1 = bb[FloatToInt(h1)];
  float m = val - c;
  r1 = (r1 + m) * 256.0;
  g1 = (g1 + m) * 256.0;
  b1 = (b1 + m) * 256.0;
  //Display("%f, %f, %f", r1, g1, b1);
  int r = FloatToInt(r1, eRoundNearest) % 256;
  int g = FloatToInt(g1, eRoundNearest) % 256;
  int b = FloatToInt(b1, eRoundNearest) % 256;
  return Game.GetColorFromRGB(r, g, b);
}


Here's an example shot:
[imgzoom]http://i.imgur.com/VpA5eTz.png[/imgzoom]

Top is saturation 0.8, value ranging from 1.0 (top) to 0.0 (bottom)
Bottom is value = 0.9, saturation ranging from 1.0 (top) to 0.0 (bottom)