From 27291f388b02c6ba88efb79b9728b65f158589ef Mon Sep 17 00:00:00 2001 From: Mitya Selivanov Date: Thu, 24 Apr 2025 03:58:52 +0200 Subject: Global gamma correction --- runtime.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'runtime.c') diff --git a/runtime.c b/runtime.c index 4ba5c15..3f20820 100644 --- a/runtime.c +++ b/runtime.c @@ -612,7 +612,7 @@ typedef struct { i32 antialiasing_scale; b8 exact_resolution : 1; - b8 disable_gamma : 1; // TODO + b8 disable_gamma : 1; b8 graceful_shutdown : 1; b8 enable_clipboard_text : 1; b8 enable_clipboard_image : 1; @@ -1290,6 +1290,18 @@ i8 utf8_write(c32 c, c8 *buffer) { // // ================================================================ +static f32 gamma_(f32 x) { + if (x >= 0.0031308f) + return 1.055f * (f32) pow(x, 1.0 / 2.4) - 0.055f; + return 12.92f * x; +} + +static f32 gamma_re_(f32 x) { + if (x >= 0.04045f) + return (f32) pow((x + 0.055f) / 1.055f, 2.4); + return x / 12.92f; +} + static u32 rgb_u32_from_f32_(vec3_f32 c) { i32 ir = (i32) floor(c.x * 255. + .5); i32 ig = (i32) floor(c.y * 255. + .5); @@ -1765,6 +1777,8 @@ static void convert_pixels_for_window_(void) { return; } + // TODO, PERF: Improve performance. + // Downscale pixels from vec4_f32 pixel buffer to internal u32 pixel buffer. // // FIXME: Check if the scale is 1:1. @@ -1812,11 +1826,27 @@ static void convert_pixels_for_window_(void) { } } - u32 *d_end = d + dst_width; - vec3_f32 *im = _internal_row; + u32 *d_end = d + dst_width; + vec3_f32 *im = _internal_row; + vec3_f32 *im_end = _internal_row + dst_width; + + if (!g_platform.disable_gamma) + for (; im < im_end; ++im) { + im->x = gamma_(im->x * k); + im->y = gamma_(im->y * k); + im->z = gamma_(im->z * k); + } + else + for (; im < im_end; ++im) { + im->x *= k; + im->y *= k; + im->z *= k; + } + + im = _internal_row; for (; d < d_end; ++d, ++im) - *d = rgb_u32_from_f32_((vec3_f32) { .x = im->x * k, .y = im->y * k, .z = im->z * k, }) | 0xff000000; + *d = rgb_u32_from_f32_(*im) | 0xff000000; } PROFILER_end(PROFILE_DOWNSCALE); @@ -1843,8 +1873,6 @@ static void convert_pixels_for_window_(void) { PROFILER_begin(PROFILE_RESIZE); - // TODO, PERF: Improve performance. - u32 x_ratio = (src_width << 16) / dst_width; u32 y_ratio = (src_height << 16) / dst_height; -- cgit v1.2.3