From 3531c320afd6816cabae31ff30b9fb0890952c45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Camilla=20L=C3=B6wy?= Date: Mon, 17 Dec 2018 17:40:18 +0100 Subject: [PATCH] Fix glfwSetGamma generating ramps of invalid sizes This makes glfwSetGamma generate a gamma ramp of the same size as the monitor's current ramp, which will avoid failure on non-256 entry monitors on X11 and avoid ramp interpolation on macOS. Closes #1387. Fixes #1388. --- README.md | 2 ++ include/GLFW/glfw3.h | 10 +++++----- src/monitor.c | 18 +++++++++++++----- 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9941f749..d2fbceaa 100644 --- a/README.md +++ b/README.md @@ -197,6 +197,8 @@ information on what to include when reporting a bug. - Bugfix: Invalid library paths were used in test and example CMake files (#930) - Bugfix: The scancode for synthetic key release events was always zero - Bugfix: The generated Doxyfile did not handle paths with spaces (#1081) +- Bugfix: The gamma ramp generated by `glfwSetGamma` did not use the monitor + ramp size (#1387,#1388) - [Win32] Added system error strings to relevant GLFW error descriptions (#733) - [Win32] Moved to `WM_INPUT` for disabled cursor mode motion input (#125) - [Win32] Removed XInput circular deadzone from joystick axis data (#1045) diff --git a/include/GLFW/glfw3.h b/include/GLFW/glfw3.h index db191c76..099cd8e6 100644 --- a/include/GLFW/glfw3.h +++ b/include/GLFW/glfw3.h @@ -2156,9 +2156,9 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* monitor); /*! @brief Generates a gamma ramp and sets it for the specified monitor. * - * This function generates a 256-element gamma ramp from the specified exponent - * and then calls @ref glfwSetGammaRamp with it. The value must be a finite - * number greater than zero. + * This function generates an appropriately sized gamma ramp from the specified + * exponent and then calls @ref glfwSetGammaRamp with it. The value must be + * a finite number greater than zero. * * The software controlled gamma ramp is applied _in addition_ to the hardware * gamma correction, which today is usually an approximation of sRGB gamma. @@ -2237,8 +2237,8 @@ GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* monitor); * @errors Possible errors include @ref GLFW_NOT_INITIALIZED and @ref * GLFW_PLATFORM_ERROR. * - * @remark Gamma ramp sizes other than 256 are not supported by all platforms - * or graphics hardware. + * @remark The size of the specified gamma ramp should match the size of the + * current ramp for that monitor. * * @remark @win32 The gamma ramp size must be 256. * diff --git a/src/monitor.c b/src/monitor.c index dea45d6e..0ab865e3 100644 --- a/src/monitor.c +++ b/src/monitor.c @@ -427,9 +427,10 @@ GLFWAPI const GLFWvidmode* glfwGetVideoMode(GLFWmonitor* handle) GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) { - int i; - unsigned short values[256]; + unsigned int i; + unsigned short* values; GLFWgammaramp ramp; + const GLFWgammaramp* original; assert(handle != NULL); assert(gamma > 0.f); assert(gamma <= FLT_MAX); @@ -442,12 +443,18 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) return; } - for (i = 0; i < 256; i++) + original = glfwGetGammaRamp(handle); + if (!original) + return; + + values = calloc(original->size, sizeof(unsigned short)); + + for (i = 0; i < original->size; i++) { float value; // Calculate intensity - value = i / 255.f; + value = i / (float) (original->size - 1); // Apply gamma curve value = powf(value, 1.f / gamma) * 65535.f + 0.5f; // Clamp to value range @@ -459,9 +466,10 @@ GLFWAPI void glfwSetGamma(GLFWmonitor* handle, float gamma) ramp.red = values; ramp.green = values; ramp.blue = values; - ramp.size = 256; + ramp.size = original->size; glfwSetGammaRamp(handle, &ramp); + free(values); } GLFWAPI const GLFWgammaramp* glfwGetGammaRamp(GLFWmonitor* handle)