diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.m index ce69e312..4f21314a 100644 --- a/src/cocoa_gamma.m +++ b/src/cocoa_gamma.m @@ -43,6 +43,27 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) { + uint32_t sampleCount; + int i; + CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; + + // 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++) + { + ramp->red[i] = red[i] * 65535; + ramp->green[i] = green[i] * 65535; + ramp->blue[i] = blue[i] * 65535; + } } @@ -52,5 +73,26 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) { + int i; + int size = GLFW_GAMMA_RAMP_SIZE; + CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; + + // 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] = ramp->red[i] / 65535.f; + green[i] = ramp->green[i] / 65535.f; + blue[i] = ramp->blue[i] / 65535.f; + } + CGSetDisplayTransferByTable(CGMainDisplayID(), GLFW_GAMMA_RAMP_SIZE, red, green, blue); } diff --git a/src/cocoa_init.m b/src/cocoa_init.m index 2455d594..dd85f3f8 100644 --- a/src/cocoa_init.m +++ b/src/cocoa_init.m @@ -225,6 +225,10 @@ int _glfwPlatformInit(void) _glfwLibrary.NS.desktopMode = (NSDictionary*) CGDisplayCurrentMode(CGMainDisplayID()); + // Save the original gamma ramp + _glfwLibrary.originalRampSize = CGDisplayGammaTableCapacity(CGMainDisplayID()); + _glfwPlatformGetGammaRamp(&_glfwLibrary.originalRamp); + return GL_TRUE; } @@ -235,7 +239,10 @@ int _glfwPlatformInit(void) int _glfwPlatformTerminate(void) { // TODO: Probably other cleanup - + + // Restore the original gamma ramp + _glfwPlatformSetGammaRamp(&_glfwLibrary.originalRamp); + [NSApp setDelegate:nil]; [_glfwLibrary.NS.delegate release]; _glfwLibrary.NS.delegate = nil; diff --git a/src/gamma.c b/src/gamma.c index 34cb22f5..9723a0ca 100644 --- a/src/gamma.c +++ b/src/gamma.c @@ -62,20 +62,34 @@ GLFWAPI void glfwSetGamma(float gamma) for (i = 0; i < size; i++) { 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 value = (float) pow(value, 1.f / gamma) * 65535.f + 0.5f; - + // Clamp values if (value < 0.f) value = 0.f; else if (value > 65535.f) value = 65535.f; - - // Set the gamma ramp values - ramp.red[i] = (unsigned short) value; - ramp.green[i] = (unsigned short) value; - ramp.blue[i] = (unsigned short) value; + + // Use original gamma as reference + diffRed = _glfwLibrary.originalRamp.red[i] - pow1; + diffGreen = _glfwLibrary.originalRamp.green[i] - pow1; + 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);