Gamma control with DirectColor visuals (fwd)

Forwarded message: -------------------Date: Thu, 24 Aug 2000 12:18:44 -0700
From: @slouken (slouken)
Subject: Gamma control with DirectColor visuals

I’ve added gamma ramp control to SDL using DirectColor visuals.
It seems to work on most XFree86 4.01 setups, but there are oddities on
some configurations.

I have a program takes the gamma as a parameter (defaults to 1.0), and
displays an image using that gamma value, and then cycles the colormap
to red and fades to black:
http://www.devolution.com/~slouken/tmp/testgamma.tar.gz

The program treats DirectColor visuals as normal truecolor visuals with
a colormap used to set gamma ramps:

    /* Calculate the appropriate palette for the given gamma ramp */
    ncolors = SDL_Visual->map_entries;
    for ( i=0; i<ncolors; ++i ) {
            Uint8 c = (256 * i / ncolors);
            xcmap[i].pixel = SDL_MapRGB(this->screen->format, c, c,

c);
xcmap[i].red = (xgamma[0][c]<<8)|xgamma[0][c];
xcmap[i].green = (xgamma[1][c]<<8)|xgamma[1][c];
xcmap[i].blue = (xgamma[2][c]<<8)|xgamma[2][c];
xcmap[i].flags = (DoRed|DoGreen|DoBlue);
}
XStoreColors(GFX_Display, SDL_XColorMap, xcmap, ncolors);
XSync(GFX_Display, False);

The gamma ramp itself is calculated with:

/* Turn a normal gamma value into an appropriate gamma ramp */
void CalculateGamma(double gamma, Uint8 *ramp)
{
int i, value;

    gamma = 1.0 / gamma;
    for ( i=0; i<256; ++i ) {
            value = (int)(pow((double)i/256.0, gamma)*256.0 + 0.5);
            if ( value > 255 ) {
                    value = 255;
            }
            ramp[i] = (Uint8)value;
    }

}

On Nvidia 0.94 drivers and XFree86 4.01, the server advertised
DirectColor visuals but setting the colormap didn’t modify the colors of
the screen.

Another odd thing is that on a Voodoo DRI XFree86 4.01 setup, the gamma
appeared to work properly, but the image didn’t display at all, however
it worked fine with a non-DRI setup freshly downloaded from
ftp.xfree86.org.

Anyway, I’m mostly looking for feedback as to how this works in general
and if I’m interpreting the way to work with DirectColor visuals
correctly. I’ll commit the code to CVS as soon as I get some feedback.

BTW, glxChooseVisual() prefers TrueColor visuals to DirectColor
visuals. Is there any particular reason for this?

Thanks!

-Sam Lantinga, Lead Programmer, Loki Entertainment Software

------------------- end forwarded message.

void CalculateGamma(double gamma, Uint8 *ramp)
{
int i, value;

gamma = 1.0 / gamma;
for ( i=0; i<256; ++i ) {
value = (int)(pow((double)i/256.0, gamma)*256.0 + 0.5);
if ( value > 255 ) {
value = 255;
}
ramp[i] = (Uint8)value;
}
}

Most screens/graphics systems have a gamma of 2.2 (the exceptions
being Macs, which have something like 1.8(?) built into quickdraw).
Either renormalise gamma to have 2.2 to produce a linear ramp, or document
gamma here as a relative gamma

The above function is only part of a test program. SDL itself doesn’t
make any assumptions about gamma. You simply feed it with a gamma ramp
:-)On Fri, Aug 25, 2000 at 10:14:41AM +0200, Mattias Engdeg?rd wrote:

void CalculateGamma(double gamma, Uint8 *ramp)
{
int i, value;

gamma = 1.0 / gamma;
for ( i=0; i<256; ++i ) {
value = (int)(pow((double)i/256.0, gamma)*256.0 + 0.5);
if ( value > 255 ) {
value = 255;
}
ramp[i] = (Uint8)value;
}
}

Most screens/graphics systems have a gamma of 2.2 (the exceptions
being Macs, which have something like 1.8(?) built into quickdraw).
Either renormalise gamma to have 2.2 to produce a linear ramp, or document
gamma here as a relative gamma


Daniel Vogel
Programmer
Loki Entertainment Software

The above function is only part of a test program. SDL itself doesn’t
make any assumptions about gamma. You simply feed it with a gamma ramp
:slight_smile:

I thought Sam intended to include SDL_SetGamma() as well as SetGammaRamp().
There could be hardware you cannot control with a ramp but whose gamma
is settable from a scalar. You could integrate the ramp but that
gets too slow and messy

The above function is only part of a test program. SDL itself doesn’t
make any assumptions about gamma. You simply feed it with a gamma ramp
:slight_smile:

I thought Sam intended to include SDL_SetGamma() as well as SetGammaRamp().
There could be hardware you cannot control with a ramp but whose gamma
is settable from a scalar. You could integrate the ramp but that
gets too slow and messy

No, I planned to support one or the other. There is so little real gamma
support out there, that I’d hate to provide two useless functions. :slight_smile:

See ya!
-Sam Lantinga, Lead Programmer, Loki Entertainment Software