gamma?

Does anyone tell me how I can do gamma correction under windows (ofcourse in my gl app.)? I know that can not be done with gl so I should use windows. But, how?

thanks

mandroka

Take a look at the SetDeviceGammaRamp and GetDeviceGammaRamp functions.

I made a test.
The GetDeviceGammaRamp returns the table, but the SetDevieGammaRamp always fail. Even with the table the get… function gave me.
I have a tnt2.

Is this the only way?

Hmmm, that is odd. I have no problem setting the gamma ramp on my TNT. Are you using the display device context, created by CreateDC(“DISPLAY”,NULL,NULL,NULL)? That’s what I use and it works fine.

Well, I used my app window’s DC. That could be the problem. I will look after it.
thanks.

Well, now I can upload a gamma table, but I do not know the correct values.
I mean if I multiply everything with 1.5 then Setgamma fails. If I try multiplying my table with 2 it works (with weird colors).

How do you compute the correct values?

You could use something like this:

static WORD old_gamma_ramp[768];

/*
SetGammaRamp(double gamma, double bright, double contrast)
gamma [0,255] (increased gamma < 127, decreased gamma > 127)
bright [0,255] (darker < 127, brighter > 127)
contrast [0,255] (lower < 127, higher > 127)

*/
SetGammaRamp(double gamma, double bright, double contrast)
{
HDC ddc=::CreateDC(“DISPLAY”,NULL,NULL,NULL);
static WORD gamma_ramp[768];
double v;
const double ft=2.0/255.0;
static bool savedramp=false;
// save old gamma ramp if this is first time modified
// FIXME: should get the gamma ramp anyway to see if it has been changed from what was
// last set
if(!savedramp)
{
::GetDeviceGammaRamp(ddc,old_gamma_ramp);
savedramp=true;
}

for(int x=0;x<256;x++)
{
if(gamma==255)
v=0.0;
else
v=pow((double)x/255,gamma/(255-gamma));
v+=ftbright-1.0;
v+=(ft
(double)x-1.0)(contrast/255.0-.5)(ftcontrast+1.0);
v
=65535;
if(v<0)
v=0;
else
if(v>65535)
v=65535;
gamma_ramp=(WORD)v;
}
memcpy(gamma_ramp+256,gamma_ramp,512);
memcpy(gamma_ramp+512,gamma_ramp,512);
::SetDeviceGammaRamp(ddc,gamma_ramp);

::DeleteDC(ddc);
}

Or even better, keep track of individual gamma, brightness and contrast values for each channel. And set each table using its respective values rather than copying one channel to the others as done in this code.
You’d probably also want to add some constraints so that a user can’t produce extreme ramps, e.g. all black or all white, as this code above will allow.

[This message has been edited by DFrey (edited 01-09-2001).]

Thank you.

How can i take a screen shot of a scene with modified gamma ramp?
The results i am getting are too dark.
Thanx.

IIRC, setting the gamma ramp affects the value passed to the DAC, after rasterization has occurred and the frame buffer is drawn. So, pressing print screen and capturing the frame buffer data will always paste identical values, regardless of the gamma ramp set.

AFAIK, individual device context gamma adjustment is a feature that MS is including in GDI Plus, but is currently not available. I do remember a thread on this board talking about achieving “overbright” which would affect the frame buffer values of a given context, but I don’t know if that will address your issue.

Glossifah

The problem with the screen-shot being dark is that when you read-back colors, you get the results in the frame buffer. The frame buffer colors are (hopefully) linear so that all the wonderful lighting and blending math will work correctly.

The problem is that when you redisplay it the transfer function to the screen has changed. If you are concerned about this, you can either gamma-correct the linear pixels you pull out of the frame buffer, or you can use a file format that can save gamma information (PNG?) and hope the image viewer displays it correctly.

As for the statement about different handling of gamma’s in Windows, seperate will help a lot of things immensely, but not the rading of values. I hope that windows never misrepresents the pixel values, as gamma-correcting them might cause precision loss. I know glReadPixels will not allow such things.

  • Evan

setdevice gammaramp works very patchy under win2000