Commit 2449ba51 authored by Niklas Haas's avatar Niklas Haas
Browse files

demos/plplay: add GUI for loading custom LUTs

Implemented using drag&drop region because nuklear doesn't provide
anything resembling a file picker dialog.

This is only for `pl_render_params.lut`, not for image/target LUTs. This
is obviously suboptimal, but I need a better place to override those.
parent 287684ab
......@@ -12,6 +12,7 @@
#include <pthread.h>
#include <time.h>
#include <libavutil/file.h>
#include <libavutil/pixdesc.h>
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
......@@ -28,6 +29,7 @@ static bool ui_draw(struct ui *ui, const struct pl_swapchain_frame *frame) { ret
#endif
#include <libplacebo/renderer.h>
#include <libplacebo/shaders/lut.h>
#include <libplacebo/utils/libav.h>
#include <libplacebo/utils/frame_queue.h>
......@@ -513,13 +515,14 @@ static void update_settings(struct plplay *p)
NK_WINDOW_TITLE;
ui_update_input(p->ui, p->win);
const char *dropped_file = window_get_file(p->win);
const struct pl_filter_preset *f;
struct pl_render_params *par = &p->params;
if (nk_begin(nk, "Settings", nk_rect(100, 100, 600, 600), win_flags)) {
nk_layout_row(nk, NK_DYNAMIC, 24, 2, (float[2]){ 0.3, 0.7 });
nk_layout_row(nk, NK_DYNAMIC, 24, 2, (float[]){ 0.3, 0.7 });
nk_label(nk, "Upscaler:", NK_TEXT_LEFT);
if (nk_combo_begin_label(nk, p->upscaler->description, nk_vec2(nk_widget_width(nk), 500))) {
nk_layout_row_dynamic(nk, 16, 1);
......@@ -558,7 +561,7 @@ static void update_settings(struct plplay *p)
nk_label(nk, "Antiringing:", NK_TEXT_LEFT);
nk_slider_float(nk, 0.0, &par->antiringing_strength, 1.0, 0.01f);
nk_layout_row(nk, NK_DYNAMIC, 24, 2, (float[2]){ 0.3, 0.7 });
nk_layout_row(nk, NK_DYNAMIC, 24, 2, (float[]){ 0.3, 0.7 });
nk_label(nk, "Frame mixer:", NK_TEXT_LEFT);
if (nk_combo_begin_label(nk, p->frame_mixer->description, nk_vec2(nk_widget_width(nk), 300))) {
nk_layout_row_dynamic(nk, 16, 1);
......@@ -623,6 +626,44 @@ static void update_settings(struct plplay *p)
nk_tree_pop(nk);
}
if (nk_tree_push(nk, NK_TREE_NODE, "Custom color LUT", NK_MINIMIZED)) {
nk_layout_row_dynamic(nk, 50, 1);
if (ui_widget_hover(nk, "Drop .cube file here...") && dropped_file) {
uint8_t *buf;
size_t size;
int ret = av_file_map(dropped_file, &buf, &size, 0, NULL);
if (ret < 0) {
fprintf(stderr, "Failed opening '%s': %s\n", dropped_file,
av_err2str(ret));
} else {
pl_lut_free((struct pl_custom_lut **) &par->lut);
par->lut = pl_lut_parse_cube(p->ctx, buf, size);
av_file_unmap(buf, size);
}
}
static const char *lut_types[] = {
[PL_LUT_UNKNOWN] = "Auto (unknown)",
[PL_LUT_NATIVE] = "Raw RGB (native)",
[PL_LUT_NORMALIZED] = "Linear RGB (normalized)",
[PL_LUT_CONVERSION] = "Gamut conversion (native)",
};
nk_layout_row(nk, NK_DYNAMIC, 24, 3, (float[]){ 0.2, 0.3, 0.5 });
if (nk_button_label(nk, "Clear")) {
pl_lut_free((struct pl_custom_lut **) &par->lut);
par->lut_type = PL_LUT_UNKNOWN;
}
nk_labelf(nk, NK_TEXT_CENTERED, "LUT type:");
par->lut_type = nk_combo(nk, lut_types, 4, par->lut_type,
16, nk_vec2(nk_widget_width(nk), 100));
nk_tree_pop(nk);
}
if (is_file_hdr(p)) {
if (nk_tree_push(nk, NK_TREE_NODE, "HDR peak detection", NK_MINIMIZED)) {
struct pl_peak_detect_params *ppar = &p->peak_detect_params;
......
......@@ -22,3 +22,35 @@ void ui_destroy(struct ui **ui);
void ui_update_input(struct ui *ui, const struct window *window);
struct nk_context *ui_get_context(struct ui *ui);
bool ui_draw(struct ui *ui, const struct pl_swapchain_frame *frame);
// Helper function to draw a custom widget for drag&drop operations, returns
// true if the widget is hovered
static inline bool ui_widget_hover(struct nk_context *nk, const char *label)
{
struct nk_rect bounds;
if (!nk_widget(&bounds, nk))
return false;
struct nk_command_buffer *canvas = nk_window_get_canvas(nk);
bool hover = nk_input_is_mouse_hovering_rect(&nk->input, bounds);
float h, s, v;
nk_color_hsv_f(&h, &s, &v, nk->style.window.background);
struct nk_color background = nk_hsv_f(h, s, v + (hover ? 0.1f : -0.02f));
struct nk_color border = nk_hsv_f(h, s, v + 0.20f);
nk_fill_rect(canvas, bounds, 0.0f, background);
nk_stroke_rect(canvas, bounds, 0.0f, 2.0f, border);
const float pad = 10.0f;
struct nk_rect text = {
.x = bounds.x + pad,
.y = bounds.y + pad,
.w = bounds.w - 2 * pad,
.h = bounds.h - 2 * pad,
};
nk_draw_text(canvas, text, label, nk_strlen(label), nk->style.font,
background, nk->style.text.color);
return hover;
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment