Take into account the original gamma before applying gamma.

This commit is contained in:
Tai Chi Minh Ralph Eastwood 2011-09-14 06:53:26 +01:00
parent 688772111d
commit 53f64983a9
3 changed files with 57 additions and 17 deletions

View File

@ -48,12 +48,21 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue red[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE];
CGGetDisplayTransferByTable(0, GLFW_GAMMA_RAMP_SIZE, red, green, blue, &sampleCount);
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
// i.e. 256. I don't think anyone would want to change the gamma on
// Mac anyway...
if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
return;
CGGetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue,
&sampleCount);
for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++) for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++)
{ {
_glfwLibrary.currentRamp.red[i] = red[i] * 65535; ramp->red[i] = red[i] * 65535;
_glfwLibrary.currentRamp.green[i] = green[i] * 65535; ramp->green[i] = green[i] * 65535;
_glfwLibrary.currentRamp.blue[i] = blue[i] * 65535; ramp->blue[i] = blue[i] * 65535;
} }
} }
@ -65,15 +74,25 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp)
void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp)
{ {
int i; int i;
int size = GLFW_GAMMA_RAMP_SIZE;
CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue red[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[GLFW_GAMMA_RAMP_SIZE];
CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE];
for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++)
// For now, don't support anything that is not GLFW_GAMMA_RAMP_SIZE
// i.e. 256. I don't think anyone would want to change the gamma on
// Mac anyway...
if (_glfwLibrary.originalRampSize != GLFW_GAMMA_RAMP_SIZE)
return;
// Convert to float & take the difference of the original gamma and
// the linear function.
for (i = 0; i < size; i++)
{ {
red[i] = ((float)_glfwLibrary.currentRamp.red[i]) / 65535.0f; red[i] = ramp->red[i] / 65535.f;
blue[i] = ((float)_glfwLibrary.currentRamp.green[i]) / 65535.0f; green[i] = ramp->green[i] / 65535.f;
green[i] = ((float)_glfwLibrary.currentRamp.blue[i]) / 65535.0f; blue[i] = ramp->blue[i] / 65535.f;
} }
CGSetDisplayTransferByTable(0, GLFW_GAMMA_RAMP_SIZE, red, green, blue); CGSetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue);
} }

View File

@ -225,6 +225,10 @@ int _glfwPlatformInit(void)
_glfwLibrary.NS.desktopMode = _glfwLibrary.NS.desktopMode =
(NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID()); (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID());
// Save the original gamma ramp
_glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID());
_glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp);
return GL_TRUE; return GL_TRUE;
} }
@ -235,7 +239,10 @@ int _glfwPlatformInit(void)
int _glfwPlatformTerminate(void) int _glfwPlatformTerminate(void)
{ {
// TODO: Probably other cleanup // TODO: Probably other cleanup
// Restore the original gamma ramp
_glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp);
[NSApp setDelegate:nil]; [NSApp setDelegate:nil];
[_glfwLibrary.NS.delegate release]; [_glfwLibrary.NS.delegate release];
_glfwLibrary.NS.delegate = nil; _glfwLibrary.NS.delegate = nil;

View File

@ -62,20 +62,34 @@ GLFWAPI void glfwSetGamma(float gamma)
for (i = 0; i < size; i++) for (i = 0; i < size; i++)
{ {
float value = (float) i / ((float) (size - 1)); float value = (float) i / ((float) (size - 1));
int diffRed, diffGreen, diffBlue, newRed, newGreen, newBlue, pow1;
// Reference our gamma 1.0f
pow1 = value * 65535.f + 0.5;
// Apply gamma // Apply gamma
value = (float) pow(value, 1.f / gamma) * 65535.f + 0.5f; value = (float) pow(value, 1.f / gamma) * 65535.f + 0.5f;
// Clamp values // Clamp values
if (value < 0.f) if (value < 0.f)
value = 0.f; value = 0.f;
else if (value > 65535.f) else if (value > 65535.f)
value = 65535.f; value = 65535.f;
// Set the gamma ramp values // Use original gamma as reference
ramp.red[i] = (unsigned short) value; diffRed = _glfwLibrary.originalRamp.red[i] - pow1;
ramp.green[i] = (unsigned short) value; diffGreen = _glfwLibrary.originalRamp.green[i] - pow1;
ramp.blue[i] = (unsigned short) value; diffBlue = _glfwLibrary.originalRamp.blue[i] - pow1;
// Calculate new values
newRed = diffRed + (unsigned short) value;
newGreen = diffGreen + (unsigned short) value;
newBlue = diffBlue + (unsigned short) value;
// Set the gamma ramp values (whilst clamping)
ramp.red[i] = newRed > 65535 ? 65535 : newRed < 0 ? 0 : newRed;
ramp.green[i] = newGreen > 65535 ? 65535 : newGreen < 0 ? 0 : newGreen;
ramp.blue[i] = newBlue > 65535 ? 65535 : newBlue < 0 ? 0 : newBlue;
} }
glfwSetGammaRamp(&ramp); glfwSetGammaRamp(&ramp);