asdamsdk
This commit is contained in:
parent
ccadf34f4c
commit
cf0af93cac
14 changed files with 437 additions and 232 deletions
|
@ -19,9 +19,9 @@ set_property(TARGET Keishiki PROPERTY CXX_STANDARD 23)
|
||||||
include_directories ("include" "include/ext" "ext/imgui" "ext/implot" "ext/plf_colony")
|
include_directories ("include" "include/ext" "ext/imgui" "ext/implot" "ext/plf_colony")
|
||||||
|
|
||||||
add_subdirectory("ext/fmt")
|
add_subdirectory("ext/fmt")
|
||||||
|
add_subdirectory("ext/glaze")
|
||||||
add_subdirectory("ext/freetype")
|
add_subdirectory("ext/freetype")
|
||||||
|
#add_compile_definitions(WL_EGL_PLATFORM)
|
||||||
add_compile_definitions(WL_EGL_PLATFORM)
|
|
||||||
add_subdirectory("ext/bgfx")
|
add_subdirectory("ext/bgfx")
|
||||||
|
|
||||||
add_compile_definitions(IMGUI_DEFINE_MATH_OPERATORS)
|
add_compile_definitions(IMGUI_DEFINE_MATH_OPERATORS)
|
||||||
|
@ -47,5 +47,5 @@ else ()
|
||||||
find_package(ECM REQUIRED NO_MODULE)
|
find_package(ECM REQUIRED NO_MODULE)
|
||||||
set(CMAKE_MODULE_PATH ${ECM_FIND_MODULE_DIR})
|
set(CMAKE_MODULE_PATH ${ECM_FIND_MODULE_DIR})
|
||||||
find_package(Wayland REQUIRED Egl)
|
find_package(Wayland REQUIRED Egl)
|
||||||
target_link_libraries (Keishiki PRIVATE freetype bgfx bx SDL3::SDL3 ${Wayland_LIBRARIES} fmt)
|
target_link_libraries (Keishiki PRIVATE freetype bgfx bx SDL3::SDL3 ${Wayland_LIBRARIES} fmt glaze_glaze)
|
||||||
endif ()
|
endif ()
|
||||||
|
|
|
@ -19,12 +19,16 @@ namespace K {
|
||||||
K::AppState app_state;
|
K::AppState app_state;
|
||||||
|
|
||||||
bool Init() {
|
bool Init() {
|
||||||
|
#if !WL_EGL_PLATFORM
|
||||||
|
SDL_SetHint(SDL_HINT_VIDEO_DRIVER, "x11");
|
||||||
|
#endif
|
||||||
if (SDL_Init(SDL_INIT_VIDEO)) {
|
if (SDL_Init(SDL_INIT_VIDEO)) {
|
||||||
Log(K_L_Error, "{}", SDL_GetError());
|
Log(K_L_Error, "{}", SDL_GetError());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
app_state.window = SDL_CreateWindow("Keishiki", app_state.window_width, app_state.window_height, SDL_WINDOW_RESIZABLE);
|
app_state.window = SDL_CreateWindow("Keishiki", app_state.window_width, app_state.window_height, SDL_WINDOW_HIGH_PIXEL_DENSITY);
|
||||||
|
SDL_SetWindowResizable(app_state.window, true);
|
||||||
|
|
||||||
if (app_state.window == nullptr) {
|
if (app_state.window == nullptr) {
|
||||||
Log(K_L_Error, "{}", SDL_GetError());
|
Log(K_L_Error, "{}", SDL_GetError());
|
||||||
|
@ -69,16 +73,16 @@ namespace K {
|
||||||
|
|
||||||
if (!K::Resource::Init())
|
if (!K::Resource::Init())
|
||||||
return false;
|
return false;
|
||||||
K::UI::Init(app_state.window);
|
UI::Init(app_state.window);
|
||||||
|
|
||||||
if (!K::Graphics::Init()) {
|
if (!K::Graphics::Init()) {
|
||||||
Log(K_L_Error, "Graphics init failed");
|
Log(K_L_Error, "Graphics init failed");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
app_state.compositions.emplace_back("default project", 0, 100, 30.0f, 1280, 550);
|
app_state.project.compositions.emplace_back("default project", 0, 100, 30.0f, 1280, 550);
|
||||||
app_state.inspecting_composition = 0;
|
app_state.project.inspecting_composition = 0;
|
||||||
K::UI::SetupViewport(app_state.compositions[0]);
|
UI::SetupViewport(app_state.project.compositions[app_state.project.inspecting_composition]);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -98,8 +102,9 @@ namespace K {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (current_event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) {
|
if (current_event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) {
|
||||||
SDL_GetWindowSize(app_state.window, &app_state.window_width, &app_state.window_height);
|
app_state.window_width = current_event.window.data1;
|
||||||
bgfx::reset(app_state.window_width, app_state.window_height);
|
app_state.window_height = current_event.window.data2;
|
||||||
|
bgfx::reset(current_event.window.data1, current_event.window.data2, BGFX_RESET_VSYNC);
|
||||||
UI::SetLogoView();
|
UI::SetLogoView();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace K::Plugboard {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Type type>
|
template <Type type>
|
||||||
typename T_Map<type>::type GetNodeInputArg(const CompState& s, const InSocket& socket) {
|
typename T_Map<type>::type GetNodeInputArg(const CompositionState& s, const InSocket& socket) {
|
||||||
bool good;
|
bool good;
|
||||||
typename T_Map<type>::type v = std::get<typename T_Map<type>::type>(ConvertValue(std::visit([&s](auto&& arg) {
|
typename T_Map<type>::type v = std::get<typename T_Map<type>::type>(ConvertValue(std::visit([&s](auto&& arg) {
|
||||||
using U = std::decay_t<decltype(arg)>;
|
using U = std::decay_t<decltype(arg)>;
|
||||||
|
@ -113,83 +113,83 @@ namespace K::Plugboard {
|
||||||
"Invalid"
|
"Invalid"
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAdd(const CompState& s, const Add& n) {
|
T_Map<T_Count>::type FetchAdd(const CompositionState& s, const Add& n) {
|
||||||
return GetNodeInputArg<T_Float>(s, n.in[0]) + GetNodeInputArg<T_Float>(s, n.in[1]);
|
return GetNodeInputArg<T_Float>(s, n.in[0]) + GetNodeInputArg<T_Float>(s, n.in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchNegate(const CompState& s, const Negate& n) {
|
T_Map<T_Count>::type FetchNegate(const CompositionState& s, const Negate& n) {
|
||||||
return -GetNodeInputArg<T_Float>(s, n.in[0]);
|
return -GetNodeInputArg<T_Float>(s, n.in[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSubtract(const CompState& s, const Subtract& n) {
|
T_Map<T_Count>::type FetchSubtract(const CompositionState& s, const Subtract& n) {
|
||||||
return GetNodeInputArg<T_Float>(s, n.in[0]) - GetNodeInputArg<T_Float>(s, n.in[1]);
|
return GetNodeInputArg<T_Float>(s, n.in[0]) - GetNodeInputArg<T_Float>(s, n.in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMultiply(const CompState& s, const Multiply& n) {
|
T_Map<T_Count>::type FetchMultiply(const CompositionState& s, const Multiply& n) {
|
||||||
return GetNodeInputArg<T_Float>(s, n.in[0]) * GetNodeInputArg<T_Float>(s, n.in[1]);
|
return GetNodeInputArg<T_Float>(s, n.in[0]) * GetNodeInputArg<T_Float>(s, n.in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchDivide(const CompState& s, const Divide& n) {
|
T_Map<T_Count>::type FetchDivide(const CompositionState& s, const Divide& n) {
|
||||||
return GetNodeInputArg<T_Float>(s, n.in[0]) / GetNodeInputArg<T_Float>(s, n.in[1]);
|
return GetNodeInputArg<T_Float>(s, n.in[0]) / GetNodeInputArg<T_Float>(s, n.in[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSign(const CompState& s, const Sign& n) {
|
T_Map<T_Count>::type FetchSign(const CompositionState& s, const Sign& n) {
|
||||||
return std::signbit(GetNodeInputArg<T_Float>(s, n.in[0])) ? -1.0f : 1.0f;
|
return std::signbit(GetNodeInputArg<T_Float>(s, n.in[0])) ? -1.0f : 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSin(const CompState& s, const Sin& n) {
|
T_Map<T_Count>::type FetchSin(const CompositionState& s, const Sin& n) {
|
||||||
return std::sin(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::sin(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchCos(const CompState& s, const Cos& n) {
|
T_Map<T_Count>::type FetchCos(const CompositionState& s, const Cos& n) {
|
||||||
return std::cos(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::cos(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchTan(const CompState& s, const Tan& n) {
|
T_Map<T_Count>::type FetchTan(const CompositionState& s, const Tan& n) {
|
||||||
return std::tan(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::tan(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArcsin(const CompState& s, const Arcsin& n) {
|
T_Map<T_Count>::type FetchArcsin(const CompositionState& s, const Arcsin& n) {
|
||||||
return std::asin(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::asin(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArccos(const CompState& s, const Arccos& n) {
|
T_Map<T_Count>::type FetchArccos(const CompositionState& s, const Arccos& n) {
|
||||||
return std::acos(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::acos(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArctan(const CompState& s, const Arctan& n) {
|
T_Map<T_Count>::type FetchArctan(const CompositionState& s, const Arctan& n) {
|
||||||
return std::atan(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::atan(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAtan2(const CompState& s, const Atan2& n) {
|
T_Map<T_Count>::type FetchAtan2(const CompositionState& s, const Atan2& n) {
|
||||||
return std::atan2(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
return std::atan2(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMinimum(const CompState& s, const Minimum& n) {
|
T_Map<T_Count>::type FetchMinimum(const CompositionState& s, const Minimum& n) {
|
||||||
return std::min(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
return std::min(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMaximum(const CompState& s, const Maximum& n) {
|
T_Map<T_Count>::type FetchMaximum(const CompositionState& s, const Maximum& n) {
|
||||||
return std::max(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
return std::max(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchPower(const CompState& s, const Power& n) {
|
T_Map<T_Count>::type FetchPower(const CompositionState& s, const Power& n) {
|
||||||
return std::pow(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
return std::pow(GetNodeInputArg<T_Float>(s, n.in[0]), GetNodeInputArg<T_Float>(s, n.in[1]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSquareRoot(const CompState& s, const SquareRoot& n) {
|
T_Map<T_Count>::type FetchSquareRoot(const CompositionState& s, const SquareRoot& n) {
|
||||||
return std::sqrt(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::sqrt(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchNaturalLogarithm(const CompState& s, const NaturalLogarithm& n) {
|
T_Map<T_Count>::type FetchNaturalLogarithm(const CompositionState& s, const NaturalLogarithm& n) {
|
||||||
return std::log(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::log(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAbsoluteValue(const CompState& s, const AbsoluteValue& n) {
|
T_Map<T_Count>::type FetchAbsoluteValue(const CompositionState& s, const AbsoluteValue& n) {
|
||||||
return std::abs(GetNodeInputArg<T_Float>(s, n.in[0]));
|
return std::abs(GetNodeInputArg<T_Float>(s, n.in[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchInterpolation(const CompState& s, const Interpolation& n) {
|
T_Map<T_Count>::type FetchInterpolation(const CompositionState& s, const Interpolation& n) {
|
||||||
return EvalInterpolation(GetNodeInputArg<T_Float>(s, n.in[0]), n.extra);
|
return EvalInterpolation(GetNodeInputArg<T_Float>(s, n.in[0]), n.extra);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +208,7 @@ namespace K::Plugboard {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchChain(const CompState& s, const Chain& n) {
|
T_Map<T_Count>::type FetchChain(const CompositionState& s, const Chain& n) {
|
||||||
i32 frame = static_cast<i32>(GetNodeInputArg<T_Int>(s, n.in[0]));
|
i32 frame = static_cast<i32>(GetNodeInputArg<T_Int>(s, n.in[0]));
|
||||||
|
|
||||||
auto& v = n.extra.chain.segments;
|
auto& v = n.extra.chain.segments;
|
||||||
|
@ -250,7 +250,7 @@ namespace K::Plugboard {
|
||||||
}, var);
|
}, var);
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type Eval(const CompState& s, const ConnectInfo& info) {
|
T_Map<T_Count>::type Eval(const CompositionState& s, const ConnectInfo& info) {
|
||||||
return std::visit([&info, &s](auto&& arg) { return arg->fetch[info.index](s, *arg); }, info.p);
|
return std::visit([&info, &s](auto&& arg) { return arg->fetch[info.index](s, *arg); }, info.p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,25 +343,32 @@ namespace K::Plugboard {
|
||||||
}, v);
|
}, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
T_Map<T_Count>::type FetchCompositionInFrame(const CompositionState& s, const GroupIn& n) {
|
||||||
T_Map<T_Count>::type FetchCompositionInFrame(const CompState& s, const CompositionIn& n) {
|
|
||||||
return T_Map<T_Count>::type{static_cast<i32>(s.current_frame)};
|
return T_Map<T_Count>::type{static_cast<i32>(s.current_frame)};
|
||||||
}
|
}
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchCompositionInTime(const CompState& s, const CompositionIn& n) {
|
T_Map<T_Count>::type FetchCompositionInAppTicks(const CompositionState& s, const GroupIn& n) {
|
||||||
return T_Map<T_Count>::type{static_cast<f32>(s.current_frame) / s.fps};
|
|
||||||
}
|
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchCompositionInAppTicks(const CompState& s, const CompositionIn& n) {
|
|
||||||
return T_Map<T_Count>::type{ static_cast<f32>(SDL_GetTicks()) };
|
return T_Map<T_Count>::type{ static_cast<f32>(SDL_GetTicks()) };
|
||||||
}
|
}
|
||||||
|
Plugboard::Plugboard() {
|
||||||
|
AddOutSocket("Frame", T_Int, FetchCompositionInFrame);
|
||||||
|
AddOutSocket("App Ticks", T_Float, FetchCompositionInAppTicks);
|
||||||
|
AddInSocket("Frame", T_Int);
|
||||||
|
AddInSocket("Ticks", T_Int);
|
||||||
|
}
|
||||||
|
void Plugboard::AddInSocket(const String& s, Type t) {
|
||||||
|
in.emplace_back(s, t);
|
||||||
|
}
|
||||||
|
void Plugboard::AddOutSocket(const String& s, Type t, T_Map<T_Count>::type(*fetch)(const CompositionState&, const GroupIn&)) {
|
||||||
|
in_instance.out.emplace_back(s, t);
|
||||||
|
in_instance.fetch.push_back(fetch);
|
||||||
|
}
|
||||||
void Plugboard::RecollectChains() {
|
void Plugboard::RecollectChains() {
|
||||||
for (u32 i = 0; i < out.in.size(); i++) {
|
for (u32 i = 0; i < out_instance.in.size(); i++) {
|
||||||
std::visit([i, this](auto&& arg) {
|
std::visit([i, this](auto&& arg) {
|
||||||
if constexpr (std::is_same_v<std::decay_t<decltype(arg)>, ConnectInfo>)
|
if constexpr (std::is_same_v<std::decay_t<decltype(arg)>, ConnectInfo>)
|
||||||
CollectChains(arg, out.show_nodes[i]);
|
CollectChains(arg, show_nodes[i]);
|
||||||
}, out.in[i].value);
|
}, out_instance.in[i].value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,28 @@
|
||||||
#include <Resource.h>
|
#include <Resource.h>
|
||||||
#include <Keishiki.h>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <Keishiki.h>
|
||||||
|
#include <glaze/glaze.hpp>
|
||||||
|
|
||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct glz::meta<ImVec2> {
|
||||||
|
using T = ImVec2;
|
||||||
|
static constexpr auto value = array(&T::x, &T::y);
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace K::Resource {
|
||||||
|
void SaveCurrentProject() {
|
||||||
|
auto ec = glz::write_file_json("soon!", "./temp.json", String{});
|
||||||
|
if (ec.ec != glz::error_code::none) {
|
||||||
|
Log(K_L_Error, "{}", ec.includer_error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bgfx::ShaderHandle LoadShader(const std::filesystem::path& file_path) {
|
bgfx::ShaderHandle LoadShader(const std::filesystem::path& file_path) {
|
||||||
FILE *file = fopen(file_path.c_str(), "rb");
|
FILE *file = fopen(file_path.c_str(), "rb");
|
||||||
|
@ -227,4 +243,77 @@ namespace K::Resource {
|
||||||
}
|
}
|
||||||
}, r.second);
|
}, r.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int DecodeURI(char *buf, int len) {
|
||||||
|
/* Decodes URI escape sequences in string buf of len bytes
|
||||||
|
(excluding the terminating NULL byte) in-place. Since
|
||||||
|
URI-encoded characters take three times the space of
|
||||||
|
normal characters, this should not be an issue.
|
||||||
|
|
||||||
|
Returns the number of decoded bytes that wound up in
|
||||||
|
the buffer, excluding the terminating NULL byte.
|
||||||
|
|
||||||
|
The buffer is guaranteed to be NULL-terminated but
|
||||||
|
may contain embedded NULL bytes.
|
||||||
|
|
||||||
|
On error, -1 is returned.
|
||||||
|
*/
|
||||||
|
int ri, wi, di;
|
||||||
|
char decode = '\0';
|
||||||
|
if (!buf || len < 0) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (len == 0) {
|
||||||
|
len = SDL_strlen(buf);
|
||||||
|
}
|
||||||
|
for (ri = 0, wi = 0, di = 0; ri < len && wi < len; ri += 1) {
|
||||||
|
if (di == 0) {
|
||||||
|
/* start decoding */
|
||||||
|
if (buf[ri] == '%') {
|
||||||
|
decode = '\0';
|
||||||
|
di += 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* normal write */
|
||||||
|
buf[wi] = buf[ri];
|
||||||
|
wi += 1;
|
||||||
|
continue;
|
||||||
|
} else if (di == 1 || di == 2) {
|
||||||
|
char off = '\0';
|
||||||
|
char isa = buf[ri] >= 'a' && buf[ri] <= 'f';
|
||||||
|
char isA = buf[ri] >= 'A' && buf[ri] <= 'F';
|
||||||
|
char isn = buf[ri] >= '0' && buf[ri] <= '9';
|
||||||
|
if (!(isa || isA || isn)) {
|
||||||
|
/* not a hexadecimal */
|
||||||
|
int sri;
|
||||||
|
for (sri = ri - di; sri <= ri; sri += 1) {
|
||||||
|
buf[wi] = buf[sri];
|
||||||
|
wi += 1;
|
||||||
|
}
|
||||||
|
di = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
/* itsy bitsy magicsy */
|
||||||
|
if (isn) {
|
||||||
|
off = 0 - '0';
|
||||||
|
} else if (isa) {
|
||||||
|
off = 10 - 'a';
|
||||||
|
} else if (isA) {
|
||||||
|
off = 10 - 'A';
|
||||||
|
}
|
||||||
|
decode |= (buf[ri] + off) << (2 - di) * 4;
|
||||||
|
if (di == 2) {
|
||||||
|
buf[wi] = decode;
|
||||||
|
wi += 1;
|
||||||
|
di = 0;
|
||||||
|
} else {
|
||||||
|
di += 1;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf[wi] = '\0';
|
||||||
|
return wi;
|
||||||
|
}
|
||||||
}
|
}
|
221
Keishiki/UI.cpp
221
Keishiki/UI.cpp
|
@ -18,6 +18,8 @@
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <fmt/chrono.h>
|
#include <fmt/chrono.h>
|
||||||
|
|
||||||
|
#include <SDL3/SDL_dialog.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
const K::Resource::Resource<K::Resource::Type::K_R_Still> *logo;
|
const K::Resource::Resource<K::Resource::Type::K_R_Still> *logo;
|
||||||
|
|
||||||
|
@ -42,7 +44,7 @@ namespace {
|
||||||
|
|
||||||
K::VisualTrack bg{};
|
K::VisualTrack bg{};
|
||||||
K::Byte *save_buffer;
|
K::Byte *save_buffer;
|
||||||
K::CompState *comp_save_called = nullptr;
|
K::CompositionState *comp_save_called = nullptr;
|
||||||
u32 ready_frame;
|
u32 ready_frame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +70,7 @@ namespace K::UI {
|
||||||
bgfx::setViewTransform(K::Graphics::K_VIEW_LOGO, view, proj);
|
bgfx::setViewTransform(K::Graphics::K_VIEW_LOGO, view, proj);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddTransformLayer(CompState& s, const String& name) {
|
void AddTransformLayer(CompositionState& s, const String& name) {
|
||||||
auto l = Layer{
|
auto l = Layer{
|
||||||
VisualTrack{},
|
VisualTrack{},
|
||||||
name,
|
name,
|
||||||
|
@ -76,40 +78,38 @@ namespace K::UI {
|
||||||
0UL,
|
0UL,
|
||||||
s.frame_max
|
s.frame_max
|
||||||
};
|
};
|
||||||
l.track.AddUniform("u_aspect_ratio", ShaderGraph::ExpandVariant(ShaderGraph::T_XY));
|
l.track.AddUniform("u_resolution", ShaderGraph::ExpandVariant(ShaderGraph::T_XY), K_U_Exposed);
|
||||||
if (s.width > s.height)
|
l.track.uniforms[0].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{static_cast<f32>(s.width), static_cast<f32>(s.height)};
|
||||||
l.track.uniforms[0].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{static_cast<f32>(s.width)/static_cast<f32>(s.height), 1.0f};
|
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
|
||||||
else
|
|
||||||
l.track.uniforms[0].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{1.0f, static_cast<f32>(s.height)/static_cast<f32>(s.width)};
|
|
||||||
|
|
||||||
l.track.AddUniform("u_opacity", ShaderGraph::ExpandVariant(ShaderGraph::T_Float));
|
l.track.AddUniform("u_opacity", ShaderGraph::ExpandVariant(ShaderGraph::T_Float), K_U_Exposed);
|
||||||
l.track.uniforms[1].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
l.track.uniforms[1].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
||||||
|
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
|
||||||
|
|
||||||
l.track.AddUniform("u_rot", ShaderGraph::ExpandVariant(ShaderGraph::T_Float));
|
l.track.AddUniform("u_rot", ShaderGraph::ExpandVariant(ShaderGraph::T_Float), K_U_Exposed);
|
||||||
l.track.uniforms[2].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
l.track.uniforms[2].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
||||||
|
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
|
||||||
|
|
||||||
l.track.AddUniform("u_scale", ShaderGraph::ExpandVariant(ShaderGraph::T_XY));
|
l.track.AddUniform("u_scale", ShaderGraph::ExpandVariant(ShaderGraph::T_XY), K_U_Exposed);
|
||||||
l.track.uniforms[3].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{1.0f, 1.0f};
|
l.track.uniforms[3].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{1.0f, 1.0f};
|
||||||
|
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
|
||||||
|
|
||||||
l.track.AddUniform("u_translate", ShaderGraph::ExpandVariant(ShaderGraph::T_XY));
|
l.track.AddUniform("u_translate", ShaderGraph::ExpandVariant(ShaderGraph::T_XY), K_U_Exposed);
|
||||||
l.track.uniforms[4].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{.0f, .0f};
|
l.track.uniforms[4].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{.0f, .0f};
|
||||||
|
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
|
||||||
|
|
||||||
l.track.shader = "void main() {\n"
|
l.track.shader = "void main() {\n"
|
||||||
"\tfloat angle = -u_rot * M_PI / 180.0f;\n"
|
"\tfloat angle = -u_rot * M_PI / 180.0f;\n"
|
||||||
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
|
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
|
||||||
"\tuv = uv * u_aspect_ratio;\n"
|
"\tuv = uv * u_resolution;\n"
|
||||||
"\tuv = uv - u_translate;\n"
|
"\tuv = uv - u_translate;\n"
|
||||||
"\tuv = vec2(cos(angle)*uv.x - sin(angle)*uv.y, sin(angle)*uv.x + cos(angle)*uv.y);\n"
|
"\tuv = vec2(cos(angle)*uv.x - sin(angle)*uv.y, sin(angle)*uv.x + cos(angle)*uv.y);\n"
|
||||||
|
"\tuv = uv / s_texColor_dims;\n"
|
||||||
"\tuv = uv / u_scale;\n"
|
"\tuv = uv / u_scale;\n"
|
||||||
"\tuv = uv + .5f;\n\n"
|
"\tuv = uv + .5f;\n\n"
|
||||||
"\tvec4 tx = texture2D(s_texColor, uv);\n"
|
"\tvec4 tx = texture2D(s_texColor, uv);\n"
|
||||||
"\tgl_FragColor = vec4(tx.rgb, tx.a * u_opacity);\n"
|
"\tgl_FragColor = vec4(tx.rgb, tx.a * u_opacity);\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
l.track.ExposeUniform(s, 0);
|
|
||||||
l.track.ExposeUniform(s, 1);
|
|
||||||
l.track.ExposeUniform(s, 2);
|
|
||||||
l.track.ExposeUniform(s, 3);
|
|
||||||
l.track.ExposeUniform(s, 4);
|
|
||||||
|
|
||||||
l.track.AddSampler("s_texColor");
|
l.track.AddSampler("s_texColor");
|
||||||
|
|
||||||
|
@ -119,6 +119,13 @@ namespace K::UI {
|
||||||
|
|
||||||
void MainMenuBar() {
|
void MainMenuBar() {
|
||||||
if (ImGui::BeginMainMenuBar()) {
|
if (ImGui::BeginMainMenuBar()) {
|
||||||
|
if (ImGui::BeginMenu("File")) {
|
||||||
|
if (ImGui::MenuItem("Save Project", "CTRL+S")) {
|
||||||
|
Resource::SaveCurrentProject();
|
||||||
|
}
|
||||||
|
ImGui::EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
if (ImGui::BeginMenu("Edit")) {
|
if (ImGui::BeginMenu("Edit")) {
|
||||||
// if (ImGui::MenuItem("Undo", "CTRL+Z")) {}
|
// if (ImGui::MenuItem("Undo", "CTRL+Z")) {}
|
||||||
// if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item
|
// if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item
|
||||||
|
@ -130,16 +137,18 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::BeginMenu("View")) {
|
if (ImGui::BeginMenu("View")) {
|
||||||
|
if (ImGui::MenuItem("Assets", "", &draw_assets)) {}
|
||||||
if (ImGui::MenuItem("Viewport", "", &draw_viewport)) {}
|
if (ImGui::MenuItem("Viewport", "", &draw_viewport)) {}
|
||||||
if (ImGui::MenuItem("Composition", "", &draw_comp)) {}
|
if (ImGui::MenuItem("Composition", "", &draw_comp)) {}
|
||||||
if (ImGui::MenuItem("Shader", "", &draw_layer)) {}
|
if (ImGui::MenuItem("Layer", "", &draw_layer)) {}
|
||||||
|
if (ImGui::MenuItem("Interpolation", "", &draw_interpolation)) {}
|
||||||
ImGui::EndMenu();
|
ImGui::EndMenu();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ImGui::EndMainMenuBar();
|
ImGui::EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupViewport(CompState& s) {
|
void SetupViewport(CompositionState& s) {
|
||||||
composite[0] = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
composite[0] = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
||||||
composite[1] = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
composite[1] = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
||||||
render = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
render = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
||||||
|
@ -165,7 +174,7 @@ namespace K::UI {
|
||||||
bx::mtxTranslate(view, 0.f, 0.f, 1.0f);
|
bx::mtxTranslate(view, 0.f, 0.f, 1.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyViewport(CompState& s) {
|
void DestroyViewport(CompositionState& s) {
|
||||||
bgfx::destroy(composite_fb[0]);
|
bgfx::destroy(composite_fb[0]);
|
||||||
bgfx::destroy(composite_fb[1]);
|
bgfx::destroy(composite_fb[1]);
|
||||||
bgfx::destroy(composite[0]);
|
bgfx::destroy(composite[0]);
|
||||||
|
@ -197,8 +206,8 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Plugboard::Node N>
|
template <Plugboard::Node N>
|
||||||
void PlugboardNodeDrawSockets(CompState& s, N& n, ImGuiStyle& style,
|
void PlugboardNodeDrawSockets(CompositionState& s, N& n, ImGuiStyle& style,
|
||||||
bool& dragging_on_socket, ImVec2& source, bool dummy = true) {
|
bool& dragging_on_socket, ImVec2& source, Dict<Plugboard::ConnectInfo, Plugboard::LinksFromSource, Plugboard::ConnectInfoHasher>& links_pos, bool dummy = true) {
|
||||||
i32 row = 1;
|
i32 row = 1;
|
||||||
for (u32 out = 0; out < n.out.size(); out++, row++) {
|
for (u32 out = 0; out < n.out.size(); out++, row++) {
|
||||||
ImGui::PushID(row);
|
ImGui::PushID(row);
|
||||||
|
@ -233,7 +242,7 @@ namespace K::UI {
|
||||||
|
|
||||||
// Update link info if needed
|
// Update link info if needed
|
||||||
if (!n.out[out].outgoing.empty()) {\
|
if (!n.out[out].outgoing.empty()) {\
|
||||||
s.plugboard.links_pos[{&n, out}].source = ImGui::GetCursorScreenPos() + ImVec2{ImGui::GetFrameHeight() / 2,
|
links_pos[{&n, out}].source = ImGui::GetCursorScreenPos() + ImVec2{ImGui::GetFrameHeight() / 2,
|
||||||
-ImGui::GetFrameHeight() / 2 -
|
-ImGui::GetFrameHeight() / 2 -
|
||||||
style.ItemInnerSpacing.y};
|
style.ItemInnerSpacing.y};
|
||||||
}
|
}
|
||||||
|
@ -264,13 +273,13 @@ namespace K::UI {
|
||||||
ImGui::TextUnformatted(n.in[in].name.c_str());
|
ImGui::TextUnformatted(n.in[in].name.c_str());
|
||||||
|
|
||||||
// Update link info
|
// Update link info
|
||||||
std::visit([&socket_link_pos, &dragging_on_socket, &source, &s](auto&& arg) {
|
std::visit([&links_pos, &socket_link_pos, &dragging_on_socket, &source, &s](auto&& arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
||||||
if (ImGui::IsItemActive())
|
if (ImGui::IsItemActive())
|
||||||
s.plugboard.links_pos[arg].sinks.push_back(ImGui::GetMousePos());
|
links_pos[arg].sinks.push_back(ImGui::GetMousePos());
|
||||||
else
|
else
|
||||||
s.plugboard.links_pos[arg].sinks.push_back(socket_link_pos);
|
links_pos[arg].sinks.push_back(socket_link_pos);
|
||||||
}
|
}
|
||||||
else if (ImGui::IsItemActive()) {
|
else if (ImGui::IsItemActive()) {
|
||||||
dragging_on_socket = true;
|
dragging_on_socket = true;
|
||||||
|
@ -288,8 +297,8 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Plugboard::Node N>
|
template <Plugboard::Node N>
|
||||||
void PlugboardDrawNode(CompState& s, N& n, ImVec2& view_pos, ImGuiIO& io, ImGuiStyle& style,
|
void PlugboardDrawNode(CompositionState& s, N& n, ImVec2& view_pos, ImGuiIO& io, ImGuiStyle& style,
|
||||||
bool& dragging_on_socket, ImVec2& source, bool& delete_request) {
|
bool& dragging_on_socket, ImVec2& source, bool& delete_request, Dict<Plugboard::ConnectInfo, Plugboard::LinksFromSource, Plugboard::ConnectInfoHasher>& links_pos) {
|
||||||
Plugboard::NodeInstanceP ptr{&n};
|
Plugboard::NodeInstanceP ptr{&n};
|
||||||
bool selected = std::ranges::find(s.plugboard.selected_nodes, ptr) != s.plugboard.selected_nodes.end();
|
bool selected = std::ranges::find(s.plugboard.selected_nodes, ptr) != s.plugboard.selected_nodes.end();
|
||||||
const auto& pos = n.pos;
|
const auto& pos = n.pos;
|
||||||
|
@ -335,7 +344,7 @@ namespace K::UI {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlugboardNodeDrawSockets<N>(s, n, style, dragging_on_socket, source);
|
PlugboardNodeDrawSockets<N>(s, n, style, dragging_on_socket, source, links_pos);
|
||||||
|
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
@ -351,7 +360,7 @@ namespace K::UI {
|
||||||
last_frame_tick = app_state.current_time;
|
last_frame_tick = app_state.current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Viewport(CompState& s) {
|
void Viewport(CompositionState& s) {
|
||||||
if (playing) {
|
if (playing) {
|
||||||
if (static_cast<f32>(app_state.current_time - last_frame_tick) >= 1000.0f / s.fps) {
|
if (static_cast<f32>(app_state.current_time - last_frame_tick) >= 1000.0f / s.fps) {
|
||||||
f32 delta = static_cast<f32>(app_state.current_time - last_frame_tick);
|
f32 delta = static_cast<f32>(app_state.current_time - last_frame_tick);
|
||||||
|
@ -361,7 +370,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::Begin("Viewport", &draw_viewport)) {
|
if (ImGui::Begin("Viewport")) {
|
||||||
if (ImGui::Shortcut(ImGuiKey_Space))
|
if (ImGui::Shortcut(ImGuiKey_Space))
|
||||||
TogglePlay();
|
TogglePlay();
|
||||||
|
|
||||||
|
@ -436,11 +445,11 @@ namespace K::UI {
|
||||||
struct PlotInfo {
|
struct PlotInfo {
|
||||||
f32 begin, end;
|
f32 begin, end;
|
||||||
i32 samples;
|
i32 samples;
|
||||||
const CompState &s;
|
const CompositionState &s;
|
||||||
Plugboard::ConnectInfo &connected_v;
|
Plugboard::ConnectInfo &connected_v;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Composition(CompState& s) {
|
void Composition(CompositionState& s) {
|
||||||
static bool layer_delete_requested = false;
|
static bool layer_delete_requested = false;
|
||||||
if (layer_delete_requested) {
|
if (layer_delete_requested) {
|
||||||
if (std::ranges::find(s.selected, s.active) != s.selected.end()) // unset active if active is selected
|
if (std::ranges::find(s.selected, s.active) != s.selected.end()) // unset active if active is selected
|
||||||
|
@ -486,7 +495,7 @@ namespace K::UI {
|
||||||
node_delete_requested = false;
|
node_delete_requested = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ImGui::Begin(("Composition: " + s.name).c_str(), &draw_comp, ImGuiWindowFlags_NoScrollbar)) {
|
if (!ImGui::Begin(("Composition: " + s.name).c_str(), nullptr, ImGuiWindowFlags_NoScrollbar)) {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -501,6 +510,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::SetNextItemWidth(150.0f);
|
ImGui::SetNextItemWidth(150.0f);
|
||||||
|
static Dict<Plugboard::ConnectInfo, Plugboard::LinksFromSource, Plugboard::ConnectInfoHasher> links_pos;
|
||||||
if (ImGui::BeginCombo("##Node", s.plugboard.nodes.GetName(static_cast<Plugboard::K_P_Nodes>(node_current)), ImGuiComboFlags_None)) {
|
if (ImGui::BeginCombo("##Node", s.plugboard.nodes.GetName(static_cast<Plugboard::K_P_Nodes>(node_current)), ImGuiComboFlags_None)) {
|
||||||
for (u32 n = 0; n < Plugboard::K_P_Count; n++) {
|
for (u32 n = 0; n < Plugboard::K_P_Count; n++) {
|
||||||
const bool is_selected = (node_current == n);
|
const bool is_selected = (node_current == n);
|
||||||
|
@ -571,7 +581,7 @@ namespace K::UI {
|
||||||
|
|
||||||
// why are we re-getting positions on each frame?
|
// why are we re-getting positions on each frame?
|
||||||
// this is just convenient because sometimes we would be dragging on a socket!
|
// this is just convenient because sometimes we would be dragging on a socket!
|
||||||
s.plugboard.links_pos.clear();
|
links_pos.clear();
|
||||||
|
|
||||||
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
|
||||||
old_view_pos = view_pos;
|
old_view_pos = view_pos;
|
||||||
|
@ -584,7 +594,7 @@ namespace K::UI {
|
||||||
(([&](auto&& arg){
|
(([&](auto&& arg){
|
||||||
for (auto& node : arg) {
|
for (auto& node : arg) {
|
||||||
PlugboardDrawNode<std::decay_t<decltype(node)>>(s, node, view_pos, io, style, dragging_on_socket,
|
PlugboardDrawNode<std::decay_t<decltype(node)>>(s, node, view_pos, io, style, dragging_on_socket,
|
||||||
drag_source, node_delete_requested);
|
drag_source, node_delete_requested, links_pos);
|
||||||
}
|
}
|
||||||
}(args)), ...);
|
}(args)), ...);
|
||||||
}, s.plugboard.nodes.nodes);
|
}, s.plugboard.nodes.nodes);
|
||||||
|
@ -596,7 +606,7 @@ namespace K::UI {
|
||||||
ImGuiChildFlags_AutoResizeY);
|
ImGuiChildFlags_AutoResizeY);
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
if (ImGui::BeginTable("Composition In", 3)) {
|
if (ImGui::BeginTable("Composition In", 3)) {
|
||||||
PlugboardNodeDrawSockets(s, s.plugboard.in, style, dragging_on_socket, drag_source, false);
|
PlugboardNodeDrawSockets(s, s.plugboard.in_instance, style, dragging_on_socket, drag_source, links_pos, false);
|
||||||
ImGui::EndTable();
|
ImGui::EndTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -928,9 +938,13 @@ namespace K::UI {
|
||||||
f32 init_y = ImGui::GetCursorScreenPos().y;
|
f32 init_y = ImGui::GetCursorScreenPos().y;
|
||||||
|
|
||||||
const static f32 layer_bound_width = 5.0f;
|
const static f32 layer_bound_width = 5.0f;
|
||||||
i32 l_in = TimelineFrameInView(view_left, view_right, current_layer.in, s.frame_max), l_out = TimelineFrameInView(view_left, view_right, current_layer.out, s.frame_max);
|
const bool l_le_right_extr = static_cast<f32>(current_layer.in) / static_cast<f32>(s.frame_max + 1) <= view_right,
|
||||||
|
l_in = l_le_right_extr && static_cast<f32>(current_layer.in) / static_cast<f32>(s.frame_max + 1) >= view_left,
|
||||||
|
l_ge_left_extr = static_cast<f32>(current_layer.out) / static_cast<f32>(s.frame_max + 1) >= view_left,
|
||||||
|
l_out = l_ge_left_extr && static_cast<f32>(current_layer.out) / static_cast<f32>(s.frame_max + 1) <= view_right;
|
||||||
f32 in_pos = TimelineFrameToScreenView(view_left, view_amt, view_width, current_layer.in, s.frame_max),
|
f32 in_pos = TimelineFrameToScreenView(view_left, view_amt, view_width, current_layer.in, s.frame_max),
|
||||||
out_pos = TimelineFrameToScreenView(view_left, view_amt, view_width, current_layer.out, s.frame_max);
|
out_pos = TimelineFrameToScreenView(view_left, view_amt, view_width, current_layer.out, s.frame_max);
|
||||||
|
ImGui::PushID(0);
|
||||||
if (l_in) {
|
if (l_in) {
|
||||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + in_pos);
|
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + in_pos);
|
||||||
static f32 l_in_old;
|
static f32 l_in_old;
|
||||||
|
@ -949,9 +963,10 @@ namespace K::UI {
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
}
|
}
|
||||||
ImGui::PushID(0);
|
if (l_le_right_extr && l_ge_left_extr) {
|
||||||
ImGui::Button(current_layer.name.c_str(),
|
ImGui::Button(current_layer.name.c_str(),
|
||||||
{std::min(out_pos + fr_step, view_width) - static_cast<f32>(l_in) * in_pos - layer_bound_width * static_cast<f32>(l_in + l_out), view_height});
|
{std::min(out_pos + fr_step, view_width) - static_cast<f32>(l_in) * in_pos -
|
||||||
|
layer_bound_width * static_cast<f32>(l_in + l_out), view_height});
|
||||||
static u32 in_old, out_old;
|
static u32 in_old, out_old;
|
||||||
if (ImGui::IsItemClicked()) {
|
if (ImGui::IsItemClicked()) {
|
||||||
in_old = current_layer.in;
|
in_old = current_layer.in;
|
||||||
|
@ -963,7 +978,7 @@ namespace K::UI {
|
||||||
current_layer.in = in_old + off;
|
current_layer.in = in_old + off;
|
||||||
current_layer.out = out_old + off;
|
current_layer.out = out_old + off;
|
||||||
}
|
}
|
||||||
ImGui::PopID();
|
}
|
||||||
if (l_out) {
|
if (l_out) {
|
||||||
static f32 r_out_old;
|
static f32 r_out_old;
|
||||||
ImGui::SameLine(0.0f, 0.0f);
|
ImGui::SameLine(0.0f, 0.0f);
|
||||||
|
@ -980,6 +995,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
ImGui::PopStyleColor();
|
ImGui::PopStyleColor();
|
||||||
}
|
}
|
||||||
|
ImGui::PopID();
|
||||||
|
|
||||||
ImGui::SetCursorScreenPos(ImVec2{tl_init_pos.x, init_y} - style.CellPadding);
|
ImGui::SetCursorScreenPos(ImVec2{tl_init_pos.x, init_y} - style.CellPadding);
|
||||||
ImGui::InvisibleButton("##TL_BG", ImVec2{ view_width + style.CellPadding.x * 2, row_height + style.CellPadding.y});
|
ImGui::InvisibleButton("##TL_BG", ImVec2{ view_width + style.CellPadding.x * 2, row_height + style.CellPadding.y});
|
||||||
|
@ -992,6 +1008,9 @@ 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)
|
||||||
|
continue;
|
||||||
|
|
||||||
ImGui::PushID(j);
|
ImGui::PushID(j);
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
|
@ -1017,9 +1036,9 @@ namespace K::UI {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>) {
|
||||||
if (ImGui::IsItemActive())
|
if (ImGui::IsItemActive())
|
||||||
s.plugboard.links_pos[arg].sinks.push_back(io.MousePos);
|
links_pos[arg].sinks.push_back(io.MousePos);
|
||||||
else
|
else
|
||||||
s.plugboard.links_pos[arg].sinks.push_back(ImGui::GetCursorScreenPos() +
|
links_pos[arg].sinks.push_back(ImGui::GetCursorScreenPos() +
|
||||||
ImVec2{ImGui::GetFrameHeight() / 2,
|
ImVec2{ImGui::GetFrameHeight() / 2,
|
||||||
-ImGui::GetFrameHeight() / 2 -
|
-ImGui::GetFrameHeight() / 2 -
|
||||||
style.ItemInnerSpacing.y});
|
style.ItemInnerSpacing.y});
|
||||||
|
@ -1027,9 +1046,11 @@ namespace K::UI {
|
||||||
else if (ImGui::IsItemActive()) {
|
else if (ImGui::IsItemActive()) {
|
||||||
if (ImGui::IsKeyPressed(ImGuiKey_LeftShift)) {
|
if (ImGui::IsKeyPressed(ImGuiKey_LeftShift)) {
|
||||||
auto& c = s.plugboard.nodes.Store(Plugboard::Chain{});
|
auto& c = s.plugboard.nodes.Store(Plugboard::Chain{});
|
||||||
|
c.extra.chain.segments.emplace_back(s.current_frame, std::get<Plugboard::T_Map<Plugboard::T_Float>::type>(arg));
|
||||||
|
c.extra.chain.selected.push_back(0);
|
||||||
Plugboard::Connect(u.connection.p, u.connection.index, &c, 0);
|
Plugboard::Connect(u.connection.p, u.connection.index, &c, 0);
|
||||||
Plugboard::Connect(&c, 0, &s.plugboard.in, 0);
|
Plugboard::Connect(&c, 0, &s.plugboard.in_instance, 0);
|
||||||
auto& nodes = s.plugboard.out.show_nodes[u.connection.index];
|
auto& nodes = s.plugboard.show_nodes[u.connection.index];
|
||||||
nodes.clear();
|
nodes.clear();
|
||||||
nodes.emplace_back(&c, 0);
|
nodes.emplace_back(&c, 0);
|
||||||
}
|
}
|
||||||
|
@ -1044,7 +1065,7 @@ namespace K::UI {
|
||||||
|
|
||||||
|
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
auto u_flags = ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_FramePadding;
|
auto u_flags = ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_NoTreePushOnOpen | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_FramePadding | ImGuiTreeNodeFlags_DefaultOpen;
|
||||||
if (connected_v.index() != 1)
|
if (connected_v.index() != 1)
|
||||||
u_flags |= ImGuiTreeNodeFlags_Leaf;
|
u_flags |= ImGuiTreeNodeFlags_Leaf;
|
||||||
bool uniform_open = ImGui::TreeNodeEx(u.name.c_str(), u_flags);
|
bool uniform_open = ImGui::TreeNodeEx(u.name.c_str(), u_flags);
|
||||||
|
@ -1080,7 +1101,7 @@ namespace K::UI {
|
||||||
ImPlot::PlotLineG("v", [](int idx, void* user_data) -> ImPlotPoint {
|
ImPlot::PlotLineG("v", [](int idx, void* user_data) -> ImPlotPoint {
|
||||||
PlotInfo i = *(PlotInfo*)user_data;
|
PlotInfo i = *(PlotInfo*)user_data;
|
||||||
f32 x = i.begin + (i.end - i.begin) * static_cast<f32>(idx) / static_cast<f32>(i.samples);
|
f32 x = i.begin + (i.end - i.begin) * static_cast<f32>(idx) / static_cast<f32>(i.samples);
|
||||||
CompState ss = i.s;
|
CompositionState ss = i.s;
|
||||||
ss.current_frame = static_cast<u64>(std::round(x));
|
ss.current_frame = static_cast<u64>(std::round(x));
|
||||||
bool good;
|
bool good;
|
||||||
Vector<Plugboard::ConnectInfo> info;
|
Vector<Plugboard::ConnectInfo> info;
|
||||||
|
@ -1099,7 +1120,7 @@ namespace K::UI {
|
||||||
tl_bg_handler();
|
tl_bg_handler();
|
||||||
|
|
||||||
if (uniform_open && connected_v.index() == 1) {
|
if (uniform_open && connected_v.index() == 1) {
|
||||||
for (const auto& info: s.plugboard.out.show_nodes[u.connection.index]) {
|
for (const auto& info: s.plugboard.show_nodes[u.connection.index]) {
|
||||||
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
ImGui::TableNextRow(ImGuiTableRowFlags_None, row_height);
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
|
@ -1227,13 +1248,16 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
ImGui::TreePop();
|
ImGui::TreePop();
|
||||||
}
|
}
|
||||||
else for (auto &u: current_layer.track.uniforms)
|
else for (auto& u: current_layer.track.uniforms) {
|
||||||
std::visit([table_left, &s](auto &&arg) {
|
if (u.status != K_U_Exposed)
|
||||||
|
continue;
|
||||||
|
std::visit([table_left](auto &&arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>)
|
if constexpr (std::is_same_v<T, Plugboard::ConnectInfo>)
|
||||||
s.plugboard.links_pos[arg].sinks.push_back( // make nodes connect to collapsed layer row
|
links_pos[arg].sinks.push_back( // make nodes connect to collapsed layer row
|
||||||
{table_left, ImGui::GetCursorScreenPos().y - row_height / 2.0f});
|
{table_left, ImGui::GetCursorScreenPos().y - row_height / 2.0f});
|
||||||
}, std::visit([&u](auto&& arg) -> auto& { return arg->in[u.connection.index].value; }, u.connection.p));
|
}, std::visit([&u](auto&& arg) -> auto& { return arg->in[u.connection.index].value; }, u.connection.p));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ImGui::PopStyleVar(); // FramePadding
|
ImGui::PopStyleVar(); // FramePadding
|
||||||
|
@ -1276,7 +1300,7 @@ namespace K::UI {
|
||||||
ImGui::SetCursorScreenPos(nodes_begin);
|
ImGui::SetCursorScreenPos(nodes_begin);
|
||||||
if (ImGui::BeginChild("Node Connection Overlay", {table_left - ImGui::GetWindowPos().x, 0.0f}, false, ImGuiWindowFlags_NoInputs)) {
|
if (ImGui::BeginChild("Node Connection Overlay", {table_left - ImGui::GetWindowPos().x, 0.0f}, false, ImGuiWindowFlags_NoInputs)) {
|
||||||
auto *window = ImGui::GetCurrentWindow();
|
auto *window = ImGui::GetCurrentWindow();
|
||||||
for (auto &[_, link]: s.plugboard.links_pos)
|
for (auto &[_, link]: links_pos)
|
||||||
for (auto &sink: link.sinks)
|
for (auto &sink: link.sinks)
|
||||||
window->DrawList->AddBezierCubic(link.source,
|
window->DrawList->AddBezierCubic(link.source,
|
||||||
{link.source.x + 60.0f, link.source.y},
|
{link.source.x + 60.0f, link.source.y},
|
||||||
|
@ -1446,7 +1470,7 @@ namespace K::UI {
|
||||||
ImPlot::PlotLineG("v", [](int idx, void *user_data) -> ImPlotPoint {
|
ImPlot::PlotLineG("v", [](int idx, void *user_data) -> ImPlotPoint {
|
||||||
PlotInfo i = *(PlotInfo *) user_data;
|
PlotInfo i = *(PlotInfo *) user_data;
|
||||||
f32 x = i.begin + (i.end - i.begin) * static_cast<f32>(idx) / static_cast<f32>(i.samples);
|
f32 x = i.begin + (i.end - i.begin) * static_cast<f32>(idx) / static_cast<f32>(i.samples);
|
||||||
CompState ss = i.s;
|
CompositionState ss = i.s;
|
||||||
ss.current_frame = static_cast<u64>(x);
|
ss.current_frame = static_cast<u64>(x);
|
||||||
bool good;
|
bool good;
|
||||||
Vector<Plugboard::ConnectInfo> info;
|
Vector<Plugboard::ConnectInfo> info;
|
||||||
|
@ -1536,7 +1560,7 @@ namespace K::UI {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Layer(CompState& s) {
|
void Layer(CompositionState& s) {
|
||||||
struct TextFilters { static int VariableName(ImGuiInputTextCallbackData *data) {
|
struct TextFilters { static int VariableName(ImGuiInputTextCallbackData *data) {
|
||||||
return !(data->EventChar < 256 &&
|
return !(data->EventChar < 256 &&
|
||||||
((data->EventChar >= 'a' && data->EventChar <= 'z') ||
|
((data->EventChar >= 'a' && data->EventChar <= 'z') ||
|
||||||
|
@ -1544,7 +1568,7 @@ namespace K::UI {
|
||||||
(data->EventChar >= '0' && data->EventChar <= '9') ||
|
(data->EventChar >= '0' && data->EventChar <= '9') ||
|
||||||
data->EventChar == '_'));
|
data->EventChar == '_'));
|
||||||
} };
|
} };
|
||||||
if (ImGui::Begin("Layer", &draw_layer)) {
|
if (ImGui::Begin("Layer")) {
|
||||||
if (s.active == -1)
|
if (s.active == -1)
|
||||||
ImGui::TextUnformatted("No active layer.");
|
ImGui::TextUnformatted("No active layer.");
|
||||||
else {
|
else {
|
||||||
|
@ -1554,8 +1578,7 @@ namespace K::UI {
|
||||||
static i32 type_current = 0;
|
static i32 type_current = 0;
|
||||||
static String name{};
|
static String name{};
|
||||||
if (ImGui::Button("Add Uniform") && !name.empty() && !isdigit(name[0]) && !(name[0] == 'f' && name.length() == 1)) {
|
if (ImGui::Button("Add Uniform") && !name.empty() && !isdigit(name[0]) && !(name[0] == 'f' && name.length() == 1)) {
|
||||||
s.layers[s.active].track.AddUniform(name, ExpandVariant(
|
s.layers[s.active].track.AddUniform("u_" + name, ExpandVariant(static_cast<ShaderGraph::Type>(type_current)), K_U_Exposed);
|
||||||
static_cast<ShaderGraph::Type>(type_current)));
|
|
||||||
VisualTrack::ExposeUniform(s, s.layers[s.active].track.uniforms.back());
|
VisualTrack::ExposeUniform(s, s.layers[s.active].track.uniforms.back());
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
@ -1575,8 +1598,10 @@ 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 (std::visit([](auto&& arg){ return arg == nullptr; }, it->connection.p))
|
if (it->status != K_U_Exposed) {
|
||||||
|
it++;
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::PushID(i++);
|
ImGui::PushID(i++);
|
||||||
|
@ -1611,14 +1636,15 @@ namespace K::UI {
|
||||||
if (ImGui::BeginTabItem("Samplers")) {
|
if (ImGui::BeginTabItem("Samplers")) {
|
||||||
static String name{};
|
static String name{};
|
||||||
if (ImGui::Button("Add Sampler") && !name.empty() && !isdigit(name[0])) {
|
if (ImGui::Button("Add Sampler") && !name.empty() && !isdigit(name[0])) {
|
||||||
s.layers[s.active].track.AddSampler(name);
|
s.layers[s.active].track.AddSampler("s_" + name);
|
||||||
}
|
}
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
ImGui::InputText("##SamplerName", &name, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::VariableName);
|
ImGui::InputText("##SamplerName", &name, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::VariableName);
|
||||||
|
|
||||||
if (ImGui::BeginTable("Samplers", 3, 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("Resource", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Dims via", ImGuiTableColumnFlags_NoSort | ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
ImGui::TableSetupColumn("Resource", 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;
|
||||||
|
@ -1628,7 +1654,19 @@ namespace K::UI {
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::TextUnformatted(it->name.c_str());
|
ImGui::TextUnformatted(it->name.c_str());
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
ImGui::Text("%s", it->resource->filename.c_str());
|
ImGui::Text("%s%s", it->name.c_str(), "_dims");
|
||||||
|
ImGui::TableNextColumn();
|
||||||
|
if (ImGui::BeginCombo("##source", it->resource->filename.c_str())) {
|
||||||
|
for (auto& [file, res_v] : Resource::resources)
|
||||||
|
if (auto *res = std::get_if<Resource::Resource<Resource::K_R_Still>>(&res_v)) {
|
||||||
|
const bool is_selected = it->resource == res;
|
||||||
|
if (ImGui::Selectable(file.c_str(), is_selected)) {
|
||||||
|
it->resource = res;
|
||||||
|
it->dims->val = ShaderGraph::XY{static_cast<f32>(res->w), static_cast<f32>(res->h)};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndCombo();
|
||||||
|
}
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if (ImGui::Button("X")) {
|
if (ImGui::Button("X")) {
|
||||||
bgfx::destroy(it->handle);
|
bgfx::destroy(it->handle);
|
||||||
|
@ -1652,8 +1690,8 @@ namespace K::UI {
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpolation(CompState& s) {
|
void Interpolation(CompositionState& s) {
|
||||||
if (ImGui::Begin("Interpolation", &draw_interpolation, ImGuiWindowFlags_NoScrollbar)) {
|
if (ImGui::Begin("Interpolation", nullptr, ImGuiWindowFlags_NoScrollbar)) {
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
|
||||||
static Plugboard::K_Interpolation type_current = Plugboard::K_I_CubicBezier;
|
static Plugboard::K_Interpolation type_current = Plugboard::K_I_CubicBezier;
|
||||||
|
@ -1663,8 +1701,10 @@ 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) {
|
||||||
for (auto& n : s.plugboard.out.show_nodes[u.connection.index]) {
|
if (u.status != K_U_Exposed)
|
||||||
|
continue;
|
||||||
|
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;
|
||||||
for (auto it = chain.segments.begin(); it != chain.segments.end(); it++) {
|
for (auto it = chain.segments.begin(); it != chain.segments.end(); it++) {
|
||||||
auto nit = std::next(it);
|
auto nit = std::next(it);
|
||||||
|
@ -1674,6 +1714,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
|
@ -1784,6 +1825,42 @@ namespace K::UI {
|
||||||
|
|
||||||
void Assets() {
|
void Assets() {
|
||||||
if (ImGui::Begin("Assets", &draw_assets)) {
|
if (ImGui::Begin("Assets", &draw_assets)) {
|
||||||
|
if (ImGui::Button("Load")) {
|
||||||
|
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) {
|
||||||
|
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)) {
|
||||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||||
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
ImGui::TableSetupColumn("Type", ImGuiTableColumnFlags_WidthFixed);
|
||||||
|
@ -1791,7 +1868,7 @@ namespace K::UI {
|
||||||
ImGui::TableHeadersRow();
|
ImGui::TableHeadersRow();
|
||||||
|
|
||||||
i32 i = 0;
|
i32 i = 0;
|
||||||
for (auto& comp : app_state.compositions) {
|
for (auto& comp : app_state.project.compositions) {
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::PushID(i++);
|
ImGui::PushID(i++);
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
|
@ -1826,10 +1903,10 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
ImGui::TableNextColumn();
|
ImGui::TableNextColumn();
|
||||||
if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_ShaderProgram>>) {
|
if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_ShaderProgram>>) {
|
||||||
ImGui::Text("%s", fmt::format("{:%Y-%m-%d %X}", std::chrono::file_clock::to_sys(arg.frag_last_updated)).c_str());
|
ImGui::Text("%s", fmt::format("{:%Y-%m-%d %H:%M:%S}", std::chrono::floor<std::chrono::seconds>(std::chrono::file_clock::to_sys(arg.frag_last_updated))).c_str());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ImGui::Text("%s", fmt::format("{:%Y-%m-%d %X}", std::chrono::file_clock::to_sys(arg.last_updated)).c_str());
|
ImGui::Text("%s", fmt::format("{:%Y-%m-%d %H:%M:%S}", std::chrono::floor<std::chrono::seconds>(std::chrono::file_clock::to_sys(arg.last_updated))).c_str());
|
||||||
}
|
}
|
||||||
}, res);
|
}, res);
|
||||||
ImGui::PopID();
|
ImGui::PopID();
|
||||||
|
@ -1854,7 +1931,7 @@ namespace K::UI {
|
||||||
|
|
||||||
if (draw_assets) Assets();
|
if (draw_assets) Assets();
|
||||||
|
|
||||||
auto& comp = app_state.compositions[app_state.inspecting_composition];
|
auto& comp = app_state.project.compositions[app_state.project.inspecting_composition];
|
||||||
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);
|
||||||
|
@ -1918,7 +1995,7 @@ namespace K::UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
bg.pg = Resource::Load<Resource::K_R_ShaderProgram>("Checkerboard")->pg;
|
bg.pg = Resource::Load<Resource::K_R_ShaderProgram>("Checkerboard")->pg;
|
||||||
bg.AddUniform("f_hw", ShaderGraph::Type::T_XYZ);
|
bg.AddUniform("f_hw", ShaderGraph::Type::T_XYZ, K_U_Inactive);
|
||||||
|
|
||||||
logo = Resource::Load<Resource::K_R_Still>("Keishiki.png");
|
logo = Resource::Load<Resource::K_R_Still>("Keishiki.png");
|
||||||
}
|
}
|
||||||
|
@ -1927,7 +2004,7 @@ namespace K::UI {
|
||||||
bgfx::destroy(bg.uniforms[0].handle);
|
bgfx::destroy(bg.uniforms[0].handle);
|
||||||
bg.uniforms.erase(bg.uniforms.begin());
|
bg.uniforms.erase(bg.uniforms.begin());
|
||||||
|
|
||||||
for (auto& comp : app_state.compositions)
|
for (auto& comp : app_state.project.compositions)
|
||||||
DestroyViewport(comp);
|
DestroyViewport(comp);
|
||||||
|
|
||||||
ImGui_Implbgfx_Shutdown();
|
ImGui_Implbgfx_Shutdown();
|
||||||
|
|
|
@ -36,7 +36,7 @@ namespace K {
|
||||||
},val);
|
},val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::GetFrame(const CompState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16],
|
void VisualTrack::GetFrame(const CompositionState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16],
|
||||||
f32 view[16], f32 transform[16]) {
|
f32 view[16], f32 transform[16]) {
|
||||||
bgfx::setViewMode(view_id, bgfx::ViewMode::Sequential);
|
bgfx::setViewMode(view_id, bgfx::ViewMode::Sequential);
|
||||||
bgfx::setViewClear(view_id, BGFX_CLEAR_COLOR);
|
bgfx::setViewClear(view_id, BGFX_CLEAR_COLOR);
|
||||||
|
@ -88,8 +88,8 @@ namespace K {
|
||||||
|
|
||||||
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] : samplers) {
|
for (auto& [_name, handle, res, _u] : samplers) {
|
||||||
bgfx::setTexture(sampler_stage++, handle, res->tex);
|
bgfx::setTexture(sampler_stage++, handle, res->tex, BGFX_SAMPLER_UVW_BORDER);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::DrawQuad(view_id, transform, BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A, pg);
|
Graphics::DrawQuad(view_id, transform, BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A, pg);
|
||||||
|
@ -101,7 +101,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] : samplers) {
|
for (auto& [name, _tex, _res, _u] : samplers) {
|
||||||
f << "SAMPLER2D(" << name << ", " << sampler_loc++ << ");\n";
|
f << "SAMPLER2D(" << name << ", " << sampler_loc++ << ");\n";
|
||||||
}
|
}
|
||||||
for (auto& u : uniforms) {
|
for (auto& u : uniforms) {
|
||||||
|
@ -150,18 +150,21 @@ namespace K {
|
||||||
samplers.clear();
|
samplers.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::ExposeUniform(CompState& s, Uniform& uu) {
|
void VisualTrack::ExposeUniform(CompositionState& s, Uniform& uu) {
|
||||||
uu.connection = {&s.plugboard.out, static_cast<u32>(s.plugboard.out.in.size())};
|
uu.connection = {&s.plugboard.out_instance, static_cast<u32>(s.plugboard.out_instance.in.size())};
|
||||||
// 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.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.out.show_nodes.emplace_back();
|
s.plugboard.show_nodes.emplace_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::ExposeUniform(CompState& s, u32 i) {
|
void VisualTrack::ExposeUniform(CompositionState& s, u32 i) {
|
||||||
ExposeUniform(s, uniforms[i]);
|
ExposeUniform(s, uniforms[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::HideUniform(CompState& s, Uniform& uu) {
|
void VisualTrack::HideUniform(CompositionState& s, Uniform& uu) {
|
||||||
|
if (uu.status != K_U_Exposed)
|
||||||
|
return;
|
||||||
|
|
||||||
Plugboard::Disconnect(uu.connection.p, uu.connection.index);
|
Plugboard::Disconnect(uu.connection.p, uu.connection.index);
|
||||||
|
|
||||||
// decrement indices of uniforms referencing CompositionOut whose index is greater
|
// decrement indices of uniforms referencing CompositionOut whose index is greater
|
||||||
|
@ -170,22 +173,22 @@ namespace K {
|
||||||
if (u_other.connection.index > uu.connection.index)
|
if (u_other.connection.index > uu.connection.index)
|
||||||
u_other.connection.index--;
|
u_other.connection.index--;
|
||||||
|
|
||||||
if (std::holds_alternative<Plugboard::ConnectInfo>(s.plugboard.out.in[uu.connection.index].value)) {
|
if (std::holds_alternative<Plugboard::ConnectInfo>(s.plugboard.out_instance.in[uu.connection.index].value)) {
|
||||||
Plugboard::Disconnect(s.plugboard.out, uu.connection.index);
|
Plugboard::Disconnect(s.plugboard.out_instance, uu.connection.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
s.plugboard.out.in.erase(s.plugboard.out.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};
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val) {
|
void VisualTrack::AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val, UniformStatus init) {
|
||||||
for (auto& u : uniforms)
|
for (auto& u : uniforms)
|
||||||
if (u.name == s)
|
if (u.name == s)
|
||||||
return;
|
return;
|
||||||
for (auto& ss : samplers)
|
for (auto& ss : samplers)
|
||||||
if (ss.name == s)
|
if (ss.name == s)
|
||||||
return;
|
return;
|
||||||
uniforms.emplace_back(Uniform{s, bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val, {{}, 0}});
|
uniforms.emplace_back(Uniform{s, bgfx::createUniform(("__" + s).c_str(), bgfx::UniformType::Vec4), val, {{}, 0}, init});
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualTrack::AddSampler(const String& s) {
|
void VisualTrack::AddSampler(const String& s) {
|
||||||
|
@ -195,6 +198,7 @@ namespace K {
|
||||||
for (auto& ss : samplers)
|
for (auto& ss : samplers)
|
||||||
if (ss.name == s)
|
if (ss.name == s)
|
||||||
return;
|
return;
|
||||||
samplers.emplace_back(Sampler{s, bgfx::createUniform(s.c_str(), bgfx::UniformType::Sampler), Resource::fallback_still});
|
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()});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,11 @@ namespace K {
|
||||||
|
|
||||||
template <typename... Ts>
|
template <typename... Ts>
|
||||||
inline void Log(LogLevel level, fmt::format_string<Ts...> fmt, Ts&&... args) {
|
inline void Log(LogLevel level, fmt::format_string<Ts...> fmt, Ts&&... args) {
|
||||||
fmt::print(level > K_L_Info ? stderr : stdout, "[{}] Keishiki: ", LogLevelNames[level]);
|
auto& t = level > K_L_Info ? stderr : stdout;
|
||||||
fmt::print(fmt, std::forward<Ts>(args)...);
|
fmt::print(t, "[{}] Keishiki: ", LogLevelNames[level]);
|
||||||
fmt::print("\n");
|
fmt::print(t, fmt, std::forward<Ts>(args)...);
|
||||||
|
fmt::print(t, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CompState; // fwd declared -- Keishiki.h <-> VisualTrack.h has dependency cycle
|
struct CompositionState; // fwd declared -- Keishiki.h <-> VisualTrack.h has dependency cycle
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace K {
|
||||||
u64 in, out;
|
u64 in, out;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompState {
|
struct CompositionState {
|
||||||
String name;
|
String name;
|
||||||
// Time
|
// Time
|
||||||
u64 current_frame;
|
u64 current_frame;
|
||||||
|
@ -33,10 +33,15 @@ namespace K {
|
||||||
Plugboard::Plugboard plugboard;
|
Plugboard::Plugboard plugboard;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ProjectState {
|
||||||
|
i32 inspecting_composition = -1;
|
||||||
|
Vector<CompositionState> compositions{};
|
||||||
|
};
|
||||||
|
|
||||||
extern struct AppState {
|
extern struct AppState {
|
||||||
SDL_Window *window = nullptr;
|
SDL_Window *window = nullptr;
|
||||||
i32 window_width = 2300,
|
i32 window_width = 2200,
|
||||||
window_height = 1300;
|
window_height = 1200;
|
||||||
|
|
||||||
std::atomic_bool running {true};
|
std::atomic_bool running {true};
|
||||||
|
|
||||||
|
@ -44,7 +49,6 @@ namespace K {
|
||||||
u32 bgfx_frame{};
|
u32 bgfx_frame{};
|
||||||
u32 n_views{};
|
u32 n_views{};
|
||||||
|
|
||||||
i32 inspecting_composition = -1;
|
ProjectState project{};
|
||||||
Vector<CompState> compositions{};
|
|
||||||
} app_state; // global !
|
} app_state; // global !
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,8 +86,8 @@ namespace K::Plugboard {
|
||||||
struct AbsoluteValue;
|
struct AbsoluteValue;
|
||||||
struct Interpolation;
|
struct Interpolation;
|
||||||
struct Chain;
|
struct Chain;
|
||||||
struct CompositionIn;
|
struct GroupIn;
|
||||||
struct CompositionOut;
|
struct GroupOut;
|
||||||
|
|
||||||
enum K_P_Nodes {
|
enum K_P_Nodes {
|
||||||
K_P_Add = 0,
|
K_P_Add = 0,
|
||||||
|
@ -144,8 +144,8 @@ namespace K::Plugboard {
|
||||||
AbsoluteValue,
|
AbsoluteValue,
|
||||||
Interpolation,
|
Interpolation,
|
||||||
Chain,
|
Chain,
|
||||||
CompositionIn,
|
GroupIn,
|
||||||
CompositionOut>;
|
GroupOut>;
|
||||||
|
|
||||||
using NodeInstanceP = NodeVar::NodeInstanceP;
|
using NodeInstanceP = NodeVar::NodeInstanceP;
|
||||||
|
|
||||||
|
@ -353,222 +353,220 @@ namespace K::Plugboard {
|
||||||
|
|
||||||
T_Map<T_Count>::type ConvertValue(const T_Map<T_Count>::type& v, Type target, bool& good);
|
T_Map<T_Count>::type ConvertValue(const T_Map<T_Count>::type& v, Type target, bool& good);
|
||||||
|
|
||||||
T_Map<T_Count>::type Eval(const CompState& s, const ConnectInfo& info);
|
T_Map<T_Count>::type Eval(const CompositionState& s, const ConnectInfo& info);
|
||||||
|
|
||||||
struct LinksFromSource {
|
struct LinksFromSource {
|
||||||
ImVec2 source;
|
ImVec2 source;
|
||||||
Vector<ImVec2> sinks;
|
Vector<ImVec2> sinks;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAdd(const CompState& s, const Add& n);
|
T_Map<T_Count>::type FetchAdd(const CompositionState& s, const Add& n);
|
||||||
struct Add {
|
struct Add {
|
||||||
const static char constexpr *name = static_cast<const char*>("Add");
|
const static char constexpr *name = static_cast<const char*>("Add");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "a+b", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "a+b", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Add&), 1> fetch = { FetchAdd };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Add&), 1> fetch = {FetchAdd };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchNegate(const CompState& s, const Negate& n);
|
T_Map<T_Count>::type FetchNegate(const CompositionState& s, const Negate& n);
|
||||||
struct Negate {
|
struct Negate {
|
||||||
const static char constexpr *name = static_cast<const char*>("Negate");
|
const static char constexpr *name = static_cast<const char*>("Negate");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "-a", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "-a", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Negate&), 1> fetch = { FetchNegate };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Negate&), 1> fetch = {FetchNegate };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSubtract(const CompState& s, const Subtract& n);
|
T_Map<T_Count>::type FetchSubtract(const CompositionState& s, const Subtract& n);
|
||||||
struct Subtract {
|
struct Subtract {
|
||||||
const static char constexpr *name = static_cast<const char*>("Subtract");
|
const static char constexpr *name = static_cast<const char*>("Subtract");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "a-b", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "a-b", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Subtract&), 1>fetch = { FetchSubtract };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Subtract&), 1>fetch = {FetchSubtract };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMultiply(const CompState& s, const Multiply& n);
|
T_Map<T_Count>::type FetchMultiply(const CompositionState& s, const Multiply& n);
|
||||||
struct Multiply {
|
struct Multiply {
|
||||||
const static char constexpr *name = static_cast<const char*>("Multiply");
|
const static char constexpr *name = static_cast<const char*>("Multiply");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "a*b", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "a*b", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Multiply&), 1> fetch = { FetchMultiply };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Multiply&), 1> fetch = {FetchMultiply };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchDivide(const CompState& s, const Divide& n);
|
T_Map<T_Count>::type FetchDivide(const CompositionState& s, const Divide& n);
|
||||||
struct Divide {
|
struct Divide {
|
||||||
const static char constexpr *name = static_cast<const char*>("Divide");
|
const static char constexpr *name = static_cast<const char*>("Divide");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "a/b", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "a/b", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Divide&), 1> fetch = { FetchDivide };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Divide&), 1> fetch = {FetchDivide };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSign(const CompState& s, const Sign& n);
|
T_Map<T_Count>::type FetchSign(const CompositionState& s, const Sign& n);
|
||||||
struct Sign {
|
struct Sign {
|
||||||
const static char constexpr *name = static_cast<const char*>("Sign");
|
const static char constexpr *name = static_cast<const char*>("Sign");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "sgn(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "sgn(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Sign&), 1> fetch = { FetchSign };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Sign&), 1> fetch = {FetchSign };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSin(const CompState& s, const Sin& n);
|
T_Map<T_Count>::type FetchSin(const CompositionState& s, const Sin& n);
|
||||||
struct Sin {
|
struct Sin {
|
||||||
const static char constexpr *name = static_cast<const char*>("Sin");
|
const static char constexpr *name = static_cast<const char*>("Sin");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "sin(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "sin(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Sin&), 1> fetch = { FetchSin };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Sin&), 1> fetch = {FetchSin };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchCos(const CompState& s, const Cos& n);
|
T_Map<T_Count>::type FetchCos(const CompositionState& s, const Cos& n);
|
||||||
struct Cos {
|
struct Cos {
|
||||||
const static char constexpr *name = static_cast<const char*>("Cos");
|
const static char constexpr *name = static_cast<const char*>("Cos");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "cos(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "cos(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Cos&), 1> fetch = { FetchCos };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Cos&), 1> fetch = {FetchCos };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchTan(const CompState& s, const Tan& n);
|
T_Map<T_Count>::type FetchTan(const CompositionState& s, const Tan& n);
|
||||||
struct Tan {
|
struct Tan {
|
||||||
const static char constexpr *name = static_cast<const char*>("Tan");
|
const static char constexpr *name = static_cast<const char*>("Tan");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a (rad)", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "tan(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "tan(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Tan&), 1> fetch = { FetchTan };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Tan&), 1> fetch = {FetchTan };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArcsin(const CompState& s, const Arcsin& n);
|
T_Map<T_Count>::type FetchArcsin(const CompositionState& s, const Arcsin& n);
|
||||||
struct Arcsin {
|
struct Arcsin {
|
||||||
const static char constexpr *name = static_cast<const char*>("Arcsin");
|
const static char constexpr *name = static_cast<const char*>("Arcsin");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "arcsin(a) (rad)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "arcsin(a) (rad)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Arcsin&), 1> fetch = { FetchArcsin };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Arcsin&), 1> fetch = {FetchArcsin };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArccos(const CompState& s, const Arccos& n);
|
T_Map<T_Count>::type FetchArccos(const CompositionState& s, const Arccos& n);
|
||||||
struct Arccos {
|
struct Arccos {
|
||||||
const static char constexpr *name = static_cast<const char*>("Arccos");
|
const static char constexpr *name = static_cast<const char*>("Arccos");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "arccos(a) (rad)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "arccos(a) (rad)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Arccos&), 1> fetch = { FetchArccos };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Arccos&), 1> fetch = {FetchArccos };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchArctan(const CompState& s, const Arctan& n);
|
T_Map<T_Count>::type FetchArctan(const CompositionState& s, const Arctan& n);
|
||||||
struct Arctan {
|
struct Arctan {
|
||||||
const static char constexpr *name = static_cast<const char*>("Arctan");
|
const static char constexpr *name = static_cast<const char*>("Arctan");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "arctan(a) (rad)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "arctan(a) (rad)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Arctan&), 1> fetch = { FetchArctan };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Arctan&), 1> fetch = {FetchArctan };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAtan2(const CompState& s, const Atan2& n);
|
T_Map<T_Count>::type FetchAtan2(const CompositionState& s, const Atan2& n);
|
||||||
struct Atan2 {
|
struct Atan2 {
|
||||||
const static char constexpr *name = static_cast<const char*>("Atan2");
|
const static char constexpr *name = static_cast<const char*>("Atan2");
|
||||||
std::array<InSocket, 2> in = { InSocket{"y", T_Float }, InSocket{"x", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"y", T_Float }, InSocket{"x", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "atan2(y, x) (rad)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "atan2(y, x) (rad)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Atan2&), 1> fetch = { FetchAtan2 };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Atan2&), 1> fetch = {FetchAtan2 };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMinimum(const CompState& s, const Minimum& n);
|
T_Map<T_Count>::type FetchMinimum(const CompositionState& s, const Minimum& n);
|
||||||
struct Minimum {
|
struct Minimum {
|
||||||
const static char constexpr *name = static_cast<const char*>("Minimum");
|
const static char constexpr *name = static_cast<const char*>("Minimum");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "min(a, b)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "min(a, b)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Minimum&), 1> fetch = { FetchMinimum };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Minimum&), 1> fetch = {FetchMinimum };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchMaximum(const CompState& s, const Maximum& n);
|
T_Map<T_Count>::type FetchMaximum(const CompositionState& s, const Maximum& n);
|
||||||
struct Maximum {
|
struct Maximum {
|
||||||
const static char constexpr *name = static_cast<const char*>("Maximum");
|
const static char constexpr *name = static_cast<const char*>("Maximum");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "max(a, b)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "max(a, b)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Maximum&), 1> fetch = { FetchMaximum };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Maximum&), 1> fetch = {FetchMaximum };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchPower(const CompState& s, const Power& n);
|
T_Map<T_Count>::type FetchPower(const CompositionState& s, const Power& n);
|
||||||
struct Power {
|
struct Power {
|
||||||
const static char constexpr *name = static_cast<const char*>("Power");
|
const static char constexpr *name = static_cast<const char*>("Power");
|
||||||
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
std::array<InSocket, 2> in = { InSocket{"a", T_Float }, InSocket{"b", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "a^b", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "a^b", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Power&), 1> fetch = { FetchPower };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Power&), 1> fetch = {FetchPower };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchSquareRoot(const CompState& s, const SquareRoot& n);
|
T_Map<T_Count>::type FetchSquareRoot(const CompositionState& s, const SquareRoot& n);
|
||||||
struct SquareRoot {
|
struct SquareRoot {
|
||||||
const static char constexpr *name = static_cast<const char*>("Square Root");
|
const static char constexpr *name = static_cast<const char*>("Square Root");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "sqrt(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "sqrt(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const SquareRoot&), 1> fetch = { FetchSquareRoot };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const SquareRoot&), 1> fetch = {FetchSquareRoot };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchNaturalLogarithm(const CompState& s, const NaturalLogarithm& n);
|
T_Map<T_Count>::type FetchNaturalLogarithm(const CompositionState& s, const NaturalLogarithm& n);
|
||||||
struct NaturalLogarithm {
|
struct NaturalLogarithm {
|
||||||
const static char constexpr *name = static_cast<const char*>("Natural Logarithm");
|
const static char constexpr *name = static_cast<const char*>("Natural Logarithm");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "log(a)", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "log(a)", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const NaturalLogarithm&), 1> fetch = { FetchNaturalLogarithm };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const NaturalLogarithm&), 1> fetch = {FetchNaturalLogarithm };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchAbsoluteValue(const CompState& s, const AbsoluteValue& n);
|
T_Map<T_Count>::type FetchAbsoluteValue(const CompositionState& s, const AbsoluteValue& n);
|
||||||
struct AbsoluteValue {
|
struct AbsoluteValue {
|
||||||
const static char constexpr *name = static_cast<const char*>("Absolute Value");
|
const static char constexpr *name = static_cast<const char*>("Absolute Value");
|
||||||
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"a", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "|a|", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "|a|", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const AbsoluteValue&), 1> fetch = { FetchAbsoluteValue };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const AbsoluteValue&), 1> fetch = {FetchAbsoluteValue };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchInterpolation(const CompState& s, const Interpolation& n);
|
T_Map<T_Count>::type FetchInterpolation(const CompositionState& s, const Interpolation& n);
|
||||||
struct Interpolation {
|
struct Interpolation {
|
||||||
const static char constexpr *name = static_cast<const char*>("Interpolation");
|
const static char constexpr *name = static_cast<const char*>("Interpolation");
|
||||||
std::array<InSocket, 1> in = { InSocket{"t", T_Float } };
|
std::array<InSocket, 1> in = { InSocket{"t", T_Float } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "Value", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "Value", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Interpolation&), 1> fetch = { FetchInterpolation };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Interpolation&), 1> fetch = {FetchInterpolation };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
InterpolationExtra extra{};
|
InterpolationExtra extra{};
|
||||||
void Draw();
|
void Draw();
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchChain(const CompState& s, const Chain& n);
|
T_Map<T_Count>::type FetchChain(const CompositionState& s, const Chain& n);
|
||||||
struct Chain {
|
struct Chain {
|
||||||
const static char constexpr *name = static_cast<const char*>("Chain");
|
const static char constexpr *name = static_cast<const char*>("Chain");
|
||||||
std::array<InSocket, 1> in = { InSocket{"In", T_Int } };
|
std::array<InSocket, 1> in = { InSocket{"In", T_Int } };
|
||||||
std::array<OutSocket, 1> out = { OutSocket{ "Out", T_Float } };
|
std::array<OutSocket, 1> out = { OutSocket{ "Out", T_Float } };
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const Chain&), 1> fetch = { FetchChain };
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const Chain&), 1> fetch = {FetchChain };
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
ChainExtra extra{};
|
ChainExtra extra{};
|
||||||
};
|
};
|
||||||
|
|
||||||
T_Map<T_Count>::type FetchCompositionInFrame(const CompState& s, const CompositionIn& n);
|
T_Map<T_Count>::type FetchCompositionInFrame(const CompositionState& s, const GroupIn& n);
|
||||||
T_Map<T_Count>::type FetchCompositionInTime(const CompState& s, const CompositionIn& n);
|
T_Map<T_Count>::type FetchCompositionInAppTicks(const CompositionState& s, const GroupIn& n);
|
||||||
T_Map<T_Count>::type FetchCompositionInAppTicks(const CompState& s, const CompositionIn& n);
|
struct GroupIn {
|
||||||
struct CompositionIn {
|
const static char constexpr *name = static_cast<const char*>("Group In");
|
||||||
const static char constexpr *name = static_cast<const char*>("Composition In");
|
std::array<InSocket, 0> in{};
|
||||||
std::array<InSocket, 0> in = {};
|
Vector<OutSocket> out{};
|
||||||
std::array<OutSocket, 3> out = { OutSocket{"Frame", T_Int}, OutSocket{"Time (s)", T_Float}, OutSocket{"App Ticks", T_Float} };
|
Vector<T_Map<T_Count>::type (*)(const CompositionState&, const GroupIn&)> fetch;
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const CompositionIn&), 3> fetch = { FetchCompositionInFrame, FetchCompositionInTime, FetchCompositionInAppTicks };
|
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CompositionOut {
|
struct GroupOut {
|
||||||
const static char constexpr *name = static_cast<const char*>("Composition Out");
|
const static char constexpr *name = static_cast<const char*>("Group Out");
|
||||||
Vector<InSocket> in = {};
|
Vector<InSocket> in{};
|
||||||
Vector<Vector<ConnectInfo>> show_nodes;
|
std::array<OutSocket, 0> out{};
|
||||||
std::array<OutSocket, 0> out = {};
|
std::array<T_Map<T_Count>::type (*)(const CompositionState&, const GroupOut&), 0> fetch = {};
|
||||||
std::array<T_Map<T_Count>::type (*)(const CompState&, const CompositionOut&), 0> fetch = {};
|
|
||||||
ImVec2 pos;
|
ImVec2 pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -648,18 +646,29 @@ namespace K::Plugboard {
|
||||||
AbsoluteValue,
|
AbsoluteValue,
|
||||||
Interpolation,
|
Interpolation,
|
||||||
Chain,
|
Chain,
|
||||||
CompositionIn,
|
GroupIn,
|
||||||
CompositionOut
|
GroupOut
|
||||||
>;
|
>;
|
||||||
|
|
||||||
struct Plugboard {
|
struct Group {
|
||||||
|
const static char constexpr *name = static_cast<const char*>("Group");
|
||||||
|
Vector<InSocket> in;
|
||||||
|
Vector<OutSocket> out;
|
||||||
|
Vector<T_Map<T_Count>::type (*)(const CompositionState&, const GroupIn&)> fetch;
|
||||||
|
ImVec2 pos;
|
||||||
|
|
||||||
|
GroupIn in_instance;
|
||||||
|
GroupOut out_instance;
|
||||||
|
|
||||||
NodeList nodes; // OK complexity wise since we would usually traverse the entire thing anyway, locality will likely be bad
|
NodeList nodes; // OK complexity wise since we would usually traverse the entire thing anyway, locality will likely be bad
|
||||||
Dict<ConnectInfo, LinksFromSource, ConnectInfoHasher> links_pos; // this is hilariously bad
|
|
||||||
CompositionIn in;
|
|
||||||
CompositionOut out;
|
|
||||||
|
|
||||||
Vector<NodeInstanceP> selected_nodes{};
|
Vector<NodeInstanceP> selected_nodes{};
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Plugboard : Group {
|
||||||
|
Vector<Vector<ConnectInfo>> show_nodes;
|
||||||
|
Plugboard();
|
||||||
|
void AddInSocket(const String& s, Type t);
|
||||||
|
void AddOutSocket(const String& s, Type t, T_Map<T_Count>::type(*fetch)(const CompositionState&, const GroupIn&));
|
||||||
void RecollectChains();
|
void RecollectChains();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -83,5 +83,7 @@ namespace K::Resource {
|
||||||
Resource<T> *Load(const std::filesystem::path& p);
|
Resource<T> *Load(const std::filesystem::path& p);
|
||||||
|
|
||||||
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name);
|
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name);
|
||||||
|
|
||||||
|
void SaveCurrentProject();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ namespace K::UI {
|
||||||
void Init(SDL_Window *window);
|
void Init(SDL_Window *window);
|
||||||
void Draw();
|
void Draw();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void SetupViewport(CompState& s);
|
void SetupViewport(CompositionState& s);
|
||||||
void DestroyViewport(CompState& s);
|
void DestroyViewport(CompositionState& s);
|
||||||
void SetLogoView();
|
void SetLogoView();
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,17 +8,26 @@
|
||||||
#include "Plugboard.h"
|
#include "Plugboard.h"
|
||||||
|
|
||||||
namespace K {
|
namespace K {
|
||||||
|
enum UniformStatus {
|
||||||
|
K_U_Inactive = 0,
|
||||||
|
K_U_Exposed,
|
||||||
|
K_U_SamplerDims,
|
||||||
|
K_U_Count
|
||||||
|
};
|
||||||
|
|
||||||
struct Uniform {
|
struct Uniform {
|
||||||
String name;
|
String name;
|
||||||
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Sampler {
|
struct Sampler {
|
||||||
String name;
|
String name;
|
||||||
bgfx::UniformHandle handle;
|
bgfx::UniformHandle handle;
|
||||||
Resource::Resource<Resource::K_R_Still> *resource;
|
Resource::Resource<Resource::K_R_Still> *resource;
|
||||||
|
Uniform *dims;
|
||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
|
@ -31,13 +40,13 @@ namespace K {
|
||||||
String shader;
|
String shader;
|
||||||
Vector<Uniform> uniforms;
|
Vector<Uniform> uniforms;
|
||||||
Vector<Sampler> samplers;
|
Vector<Sampler> samplers;
|
||||||
void GetFrame(const CompState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16],
|
void GetFrame(const CompositionState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16],
|
||||||
f32 view[16], f32 transform[16]);
|
f32 view[16], f32 transform[16]);
|
||||||
static void ExposeUniform(CompState& s, Uniform& uu);
|
static void ExposeUniform(CompositionState& s, Uniform& uu);
|
||||||
void ExposeUniform(CompState& s, u32 i);
|
void ExposeUniform(CompositionState& s, u32 i);
|
||||||
static void HideUniform(CompState& s, Uniform& uu);
|
static void HideUniform(CompositionState& s, Uniform& uu);
|
||||||
|
|
||||||
void AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val);
|
void AddUniform(const String& s, ShaderGraph::T_Map<ShaderGraph::T_Count>::type&& val, UniformStatus init);
|
||||||
void AddSampler(const String& s);
|
void AddSampler(const String& s);
|
||||||
|
|
||||||
void Compile();
|
void Compile();
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
- [Dear ImGui](https://github.com/ocornut/imgui)
|
- [Dear ImGui](https://github.com/ocornut/imgui)
|
||||||
- [fmt](https://github.com/fmtlib/fmt)
|
- [fmt](https://github.com/fmtlib/fmt)
|
||||||
- [FreeType](https://freetype.org/)
|
- [FreeType](https://freetype.org/)
|
||||||
|
- [Glaze](https://github.com/stephenberry/glaze)
|
||||||
- [imgui_impl_bgfx](https://gist.github.com/pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb)
|
- [imgui_impl_bgfx](https://gist.github.com/pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb)
|
||||||
- [ImPlot](https://github.com/epezent/implot)
|
- [ImPlot](https://github.com/epezent/implot)
|
||||||
- [SDL2](https://www.libsdl.org/)
|
- [SDL2](https://www.libsdl.org/)
|
||||||
|
|
3
TODO.md
3
TODO.md
|
@ -23,8 +23,6 @@
|
||||||
|
|
||||||
# Later
|
# Later
|
||||||
## IO
|
## IO
|
||||||
- File dialogues pending SDL3
|
|
||||||
- https://wiki.libsdl.org/SDL3/CategoryDialog
|
|
||||||
- Clipboard pending SDL3
|
- Clipboard pending SDL3
|
||||||
- OIIO output for more than PNG's
|
- OIIO output for more than PNG's
|
||||||
- don't care about video export -- leave it for ffmpeg
|
- don't care about video export -- leave it for ffmpeg
|
||||||
|
@ -45,4 +43,3 @@
|
||||||
- Wait for SDL3!
|
- Wait for SDL3!
|
||||||
- SDL_mixer will be able to do all of wav ogg flac mp3 opus, we live in good times
|
- SDL_mixer will be able to do all of wav ogg flac mp3 opus, we live in good times
|
||||||
- output needs to be handled differently (if we care at all -- likely not)
|
- output needs to be handled differently (if we care at all -- likely not)
|
||||||
z
|
|
Loading…
Add table
Reference in a new issue