gg blend modes
This commit is contained in:
parent
30735c4f78
commit
facd0d7022
10 changed files with 264 additions and 244 deletions
|
@ -225,10 +225,10 @@ namespace K::Graphics {
|
|||
|
||||
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_A = bgfx::createUniform("s_A", bgfx::UniformType::Sampler);
|
||||
composite_B = bgfx::createUniform("s_B", bgfx::UniformType::Sampler);
|
||||
composite_pg = load_shader_program("BinaryComposite");
|
||||
composite_mode = bgfx::createUniform("f_mode", bgfx::UniformType::Vec4);
|
||||
composite_mode = bgfx::createUniform("u_mode", bgfx::UniformType::Vec4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -427,24 +427,23 @@ 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]) {
|
||||
void Composite(u32 view_id, 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);
|
||||
pack[3] = pack[2] = pack[1] = pack[0] = static_cast<f32>(mode);
|
||||
|
||||
bgfx::touch(K::Graphics::K_VIEW_COMP_COMPOSITE);
|
||||
bgfx::setViewMode(K::Graphics::K_VIEW_COMP_COMPOSITE, bgfx::ViewMode::Sequential);
|
||||
bgfx::setViewClear(K::Graphics::K_VIEW_COMP_COMPOSITE, 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::setViewMode(view_id, bgfx::ViewMode::Sequential);
|
||||
bgfx::setViewClear(view_id, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL);
|
||||
bgfx::setViewFrameBuffer(view_id, fb);
|
||||
bgfx::setViewTransform(view_id, composite_view, proj);
|
||||
bgfx::setViewRect(view_id, 0, 0, w, h);
|
||||
|
||||
bgfx::setTransform(transform);
|
||||
bgfx::setVertexBuffer(0, vbh);
|
||||
bgfx::setIndexBuffer(ibh);
|
||||
bgfx::setTexture(0, composite_A, composite);
|
||||
bgfx::setTexture(1, 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);
|
||||
bgfx::setTexture(0, composite_A, from); // A
|
||||
bgfx::setTexture(1, composite_B, composite); // B
|
||||
bgfx::setUniform(composite_mode, pack); // A over B
|
||||
bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
|
||||
bgfx::submit(view_id, composite_pg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,19 +13,13 @@
|
|||
#include <imgui.h>
|
||||
|
||||
namespace {
|
||||
SDL_Window *window;
|
||||
u16 window_width = 1920;
|
||||
u16 window_height = 1080;
|
||||
|
||||
u64 init_time, last_time, current_time, delta_t;
|
||||
u32 frame;
|
||||
bool running = false;
|
||||
|
||||
K::CompState state;
|
||||
K::Graphics::ImageTexture *logo;
|
||||
}
|
||||
|
||||
namespace K {
|
||||
K::AppState app_state;
|
||||
|
||||
PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type FetchCompFrame(const CompState& s, const PlugboardGraph::NodeInstance& n) {
|
||||
return PlugboardGraph::T_Map<PlugboardGraph::T_Count>::type{static_cast<i32>(s.current_frame)};
|
||||
}
|
||||
|
@ -42,28 +36,28 @@ namespace K {
|
|||
return false;
|
||||
}
|
||||
|
||||
window = SDL_CreateWindow("Keishiki",
|
||||
app_state.window = SDL_CreateWindow("Keishiki",
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
window_width, window_height,
|
||||
app_state.window_width, app_state.window_height,
|
||||
SDL_WINDOW_SHOWN);
|
||||
|
||||
if (window == nullptr) {
|
||||
if (app_state.window == nullptr) {
|
||||
LogError(SDL_GetError());
|
||||
return false;
|
||||
}
|
||||
|
||||
bgfx::Init bgfxInit;
|
||||
bgfxInit.type = bgfx::RendererType::Count; // Automatically choose a renderer.
|
||||
bgfxInit.resolution.width = window_width;
|
||||
bgfxInit.resolution.height = window_height;
|
||||
bgfxInit.resolution.width = app_state.window_width;
|
||||
bgfxInit.resolution.height = app_state.window_height;
|
||||
bgfxInit.resolution.reset = BGFX_RESET_VSYNC;
|
||||
|
||||
|
||||
#if !BX_PLATFORM_EMSCRIPTEN
|
||||
SDL_SysWMinfo wmi;
|
||||
SDL_VERSION(&wmi.version);
|
||||
if (!SDL_GetWindowWMInfo(window, &wmi)) {
|
||||
if (!SDL_GetWindowWMInfo(app_state.window, &wmi)) {
|
||||
LogError(SDL_GetError());
|
||||
}
|
||||
#endif
|
||||
|
@ -85,16 +79,16 @@ namespace K {
|
|||
}
|
||||
|
||||
bgfx::setDebug(BGFX_DEBUG_TEXT);
|
||||
bgfx::setViewRect(K::Graphics::K_VIEW_LOGO, 0, 0, window_width, window_height);
|
||||
bgfx::setViewRect(K::Graphics::K_VIEW_LOGO, 0, 0, app_state.window_width, app_state.window_height);
|
||||
float view[16];
|
||||
bx::mtxTranslate(view, 0.f, 0.f, 1.0f);
|
||||
float proj[16];
|
||||
bx::mtxOrtho(proj, 0.0f, window_width, 0.0f, window_height, 0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
|
||||
bx::mtxOrtho(proj, 0.0f, app_state.window_width, 0.0f, app_state.window_height, 0.1f, 100.0f, 0.f, bgfx::getCaps()->homogeneousDepth);
|
||||
bgfx::setViewTransform(K::Graphics::K_VIEW_LOGO, view, proj);
|
||||
|
||||
K::UI::Init(window);
|
||||
K::UI::Init(app_state.window);
|
||||
|
||||
if (!K::Graphics::Init(window_width, window_height)) {
|
||||
if (!K::Graphics::Init(app_state.window_width, app_state.window_height)) {
|
||||
LogError("Graphics init failed");
|
||||
return false;
|
||||
}
|
||||
|
@ -105,7 +99,7 @@ namespace K {
|
|||
state.height = 550;
|
||||
state.current_frame = 0;
|
||||
state.fps = 30.0f;
|
||||
state.frame_max = 50;
|
||||
state.frame_max = 200;
|
||||
state.plugboard.comp_in = PlugboardGraph::Node{
|
||||
"Composition In",
|
||||
{},
|
||||
|
@ -128,46 +122,47 @@ namespace K {
|
|||
}
|
||||
|
||||
void Render() {
|
||||
K::Graphics::DrawTextureImageAlpha(K::Graphics::K_VIEW_LOGO, *logo, window_width - logo->w + 10, 0, .4f);
|
||||
K::Graphics::DrawTextureImageAlpha(K::Graphics::K_VIEW_LOGO, *logo, app_state.window_width - logo->w + 10, 0, .4f);
|
||||
|
||||
UI::Draw(frame, state);
|
||||
UI::Draw(app_state.bgfx_frame, state);
|
||||
|
||||
const bgfx::Stats *stat = bgfx::getStats();
|
||||
const bgfx::Caps *caps = bgfx::getCaps();
|
||||
bgfx::dbgTextClear();
|
||||
bgfx::dbgTextPrintf(0, window_height/16 - 4, 0xf8,
|
||||
bgfx::dbgTextPrintf(0, app_state.window_height/16 - 4, 0xf8,
|
||||
" lachrymal.net :: %s Renderer :: Max Views %u :: Max FBs %u :: Max Texture Samplers %u :: Blitting %s :: %u FPS",
|
||||
caps->supported & BGFX_CAPS_RENDERER_MULTITHREADED ? "Multithreaded" : "Singlethreaded",
|
||||
caps->limits.maxViews, caps->limits.maxFrameBuffers,
|
||||
caps->limits.maxTextureSamplers, caps->supported & BGFX_CAPS_TEXTURE_BLIT ? "OK" : "NO",
|
||||
stat->cpuTimerFreq / stat->cpuTimeFrame);
|
||||
bgfx::dbgTextPrintf(0, window_height/16 - 3, 0xf8,
|
||||
bgfx::dbgTextPrintf(0, app_state.window_height/16 - 3, 0xf8,
|
||||
" Project Keishiki :: %s :: Build %s %s :: SDL %i.%i.%i :: bgfx 1.%i :: Dear ImGui %s :: %s",
|
||||
BX_COMPILER_NAME, __DATE__, __TIME__, SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL,
|
||||
BGFX_API_VERSION, ImGui::GetVersion(), bgfx::getRendererName(bgfx::getRendererType()));
|
||||
|
||||
frame = bgfx::frame();
|
||||
app_state.bgfx_frame = bgfx::frame();
|
||||
}
|
||||
|
||||
void Run() {
|
||||
last_time = init_time = SDL_GetTicks64();
|
||||
app_state.init_time = SDL_GetTicks64();
|
||||
app_state.last_time = app_state.init_time;
|
||||
|
||||
running = true;
|
||||
while (running) {
|
||||
current_time = SDL_GetTicks64();
|
||||
delta_t = current_time - last_time;
|
||||
app_state.running = true;
|
||||
while (app_state.running) {
|
||||
app_state.current_time = SDL_GetTicks64();
|
||||
app_state.delta_t = app_state.current_time - app_state.last_time;
|
||||
|
||||
for (SDL_Event current_event; SDL_PollEvent(¤t_event) != 0;) {
|
||||
ImGui_ImplSDL2_ProcessEvent(¤t_event);
|
||||
if (current_event.type == SDL_QUIT) {
|
||||
running = false;
|
||||
app_state.running = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Render();
|
||||
|
||||
last_time = current_time;
|
||||
app_state.last_time = app_state.current_time;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,7 +170,7 @@ namespace K {
|
|||
K::Graphics::Shutdown();
|
||||
K::UI::Shutdown(state);
|
||||
bgfx::shutdown();
|
||||
SDL_DestroyWindow(window);
|
||||
SDL_DestroyWindow(app_state.window);
|
||||
SDL_Quit();
|
||||
}
|
||||
}
|
||||
|
|
182
Keishiki/UI.cpp
182
Keishiki/UI.cpp
|
@ -29,11 +29,12 @@ namespace {
|
|||
const f32 row_height = 20.0f;
|
||||
|
||||
// Viewport
|
||||
bgfx::TextureHandle composite = BGFX_INVALID_HANDLE,
|
||||
composite_blit = BGFX_INVALID_HANDLE,
|
||||
bool playing;
|
||||
u64 last_frame_tick;
|
||||
bgfx::TextureHandle composite[2] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE },
|
||||
render = BGFX_INVALID_HANDLE,
|
||||
save = BGFX_INVALID_HANDLE;
|
||||
bgfx::FrameBufferHandle composite_fb = BGFX_INVALID_HANDLE,
|
||||
bgfx::FrameBufferHandle composite_fb[2] = { BGFX_INVALID_HANDLE, BGFX_INVALID_HANDLE },
|
||||
render_fb = BGFX_INVALID_HANDLE;
|
||||
K::VisualTrack bg{};
|
||||
f32 proj[16], transform[16], view[16];
|
||||
|
@ -55,6 +56,53 @@ namespace ImGui {
|
|||
}
|
||||
|
||||
namespace K::UI {
|
||||
|
||||
void AddTransformLayer(CompState& s, const std::string& name) {
|
||||
auto l = Layer{
|
||||
VisualTrack{},
|
||||
name,
|
||||
Graphics::K_V_AlphaOver,
|
||||
0UL,
|
||||
s.frame_max
|
||||
};
|
||||
l.track.add_uniform("aspect_ratio", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
if (s.width > s.height)
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(static_cast<f32>(s.width)/static_cast<f32>(s.height), 1.0f);
|
||||
else
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, static_cast<f32>(s.height)/static_cast<f32>(s.width));
|
||||
|
||||
l.track.add_uniform("opacity", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["opacity"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
||||
|
||||
l.track.add_uniform("rot", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["rot"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
||||
|
||||
l.track.add_uniform("scale", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["scale"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, 1.0f);
|
||||
|
||||
l.track.add_uniform("translate", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["translate"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(.0f, .0f);
|
||||
|
||||
l.track.shader = "void main() {\n"
|
||||
"\tfloat angle = -rot * M_PI / 180.0f;\n"
|
||||
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
|
||||
"\tuv = uv * aspect_ratio;\n"
|
||||
"\tuv = uv - translate;\n"
|
||||
"\tuv = vec2(cos(angle)*uv.x - sin(angle)*uv.y, sin(angle)*uv.x + cos(angle)*uv.y);\n"
|
||||
"\tuv = uv / scale;\n"
|
||||
"\tuv = uv + .5f;\n\n"
|
||||
"\tvec4 tx = texture2D(s_texColor, uv);\n"
|
||||
"\tgl_FragColor = vec4(tx.rgb, tx.a * opacity);\n"
|
||||
"}\n";
|
||||
l.track.compile();
|
||||
l.track.expose_uniform(s, "aspect_ratio");
|
||||
l.track.expose_uniform(s, "opacity");
|
||||
l.track.expose_uniform(s, "rot");
|
||||
l.track.expose_uniform(s, "scale");
|
||||
l.track.expose_uniform(s, "translate");
|
||||
s.layers.push_back(std::move(l));
|
||||
}
|
||||
|
||||
void MainMenuBar(const CompState& s) {
|
||||
if (ImGui::BeginMainMenuBar()) {
|
||||
if (ImGui::BeginMenu("Edit")) {
|
||||
|
@ -78,13 +126,15 @@ namespace K::UI {
|
|||
}
|
||||
|
||||
void SetupViewport(CompState& s) {
|
||||
composite = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
||||
composite_blit = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_BLIT_DST);
|
||||
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);
|
||||
render = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_RT);
|
||||
bgfx::Attachment comp{}, ren{};
|
||||
comp.init(composite, bgfx::Access::Write); // DX 11 requires Write only
|
||||
bgfx::Attachment comp{}, comp2{}, ren{};
|
||||
comp.init(composite[0], bgfx::Access::Write); // DX 11 requires Write only
|
||||
comp2.init(composite[1], bgfx::Access::Write); // DX 11 requires Write only
|
||||
ren.init(render, bgfx::Access::ReadWrite);
|
||||
composite_fb = bgfx::createFrameBuffer(1, &comp);
|
||||
composite_fb[0] = bgfx::createFrameBuffer(1, &comp);
|
||||
composite_fb[1] = bgfx::createFrameBuffer(1, &comp2);
|
||||
render_fb = bgfx::createFrameBuffer(1, &ren);
|
||||
|
||||
save = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK | BGFX_TEXTURE_BLIT_DST);
|
||||
|
@ -104,9 +154,10 @@ namespace K::UI {
|
|||
}
|
||||
|
||||
void DestroyViewport(CompState& s) {
|
||||
bgfx::destroy(composite_fb);
|
||||
bgfx::destroy(composite);
|
||||
bgfx::destroy(composite_blit);
|
||||
bgfx::destroy(composite_fb[0]);
|
||||
bgfx::destroy(composite_fb[1]);
|
||||
bgfx::destroy(composite[0]);
|
||||
bgfx::destroy(composite[1]);
|
||||
bgfx::destroy(render_fb);
|
||||
bgfx::destroy(render);
|
||||
|
||||
|
@ -268,29 +319,64 @@ namespace K::UI {
|
|||
}
|
||||
|
||||
void Viewport(CompState& s) {
|
||||
if (ImGui::Begin("Viewport", &draw_viewport)) {
|
||||
ImTextureID idx;
|
||||
if (playing) {
|
||||
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 frames_passed = delta / (1000.0f / s.fps);
|
||||
s.current_frame = (s.current_frame + static_cast<u64>(std::floor(frames_passed))) % (s.frame_max + 1);
|
||||
last_frame_tick = app_state.current_time - static_cast<u64>(std::fmod(delta, 1000.0f / s.fps));
|
||||
}
|
||||
}
|
||||
|
||||
if (ImGui::Begin("Viewport", &draw_viewport)) {
|
||||
u32 view_count = 0, layers_done = 0;
|
||||
bgfx::setViewFrameBuffer(Graphics::K_VIEW_COMP_COMPOSITE + view_count, composite_fb[0]); // the other fb will be cleared in composite
|
||||
bgfx::setViewClear(Graphics::K_VIEW_COMP_COMPOSITE + view_count, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL, 0x00000000);
|
||||
bgfx::setViewRect(Graphics::K_VIEW_COMP_COMPOSITE + view_count, 0, 0, s.width, s.height);
|
||||
bgfx::touch(Graphics::K_VIEW_COMP_COMPOSITE + view_count);
|
||||
view_count++;
|
||||
|
||||
bg.get_frame(s, composite_fb, s.width, s.height, proj, view, transform);
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_COMPOSITE, composite_blit, 0, 0, composite);
|
||||
for (u32 i = s.layers.size() - 1; i != u32(-1); i--) {
|
||||
if (s.disabled.contains(i)) continue;
|
||||
if (s.current_frame > s.layers[i].out || s.current_frame < s.layers[i].in) continue;
|
||||
Graphics::Composite( composite_fb, composite_blit, s.layers[i].track.get_frame(s, render_fb, s.width, s.height, proj, view, transform),
|
||||
i == s.layers.size() - 1 ? Graphics::K_V_AlphaOver : s.layers[i].mode, s.width, s.height, proj, transform);
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_COMPOSITE, composite_blit, 0, 0, composite);
|
||||
|
||||
s.layers[i].track.get_frame(s, Graphics::K_VIEW_COMP_COMPOSITE + view_count++, render_fb, s.width, s.height, proj, view, transform);
|
||||
Graphics::Composite(Graphics::K_VIEW_COMP_COMPOSITE + view_count++, composite_fb[(layers_done + 1) % 2], composite[layers_done % 2], render, s.layers[i].mode, s.width, s.height, proj, transform);
|
||||
layers_done++;
|
||||
}
|
||||
idx = ImGui::toId(composite, 0, 0);
|
||||
if (layers_done != 0) {
|
||||
bg.get_frame(s, Graphics::K_VIEW_COMP_COMPOSITE + view_count++, render_fb, s.width, s.height, proj, view,
|
||||
transform);
|
||||
Graphics::Composite(Graphics::K_VIEW_COMP_COMPOSITE + view_count++, composite_fb[(layers_done + 1) % 2],
|
||||
render, composite[layers_done % 2], Graphics::K_V_AlphaOver, s.width, s.height,
|
||||
proj, transform);
|
||||
layers_done++;
|
||||
}
|
||||
else {
|
||||
bg.get_frame(s, Graphics::K_VIEW_COMP_COMPOSITE + view_count++, composite_fb[0], s.width, s.height, proj, view,
|
||||
transform);
|
||||
}
|
||||
|
||||
Vector<bgfx::ViewId> views;
|
||||
for (u32 i = 0; i < view_count; i++)
|
||||
views.push_back(Graphics::K_VIEW_COMP_COMPOSITE + i);
|
||||
views.push_back(Graphics::K_VIEW_COMP_SAVE);
|
||||
views.push_back(Graphics::K_VIEW_UI);
|
||||
views.push_back(Graphics::K_VIEW_LOGO);
|
||||
bgfx::setViewOrder(0, views.size(), views.data());
|
||||
|
||||
ImTextureID idx = ImGui::toId(composite[layers_done % 2], 0, 0);
|
||||
if (idx != nullptr)
|
||||
ImGui::Image(idx, ImVec2{ static_cast<f32>(s.width), static_cast<f32>(s.height) });
|
||||
|
||||
ImGui::Text("Composition Size: %ux%u", s.width, s.height);
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::DragFloat("FPS", &s.fps, 1.0f, 1.0f, 120.0f);
|
||||
ImGui::SameLine();
|
||||
|
||||
ImGui::BeginDisabled(save_called);
|
||||
if (ImGui::Button("Save to frame.png")) {
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_SAVE, save, 0, 0, composite);
|
||||
bgfx::blit(Graphics::K_VIEW_COMP_SAVE, save, 0, 0, composite[layers_done % 2]);
|
||||
ready_frame = bgfx::readTexture(save, save_buffer);
|
||||
save_called = true;
|
||||
}
|
||||
|
@ -339,6 +425,13 @@ namespace K::UI {
|
|||
ImGui::EndCombo();
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
bool playing_cp = playing;
|
||||
ImGui::Checkbox("Playing", &playing);
|
||||
if (!playing_cp && playing) {
|
||||
last_frame_tick = app_state.current_time;
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("%lu / %lu Frames", s.current_frame, s.frame_max);
|
||||
ImGui::SameLine();
|
||||
|
@ -347,49 +440,7 @@ namespace K::UI {
|
|||
|
||||
static String name{};
|
||||
if (ImGui::Button("Add Layer") && !name.empty()) {
|
||||
auto l = Layer{
|
||||
VisualTrack{},
|
||||
name,
|
||||
Graphics::K_V_AlphaOver,
|
||||
0UL,
|
||||
s.frame_max
|
||||
};
|
||||
l.track.add_uniform("aspect_ratio", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
if (s.width > s.height)
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(static_cast<f32>(s.width)/static_cast<f32>(s.height), 1.0f);
|
||||
else
|
||||
l.track.uniforms["aspect_ratio"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, static_cast<f32>(s.height)/static_cast<f32>(s.width));
|
||||
|
||||
l.track.add_uniform("opacity", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["opacity"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(1.0f);
|
||||
|
||||
l.track.add_uniform("rot", ShaderGraph::expand_type(ShaderGraph::T_Float));
|
||||
l.track.uniforms["rot"].val = ShaderGraph::T_Map<ShaderGraph::T_Float>::type(.0f);
|
||||
|
||||
l.track.add_uniform("scale", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["scale"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(1.0f, 1.0f);
|
||||
|
||||
l.track.add_uniform("translate", ShaderGraph::expand_type(ShaderGraph::T_XY));
|
||||
l.track.uniforms["translate"].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type(.0f, .0f);
|
||||
|
||||
l.track.shader = "void main() {\n"
|
||||
"\tfloat angle = -rot * M_PI / 180.0f;\n"
|
||||
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
|
||||
"\tuv = uv * aspect_ratio;\n"
|
||||
"\tuv = uv - translate;\n"
|
||||
"\tuv = vec2(cos(angle)*uv.x - sin(angle)*uv.y, sin(angle)*uv.x + cos(angle)*uv.y);\n"
|
||||
"\tuv = uv / scale;\n"
|
||||
"\tuv = uv + .5f;\n\n"
|
||||
"\tvec4 tx = texture2D(s_texColor, uv);\n"
|
||||
"\tgl_FragColor = vec4(tx.rgb, tx.a * opacity);\n"
|
||||
"}\n";
|
||||
l.track.compile();
|
||||
l.track.expose_uniform(s, "aspect_ratio");
|
||||
l.track.expose_uniform(s, "opacity");
|
||||
l.track.expose_uniform(s, "rot");
|
||||
l.track.expose_uniform(s, "scale");
|
||||
l.track.expose_uniform(s, "translate");
|
||||
s.layers.push_back(std::move(l));
|
||||
AddTransformLayer(s, name);
|
||||
}
|
||||
ImGui::SameLine();
|
||||
ImGui::SetNextItemWidth(-100.0f);
|
||||
|
@ -869,7 +920,8 @@ namespace K::UI {
|
|||
f32 x = i.begin + (i.end - i.begin) * static_cast<f32>(idx) / static_cast<f32>(i.samples);
|
||||
CompState ss = i.s;
|
||||
ss.current_frame = static_cast<u64>(std::round(x));
|
||||
return {x, std::get<PlugboardGraph::T_Map<PlugboardGraph::T_Float>::type>(PlugboardGraph::Eval(ss, i.connected_v))};
|
||||
bool good;
|
||||
return {x, std::get<PlugboardGraph::T_Map<PlugboardGraph::T_Float>::type>(PlugboardGraph::ConvertValue(PlugboardGraph::Eval(ss, i.connected_v), PlugboardGraph::T_Float, good))};
|
||||
}, &info, info.samples);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
|
|
|
@ -36,15 +36,13 @@ namespace K {
|
|||
},val);
|
||||
}
|
||||
|
||||
bgfx::TextureHandle
|
||||
VisualTrack::get_frame(const CompState& s, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 *proj, f32 *view, f32 *transform) const {
|
||||
bgfx::touch(K::Graphics::K_VIEW_COMP_COMPOSITE);
|
||||
bgfx::setViewMode(K::Graphics::K_VIEW_COMP_COMPOSITE, bgfx::ViewMode::Sequential);
|
||||
bgfx::setViewClear(K::Graphics::K_VIEW_COMP_COMPOSITE, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH, 0x00000000, 1.0f, 0);
|
||||
bgfx::setViewFrameBuffer(K::Graphics::K_VIEW_COMP_COMPOSITE, fb);
|
||||
void VisualTrack::get_frame(const CompState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 *proj, f32 *view, f32 *transform) const {
|
||||
bgfx::setViewMode(view_id, bgfx::ViewMode::Sequential);
|
||||
bgfx::setViewClear(view_id, BGFX_CLEAR_COLOR | BGFX_CLEAR_DEPTH | BGFX_CLEAR_STENCIL);
|
||||
bgfx::setViewFrameBuffer(view_id, fb);
|
||||
|
||||
bgfx::setViewTransform(K::Graphics::K_VIEW_COMP_COMPOSITE, view, proj);
|
||||
bgfx::setViewRect(K::Graphics::K_VIEW_COMP_COMPOSITE, 0, 0, w, h);
|
||||
bgfx::setViewTransform(view_id, view, proj);
|
||||
bgfx::setViewRect(view_id, 0, 0, w, h);
|
||||
|
||||
for (auto& [_name, u] : uniforms) {
|
||||
f32 pack[4]{};
|
||||
|
@ -87,10 +85,8 @@ namespace K {
|
|||
bgfx::setUniform(u.handle, pack);
|
||||
}
|
||||
|
||||
Graphics::DrawTextureWithTransform(K::Graphics::K_VIEW_COMP_COMPOSITE, Graphics::mmaker->tx, transform,
|
||||
(BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) &
|
||||
~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS), pg);
|
||||
return bgfx::getTexture(fb);
|
||||
Graphics::DrawTextureWithTransform(view_id, Graphics::mmaker->tx, transform,
|
||||
BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A, pg);
|
||||
}
|
||||
|
||||
void VisualTrack::compile() {
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
namespace K::Graphics {
|
||||
enum VIEW_ID {
|
||||
K_VIEW_COMP_COMPOSITE,
|
||||
K_VIEW_COMP_SAVE,
|
||||
K_VIEW_DRAW,
|
||||
K_VIEW_UI,
|
||||
K_VIEW_LOGO,
|
||||
|
||||
K_VIEW_COMP_COMPOSITE, // Remember to call setViewOrder!
|
||||
};
|
||||
|
||||
bool Init(u16 width, u16 height);
|
||||
|
@ -120,7 +120,7 @@ namespace K::Graphics {
|
|||
"Invalid"
|
||||
};
|
||||
|
||||
void Composite(bgfx::FrameBufferHandle fb, bgfx::TextureHandle composite, bgfx::TextureHandle from, Blending mode, u16 w, u16 h, f32 proj[16], f32 transform[16]);
|
||||
void Composite(u32 view_id, 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;
|
||||
}
|
||||
|
|
|
@ -34,4 +34,14 @@ namespace K {
|
|||
|
||||
PlugboardGraph::PlugboardGraph plugboard;
|
||||
};
|
||||
|
||||
extern struct AppState {
|
||||
SDL_Window *window = nullptr;
|
||||
u16 window_width = 1920;
|
||||
u16 window_height = 1080;
|
||||
|
||||
u64 init_time{}, last_time{}, current_time{}, delta_t{};
|
||||
u32 bgfx_frame{};
|
||||
bool running = false;
|
||||
} app_state; // global !
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ namespace K {
|
|||
String shader;
|
||||
Dict<String, Uniform> uniforms;
|
||||
// Vector<String> samplers;
|
||||
bgfx::TextureHandle get_frame(const CompState& s, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16], f32 view[16], f32 transform[16]) const;
|
||||
void get_frame(const CompState& s, u32 view_id, bgfx::FrameBufferHandle fb, u32 w, u32 h, f32 proj[16], f32 view[16], f32 transform[16]) const;
|
||||
void expose_uniform(CompState& s, const String& u);
|
||||
void hide_uniform(CompState& s, const String& u);
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ P = lambda location, platform, frag, vert: { 'location': location, 'platform': p
|
|||
plats = [
|
||||
P('glsl', 'windows', '140', '140'),
|
||||
# P('dx11', 'windows', 's_5_0', 's_5_0'),
|
||||
P('spirv', 'windows', 'spirv', 'spirv'),
|
||||
P('spirv', 'linux', 'spirv', 'spirv'),
|
||||
P('metal', 'osx', 'metal', 'metal')
|
||||
]
|
||||
|
||||
|
|
|
@ -1,146 +1,113 @@
|
|||
/* Reference: https://drafts.fxtf.org/compositing-1 */
|
||||
|
||||
$input v_texcoord0
|
||||
|
||||
#include <bgfx_shader.sh>
|
||||
#include <shaderlib.sh>
|
||||
|
||||
uniform vec4 f_mode;
|
||||
SAMPLER2D(v_A, 0);
|
||||
SAMPLER2D(v_B, 1);
|
||||
uniform vec4 u_mode;
|
||||
SAMPLER2D(s_A, 0);
|
||||
SAMPLER2D(s_B, 1);
|
||||
|
||||
void main()
|
||||
{
|
||||
void main() {
|
||||
vec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y);
|
||||
vec4 _A = texture2D(v_A, uv);
|
||||
vec4 _B = texture2D(v_B, uv);
|
||||
vec4 _A = texture2D(s_A, uv);
|
||||
vec4 _B = texture2D(s_B, uv);
|
||||
// Premult
|
||||
_A.xyz = _A.xyz * _A.w;
|
||||
_B.xyz = _B.xyz * _B.w;
|
||||
|
||||
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);
|
||||
// Porter-Duff Source Over
|
||||
gl_FragColor.w = _A.w + _B.w * (1 - _A.w);
|
||||
vec3 blend = vec3(0.0f, 0.0f, 0.0f);
|
||||
|
||||
int mode = round(u_mode.x);
|
||||
|
||||
if (mode == 0) { // Normal
|
||||
blend = _A.xyz;
|
||||
}
|
||||
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 (mode == 1) { // Dissolve
|
||||
blend = _A.w > random(uv) ? _A.xyz : _B.xyz;
|
||||
}
|
||||
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 (mode == 2) { // Add
|
||||
blend = _A.xyz + _B.xyz;
|
||||
}
|
||||
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 (mode == 3) { // Subtract
|
||||
blend = _A.xyz - _B.xyz;
|
||||
}
|
||||
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 (mode == 4) { // Difference
|
||||
blend = abs(_A.xyz - _B.xyz);
|
||||
}
|
||||
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 (mode == 5) { // Exclusion
|
||||
blend = _B.xyz + _A.xyz - 2.0f * _B.xyz * _A.xyz;
|
||||
}
|
||||
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 (mode == 6) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 7) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 8) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 9) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 10) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 11) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 12) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 13) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 14) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 15) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 16) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 17) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 18) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 19) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 20) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 21) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 22) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 23) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 24) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
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 (mode == 25) {
|
||||
gl_FragColor = vec4(50.0f, 0.0f, 0.0f, 1.0f);
|
||||
}
|
||||
else {
|
||||
gl_FragColor = vec4(uv, 0.0f, 1.0f);
|
||||
}
|
||||
|
||||
// Porter-Duff Source Over
|
||||
gl_FragColor.xyz = blend + _B.xyz * (1.0f - _A.w);
|
||||
|
||||
// Unmult
|
||||
gl_FragColor.xyz = gl_FragColor.xyz / gl_FragColor.w;
|
||||
}
|
||||
|
|
7
TODO.md
7
TODO.md
|
@ -4,22 +4,23 @@
|
|||
- Node groups
|
||||
|
||||
## Compositor
|
||||
- Playback...
|
||||
- Manage Samplers -- (Resources in general)
|
||||
- Blender previews (important !)
|
||||
- Data model for comps
|
||||
- Dump and read back state, (de)serialization!!!
|
||||
- Non-negotiables:
|
||||
- Text (idea: index-based evaluation in plugboard)
|
||||
- Shapes (idea: embed glisp :mmtroll:, need to inquire -- still a lot of friction for simple shapes if we don't also get the glisp gizmos)
|
||||
- External data driving (csv, json or something else?) -- use a node to select source
|
||||
- Pre-compose/Layer Groups (jokes -- can be completely UI side)
|
||||
- Data model for comps
|
||||
- Pre-compose/Layer Groups (jokes -- can be completely UI side)
|
||||
- Motion blur
|
||||
|
||||
## UI
|
||||
- Viewport gizmos (Layer-specific & nodes -- can separate into different tools?) -- Not sure how to go about this
|
||||
- Node loop detection (separate DFS (extra work) or be smart in recursion)
|
||||
- detect time-sensitive nodes in tree and display on timeline
|
||||
- Key selection in comp panel
|
||||
- Graph editor
|
||||
|
||||
# Later
|
||||
## Compositor
|
||||
|
|
Loading…
Add table
Reference in a new issue