This commit is contained in:
lachrymaLF 2024-05-23 03:18:24 -04:00
parent f0db892b6a
commit 2de32140be
14 changed files with 497 additions and 168 deletions

View file

@ -10,7 +10,7 @@ add_executable (Keishiki
"ext/imgui/imgui_demo.cpp" "ext/imgui/imgui_draw.cpp" "ext/imgui/imgui_tables.cpp" "ext/imgui/imgui_widgets.cpp"
"ext/imgui/misc/cpp/imgui_stdlib.cpp"
"Keishiki.cpp" "Graphics.cpp" "UI.cpp" "ShaderGraph.cpp" "include/ShaderGraph.h" "include/ShaderNodes.h")
"Keishiki.cpp" "Graphics.cpp" "UI.cpp" "ShaderGraph.cpp")
if (CMAKE_VERSION VERSION_GREATER 3.12)
set_property(TARGET Keishiki PROPERTY CXX_STANDARD 20)

View file

@ -20,7 +20,6 @@ namespace {
switch (bgfx::getRendererType()) {
case bgfx::RendererType::Noop:
// case bgfx::RendererType::Direct3D9: shaderPath = "shaders/dx9/"; break;
case bgfx::RendererType::Direct3D11:
case bgfx::RendererType::Direct3D12: shaderPath = "shaders/dx11/"; break;
case bgfx::RendererType::Gnm: shaderPath = "shaders/pssl/"; break;
@ -55,7 +54,7 @@ namespace {
f32 v;
};
static PosUVVertex quad_vert[] =
PosUVVertex quad_vert[] =
{
{ 0.f, 0.f, 0.0f, 0.0f, 0.0f },
{ 0.f, 1.f, 0.0f, 0.0f, 1.0f },
@ -63,7 +62,7 @@ namespace {
{ 1.f, 1.f, 0.0f, 1.0f, 1.0f }
};
static const u16 quad_indices[] =
const u16 quad_indices[] =
{
0, 2, 1,
1, 2, 3
@ -182,7 +181,8 @@ namespace {
}
Font regular, bold;
bgfx::ProgramHandle a_program, imga_program;
bgfx::ProgramHandle imga_program;
bgfx::ProgramHandle a_program;
bgfx::UniformHandle s_texColor;
bgfx::UniformHandle imga_opacity;
@ -192,6 +192,10 @@ namespace {
bgfx::VertexLayout pcvDecl;
Dict<String, ImageTexture> imgs;
f32 composite_view[16];
bgfx::UniformHandle composite_A, composite_B, composite_mode;
bgfx::ProgramHandle composite_pg;
}
namespace K::Graphics {
@ -225,6 +229,11 @@ namespace K::Graphics {
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
mmaker = Graphics::GetImageTextureFromFile("mmaker.png");
bx::mtxTranslate(composite_view, 0.f, 0.f, 1.0f);
composite_A = bgfx::createUniform("v_A", bgfx::UniformType::Sampler);
composite_B = bgfx::createUniform("v_B", bgfx::UniformType::Sampler);
composite_pg = load_shader_program("BinaryComposite");
composite_mode = bgfx::createUniform("f_mode", bgfx::UniformType::Vec4);
return true;
}
@ -246,16 +255,16 @@ namespace K::Graphics {
bgfx::destroy(s_texColor);
bgfx::destroy(imga_opacity);
bgfx::destroy(composite_A);
bgfx::destroy(composite_B);
bgfx::destroy(composite_pg);
bgfx::destroy(composite_mode);
}
// Draws quad with texture on Z = 0
void DrawTexture(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg) {
f32 mtx1[16], mtx2[16], mtx3[16];
bx::mtxTranslate(mtx1, pos_x, pos_y, 0.0f);
bx::mtxScale(mtx2, w, h, 1.0f);
bx::mtxMul(mtx3, mtx2, mtx1);
bgfx::setTransform(mtx3);
void DrawTextureWithTransform(u32 view_id, const bgfx::TextureHandle& tex, f32 mtx[16], u64 state, const bgfx::ProgramHandle& pg) {
bgfx::setTransform(mtx);
bgfx::setVertexBuffer(0, vbh);
bgfx::setIndexBuffer(ibh);
@ -266,8 +275,17 @@ namespace K::Graphics {
bgfx::submit(view_id, pg);
}
void DrawTexture(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg) {
static f32 mtx1[16], mtx2[16], mtx3[16];
bx::mtxTranslate(mtx1, pos_x, pos_y, 0.0f);
bx::mtxScale(mtx2, w, h, 1.0f);
bx::mtxMul(mtx3, mtx2, mtx1);
DrawTextureWithTransform(view_id, tex, mtx3, state, pg);
}
void DrawTextureImageAlpha(u32 view_id, const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha) {
f32 pack[4]{};
static f32 pack[4]{};
pack[0] = alpha;
bgfx::setUniform(imga_opacity, pack);
DrawTexture(view_id, img.tx, pos_x, pos_y, img.w, img.h, (BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS), imga_program);
@ -413,4 +431,25 @@ namespace K::Graphics {
}
return pos_x;
}
void Composite(bgfx::FrameBufferHandle fb, bgfx::TextureHandle composite, bgfx::TextureHandle from, Blending mode, u16 w, u16 h, f32 proj[16], f32 transform[16]) {
static f32 pack[4]{};
pack[0] = static_cast<f32>(mode);
bgfx::touch(K::Graphics::K_VIEW_DRAW);
bgfx::setViewMode(K::Graphics::K_VIEW_DRAW, bgfx::ViewMode::Sequential);
bgfx::setViewClear(K::Graphics::K_VIEW_DRAW, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
bgfx::setViewFrameBuffer(K::Graphics::K_VIEW_COMP_COMPOSITE, fb);
bgfx::setViewTransform(K::Graphics::K_VIEW_COMP_COMPOSITE, composite_view, proj);
bgfx::setViewRect(K::Graphics::K_VIEW_COMP_COMPOSITE, 0, 0, w, h);
bgfx::setTransform(transform);
bgfx::setVertexBuffer(0, vbh);
bgfx::setIndexBuffer(ibh);
bgfx::setTexture(0, composite_A, composite);
bgfx::setTexture(0, composite_B, from);
bgfx::setUniform(composite_mode, pack);
bgfx::setState((BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS));
bgfx::submit(K::Graphics::K_VIEW_COMP_COMPOSITE, composite_pg);
}
}

View file

@ -9,9 +9,8 @@
#include <bgfx/bgfx.h>
#include <bgfx/platform.h>
#include <imgui.h>
#include "backends/imgui_impl_sdl2.h"
#include "imgui_impl_bgfx.h"
#include <imgui.h>
namespace {
SDL_Window* window;
@ -22,13 +21,9 @@ namespace {
bool running = false;
K::CompState state;
bgfx::FrameBufferHandle fb = BGFX_INVALID_HANDLE;
K::Graphics::ImageTexture* mm;
}
namespace K {
const char* BlendingToString[] = { "Normal", "Additive", "Invalid Blending" };
bool Init() {
if (SDL_Init(SDL_INIT_VIDEO)) {
LogError(SDL_GetError());
@ -75,25 +70,14 @@ namespace K {
if (!bgfx::init(bgfxInit)) {
LogError("bgfx initialization failed");
return false;
};
}
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// io.Fonts->AddFontFromFileTTF("SourceHanSans-Regular.ttc", 17);
ImGui_Implbgfx_Init(K::Graphics::K_VIEW_TOP);
bgfx::setDebug(BGFX_DEBUG_TEXT);
bgfx::setViewClear(K::Graphics::K_VIEW_TOP, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x000000ff, 1.0f, 0);
bgfx::setViewRect(K::Graphics::K_VIEW_TOP, 0, 0, window_width, window_height);
#if BX_PLATFORM_WINDOWS
ImGui_ImplSDL2_InitForD3D(window);
#elif BX_PLATFORM_OSX
ImGui_ImplSDL2_InitForMetal(window);
#elif BX_PLATFORM_LINUX || BX_PLATFORM_EMSCRIPTEN
ImGui_ImplSDL2_InitForOpenGL(window, nullptr);
#endif
K::UI::Init(window);
if (!K::Graphics::Init(window_width, window_height)) {
LogError("Graphics init failed");
@ -102,23 +86,13 @@ namespace K {
state.width = 800;
state.height = 600;
fb = bgfx::createFrameBuffer(state.width, state.height, bgfx::TextureFormat::RGBA8);
state.layers.push_back(Layer{
VisualTrack{},
"garfield",
true,
false,
K_V_Normal
});
K::UI::SetupViewport(state);
return true;
}
void Render() {
// ImGui::ShowDemoWindow();
UI::Draw(state, mm, fb);
ImGui::Render();
ImGui_Implbgfx_RenderDrawLists(ImGui::GetDrawData());
UI::Draw(state);
const bgfx::Stats* stat = bgfx::getStats();
bgfx::dbgTextClear();
@ -137,10 +111,6 @@ namespace K {
current_time = SDL_GetTicks64();
delta_t = current_time - last_time;
ImGui_ImplSDL2_NewFrame();
ImGui_Implbgfx_NewFrame();
ImGui::NewFrame();
for (SDL_Event current_event; SDL_PollEvent(&current_event) != 0;) {
ImGui_ImplSDL2_ProcessEvent(&current_event);
if (current_event.type == SDL_QUIT) {
@ -156,11 +126,8 @@ namespace K {
}
void Shutdown() {
bgfx::destroy(fb);
K::Graphics::Shutdown();
ImGui_Implbgfx_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
K::UI::Shutdown(state);
bgfx::shutdown();
SDL_DestroyWindow(window);
SDL_Quit();

View file

@ -5,18 +5,23 @@
#include <imgui.h>
#include <imgui_internal.h>
#include <misc/cpp/imgui_stdlib.h>
#include <fstream>
namespace {
bool draw_viewport = true;
bool draw_sequencer = true;
bool draw_nodes = true;
// Viewport
bgfx::FrameBufferHandle composite_fb = BGFX_INVALID_HANDLE, render_fb = BGFX_INVALID_HANDLE;
K::VisualTrack bg{};
f32 proj[16], transform[16];
}
namespace ImGui {
inline ImTextureID toId(bgfx::TextureHandle _handle, uint8_t _flags, uint8_t _mip)
{
union { struct { bgfx::TextureHandle handle; uint8_t flags; uint8_t mip; } s; ImTextureID id; } tex;
union { struct { bgfx::TextureHandle handle; uint8_t flags; uint8_t mip; } s; ImTextureID id; } tex{};
tex.s.handle = _handle;
tex.s.flags = _flags;
tex.s.mip = _mip;
@ -46,24 +51,74 @@ namespace K::UI {
}
ImGui::EndMainMenuBar();
}
void Viewport(CompState& s, Graphics::ImageTexture* mm, bgfx::FrameBufferHandle fb) {
void SetupViewport(CompState& s) {
composite_fb = bgfx::createFrameBuffer(s.width, s.height, bgfx::TextureFormat::RGBA8);
render_fb = bgfx::createFrameBuffer(s.width, s.height, bgfx::TextureFormat::RGBA8);
bg.pg = K::Graphics::load_shader_program("Checkerboard");
bg.add_uniform("f_hw", ShaderGraph::Type::T_XYZ);
bx::mtxOrtho(proj, 0.0f, static_cast<f32>(s.width), 0.0f, static_cast<f32>(s.height),
0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
f32 mtx1[16], mtx2[16];
bx::mtxTranslate(mtx1, 0, 0, 0.0f);
bx::mtxScale(mtx2, s.width, s.height, 1.0f);
bx::mtxMul(transform, mtx2, mtx1);
}
void DestroyViewport(CompState& s) {
bgfx::destroy(composite_fb);
bgfx::destroy(render_fb);
bgfx::destroy(bg.pg);
bgfx::destroy(bg.uniforms.begin()->second.first);
bg.uniforms.erase(bg.uniforms.begin());
for (auto& layer : s.layers) {
if (bgfx::isValid(layer.track.pg))
bgfx::destroy(layer.track.pg);
for (auto& uniform : layer.track.uniforms) {
bgfx::destroy(uniform.second.first);
}
}
}
void Viewport(CompState& s) {
if (ImGui::Begin("Viewport", &draw_viewport)) {
ImTextureID idx = nullptr;
// If we need new frame
bgfx::TextureHandle composite = bg.get_frame(composite_fb, s.width, s.height);
for (auto& layer : s.layers) {
if (!layer.enabled) continue;
bgfx::TextureHandle tx = layer.track.get_frame(0, mm, fb, s.width, s.height);
idx = ImGui::toId(tx, 0, 0);
Graphics::Composite(composite_fb, composite, layer.track.get_frame(render_fb, s.width, s.height),
&layer == &s.layers.front() ? Graphics::K_V_AlphaOver : layer.mode, s.width, s.height, proj, transform);
}
idx = ImGui::toId(composite, 0, 0);
if (idx != nullptr)
ImGui::Image(idx, ImVec2{ 800, 600 });
ImGui::Image(idx, ImVec2{ static_cast<f32>(s.width), static_cast<f32>(s.height) });
ImGui::Text("Comp Size: %ux%u", s.width, s.height);
}
ImGui::End();
}
void Sequencer(CompState& s){
if (ImGui::Begin("Sequencer", &draw_sequencer)) {
static String name{};
if (ImGui::Button("Add Layer") && !name.empty()) {
s.layers.push_back(Layer{
VisualTrack{},
name,
true,
false,
Graphics::K_V_AlphaOver
});
}
ImGui::SameLine();
ImGui::InputText("##UniformName", &name);
if (ImGui::BeginTable("Layers", 5, ImGuiTableFlags_Borders | ImGuiTableFlags_SizingFixedFit)) {
ImGui::TableSetupColumn("#", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_NoSort);
@ -76,18 +131,19 @@ namespace K::UI {
ImGui::TableNextColumn();
ImGui::Text("%u", i);
ImGui::TableNextColumn();
if (ImGui::Selectable(s.layers[i].name.c_str(), &s.layers[i].selected)) {
s.active = s.layers[i].selected ? &s.layers[i] : nullptr;
// if (s.active != nullptr && ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held
// layers[i].selected = !layers[i].selected;
if (ImGui::Selectable((s.layers[i].name + "##" + std::to_string(i)).c_str(), &s.layers[i].selected)) {
s.active = s.layers[i].selected ? i : -1;
if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held
for (u32 j = 0; j < s.layers.size(); j++)
s.layers[j].selected = j == i && s.layers[j].selected;
}
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(100.0f);
if (ImGui::BeginCombo(("##Blending" + std::to_string(i)).c_str(), BlendingToString[s.layers[i].mode])) {
for (i32 b = K_V_Normal; b != K_V_Count; b++) {
const bool is_selected = ((Blending)b == s.layers[i].mode);
if (ImGui::Selectable(BlendingToString[b], is_selected))
s.layers[i].mode = (Blending)b;
if (ImGui::BeginCombo(("##Blending" + std::to_string(i)).c_str(), Graphics::BlendingToString[s.layers[i].mode])) {
for (i32 b = Graphics::K_V_AlphaOver; b != Graphics::K_V_Count; b++) {
const bool is_selected = (static_cast<Graphics::Blending>(b) == s.layers[i].mode);
if (ImGui::Selectable(Graphics::BlendingToString[b], is_selected))
s.layers[i].mode = static_cast<Graphics::Blending>(b);
if (is_selected)
ImGui::SetItemDefaultFocus();
}
@ -101,6 +157,7 @@ namespace K::UI {
}
ImGui::End();
}
/*void Nodegraph(CompState& s) {
Layer* active = nullptr;
u32 active_index = 0;
@ -246,18 +303,19 @@ namespace K::UI {
}
ImGui::End();
}*/
void Shader(CompState& s) {
if (ImGui::Begin("Shader", &draw_nodes)) {
if (s.active == nullptr)
if (s.active == -1)
ImGui::Text("No active layer.");
else {
static int type_current = 0;
static char text[8] = "";
if (ImGui::Button("Add Uniform") && text[0] != '\0') { // todo LEAK!!
s.active->track.add_uniform(text, ShaderGraph::expand_type(static_cast<ShaderGraph::Type>(type_current)));
static String name{};
if (ImGui::Button("Add Uniform") && !name.empty()) {
s.layers[s.active].track.add_uniform(name, ShaderGraph::expand_type(static_cast<ShaderGraph::Type>(type_current)));
}
ImGui::SameLine();
ImGui::InputText("##UniformName", text, IM_ARRAYSIZE(text));
ImGui::InputText("##UniformName", &name);
ImGui::SameLine();
ImGui::Combo("Type", &type_current, ShaderGraph::Type_To_Str, ShaderGraph::T_Count);
@ -268,7 +326,7 @@ namespace K::UI {
ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_NoSort);
ImGui::TableSetupColumn("##del", ImGuiTableColumnFlags_NoSort);
ImGui::TableHeadersRow();
for (auto it = s.active->track.uniforms.begin(); it != s.active->track.uniforms.end();) {
for (auto it = s.layers[s.active].track.uniforms.begin(); it != s.layers[s.active].track.uniforms.end();) {
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s", it->first.c_str());
@ -286,71 +344,65 @@ namespace K::UI {
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_RGBA>::type>)
ImGui::InputFloat4(("##" + it->first).c_str(), &arg.r);
else if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_XYZ>::type>)
ImGui::InputFloat3(("##" + it->first).c_str(), &arg.x);;
ImGui::InputFloat3(("##" + it->first).c_str(), &arg.x);
}, it->second.second);
ImGui::TableNextColumn();
if (ImGui::Button("Delete Uniform")) {
bgfx::destroy(it->second.first);
it = s.active->track.uniforms.erase(it);
it = s.layers[s.active].track.uniforms.erase(it);
}
else it++;
}
ImGui::EndTable();
}
ImGui::Text("Editing Layer %u: %s", 0, s.active->name.c_str());
ImGuiIO& io = ImGui::GetIO();
ImGui::InputTextMultiline("##source", &s.active->track.shader, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 24), ImGuiInputTextFlags_AllowTabInput);
if (ImGui::Button("Submit Shader")) {
// Compile shader and assign
std::ofstream f("temp.frag");
f << s.active->track.shader;
f.close();
if (std::system(
#if BX_PLATFORM_WINDOWS
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform windows "
"--profile " "ps_5_0" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "dx11" "/temp.frag.bin"
#elif BX_PLATFORM_LINUX
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform windows "
"--profile " "spirv" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "spirv" "/temp.frag.bin"
#elif BX_PLATFORM_OSX
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform osx "
"--profile " "metal" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "metal" "/temp.frag.bin"
#endif
) == 0) {
if (isValid( s.layers[0].track.pg)) bgfx::destroy(s.layers[0].track.pg);
s.layers[0].track.pg = Graphics::load_shader_program("temp"); // todo LEAK!!!
}
else
Log("User shader compilation failed");
}
ImGui::Text("Editing Layer %u: %s", s.active, s.layers[s.active].name.c_str());
ImGui::InputTextMultiline("##source", &s.layers[s.active].track.shader, ImVec2(-FLT_MIN, ImGui::GetTextLineHeight() * 40), ImGuiInputTextFlags_AllowTabInput);
if (ImGui::Button("Submit Shader"))
s.layers[s.active].track.compile();
}
}
ImGui::End();
}
void Draw(CompState& s, Graphics::ImageTexture* mm, bgfx::FrameBufferHandle fb) {
void Draw(CompState& s) {
ImGui_ImplSDL2_NewFrame();
ImGui_Implbgfx_NewFrame();
ImGui::NewFrame();
// ImGui::ShowDemoWindow();
static ImGuiStyle& style = ImGui::GetStyle();
style.GrabRounding = style.FrameRounding = 15.0f;
style.GrabRounding = style.FrameRounding = 5.0f;
MainMenuBar(s);
if (draw_viewport) Viewport(s, mm, fb);
if (draw_viewport) Viewport(s);
if (draw_nodes) Shader(s);
if (draw_sequencer) Sequencer(s);
ImGui::Render();
ImGui_Implbgfx_RenderDrawLists(ImGui::GetDrawData());
}
void Init(SDL_Window* window) {
ImGui::CreateContext();
ImGuiIO& io = ImGui::GetIO();
io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
// io.Fonts->AddFontFromFileTTF("SourceHanSans-Regular.ttc", 17);
ImGui_Implbgfx_Init(K::Graphics::K_VIEW_TOP);
#if BX_PLATFORM_WINDOWS
ImGui_ImplSDL2_InitForD3D(window);
#elif BX_PLATFORM_OSX
ImGui_ImplSDL2_InitForMetal(window);
#elif BX_PLATFORM_LINUX || BX_PLATFORM_EMSCRIPTEN
ImGui_ImplSDL2_InitForVulkan(window);
#endif
}
void Shutdown(CompState& s) {
DestroyViewport(s);
ImGui_Implbgfx_Shutdown();
ImGui_ImplSDL2_Shutdown();
ImGui::DestroyContext();
}
}

View file

@ -8,7 +8,8 @@
namespace K::Graphics {
enum VIEW_ID {
K_VIEW_TOP = 0,
K_VIEW_DRAW = 5
K_VIEW_COMP_COMPOSITE,
K_VIEW_DRAW
};
bool Init(u16 width, u16 height);
@ -23,6 +24,7 @@ namespace K::Graphics {
};
ImageTexture* GetImageTextureFromFile(const std::string& file);
void DrawTextureWithTransform(u32 view_id, const bgfx::TextureHandle& tex, f32 mtx[16], u64 state, const bgfx::ProgramHandle& pg);
void DrawTexture(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h, u64 state, const bgfx::ProgramHandle& pg);
void DrawTextureImageAlpha(u32 view_id, const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha);
void DrawTextureStencilAlpha(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
@ -39,5 +41,86 @@ namespace K::Graphics {
i32 RenderSubstringBox(u32 view_id, const String& s, i32& pos_x, i32& pos_y, i32 reset_x, u32 w, u32 col, size_t s_end = String::npos);
enum Blending {
K_V_AlphaOver = 0,
K_V_Dissolve,
K_V_Add,
K_V_Subtract,
K_V_Difference,
K_V_Exclusion,
K_V_Multiply,
K_V_Divide,
K_V_Lighten,
K_V_Darken,
K_V_LighterColour,
K_V_DarkerColour,
K_V_Screen,
K_V_Overlay,
K_V_HardLight,
K_V_SoftLight,
K_V_VividLight,
K_V_LinearLight,
K_V_ColourBurn,
K_V_LinearBurn,
K_V_ColourDodge,
K_V_LinearDodge,
K_V_Hue,
K_V_Saturation,
K_V_Color,
K_V_Luminosity,
K_V_Count
};
static const char* BlendingToString[] = {
"Alpha Over",
"Dissolve",
"Add",
"Subtract",
"Difference",
"Exclusion",
"Multiply",
"Divide",
"Lighten",
"Darken",
"Lighter Colour",
"Darker Colour",
"Screen",
"Overlay",
"Hard Light",
"Soft Light",
"Vivid Light",
"Linear Light",
"Pin Light",
"Colour Burn",
"Linear Burn",
"Colour Dodge",
"Linear Dodge",
"Hue",
"Saturation",
"Color",
"Luminosity",
"Invalid"
};
void Composite(bgfx::FrameBufferHandle fb, bgfx::TextureHandle composite, bgfx::TextureHandle from, Blending mode, u16 w, u16 h, f32 proj[16], f32 transform[16]);
extern Graphics::ImageTexture* mmaker;
}

View file

@ -9,19 +9,11 @@ namespace K {
void Render();
extern const char* BlendingToString[];
enum Blending {
K_V_Normal = 0,
K_V_Additive,
K_V_Count
};
struct Layer {
VisualTrack track;
String name;
bool enabled, selected;
Blending mode;
Graphics::Blending mode;
};
struct CompState {
@ -30,6 +22,6 @@ namespace K {
u32 fps;
u32 width, height;
Vector<Layer> layers;
Layer* active = nullptr;
i32 active = -1;
};
}

View file

@ -8,6 +8,8 @@
#include "imgui_impl_bgfx.h"
namespace K::UI {
void Draw(CompState& s, Graphics::ImageTexture* mm, bgfx::FrameBufferHandle fb);
void Init(SDL_Window* window);
void Draw(CompState& s);
void Shutdown(CompState& s);
void SetupViewport(CompState& s);
}

View file

@ -4,6 +4,7 @@
#include "ShaderGraph.h"
#include <functional>
#include <bx/math.h>
#include <fstream>
namespace K {
template <typename T>
@ -21,7 +22,8 @@ namespace K {
bgfx::ProgramHandle pg = BGFX_INVALID_HANDLE;
String shader{};
Dict<String, std::pair<bgfx::UniformHandle, ShaderGraph::T_Map<ShaderGraph::T_Count>::type>> uniforms;
bgfx::TextureHandle get_frame(u64 time, Graphics::ImageTexture* mm, bgfx::FrameBufferHandle fb, u32 w, u32 h) const {
// Vector<String> samplers;
bgfx::TextureHandle get_frame(bgfx::FrameBufferHandle fb, u32 w, u32 h) const {
bgfx::touch(K::Graphics::K_VIEW_DRAW);
bgfx::setViewMode(K::Graphics::K_VIEW_DRAW, bgfx::ViewMode::Sequential);
bgfx::setViewClear(K::Graphics::K_VIEW_DRAW, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
@ -66,6 +68,46 @@ namespace K {
if (!uniforms.contains(s))
uniforms.emplace(s, std::make_pair(bgfx::createUniform(s.c_str(), bgfx::UniformType::Vec4), std::move(val)));
}
void compile() {
std::ofstream f("temp.frag");
f << shader;
f.close();
if (std::system(
#if BX_PLATFORM_WINDOWS
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform windows "
"--profile " "ps_5_0" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "dx11" "/temp.frag.bin"
#elif BX_PLATFORM_LINUX
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform windows "
"--profile " "spirv" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "spirv" "/temp.frag.bin"
#elif BX_PLATFORM_OSX
"./ext/bgfx/cmake/bgfx/shaderc "
"-f temp.frag "
"--type fragment "
"--platform osx "
"--profile " "metal" " "
"--varyingdef temp.varying.def.sc "
"-i ./ "
"-o shaders/" "metal" "/temp.frag.bin"
#endif
) == 0) {
if (isValid(pg)) bgfx::destroy(pg);
pg = Graphics::load_shader_program("temp");
}
else
Log("User shader compilation failed");
}
};
void Composite();

View file

@ -1,16 +1,19 @@
import subprocess, os
#SHADERC = "..\\out\\install\\x64-Debug\\bin\\shaderc"
SHADERC = "/Users/lachrymal/Projects/NouVeL/build/ADVect/ext/bgfx/Debug/shaderc"
# SHADERC = "/Users/lachrymal/Projects/NouVeL/build/ADVect/ext/bgfx/Debug/shaderc"
SHADERC = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/ext/bgfx/cmake/bgfx/shaderc"
#OUT = "..\\out\\build\\x64-Debug\\ADVect\\shaders\\"
# OUT = "..\\build\\ADVect\\shaders\\"
OUT = "/Users/lachrymal/Projects/NouVeL/ADVect/runtime/shaders/"
# OUT = "/Users/lachrymal/Projects/NouVeL/ADVect/runtime/shaders/"
OUT = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/shaders/"
I = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/"
P = lambda location, platform, frag, vert: { 'location': location, 'platform': platform, 'frag': frag, 'vert': vert }
plats = [
# P('glsl', 'windows', '140', '140'),
# P('dx11', 'windows', 'ps_5_0', 'vs_5_0'),
# P('spirv', 'windows', 'spirv', 'spirv'),
P('glsl', 'windows', '140', '140'),
# P('dx11', 'windows', 's_5_0', 's_5_0'),
P('spirv', 'windows', 'spirv', 'spirv'),
P('metal', 'osx', 'metal', 'metal')
]
@ -22,15 +25,13 @@ for root, dirs, _ in os.walk('shaders'):
"--platform", config['platform'],
"--profile", config['frag'],
"--varyingdef", os.path.join(root, name, "varying.def.sc"),
"-i", "/Users/lachrymal/Projects/NouVeL/ADVect/ext/bgfx/bgfx/examples/common",
"-i", "/Users/lachrymal/Projects/NouVeL/ADVect/ext/bgfx/bgfx/src",
"-o", OUT + config['location'] + "\\" + name + ".frag.bin"])
"-i", I,
"-o", OUT + config['location'] + "/" + name + ".frag.bin"])
subprocess.run([SHADERC, "-f", os.path.join(root, name, name + '.vert'),
"--type", "vertex",
"--platform", config['platform'],
"--profile", config['vert'],
"--varyingdef", os.path.join(root, name, "varying.def.sc"),
"-i", "/Users/lachrymal/Projects/NouVeL/ADVect/ext/bgfx/bgfx/examples/common",
"-i", "/Users/lachrymal/Projects/NouVeL/ADVect/ext/bgfx/bgfx/src",
"-o", OUT + config['location'] + "\\" + name + ".vert.bin"])
"-i", I,
"-o", OUT + config['location'] + "/" + name + ".vert.bin"])

View file

@ -3,11 +3,149 @@ $input v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
SAMPLER2D(A, 0);
SAMPLER2D(B, 0);
uniform vec4 f_mode;
SAMPLER2D(v_A, 0);
SAMPLER2D(v_B, 0);
void main()
{
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y);
gl_FragColor = texture2D(A, uv) + texture2D(B, uv).a;
vec4 _A = texture2D(v_A, uv);
vec4 _B = texture2D(v_B, uv);
if (f_mode.x == 0.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 1.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 2.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 3.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 4.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 5.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 6.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 7.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 8.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 9.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 10.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 11.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 12.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 13.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 14.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 15.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 16.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 17.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 18.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 19.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 20.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 21.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 22.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 23.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 24.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 25.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
else if (f_mode.x == 26.0f) {
float alpha_b = _A.a * (1.0f - _B.a);
float alpha = _A.a + alpha_b;
gl_FragColor = vec4((_A.rgb * _A.a + _B.rgb * alpha_b)/alpha, alpha);
}
}

View file

@ -0,0 +1,11 @@
$input a_position, a_texcoord0
$output v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
void main()
{
gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0));
v_texcoord0 = a_texcoord0;
}

View file

@ -3,8 +3,12 @@ $input v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
uniform vec4 f_hw;
void main()
{
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) * 100.0f;
gl_FragColor = ceil((uv - floor(uv)) - 0.5f);
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) * 20.0f;
vec2 uvv = ceil(uv- floor(uv) - 0.5f);
float b = 0.8f - mod((uvv.x + uvv.y), 2.0f) * 0.2;
gl_FragColor = vec4(b, b, b, 1.0f);
}

View file

@ -1,6 +1,6 @@
<img src="Keishiki.webp" alt="Logo" width="300"/>
# Keishiki Compositor-Sequencer
# Keishiki: GPU Compositor-Sequencer
## Libraries
- [SDL2](https://www.libsdl.org/)

View file

@ -1,12 +1,10 @@
## Compositor
- BinaryComposite
- Manage Samplers
- Data model for comps
- Dump state, non-POD needs serialization!!!
- Dump and read back state, (de)serialization!!!
## UI
- Sequencer timeline init
- Node editor
- Viewport Gizmos (https://github.com/CedricGuillemet/ImGuizmo)
- Shader nodes (https://github.com/CedricGuillemet/ImGuizmo)