ui! ui! ui! ui!
This commit is contained in:
parent
25468bad25
commit
4b7e5e3018
8 changed files with 232 additions and 93 deletions
|
@ -26,8 +26,8 @@ namespace K {
|
||||||
|
|
||||||
i32 CompositionState::GetFrame(u32 frame) {
|
i32 CompositionState::GetFrame(u32 frame) {
|
||||||
if (frame > frame_max) {
|
if (frame > frame_max) {
|
||||||
Log(K_L_Error, "Comp {} frame out of range! Requesting {}, max {}", name, frame, frame_max);
|
Log(K_L_Warning, "Comp {} frame out of range! Requesting {}, max {}", name, frame, frame_max);
|
||||||
return -1;
|
frame = frame_max;
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 tmp = current_frame;
|
u64 tmp = current_frame;
|
||||||
|
|
|
@ -16,10 +16,40 @@ struct glz::meta<ImVec2> {
|
||||||
|
|
||||||
namespace K::Resource {
|
namespace K::Resource {
|
||||||
void SaveCurrentProject() {
|
void SaveCurrentProject() {
|
||||||
auto ec = glz::write_file_json("soon!", "./temp.json", String{});
|
static const SDL_DialogFileFilter save_filters[] = {
|
||||||
|
{ "JSON", "json" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
struct SaveCallback {
|
||||||
|
static void SDLCALL f(void *userdata, const char* const* filelist, i32 filter) {
|
||||||
|
if (!filelist) {
|
||||||
|
Log(K_L_Error, "{}", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!*filelist) // The user did not select any file. Most likely, the dialog was canceled.
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (*filelist) {
|
||||||
|
auto ec = glz::write_file_json("soon! :)", *filelist, String{});
|
||||||
if (ec.ec != glz::error_code::none) {
|
if (ec.ec != glz::error_code::none) {
|
||||||
Log(K_L_Error, "{}", ec.includer_error);
|
Log(K_L_Error, "{}", ec.includer_error);
|
||||||
}
|
}
|
||||||
|
filelist++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == -1) {
|
||||||
|
Log(K_L_Info, "Platform does not support fetching file filters.");
|
||||||
|
}
|
||||||
|
else if (filter < SDL_arraysize(save_filters)) {
|
||||||
|
SDL_Log("The filter selected by the user is '%s' (%s).",
|
||||||
|
save_filters[filter].pattern, save_filters[filter].name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Log("The user did not select any filter.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
SDL_ShowSaveFileDialog(SaveCallback::f, nullptr, app_state.window, save_filters, 1, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +133,43 @@ namespace K::Resource {
|
||||||
return bgfx::createProgram(LoadShader(vert), LoadShader(frag), true);
|
return bgfx::createProgram(LoadShader(vert), LoadShader(frag), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LoadFile() {
|
||||||
|
static const SDL_DialogFileFilter import_filters[] = {
|
||||||
|
{ "PNG images", "png" },
|
||||||
|
{ "JPEG images", "jpg;jpeg" },
|
||||||
|
{ "All images", "png;jpg;jpeg" },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
struct ImportCallback {
|
||||||
|
static void SDLCALL f(void *userdata, const char* const* filelist, i32 filter) {
|
||||||
|
if (!filelist) {
|
||||||
|
Log(K_L_Error, "{}", SDL_GetError());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (!*filelist) // The user did not select any file. Most likely, the dialog was canceled.
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (*filelist) {
|
||||||
|
Load<K_R_Still>(*filelist);
|
||||||
|
filelist++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filter == -1) {
|
||||||
|
Log(K_L_Info, "Platform does not support fetching file filters.");
|
||||||
|
}
|
||||||
|
else if (filter < SDL_arraysize(import_filters)) {
|
||||||
|
SDL_Log("The filter selected by the user is '%s' (%s).",
|
||||||
|
import_filters[filter].pattern, import_filters[filter].name);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
SDL_Log("The user did not select any filter.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SDL_ShowOpenFileDialog(ImportCallback::f, nullptr, app_state.window, import_filters, 3, nullptr, true);
|
||||||
|
}
|
||||||
|
|
||||||
void HotReload() {
|
void HotReload() {
|
||||||
while (app_state.running.load()) {
|
while (app_state.running.load()) {
|
||||||
for (auto& [path, resource] : resources)
|
for (auto& [path, resource] : resources)
|
||||||
|
|
194
Keishiki/UI.cpp
194
Keishiki/UI.cpp
|
@ -324,17 +324,11 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport(CompositionState& s) {
|
void Viewport(CompositionState& s) {
|
||||||
if (playing) {
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{});
|
||||||
if (static_cast<f32>(app_state.current_time - last_frame_tick) >= 1000.0f / s.fps) {
|
if (ImGui::Begin("Viewport", nullptr, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoScrollWithMouse)) {
|
||||||
f32 delta = static_cast<f32>(app_state.current_time - last_frame_tick);
|
static bool do_bg = true, dragging = false;
|
||||||
f32 frames_passed = delta / (1000.0f / s.fps);
|
static f32 size = 1.0f, angle = 0;
|
||||||
s.current_frame = (s.current_frame + static_cast<u64>(std::floor(frames_passed))) % (s.frame_max + 1);
|
static ImVec2 pos{}, old = pos;
|
||||||
last_frame_tick = app_state.current_time - static_cast<u64>(std::fmod(delta, 1000.0f / s.fps));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ImGui::Begin("Viewport")) {
|
|
||||||
static bool do_bg = true;
|
|
||||||
|
|
||||||
if (ImGui::Shortcut(ImGuiKey_Space))
|
if (ImGui::Shortcut(ImGuiKey_Space))
|
||||||
TogglePlay();
|
TogglePlay();
|
||||||
|
@ -357,11 +351,31 @@ namespace K::UI {
|
||||||
present = s.composite[result_index];
|
present = s.composite[result_index];
|
||||||
|
|
||||||
ImTextureID idx = ImGui::toId(present, 1, 0);
|
ImTextureID idx = ImGui::toId(present, 1, 0);
|
||||||
if (idx != nullptr)
|
if (idx != nullptr) {
|
||||||
ImGui::Image(idx, ImVec2{ static_cast<f32>(s.width), static_cast<f32>(s.height) });
|
ImVec2 image_size = {static_cast<f32>(s.width) * size, static_cast<f32>(s.height) * size};
|
||||||
|
|
||||||
ImGui::Text("%ux%u", s.width, s.height);
|
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||||
ImGui::SameLine();
|
static auto rot = [](const ImVec2& v, float cos_a, float sin_a) {
|
||||||
|
return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a);
|
||||||
|
};
|
||||||
|
ImVec2 center = ImGui::GetCursorScreenPos() + ImGui::GetContentRegionAvail() * .5f + pos;
|
||||||
|
f32 cos_a = std::cosf(angle / 180.0f * std::numbers::pi);
|
||||||
|
f32 sin_a = std::sinf(angle / 180.0f * std::numbers::pi);
|
||||||
|
ImVec2 quad[4] = {
|
||||||
|
center + rot(ImVec2(-image_size.x * 0.5f, -image_size.y * 0.5f), cos_a, sin_a),
|
||||||
|
center + rot(ImVec2(+image_size.x * 0.5f, -image_size.y * 0.5f), cos_a, sin_a),
|
||||||
|
center + rot(ImVec2(+image_size.x * 0.5f, +image_size.y * 0.5f), cos_a, sin_a),
|
||||||
|
center + rot(ImVec2(-image_size.x * 0.5f, +image_size.y * 0.5f), cos_a, sin_a)
|
||||||
|
};
|
||||||
|
ImVec2 uvs[4] = {
|
||||||
|
ImVec2(0.0f, 0.0f),
|
||||||
|
ImVec2(1.0f, 0.0f),
|
||||||
|
ImVec2(1.0f, 1.0f),
|
||||||
|
ImVec2(0.0f, 1.0f)
|
||||||
|
};
|
||||||
|
|
||||||
|
draw_list->AddImageQuad(idx, quad[0], quad[1], quad[2], quad[3], uvs[0], uvs[1], uvs[2], uvs[3], IM_COL32_WHITE);
|
||||||
|
}
|
||||||
|
|
||||||
/* ImGui::BeginDisabled(comp_save_called != nullptr);
|
/* ImGui::BeginDisabled(comp_save_called != nullptr);
|
||||||
if (ImGui::Button("Save to frame.png")) {
|
if (ImGui::Button("Save to frame.png")) {
|
||||||
|
@ -371,13 +385,51 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
ImGui::EndDisabled();*/
|
ImGui::EndDisabled();*/
|
||||||
|
|
||||||
ImGui::SetNextItemWidth(50.0f);
|
ImGuiIO io = ImGui::GetIO();
|
||||||
ImGui::DragFloat("FPS", &s.fps, 1.0f, 1.0f, 120.0f);
|
if (ImGui::IsWindowHovered()) {
|
||||||
ImGui::SameLine();
|
if (io.MouseWheel != 0.0f) {
|
||||||
ImGui::Checkbox("BG", &do_bg);
|
size += io.MouseWheel * 0.25f;
|
||||||
|
size = std::max(size, 0.25f);
|
||||||
|
}
|
||||||
|
if (io.MouseClicked[ImGuiMouseButton_Middle]) {
|
||||||
|
dragging = true;
|
||||||
|
old = pos;
|
||||||
|
}
|
||||||
|
if (io.MouseDoubleClicked[ImGuiMouseButton_Middle]) {
|
||||||
|
size = 1.0f;
|
||||||
|
pos.x = 0.0f;
|
||||||
|
pos.y = 0.0f;
|
||||||
|
old = pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (dragging) {
|
||||||
|
pos = old + ImGui::GetMouseDragDelta(ImGuiMouseButton_Middle);
|
||||||
|
}
|
||||||
|
if (io.MouseReleased[ImGuiMouseButton_Middle]) {
|
||||||
|
dragging = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::SetCursorPosY(ImGui::GetWindowHeight() - 25.0f);
|
||||||
|
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0x99000000);
|
||||||
|
if (ImGui::BeginChild("Controls")) {
|
||||||
|
ImGui::Text("%ux%u@%.1f", s.width, s.height, s.fps);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Checkbox("Transparency Grid", &do_bg);
|
||||||
|
ImGui::SameLine();
|
||||||
|
f32 percentage = size * 100.0f;
|
||||||
|
ImGui::SetNextItemWidth(110.0f);
|
||||||
|
if (ImGui::InputFloat("View Scale", &percentage, 15.0f, 25.0f, "%.2f%%")) {
|
||||||
|
size = std::max(.25f, percentage / 100.0f);
|
||||||
|
}
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::SetNextItemWidth(50.0f);
|
||||||
|
ImGui::DragFloat("Rotation", &angle);
|
||||||
|
}
|
||||||
|
ImGui::EndChild();
|
||||||
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
|
ImGui::PopStyleVar();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool TimelineFrameInView(f32 view_left, f32 view_right, i64 frame, u64 frame_max) {
|
constexpr bool TimelineFrameInView(f32 view_left, f32 view_right, i64 frame, u64 frame_max) {
|
||||||
|
@ -546,6 +598,7 @@ namespace K::UI {
|
||||||
static Vector<Plugboard::ChainSegment*> keys_selected_by_bg_drag{};
|
static Vector<Plugboard::ChainSegment*> keys_selected_by_bg_drag{};
|
||||||
auto tl_bg_handler = [&view_width, &style, &view_amt, &s, &mouse_tl_x, &io](f32 h = 0.0f, f32 w = 0.0f) {
|
auto tl_bg_handler = [&view_width, &style, &view_amt, &s, &mouse_tl_x, &io](f32 h = 0.0f, f32 w = 0.0f) {
|
||||||
static f32 pan_x, view_left_old, view_right_old;
|
static f32 pan_x, view_left_old, view_right_old;
|
||||||
|
static bool middle_dragging = false;
|
||||||
ImGui::InvisibleButton("##TL_BG", ImVec2{ w == 0.0f ? view_width + style.CellPadding.x * 2 : w, h == 0.0f ? row_height : h});
|
ImGui::InvisibleButton("##TL_BG", ImVec2{ w == 0.0f ? view_width + style.CellPadding.x * 2 : w, h == 0.0f ? row_height : h});
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
tl_clear_selection_request = !(io.KeyCtrl || io.KeyShift);
|
tl_clear_selection_request = !(io.KeyCtrl || io.KeyShift);
|
||||||
|
@ -563,8 +616,9 @@ namespace K::UI {
|
||||||
pan_x = mouse_tl_x;
|
pan_x = mouse_tl_x;
|
||||||
view_left_old = view_left;
|
view_left_old = view_left;
|
||||||
view_right_old = view_right;
|
view_right_old = view_right;
|
||||||
|
middle_dragging = true;
|
||||||
}
|
}
|
||||||
if (ImGui::IsKeyDown(ImGuiKey_MouseMiddle) && ImGui::IsItemHovered()) {
|
if (middle_dragging && ImGui::IsKeyDown(ImGuiKey_MouseMiddle)) {
|
||||||
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
ImGui::SetMouseCursor(ImGuiMouseCursor_Hand);
|
||||||
f32 shift_amt = (mouse_tl_x - pan_x) / view_width * view_amt;
|
f32 shift_amt = (mouse_tl_x - pan_x) / view_width * view_amt;
|
||||||
view_left = view_left_old - shift_amt;
|
view_left = view_left_old - shift_amt;
|
||||||
|
@ -578,6 +632,8 @@ namespace K::UI {
|
||||||
view_right = 1.0f;
|
view_right = 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (ImGui::IsMouseReleased(ImGuiMouseButton_Middle))
|
||||||
|
middle_dragging = false;
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_Delete) && ImGui::IsItemHovered()) {
|
if (ImGui::IsKeyPressed(ImGuiKey_Delete) && ImGui::IsItemHovered()) {
|
||||||
delete_requests[K_DR_Selected_Keys] = true;
|
delete_requests[K_DR_Selected_Keys] = true;
|
||||||
}
|
}
|
||||||
|
@ -706,6 +762,9 @@ namespace K::UI {
|
||||||
view_right = std::clamp(view_right_old + ImGui::GetMouseDragDelta().x / tl_width, view_left + 2.0f / static_cast<f32>(s.frame_max), 1.0f);
|
view_right = std::clamp(view_right_old + ImGui::GetMouseDragDelta().x / tl_width, view_left + 2.0f / static_cast<f32>(s.frame_max), 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window->DrawList->AddLine({tl_init_pos.x + static_cast<f32>(s.current_frame) / static_cast<f32>(s.frame_max + 1) * view_width, tl_init_pos.y},
|
||||||
|
{tl_init_pos.x + static_cast<f32>(s.current_frame) / static_cast<f32>(s.frame_max + 1) * view_width, tl_init_pos.y + view_height},
|
||||||
|
0x773333FF);
|
||||||
window->DrawList->AddRect({tl_init_pos.x - knob_width / 2.0f, tl_init_pos.y}, {tl_init_pos.x + knob_width / 2.0f, tl_init_pos.y + view_height},
|
window->DrawList->AddRect({tl_init_pos.x - knob_width / 2.0f, tl_init_pos.y}, {tl_init_pos.x + knob_width / 2.0f, tl_init_pos.y + view_height},
|
||||||
0x22FFFFFF);
|
0x22FFFFFF);
|
||||||
window->DrawList->AddRect({tl_init_pos.x + view_width - knob_width / 2.0f, tl_init_pos.y},
|
window->DrawList->AddRect({tl_init_pos.x + view_width - knob_width / 2.0f, tl_init_pos.y},
|
||||||
|
@ -720,6 +779,9 @@ namespace K::UI {
|
||||||
{tl_init_pos.x + view_width * view_left, tl_init_pos.y + view_height * .2f},
|
{tl_init_pos.x + view_width * view_left, tl_init_pos.y + view_height * .2f},
|
||||||
{tl_init_pos.x + view_width * view_right, tl_init_pos.y + view_height * .8f}, 0x33FFFFFF, 2.0f);
|
{tl_init_pos.x + view_width * view_right, tl_init_pos.y + view_height * .8f}, 0x33FFFFFF, 2.0f);
|
||||||
|
|
||||||
|
ImGui::SetCursorScreenPos(tl_init_pos);
|
||||||
|
ImGui::InvisibleButton("##TL_BG", {view_width, view_height}); // block bg interaction
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::TableHeader(""); // TL header
|
ImGui::TableHeader(""); // TL header
|
||||||
|
|
||||||
|
@ -935,7 +997,7 @@ namespace K::UI {
|
||||||
if (layer_open) {
|
if (layer_open) {
|
||||||
i32 j = 0;
|
i32 j = 0;
|
||||||
for (auto &u: current_layer.track.uniforms) {
|
for (auto &u: current_layer.track.uniforms) {
|
||||||
if (u.status != K_U_Exposed)
|
if (!(u.status & K_U_Exposed))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ImGui::PushID(j);
|
ImGui::PushID(j);
|
||||||
|
@ -1163,7 +1225,7 @@ namespace K::UI {
|
||||||
ImGui::SetCursorScreenPos(draw_pos);
|
ImGui::SetCursorScreenPos(draw_pos);
|
||||||
|
|
||||||
ImGui::PushStyleColor(ImGuiCol_Button, 0x00000000);
|
ImGui::PushStyleColor(ImGuiCol_Button, 0x00000000);
|
||||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1.0f, 0));
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(1.0f, (row_height - ImGui::GetTextLineHeight()) / 2.0f));
|
||||||
ImGui::Button((const char*)(is_sel ? u8"\u25c8" : u8"\u25c7"), {kf_tab_width, row_height * .8f});
|
ImGui::Button((const char*)(is_sel ? u8"\u25c8" : u8"\u25c7"), {kf_tab_width, row_height * .8f});
|
||||||
ImGui::PopStyleVar();
|
ImGui::PopStyleVar();
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
|
@ -1206,7 +1268,7 @@ namespace K::UI {
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
else for (auto& u: current_layer.track.uniforms) {
|
else for (auto& u: current_layer.track.uniforms) {
|
||||||
if (u.status != K_U_Exposed)
|
if (!(u.status & K_U_Exposed))
|
||||||
continue;
|
continue;
|
||||||
std::visit([table_left, &init_y](auto &&arg) {
|
std::visit([table_left, &init_y](auto &&arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
@ -1463,13 +1525,7 @@ namespace K::UI {
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(tl_grid_cursor_pos);
|
ImGui::SetCursorScreenPos(tl_grid_cursor_pos);
|
||||||
if (ImGui::BeginChild("TL Grid Overlay", ImGui::GetContentRegionAvail(), ImGuiChildFlags_None, ImGuiWindowFlags_NoInputs)) {
|
if (ImGui::BeginChild("TL Grid Overlay", ImGui::GetContentRegionAvail(), ImGuiChildFlags_None, ImGuiWindowFlags_NoInputs)) {
|
||||||
// Playhead
|
|
||||||
auto window = ImGui::GetCurrentWindow();
|
auto window = ImGui::GetCurrentWindow();
|
||||||
window->DrawList->AddLine({tl_init_pos.x + view_width * static_cast<f32>(s.current_frame) /
|
|
||||||
static_cast<f32>(s.frame_max + 1), tl_init_pos.y},
|
|
||||||
{tl_init_pos.x + view_width * static_cast<f32>(s.current_frame) /
|
|
||||||
static_cast<f32>(s.frame_max + 1),
|
|
||||||
tl_init_pos.y}, 0xFF3333FF, 2.0f);
|
|
||||||
|
|
||||||
// Frame Grid
|
// Frame Grid
|
||||||
static f32 frame_grid_min_width = 20.0f;
|
static f32 frame_grid_min_width = 20.0f;
|
||||||
|
@ -1482,12 +1538,16 @@ namespace K::UI {
|
||||||
window->DrawList->AddLine({fr, tl_init_pos.y},
|
window->DrawList->AddLine({fr, tl_init_pos.y},
|
||||||
{fr, ImGui::GetWindowSize().y + tl_init_pos.y}, 0x11FFFFFF, 1.0f);
|
{fr, ImGui::GetWindowSize().y + tl_init_pos.y}, 0x11FFFFFF, 1.0f);
|
||||||
|
|
||||||
|
// Playhead
|
||||||
if (TimelineFrameInView(view_left, view_right, s.current_frame, s.frame_max)) {
|
if (TimelineFrameInView(view_left, view_right, s.current_frame, s.frame_max)) {
|
||||||
f32 fr = TimelineFrameToScreenView(view_left, view_amt, view_width, s.current_frame, s.frame_max) +
|
f32 fr = TimelineFrameToScreenView(view_left, view_amt, view_width, s.current_frame, s.frame_max) +
|
||||||
tl_init_pos.x;
|
tl_init_pos.x;
|
||||||
window->DrawList->AddLine(
|
window->DrawList->AddLine(
|
||||||
{fr, tl_init_pos.y},
|
{fr, tl_init_pos.y},
|
||||||
{fr, ImGui::GetWindowSize().y + tl_init_pos.y}, 0x773333FF, 1.0f);
|
{fr, ImGui::GetWindowSize().y + tl_init_pos.y}, 0x773333FF, 1.0f);
|
||||||
|
window->DrawList->AddRectFilled(
|
||||||
|
{fr, tl_init_pos.y},
|
||||||
|
{fr + fr_step, ImGui::GetWindowSize().y + tl_init_pos.y}, 0x223333FF, 1.0f);
|
||||||
}
|
}
|
||||||
if (bg_drag_select_active) {
|
if (bg_drag_select_active) {
|
||||||
window->DrawList->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, 0x55AA5555);
|
window->DrawList->AddRectFilled(io.MouseClickedPos[ImGuiMouseButton_Left], io.MousePos, 0x55AA5555);
|
||||||
|
@ -1565,7 +1625,7 @@ namespace K::UI {
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
i32 i = 0;
|
i32 i = 0;
|
||||||
for (auto it = s.layers[s.active].track.uniforms.begin(); it != s.layers[s.active].track.uniforms.end();) {
|
for (auto it = s.layers[s.active].track.uniforms.begin(); it != s.layers[s.active].track.uniforms.end();) {
|
||||||
if (it->status != K_U_Exposed) {
|
if (!(it->status & K_U_Exposed)) {
|
||||||
it++;
|
it++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -1611,7 +1671,7 @@ namespace K::UI {
|
||||||
if (ImGui::BeginTable("Samplers", 4, ImGuiTableFlags_Borders)) {
|
if (ImGui::BeginTable("Samplers", 4, ImGuiTableFlags_Borders)) {
|
||||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableSetupColumn("Dims via", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Dims via", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableSetupColumn("Resource", ImGuiTableColumnFlags_NoSort);
|
ImGui::TableSetupColumn("Source", ImGuiTableColumnFlags_NoSort);
|
||||||
ImGui::TableSetupColumn("##del", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("##del", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
i32 i = 0;
|
i32 i = 0;
|
||||||
|
@ -1632,27 +1692,41 @@ namespace K::UI {
|
||||||
return arg->name.c_str();
|
return arg->name.c_str();
|
||||||
}
|
}
|
||||||
}, it->resource);
|
}, it->resource);
|
||||||
|
u32 id = 0;
|
||||||
if (ImGui::BeginCombo("##source", r_name)) {
|
if (ImGui::BeginCombo("##source", r_name)) {
|
||||||
|
ImGui::TextUnformatted("--Resources--");
|
||||||
for (auto& [file, res_v] : Resource::resources)
|
for (auto& [file, res_v] : Resource::resources)
|
||||||
if (auto *res = std::get_if<Resource::Resource<Resource::K_R_Still>>(&res_v)) {
|
if (auto *res = std::get_if<Resource::Resource<Resource::K_R_Still>>(&res_v)) {
|
||||||
|
ImGui::PushID(id++);
|
||||||
const bool is_selected = r_name == res->filename.c_str(); // lol
|
const bool is_selected = r_name == res->filename.c_str(); // lol
|
||||||
if (ImGui::Selectable(file.c_str(), is_selected)) {
|
if (ImGui::Selectable(file.c_str(), is_selected)) {
|
||||||
it->resource = res;
|
it->resource = res;
|
||||||
it->dims->val = ShaderGraph::XY{static_cast<f32>(res->w), static_cast<f32>(res->h)};
|
it->dims->val = ShaderGraph::XY{static_cast<f32>(res->w), static_cast<f32>(res->h)};
|
||||||
|
if (std::visit([](auto&& arg){ return arg != nullptr; }, it->frame->connection.p))
|
||||||
|
s.layers[s.active].track.HideUniform(s, *it->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_selected)
|
if (is_selected)
|
||||||
ImGui::SetItemDefaultFocus();
|
ImGui::SetItemDefaultFocus();
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
|
ImGui::TextUnformatted("--Compositions--");
|
||||||
for (auto& comp : app_state.project.compositions) {
|
for (auto& comp : app_state.project.compositions) {
|
||||||
|
ImGui::PushID(id++);
|
||||||
const bool is_selected = r_name == comp.name.c_str(); // lol
|
const bool is_selected = r_name == comp.name.c_str(); // lol
|
||||||
if (ImGui::Selectable(comp.name.c_str(), is_selected)) {
|
if (ImGui::Selectable(comp.name.c_str(), is_selected)) {
|
||||||
it->resource = ∁
|
it->resource = ∁
|
||||||
it->dims->val = ShaderGraph::XY{static_cast<f32>(comp.width), static_cast<f32>(comp.height)};
|
it->dims->val = ShaderGraph::XY{static_cast<f32>(comp.width), static_cast<f32>(comp.height)};
|
||||||
|
it->frame->val = ShaderGraph::T_Map<ShaderGraph::T_Int>::type(0);
|
||||||
|
if (std::visit([](auto&& arg){ return arg == nullptr; }, it->frame->connection.p))
|
||||||
|
s.layers[s.active].track.ExposeUniform(s, *it->frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_selected)
|
if (is_selected)
|
||||||
ImGui::SetItemDefaultFocus();
|
ImGui::SetItemDefaultFocus();
|
||||||
|
|
||||||
|
ImGui::PopID();
|
||||||
}
|
}
|
||||||
ImGui::EndCombo();
|
ImGui::EndCombo();
|
||||||
}
|
}
|
||||||
|
@ -1691,7 +1765,7 @@ namespace K::UI {
|
||||||
if (ImGui::Button("Apply"))
|
if (ImGui::Button("Apply"))
|
||||||
for (auto& layer : s.layers)
|
for (auto& layer : s.layers)
|
||||||
for (auto& u : layer.track.uniforms) {
|
for (auto& u : layer.track.uniforms) {
|
||||||
if (u.status != K_U_Exposed)
|
if (!(u.status & K_U_Exposed))
|
||||||
continue;
|
continue;
|
||||||
for (auto& n : s.plugboard.show_nodes[u.connection.index]) {
|
for (auto& n : s.plugboard.show_nodes[u.connection.index]) {
|
||||||
auto& [chain, _] = std::get<Plugboard::Chain*>(n.p)->extra;
|
auto& [chain, _] = std::get<Plugboard::Chain*>(n.p)->extra;
|
||||||
|
@ -1831,7 +1905,7 @@ namespace K::UI {
|
||||||
if (ImGui::InputFloat("FPS", &fps, 1.0f, 5.0f, "%.1f"))
|
if (ImGui::InputFloat("FPS", &fps, 1.0f, 5.0f, "%.1f"))
|
||||||
fps = std::clamp(fps, 1.0f, 120.0f);
|
fps = std::clamp(fps, 1.0f, 120.0f);
|
||||||
|
|
||||||
static i32 dims[2] = { 1280, 720 };
|
static i32 dims[2] = { 1280, 550 };
|
||||||
if (ImGui::InputInt2("Dimensions", dims)) {
|
if (ImGui::InputInt2("Dimensions", dims)) {
|
||||||
dims[0] = std::max(1, dims[0]);
|
dims[0] = std::max(1, dims[0]);
|
||||||
dims[1] = std::max(1, dims[1]);
|
dims[1] = std::max(1, dims[1]);
|
||||||
|
@ -1891,40 +1965,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Button("Load")) {
|
if (ImGui::Button("Load")) {
|
||||||
static const SDL_DialogFileFilter import_filters[] = {
|
Resource::LoadFile();
|
||||||
{ "PNG images", "png" },
|
|
||||||
{ "JPEG images", "jpg;jpeg" },
|
|
||||||
{ "All images", "png;jpg;jpeg" },
|
|
||||||
{ NULL, NULL }
|
|
||||||
};
|
|
||||||
struct ImportCallback {
|
|
||||||
static void SDLCALL f(void *userdata, const char* const* filelist, i32 filter) {
|
|
||||||
if (!filelist) {
|
|
||||||
Log(K_L_Error, "{}", SDL_GetError());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else if (!*filelist) // The user did not select any file. Most likely, the dialog was canceled.
|
|
||||||
return;
|
|
||||||
|
|
||||||
while (*filelist) {
|
|
||||||
Resource::Load<Resource::K_R_Still>(*filelist);
|
|
||||||
filelist++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (filter == -1) {
|
|
||||||
Log(K_L_Info, "Platform does not support fetching file filters.");
|
|
||||||
}
|
|
||||||
else if (filter < SDL_arraysize(import_filters)) {
|
|
||||||
SDL_Log("The filter selected by the user is '%s' (%s).",
|
|
||||||
import_filters[filter].pattern, import_filters[filter].name);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SDL_Log("The user did not select any filter.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
SDL_ShowOpenFileDialog(ImportCallback::f, nullptr, app_state.window, import_filters, 3, nullptr, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginTable("Assets", 3, ImGuiTableFlags_Borders)) {
|
if (ImGui::BeginTable("Assets", 3, ImGuiTableFlags_Borders)) {
|
||||||
|
@ -1989,6 +2030,7 @@ namespace K::UI {
|
||||||
static_cast<f32>(Resource::fallback_still->w),
|
static_cast<f32>(Resource::fallback_still->w),
|
||||||
static_cast<f32>(Resource::fallback_still->h)
|
static_cast<f32>(Resource::fallback_still->h)
|
||||||
};
|
};
|
||||||
|
layer.track.HideUniform(s, *sampler.frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
it->Destroy();
|
it->Destroy();
|
||||||
|
@ -2047,11 +2089,13 @@ namespace K::UI {
|
||||||
for (auto& chain : s.plugboard.selected_nodes) {
|
for (auto& chain : s.plugboard.selected_nodes) {
|
||||||
if (auto *c = std::get_if<Plugboard::Chain*>(&chain)) {
|
if (auto *c = std::get_if<Plugboard::Chain*>(&chain)) {
|
||||||
auto& [segments, selected] = (*c)->extra.chain;
|
auto& [segments, selected] = (*c)->extra.chain;
|
||||||
|
std::ranges::sort(selected, std::ranges::greater{});
|
||||||
for (u32 i : selected)
|
for (u32 i : selected)
|
||||||
segments.erase(segments.begin() + i);
|
segments.erase(segments.begin() + i);
|
||||||
selected.clear();
|
selected.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
delete_requests[K_DR_Selected_Keys] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2060,17 +2104,29 @@ namespace K::UI {
|
||||||
ImGui_Implbgfx_NewFrame();
|
ImGui_Implbgfx_NewFrame();
|
||||||
ImGui::NewFrame();
|
ImGui::NewFrame();
|
||||||
|
|
||||||
Graphics::DrawTextureImageAlpha(K::Graphics::K_VIEW_LOGO, logo, app_state.window_width - logo->w + 10, 0, .4f);
|
Graphics::DrawTextureImageAlpha(K::Graphics::K_VIEW_LOGO, logo, app_state.window_width - logo->w + 10, 0, .7f);
|
||||||
|
|
||||||
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
|
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
|
||||||
|
|
||||||
ImGui::ShowDemoWindow();
|
|
||||||
|
|
||||||
|
// ImGui::ShowDemoWindow();
|
||||||
MainMenuBar();
|
MainMenuBar();
|
||||||
|
|
||||||
if (draw_assets) Assets();
|
if (draw_assets) Assets();
|
||||||
|
|
||||||
if (app_state.project.inspecting_composition != nullptr) {
|
if (app_state.project.inspecting_composition != nullptr) {
|
||||||
auto &comp = *app_state.project.inspecting_composition;
|
auto &comp = *app_state.project.inspecting_composition;
|
||||||
|
|
||||||
|
if (playing) {
|
||||||
|
if (static_cast<f32>(app_state.current_time - last_frame_tick) >= 1000.0f / comp.fps) {
|
||||||
|
f32 delta = static_cast<f32>(app_state.current_time - last_frame_tick);
|
||||||
|
f32 frames_passed = delta / (1000.0f / comp.fps);
|
||||||
|
comp.current_frame = (comp.current_frame + static_cast<u64>(std::floor(frames_passed))) % (comp.frame_max + 1);
|
||||||
|
last_frame_tick = app_state.current_time - static_cast<u64>(std::fmod(delta, 1000.0f / comp.fps));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (draw_viewport) Viewport(comp);
|
if (draw_viewport) Viewport(comp);
|
||||||
if (draw_layer) Layer(comp);
|
if (draw_layer) Layer(comp);
|
||||||
if (draw_comp) Composition(comp);
|
if (draw_comp) Composition(comp);
|
||||||
|
|
|
@ -40,13 +40,13 @@ namespace K {
|
||||||
f32 view[16], f32 transform[16]) {
|
f32 view[16], f32 transform[16]) {
|
||||||
std::shared_lock lk{Resource::resource_lock};
|
std::shared_lock lk{Resource::resource_lock};
|
||||||
u32 sampler_stage = 0;
|
u32 sampler_stage = 0;
|
||||||
for (auto& [_name, handle, res, _u] : samplers) {
|
for (auto& [_name, handle, res, _u, u_frame] : samplers) {
|
||||||
bgfx::TextureHandle tx = std::visit([](auto&& arg) {
|
bgfx::TextureHandle tx = std::visit([&s, &u_frame](auto&& arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_Still>*>)
|
if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_Still>*>)
|
||||||
return arg->tex;
|
return arg->tex;
|
||||||
else if constexpr (std::is_same_v<T, CompositionState*>) {
|
else if constexpr (std::is_same_v<T, CompositionState*>) {
|
||||||
i32 slot = arg->GetFrame(0);
|
i32 slot = arg->GetFrame(std::get<Plugboard::T_Int>(std::get<Plugboard::T_Map<Plugboard::T_Count>::type>(s.plugboard.out_instance.in[u_frame->connection.index].value)));
|
||||||
return arg->composite[slot];
|
return arg->composite[slot];
|
||||||
}
|
}
|
||||||
}, res);
|
}, res);
|
||||||
|
@ -61,6 +61,9 @@ namespace K {
|
||||||
bgfx::setViewRect(app_state.render_view, 0, 0, w, h);
|
bgfx::setViewRect(app_state.render_view, 0, 0, w, h);
|
||||||
|
|
||||||
for (auto& u : uniforms) {
|
for (auto& u : uniforms) {
|
||||||
|
if (u.status & K_U_SamplerFrame)
|
||||||
|
continue;
|
||||||
|
|
||||||
f32 pack[4]{};
|
f32 pack[4]{};
|
||||||
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val_target;
|
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val_target;
|
||||||
if (std::visit([](auto&& arg){ return arg == nullptr; }, u.connection.p))
|
if (std::visit([](auto&& arg){ return arg == nullptr; }, u.connection.p))
|
||||||
|
@ -110,7 +113,7 @@ namespace K {
|
||||||
"#include <bgfx_shader.sh>\n"
|
"#include <bgfx_shader.sh>\n"
|
||||||
"#include <shaderlib.sh>\n";
|
"#include <shaderlib.sh>\n";
|
||||||
u32 sampler_loc = 0;
|
u32 sampler_loc = 0;
|
||||||
for (auto& [name, _tex, _res, _u] : samplers) {
|
for (auto& [name, _tex, _res, _u, _uu] : samplers) {
|
||||||
f << "SAMPLER2D(" << name << ", " << sampler_loc++ << ");\n";
|
f << "SAMPLER2D(" << name << ", " << sampler_loc++ << ");\n";
|
||||||
}
|
}
|
||||||
for (auto& u : uniforms) {
|
for (auto& u : uniforms) {
|
||||||
|
@ -150,6 +153,7 @@ namespace K {
|
||||||
if (bgfx::isValid(pg))
|
if (bgfx::isValid(pg))
|
||||||
bgfx::destroy(pg);
|
bgfx::destroy(pg);
|
||||||
for (auto& uniform : uniforms) {
|
for (auto& uniform : uniforms) {
|
||||||
|
if (!(uniform.status & K_U_SamplerFrame))
|
||||||
bgfx::destroy(uniform.handle);
|
bgfx::destroy(uniform.handle);
|
||||||
}
|
}
|
||||||
uniforms.clear();
|
uniforms.clear();
|
||||||
|
@ -164,6 +168,8 @@ namespace K {
|
||||||
// this is shaky and bug prone -- relies on the shader types being in line with plugboard types
|
// this is shaky and bug prone -- relies on the shader types being in line with plugboard types
|
||||||
s.plugboard.out_instance.in.push_back(Plugboard::InSocket{ uu.name, Plugboard::Type(uu.val.index()), ShaderValToPlugboard(uu.val)});
|
s.plugboard.out_instance.in.push_back(Plugboard::InSocket{ uu.name, Plugboard::Type(uu.val.index()), ShaderValToPlugboard(uu.val)});
|
||||||
s.plugboard.show_nodes.emplace_back();
|
s.plugboard.show_nodes.emplace_back();
|
||||||
|
|
||||||
|
uu.status |= K_U_Exposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::ExposeUniform(CompositionState& s, u32 i) {
|
void VisualTrack::ExposeUniform(CompositionState& s, u32 i) {
|
||||||
|
@ -171,7 +177,7 @@ namespace K {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::HideUniform(CompositionState& s, Uniform& uu) {
|
void VisualTrack::HideUniform(CompositionState& s, Uniform& uu) {
|
||||||
if (uu.status != K_U_Exposed)
|
if (!(uu.status & K_U_Exposed))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Plugboard::Disconnect(uu.connection.p, uu.connection.index);
|
Plugboard::Disconnect(uu.connection.p, uu.connection.index);
|
||||||
|
@ -188,6 +194,8 @@ namespace K {
|
||||||
|
|
||||||
s.plugboard.out_instance.in.erase(s.plugboard.out_instance.in.begin() + uu.connection.index);
|
s.plugboard.out_instance.in.erase(s.plugboard.out_instance.in.begin() + uu.connection.index);
|
||||||
uu.connection = {(Plugboard::Add*)(nullptr), 0};
|
uu.connection = {(Plugboard::Add*)(nullptr), 0};
|
||||||
|
|
||||||
|
uu.status &= ~K_U_Exposed;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val, UniformStatus init) {
|
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val, UniformStatus init) {
|
||||||
|
@ -197,7 +205,10 @@ namespace K {
|
||||||
for (auto& ss : samplers)
|
for (auto& ss : samplers)
|
||||||
if (ss.name == s)
|
if (ss.name == s)
|
||||||
return;
|
return;
|
||||||
|
if (!(init & K_U_SamplerFrame))
|
||||||
uniforms.emplace_back(Uniform{s, bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val, {{}, 0}, init});
|
uniforms.emplace_back(Uniform{s, bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val, {{}, 0}, init});
|
||||||
|
else
|
||||||
|
uniforms.emplace_back(Uniform{s, BGFX_INVALID_HANDLE, val, {{}, 0}, init});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::AddSampler(const String& s) {
|
void VisualTrack::AddSampler(const String& s) {
|
||||||
|
@ -208,6 +219,7 @@ namespace K {
|
||||||
if (ss.name == s)
|
if (ss.name == s)
|
||||||
return;
|
return;
|
||||||
AddUniform(s + "_dims", ShaderGraph::XY{static_cast<f32>(Resource::fallback_still->w), static_cast<f32>(Resource::fallback_still->h)}, K_U_SamplerDims);
|
AddUniform(s + "_dims", ShaderGraph::XY{static_cast<f32>(Resource::fallback_still->w), static_cast<f32>(Resource::fallback_still->h)}, K_U_SamplerDims);
|
||||||
samplers.emplace_back(Sampler{s, bgfx::createUniform(s.c_str(), bgfx::UniformType::Sampler), Resource::fallback_still, &uniforms.back()});
|
AddUniform(s + "_frame", ShaderGraph::T_Map<ShaderGraph::T_Int>::type{0}, K_U_SamplerFrame);
|
||||||
|
samplers.emplace_back(Sampler{s, bgfx::createUniform(s.c_str(), bgfx::UniformType::Sampler), Resource::fallback_still, &*std::next(uniforms.rbegin()), &uniforms.back()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace K {
|
||||||
|
|
||||||
Vector<Layer> layers;
|
Vector<Layer> layers;
|
||||||
i32 active = -1; // index for layers
|
i32 active = -1; // index for layers
|
||||||
Vector<u32> selected; // indices for layers
|
Vector<u32> selected; // indices for layers todo use flat_set instead
|
||||||
Vector<u32> disabled; // indices for layers
|
Vector<u32> disabled; // indices for layers todo use flat_set instead
|
||||||
|
|
||||||
Plugboard::Plugboard plugboard;
|
Plugboard::Plugboard plugboard;
|
||||||
|
|
||||||
|
@ -36,13 +36,16 @@ namespace K {
|
||||||
render_fb = BGFX_INVALID_HANDLE;
|
render_fb = BGFX_INVALID_HANDLE;
|
||||||
f32 proj[16], transform[16], view[16];
|
f32 proj[16], transform[16], view[16];
|
||||||
|
|
||||||
|
// Dependence
|
||||||
|
Vector<std::pair<CompositionState*, u32>> depends_on{}; // todo use flat_map instead
|
||||||
|
|
||||||
void Setup();
|
void Setup();
|
||||||
i32 GetFrame(u32 frame);
|
i32 GetFrame(u32 frame);
|
||||||
void Destroy();
|
void Destroy();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ProjectState {
|
struct ProjectState {
|
||||||
CompositionState *inspecting_composition;
|
CompositionState *inspecting_composition = nullptr;
|
||||||
plf::colony<CompositionState> compositions{};
|
plf::colony<CompositionState> compositions{};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -84,6 +84,8 @@ namespace K::Resource {
|
||||||
|
|
||||||
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name);
|
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name);
|
||||||
|
|
||||||
|
void LoadFile();
|
||||||
|
|
||||||
void SaveCurrentProject();
|
void SaveCurrentProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@
|
||||||
namespace K {
|
namespace K {
|
||||||
enum UniformStatus {
|
enum UniformStatus {
|
||||||
K_U_Inactive = 0,
|
K_U_Inactive = 0,
|
||||||
K_U_Exposed,
|
K_U_Exposed = 1 << 1,
|
||||||
K_U_SamplerDims,
|
K_U_SamplerDims = 1 << 2,
|
||||||
K_U_Count
|
K_U_SamplerFrame = 1 << 3 // "fake" frame -- since shader does not care about the frame of the image
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Uniform {
|
struct Uniform {
|
||||||
|
@ -20,14 +20,14 @@ namespace K {
|
||||||
bgfx::UniformHandle handle;
|
bgfx::UniformHandle handle;
|
||||||
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val;
|
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val;
|
||||||
Plugboard::ConnectInfo connection;
|
Plugboard::ConnectInfo connection;
|
||||||
UniformStatus status = K_U_Inactive;
|
i32 status = K_U_Inactive; // enum UniformStatus
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sampler {
|
struct Sampler {
|
||||||
String name;
|
String name;
|
||||||
bgfx::UniformHandle handle;
|
bgfx::UniformHandle handle;
|
||||||
std::variant<Resource::Resource<Resource::K_R_Still>*, CompositionState*> resource;
|
std::variant<Resource::Resource<Resource::K_R_Still>*, CompositionState*> resource;
|
||||||
Uniform *dims;
|
Uniform *dims, *frame;
|
||||||
};
|
};
|
||||||
|
|
||||||
ShaderGraph::T_Map<ShaderGraph::T_Count>::type PlugboardValToShader(const Plugboard::T_Map<Plugboard::T_Count>::type& val);
|
ShaderGraph::T_Map<ShaderGraph::T_Count>::type PlugboardValToShader(const Plugboard::T_Map<Plugboard::T_Count>::type& val);
|
||||||
|
|
1
TODO.md
1
TODO.md
|
@ -7,7 +7,6 @@
|
||||||
- Blender previews resource
|
- Blender previews resource
|
||||||
- Data models
|
- Data models
|
||||||
- Dump and read back state, (de)serialization!!!
|
- Dump and read back state, (de)serialization!!!
|
||||||
- Pre-compose/Layer Groups
|
|
||||||
- Undo's
|
- Undo's
|
||||||
- Node groups
|
- Node groups
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue