• Sábado 11 de Mayo de 2024, 17:19

Autor Tema:  Color De Mascara  (Leído 3126 veces)

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Color De Mascara
« en: Lunes 11 de Octubre de 2004, 04:43 »
0
saludo...
se me ha presentasdo un inconveniente..
he diseñado en directx unas librerias para soportar sprites con un color de mascara
R=255 G=0 B=255
adicionalmente las librerias soportan cualquier color de mascara segun se pase un parametro en el constructor del personaje, es decir cualquier color de mascara funciona OK.
Adicionalmente tambien soportan un rango de color desde que este sea pasado como un rango de enteros de 32 bit.

Hasta aca todo esta OK, esto siempre y cuando se utilice modo de color 32 o de 24 bit, pro al inicialzar el modo de color de 16 bit ninguno de los colores de mascara surten efecto...

No se porque sucede esto, ya que la mascara la establezco con el colorkey que posee directX, es decir no uso nada del otro mundo...

Cuando mire detenidamente me di cuenta que en modo de 16 bit asume como mascara el color negro unicamente o por lo menos eso es lo que parece, la pregunta es si alguno de ustedes sabe como puedo establecer mi propio color de mascara en modo de 16 bit.

Esto solo falla cuando se establece el modo de pantalla completa ya que en el modo ventana todo funciona segun lo previsto.

agradezco cualquier comentario.

Anexo ejemplo de lo que sucede.
El mensaje contiene 1 archivo adjunto. Debes ingresar o registrarte para poder verlo y descargarlo.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Amilius

  • Miembro HIPER activo
  • ****
  • Mensajes: 665
    • Ver Perfil
Re: Color De Mascara
« Respuesta #1 en: Lunes 11 de Octubre de 2004, 06:11 »
0
Saludos al foro!!

Y que tal provando con el color Magenta directamente como su valor entero y no como triada RGB:

$3E0F (15 bits.)

$F81F (16 bits.)

$FF00FF (24 bits)

$00FF00FF (32 bits)

El color negro siempre funciona por que obviamente el R:0,G:0,B:0 que es el negro siempre es 0 en 15,16,24,32 bits.

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #2 en: Lunes 11 de Octubre de 2004, 07:26 »
0
:D  De hecho con los valores enteros si funciona, de eso me he dado cuenta ya hace unas horas  B)
En todo caso mil gracias amilus...
Ahora el problema realmente radica en que ya tengo hechas las funciones que me aceptan usar las diferentes sobrecargas del constructor de pesonajes para usar cualquier color de mascara o cualquier rango de colores de mascara, o el color que siempre he usado por defecto (Magenta)... pero no funcionan con 16 bits ...

pero ya lo solucione!!  :ph34r:

Codigo de las clase que carga los personajes desde achivos:
Código: Text
  1.  
  2.  
  3.       if(gc.ProfColor == 16 && gc.EstadoVideo ==EnEstadoVideo.PantallaCompleta)
  4.       {
  5.         ck.ColorSpaceLowValue = gc.ConvierteA16Bit(ccb);
  6.         ck.ColorSpaceHighValue = gc.ConvierteA16Bit(cca);
  7.       }
  8.       else
  9.       {
  10.         ck.ColorSpaceLowValue = ccb;
  11.         ck.ColorSpaceHighValue = cca;
  12.       }
  13.  
  14.  

Codigo del administrador grafico:
Código: Text
  1.  
  2.     public UInt16 ConvierteA16Bit(Int32 color)
  3.         {
  4.       byte uno, dos, tres;
  5.       ushort ret;
  6.       byte p1, p2;
  7.  
  8.       uno = (byte)(color & 0x000000FF);
  9.       dos = (byte)((color & 0x0000FF00)>>8);
  10.       tres= (byte)((color & 0x00FF0000)>>16);
  11.  
  12.       uno= (byte)(0x1F*uno/0xFF);
  13.       tres=(byte)(0x1F*tres/0xFF);
  14.       dos= (byte)(0x3F*dos/0xFF);
  15.  
  16.       p1 = uno;
  17.       p1 = (byte)(p1&((dos <<5)|0xFF));
  18.  
  19.       p2 = (byte)(dos>>3);
  20.       p2 = (byte)(p2|(tres<<3));
  21.  
  22.       ret =p1&#59;
  23.       ret =(ushort)(ret|(p2<<8));
  24.      
  25.       return ret;
  26.     }
  27.  

Ahora ya ha quedado solucionado ;)

Sin embargo pues la verdad no soy muy bueno con la eficiencia en los algoritmos de bajo nivel, asi que me tomo el atrevimiento de ahora pedir ayuda para hacer mas eficiente la funcion de conversion de colores, no es que tenga problemas, de hecho como solo se usa cuando se establece el colorKey, es decir en los cambios de modo de  pantalla y al inicializar  no es muy importante y nunca se notaria las fallas de rendimiento.. pero estoy totalmente seguro de que se puede hacer de una manera mucho mas eficiente, y pues la verdad no tengo mucho tiempo para dedicarle a ese tipo de cosas (aunque son muy importantes),
nuevamente agradezco cualquier colaboracion.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Color De Mascara
« Respuesta #3 en: Lunes 11 de Octubre de 2004, 13:16 »
0
Hola.

La manera más óptima que se me ocurre de pasar de 32 bits a 16 es:
Código: Text
  1.     public UInt16 ConvierteA16Bit(Int32 color)
  2.     {
  3.       return (ushort) ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | (color >> 3) );
  4.     }
  5.  

Intuitivamente debería de funcionar. Primero desplazo los bits más significativos a la posición que deberían ocupar si fuese de 16 bits, después elimino los menos significativos que no quiero, y después lo recompongo todo.

Ya me dirás si funciona (espero que sí :blink: ).

Un saludo.

Ruben3d

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #4 en: Martes 12 de Octubre de 2004, 14:30 »
0
;)
Hola ruben3D,

Gracias.


Arrojo el error que anexo.

En todo caso revisare muy bien tu propuesta para ver si puedo hacerla funcionar.
El mensaje contiene 1 archivo adjunto. Debes ingresar o registrarte para poder verlo y descargarlo.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Amilius

  • Miembro HIPER activo
  • ****
  • Mensajes: 665
    • Ver Perfil
Re: Color De Mascara
« Respuesta #5 en: Martes 12 de Octubre de 2004, 15:40 »
0
Creo que el problema es este:

(ushort)  ;)

Código: Text
  1.  
  2. public Int32 ConvertirA16Bit(Int32 color)
  3.    {
  4.      return (Int32) ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | ((color >> 3) & 0x001F) );
  5.    }
  6.  
  7.  

Una cosa más... esto depende de la forma de especificar el color en 24 o 32 bits... pero ¿No se intercambian el color rojo por el azul?

Editado: Faltaba la última máscara.  :rolleyes:

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Color De Mascara
« Respuesta #6 en: Martes 12 de Octubre de 2004, 16:40 »
0
Citar
Creo que el problema es este:

(ushort) 
Pudiera ser. En C++ así debería de funcionar (con sus tipos equivalentes) y el cast desecharía los bits más significativos y se quedaría con los menos: el color en 16 bits. En C# no sé cómo hacer eso.

Citar
esto depende de la forma de especificar el color en 24 o 32 bits... pero ¿No se intercambian el color rojo por el azul?

Yo asumo que la entrada en un color de 32 bits es AARRGGBB y en uno de 24 es 00RRGGBB. Así, funciona para los dos casos. De todas formas, en algunos sitios ésto cambia. Por ejemplo, en los TGA se guarda el color en formato BGR en vez de RGB. Si la entrada es diferente, ya es cosa de JuanK adaptarla :D

Un saludo.

Ruben3d

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #7 en: Miércoles 13 de Octubre de 2004, 06:04 »
0
Citar
public Int32 ConvertirA16Bit(Int32 color)
  {
    return (Int32) ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | (color >> 3) );
  }


Mas o menos,  con eso se corrige el problema pero se corrige mal ya que el problema se genera porque se el valor resultante ocupa mas de 16 bits, asi que colorcar la funcion como tipo Int32 esconde el problema pero no lo soluciona.

el objetivo de la funcion es generar color de 16 bits asi que no deberia generarce nunca mas de 16 bit.

Citar
Yo asumo que la entrada en un color de 32 bits es AARRGGBB y en uno de 24 es 00RRGGBB. Así, funciona para los dos casos. De todas formas, en algunos sitios ésto cambia. Por ejemplo, en los TGA se guarda el color en formato BGR en vez de RGB. Si la entrada es diferente, ya es cosa de JuanK adaptarla

Asi es , los datos no se estan leyendo del archivo sino directo de la memoria y por lo menos en lo que he visto en memoria de video todos son mapas de bits y el formato es como dice Ruben3D.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #8 en: Miércoles 13 de Octubre de 2004, 08:39 »
0
saludos
yo habia mejorado a esto:
Código: Text
  1.  
  2.     public UInt16 ConvierteA16Bit(Int32 color)
  3.         {
  4.       byte uno, dos, tres;
  5.  
  6.       /* Separar las componentes de byte
  7.        * para poder posteriormente calcular la proporcion
  8.        * independiente por cada componente de color.*/
  9.       uno = (byte)(color & 0x000000FF);
  10.       dos = (byte)((color & 0x0000FF00)>>8);
  11.       tres= (byte)((color & 0x00FF0000)>>16);
  12.  
  13.       /* Calcular proporciones por regla de tres
  14.        * es decir ej.:
  15.        *  valor byte        max valor
  16.        *     uno               255 (0xFF, es decir maximo 8 bits prendidos)
  17.        *      ?                 31 (0x1F, es decir maximo 5 bits prendidos)
  18.        *  
  19.        *  ? = uno * 31 /255 => ? = (0x1F*uno/0xFF)
  20.        * */
  21.       uno= (byte)(0x1F*uno/0xFF);
  22.       tres=(byte)(0x1F*tres/0xFF);
  23.       dos= (byte)(0x3F*dos/0xFF);
  24.  
  25.       return (ushort)(  (uno|(dos <<5)) |
  26.                       ( (tres<<3 | dos>>3 ) ) <<8 );
  27.     }
  28.  

Pero no sabia como optimizar lo de las proporciones, en otro foro me dieron una solucion pero no entiendo muy bien la logica para llegar a ello, lo importante es que funciona.
Les pido ayuda por favor para ver si puedo entender mejor como se calcula lo de las proporciones utilizando  & y corrimientos en vez de multiplicacion y division?

aca esta como me quedo la adaptacion:
Código: Text
  1.  
  2.     public UInt16 ConvierteA16Bit(Int32 color)
  3.         {
  4.       byte uno, dos, tres;
  5.  
  6.       /* Separar las componentes de byte
  7.        * para poder posteriormente calcular la proporcion
  8.        * independiente por cada componente de color.*/
  9.       uno = (byte)(color & 0x000000FF);
  10.       dos = (byte)((color & 0x0000FF00)>>8);
  11.       tres= (byte)((color & 0x00FF0000)>>16);
  12.       return ( (ushort)( (((uno >> 3) & 0x1F) << 11) | (((dos >> 2) & 0x3F) << 5) | (((tres >> 3) & 0x1F) << 0) ) );
  13.     }
  14.  
  15.  
  16.  
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

Ruben3d

  • Miembro HIPER activo
  • ****
  • Mensajes: 710
  • Nacionalidad: es
    • Ver Perfil
    • Web personal
Re: Color De Mascara
« Respuesta #9 en: Miércoles 13 de Octubre de 2004, 16:47 »
0
Citar
Código: Text
  1.     public UInt16 ConvierteA16Bit(Int32 color)
  2.        {
  3.       byte uno, dos, tres;
  4.  
  5.       /* Separar las componentes de byte
  6.        * para poder posteriormente calcular la proporcion
  7.        * independiente por cada componente de color.*/
  8.       uno = (byte)(color & 0x000000FF);
  9.       dos = (byte)((color & 0x0000FF00)>>8);
  10.       tres= (byte)((color & 0x00FF0000)>>16);
  11.       return ( (ushort)( (((uno >> 3) & 0x1F) << 11) | (((dos >> 2) & 0x3F) << 5) | (((tres >> 3) & 0x1F) << 0) ) );
  12.     }
  13.  

La verdad, no sé cómo funciona :P

uno, dos y tres guardan, respectivamente, las componentes azul, verde y roja, gracias a la máscara y al desplazamiento.

Llegados al return, el primer desplazamiento de bits se usa para rebajar su tamaño de 8 bits cada una a 5, 6 y 5 respectivamente.

A continuación aplica una máscara que me parece innecesaria, para poner a 0 los bits que no se usan (ya estaban a cero).

Por último, hace el desplazamiento que coloca cada componente en su posición final. Lo extraño es que parece hacerlo en formato BGR en vez de RGB, ya que 'uno', que es azul, lo pone en la posición del rojo. Y lo mismo pasa con el rojo, en la posición del azul. Por eso digo que no sé cómo funciona.

Por otro lado, prueba a ver si esta versión de la función que te di no arroja excepción:
Código: Text
  1. public UInt16 ConvierteA16Bit(Int32 color)
  2.    {
  3.      return (ushort) ( ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | (color >> 3) ) & 0x00FFFF);
  4.    }
  5.  

Lo que hago es aplicar una máscara que elimine los 8 bits de mayor peso, para ver si al tener un dato de 16 bits no se queja al devolverlo como ushort.

Un saludo.

Ruben3d

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #10 en: Jueves 14 de Octubre de 2004, 04:54 »
0
:(
Me disponia optimistamente a colocar mi post con lo que habia logfrado reducir el codigo.. y me encuentro con el post... de ruben muy bien si funciono y a la perfección
Este es el mio ;'(
Código: Text
  1.     public UInt16 ConvierteA16Bit(Int32 color)
  2.         {
  3.       byte azul, verde, rojo;
  4.  
  5.       azul = (byte)( color & 0x000000FF);
  6.       verde= (byte)((color & 0x0000FF00)>>8);
  7.       rojo = (byte)((color & 0x00FF0000)>>16);
  8.      
  9.       return (ushort)((rojo >> 3 << 11)|(verde >> 2 << 5)|(azul >> 3));
  10.      
  11.  

funiona pero se queda corto en comparacioj con el tuyo.

Lo estudiare a ver que puedo aprender.

Gracias ruben.
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io

JuanK

  • Miembro de ORO
  • ******
  • Mensajes: 5393
  • Nacionalidad: co
    • Ver Perfil
    • http://juank.io
Re: Color De Mascara
« Respuesta #11 en: Domingo 17 de Octubre de 2004, 23:33 »
0
Finalmente quedo asi:

Codigo en las clases de actores:
fu necesario hacer varias adecuadiones porque todo estaba muy bien hasta cuando estableci windows  a 16 bit..
ahi todo fallo porque cuando se esta en modo ventana prima la recolucion del sistema operativo, no siendo asi cuando se esta en pantalla completa,
por lo cual tuve que determinar cada caso por separado.

Cuando se esta en pantalla completa se debe realizar conversion del color de 16 bit solo si el Device de directx esta en color de 16 bit sin importar la profundidad de color del sistema,
Cuando se esta en modo ventana se debe realizar la conversion de color a 16 bit solo si la resolcuon del Sistema es de 16 bit , sin importar el modo de Device de directX.
Código: Text
  1.  
  2.       if(gc.EstadoVideo ==EnEstadoVideo.PantallaCompleta)
  3.       {
  4.         // Determinar la profundidad del color para pantalla completa
  5.         if(gc.ProfColor == 16 )
  6.         {
  7.           // Si es de 16 bit se debe hacer conversion de colores
  8.           ck.ColorSpaceLowValue = gc.ConvierteA16Bit(ccb);
  9.           ck.ColorSpaceHighValue = gc.ConvierteA16Bit(cca);
  10.         }
  11.         else
  12.         {
  13.           ck.ColorSpaceLowValue = ccb;
  14.           ck.ColorSpaceHighValue = cca;
  15.         }
  16.       }
  17.       else
  18.       {
  19.         // Determinar la profundidad del color para modo ventana
  20.         if(gc.disGrafico.DisplayMode.PixelFormatStructure.RgbBitCount == 16 )
  21.         {
  22.           // Si es de 16 bit se debe hacer conversion de colores
  23.           ck.ColorSpaceLowValue = gc.ConvierteA16Bit(ccb);
  24.           ck.ColorSpaceHighValue = gc.ConvierteA16Bit(cca);
  25.         }
  26.         else
  27.         {
  28.           ck.ColorSpaceLowValue = ccb;
  29.           ck.ColorSpaceHighValue = cca;
  30.         }
  31.       }
  32.  
  33.  

Codigo en la clase grafica
Código: Text
  1.  
  2.  
  3.     public UInt16 ConvierteA16Bit(Int32 color)
  4.         {
  5.       return (ushort) ( ( ((color >> 8) & 0xF800) | ((color >> 5) & 0x07E0) | (color >> 3) ) & 0x00FFFF);
  6.     }
  7.  
[size=109]Juan Carlos Ruiz Pacheco
[/size]
Microsoft Technical Evangelist
@JuanKRuiz
http://juank.io