Compare commits

...

10 commits

Author SHA1 Message Date
ad73f0c921 screenshot 2025-01-23 22:44:52 -05:00
327193c503 need python to run shader script 2025-01-23 22:33:12 -05:00
2601de3266 d 2024-11-02 14:55:46 -04:00
2921e053f9 d 2024-08-13 16:07:57 -04:00
09845b2286 d 2024-08-13 16:05:45 -04:00
e2b00e429d d 2024-08-13 16:04:13 -04:00
f544498298 asd 2024-08-13 16:03:48 -04:00
lachrymaLF
b5fea1184b d 2024-08-13 16:03:08 -04:00
lachrymaLF
63ab0724a1 d 2024-08-13 16:02:30 -04:00
fc6e4ef50f asd 2024-08-13 01:17:10 -04:00
27 changed files with 577 additions and 421 deletions

1
.gitignore vendored
View file

@ -3,3 +3,4 @@ out
.idea
cmake-build-debug
build
**/.DS_Store

6
.gitmodules vendored
View file

@ -17,9 +17,9 @@
[submodule "Keishiki/ext/fmt"]
path = Keishiki/ext/fmt
url = https://github.com/fmtlib/fmt.git
[submodule "Keishiki/ext/glaze"]
path = Keishiki/ext/glaze
url = https://github.com/stephenberry/glaze.git
[submodule "Keishiki/ext/vg-renderer"]
path = Keishiki/ext/vg-renderer
url = https://github.com/jdryg/vg-renderer.git
[submodule "Keishiiki/ext/SDL"]
path = Keishiki/ext/SDL
url = https://github.com/libsdl-org/SDL.git

51
Keishiki/Actions.cpp Normal file
View file

@ -0,0 +1,51 @@
#include <Actions.h>
#include <VisualTrack.h>
namespace K {
void AddTransformLayer(CompositionState& s, const String& name) {
auto l = Layer{
VisualTrack{},
name,
Graphics::K_V_AlphaOver,
0UL,
s.frame_max
};
l.track.AddUniform("u_resolution", ShaderGraph::ExpandVariant(ShaderGraph::T_XY), K_U_Exposed);
l.track.uniforms[0].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{static_cast<f32>(s.width), static_cast<f32>(s.height)};
VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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);
VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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);
VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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};
VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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};
VisualTrack::ExposeUniform(s, l.track.uniforms.back());
l.track.shader = "void main() {\n"
"\tfloat angle = -u_rot * M_PI / 180.0f;\n"
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
"\tuv = uv * u_resolution;\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 = uv / s_texColor_dims;\n"
"\tuv = uv / u_scale;\n"
"\tuv = uv + .5f;\n\n"
"\tvec4 tx = texture2D(s_texColor, uv);\n"
"\tgl_FragColor = vec4(tx.rgb, tx.a * u_opacity);\n"
"}\n";
l.track.AddSampler("s_texColor");
l.track.Compile();
s.layers.push_back(std::move(l));
}
}

View file

@ -1,4 +1,4 @@
# CMakeList.txt : CMake project for Keishiki, include source and define
# CMakeList.txt : CMake project for Keishiki, include source and define
# project specific logic here.
#
cmake_minimum_required (VERSION 3.16)
@ -20,9 +20,7 @@ include_directories ("include" "include/ext" "ext/imgui" "ext/implot" "ext/plf_c
add_subdirectory("ext/SDL")
add_subdirectory("ext/fmt")
# add_subdirectory("ext/glaze")
# add_subdirectory("ext/freetype")
# add_compile_definitions(WL_EGL_PLATFORM)
add_subdirectory("ext/bgfx")
add_compile_definitions(IMGUI_DEFINE_MATH_OPERATORS)
@ -41,11 +39,7 @@ if (WIN32)
include_directories("include/windows")
target_link_libraries (Keishiki PRIVATE freetype bgfx bx ${PROJECT_SOURCE_DIR}/lib/x64/SDL2.lib ${PROJECT_SOURCE_DIR}/lib/x64/SDL2main.lib)
elseif (APPLE)
target_link_libraries (Keishiki PRIVATE freetype bgfx bx SDL3::SDL3 fmt glaze_glaze)
target_link_libraries (Keishiki PRIVATE bgfx bx SDL3::SDL3 fmt)
else ()
find_package(SDL3 REQUIRED CONFIG REQUIRED COMPONENTS SDL3-shared)
find_package(ECM REQUIRED NO_MODULE)
set(CMAKE_MODULE_PATH ${ECM_FIND_MODULE_DIR})
find_package(Wayland REQUIRED Egl)
target_link_libraries (Keishiki PRIVATE freetype bgfx bx SDL3::SDL3 ${Wayland_LIBRARIES} fmt glaze_glaze)
target_link_libraries (Keishiki PRIVATE bgfx bx SDL3::SDL3 fmt)
endif ()

View file

@ -2,11 +2,8 @@
#include "Graphics.h"
#include "UI.h"
#if BX_PLATFORM_LINUX && WL_EGL_PLATFORM
#include <wayland-egl.h>
#endif
#include <SDL3/SDL.h>
#include <SDL3/SDL_main.h>
#include <SDL3/SDL_timer.h>
#include <bgfx/bgfx.h>
@ -16,17 +13,20 @@
#include <imgui.h>
namespace K {
constexpr auto RESET_FLAGS = BGFX_RESET_VSYNC | BGFX_RESET_HIDPI;
bool Init() {
#if BX_PLATFORM_LINUX && !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());
return false;
}
app_state.window = SDL_CreateWindow("Keishiki", app_state.window_width, app_state.window_height, SDL_WINDOW_HIGH_PIXEL_DENSITY);
if (app_state.window == nullptr) {
Log(K_L_Error, "{}", SDL_GetError());
return false;
}
SDL_SetWindowResizable(app_state.window, true);
i32 display_n;
SDL_DisplayID *ids = SDL_GetDisplays(&display_n);
@ -34,36 +34,31 @@ namespace K {
SDL_free(ids);
app_state.window_width *= app_state.dpi_scale;
app_state.window_height *= app_state.dpi_scale;
if (app_state.window == nullptr) {
Log(K_L_Error, "{}", SDL_GetError());
return false;
}
bgfx::Init bgfxInit;
bgfxInit.type = bgfx::RendererType::Count; // Automatically choose a renderer.
bgfxInit.resolution.width = app_state.window_width;
bgfxInit.resolution.height = app_state.window_height;
bgfxInit.resolution.reset = BGFX_RESET_VSYNC | BGFX_RESET_HIDPI;
bgfxInit.resolution.reset = RESET_FLAGS;
#if BX_PLATFORM_WINDOWS
bgfxInit.platformData.nwh = SDL_GetProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
bgfxInit.platformData.nwh = SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
#elif BX_PLATFORM_OSX
bgfxInit.platformData.nwh = SDL_GetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
bgfxInit.platformData.nwh = SDL_GetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_COCOA_WINDOW_POINTER, NULL);
bgfx::renderFrame();
#elif BX_PLATFORM_LINUX
if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
bgfxInit.platformData.ndt = SDL_GetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
bgfxInit.platformData.ndt = SDL_GetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
bgfxInit.platformData.nwh = (void*)SDL_GetNumberProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);
}
#if WL_EGL_PLATFORM
else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
bgfxInit.platformData.type = bgfx::NativeWindowHandleType::Wayland;
bgfxInit.platformData.ndt = SDL_GetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
bgfxInit.platformData.nwh = SDL_GetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_EGL_WINDOW_POINTER, NULL);
bgfxInit.platformData.ndt = SDL_GetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
bgfxInit.platformData.nwh = SDL_GetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_EGL_WINDOW_POINTER, NULL);
if (!bgfxInit.platformData.nwh) {
bgfxInit.platformData.nwh = wl_egl_window_create((struct wl_surface *)SDL_GetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL), app_state.window_width, app_state.window_height);
SDL_SetProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_EGL_WINDOW_POINTER, (void*)(uintptr_t)bgfxInit.platformData.nwh);
bgfxInit.platformData.nwh = wl_egl_window_create((struct wl_surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL), app_state.window_width, app_state.window_height);
SDL_SetPointerProperty(SDL_GetWindowProperties(app_state.window), SDL_PROP_WINDOW_WAYLAND_EGL_WINDOW_POINTER, (void*)(uintptr_t)bgfxInit.platformData.nwh);
}
}
#endif
@ -105,7 +100,7 @@ namespace K {
if (current_event.type == SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED) {
app_state.window_width = current_event.window.data1;
app_state.window_height = current_event.window.data2;
bgfx::reset(current_event.window.data1, current_event.window.data2, BGFX_RESET_VSYNC | BGFX_RESET_HIDPI);
bgfx::reset(current_event.window.data1, current_event.window.data2, RESET_FLAGS);
UI::SetLogoView();
}
}
@ -121,11 +116,7 @@ namespace K {
K::UI::Shutdown();
K::Resource::Shutdown();
bgfx::shutdown();
#if !(BX_PLATFORM_LINUX && WL_EGL_PLATFORM)
SDL_DestroyWindow(app_state.window);
#endif
SDL_Quit();
}

View file

@ -1,8 +1,8 @@
#include "Graphics.h"
#include <Keishiki.h>
#include <Resource.h>
#include <ft2build.h>
#include FT_FREETYPE_H
//#include <ft2build.h>
//#include FT_FREETYPE_H
#include <bx/math.h>
@ -30,94 +30,94 @@ namespace {
1, 2, 3
};
FT_Library library;
FT_Error error;
struct Glyph {
bgfx::TextureHandle tex = { bgfx::kInvalidHandle };
u32 w = 0, h = 0;
i32 x = 0, y = 0, adv_x = 0, adv_y = 0;
};
struct Font {
FT_Face face = nullptr;
K::Dict<K::Char, Glyph> cache{};
Glyph& get_char(K::Char c) {
if (cache.find(c) == cache.end()) {
FT_GlyphSlot slot = face->glyph;
error = FT_Load_Char(face, c, FT_LOAD_RENDER);
if (error) {
K::Log(K::K_L_Error, "Failed to load character");
}
if (slot->bitmap.width != 0) {
const bgfx::Memory *buf = bgfx::copy(slot->bitmap.buffer, slot->bitmap.pitch * slot->bitmap.rows);
cache.emplace(c, Glyph{
bgfx::createTexture2D(
slot->bitmap.width,
slot->bitmap.rows,
false,
1,
bgfx::TextureFormat::A8,
BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
buf
),
slot->bitmap.width,
slot->bitmap.rows,
slot->bitmap_left,
slot->bitmap_top,
static_cast<i32>(slot->advance.x),
static_cast<i32>(slot->advance.y)
});
}
else cache.emplace(c, Glyph{
{ bgfx::kInvalidHandle },
0,
0,
0,
0,
static_cast<i32>(slot->advance.x),
static_cast<i32>(slot->advance.y)
});
}
return cache[c];
}
};
std::optional<Font> GetFont(const char *path) {
Font f;
error = FT_New_Face(library, path, 0, &f.face);
if (error == FT_Err_Unknown_File_Format) {
K::Log(K::K_L_Error, "FreeType Unknown_File_Format");
return std::nullopt;
}
else if (error) {
K::Log(K::K_L_Error, "FreeType font loading error");
return std::nullopt;
}
error = FT_Set_Char_Size(f.face, 0, 20 * 64, 72, 72);
if (error) {
K::Log(K::K_L_Error, "FreeType Set_Char_Size error");
return std::nullopt;
}
return f;
}
void DestroyFont(Font& f) {
FT_Done_Face(f.face);
for (auto & it : f.cache) {
if (isValid(it.second.tex))
bgfx::destroy(it.second.tex);
}
}
Font regular, bold;
// FT_Library library;
// FT_Error error;
//
// struct Glyph {
// bgfx::TextureHandle tex = { bgfx::kInvalidHandle };
// u32 w = 0, h = 0;
// i32 x = 0, y = 0, adv_x = 0, adv_y = 0;
// };
//
// struct Font {
// FT_Face face = nullptr;
// K::Dict<K::Char, Glyph> cache{};
//
// Glyph& get_char(K::Char c) {
// if (cache.find(c) == cache.end()) {
// FT_GlyphSlot slot = face->glyph;
//
// error = FT_Load_Char(face, c, FT_LOAD_RENDER);
// if (error) {
// K::Log(K::K_L_Error, "Failed to load character");
// }
//
// if (slot->bitmap.width != 0) {
// const bgfx::Memory *buf = bgfx::copy(slot->bitmap.buffer, slot->bitmap.pitch * slot->bitmap.rows);
//
// cache.emplace(c, Glyph{
// bgfx::createTexture2D(
// slot->bitmap.width,
// slot->bitmap.rows,
// false,
// 1,
// bgfx::TextureFormat::A8,
// BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
// buf
// ),
// slot->bitmap.width,
// slot->bitmap.rows,
// slot->bitmap_left,
// slot->bitmap_top,
// static_cast<i32>(slot->advance.x),
// static_cast<i32>(slot->advance.y)
// });
// }
// else cache.emplace(c, Glyph{
// { bgfx::kInvalidHandle },
// 0,
// 0,
// 0,
// 0,
// static_cast<i32>(slot->advance.x),
// static_cast<i32>(slot->advance.y)
// });
// }
// return cache[c];
// }
// };
//
// std::optional<Font> GetFont(const char *path) {
// Font f;
//
// error = FT_New_Face(library, path, 0, &f.face);
// if (error == FT_Err_Unknown_File_Format) {
// K::Log(K::K_L_Error, "FreeType Unknown_File_Format");
// return std::nullopt;
// }
// else if (error) {
// K::Log(K::K_L_Error, "FreeType font loading error");
// return std::nullopt;
// }
//
// error = FT_Set_Char_Size(f.face, 0, 20 * 64, 72, 72);
// if (error) {
// K::Log(K::K_L_Error, "FreeType Set_Char_Size error");
// return std::nullopt;
// }
//
// return f;
// }
//
// void DestroyFont(Font& f) {
// FT_Done_Face(f.face);
// for (auto & it : f.cache) {
// if (isValid(it.second.tex))
// bgfx::destroy(it.second.tex);
// }
// }
//
// Font regular, bold;
bgfx::ProgramHandle imga_program;
bgfx::ProgramHandle a_program;
@ -135,15 +135,15 @@ namespace {
namespace K::Graphics {
bool Init() {
error = FT_Init_FreeType(&library);
if (error) {
Log(K_L_Info, "FreeType init error: {}", error);
return false;
}
if (auto f = GetFont("SourceHanSans-Regular.ttc")) regular = *f; else return false;
if (auto f = GetFont("SourceHanSans-Bold.ttc")) bold = *f; else return false;
// error = FT_Init_FreeType(&library);
// if (error) {
// Log(K_L_Info, "FreeType init error: {}", error);
// return false;
// }
// if (auto f = GetFont("SourceHanSans-Regular.ttc")) regular = *f; else return false;
// if (auto f = GetFont("SourceHanSans-Bold.ttc")) bold = *f; else return false;
//
pcvDecl.begin()
.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
@ -167,9 +167,9 @@ namespace K::Graphics {
}
void Shutdown() {
DestroyFont(regular);
DestroyFont(bold);
FT_Done_FreeType(library);
// DestroyFont(regular);
// DestroyFont(bold);
// FT_Done_FreeType(library);
bgfx::destroy(imga_program);
bgfx::destroy(a_program);
@ -227,130 +227,130 @@ namespace K::Graphics {
DrawTexture(view_id, tex, pos_x, pos_y, w, h, (BGFX_STATE_DEFAULT | BGFX_STATE_BLEND_ALPHA) & ~(BGFX_STATE_WRITE_Z | BGFX_STATE_DEPTH_TEST_LESS), a_program);
}
void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y) {
Font *f = &regular;
auto& [tx, w, h, l, t, x, y] = f->get_char(c);
pos_x += l;
pos_x += x >> 6;
pos_y += y >> 6;
}
void RenderWalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y, u32 col) {
Font *f = &regular;
auto& [tx, w, h, l, t, x, y] = f->get_char(c);
pos_x += l;
if (isValid(tx) && w != 0) {
DrawTextureStencilAlpha(view_id, tx, pos_x, pos_y - (h - t), w, h);
}
pos_x += x >> 6;
pos_y += y >> 6;
}
void RenderGlyph(u32 view_id, Char c, i32 pos_x, i32 pos_y, u32 col) {
Font *f = &regular;
auto& [tx, w, h, l, t, x, y] = f->get_char(c);
pos_x += l;
if (isValid(tx) && w != 0) {
DrawTextureStencilAlpha(view_id, tx, pos_x, pos_y - (h - t), w, h);
}
pos_x += x >> 6;
pos_y += y >> 6;
}
void WalkString(u32 view_id, const String& s, i32& pos_x, i32& pos_y) {
for (const auto& c : s)
WalkGlyph(view_id, c, pos_x, pos_y);
}
void RenderString(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col) {
for (const auto& c : s)
RenderWalkGlyph(view_id, c, pos_x, pos_y, col);
}
void WalkString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32& pos_x, i32& pos_y) {
while (cbegin < cend)
WalkGlyph(view_id, *cbegin++, pos_x, pos_y);
}
void RenderString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32 pos_x, i32 pos_y, u32 col) {
while (cbegin < cend)
RenderGlyph(view_id, *cbegin++, pos_x, pos_y, col);
}
void RenderStringCentered(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col) {
i32 copy_x = 0, copy_y = 0;
WalkString(view_id, s, copy_x, copy_y);
RenderString(view_id, s, pos_x - copy_x / 2, pos_y, col);
}
// I cannot reason this function, returns where the string would end if it was not halted
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) {
Font *f = &regular;
String::const_iterator last = s.cbegin(), end = s.cend(), pos = std::find(last, end, u' '),
halt = s_end > s.length() ? end : last + s_end;
if (pos == end) { // Render the entire thing with hard break if we don't split at all
String::const_iterator last_copy = last;
i32 copy_x = pos_x, copy_y = pos_y;
while (last != std::min(pos, halt)) {
RenderGlyph(view_id, *last++, pos_x, pos_y, col);
if (pos_x - reset_x > w) {
pos_x = reset_x;
pos_y -= f->face->size->metrics.height / 64;
}
if (last >= halt) {
WalkString(view_id, last_copy, pos, copy_x, copy_y);
return copy_x;
};
}
}
else while (last != end) { // Loop through all segments
i32 copy_x = pos_x, old_x = pos_x, copy_y = pos_y;
WalkString(view_id, last, pos, copy_x, copy_y);
if (copy_x - reset_x > w) { // if walk exceeded max w
copy_x = reset_x, copy_y = pos_y; // try walk again from leftmost of box, see if a soft break works; reset y from last walk
WalkString(view_id, last, pos, copy_x, copy_y);
if (copy_x - reset_x > w) { // soft break won't work, go back to old x and hard break
pos_x = old_x;
while (last != pos) {
RenderGlyph(view_id, *last++, pos_x, pos_y, col);
if (pos_x - reset_x > w) {
pos_x = reset_x;
pos_y -= f->face->size->metrics.height / 64;
}
if (last >= halt) return copy_x;
}
}
else { // soft break and kill beginning space
pos_x = reset_x;
pos_y -= f->face->size->metrics.height / 64;
last++;
RenderString(view_id, last, std::min(pos, halt), pos_x, pos_y, col);
if (last >= halt) return copy_x;
}
}
else {
RenderString(view_id, last, std::min(pos, halt), pos_x, pos_y, col);
if (last >= halt) return copy_x;
}
last = pos;
if (pos != end)
pos = std::find(std::next(pos), end, ' ');
}
return pos_x;
}
// void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y) {
// Font *f = &regular;
//
// auto& [tx, w, h, l, t, x, y] = f->get_char(c);
//
// pos_x += l;
//
// pos_x += x >> 6;
// pos_y += y >> 6;
// }
//
// void RenderWalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y, u32 col) {
// Font *f = &regular;
//
// auto& [tx, w, h, l, t, x, y] = f->get_char(c);
//
// pos_x += l;
//
// if (isValid(tx) && w != 0) {
// DrawTextureStencilAlpha(view_id, tx, pos_x, pos_y - (h - t), w, h);
// }
//
// pos_x += x >> 6;
// pos_y += y >> 6;
// }
//
// void RenderGlyph(u32 view_id, Char c, i32 pos_x, i32 pos_y, u32 col) {
// Font *f = &regular;
//
// auto& [tx, w, h, l, t, x, y] = f->get_char(c);
//
// pos_x += l;
//
// if (isValid(tx) && w != 0) {
// DrawTextureStencilAlpha(view_id, tx, pos_x, pos_y - (h - t), w, h);
// }
//
// pos_x += x >> 6;
// pos_y += y >> 6;
// }
//
// void WalkString(u32 view_id, const String& s, i32& pos_x, i32& pos_y) {
// for (const auto& c : s)
// WalkGlyph(view_id, c, pos_x, pos_y);
// }
//
// void RenderString(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col) {
// for (const auto& c : s)
// RenderWalkGlyph(view_id, c, pos_x, pos_y, col);
// }
//
// void WalkString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32& pos_x, i32& pos_y) {
// while (cbegin < cend)
// WalkGlyph(view_id, *cbegin++, pos_x, pos_y);
// }
//
// void RenderString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32 pos_x, i32 pos_y, u32 col) {
// while (cbegin < cend)
// RenderGlyph(view_id, *cbegin++, pos_x, pos_y, col);
// }
//
// void RenderStringCentered(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col) {
// i32 copy_x = 0, copy_y = 0;
// WalkString(view_id, s, copy_x, copy_y);
// RenderString(view_id, s, pos_x - copy_x / 2, pos_y, col);
// }
//
// // I cannot reason this function, returns where the string would end if it was not halted
// 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) {
// Font *f = &regular;
//
// String::const_iterator last = s.cbegin(), end = s.cend(), pos = std::find(last, end, u' '),
// halt = s_end > s.length() ? end : last + s_end;
// if (pos == end) { // Render the entire thing with hard break if we don't split at all
// String::const_iterator last_copy = last;
// i32 copy_x = pos_x, copy_y = pos_y;
// while (last != std::min(pos, halt)) {
// RenderGlyph(view_id, *last++, pos_x, pos_y, col);
// if (pos_x - reset_x > w) {
// pos_x = reset_x;
// pos_y -= f->face->size->metrics.height / 64;
// }
// if (last >= halt) {
// WalkString(view_id, last_copy, pos, copy_x, copy_y);
// return copy_x;
// };
// }
// }
// else while (last != end) { // Loop through all segments
// i32 copy_x = pos_x, old_x = pos_x, copy_y = pos_y;
// WalkString(view_id, last, pos, copy_x, copy_y);
// if (copy_x - reset_x > w) { // if walk exceeded max w
// copy_x = reset_x, copy_y = pos_y; // try walk again from leftmost of box, see if a soft break works; reset y from last walk
// WalkString(view_id, last, pos, copy_x, copy_y);
// if (copy_x - reset_x > w) { // soft break won't work, go back to old x and hard break
// pos_x = old_x;
// while (last != pos) {
// RenderGlyph(view_id, *last++, pos_x, pos_y, col);
// if (pos_x - reset_x > w) {
// pos_x = reset_x;
// pos_y -= f->face->size->metrics.height / 64;
// }
// if (last >= halt) return copy_x;
// }
// }
// else { // soft break and kill beginning space
// pos_x = reset_x;
// pos_y -= f->face->size->metrics.height / 64;
// last++;
// RenderString(view_id, last, std::min(pos, halt), pos_x, pos_y, col);
// if (last >= halt) return copy_x;
// }
// }
// else {
// RenderString(view_id, last, std::min(pos, halt), pos_x, pos_y, col);
// if (last >= halt) return copy_x;
// }
//
// last = pos;
// if (pos != end)
// pos = std::find(std::next(pos), end, ' ');
// }
// 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]{};

View file

@ -3,71 +3,71 @@
#include <mutex>
#include <thread>
#include <Keishiki.h>
#include <glaze/glaze.hpp>
//#include <glaze/glaze.hpp>
#define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h>
namespace glz {
template <>
struct meta<ImVec2> {
using T = ImVec2;
static constexpr auto value = array(&T::x, &T::y);
};
template <>
struct meta<K::Uniform> {
using T = K::Uniform;
static constexpr auto value = object(&T::name,
&T::val,
// &T::connection, // todo need lookup
&T::status);
};
template <>
struct meta<K::Sampler> {
using T = K::Sampler;
static constexpr auto value = object(&T::name);
// &T::resource, // todo need lookup
// &T::dims, // todo need lookup
// &T::frame); // todo need lookup
};
template <>
struct meta<K::VisualTrack> {
using T = K::VisualTrack;
static constexpr auto value = object(&T::shader, &T::uniforms, &T::samplers);
};
template <>
struct meta<K::Plugboard::Plugboard> {
using T = K::Plugboard::Plugboard;
static constexpr auto value = object(); // todo this one is actually so complicated
};
template <>
struct meta<K::CompositionState> {
using T = K::CompositionState;
static constexpr auto value = object(&T::name,
&T::current_frame,
&T::frame_max,
&T::fps,
&T::width,
&T::height,
&T::layers,
&T::active,
&T::selected,
&T::disabled,
&T::plugboard);
};
template <>
struct meta<K::ProjectState> {
using T = K::ProjectState;
static constexpr auto value = object(&T::compositions);
};
}
//namespace glz {
//template <>
//struct meta<ImVec2> {
// using T = ImVec2;
// static constexpr auto value = array(&T::x, &T::y);
//};
//
//template <>
//struct meta<K::Uniform> {
// using T = K::Uniform;
// static constexpr auto value = object(&T::name,
// &T::val,
// // &T::connection, // todo need lookup
// &T::status);
//};
//
//template <>
//struct meta<K::Sampler> {
// using T = K::Sampler;
// static constexpr auto value = object(&T::name);
// // &T::resource, // todo need lookup
// // &T::dims, // todo need lookup
// // &T::frame); // todo need lookup
//};
//
//template <>
//struct meta<K::VisualTrack> {
// using T = K::VisualTrack;
// static constexpr auto value = object(&T::shader, &T::uniforms, &T::samplers);
//};
//
//template <>
//struct meta<K::Plugboard::Plugboard> {
// using T = K::Plugboard::Plugboard;
// static constexpr auto value = object(); // todo this one is actually so complicated
//};
//
//template <>
//struct meta<K::CompositionState> {
// using T = K::CompositionState;
// static constexpr auto value = object(&T::name,
// &T::current_frame,
// &T::frame_max,
// &T::fps,
// &T::width,
// &T::height,
// &T::layers,
// &T::active,
// &T::selected,
// &T::disabled,
// &T::plugboard);
//};
//
//template <>
//struct meta<K::ProjectState> {
// using T = K::ProjectState;
// static constexpr auto value = object(&T::compositions);
//};
//
//}
namespace K::Resource {
void ReadProject() {
@ -85,10 +85,10 @@ namespace K::Resource {
return;
while (*filelist) {
auto ec = glz::read_file_json(app_state.project, *filelist, String{});
if (ec.ec != glz::error_code::none) {
Log(K_L_Error, "{}", ec.includer_error);
}
// auto ec = glz::read_file_json(app_state.project, *filelist, String{});
// if (ec.ec != glz::error_code::none) {
// Log(K_L_Error, "{}", ec.includer_error);
// }
filelist++;
}
@ -121,10 +121,10 @@ namespace K::Resource {
return;
while (*filelist) {
auto ec = glz::write_file_json(app_state.project, *filelist, String{});
if (ec.ec != glz::error_code::none) {
Log(K_L_Error, "{}", ec.includer_error);
}
// auto ec = glz::write_file_json(app_state.project, *filelist, String{});
// if (ec.ec != glz::error_code::none) {
// Log(K_L_Error, "{}", ec.includer_error);
// }
filelist++;
}
@ -175,7 +175,7 @@ namespace K::Resource {
std::shared_mutex resource_lock{};
std::filesystem::path ffmpeg_path = "ffmpeg";
std::filesystem::path shaderc_path = "/Users/lachrymal/Projects/Keishiki/build/Keishiki/ext/bgfx/cmake/bgfx/Debug/shaderc";
std::filesystem::path shaderc_path = "./ext/bgfx/cmake/bgfx/shaderc";
const char *shaderc_temp_args;
Resource<Type::K_R_Still> *fallback_still;

View file

@ -2,6 +2,8 @@
#include "Graphics.h"
#include "VisualTrack.h"
#include <Actions.h>
#include <imgui.h>
#include <imgui_internal.h>
#include <misc/cpp/imgui_stdlib.h>
@ -75,53 +77,6 @@ namespace K::UI {
bgfx::setViewTransform(K::Graphics::K_VIEW_LOGO, view, proj);
}
void AddTransformLayer(CompositionState& s, const String& name) {
auto l = Layer{
VisualTrack{},
name,
Graphics::K_V_AlphaOver,
0UL,
s.frame_max
};
l.track.AddUniform("u_resolution", ShaderGraph::ExpandVariant(ShaderGraph::T_XY), K_U_Exposed);
l.track.uniforms[0].val = ShaderGraph::T_Map<ShaderGraph::T_XY>::type{static_cast<f32>(s.width), static_cast<f32>(s.height)};
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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);
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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);
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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};
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
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};
K::VisualTrack::ExposeUniform(s, l.track.uniforms.back());
l.track.shader = "void main() {\n"
"\tfloat angle = -u_rot * M_PI / 180.0f;\n"
"\tvec2 uv = vec2(v_texcoord0.x, 1.0f - v_texcoord0.y) - .5f;\n"
"\tuv = uv * u_resolution;\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 = uv / s_texColor_dims;\n"
"\tuv = uv / u_scale;\n"
"\tuv = uv + .5f;\n\n"
"\tvec4 tx = texture2D(s_texColor, uv);\n"
"\tgl_FragColor = vec4(tx.rgb, tx.a * u_opacity);\n"
"}\n";
l.track.AddSampler("s_texColor");
l.track.Compile();
s.layers.push_back(std::move(l));
}
void MainMenuBar() {
if (ImGui::BeginMainMenuBar()) {
if (ImGui::BeginMenu("File")) {
@ -334,6 +289,7 @@ namespace K::UI {
static bool do_bg = true, dragging = false;
static f32 size = 1.0f, angle = 0;
static ImVec2 pos{}, old = pos;
static i32 ch = 0;
if (ImGui::Shortcut(ImGuiKey_Space))
TogglePlay();
@ -356,7 +312,7 @@ namespace K::UI {
present = s.composite[result_index];
ImTextureID idx = ImGui::toId(present, 1, 0);
if (idx != nullptr) {
if (idx != NULL) {
ImVec2 image_size = {static_cast<f32>(s.width) * size, static_cast<f32>(s.height) * size};
ImDrawList* draw_list = ImGui::GetWindowDrawList();
@ -364,8 +320,8 @@ namespace K::UI {
return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a);
};
ImVec2 center = ImGui::GetCursorScreenPos() + ImGui::GetContentRegionAvail() * .5f + pos;
f32 cos_a = std::cosf(angle / 180.0f * std::numbers::pi);
f32 sin_a = std::sinf(angle / 180.0f * std::numbers::pi);
f32 cos_a = std::cos(angle / 180.0f * std::numbers::pi);
f32 sin_a = std::sin(angle / 180.0f * std::numbers::pi);
ImVec2 quad[4] = {
center + rot(ImVec2(-image_size.x * 0.5f, -image_size.y * 0.5f), cos_a, sin_a),
center + rot(ImVec2(+image_size.x * 0.5f, -image_size.y * 0.5f), cos_a, sin_a),
@ -380,6 +336,7 @@ namespace K::UI {
};
draw_list->AddImageQuad(idx, quad[0], quad[1], quad[2], quad[3], uvs[0], uvs[1], uvs[2], uvs[3], IM_COL32_WHITE);
draw_list->AddQuad(quad[0], quad[1], quad[2], quad[3], 0x22FFFFFF, 1.0f);
}
/* ImGui::BeginDisabled(comp_save_called != nullptr);
@ -419,15 +376,18 @@ namespace K::UI {
ImGui::Text("%ux%u@%.1f", s.width, s.height, s.fps);
ImGui::SameLine();
f32 percentage = size * 100.0f;
ImGui::SetNextItemWidth(110.0f);
ImGui::SetNextItemWidth(100.0f);
if (ImGui::InputFloat("View Scale", &percentage, 15.0f, 25.0f, "%.2f%%")) {
size = std::max(.25f, percentage / 100.0f);
}
ImGui::SameLine();
ImGui::SetNextItemWidth(50.0f);
ImGui::SetNextItemWidth(35.0f);
ImGui::DragFloat("View Angle", &angle, .05f, 0.0f, 0.0f, "%.1f");
ImGui::SameLine();
ImGui::Checkbox("Transparency Grid", &do_bg);
ImGui::SetNextItemWidth(90.0f);
ImGui::Combo("Channels", &ch, "Combined\0Red\0Green\0Blue\0Alpha\0");
ImGui::SameLine();
ImGui::Checkbox("Alpha Grid", &do_bg);
}
ImGui::EndChild();
ImGui::PopStyleColor();
@ -535,9 +495,9 @@ namespace K::UI {
// Grid
const f32 grid_inc = 20.0f;
const f32 w = window->ContentRegionRect.GetWidth(), h = window->ContentRegionRect.GetHeight();
for (f32 x = std::fmodf(nodes_view_pos.x, grid_inc); x < w; x += grid_inc)
for (f32 x = std::fmod(nodes_view_pos.x, grid_inc); x < w; x += grid_inc)
window->DrawList->AddLine(window_pos + ImVec2(x, 0.0f), window_pos + ImVec2(x, h), 0xFF222222, 1.0f);
for (f32 y = std::fmodf(nodes_view_pos.y, grid_inc); y < h; y += grid_inc)
for (f32 y = std::fmod(nodes_view_pos.y, grid_inc); y < h; y += grid_inc)
window->DrawList->AddLine(window_pos + ImVec2(0.0f, y), window_pos + ImVec2(w, y), 0xFF222222, 1.0f);
// why are we re-getting positions on each frame?
@ -2181,7 +2141,7 @@ namespace K::UI {
ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode);
ImGui::ShowDemoWindow();
// ImGui::ShowDemoWindow();
MainMenuBar();
if (draw_assets) Assets();

@ -1 +1 @@
Subproject commit 4cc3410dce50cefce98d3cf3cf1bc8eca83b862a
Subproject commit 615d2dcd5b6352aea50372745a05779e24ff8d31

@ -1 +1 @@
Subproject commit 4ceffda6def0e57d70d8ea6aab8178be091fed37
Subproject commit 709e2d49f0d71d35203b0366a6d21b071059cb36

@ -1 +1 @@
Subproject commit c98518351efd5a46f5d448e947e0b7242d197d07
Subproject commit 7e73566ce7bd3617cd4b14a2e3a19a2a30b524c7

@ -1 +1 @@
Subproject commit ec378cecaf3cd656a9aa4bf237495d401521ae21
Subproject commit 0ae7e607370cc66218ccfacf5de4db8a35424c2f

@ -1 +0,0 @@
Subproject commit 951eccb69d7153206cc5487ca51256a24f518f6f

@ -1 +1 @@
Subproject commit 10a5a857f5b5cd6eae7f86461b939ec05e9235b2
Subproject commit ee1deccc08c14ab1e6abcfa6aae11d915763cdb7

View file

@ -131,7 +131,7 @@ bool ImGui_Implbgfx_CreateFontsTexture()
0, bgfx::copy(pixels, width * height * 4));
// Store our identifier
io.Fonts->TexID = (void*)(intptr_t)g_FontTexture.idx;
io.Fonts->TexID = (ImTextureID)(intptr_t)g_FontTexture.idx;
return true;
}

@ -1 +1 @@
Subproject commit f156599faefe316f7dd20fe6c783bf87c8bb6fd9
Subproject commit 419a8a0f5fcb77e1e7c19ab540441686bfe21bca

@ -1 +1 @@
Subproject commit 54df6ac3f500f4ec737c14636f7f908e6905081d
Subproject commit 55e9ad0867568e3dfb4d4c89efc3b9dde344060f

@ -1 +1 @@
Subproject commit 8ba8544709057644c7584a9b11158d28c71815ff
Subproject commit ddb95a8ae52d8015b5f22d67b2ca71e38faf435a

View file

@ -0,0 +1,9 @@
#include <Common.h>
#include <Keishiki.h>
namespace K {
struct Action {
};
void AddTransformLayer(CompositionState& s, const String& name);
}

View file

@ -28,16 +28,16 @@ namespace K::Graphics {
void DrawTextureStencilAlpha(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
// Text
void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y);
void RenderWalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y, u32 col);
void RenderGlyph(u32 view_id, Char c, i32 pos_x, i32 pos_y, u32 col);
void WalkString(u32 view_id, const String& s, i32& pos_x, i32& pos_y);
void RenderString(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col);
void WalkString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32& pos_x, i32& pos_y);
void RenderString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32 pos_x, i32 pos_y, u32 col);
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);
// void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y);
// void RenderWalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y, u32 col);
// void RenderGlyph(u32 view_id, Char c, i32 pos_x, i32 pos_y, u32 col);
//
// void WalkString(u32 view_id, const String& s, i32& pos_x, i32& pos_y);
// void RenderString(u32 view_id, const String& s, i32 pos_x, i32 pos_y, u32 col);
// void WalkString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32& pos_x, i32& pos_y);
// void RenderString(u32 view_id, String::const_iterator cbegin, String::const_iterator cend, i32 pos_x, i32 pos_y, u32 col);
//
// 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,

View file

@ -1,17 +1,17 @@
import subprocess, os
#SHADERC = "..\\build\\Keishiki\\ext\\bgfx\\cmake\\bgfx\\Debug\\shaderc"
SHADERC = "/Users/lachrymal/Projects/Keishiki/build/Keishiki/ext/bgfx/cmake/bgfx/Debug/shaderc"
#SHADERC = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/ext/bgfx/cmake/bgfx/shaderc"
#OUT = "..\\build\\Keishiki\\Debug\\shaders\\"
OUT = "/Users/lachrymal/Projects/Keishiki/Keishiki/runtime/shaders/"
#OUT = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/shaders/"
#I = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/"
I = "/Users/lachrymal/Projects/Keishiki/Keishiki/runtime/"
# SHADERC = "/Users/lachrymal/Projects/Keishiki/build/Keishiki/ext/bgfx/cmake/bgfx/Debug/shaderc"
SHADERC = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/ext/bgfx/cmake/bgfx/shaderc"
# OUT = "..\\build\\Keishiki\\Debug\\shaders\\"
# OUT = "/Users/lachrymal/Projects/Keishiki/Keishiki/runtime/shaders/"
OUT = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/shaders/"
I = "/home/lach/Projects/Keishiki/cmake-build-debug/Keishiki/"
# I = "/Users/lachrymal/Projects/Keishiki/Keishiki/runtime/"
P = lambda location, platform, frag, vert: { 'location': location, 'platform': platform, 'frag': frag, 'vert': vert }
plats = [
P('glsl', 'windows', '140', '140'),
P('glsl', 'linux', '440', '440'),
# P('dx11', 'windows', 's_5_0', 's_5_0'),
P('spirv', 'linux', 'spirv', 'spirv'),
P('metal', 'osx', 'metal', 'metal')

View file

@ -3,11 +3,11 @@ $input v_texcoord0
#include <bgfx_shader.sh>
#include <shaderlib.sh>
uniform vec4 __f_hw;
uniform vec4 _f_hw;
void main()
{
vec2 uv = vec2(v_texcoord0.x, (1.0f - v_texcoord0.y)) * __f_hw.xy / 20.0f;
vec2 uv = vec2(v_texcoord0.x, (1.0f - v_texcoord0.y)) * _f_hw.xy / 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,8 @@
<img src="Keishiki.webp" alt="Logo" width="300"/>
<img src="Keishiki.webp" alt="Logo" width="200"/>
# Keishiki: Real-Time Compositor-Sequencer Framework
![Main UI](static/screenshot.png)
## Libraries
- [bgfx](https://github.com/bkaradzic/bgfx)
@ -10,13 +12,21 @@
- [Glaze](https://github.com/stephenberry/glaze)
- [imgui_impl_bgfx](https://gist.github.com/pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb)
- [ImPlot](https://github.com/epezent/implot)
- [SDL2](https://www.libsdl.org/)
- [SDL3](https://www.libsdl.org/)
- [stb](https://github.com/nothings/stb)
- [SRELL](https://www.akenotsuki.com/misc/srell/en/)
- [plf::colony](https://plflib.org/colony.htm)
Mostly using git submodules, please clone recursively.
## Runtime Dependency
- [ffmpeg](https://ffmpeg.org/)
- shaderc
Paths to runtime dependencies are currently hardcoded.
## Building
Use `CMakeLists.txt` in the root directory. The default target is `Keishiki`.
## Inspired by
- [Automaton](https://github.com/0b5vr/automaton)

View file

@ -37,6 +37,7 @@
# Later
## Compositor
- Investigate bgfx vulkan regression on 1109f3c5bf71f5e5c30fcaf6f899a25e3316adff
- Simple 3D engine
- Particles -- shoot for performance in https://github.com/CHCTW/DirectX12-Framework-
- Flat sets and flat maps pending compiler support

61
flake.lock generated Normal file
View file

@ -0,0 +1,61 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1726560853,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1730200266,
"narHash": "sha256-l253w0XMT8nWHGXuXqyiIC/bMvh1VRszGXgdpQlfhvU=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "807e9154dcb16384b1b765ebe9cd2bba2ac287fd",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

79
flake.nix Normal file
View file

@ -0,0 +1,79 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils, ... }: flake-utils.lib.eachDefaultSystem (system:
let
pkgs = import nixpkgs {
inherit system;
config.allowUnfree = true;
};
in
{
devShell = pkgs.mkShell rec {
packages = with pkgs; [
gcc
libtool
gnumake
cmake
gdb
pkg-config
jetbrains.clion
python3
xorg.xorgproto
xorg.libX11
xorg.libX11.dev
xorg.libxcb
xorg.libxcb.dev
xorg.libXext
xorg.libXft
xorg.libXinerama
xorg.libXpm
xorg.libXrandr
xorg.libXrender
xorg.libXau
xorg.libXcursor
xorg.libXi
xorg.libXi.dev
xorg.libXfixes
xorg.libXxf86vm
xorg.xinput
xorg.libICE
xorg.libXScrnSaver
libdrm
libGL
libGL.dev
libGLU
libglvnd
libglvnd.dev
libxkbcommon
mesa
egl-wayland
egl-wayland.dev
wayland
wayland-scanner
alsa-lib
audiofile
dbus
libdecor
pipewire
udev
renderdoc
vulkan-headers
vulkan-helper
vulkan-loader
vulkan-tools
vulkan-volk
];
shellHook = ''
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${
with pkgs;
lib.makeLibraryPath packages
}"
'';
};
}
);
}

BIN
static/screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 MiB