From 197d41a3e23cab35848f623c6133baccc62aacbe Mon Sep 17 00:00:00 2001 From: Andrew Opalach Date: Wed, 26 Aug 2026 17:56:52 -0400 Subject: OSD stuff and Android fixes Signed-off-by: Andrew Opalach --- src/render/renderer.h | 2 +- src/render/renderer_libplacebo.c | 300 ++++++++++++++++++++++++++++++++----- src/render/renderer_libplacebo.h | 23 ++- src/render/shaders/osd.h | 73 +++++++++ src/render/shaders/osd_binds.h | 311 +++++++++++++++++++++++++++++++++++++++ src/render/shaders/osd_header.h | 146 ++++++++++++++++++ 6 files changed, 818 insertions(+), 37 deletions(-) create mode 100644 src/render/shaders/osd.h create mode 100644 src/render/shaders/osd_binds.h create mode 100644 src/render/shaders/osd_header.h (limited to 'src/render') diff --git a/src/render/renderer.h b/src/render/renderer.h index 0eae5cb..ffd590e 100644 --- a/src/render/renderer.h +++ b/src/render/renderer.h @@ -48,7 +48,7 @@ struct camu_renderer { VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), VkResult (*vk_destroy_surface)(VkInstance, VkSurfaceKHR), - const char *const *(*vk_get_extensions)(u32 *), + const char * const *(*vk_get_extensions)(u32 *), #elif defined STELA_API_DX11 HWND win32_window, #elif defined STELA_API_OPENGL diff --git a/src/render/renderer_libplacebo.c b/src/render/renderer_libplacebo.c index d6f95a8..8c28162 100644 --- a/src/render/renderer_libplacebo.c +++ b/src/render/renderer_libplacebo.c @@ -2,15 +2,21 @@ //#define AL_LOG_ENABLE_TRACE #include #include +#include #include #include +#include #include "../screen/screen.h" #include "../util/color_palette.h" +#include "../util/print_time.h" #include "renderer_libplacebo.h" #include "queue_libplacebo.h" +#include "shaders/osd_header.h" +#include "shaders/osd.h" +#include "shaders/osd_binds.h" #include "shaders/vr_video.h" #ifdef AL_DEBUG @@ -21,14 +27,18 @@ #endif #define CRT_BACKGROUND -#define CRT_BACKGROUND_COLOR (1.f / 7.5f) -#define CRT_BACKGROUND_COLOR_ON (0.025f) +#define CRT_BACKGROUND_COLOR(c4) do { \ + c4[0] = 0.1333f; c4[1] = 0.1333f; c4[2] = 0.1333f; \ +} while (0) +#define CRT_BACKGROUND_COLOR_ON(lr, c4) do { \ + if (lr->params.background != PL_CLEAR_SKIP) { \ + c4[0] = 0.025f; c4[1] = 0.025f; c4[2] = 0.025f; \ + } else { \ + c4[0] = 0.f; c4[1] = 0.f; c4[2] = 0.f; \ + } \ +} while (0) -#ifdef CRT_BACKGROUND -static f32 clear_color[4] = { CRT_BACKGROUND_COLOR, CRT_BACKGROUND_COLOR, CRT_BACKGROUND_COLOR, 1.f }; -#else static f32 clear_color[4] = { 0.f, 0.f, 0.f, 1.f }; -#endif static struct pl_render_params default_params; @@ -62,13 +72,14 @@ static void renderer_lp_set(struct camu_renderer *renderer, u8 option, u8 value) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; switch (option) { - case CAMU_RENDERER_FULLSCREEN: + case CAMU_RENDERER_FULLSCREEN: { #ifdef STELA_API_DX11 IDXGISwapChain *d3d_swapchain = pl_d3d11_swapchain_unwrap(lr->swapchain); IDXGISwapChain_SetFullscreenState(d3d_swapchain, value, NULL); IDXGISwapChain_Release(d3d_swapchain); #endif break; + } case CAMU_RENDERER_SCALING: switch (value) { case CAMU_SCALING_DEFAULT: @@ -106,7 +117,7 @@ static void log_callback(void *userdata, enum pl_log_level level, const char *me // will be shot anyway so allow it. log_info(message); } else { - log_debug(message); + log_info(message); } } @@ -136,7 +147,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL (*get_vk_proc_address)(VkInstance, const char *), VkResult (*vk_create_surface)(void *, VkInstance, VkSurfaceKHR *), VkResult (*vk_destroy_surface)(VkInstance, VkSurfaceKHR), - const char *const *(*vk_get_extensions)(u32 *), + const char * const *(*vk_get_extensions)(u32 *), #elif defined STELA_API_DX11 HWND win32_window, #elif defined STELA_API_OPENGL @@ -174,7 +185,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid lr->vk_destroy_surface = vk_destroy_surface; u32 num; - const char *const *extensions = vk_get_extensions(&num); + const char * const *extensions = vk_get_extensions(&num); lr->vk_inst = pl_vk_inst_create(lr->logger, pl_vk_inst_params( .debug = RENDERER_DEBUG, .get_proc_addr = get_vk_proc_address, @@ -229,7 +240,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid // https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_chain_flag // https://learn.microsoft.com/en-us/windows/win32/api/dxgi/ne-dxgi-dxgi_swap_effect char *FLIP = getenv("SINK_DXGI_FLIP"); - if (!FLIP) FLIP = "0"; + if (!FLIP) FLIP = "1"; lr->swapchain = pl_d3d11_create_swapchain(lr->d3d11, pl_d3d11_swapchain_params( .window = win32_window, .blit = al_strscmp(FLIP, "0") == 0, @@ -280,6 +291,22 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid log_info("Using OpenGL."); #endif +#ifdef USE_LIBPLACEBO_CACHE + lr->cache = pl_cache_create(pl_cache_params( + .log = lr->logger, + .max_total_size = MB(50) + )); + pl_gpu_set_cache(lr->gpu, lr->cache); + FILE *cache_file = fopen("sink.cache", "rb"); + if (cache_file) { + pl_cache_load_file(lr->cache, cache_file); + //p->cache_sig = pl_cache_signature(p->cache); + fclose(cache_file); + } +#endif + + lr->dispatch = pl_dispatch_create(lr->gpu->log, lr->gpu); + lr->renderer = pl_renderer_create(lr->logger, lr->gpu); pl_swapchain_resize_compat(lr->swapchain, width, height); @@ -291,6 +318,7 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid al_memset(&lr->params, 0, sizeof(struct pl_render_params)); lr->params = default_params; + lr->params.deband_params = NULL; //lr->params.frame_mixer = NULL; @@ -302,16 +330,79 @@ static bool renderer_lp_create_renderer(struct camu_renderer *renderer, u32 *wid // Prioritize a more consistent image. lr->params.correct_subpixel_offsets = true; - //lr->params.distort_params = pl_distort_params(.unscaled = false); - lr->vr_emulation_hook[0] = pl_mpv_user_shader_parse(lr->gpu, vr_video_shader, sizeof(vr_video_shader) - 1); - /* + lr->osd.vars[0].var = pl_var_uvec2("screen"); + lr->osd.vars[1].var = pl_var_uint("scale"); + lr->osd.vars[2].var = pl_var_float("time"); + lr->osd.vars[3].var = pl_var_uint("show_osd"); + lr->osd.vars[4].var = pl_var_uint("connecting"); + lr->osd.vars[5].var = pl_var_uint("paused"); + lr->osd.vars[6].var = pl_var_uint("bar_mode"); + lr->osd.vars[7].var = pl_var_float("bar"); + lr->osd.vars[8].var = pl_var_float("dbar"); + lr->osd.vars[9].var = pl_var_float("bbar"); + lr->osd.vars[10].var = pl_var_uint("show_hour"); + lr->osd.vars[11].var = pl_var_uint("negative"); + static const char num_names[9][6] = { + "num1", "num2", "num3", "num4", + "num5", "num6", "num7", "num8", + "num9" + }; + for (u32 i = 0; i < 9; i++) { + lr->osd.vars[12 + i].var = pl_var_uint(num_names[i]); + } + for (u32 i = 0; i < 21; i++) { + lr->osd.vars[i].dynamic = true; + } + + lr->osd.attribs[0] = (struct pl_vertex_attrib){ + .name = "pos", + .offset = 0, + .fmt = pl_find_vertex_fmt(lr->gpu, PL_FMT_FLOAT, 2) + }; + lr->osd.attribs[1] = (struct pl_vertex_attrib){ + .name = "coord", + .offset = sizeof(f32) * 2, + .fmt = pl_find_vertex_fmt(lr->gpu, PL_FMT_FLOAT, 2) + }; + + al_memcpy(lr->osd.vertices, (f32[]){ + 1.f, 1.f, 1.f, 1.f, + -1.f, -1.f, 0.f, 0.f, + -1.f, 1.f, 0.f, 1.f, + -1.f, -1.f, 0.f, 0.f, + 1.f, -1.f, 1.f, 0.f, + 1.f, 1.f, 1.f, 1.f, + }, sizeof(f32) * 24); + + lr->osd.prelude = osd_header_shader; + lr->osd.header = osd_shader; + lr->osd.binds = osd_binds_shader; +#if 0 struct nn_file file; - if (nn_file_open(&file, &al_str_c(""), 0)) { + if (nn_file_open(&file, &al_str_c("../src/render/shaders/osd_header.glsl"), 0)) { char *c_str; - size_t length = nn_file_read_as_c_str(&file, &c_str); - const struct pl_hook *hook = pl_mpv_user_shader_parse(lr->gpu, (const char *)c_str, length); + nn_file_read_as_c_str(&file, &c_str); + lr->osd.prelude = c_str; + nn_file_close(&file); } - */ + if (nn_file_open(&file, &al_str_c("../src/render/shaders/osd.glsl"), 0)) { + char *c_str; + nn_file_read_as_c_str(&file, &c_str); + lr->osd.header = c_str; + nn_file_close(&file); + } + if (nn_file_open(&file, &al_str_c("../src/render/shaders/osd_binds.glsl"), 0)) { + char *c_str; + nn_file_read_as_c_str(&file, &c_str); + lr->osd.binds = c_str; + nn_file_close(&file); + } +#endif + lr->osd.tick_time = -1.0; + lr->osd.logged_fail = false; + + lr->vr_init_failed = false; + lr->vr_emulation_hook[0] = NULL; #ifdef CAMU_HAVE_FFMPEG lr->r.get_buffer2 = pl_get_buffer2; @@ -385,6 +476,125 @@ static inline intptr_t float_64_hash(f64 value) return hash; } +#define ROUND_SECONDS(h, m, s, n) do { \ + if (n >= 50) { \ + if (s == 59) { \ + if (m == 59) { \ + h++; \ + m = 0; \ + } else m++; \ + s = 0; \ + } else s++; \ + } \ +} while (0) + +static inline bool render_osd(struct camu_renderer_lp *lr, struct camu_screen *scr) +{ + f64 duration = scr->osd.duration / 1000000.0; + f32 bar, dbar, bbar; + f32 progress = ((duration != 0) ? scr->osd.pts / duration : 0.f); + if (scr->osd.bar_mode != CAMU_OSD_BAR_VOLUME) { + dbar = progress; + bbar = dbar; // @TODO: Should be buffered, once that's supported in the VCR. + } else { + dbar = 0.f; + bbar = 0.f; + } + bar = (scr->osd.bar_mode == CAMU_OSD_BAR_PROGRESS) ? progress : scr->osd.bar; + lr->osd.screen_size[0] = scr->width; + lr->osd.screen_size[1] = scr->height; + lr->osd.vars[0].data = lr->osd.screen_size; + u32 scale = 1; + lr->osd.vars[1].data = &scale; + f64 tick = nn_get_tick(); + if (lr->osd.tick_time == -1.0) lr->osd.tick_time = tick; + lr->osd.time = (f32)(tick - lr->osd.tick_time); + lr->osd.vars[2].data = &lr->osd.time; + lr->osd.vars[3].data = &scr->osd.show; + lr->osd.vars[4].data = &scr->osd.connecting; + lr->osd.vars[5].data = &scr->osd.paused; + lr->osd.vars[6].data = &scr->osd.bar_mode; + lr->osd.vars[7].data = &bar; + lr->osd.vars[8].data = &dbar; + lr->osd.vars[9].data = &bbar; + u32 hours1, minutes1, seconds1, hundredths; + u32 show_hour; + show_hour = camu_split_time(scr->osd.duration, &hours1, &minutes1, &seconds1, &hundredths); + ROUND_SECONDS(hours1, minutes1, seconds1, hundredths); + lr->osd.vars[10].data = &show_hour; + u32 negative; + negative = scr->osd.pts < 0.0f; + lr->osd.vars[11].data = &negative; + lr->osd.vars[15].data = &hours1; + lr->osd.vars[16].data = &minutes1; + lr->osd.vars[17].data = &seconds1; + u32 hours2, minutes2, seconds2; + camu_split_time(fabs(scr->osd.pts) * 1000000u, &hours2, &minutes2, &seconds2, &hundredths); + // The trade-off of rounding PTS is that if we do, second 0 will be shown for only half a second. + // If we don't, more noticeably, PTS will never equal duration if duration rounds up. + // There's also the option of not rounding either. + ROUND_SECONDS(hours2, minutes2, seconds2, hundredths); + lr->osd.vars[12].data = &hours2; + lr->osd.vars[13].data = &minutes2; + lr->osd.vars[14].data = &seconds2; + u32 zero = 0; + lr->osd.vars[18].data = &zero; + lr->osd.vars[19].data = &zero; + lr->osd.vars[20].data = &zero; + if (scr->osd.bar_mode == CAMU_OSD_BAR_SEEK) { + u32 hours3, minutes3, seconds3; + camu_split_time(fabs(duration * bar) * 1000000u, &hours3, &minutes3, &seconds3, &hundredths); + ROUND_SECONDS(hours3, minutes3, seconds3, hundredths); + lr->osd.vars[18].data = &hours3; + lr->osd.vars[19].data = &minutes3; + lr->osd.vars[20].data = &seconds3; + } else { + f64 whole = floor(bar); + f64 frac = (bar - whole) * 100.0; + u32 num1, num2; + num1 = (u32)whole; + num2 = (u32)round(frac); + lr->osd.vars[19].data = &num1; + lr->osd.vars[20].data = &num2; + } + + lr->osd.sh = pl_dispatch_begin(lr->dispatch); + pl_shader_custom(lr->osd.sh, &(struct pl_custom_shader){ + .description = "osd", + .prelude = lr->osd.prelude, + .header = scr->osd.show_binds ? lr->osd.binds : lr->osd.header, + .body = "color = (show_osd == 0u) ? vec4(0.) : draw_osd();", + .output = PL_SHADER_SIG_COLOR, + .num_variables = 21, + .variables = lr->osd.vars + }); + + struct pl_color_repr repr = lr->frame.color_repr; + pl_shader_color_map_ex(lr->osd.sh, NULL, pl_color_map_args( + .src = pl_color_space_srgb, + .dst = lr->frame.color_space + )); + pl_shader_encode_color(lr->osd.sh, &repr); + + struct pl_dispatch_vertex_params params = { 0 }; + params = *pl_dispatch_vertex_params( + .shader = &lr->osd.sh, + .target = lr->frame.fbo, + .blend_params = &pl_alpha_overlay, + .vertex_attribs = lr->osd.attribs, + .num_vertex_attribs = 2, + .vertex_stride = sizeof(f32) * 4, + .vertex_position_idx = 0, + .vertex_coords = PL_COORDS_NORMALIZED, + .vertex_flipped = lr->frame.flipped, + .vertex_type = PL_PRIM_TRIANGLE_LIST, + .vertex_count = 6, + .vertex_data = lr->osd.vertices + ); + + return pl_dispatch_vertex(lr->dispatch, ¶ms); +} + static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_screen *scr, bool force) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)renderer; @@ -396,9 +606,8 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree #endif if (!lr->have_frame) { - struct pl_swapchain_frame frame; - if (pl_swapchain_start_frame(lr->swapchain, &frame)) { - pl_frame_from_swapchain(&lr->target, &frame); + if (pl_swapchain_start_frame(lr->swapchain, &lr->frame)) { + pl_frame_from_swapchain(&lr->target, &lr->frame); lr->have_frame = true; #ifdef CRT_BACKGROUND lr->frame_cleared = false; @@ -413,7 +622,15 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree } f64 mouse_x, mouse_y; - bool vr_emulation = scr->vr_emulation && lr->vr_emulation_hook[0]; + bool vr_emulation = scr->vr_emulation && !lr->vr_init_failed; + if (vr_emulation && !lr->vr_emulation_hook[0]) { + lr->vr_emulation_hook[0] = pl_mpv_user_shader_parse(lr->gpu, vr_video_shader, sizeof(vr_video_shader) - 1); + lr->vr_init_failed = !lr->vr_emulation_hook[0]; + if (lr->vr_init_failed) { + log_error("Failed to compile VR emulation shader."); + vr_emulation = false; + } + } if (vr_emulation) { mouse_x = (scr->last_pointer_x / scr->width) - (scr->vr_calibrate_x - 0.5); mouse_y = (scr->last_pointer_y / scr->height) - (scr->vr_calibrate_y - 0.5); @@ -484,8 +701,8 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree target->crop.x1 += video->view.x_offset; target->crop.y1 += video->view.y_offset; target->rotation = mix.frames[0]->rotation - video->view.rotation; - /* //lr->params.color_map_params = pl_color_map_params(.inverse_tone_mapping = true); + /* if () { target->color = pl_color_space_srgb; target->color.hdr.max_luma = PL_COLOR_SDR_WHITE - 50.f; @@ -494,15 +711,7 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree */ #ifdef CRT_BACKGROUND if (!lr->frame_cleared) { - if (lr->params.background != PL_CLEAR_SKIP) { - clear_color[0] = CRT_BACKGROUND_COLOR_ON; - clear_color[1] = CRT_BACKGROUND_COLOR_ON; - clear_color[2] = CRT_BACKGROUND_COLOR_ON; - } else { - clear_color[0] = 0.f; - clear_color[1] = 0.f; - clear_color[2] = 0.f; - } + CRT_BACKGROUND_COLOR_ON(lr, clear_color); pl_frame_clear_rgba(lr->gpu, &lr->target, clear_color); lr->frame_cleared = true; } @@ -539,14 +748,20 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree #ifdef CRT_BACKGROUND if (!lr->frame_cleared) { - clear_color[0] = CRT_BACKGROUND_COLOR; - clear_color[1] = CRT_BACKGROUND_COLOR; - clear_color[2] = CRT_BACKGROUND_COLOR; + CRT_BACKGROUND_COLOR(clear_color); pl_frame_clear_rgba(lr->gpu, &lr->target, clear_color); lr->frame_cleared = true; } #endif + if (scr->osd.show || (result & RESULT_WAIT)) { + al_assert(lr->osd.prelude && lr->osd.header && lr->osd.binds); + if (!render_osd(lr, scr) && !lr->osd.logged_fail) { + log_error("Failed to render OSD."); + lr->osd.logged_fail = true; + } + } + if (pl_swapchain_submit_frame(lr->swapchain)) { lr->have_frame = false; } else { @@ -571,10 +786,25 @@ static bool renderer_lp_render(struct camu_renderer *renderer, struct camu_scree void renderer_lp_free(struct camu_renderer **renderer) { struct camu_renderer_lp *lr = (struct camu_renderer_lp *)*renderer; + if (lr->have_frame) { + pl_swapchain_submit_frame(lr->swapchain); + lr->have_frame = false; + } #ifdef CAMU_HAVE_SUBTITLES if (lr->ass) ass_library_done(lr->ass); #endif if (lr->vr_emulation_hook[0]) pl_mpv_user_shader_destroy(&lr->vr_emulation_hook[0]); +#ifdef USE_LIBPLACEBO_CACHE + if (lr->cache) { + FILE *cache_file = fopen("sink.cache", "wb"); + if (cache_file) { + pl_cache_save_file(lr->cache, cache_file); + fclose(cache_file); + } + pl_cache_destroy(&lr->cache); + } +#endif + if (lr->dispatch) pl_dispatch_destroy(&lr->dispatch); if (lr->renderer) pl_renderer_destroy(&lr->renderer); if (lr->swapchain) pl_swapchain_destroy(&lr->swapchain); #if defined STELA_API_VULKAN diff --git a/src/render/renderer_libplacebo.h b/src/render/renderer_libplacebo.h index 532963f..a8a5001 100644 --- a/src/render/renderer_libplacebo.h +++ b/src/render/renderer_libplacebo.h @@ -16,6 +16,8 @@ #include #endif +//#define USE_LIBPLACEBO_CACHE + struct camu_renderer_lp { struct camu_renderer r; #if defined STELA_API_VULKAN @@ -29,15 +31,34 @@ struct camu_renderer_lp { pl_opengl gl; #endif pl_gpu gpu; +#ifdef USE_LIBPLACEBO_CACHE + pl_cache cache; +#endif + pl_dispatch dispatch; pl_log logger; pl_swapchain swapchain; - struct pl_frame target; + struct pl_swapchain_frame frame; bool have_frame; bool frame_cleared; + struct pl_frame target; pl_renderer renderer; f64 last_swap_tick; struct pl_render_params params; + struct { + char *prelude; + char *header; + char *binds; + pl_shader sh; + u32 screen_size[2]; + f32 time; + struct pl_shader_var vars[21]; + f32 vertices[24]; + struct pl_vertex_attrib attribs[2]; + f64 tick_time; + bool logged_fail; + } osd; const struct pl_hook *vr_emulation_hook[1]; + bool vr_init_failed; #ifdef CAMU_HAVE_SUBTITLES ASS_Library *ass; #endif diff --git a/src/render/shaders/osd.h b/src/render/shaders/osd.h new file mode 100644 index 0000000..1109a50 --- /dev/null +++ b/src/render/shaders/osd.h @@ -0,0 +1,73 @@ +static char osd_shader[] = \ +"float text(vec2 uv, vec2 pos1, vec2 pos2) {\n" +" float col = 0.;\n" +" pp = pos1;\n" +" if (connecting != 0u) {\n" +" float t = mod(time,1.8);\n" +" for (int i = 0; i < 3; i++) {\n" +" col += char(ch_per,uv)*float(t >= float(i)*0.6);\n" +" }\n" +" } else if (paused != 0u) {\n" +" col = char(ch_p,uv)+char(ch_a,uv)+char(ch_u,uv)+char(ch_s,uv)+char(ch_e,uv)+char(ch_d,uv);\n" +" }\n" +" pp = pos2;\n" +" if (negative != 0u) {\n" +" col += char(ch_dsh,uv);\n" +" }\n" +" if (show_hour != 0u) {\n" +" col += integer(num1,uv)+char(ch_col,uv);\n" +" }\n" +" col += integer(num2,uv)+char(ch_col,uv)+integer(num3,uv)+char(ch_lsl,uv);\n" +" if (show_hour != 0u) {\n" +" col += integer(num4,uv)+char(ch_col,uv);\n" +" }\n" +" col += integer(num5,uv)+char(ch_col,uv)+integer(num6,uv);\n" +" return col;\n" +"}\n" +"float text_over(vec2 uv, vec2 pos3) {\n" +" float col = 0.;\n" +" pp = pos3;\n" +" if (show_hour != 0u && bar_mode == 1u) {\n" +" col = integer(num7,uv)+char(ch_col,uv);\n" +" }\n" +" col += integer(num8,uv)+((bar_mode == 2u) ? char(ch_per,uv) : char(ch_col,uv))+integer(num9,uv);\n" +" return col;\n" +"}\n" +"vec4 draw_osd() {\n" +" vec2 sf = vec2(screen/scale);\n" +" vec2 ss = sf/3.;\n" +" vec2 c = vec2(coord.x,1.-coord.y);\n" +" vec2 uv = c*ss;\n" +" vec2 pos1 = vec2(8.,ss.y-4.-STRH(1.));\n" +" float width1 = (show_hour != 0u) ? 17. : 11.;\n" +" width1 += float(negative);\n" +" vec2 pos2 = floor(vec2(ss.x/2.-STRW(width1)/2.,ss.y/9.));\n" +" pos2.x -= STRW(0.5) * float(negative);\n" +" float ov = fract(bar);\n" +" ov = (-1.+(bar-ov)+float(c.x < ov))/1.5;\n" +" vec4 color = mix(bcolor,mix(tcolor,vec4(0.7,0.45,0.,1.),ov),float(c.x < bar));\n" +" float alpha = (c.x >= bar) ? 0.7 : 1.;\n" +" color = mix(color,vec4(tcolor.xyz,alpha)+float(bar > dbar)*0.15,float(c.x < dbar));\n" +" color = mix(color,vec4(tcolor.xyz,alpha-0.1)+float(bar > bbar)*0.15,float(c.x < bbar)*0.5);\n" +" color *= float(uv.y <= 5.);\n" +" if (paused != 0u) {\n" +" color = mix(color,bcolor,in_box(uv,pos1-vec2(2.,2.),pos1+vec2(STRW(6.)+1.,STRH(1.)+1.)));\n" +" }\n" +" color = mix(color,bcolor,in_box(uv,pos2-vec2(3.,1.),pos2+vec2(STRW(width1)+2.,STRH(1.)+2.)));\n" +" float pixel = text(uv,pos1,pos2);\n" +" color = mix(color,tcolor,pixel);\n" +" color -= pixel*float(mod(c.y*sf.y,3.) < 1.)*0.5;\n" +" if (bar_mode != 0u) {\n" +" ss = sf/2.;\n" +" uv = c*ss;\n" +" float width2 = (show_hour != 0u && bar_mode == 1u) ? 8. : 5.;\n" +" vec2 pos3 = floor(vec2(ss.x/2.-STRW(width2)/2.,11.));\n" +" float box = in_box(uv,pos3-vec2(2.,2.),pos3+vec2(STRW(width2)+1.,STRH(1.)+3.));\n" +" color.xyz = mix(color.xyz,bcolor.xyz,box);\n" +" color.w = color.w+(bcolor.w*box);\n" +" pixel = text_over(uv,pos3);\n" +" color = mix(color,tcolor,pixel);\n" +" color -= pixel*float(mod(c.y*sf.y,2.) < 1.)*0.5;\n" +" }\n" +" return color;\n" +"}\n"; diff --git a/src/render/shaders/osd_binds.h b/src/render/shaders/osd_binds.h new file mode 100644 index 0000000..5d6806a --- /dev/null +++ b/src/render/shaders/osd_binds.h @@ -0,0 +1,311 @@ +static char osd_binds_shader[] = \ +"float text(vec2 uv, vec2 pos) {\n" +" float col = 0.;\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_L,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_f,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_R,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_h,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(1)\n" +" col += char(ch_N,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_x,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_P,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_v,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_lpa,uv);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_col,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_crs,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_dsh,uv);\n" +" col += char(ch_1,uv);\n" +" col += char(ch_0,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_rpa,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_p,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_c,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(6)\n" +" col += char(ch_P,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_e,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_M,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_M,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_lpa,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_h,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_f,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_col,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_1,uv);\n" +" col += char(ch_0,uv);\n" +" col += char(ch_0,uv);\n" +" col += char(ch_pct,uv);\n" +" col += char(ch_rpa,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_T,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_b,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(8)\n" +" col += char(ch_T,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_O,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_D,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(7)\n" +" col += char(ch_S,uv);\n" +" col += char(ch_h,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_w,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_O,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_D,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_k,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_lpa,uv);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_c,uv);\n" +" col += char(ch_k,uv);\n" +" col += char(ch_rpa,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_T,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_b,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_s,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_E,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_R,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_k,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_crs,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_dsh,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(8)\n" +" col += char(ch_Z,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_m,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_I,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_lsl,uv);\n" +" col += char(ch_O,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_t,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_N,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_D,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_b,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_c,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_g,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_T,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_p,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_B,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_c,uv);\n" +" col += char(ch_k,uv);\n" +" col += char(ch_g,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_o,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_d,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_V,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_V,uv);\n" +" col += char(ch_R,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_lpa,uv);\n" +" col += char(ch_S,uv);\n" +" col += char(ch_h,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_f,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_col,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_3,uv);\n" +" col += char(ch_6,uv);\n" +" col += char(ch_0,uv);\n" +" col += char(ch_dgr,uv);\n" +" col += char(ch_com,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_l,uv);\n" +" col += char(ch_col,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_C,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_n,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_r,uv);\n" +" col += char(ch_rpa,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_B,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_S,uv);\n" +" col += char(ch_w,uv);\n" +" col += char(ch_a,uv);\n" +" col += char(ch_p,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_E,uv);\n" +" col += char(ch_y,uv);\n" +" col += char(ch_e,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_R,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_R,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_s,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_t,uv);\n" +" col += char(ch_spc,uv);\n" +" col += char(ch_V,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_e,uv);\n" +" col += char(ch_w,uv);\n" +" pos.y -= STRH(1.2);\n" +" pp = vec2(pos.x,pos.y);\n" +" col += char(ch_Q,uv);\n" +" col += char(ch_col,uv);\n" +" spaces(10)\n" +" col += char(ch_Q,uv);\n" +" col += char(ch_u,uv);\n" +" col += char(ch_i,uv);\n" +" col += char(ch_t,uv);\n" +" return col;\n" +"}\n" +"vec4 draw_osd() {\n" +" vec2 sf = vec2(screen/scale);\n" +" vec2 ss = sf/2.;\n" +" vec2 c = vec2(coord.x,1.-coord.y);\n" +" vec2 uv = c*ss;\n" +" vec2 pos = floor(vec2(ss.x/2.-STRW(43.)/2.,(ss.y/2.)+STRH(1.2*10.)));\n" +" float pixel = text(uv, pos);\n" +" float box = in_box(uv,pos-vec2(8.,STRH(1.2*13.)+8.),pos+vec2(STRW(43.)+8.,STRH(1.2)+8.));\n" +" vec4 color = bcolor*box;\n" +" color = mix(color,tcolor,pixel);\n" +" color -= pixel*float(mod(c.y*sf.y,3.) < 1.)*0.5;\n" +" return color;\n" +"}\n"; diff --git a/src/render/shaders/osd_header.h b/src/render/shaders/osd_header.h new file mode 100644 index 0000000..5ba6491 --- /dev/null +++ b/src/render/shaders/osd_header.h @@ -0,0 +1,146 @@ +static char osd_header_shader[] = \ +"#define ch_dgr uvec4(0x001824,0x241800,0x000000,0x000000)\n" +"#define ch_spc uvec4(0x000000,0x000000,0x000000,0x000000)\n" +"#define ch_exc uvec4(0x003078,0x787830,0x300030,0x300000)\n" +"#define ch_quo uvec4(0x006666,0x662400,0x000000,0x000000)\n" +"#define ch_hsh uvec4(0x006C6C,0xFE6C6C,0x6CFE6C,0x6C0000)\n" +"#define ch_dol uvec4(0x30307C,0xC0C078,0x0C0CF8,0x303000)\n" +"#define ch_pct uvec4(0x000000,0xC4CC18,0x3060CC,0x8C0000)\n" +"#define ch_amp uvec4(0x0070D8,0xD870FA,0xDECCDC,0x760000)\n" +"#define ch_apo uvec4(0x003030,0x306000,0x000000,0x000000)\n" +"#define ch_lbr uvec4(0x000C18,0x306060,0x603018,0x0C0000)\n" +"#define ch_rbr uvec4(0x006030,0x180C0C,0x0C1830,0x600000)\n" +"#define ch_ast uvec4(0x000000,0x663CFF,0x3C6600,0x000000)\n" +"#define ch_crs uvec4(0x000000,0x18187E,0x181800,0x000000)\n" +"#define ch_com uvec4(0x000000,0x000000,0x000038,0x386000)\n" +"#define ch_dsh uvec4(0x000000,0x0000FE,0x000000,0x000000)\n" +"#define ch_per uvec4(0x000000,0x000000,0x000038,0x380000)\n" +"#define ch_lsl uvec4(0x000002,0x060C18,0x3060C0,0x800000)\n" +"#define ch_0 uvec4(0x007CC6,0xD6D6D6,0xD6D6C6,0x7C0000)\n" +"#define ch_1 uvec4(0x001030,0xF03030,0x303030,0xFC0000)\n" +"#define ch_2 uvec4(0x0078CC,0xCC0C18,0x3060CC,0xFC0000)\n" +"#define ch_3 uvec4(0x0078CC,0x0C0C38,0x0C0CCC,0x780000)\n" +"#define ch_4 uvec4(0x000C1C,0x3C6CCC,0xFE0C0C,0x1E0000)\n" +"#define ch_5 uvec4(0x00FCC0,0xC0C0F8,0x0C0CCC,0x780000)\n" +"#define ch_6 uvec4(0x003860,0xC0C0F8,0xCCCCCC,0x780000)\n" +"#define ch_7 uvec4(0x00FEC6,0xC6060C,0x183030,0x300000)\n" +"#define ch_8 uvec4(0x0078CC,0xCCEC78,0xDCCCCC,0x780000)\n" +"#define ch_9 uvec4(0x0078CC,0xCCCC7C,0x181830,0x700000)\n" +"#define ch_col uvec4(0x000000,0x383800,0x003838,0x000000)\n" +"#define ch_scl uvec4(0x000000,0x383800,0x003838,0x183000)\n" +"#define ch_les uvec4(0x000C18,0x3060C0,0x603018,0x0C0000)\n" +"#define ch_equ uvec4(0x000000,0x007E00,0x7E0000,0x000000)\n" +"#define ch_grt uvec4(0x006030,0x180C06,0x0C1830,0x600000)\n" +"#define ch_que uvec4(0x0078CC,0x0C1830,0x300030,0x300000)\n" +"#define ch_ats uvec4(0x007CC6,0xC6DEDE,0xDEC0C0,0x7C0000)\n" +"#define ch_A uvec4(0x003078,0xCCCCCC,0xFCCCCC,0xCC0000)\n" +"#define ch_B uvec4(0x00FC66,0x66667C,0x666666,0xFC0000)\n" +"#define ch_C uvec4(0x003C66,0xC6C0C0,0xC0C666,0x3C0000)\n" +"#define ch_D uvec4(0x00F86C,0x666666,0x66666C,0xF80000)\n" +"#define ch_E uvec4(0x00FE62,0x60647C,0x646062,0xFE0000)\n" +"#define ch_F uvec4(0x00FE66,0x62647C,0x646060,0xF00000)\n" +"#define ch_G uvec4(0x003C66,0xC6C0C0,0xCEC666,0x3E0000)\n" +"#define ch_H uvec4(0x00CCCC,0xCCCCFC,0xCCCCCC,0xCC0000)\n" +"#define ch_I uvec4(0x007830,0x303030,0x303030,0x780000)\n" +"#define ch_J uvec4(0x001E0C,0x0C0C0C,0xCCCCCC,0x780000)\n" +"#define ch_K uvec4(0x00E666,0x6C6C78,0x6C6C66,0xE60000)\n" +"#define ch_L uvec4(0x00F060,0x606060,0x626666,0xFE0000)\n" +"#define ch_M uvec4(0x00C6EE,0xFEFED6,0xC6C6C6,0xC60000)\n" +"#define ch_N uvec4(0x00C6C6,0xE6F6FE,0xDECEC6,0xC60000)\n" +"#define ch_O uvec4(0x00386C,0xC6C6C6,0xC6C66C,0x380000)\n" +"#define ch_P uvec4(0x00FC66,0x66667C,0x606060,0xF00000)\n" +"#define ch_Q uvec4(0x00386C,0xC6C6C6,0xCEDE7C,0x0C1E00)\n" +"#define ch_R uvec4(0x00FC66,0x66667C,0x6C6666,0xE60000)\n" +"#define ch_S uvec4(0x0078CC,0xCCC070,0x18CCCC,0x780000)\n" +"#define ch_T uvec4(0x00FCB4,0x303030,0x303030,0x780000)\n" +"#define ch_U uvec4(0x00CCCC,0xCCCCCC,0xCCCCCC,0x780000)\n" +"#define ch_V uvec4(0x00CCCC,0xCCCCCC,0xCCCC78,0x300000)\n" +"#define ch_W uvec4(0x00C6C6,0xC6C6D6,0xD66C6C,0x6C0000)\n" +"#define ch_X uvec4(0x00CCCC,0xCC7830,0x78CCCC,0xCC0000)\n" +"#define ch_Y uvec4(0x00CCCC,0xCCCC78,0x303030,0x780000)\n" +"#define ch_Z uvec4(0x00FECE,0x981830,0x6062C6,0xFE0000)\n" +"#define ch_lsb uvec4(0x003C30,0x303030,0x303030,0x3C0000)\n" +"#define ch_rsl uvec4(0x000080,0xC06030,0x180C06,0x020000)\n" +"#define ch_rsb uvec4(0x003C0C,0x0C0C0C,0x0C0C0C,0x3C0000)\n" +"#define ch_pow uvec4(0x10386C,0xC60000,0x000000,0x000000)\n" +"#define ch_usc uvec4(0x000000,0x000000,0x000000,0x00FF00)\n" +"#define ch_a uvec4(0x000000,0x00780C,0x7CCCCC,0x760000)\n" +"#define ch_b uvec4(0x00E060,0x607C66,0x666666,0xDC0000)\n" +"#define ch_c uvec4(0x000000,0x0078CC,0xC0C0CC,0x780000)\n" +"#define ch_d uvec4(0x001C0C,0x0C7CCC,0xCCCCCC,0x760000)\n" +"#define ch_e uvec4(0x000000,0x0078CC,0xFCC0CC,0x780000)\n" +"#define ch_f uvec4(0x00386C,0x6060F8,0x606060,0xF00000)\n" +"#define ch_g uvec4(0x000000,0x0076CC,0xCCCC7C,0x0CCC78)\n" +"#define ch_h uvec4(0x00E060,0x606C76,0x666666,0xE60000)\n" +"#define ch_i uvec4(0x001818,0x007818,0x181818,0x7E0000)\n" +"#define ch_j uvec4(0x000C0C,0x003C0C,0x0C0C0C,0xCCCC78)\n" +"#define ch_k uvec4(0x00E060,0x60666C,0x786C66,0xE60000)\n" +"#define ch_l uvec4(0x007818,0x181818,0x181818,0x7E0000)\n" +"#define ch_m uvec4(0x000000,0x00FCD6,0xD6D6D6,0xC60000)\n" +"#define ch_n uvec4(0x000000,0x00F8CC,0xCCCCCC,0xCC0000)\n" +"#define ch_o uvec4(0x000000,0x0078CC,0xCCCCCC,0x780000)\n" +"#define ch_p uvec4(0x000000,0x00DC66,0x666666,0x7C60F0)\n" +"#define ch_q uvec4(0x000000,0x0076CC,0xCCCCCC,0x7C0C1E)\n" +"#define ch_r uvec4(0x000000,0x00EC6E,0x766060,0xF00000)\n" +"#define ch_s uvec4(0x000000,0x0078CC,0x6018CC,0x780000)\n" +"#define ch_t uvec4(0x000020,0x60FC60,0x60606C,0x380000)\n" +"#define ch_u uvec4(0x000000,0x00CCCC,0xCCCCCC,0x760000)\n" +"#define ch_v uvec4(0x000000,0x00CCCC,0xCCCC78,0x300000)\n" +"#define ch_w uvec4(0x000000,0x00C6C6,0xD6D66C,0x6C0000)\n" +"#define ch_x uvec4(0x000000,0x00C66C,0x38386C,0xC60000)\n" +"#define ch_y uvec4(0x000000,0x006666,0x66663C,0x0C18F0)\n" +"#define ch_z uvec4(0x000000,0x00FC8C,0x1860C4,0xFC0000)\n" +"#define ch_lpa uvec4(0x001C30,0x3060C0,0x603030,0x1C0000)\n" +"#define ch_bar uvec4(0x001818,0x181800,0x181818,0x180000)\n" +"#define ch_rpa uvec4(0x00E030,0x30180C,0x183030,0xE00000)\n" +"#define ch_tid uvec4(0x0073DA,0xCE0000,0x000000,0x000000)\n" +"#define ch_lar uvec4(0x000000,0x10386C,0xC6C6FE,0x000000)\n" +"#define spaces(n) for (int i = 0; i < n; i++) { col += char(ch_spc,uv); }\n" +"#define STRW(c) (c*8.)\n" +"#define STRH(c) (c*12.)\n" +"const vec4 tcolor = vec4(0.78,0.76,0.76,1.);\n" +"const vec4 bcolor = vec4(0.1,0.1,0.1,0.65);\n" +"vec2 pp = vec2(0.);\n" +"float in_box(vec2 v, vec2 bl, vec2 tr) {\n" +" vec2 s = step(bl,v)-step(tr,v);\n" +" return s.x*s.y;\n" +"}\n" +"float sprite(uvec4 spr, vec2 uv) {\n" +" uint b = uint((7.-uv.x)+uv.y*8.);\n" +" uvec4 bv = (spr>>min(uvec4(b-72u,b-48u,b-24u,b),31u))&1u;\n" +#ifndef NAUNET_ON_ANDROID +#define HAVE_UVEC_DOT +#endif +#ifdef HAVE_UVEC_DOT +" return in_box(uv,vec2(0.),vec2(8.,12.))*float(dot(bv,uvec4(1u)));\n" +#else +" return in_box(uv,vec2(0.),vec2(8.,12.))*float(bv.x+bv.y+bv.z+bv.w);\n" +#endif +"}\n" +"float char(uvec4 ch, vec2 uv) {\n" +" float px = sprite(ch,floor(uv-pp));\n" +" pp += vec2(8.,0.);\n" +" return px;\n" +"}\n" +"uvec4 digit(uint d) {\n" +" switch (d) {\n" +" case 0: return ch_0;\n" +" case 1: return ch_1;\n" +" case 2: return ch_2;\n" +" case 3: return ch_3;\n" +" case 4: return ch_4;\n" +" case 5: return ch_5;\n" +" case 6: return ch_6;\n" +" case 7: return ch_7;\n" +" case 8: return ch_8;\n" +" case 9:\n" +" default: return ch_9;\n" +" }\n" +"}\n" +"float integer(uint number, vec2 uv) {\n" +" float r = 0.;\n" +" for (int i = 1; i >= 0; i--) {\n" +" r += char(digit(uint(mod(float(number)/max(1.,float(i)*10.),10.))),uv);\n" +" }\n" +" return r;\n" +"}\n"; -- cgit v1.2.3-101-g0448