Dissolve color to R,G,B,A

Started by EugeneP, November 04, 2010, 04:19:48 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

EugeneP

I have a problem ( as usual :| )

I am reading colours from map by map_get_pixel and I want to know R,G,B,A values for each pixel. Screen modes are 16 or 32 bit, Map bit depths is generally unknown. Is where any good way to do such thing?

Knowing Bennu's colour format  I can do it by using bit masks (11111 00000 00000 0, 00000 11111 00000 0, and so on ) but it's ugly and uncool.

handsource-dyko

Are you using map_get_pixel() for collision detection hardnessmaps?
In that case your hardnessmaps should be in 8-bit 256 color index mode, with
rgb modes it does not work in a bulletproof way beacause of the analog nature
of graphics cards (at least that used to be in the fenix days, I'm not sure now).

Actually, there's a get_rgb() function, that returns color components.
These are converted to a integer index number as fas as I can remember.
So, it does not retrieve the rgb components directly.

Drumpi

Yes, you have GET_RGB and GET_RGBA too. You only need 3 or 4 pointers respectively.

Don't know how to use pointers? no problem. If you have:

int my_r,my_g,my_b,my_a;

get_rgba(map_get_pixel(my_fpg,my_map,x,y), &my_r, &my_g, &my_b, &my_a);


Easy, doesn't it?
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

EugeneP

Yes, thank you. get_rgba is exactly what I want. There is no article on Wiki. Next time I'll search the source before asking :)

handsource-dyko

Quote from: EugeneP on November 07, 2010, 06:53:24 PM
Yes, thank you. get_rgba is exactly what I want. There is no article on Wiki. Next time I'll search the source before asking :)

Actually, there's a lot more functions and features that are not documented at all.
You can also run the trinit manual through google translate to get some clues, I sometimes do that.

Did you know that mod_map has so many more functions that are listed on the wiki?
Well, I found out using moddesc.exe wich lists them for you.

Drumpi

Be carefull, GET_RGBA only works on 32 bits, because RGBA needs 8bits for Red component, 8bits for Green, 8bits for Blue and 8bits for Alpha (transparency): a total of 32bits.
16bits color mode use 5-6-5 bits for RGB components.

Maybe they will works, i didn't try, but I don't know if they works correctly.

We need people to write on wiki... people with time ^^U
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

EugeneP

moddesc gave me some additional info, thanks.

But is there a good reason why rgb(), rgba(), get_grb() and get_rgba() ignore alpha channel in 16 bit mode?

EugeneP

I mean something like this:

g_pal.c
[code language="c"]/* --------------------------------------------------------------------------- */
/* This functions is used only for 16 and 32 bits                              */

int gr_rgba( int r, int g, int b, int a )
{
    int color = 0;

    if ( sys_pixel_format->depth == 32 )
    {
        return  (( a << 24 ) & 0xff000000 ) |
                (( r << 16 ) & 0x00ff0000 ) |
                (( g <<  8 ) & 0x0000ff00 ) |
                (( b       ) & 0x000000ff ) ;
    }

    /* 16 bits */
    if( a < 127 ) // consider alpha < 50% as transparent
      color = 0;
    else 
      color = (( r >> sys_pixel_format->Rloss ) << sys_pixel_format->Rshift ) |
              (( g >> sys_pixel_format->Gloss ) << sys_pixel_format->Gshift ) |
              (( b >> sys_pixel_format->Bloss ) << sys_pixel_format->Bshift ) ;

    //if ( !color ) return 1 ;

    return color ;
}

/* --------------------------------------------------------------------------- */

void gr_get_rgb( int color, int *r, int *g, int *b )
{
    /* 8 bits mode, work with system palette */

    if ( sys_pixel_format->depth < 16 )
    {
        rgb_component * rgb ;

        if ( !sys_pixel_format->palette ) {
            rgb = ( rgb_component * ) default_palette;
   }
        else {
            rgb = sys_pixel_format->palette->rgb ;
   }

        color &= 0xFF ;
        ( *r ) = rgb[ color ].r ;
        ( *g ) = rgb[ color ].g ;
        ( *b ) = rgb[ color ].b ;

        return ;
    }

    ( *r ) = (( color & sys_pixel_format->Rmask ) >> sys_pixel_format->Rshift ) << sys_pixel_format->Rloss;
    ( *g ) = (( color & sys_pixel_format->Gmask ) >> sys_pixel_format->Gshift ) << sys_pixel_format->Gloss;
    ( *b ) = (( color & sys_pixel_format->Bmask ) >> sys_pixel_format->Bshift ) << sys_pixel_format->Bloss;
}

/* --------------------------------------------------------------------------- */

void gr_get_rgba( int color, int *r, int *g, int *b, int *a )
{
    /* 8 bits mode, work with system palette */

    if ( sys_pixel_format->depth < 16 )
    {
        rgb_component * rgb ;

        if ( !sys_pixel_format->palette )
            rgb = ( rgb_component * ) default_palette;
        else
            rgb = sys_pixel_format->palette->rgb ;

   ( *a ) = color ? 255 : 0;
   
        color &= 0xFF ;
        ( *r ) = rgb[ color ].r ;
        ( *g ) = rgb[ color ].g ;
        ( *b ) = rgb[ color ].b ;

        return ;
    }

    ( *r ) = (( color & sys_pixel_format->Rmask ) >> sys_pixel_format->Rshift ) << sys_pixel_format->Rloss ;
    ( *g ) = (( color & sys_pixel_format->Gmask ) >> sys_pixel_format->Gshift ) << sys_pixel_format->Gloss ;
    ( *b ) = (( color & sys_pixel_format->Bmask ) >> sys_pixel_format->Bshift ) << sys_pixel_format->Bloss ;

    if ( sys_pixel_format->depth == 32 )
    {
        ( *a ) = (( color & sys_pixel_format->Amask ) >> sys_pixel_format->Ashift ) << sys_pixel_format->Aloss ;
    }
    else
    {
   ( *a ) = color ? 255 : 0;
    }
     
}[/code]

I am not sure if I get all bennu's specific right, but you've got an idea.

osk

Quote from: handsource-dyko on November 07, 2010, 07:05:57 PM
Actually, there's a lot more functions and features that are not documented at all.
You can also run the trinit manual through google translate to get some clues, I sometimes do that.


You can also read my very complete manual of Bennu (in spanish, though):
http://iespuigcastellar.xeill.net/departaments/informatica/fitxers/programacio/manualbennu.pdf

EugeneP

Quote from: osk on November 08, 2010, 02:49:59 PM
an also read my very complete manual of Bennu (in spanish, though):
http://iespuigcastellar.xeill.net/departaments/informatica/fitxers/programacio/manualbennu.pdf
Thanks. I guess I'll learn Spanish after all the time dealing with Bennu  :)

Drumpi

Quote from: EugeneP on November 08, 2010, 05:23:11 AM
moddesc gave me some additional info, thanks.

But is there a good reason why rgb(), rgba(), get_grb() and get_rgba() ignore alpha channel in 16 bit mode?

I said why in my last post.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

EugeneP

Quote from: Drumpi on November 08, 2010, 08:53:43 PM
Quote from: EugeneP on November 08, 2010, 05:23:11 AM
moddesc gave me some additional info, thanks.

But is there a good reason why rgb(), rgba(), get_grb() and get_rgba() ignore alpha channel in 16 bit mode?

I said why in my last post.
Nahhh. A good reasons sound like: "It would take a many hours of work", "It is incompatible with rendering system", "It would break backward compatibility".

I added few lines to g_pal.c and now rgba( r,g,b,0 ) returns actually transparent colour in 8, 16 and 32 bit mode, and get_rgba( &r, &g, &b, &a ) sets a=255 for opaque colours and a=0 for transparent colours in 8 and 16 bit mode.

Maybe my approach is totally wrong or inapplicable. If it is, I would like to know why and rework it.

Drumpi

But you don't have alpha channel on 8 or 16 bits mode, so it's useless to read the alpha channel in your maps, this is why Bennu ignore them.

By the way, talk to splinter, maybe he likes your changes and add them to official cvs. If not, you can create your own non-official module and share it, like others (bennu3D, VSE, Pango...).
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)