This commit is contained in:
lachrymaLF 2024-05-29 18:34:18 -04:00
parent 8232b4d3f3
commit f5ae66e82d
7 changed files with 191 additions and 140 deletions

View file

@ -14,8 +14,8 @@
namespace {
SDL_Window *window;
u16 window_width = 2200;
u16 window_height = 1200;
u16 window_width = 1920;
u16 window_height = 1080;
u64 init_time, last_time, current_time, delta_t;
u32 frame;

View file

@ -23,4 +23,126 @@ namespace K::PlugboardGraph {
static T_Map<T_Count>::type table[] = {f32{}, i32{}, RGBA{}, XY{}, XYZ{}, String{}};
return table[i];
}
T_Map<T_Count>::type Eval(const CompState& s, const ConnectInfo& info) {
Vector<T_Map<T_Count>::type> pack;
for (u32 i = 0; i < info.p->inputs_fed.size(); i++) {
bool good;
auto val = ConvertValue(std::visit([&s](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ConnectInfo>)
return Eval(s,arg);
else if constexpr (std::is_same_v<T, T_Map<Type::T_Count>::type>)
return arg;
}, info.p->inputs_fed[i]), info.p->node->in[i].type, good);
if (good) {
pack.push_back(val);
}
else return {}; // todo panic!
}
return info.p->node->fetch[info.index](s, pack);
}
NodeInstance MakeInstance(Node& n) {
Vector<std::variant<T_Map<Type::T_Count>::type, ConnectInfo>> inp;
Vector<Vector<ConnectInfo>> out;
for (const auto& t : n.in)
inp.emplace_back(expand_type(t.type));
for (auto t : n.out)
out.emplace_back();
return {
.node = &n,
.inputs_fed = std::move(inp),
.outputs_going = std::move(out)
};
}
T_Map<T_Count>::type ConvertValue(const T_Map<T_Count>::type& v, Type target, bool& good) {
good = true;
return std::visit([&good, target](auto&& arg) -> T_Map<T_Count>::type {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, T_Map<T_Float>::type>) {
switch (target) {
case T_Float:
return arg;
case T_Int:
return static_cast<T_Map<T_Float>::type>(arg);
case T_RGBA:
return RGBA{ arg, arg, arg, arg };
case T_XY:
return XY{ arg, arg };
case T_XYZ:
return XYZ{ arg, arg, arg };
case T_String:
return VarToString(arg);
case T_Count:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, T_Map<T_Int>::type>) {
auto f = static_cast<T_Map<T_Float>::type>(arg);
switch (target) {
case T_Float:
return f;
case T_Int:
return arg;
case T_RGBA:
return RGBA{ f, f, f, f };
case T_XY:
return XY{ f, f };
case T_XYZ:
return XYZ{ f, f, f };
case T_String:
return VarToString(arg);
case T_Count:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, T_Map<T_RGBA>::type>) {
switch (target) {
case T_RGBA:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, T_Map<T_XY>::type>) {
switch (target) {
case T_XY:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, T_Map<T_XYZ>::type>) {
switch (target) {
case T_XYZ:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, T_Map<T_String>::type>) {
switch (target) {
case T_String:
return arg;
default:
good = false;
return {};
}
}
return {};
}, v);
}
}

View file

@ -36,4 +36,9 @@ namespace K::ShaderGraph {
if (RGBA_node->node->out_types[RGBA_node_out_index] != Type::T_RGBA) return {};
return BuildNode(*RGBA_node);
}
T_Map<T_Count>::type expand_type(Type i) {
static constexpr T_Map<T_Count>::type table[] = {f32{}, i32{}, RGBA{}, XY{}, XYZ{}};
return table[i];
}
}

View file

@ -20,8 +20,7 @@ namespace {
draw_comp = true,
draw_interpolation = true,
draw_properties = true,
draw_assets = true,
draw_color = true;
draw_assets = true;
const f32 row_height = 20.0f;
@ -796,7 +795,7 @@ namespace K::UI {
}
ImGui::SetCursorScreenPos(nodes_begin);
if (ImGui::BeginChild("Overlay", {}, false, ImGuiWindowFlags_NoInputs)) {
if (ImGui::BeginChild("Overlay", {table_left - ImGui::GetWindowPos().x, 0.0f}, false, ImGuiWindowFlags_NoInputs)) {
for (auto &[_, link]: s.plugboard.links_pos)
for (auto &sink: link.sinks)
ImGui::GetCurrentWindow()->DrawList->AddBezierCubic(link.source,
@ -827,8 +826,9 @@ namespace K::UI {
void Shader(CompState& s) {
if (ImGui::Begin("Shader", &draw_shader)) {
if (s.active == -1)
ImGui::Text("No active layer.");
ImGui::TextUnformatted("No active layer.");
else {
ImGui::Text("Editing Layer %u: %s", s.active, s.layers[s.active].name.c_str());
static i32 type_current = 0;
static String name{};
if (ImGui::Button("Add Uniform") && !name.empty() && !isdigit(name[0]) && !(name[0] == 'f' && name.length() == 1)) {
@ -892,7 +892,6 @@ namespace K::UI {
}
ImGui::EndTable();
}
ImGui::Text("Editing Layer %u: %s", s.active, s.layers[s.active].name.c_str());
ImGui::InputTextMultiline("##source", &s.layers[s.active].track.shader, ImVec2(-FLT_MIN, ImGui::GetContentRegionAvail().y - 25.0f), ImGuiInputTextFlags_AllowTabInput);
if (ImGui::Button("Submit Shader"))
s.layers[s.active].track.compile();
@ -902,8 +901,60 @@ namespace K::UI {
}
void Interpolation(CompState& s) {
if (ImGui::Begin("Interpolation", &draw_interpolation)) {
if (ImGui::Begin("Interpolation", &draw_interpolation, ImGuiWindowFlags_NoScrollbar)) {
ImGuiIO& io = ImGui::GetIO();
static const ImVec2 p1 { 0.0f, 0.0f}, p4 {1.0f, 1.0f};
static ImVec2 p2 { 1.0f, 0.0f }, p3 { 0.0f, 1.0f }, p2_old = p2, p3_old = p3;
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, {10.0f, 10.0f});
f32 y_max = std::max(std::max(p2.y, p3.y), p4.y),
y_min = std::min(std::min(p1.y, p2.y), p3.y),
y_range = y_max - y_min;
f32 w_window = ImGui::GetContentRegionAvail().x;
if (ImGui::BeginChild("Canvas", {w_window, w_window}, ImGuiChildFlags_Border, ImGuiWindowFlags_NoScrollbar)) {
f32 w = ImGui::GetContentRegionAvail().x;
ImVec2 pos = ImGui::GetCursorScreenPos();
auto *dl = ImGui::GetWindowDrawList();
ImVec2 tp1 = pos + ImVec2{p1.x * w, ((1.0f - p1.y) - (1.0f - y_max)) * w / y_range},
tp4 = pos + ImVec2{p4.x * w, ((1.0f - p4.y) - (1.0f - y_max)) * w / y_range},
tp2 = pos + ImVec2{p2.x * w, ((1.0f - p2.y) - (1.0f - y_max)) * w / y_range},
tp3 = pos + ImVec2{p3.x * w, ((1.0f - p3.y) - (1.0f - y_max)) * w / y_range};
dl->AddBezierCubic(tp1, tp2, tp3, tp4, 0xFFFFFFFF, 2.0f);
dl->AddLine(tp1, tp2, 0xAAFFFFFF, 1.5f);
dl->AddLine(tp3, tp4, 0xAAFFFFFF, 1.5f);
dl->AddLine(tp1, {tp1.x + w, tp1.y}, 0x44FFFFFF, 2.0f);
dl->AddLine(tp4, {tp4.x - w, tp4.y}, 0x44FFFFFF, 2.0f);
dl->AddText(tp1 + ImVec2{10.0f, -20.0f}, 0xFFFFFFFF, "0.0");
dl->AddText(tp4 + ImVec2{-30.0f, 15.0f}, 0xFFFFFFFF, "1.0");
ImVec2 size = {15.0f, 15.0f};
ImGui::SetCursorScreenPos(tp2 - size / 2.0f);
ImVec2 off = io.MousePos - io.MouseClickedPos[0];
ImGui::Button("##P2", size);
if (ImGui::IsItemClicked()) {
p2_old = p2;
}
if (ImGui::IsItemActive()) {
p2 = p2_old + ImVec2{off.x / w, off.y / -w * y_range};
p2.x = std::clamp(p2.x, 0.0f, 1.0f);
}
ImGui::SetCursorScreenPos(tp3 - size / 2.0f);
ImGui::Button("##P3", size);
if (ImGui::IsItemClicked()) {
p3_old = p3;
}
if (ImGui::IsItemActive()) {
p3 = p3_old + ImVec2{off.x / w, off.y / -w * y_range};
p3.x = std::clamp(p3.x, 0.0f, 1.0f);
}
}
ImGui::PopStyleVar(1);
ImGui::EndChild();
ImGui::Button("Apply");
}
ImGui::End();
}
@ -922,13 +973,6 @@ namespace K::UI {
ImGui::End();
}
void Color(CompState& s) {
if (ImGui::Begin("Color", &draw_color)) {
}
ImGui::End();
}
void Draw(u32 frame, CompState& s) {
ImGui_ImplSDL2_NewFrame();
ImGui_Implbgfx_NewFrame();
@ -946,7 +990,6 @@ namespace K::UI {
if (draw_interpolation) Interpolation(s);
if (draw_properties) Properties(s);
if (draw_assets) Assets(s);
if (draw_color) Color(s);
if (save_called && ready_frame == frame) {
stbi_write_png("frame.png", static_cast<i32>(s.width), static_cast<i32>(s.height), 4, save_buffer, static_cast<i32>(s.width) * 4);

View file

@ -114,7 +114,7 @@ namespace K::Graphics {
"Hue",
"Saturation",
"Color",
"Colour",
"Luminosity",
"Invalid"

View file

@ -118,127 +118,11 @@ namespace K::PlugboardGraph {
};
inline NodeInstance MakeInstance(Node& n) {
Vector<std::variant<T_Map<Type::T_Count>::type, ConnectInfo>> inp;
Vector<Vector<ConnectInfo>> out;
for (const auto& t : n.in)
inp.emplace_back(expand_type(t.type));
for (auto t : n.out)
out.emplace_back();
return {
.node = &n,
.inputs_fed = std::move(inp),
.outputs_going = std::move(out)
};
}
NodeInstance MakeInstance(Node& n);
inline T_Map<T_Count>::type ConvertValue(const T_Map<T_Count>::type& v, Type target, bool& good) {
good = true;
return std::visit([&good, target](auto&& arg) -> T_Map<T_Count>::type {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_Float>::type>) {
switch (target) {
case T_Float:
return arg;
case T_Int:
return static_cast<T_Map<T_Float>::type>(arg);
case T_RGBA:
return RGBA{ arg, arg, arg, arg };
case T_XY:
return XY{ arg, arg };
case T_XYZ:
return XYZ{ arg, arg, arg };
case T_String:
return VarToString(arg);
case T_Count:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_Int>::type>) {
auto f = static_cast<T_Map<T_Float>::type>(arg);
switch (target) {
case T_Float:
return f;
case T_Int:
return arg;
case T_RGBA:
return RGBA{ f, f, f, f };
case T_XY:
return XY{ f, f };
case T_XYZ:
return XYZ{ f, f, f };
case T_String:
return VarToString(arg);
case T_Count:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_RGBA>::type>) {
switch (target) {
case T_RGBA:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_XY>::type>) {
switch (target) {
case T_XY:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_XYZ>::type>) {
switch (target) {
case T_XYZ:
return arg;
case T_String:
return VarToString(arg);
default:
good = false;
return {};
}
}
else if constexpr (std::is_same_v<T, PlugboardGraph::T_Map<PlugboardGraph::T_String>::type>) {
switch (target) {
case T_String:
return arg;
default:
good = false;
return {};
}
}
return {};
}, v);
}
T_Map<T_Count>::type ConvertValue(const T_Map<T_Count>::type& v, Type target, bool& good);
inline T_Map<T_Count>::type Eval(const CompState& s, const ConnectInfo& info) {
Vector<T_Map<T_Count>::type> pack;
for (u32 i = 0; i < info.p->inputs_fed.size(); i++) {
bool good;
auto val = ConvertValue(std::visit([&s](auto&& arg) {
using T = std::decay_t<decltype(arg)>;
if constexpr (std::is_same_v<T, ConnectInfo>)
return Eval(s,arg);
else if constexpr (std::is_same_v<T, T_Map<Type::T_Count>::type>)
return arg;
}, info.p->inputs_fed[i]), info.p->node->in[i].type, good);
if (good) {
pack.push_back(val);
}
else return {}; // todo panic!
}
return info.p->node->fetch[info.index](s, pack);
}
T_Map<T_Count>::type Eval(const CompState& s, const ConnectInfo& info);
struct LinksFromSource {
ImVec2 source;

View file

@ -46,10 +46,7 @@ namespace K::ShaderGraph {
};
String VarToString(const T_Map<T_Count>::type& var);
inline T_Map<T_Count>::type expand_type(Type i) {
static constexpr T_Map<T_Count>::type table[] = {f32{}, i32{}, ShaderGraph::RGBA{}, ShaderGraph::XY{}, ShaderGraph::XYZ{}};
return table[i];
}
T_Map<T_Count>::type expand_type(Type i);
struct Node;
struct InSlot {