plugboard init
This commit is contained in:
parent
0d713b6da6
commit
5f6adef565
13 changed files with 479 additions and 163 deletions
|
@ -14,8 +14,8 @@
|
|||
|
||||
namespace {
|
||||
SDL_Window *window;
|
||||
u16 window_width = 1920;
|
||||
u16 window_height = 1080;
|
||||
u16 window_width = 2200;
|
||||
u16 window_height = 1200;
|
||||
|
||||
u64 init_time, last_time, current_time, delta_t;
|
||||
u32 frame;
|
||||
|
|
21
Keishiki/PlugboardGraph.cpp
Normal file
21
Keishiki/PlugboardGraph.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <PlugboardGraph.h>
|
||||
|
||||
namespace K::PlugboardGraph {
|
||||
String VarToString(const T_Map<T_Count>::type& var) {
|
||||
return std::visit([](auto&& arg) -> String {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, T_Map<T_Float>::type>)
|
||||
return std::to_string(arg) + "f";
|
||||
else if constexpr (std::is_same_v<T, T_Map<T_Int>::type>)
|
||||
return std::to_string(arg);
|
||||
else if constexpr (std::is_same_v<T, T_Map<T_RGBA>::type>)
|
||||
return "vec4(" + std::to_string(arg.r) + "," + std::to_string(arg.g) + "," + std::to_string(arg.b) + "," + std::to_string(arg.a) + ")";
|
||||
else if constexpr (std::is_same_v<T, T_Map<T_XY>::type>)
|
||||
return "vec2(" + std::to_string(arg.x) + "," + std::to_string(arg.y) + ")";
|
||||
else if constexpr (std::is_same_v<T, T_Map<T_XYZ>::type>)
|
||||
return "vec3(" + std::to_string(arg.x) + "," + std::to_string(arg.y) + "," + std::to_string(arg.z) + ")";
|
||||
else if constexpr (std::is_same_v<T, T_Map<T_String>::type>)
|
||||
return arg;
|
||||
}, var);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
#include <ShaderGraph.h>
|
||||
#include <format>
|
||||
#include "srell.hpp"
|
||||
|
||||
namespace {
|
||||
|
|
346
Keishiki/UI.cpp
346
Keishiki/UI.cpp
|
@ -1,6 +1,8 @@
|
|||
#include "UI.h"
|
||||
#include "Graphics.h"
|
||||
#include "VisualTrack.h"
|
||||
#include "PlugboardNodes.h"
|
||||
|
||||
#include "ext/imgui/misc/cpp/imgui_stdlib.h"
|
||||
#include <imgui.h>
|
||||
#include <imgui_internal.h>
|
||||
#include <misc/cpp/imgui_stdlib.h>
|
||||
|
@ -85,7 +87,7 @@ namespace K::UI {
|
|||
|
||||
bg.pg = K::Graphics::load_shader_program("Checkerboard");
|
||||
bg.add_uniform("f_hw", ShaderGraph::Type::T_XYZ);
|
||||
bg.uniforms.begin()->second.second = ShaderGraph::XYZ{ static_cast<f32>(s.width), static_cast<f32>(s.height), 0.0f };
|
||||
bg.uniforms.begin()->second.val = ShaderGraph::XYZ{ static_cast<f32>(s.width), static_cast<f32>(s.height), 0.0f };
|
||||
|
||||
bx::mtxOrtho(proj, 0.0f, static_cast<f32>(s.width), 0.0f, static_cast<f32>(s.height),
|
||||
0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
|
||||
|
@ -107,7 +109,7 @@ namespace K::UI {
|
|||
std::free(save_buffer);
|
||||
|
||||
bgfx::destroy(bg.pg);
|
||||
bgfx::destroy(bg.uniforms.begin()->second.first);
|
||||
bgfx::destroy(bg.uniforms.begin()->second.handle);
|
||||
bg.uniforms.erase(bg.uniforms.begin());
|
||||
|
||||
for (auto& layer : s.layers)
|
||||
|
@ -116,7 +118,7 @@ namespace K::UI {
|
|||
|
||||
void Viewport(CompState& s) {
|
||||
if (ImGui::Begin("Viewport", &draw_viewport)) {
|
||||
ImTextureID idx = nullptr;
|
||||
ImTextureID idx;
|
||||
|
||||
bg.get_frame(composite_fb, s.width, s.height, proj, view, transform);
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_COMPOSITE, composite_blit, 0, 0, composite);
|
||||
|
@ -134,14 +136,13 @@ namespace K::UI {
|
|||
|
||||
ImGui::SameLine();
|
||||
|
||||
auto cp = save_called;
|
||||
if (cp) ImGui::BeginDisabled();
|
||||
ImGui::BeginDisabled(save_called);
|
||||
if (ImGui::Button("Save to frame.png")) {
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_SAVE, save, 0, 0, composite);
|
||||
ready_frame = bgfx::readTexture(save, save_buffer);
|
||||
save_called = true;
|
||||
}
|
||||
if (cp) ImGui::EndDisabled();
|
||||
ImGui::EndDisabled();
|
||||
|
||||
}
|
||||
ImGui::End();
|
||||
|
@ -164,21 +165,21 @@ namespace K::UI {
|
|||
};
|
||||
l.track.add_uniform("aspect_ratio", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
if (s.width > s.height)
|
||||
l.track.uniforms["aspect_ratio"].second = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(static_cast<f32>(s.width)/static_cast<f32>(s.height), 1.0f);
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(static_cast<f32>(s.width)/static_cast<f32>(s.height), 1.0f);
|
||||
else
|
||||
l.track.uniforms["aspect_ratio"].second = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, static_cast<f32>(s.height)/static_cast<f32>(s.width));
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, static_cast<f32>(s.height)/static_cast<f32>(s.width));
|
||||
|
||||
l.track.add_uniform("opacity", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["opacity"].second = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
||||
l.track.uniforms["opacity"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
||||
|
||||
l.track.add_uniform("rot", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["rot"].second = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
||||
l.track.uniforms["rot"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
||||
|
||||
l.track.add_uniform("scale", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["scale"].second = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, 1.0f);
|
||||
l.track.uniforms["scale"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, 1.0f);
|
||||
|
||||
l.track.add_uniform("translate", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["translate"].second = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(.0f, .0f);
|
||||
l.track.uniforms["translate"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(.0f, .0f);
|
||||
|
||||
l.track.shader = "void main() {\n"
|
||||
"\tfloat angle = -rot * M_PI / 180.0f;\n"
|
||||
|
@ -266,7 +267,7 @@ namespace K::UI {
|
|||
if (!no_selection) source_flags |= ImGuiDragDropFlags_SourceNoPreviewTooltip;
|
||||
if ((no_selection || s.selected.contains(i)) && ImGui::BeginDragDropSource(source_flags)) {
|
||||
if (s.selected.empty()) ImGui::Text("Swap with #%u %s", i, s.layers[i].name.c_str());
|
||||
ImGui::SetDragDropPayload("DND_DEMO_NAME", &i, sizeof(u32));
|
||||
ImGui::SetDragDropPayload("K_COMP_REORDER", &i, sizeof(u32));
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if ((no_selection || !s.selected.contains(i)) && ImGui::BeginDragDropTarget()) {
|
||||
|
@ -278,7 +279,7 @@ namespace K::UI {
|
|||
ImGui::SetTooltip("Before #%u %s", i, s.layers[i].name.c_str());
|
||||
}
|
||||
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("DND_DEMO_NAME")) {
|
||||
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("K_COMP_REORDER")) {
|
||||
move_from = *(const int*)payload->Data;
|
||||
move_to = i;
|
||||
}
|
||||
|
@ -338,160 +339,197 @@ namespace K::UI {
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
void PlugboardNodeDrawSockets(PlugboardGraph::NodeInstance& n, ImGuiStyle& style,
|
||||
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, ImVec4, PlugboardGraph::_ConnectInfoHasher>& link_pos,
|
||||
bool dummy = true) {
|
||||
i32 row = 1;
|
||||
for (u32 out = 0; out < n.node->out_names.size(); out++, row++) {
|
||||
ImGui::PushID(row);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
if (dummy)
|
||||
ImGui::Dummy({100.0f - ImGui::CalcTextSize(n.node->out_names[out].c_str()).x - style.ItemSpacing.x, 0.0f});
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%s", n.node->out_names[out].c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("##Out", false);
|
||||
if (ImGui::IsItemActive()) {
|
||||
dragging_on_socket = true;
|
||||
source = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
PlugboardGraph::ConnectInfo d{ &n, out };
|
||||
ImGui::SetDragDropPayload("K_PLUG_OUT_TO_IN", &d, sizeof(d));
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_PLUG_IN_TO_OUT")) {
|
||||
PlugboardGraph::ConnectInfo in = *(const PlugboardGraph::ConnectInfo*)payload->Data;
|
||||
in.p->connect(in.index, &n, out);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
ImGui::PopID();
|
||||
|
||||
// Update link info if needed
|
||||
if (n.outputs_going[out].p != nullptr) {
|
||||
auto pos = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
|
||||
auto& d = link_pos[std::get<PlugboardGraph::ConnectInfo>(n.outputs_going[out].p->inputs_fed[n.outputs_going[out].index])];
|
||||
d.w = pos.x;
|
||||
d.z = pos.y;
|
||||
}
|
||||
}
|
||||
for (u32 in = 0; in < n.inputs_fed.size(); in++, row++) {
|
||||
ImGui::PushID(row);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("##In", false);
|
||||
if (ImGui::IsItemActive()) {
|
||||
dragging_on_socket = true;
|
||||
source = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
PlugboardGraph::ConnectInfo d{ &n, in };
|
||||
ImGui::SetDragDropPayload("K_PLUG_IN_TO_OUT", &d, sizeof(d));
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_PLUG_OUT_TO_IN")) {
|
||||
PlugboardGraph::ConnectInfo out = *(const PlugboardGraph::ConnectInfo*)payload->Data;
|
||||
n.connect(in, out.p, out.index);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
// Update link info if needed
|
||||
if (n.inputs_fed[in].index() == 0) {
|
||||
auto pos = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y};
|
||||
auto& d = link_pos[std::get<PlugboardGraph::ConnectInfo>(n.inputs_fed[in])];
|
||||
d.x = pos.x;
|
||||
d.y = pos.y;
|
||||
}
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", n.node->in_names[in].c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PopID();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void PlugboardDrawNode(PlugboardGraph::NodeInstance& n, ImVec2& view_pos, i32 id, ImGuiIO& io, ImGuiStyle& style,
|
||||
bool& dragging_on_socket, ImVec2& source, std::unordered_map<PlugboardGraph::ConnectInfo, ImVec4, PlugboardGraph::_ConnectInfoHasher>& link_pos) {
|
||||
ImGui::SetCursorPos(view_pos + n.pos);
|
||||
ImGui::PushID(id);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xFF080813);
|
||||
ImGui::BeginChild(n.node->name.c_str(), {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Border);
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::BeginTable(n.node->name.c_str(), 3)) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button(n.node->name.c_str(), {100.0f , 0.0f});
|
||||
if (ImGui::IsItemClicked()) {
|
||||
n.old_pos = n.pos;
|
||||
}
|
||||
if (ImGui::IsItemActive()) {
|
||||
n.pos = n.old_pos + (io.MousePos - io.MouseClickedPos[0]);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
PlugboardNodeDrawSockets(n, style, dragging_on_socket, source, link_pos);
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
||||
void Plugboard(CompState& s) {
|
||||
if (!ImGui::Begin("Plugboard", &draw_plugboard)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
if (ImGui::Button("Add Sine"))
|
||||
s.plugboard.nodes.push_back(PlugboardGraph::MakeInstance(PlugboardNodes::Sine));
|
||||
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
ImGuiStyle style = ImGui::GetStyle();
|
||||
|
||||
static f32 view_scale = 1.0f;
|
||||
static ImVec2 view_pos{}, old_view_pos{};
|
||||
|
||||
bool dragging_on_socket{};
|
||||
static ImVec2 drag_source{};
|
||||
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xFF100500);
|
||||
ImGui::BeginChild("view_port", ImGui::GetContentRegionAvail(), 0, ImGuiWindowFlags_NoMove);
|
||||
ImGui::BeginChild("Nodes", ImGui::GetContentRegionAvail(), 0, ImGuiWindowFlags_NoMove);
|
||||
ImGui::PopStyleColor();
|
||||
|
||||
if (ImGui::IsMouseClicked(0)) {
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_PLUG_IN_TO_OUT")) {
|
||||
PlugboardGraph::ConnectInfo in = *(const PlugboardGraph::ConnectInfo*)payload->Data;
|
||||
in.p->disconnect(in.index);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_PLUG_OUT_TO_IN")) {
|
||||
PlugboardGraph::ConnectInfo out = *(const PlugboardGraph::ConnectInfo*)payload->Data;
|
||||
auto& in = out.p->outputs_going[out.index];
|
||||
in.p->disconnect(in.index);
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGuiWindow* window = ImGui::GetCurrentWindow();
|
||||
|
||||
s.plugboard.links_pos.clear();
|
||||
|
||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||
old_view_pos = view_pos;
|
||||
}
|
||||
if (ImGui::IsItemActive()) {
|
||||
view_pos = old_view_pos + (io.MousePos - io.MouseClickedPos[0]);
|
||||
}
|
||||
|
||||
static ImVec2 out{}, in{}, out2{}, in2{};
|
||||
|
||||
static ImVec2 pos{}, old_pos{};
|
||||
ImGui::SetCursorPos(view_pos + pos);
|
||||
static bool active{};
|
||||
ImGui::PushID(1);
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0xFF080813);
|
||||
ImGui::BeginChild("sad", {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY | ImGuiChildFlags_Border);
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::BeginTable("s", 3)) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Button("Asdf", {100.0f , 0.0f});
|
||||
if (ImGui::IsItemClicked()) {
|
||||
old_pos = pos;
|
||||
}
|
||||
if (ImGui::IsItemActive()) {
|
||||
pos = old_pos + (io.MousePos - io.MouseClickedPos[0]);
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
ImGui::PushID(1);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Dummy({100.0f - ImGui::CalcTextSize("asd").x - style.ItemSpacing.x, 0.0f});
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("qq");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("##asd", active);
|
||||
out = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y };
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("##asd", active);
|
||||
in2 = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y };
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("asd");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::PopID();
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
if (ImGui::IsItemActive()) {
|
||||
}
|
||||
|
||||
if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
OutToIn d{ &n, u };
|
||||
ImGui::SetDragDropPayload("K_SHADER_OUT_TO_IN", &d, sizeof(d));
|
||||
ImGui::Text("asdf");
|
||||
ImGui::EndDragDropSource();
|
||||
}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_SHADER_IN_TO_OUT")) {
|
||||
InSlot* in = *(InSlot**)payload->Data;
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
*/
|
||||
|
||||
/* for (InSlot& s : n.inputs) {
|
||||
ImGui::PushID(i);
|
||||
|
||||
bool active = s.node != nullptr;
|
||||
if (active) {
|
||||
window->DrawList->AddLine(window->DC.CursorPos, io.MousePos, 0xFFAAAAAA, 2.0f);
|
||||
}
|
||||
ImGui::RadioButton((s.name).c_str(), active);
|
||||
if (ImGui::IsItemActive())
|
||||
window->DrawList->AddLine(io.MouseClickedPos[0], io.MousePos, 0xFFAAAAAA, 2.0f);
|
||||
|
||||
//if (ImGui::BeginDragDropSource(ImGuiDragDropFlags_None)) {
|
||||
// const InSlot* ptr = &s;
|
||||
// ImGui::SetDragDropPayload("K_SHADER_IN_TO_OUT", &ptr, sizeof(ptr));
|
||||
// ImGui::Text("%s", Type_To_Str[s.type]);
|
||||
// ImGui::EndDragDropSource();
|
||||
//}
|
||||
if (ImGui::BeginDragDropTarget()) {
|
||||
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("K_SHADER_OUT_TO_IN")) {
|
||||
OutToIn out = *(const OutToIn*)payload->Data;
|
||||
if (out.node->out[out.index].first == s.type) {
|
||||
s.node = out.node;
|
||||
s.out_index = out.index;
|
||||
}
|
||||
}
|
||||
ImGui::EndDragDropTarget();
|
||||
}
|
||||
|
||||
ImGui::PopID();
|
||||
i++;
|
||||
}*/
|
||||
|
||||
ImGui::EndChild();
|
||||
ImGui::PopID();
|
||||
for (u32 i = 0; i < s.plugboard.nodes.size(); i++)
|
||||
PlugboardDrawNode(s.plugboard.nodes[i], view_pos, i, io, style, dragging_on_socket, drag_source, s.plugboard.links_pos);
|
||||
|
||||
ImGui::SetCursorPos({});
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0x33FFFFFF);
|
||||
ImGui::BeginChild("asdasd", {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY );
|
||||
ImGui::BeginChild(s.plugboard.comp_in.name.c_str(), {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY );
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::BeginTable("Source", 2)) {
|
||||
ImGui::PushID(1);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("Time");
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("##asd", active);
|
||||
out2 = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y };
|
||||
ImGui::PopID();
|
||||
if (ImGui::BeginTable(s.plugboard.comp_in.name.c_str(), 3)) {
|
||||
PlugboardNodeDrawSockets(s.plugboard.in_instance, style, dragging_on_socket, drag_source, s.plugboard.links_pos, false);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::SetCursorPos({ImGui::GetContentRegionAvail().x - 100.0f, 0.0f});
|
||||
static f32 right_offset = 0.0f; // check after drawing this frame, so next frame will be correct
|
||||
ImGui::SetCursorPos({ImGui::GetContentRegionAvail().x - right_offset, 0.0f});
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, 0x33FFFFFF);
|
||||
ImGui::BeginChild("ert", {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY);
|
||||
ImGui::BeginChild(s.plugboard.comp_out.name.c_str(), {}, ImGuiChildFlags_AlwaysAutoResize | ImGuiChildFlags_AutoResizeX | ImGuiChildFlags_AutoResizeY);
|
||||
ImGui::PopStyleColor();
|
||||
if (ImGui::BeginTable("Source", 1)) {
|
||||
ImGui::PushID(1);
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::RadioButton("asfnjklanf", active);
|
||||
in = ImGui::GetCursorScreenPos() + ImVec2{ ImGui::GetFrameHeight() / 2, -ImGui::GetFrameHeight() / 2 - style.ItemInnerSpacing.y };
|
||||
ImGui::PopID();
|
||||
if (ImGui::BeginTable(s.plugboard.comp_out.name.c_str(), 3)) {
|
||||
PlugboardNodeDrawSockets(s.plugboard.out_instance, style, dragging_on_socket, drag_source, s.plugboard.links_pos, false);
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::EndChild();
|
||||
|
||||
ImGui::GetCurrentWindow()->DrawList->AddLine(in, out, 0xFFFFFFFF, 2.0f);
|
||||
ImGui::GetCurrentWindow()->DrawList->AddLine(in2, out2, 0xFFAAAAAA, 2.0f);
|
||||
right_offset += ImGui::GetItemRectMax().x - ImGui::GetWindowWidth();
|
||||
|
||||
for (auto& [_, link] : s.plugboard.links_pos)
|
||||
window->DrawList->AddLine({link.x, link.y}, {link.w, link.z}, 0xFFFFFFFF, 2.0f);
|
||||
|
||||
if (dragging_on_socket)
|
||||
window->DrawList->AddLine(ImGui::GetMousePos(), drag_source, 0xFFFFFFFF, 2.0f);
|
||||
|
||||
ImGui::EndChild();
|
||||
|
||||
|
@ -537,13 +575,36 @@ namespace K::UI {
|
|||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", it->first.c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", ShaderGraph::Type_To_Str[it->second.second.index()]);
|
||||
ImGui::Text("%s", ShaderGraph::Type_To_Str[it->second.val.index()]);
|
||||
ImGui::TableNextColumn();
|
||||
bool temp{};
|
||||
ImGui::Checkbox("##Expose", &temp);
|
||||
bool d = it->second.exposure.p != nullptr, cp = d;
|
||||
ImGui::Checkbox("##Expose", &d);
|
||||
if (d != cp) {
|
||||
if (d) {
|
||||
String id = s.layers[s.active].name + "." + it->first;
|
||||
it->second.exposure = {&s.plugboard.out_instance, static_cast<u32>(s.plugboard.out_instance.node->in_names.size())};
|
||||
s.plugboard.out_instance.node->in_names.push_back(id);
|
||||
s.plugboard.out_instance.node->in_types.push_back(PlugboardGraph::Type(it->second.val.index())); // this is shaky and bug prone -- relies on the shader types being in line with plugboard types
|
||||
s.plugboard.out_instance.inputs_fed.push_back(ShaderValToPlugboard(it->second.val));
|
||||
}
|
||||
else {
|
||||
it->second.exposure.p->disconnect(it->second.exposure.index);
|
||||
|
||||
for (auto& l : s.layers)
|
||||
for (auto& u : l.track.uniforms)
|
||||
if (u.second.exposure.index > it->second.exposure.index)
|
||||
u.second.exposure.index--;
|
||||
s.plugboard.comp_out.in_names.erase(s.plugboard.out_instance.node->in_names.begin() + it->second.exposure.index);
|
||||
s.plugboard.comp_out.in_types.erase(s.plugboard.out_instance.node->in_types.begin() + it->second.exposure.index);
|
||||
s.plugboard.out_instance.inputs_fed.erase(s.plugboard.out_instance.inputs_fed.begin() + it->second.exposure.index);
|
||||
|
||||
it->second.exposure = {nullptr, 0};
|
||||
}
|
||||
}
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::SetNextItemWidth(-FLT_MIN);
|
||||
std::visit([it](auto&& arg) {
|
||||
ImGui::BeginDisabled(it->second.exposure.p != nullptr);
|
||||
std::visit([](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Float>::type>)
|
||||
ImGui::DragFloat("##", &arg, 0.005f);
|
||||
|
@ -555,10 +616,11 @@ namespace K::UI {
|
|||
ImGui::DragFloat2("##", &arg.x, 0.005f);
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_XYZ>::type>)
|
||||
ImGui::DragFloat3("##", &arg.x, 0.005f);
|
||||
}, it->second.second);
|
||||
}, it->second.val);
|
||||
ImGui::EndDisabled();
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Button("X")) {
|
||||
bgfx::destroy(it->second.first);
|
||||
bgfx::destroy(it->second.handle);
|
||||
it = s.layers[s.active].track.uniforms.erase(it);
|
||||
}
|
||||
else it++;
|
||||
|
@ -632,7 +694,7 @@ namespace K::UI {
|
|||
break;
|
||||
default:
|
||||
LogError("Unsupported Renderer");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void Shutdown(CompState& s) {
|
||||
|
|
|
@ -23,7 +23,7 @@ namespace K {
|
|||
using Byte = u8;
|
||||
using Char = char;
|
||||
template <typename T> using Vector = std::vector<T>;
|
||||
template <typename T, typename U> using Dict = std::unordered_map<T, U>; // to be replaced
|
||||
template <typename T, typename U> using Dict = std::unordered_map<T, U>; // to be replaced
|
||||
|
||||
inline void LogBase(const String& s, u8 level) {
|
||||
static const char *levels[] = {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "VisualTrack.h"
|
||||
#include <set>
|
||||
#include <unordered_set>
|
||||
#include "PlugboardGraph.h"
|
||||
|
||||
namespace K {
|
||||
bool Init();
|
||||
|
@ -18,13 +19,19 @@ namespace K {
|
|||
};
|
||||
|
||||
struct CompState {
|
||||
// Time
|
||||
u64 current_frame;
|
||||
u64 frame_max;
|
||||
u32 fps;
|
||||
u32 fps;
|
||||
|
||||
u32 width, height;
|
||||
|
||||
Vector<Layer> layers;
|
||||
i32 active = -1; // index for layers
|
||||
std::set<u32> selected; // indices for layers
|
||||
std::unordered_set<u32> disabled; // indices for layers
|
||||
|
||||
|
||||
PlugboardGraph::PlugboardGraph plugboard;
|
||||
};
|
||||
}
|
||||
|
|
162
Keishiki/include/PlugboardGraph.h
Normal file
162
Keishiki/include/PlugboardGraph.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "Graphics.h"
|
||||
#include <variant>
|
||||
#include <functional>
|
||||
#include <imgui.h>
|
||||
|
||||
namespace K::PlugboardGraph {
|
||||
enum Type {
|
||||
T_Float,
|
||||
T_Int,
|
||||
T_RGBA,
|
||||
T_XY,
|
||||
T_XYZ,
|
||||
T_String,
|
||||
T_Count
|
||||
};
|
||||
static const char *Type_To_Str[] = {
|
||||
"Float",
|
||||
"Int",
|
||||
"RGBA",
|
||||
"XY",
|
||||
"XYZ",
|
||||
"String",
|
||||
"Error"
|
||||
};
|
||||
|
||||
struct RGBA { f32 r, g, b, a; };
|
||||
struct XYZ { f32 x, y, z; };
|
||||
struct XY { f32 x, y; };
|
||||
template<Type> struct T_Map;
|
||||
template<> struct T_Map<T_Float> {
|
||||
using type = f32;
|
||||
};
|
||||
template<> struct T_Map<T_Int> {
|
||||
using type = i32;
|
||||
};
|
||||
template<> struct T_Map<T_RGBA> {
|
||||
using type = RGBA;
|
||||
};
|
||||
template<> struct T_Map<T_XY> {
|
||||
using type = XY;
|
||||
};
|
||||
template<> struct T_Map<T_XYZ> {
|
||||
using type = XYZ;
|
||||
};
|
||||
template<> struct T_Map<T_String> {
|
||||
using type = String;
|
||||
};
|
||||
template<> struct T_Map<T_Count> {
|
||||
using type = std::variant<f32, i32, RGBA, XY, XYZ, String>;
|
||||
};
|
||||
String VarToString(const T_Map<T_Count>::type& var);
|
||||
|
||||
inline T_Map<T_Count>::type expand_type(Type i) {
|
||||
static T_Map<T_Count>::type table[] = {f32{}, i32{}, PlugboardGraph::RGBA{}, PlugboardGraph::XY{}, PlugboardGraph::XYZ{}, String{}};
|
||||
return table[i];
|
||||
}
|
||||
|
||||
struct Node {
|
||||
String name;
|
||||
|
||||
Vector<String> in_names;
|
||||
Vector<Type> in_types;
|
||||
|
||||
Vector<String> out_names;
|
||||
Vector<Type> out_types;
|
||||
Vector<std::function<T_Map<T_Count>::type(Vector<T_Map<T_Count>::type>)>> fetch; // maybe change to a function pointer later
|
||||
// todo investigate how you might wanna jit this instead of evaluating a tree for each output at runtime
|
||||
};
|
||||
|
||||
struct NodeInstance;
|
||||
|
||||
struct ConnectInfo {
|
||||
NodeInstance *p; u32 index;
|
||||
auto operator<=>(const ConnectInfo&) const = default;
|
||||
};
|
||||
|
||||
struct _ConnectInfoHasher
|
||||
{
|
||||
std::size_t operator()(const ConnectInfo& k) const
|
||||
{
|
||||
return std::hash<NodeInstance *>()(k.p);
|
||||
}
|
||||
};
|
||||
|
||||
struct NodeInstance {
|
||||
Node *node;
|
||||
|
||||
Vector<std::variant<ConnectInfo, T_Map<Type::T_Count>::type>> inputs_fed;
|
||||
Vector<ConnectInfo> outputs_going;
|
||||
|
||||
ImVec2 pos, old_pos;
|
||||
|
||||
void connect(u32 input_index, NodeInstance *to, u32 to_out_index) {
|
||||
inputs_fed[input_index] = ConnectInfo{to, to_out_index};
|
||||
to->outputs_going[to_out_index] = {this, input_index};
|
||||
}
|
||||
|
||||
void disconnect(u32 input_index) {
|
||||
std::visit([](auto&& arg){
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, ConnectInfo>)
|
||||
arg.p->outputs_going[arg.index] = {nullptr, 0};
|
||||
else if constexpr (std::is_same_v<T, T_Map<Type::T_Count>::type>)
|
||||
;
|
||||
}, inputs_fed[input_index]);
|
||||
inputs_fed[input_index] = expand_type(node->in_types[input_index]);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
inline NodeInstance MakeInstance(Node& n) {
|
||||
Vector<std::variant<ConnectInfo, T_Map<Type::T_Count>::type>> inp;
|
||||
Vector<ConnectInfo> out;
|
||||
for (auto t : n.in_types)
|
||||
inp.push_back(expand_type(t));
|
||||
for (auto t : n.out_types)
|
||||
out.push_back({});
|
||||
return {
|
||||
.node = &n,
|
||||
.inputs_fed = std::move(inp),
|
||||
.outputs_going = std::move(out)
|
||||
};
|
||||
}
|
||||
|
||||
inline T_Map<T_Count>::type Eval(const ConnectInfo& info) {
|
||||
Vector<T_Map<T_Count>::type> pack;
|
||||
for (auto& v : info.p->inputs_fed)
|
||||
std::visit([&pack](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, ConnectInfo>)
|
||||
pack.push_back(Eval(arg));
|
||||
else if constexpr (std::is_same_v<T, T_Map<Type::T_Count>::type>)
|
||||
pack.push_back(arg);
|
||||
}, v);
|
||||
return info.p->node->fetch[info.index](pack);
|
||||
}
|
||||
|
||||
struct PlugboardGraph {
|
||||
Vector<NodeInstance> nodes;
|
||||
std::unordered_map<ConnectInfo, ImVec4, _ConnectInfoHasher> links_pos; // this is hilariously bad
|
||||
Node comp_in = {
|
||||
"Composition In",
|
||||
{},
|
||||
{},
|
||||
{"Time"},
|
||||
{T_Float},
|
||||
{[](Vector<T_Map<T_Count>::type> v) { return T_Map<T_Count>::type{ static_cast<f32>(SDL_GetTicks()) / 20.0f }; }} // kill me
|
||||
},
|
||||
comp_out = {
|
||||
"Composition Out",
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{}
|
||||
};
|
||||
NodeInstance in_instance = {&comp_in, {}, {{nullptr, 0}}}, out_instance = {&comp_out};
|
||||
};
|
||||
|
||||
}
|
17
Keishiki/include/PlugboardNodes.h
Normal file
17
Keishiki/include/PlugboardNodes.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "PlugboardGraph.h"
|
||||
|
||||
namespace K::PlugboardNodes {
|
||||
PlugboardGraph::Node Sine = {
|
||||
.name = "Sine",
|
||||
.in_names = { "In" },
|
||||
.in_types = { PlugboardGraph::T_Float },
|
||||
|
||||
.out_names = { "Out" },
|
||||
.out_types = { PlugboardGraph::T_Float },
|
||||
.fetch = {[](const Vector<PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type>& arg) {
|
||||
return std::sin(std::get<PlugboardGraph::T_Float>(arg[0]));
|
||||
}}
|
||||
};
|
||||
}
|
|
@ -2,9 +2,8 @@
|
|||
#include "Common.h"
|
||||
#include "Graphics.h"
|
||||
#include <variant>
|
||||
#include "imgui.h"
|
||||
#include "Graphics.h"
|
||||
|
||||
// todo a lot of problems in this unit can lead to very bad performance
|
||||
namespace K::ShaderGraph {
|
||||
enum Type {
|
||||
T_Float,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
#pragma once
|
||||
#include "Common.h"
|
||||
#include "Keishiki.h"
|
||||
#include "Graphics.h"
|
||||
#include "VisualTrack.h"
|
||||
|
||||
namespace K::UI {
|
||||
void Init(SDL_Window *window);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <functional>
|
||||
#include <bx/math.h>
|
||||
#include <fstream>
|
||||
#include "PlugboardGraph.h"
|
||||
|
||||
namespace K {
|
||||
template <typename T>
|
||||
|
@ -18,11 +19,51 @@ namespace K {
|
|||
}
|
||||
};
|
||||
|
||||
struct Uniform {
|
||||
bgfx::UniformHandle handle;
|
||||
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val;
|
||||
PlugboardGraph::ConnectInfo exposure;
|
||||
};
|
||||
|
||||
inline ShaderGraph::T_Map<ShaderGraph::T_Count>::type PlugboardValToShader(const PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type& val) {
|
||||
return std::visit([](auto&& arg) -> ShaderGraph::T_Map<ShaderGraph::T_Count>::type {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_Float>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_Float>::type(arg);
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_Int>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_Int>::type(arg);
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_RGBA>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_RGBA>::type(arg.r, arg.g, arg.b, arg.a);
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_XY>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_XY>::type(arg.x, arg.y);
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_XYZ>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_XYZ>::type(arg.x, arg.y, arg.z);
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_String>::type>)
|
||||
return ShaderGraph::T_Map<ShaderGraph::T_Count>::type{};
|
||||
},val);
|
||||
}
|
||||
|
||||
inline PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type ShaderValToPlugboard(const ShaderGraph::T_Map<ShaderGraph::T_Count>::type& val) {
|
||||
return std::visit([](auto&& arg) -> PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Float>::type>)
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_Float>::type(arg);
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Int>::type>)
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_Int>::type(arg);
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_RGBA>::type>)
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_RGBA>::type(arg.r, arg.g, arg.b, arg.a);
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_XY>::type>)
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_XY>::type(arg.x, arg.y);
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_XYZ>::type>)
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_XYZ>::type(arg.x, arg.y, arg.z);
|
||||
},val);
|
||||
}
|
||||
|
||||
struct VisualTrack {
|
||||
ShaderGraph::ShaderGraph tree;
|
||||
bgfx::ProgramHandle pg = BGFX_INVALID_HANDLE;
|
||||
String shader;
|
||||
Dict<String, std::pair<bgfx::UniformHandle, ShaderGraph::T_Map<ShaderGraph::T_Count>::type>> uniforms;
|
||||
Dict<String, Uniform> uniforms;
|
||||
// Vector<String> samplers;
|
||||
bgfx::TextureHandle get_frame(bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16], f32 view[16], f32 transform[16]) const {
|
||||
bgfx::touch(K::Graphics::K_VIEW_COMP_COMPOSITE);
|
||||
|
@ -35,6 +76,18 @@ namespace K {
|
|||
|
||||
for (auto& [_name, u] : uniforms) {
|
||||
f32 pack[4]{};
|
||||
ShaderGraph::T_Map<ShaderGraph::T_Count>::type val_target;
|
||||
if (u.exposure.p == nullptr)
|
||||
val_target = u.val;
|
||||
else {
|
||||
std::visit([&val_target](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, PlugboardGraph::ConnectInfo>)
|
||||
val_target = PlugboardValToShader(PlugboardGraph::Eval(arg));
|
||||
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type>)
|
||||
val_target = PlugboardValToShader(arg);
|
||||
}, u.exposure.p->inputs_fed[u.exposure.index]);
|
||||
}
|
||||
std::visit([&pack](auto&& arg) {
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Float>::type> || std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Int>::type>)
|
||||
|
@ -54,8 +107,8 @@ namespace K {
|
|||
pack[1] = arg.y;
|
||||
pack[2] = arg.z;
|
||||
}
|
||||
}, u.second);
|
||||
bgfx::setUniform(u.first, pack);
|
||||
}, val_target);
|
||||
bgfx::setUniform(u.handle, pack);
|
||||
}
|
||||
|
||||
Graphics::DrawTextureWithTransform(K::Graphics::K_VIEW_COMP_COMPOSITE, Graphics::mmaker->tx, transform,
|
||||
|
@ -65,7 +118,7 @@ namespace K {
|
|||
}
|
||||
void add_uniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val) {
|
||||
if (!uniforms.contains(s))
|
||||
uniforms.emplace(s, std::make_pair(bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val));
|
||||
uniforms.emplace(s, Uniform{bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val, {nullptr, 0}});
|
||||
}
|
||||
void compile() {
|
||||
std::ofstream f("temp.frag");
|
||||
|
@ -88,7 +141,7 @@ namespace K {
|
|||
f << ".xy";
|
||||
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_XYZ>::type>)
|
||||
f << ".xyz";
|
||||
}, u.second.second);
|
||||
}, u.second.val);
|
||||
f << "\n";
|
||||
}
|
||||
f << shader;
|
||||
|
@ -144,7 +197,7 @@ namespace K {
|
|||
if (bgfx::isValid(pg))
|
||||
bgfx::destroy(pg);
|
||||
for (auto& uniform : uniforms) {
|
||||
bgfx::destroy(uniform.second.first);
|
||||
bgfx::destroy(uniform.second.handle);
|
||||
}
|
||||
uniforms.clear();
|
||||
}
|
||||
|
|
|
@ -143,9 +143,4 @@ void main()
|
|||
float alpha = _A.a + alpha_b;
|
||||
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
|
||||
}
|
||||
else if (f_mode.x == 26.0f) {
|
||||
float alpha_b = _A.a * (1.0f - _B.a);
|
||||
float alpha = _A.a + alpha_b;
|
||||
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
|
||||
}
|
||||
}
|
||||
|
|
5
TODO.md
5
TODO.md
|
@ -7,7 +7,7 @@
|
|||
- Non-negotiables:
|
||||
- Text (idea: index-based evaluation in plugboard)
|
||||
- Shapes (idea: embed glisp :mmtroll:, need to inquire -- still a lot of friction for simple shapes if we don't also get the glisp tools)
|
||||
- External data driving (json?)
|
||||
- External data driving (json or something else?)
|
||||
- Layer Groups (jokes -- can be completely UI side)
|
||||
|
||||
## UI
|
||||
|
@ -20,6 +20,9 @@
|
|||
- std::unordered_map -> std::flat_map pending compiler support
|
||||
- Simple 3D engine
|
||||
|
||||
## UI
|
||||
- Adapt nodes for shader graph -- code editor will be fine for now
|
||||
|
||||
## Audio
|
||||
- Wait for SDL3!
|
||||
- SDL_mixer will be able to do all of wav ogg flac mp3 opus, we live in good times
|
||||
|
|
Loading…
Add table
Reference in a new issue