[comp.sys.sgi] getmcolor

drb@eecg.toronto.edu (David R. Blythe) (02/22/91)

getmcolor() doesn't appear to work in RGB mode (it returns 0's).
I guess this shouldn't come as a surprise, but its not documented as working
only in cmode, and mapcolor() does seem to work in RGB mode.  The reasons
for trying to use it in RGB mode are a bit obscure and its easy to work
around, but someone may want to fix it (if its fixable). 4D/70GT running
3.3.1.
	david blythe
	drb@clsc.utoronto.ca

drb@eecg.toronto.edu (David R. Blythe) (02/23/91)

In article <1991Feb22.151942.26855@ux1.cso.uiuc.edu> marcc@yoyodyne.ncsa.uiuc.edu (Marc Cooper) writes:
>In article <1991Feb21.223016.8843@jarvis.csri.toronto.edu> drb@eecg.toronto.edu (David R. Blythe) writes:
>>getmcolor() doesn't appear to work in RGB mode (it returns 0's).
...
>>around, but someone may want to fix it (if its fixable). 4D/70GT running
>>3.3.1.
>
>
>When I converted an 8-bit program to 24 bit, I used getmcolor() frequently and
>it worked like a charm.  It allowed me to still keep the colormap manipulation
>I wanted and use lighting...  Make sure you're using pointers:
>
>short r,g,b;
>int index;
>
>getmcolor(index, &r, &g, &b);
>
>
>Other than that, there shouldn't be a problem.  I running it nicely on a PI 
>using 3.3.1

My test program looks like this:

#include <gl/gl.h>
main() {
    int i;
    short b[3];

    winopen("");
    RGBmode();
    gconfig();
    for(i = 0; i < 1000; i++) {
	getmcolor(i, b, b+1, b+2);
	printf("%d  %x %x %x\n", i, b[0], b[1], b[2]);
    }
}

It returns all zeros.  I fixed my application by having it call cmode()
before calling getmcolor().  This is a 4D/70GT running 3.3.1
	-drb

marcc@yoyodyne.ncsa.uiuc.edu (Marc Cooper) (06/24/91)

Here's an interesting little problem:


It was recently my pleasure (right) to convert an 8 bit GL program to 24 bit.
Wanting to take the path of least resistence, thus freeing me from redoing
all the nifty pallette manipulation stuff that was already there, I 
simply wrote a routine I called rbgcolor() that took the place of color()


It looks something like the following:

rbgcolor(int index)
{
	short r,g,b;

	getmcolor(index,&r,&g,&b);
	RGBcolor(r,g,b);
}


wallah!  24 bit color! (This was madified to do lighting and depthcuing and 
other stuff, so it isn't quite as pointless as it looks..)

Anyway, it works just fine on my PI.  But when I go run it on a VGX, the
r,g, and b values all come back 0.  There was something in the manual about the
last 256 entries in the map being used for gamma corrections, but I'm starting
my map at 512 (just after the system colors).  And again, this works just fine
on a PI.  It fails on VGX machines.

Any hints, clues, etc?

-Marc Cooper
 marcc@ncsa.uiuc.edu

fouts@teehee.dallas.sgi.com (Chris Fouts) (06/26/91)

In article <1991Jun24.142930.29853@ux1.cso.uiuc.edu>, marcc@yoyodyne.ncsa.uiuc.edu (Marc Cooper) writes:
|> 
|> 
|> 
|> Here's an interesting little problem:
|> 
|> 
|> It was recently my pleasure (right) to convert an 8 bit GL program to 24 bit.
|> Wanting to take the path of least resistence, thus freeing me from redoing
|> all the nifty pallette manipulation stuff that was already there, I 
|> simply wrote a routine I called rbgcolor() that took the place of color()
|> 
|> 
|> It looks something like the following:
|> 
|> rbgcolor(int index)
|> {
|> 	short r,g,b;
|> 
|> 	getmcolor(index,&r,&g,&b);
|> 	RGBcolor(r,g,b);
|> }
|> 
|> 
|> wallah!  24 bit color! (This was madified to do lighting and depthcuing and 
|> other stuff, so it isn't quite as pointless as it looks..)
|> 
|> Anyway, it works just fine on my PI.  But when I go run it on a VGX, the
|> r,g, and b values all come back 0.  There was something in the manual about the
|> last 256 entries in the map being used for gamma corrections, but I'm starting
|> my map at 512 (just after the system colors).  And again, this works just fine
|> on a PI.  It fails on VGX machines.
|> 
|> Any hints, clues, etc?

If you try to read the colormap from an RGB window on a VGX it will fail (after
all, it's an RGB window--not a colormap window).  You can get around this with
something like (untested code follows :^):

in_your_graphics_initialization_routine()
{
        extern long map_id ;
        ....
	noport();
	map_id = winopen( "noshow");
        ....
        /* open your other windows */
        ....
}

rbgcolor(int index)
{
	short r,g,b;
        extern long map_id ;
        long prev_id;

        prev_id = winget() ;     	/* save previous window ID */
        winset( map_id ) ;		/* set to noport colormap window */
	getmcolor(index,&r,&g,&b);	/* read the colormap */
        winset( prev_id ) ;		/* restore previous window ID */
	RGBcolor(r,g,b);
}


This should work since the map_id window is a colormap window (even though
it isn't mapped).  Of course, you'll take a slight performance hit with the
extra calls.

Alternatively, you could write your own routines that store the map color
values in your own local table, and reference the colors from that.

-- 

Chris Fouts				Email:  fouts@dallas.sgi.com
Systems Engineer			Phone:  (214)-788-4122
Silicon Graphics Computer Systems	Vmail:	8714
Dallas, TX

'The GFX-100 looks like an outdoor satellite "dish," but works indoors
 like ordinary "rabbit ears." You pay NO cable fees because you're NOT
 getting cable!!!  You pay NO satellite fees because you're NOT using
 satellite technology or service!!! Works entirely via proven "RF"
 technology--actually pulls signals right out of the air....Not
 technical razzle-dazzle but the sheer aesthetic superiority of its
 elegant parabolic design make the GFX-100 a marketing breakthrough.'

			-- Ad for GFX-100 Indoor TV "Dish" Antenna.

markov@cs.ruu.nl (Mark Overmars) (06/26/91)

In <1991Jun25.191922.7763@odin.corp.sgi.com> fouts@teehee.dallas.sgi.com (Chris Fouts) writes:

>
>If you try to read the colormap from an RGB window on a VGX it will fail (after
>all, it's an RGB window--not a colormap window).  You can get around this with
>something like (untested code follows :^):
>
> (stuff deleted)
>
>This should work since the map_id window is a colormap window (even though
>it isn't mapped).  Of course, you'll take a slight performance hit with the
>extra calls.
>

Well, I had this same problem. I first solved it this way. The performance
penalty is tremendous. So better don't do it this way. The problems seems to
be the winset() calls that are expensive.

>Alternatively, you could write your own routines that store the map color
>values in your own local table, and reference the colors from that.
>

This is indeed the easiest to do. The following piece of code might be what
you want for this:

short fl_red[4096], fl_green[4096], fl_blue[4096];

void fl_init_colormap()
{
  long cmwin;
  int i;
  noport();
  cmwin = winopen("CM");
  for (i=0; i<4096; i++)
    getmcolor(i,&fl_red[i],&fl_green[i],&fl_blue[i]);
  winclose(cmwin);
}

Now define

void fl_color(int col)
{
  RGBcolor(fl_red[col],fl_green[col],fl_blue[col]);
}

and use fl_color() instead of color(). Better change the fl_ things in front
of the calls. You might get problems with Forms otherwise.
(Guess where this came from :-)

Note that this does not give exact colormap behaviour but it does the basic
thing.

Mark Overmars