From d426b8b8935acf73d6152ce55abd3ddd47ce5f2d Mon Sep 17 00:00:00 2001 From: hgn Date: Wed, 31 Jan 2024 05:25:58 +0000 Subject: [PATCH] intermediate representation HSV --- vg_imgui.h | 48 +++++++++++++++++++++++------------------------- vg_m.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 25 deletions(-) diff --git a/vg_imgui.h b/vg_imgui.h index 32fab49..5c957ed 100644 --- a/vg_imgui.h +++ b/vg_imgui.h @@ -1416,7 +1416,7 @@ static void ui_enum_post(void){ * ----------------------------------------------------------------------------- */ -static void _ui_slider( ui_rect box, +static enum ui_button_state _ui_slider( ui_rect box, f32 min, f32 max, f32 *value, const char *format ){ f32 t; @@ -1446,6 +1446,8 @@ static void _ui_slider( ui_rect box, char buf[32]; snprintf( buf, sizeof(buf), format? format: "%.2f", *value ); ui_text( box, buf, 1, k_ui_align_middle_center, 0 ); + + return state; } static void ui_slider( ui_rect inout_panel, const char *str_label, @@ -1472,8 +1474,13 @@ static void ui_colourpicker( ui_rect inout_panel, const char *str_label, ui_split_ratio( sliders[0], k_ui_axis_h, 0.5f, 2, sliders[0], sliders[1] ); ui_split_ratio( sliders[2], k_ui_axis_h, 0.5f, 2, sliders[2], sliders[3] ); + v4f hsv; + vg_rgb_hsv( value, hsv ); + + enum ui_button_state modified = 0x00; + for( u32 i=0; i<4; i ++ ){ - _ui_slider( sliders[i], 0.0f, 1.0f, value+i, + modified |= _ui_slider( sliders[i], 0.0f, 1.0f, hsv+i, (const char *[]){ "hue %.2f", "sat %.2f", "lum %.2f", @@ -1484,6 +1491,7 @@ static void ui_colourpicker( ui_rect inout_panel, const char *str_label, ui_split_ratio( left, k_ui_axis_v, 0.8f, 8, square, preview ); u32 state = ui_colourbutton( square, 0, 0, 0, 0 ); + modified |= state; enum ui_button_state mask_using = @@ -1493,50 +1501,40 @@ static void ui_colourpicker( ui_rect inout_panel, const char *str_label, if( state & mask_using ){ for( u32 i=0; i<2; i ++ ){ - value[1+i] = vg_clampf( + hsv[1+i] = vg_clampf( (f32)(vg_ui.mouse[i] - square[i]) / (f32)(square[2+i]), 0.0f, 1.0f ); } - value[2] = 1.0f-value[2]; + hsv[2] = 1.0f-hsv[2]; + } + + if( modified & (k_ui_button_click|k_ui_button_holding_inside| + k_ui_button_holding_outside) ){ + vg_hsv_rgb( hsv, value ); } ui_outline( square, 1, ui_colour( state? k_ui_fg+3: k_ui_bg+3 ), 0 ); /* preview colour */ - i32 i = floorf( value[0]*6.0f ); - f32 v = value[2], - f = value[0] * 6.0f - (f32)i, - p = v * (1.0f-value[1]), - q = v * (1.0f-f*value[1]), - t = v * (1.0f-(1.0f-f)*value[1]); - v4f colour; - - switch( i % 6 ){ - case 0: colour[0] = v; colour[1] = t; colour[2] = p; break; - case 1: colour[0] = q; colour[1] = v; colour[2] = p; break; - case 2: colour[0] = p; colour[1] = v; colour[2] = t; break; - case 3: colour[0] = p; colour[1] = q; colour[2] = v; break; - case 4: colour[0] = t; colour[1] = p; colour[2] = v; break; - case 5: colour[0] = v; colour[1] = p; colour[2] = q; break; - } + vg_hsv_rgb( hsv, colour ); colour[3] = 1.0f; ui_fill( preview, v4f_u32_colour( colour ) ); /* Draw hsv shader thingy */ ui_flush( k_ui_shader_colour, vg.window_x, vg.window_y ); ui_fill_rect( square, 0xffffffff, (ui_px[4]){ 0,256,256,0 } ); - vg_ui.hue = value[0]; + vg_ui.hue = hsv[0]; ui_flush( k_ui_shader_hsv, vg.window_x, vg.window_y ); - ui_rect marker = { square[0] + value[1] * (f32)square[2] - 4, - square[1] + (1.0f-value[2]) * (f32)square[3] - 4, + ui_rect marker = { square[0] + hsv[1] * (f32)square[2] - 4, + square[1] + (1.0f-hsv[2]) * (f32)square[3] - 4, 8, 8 }, lx = { square[0], - square[1] + (1.0f-value[2]) * (f32)square[3], + square[1] + (1.0f-hsv[2]) * (f32)square[3], square[2], 1 }, - ly = { square[0] + value[1] * (f32)square[2], + ly = { square[0] + hsv[1] * (f32)square[2], square[1], 1, square[3] }; diff --git a/vg_m.h b/vg_m.h index 6cbac62..436ca63 100644 --- a/vg_m.h +++ b/vg_m.h @@ -2531,4 +2531,54 @@ static void vg_rand_cone( vg_rand *rand, v3f out_dir, f32 angle ){ out_dir[2] = cosf(r); } +static void vg_hsv_rgb( v3f hsv, v3f rgb ){ + i32 i = floorf( hsv[0]*6.0f ); + f32 v = hsv[2], + f = hsv[0] * 6.0f - (f32)i, + p = v * (1.0f-hsv[1]), + q = v * (1.0f-f*hsv[1]), + t = v * (1.0f-(1.0f-f)*hsv[1]); + + switch( i % 6 ){ + case 0: rgb[0] = v; rgb[1] = t; rgb[2] = p; break; + case 1: rgb[0] = q; rgb[1] = v; rgb[2] = p; break; + case 2: rgb[0] = p; rgb[1] = v; rgb[2] = t; break; + case 3: rgb[0] = p; rgb[1] = q; rgb[2] = v; break; + case 4: rgb[0] = t; rgb[1] = p; rgb[2] = v; break; + case 5: rgb[0] = v; rgb[1] = p; rgb[2] = q; break; + } +} + +static void vg_rgb_hsv( v3f rgb, v3f hsv ){ + f32 min = v3_minf( rgb ), + max = v3_maxf( rgb ), + range = max-min, + k_epsilon = 0.00001f; + + hsv[2] = max; + if( range < k_epsilon ){ + hsv[0] = 0.0f; + hsv[1] = 0.0f; + return; + } + + if( max > k_epsilon ){ + hsv[1] = range/max; + } + else { + hsv[0] = 0.0f; + hsv[1] = 0.0f; + return; + } + + if( rgb[0] >= max ) + hsv[0] = (rgb[1]-rgb[2])/range; + else if( max == rgb[1] ) + hsv[0] = 2.0f+(rgb[2]-rgb[0])/range; + else + hsv[0] = 4.0f+(rgb[0]-rgb[1])/range; + + hsv[0] = vg_fractf( hsv[0] * (60.0f/360.0f) ); +} + #endif /* VG_M_H */ -- 2.25.1