| 461 | } |
| 462 | |
| 463 | void draw_graph_window(Config &ctx) { |
| 464 | std::array<char, 0x40> buf; |
| 465 | std::snprintf(buf.data(), buf.size(), "Gamma ramps (%s)###gammaramp", |
| 466 | ctx.is_editing_day_profile ? "day" : ctx.is_editing_night_profile ? "night" : "none"); |
| 467 | |
| 468 | if (!im::Begin(buf.data(), nullptr, ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoResize | |
| 469 | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoMove)) |
| 470 | return; |
| 471 | FZ_SCOPEGUARD([] { im::End(); }); |
| 472 | |
| 473 | auto [width, height] = im::GetIO().DisplaySize; |
| 474 | im::SetWindowPos( { 0.53f * width, 0.60f * height }, ImGuiCond_Always); |
| 475 | im::SetWindowSize({ 0.38f * width, 0.35f * height }, ImGuiCond_Always); |
| 476 | |
| 477 | FizeauSettings set = ctx.is_editing_day_profile ? ctx.profile.day_settings : ctx.profile.night_settings; |
| 478 | |
| 479 | // Calculate ramps |
| 480 | std::array<std::uint16_t, 256> lut1; |
| 481 | std::array<std::uint16_t, 960> lut2; |
| 482 | |
| 483 | float off = (1.0f - contrast_slant(set.contrast)) / 2.0f; |
| 484 | degamma_ramp(lut1.data(), lut1.size(), DEFAULT_GAMMA, 8); |
| 485 | regamma_ramp(lut2.data(), lut2.size(), set.gamma, 8, 0.0f, 1.0f, off); |
| 486 | |
| 487 | apply_luma(lut2.data(), lut2.size(), 8, set.luminance); |
| 488 | apply_range(lut2.data(), lut2.size(), 8, set.range.lo, std::min(set.range.hi, lut2.back() / 255.0f)); |
| 489 | |
| 490 | std::array<float, 2> linear = { 0, 1 }; |
| 491 | std::array<float, lut1.size()> lut1_float; |
| 492 | std::array<float, lut2.size()> lut2_float; |
| 493 | |
| 494 | std::transform(lut1.begin(), lut1.end(), lut1_float.begin(), [](std::uint16_t val) { return static_cast<float>(val) / 255.0f; }); |
| 495 | std::transform(lut2.begin(), lut2.end(), lut2_float.begin(), [](std::uint16_t val) { return static_cast<float>(val) / 255.0f; }); |
| 496 | |
| 497 | auto &style = im::GetStyle(); |
| 498 | auto *window = im::GetCurrentWindow(); |
| 499 | |
| 500 | ImVec2 frame_size = { 0.95f * window->Size.x, 0.75f * window->Size.y }; |
| 501 | |
| 502 | const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); |
| 503 | const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); |
| 504 | im::ItemSize(frame_bb, style.FramePadding.y); |
| 505 | if (!im::ItemAdd(frame_bb, 0, &frame_bb)) |
| 506 | return; |
| 507 | im::RenderFrame(frame_bb.Min, frame_bb.Max, im::GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); |
| 508 | |
| 509 | // Draw grid |
| 510 | int nb_x_ticks = 7, nb_y_ticks = 5; |
| 511 | auto grid_col = IM_COL32(127.0f, 127.0f, 127.0f, 200.0f); |
| 512 | for (int i = 0; i < nb_x_ticks; ++i) { |
| 513 | float x = ImLerp(inner_bb.Min.x, inner_bb.Max.x, static_cast<float>(i) / static_cast<float>(nb_x_ticks - 1)); |
| 514 | window->DrawList->AddLine({ x, inner_bb.Min.y }, { x, inner_bb.Max.y }, grid_col); |
| 515 | } |
| 516 | for (int i = 0; i < nb_x_ticks; ++i) { |
| 517 | float y = ImLerp(inner_bb.Min.y, inner_bb.Max.y, static_cast<float>(i) / static_cast<float>(nb_y_ticks - 1)); |
| 518 | window->DrawList->AddLine({ inner_bb.Min.x, y }, { inner_bb.Max.x, y }, grid_col); |
| 519 | } |
| 520 |
no test coverage detected