From 688772111d56526b7297b9dcf31eb7cf12c20fdc Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Mon, 12 Sep 2011 22:16:28 +0100 Subject: [PATCH 1/2] Initial implementation of gamma through Cocoa. --- src/cocoa_gamma.m | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.m index ce69e312..ffb70f51 100644 --- a/src/cocoa_gamma.m +++ b/src/cocoa_gamma.m @@ -43,6 +43,18 @@ 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]; + CGGetDisplayTransferByTable(0, GLFW_GAMMA_RAMP_SIZE, red, green, blue, &sampleCount); + for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++) + { + _glfwLibrary.currentRamp.red[i] = red[i] * 65535; + _glfwLibrary.currentRamp.green[i] = green[i] * 65535; + _glfwLibrary.currentRamp.blue[i] = blue[i] * 65535; + } } @@ -52,5 +64,16 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) void _glfwPlatformSetGammaRamp(const GLFWgammaramp* ramp) { + int i; + CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue green[GLFW_GAMMA_RAMP_SIZE]; + CGGammaValue blue[GLFW_GAMMA_RAMP_SIZE]; + for (i = 0; i < GLFW_GAMMA_RAMP_SIZE; i++) + { + red[i] = ((float)_glfwLibrary.currentRamp.red[i]) / 65535.0f; + blue[i] = ((float)_glfwLibrary.currentRamp.green[i]) / 65535.0f; + green[i] = ((float)_glfwLibrary.currentRamp.blue[i]) / 65535.0f; + } + CGSetDisplayTransferByTable(0, GLFW_GAMMA_RAMP_SIZE, red, green, blue); } From 53f64983a9a624fe7ee8c57f7e1c679636f8dc26 Mon Sep 17 00:00:00 2001 From: Tai Chi Minh Ralph Eastwood Date: Wed, 14 Sep 2011 06:53:26 +0100 Subject: [PATCH 2/2] Take into account the original gamma before applying gamma. --- src/cocoa_gamma.m | 37 ++++++++++++++++++++++++++++--------- src/cocoa_init.m | 9 ++++++++- src/gamma.c | 28 +++++++++++++++++++++------- 3 files changed, 57 insertions(+), 17 deletions(-) diff --git a/src/cocoa_gamma.m b/src/cocoa_gamma.m index ffb70f51..4f21314a 100644 --- a/src/cocoa_gamma.m +++ b/src/cocoa_gamma.m @@ -48,12 +48,21 @@ void _glfwPlatformGetGammaRamp(GLFWgammaramp* ramp) CGGammaValue red[GLFW_GAMMA_RAMP_SIZE]; CGGammaValue green[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++) { - _glfwLibrary.currentRamp.red[i] = red[i] * 65535; - _glfwLibrary.currentRamp.green[i] = green[i] * 65535; - _glfwLibrary.currentRamp.blue[i] = blue[i] * 65535; + ramp->red[i] = red[i] * 65535; + ramp->green[i] = green[i] * 65535; + ramp->blue[i] = blue[i] * 65535; } } @@ -65,15 +74,25 @@ 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 (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; - blue[i] = ((float)_glfwLibrary.currentRamp.green[i]) / 65535.0f; - green[i] = ((float)_glfwLibrary.currentRamp.blue[i]) / 65535.0f; + red[i] = ramp->red[i] / 65535.f; + green[i] = ramp->green[i] / 65535.f; + 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); } 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);