Hace unos momentos me ha entrado la curiosidad y me ha dado por ver el código desensambaldo de la clase Color de XNA. Seguramente pensaréis, pues vaya tontería, seguramente tendréis razón, pero como sabéis, hay que leer código de otros para aprender. Y he aprendido a pensar dos veces ántes de crear una clase intermedia para realizar conversiones, ojo, sólo digo que hay que pensárselo dos veces, no digo que esté mal hacerlo.
Y es que esta clase usa internamente valores bytes para gestionar los valores de RGBA, cosa que me venía oliendo, y desplazamientos binarios de por medio. En concreto, el constructor que recibe parámetros enteros:
public Color(int r, int g, int b, int a)
{
if (((r | g | b | a) & -256) != 0)
{
r = Color.ClampToByte32(r);
g = Color.ClampToByte32(g);
b = Color.ClampToByte32(b);
a = Color.ClampToByte32(a);
}
g <<= 8;
b <<= 16;
a <<= 24;
this.packedValue = (uint)(r | g | b | a);
}
Vemos cómo está desplazando los valores que recibe como parámetros y luego hace la operación OR que guarda en la variable entera sin signo (un byte vamos) el resultado.
Y el Constructor con floats:
public Color(float r, float g, float b, float a)
{
this.packedValue = Color.PackHelper(r, g, b, a);
}
¿Color.PackHelper? vamos a echar un vistazo:
private static uint PackHelper(float vectorX, float vectorY, float vectorZ, float vectorW)
{
uint num = PackUtils.PackUNorm(255f, vectorX);
uint num2 = (int)PackUtils.PackUNorm(255f, vectorY) << 8;
uint num3 = (int)PackUtils.PackUNorm(255f, vectorZ) << 16;
uint num4 = (int)PackUtils.PackUNorm(255f, vectorW) << 24;
return num | num2 | num3 | num4;
}
Vaya, pues tres cuartos de lo mismo.
Juan María Laó Ramos.