resource manager init
This commit is contained in:
parent
2f958f7ede
commit
667a23ecb2
12 changed files with 263 additions and 138 deletions
|
@ -23,14 +23,16 @@ add_subdirectory("ext/bgfx")
|
||||||
|
|
||||||
add_compile_definitions(IMGUI_DEFINE_MATH_OPERATORS)
|
add_compile_definitions(IMGUI_DEFINE_MATH_OPERATORS)
|
||||||
|
|
||||||
# Disable RTTI
|
# Disable RTTI and exceptions
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
string(REGEX REPLACE "/GR" "/GR-" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
string(REGEX REPLACE "/GR" "/GR-" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
|
string(REGEX REPLACE "/EHsc" "/EHs-c-" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
include_directories("include/windows")
|
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)
|
target_link_libraries (Keishiki PRIVATE freetype bgfx bx ${PROJECT_SOURCE_DIR}/lib/x64/SDL2.lib ${PROJECT_SOURCE_DIR}/lib/x64/SDL2main.lib)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
|
#include <Resource.h>
|
||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
@ -12,37 +13,6 @@
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
bgfx::ShaderHandle LoadShader(const std::string& FILENAME) {
|
|
||||||
std::string shaderPath{};
|
|
||||||
|
|
||||||
switch (bgfx::getRendererType()) {
|
|
||||||
case bgfx::RendererType::Noop:
|
|
||||||
case bgfx::RendererType::Direct3D11:
|
|
||||||
case bgfx::RendererType::Direct3D12: shaderPath = "shaders/dx11/"; break;
|
|
||||||
case bgfx::RendererType::Gnm: shaderPath = "shaders/pssl/"; break;
|
|
||||||
case bgfx::RendererType::Metal: shaderPath = "shaders/metal/"; break;
|
|
||||||
case bgfx::RendererType::OpenGL: shaderPath = "shaders/glsl/"; break;
|
|
||||||
case bgfx::RendererType::OpenGLES: shaderPath = "shaders/essl/"; break;
|
|
||||||
case bgfx::RendererType::Vulkan: shaderPath = "shaders/spirv/"; break;
|
|
||||||
default: K::LogError("Unsupported renderer"); break;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::string filePath = shaderPath + FILENAME;
|
|
||||||
|
|
||||||
FILE *file = fopen(filePath.c_str(), "rb");
|
|
||||||
fseek(file, 0, SEEK_END);
|
|
||||||
long fileSize = ftell(file);
|
|
||||||
fseek(file, 0, SEEK_SET);
|
|
||||||
|
|
||||||
const bgfx::Memory *mem = bgfx::alloc(fileSize + 1);
|
|
||||||
fread(mem->data, 1, fileSize, file);
|
|
||||||
mem->data[mem->size - 1] = '\0';
|
|
||||||
fclose(file);
|
|
||||||
|
|
||||||
return bgfx::createShader(mem);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct PosUVVertex {
|
struct PosUVVertex {
|
||||||
f32 x;
|
f32 x;
|
||||||
f32 y;
|
f32 y;
|
||||||
|
@ -150,34 +120,9 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<K::Graphics::ImageTexture> GetImageTexture(const std::string& file) {
|
|
||||||
K::Graphics::ImageTexture i;
|
|
||||||
i.buffer = stbi_load(file.c_str(), &i.w, &i.h, &i.channels, 0);
|
|
||||||
if (i.buffer == NULL) {
|
|
||||||
K::LogError("ADV: STB IMAGE loading failed for " + file);
|
|
||||||
return std::nullopt;
|
|
||||||
}
|
|
||||||
const bgfx::Memory *buf = bgfx::makeRef(i.buffer, i.w * i.h * i.channels * sizeof(u8));
|
|
||||||
i.tx = bgfx::createTexture2D(
|
|
||||||
i.w,
|
|
||||||
i.h,
|
|
||||||
false,
|
|
||||||
1,
|
|
||||||
i.channels == 4 ? bgfx::TextureFormat::RGBA8 : bgfx::TextureFormat::RGB8,
|
|
||||||
BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
|
|
||||||
buf
|
|
||||||
);
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DestroyImageTexture(K::Graphics::ImageTexture& i) {
|
|
||||||
stbi_image_free(i.buffer);
|
|
||||||
bgfx::destroy(i.tx);
|
|
||||||
}
|
|
||||||
|
|
||||||
Font regular, bold;
|
Font regular, bold;
|
||||||
bgfx::ProgramHandle imga_program;
|
const K::Resource::Resource<K::Resource::Type::K_R_ShaderProgram> *imga_program;
|
||||||
bgfx::ProgramHandle a_program;
|
const K::Resource::Resource<K::Resource::Type::K_R_ShaderProgram> *a_program;
|
||||||
|
|
||||||
bgfx::UniformHandle s_texColor;
|
bgfx::UniformHandle s_texColor;
|
||||||
bgfx::UniformHandle imga_opacity;
|
bgfx::UniformHandle imga_opacity;
|
||||||
|
@ -186,19 +131,13 @@ namespace {
|
||||||
bgfx::VertexBufferHandle vbh;
|
bgfx::VertexBufferHandle vbh;
|
||||||
bgfx::VertexLayout pcvDecl;
|
bgfx::VertexLayout pcvDecl;
|
||||||
|
|
||||||
K::Dict<K::String, K::Graphics::ImageTexture> imgs;
|
|
||||||
|
|
||||||
f32 composite_view[16];
|
f32 composite_view[16];
|
||||||
bgfx::UniformHandle composite_A, composite_B, composite_mode;
|
bgfx::UniformHandle composite_A, composite_B, composite_mode;
|
||||||
bgfx::ProgramHandle composite_pg;
|
const K::Resource::Resource<K::Resource::Type::K_R_ShaderProgram> *composite_pg;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace K::Graphics {
|
namespace K::Graphics {
|
||||||
Graphics::ImageTexture *mmaker;
|
const Resource::Resource<Resource::Type::K_R_Still> *mmaker;
|
||||||
|
|
||||||
bgfx::ProgramHandle load_shader_program(const std::string& FILENAME) {
|
|
||||||
return bgfx::createProgram(LoadShader(FILENAME + ".vert.bin"), LoadShader(FILENAME + ".frag.bin"), true);
|
|
||||||
};
|
|
||||||
|
|
||||||
bool Init(u16 width, u16 height) {
|
bool Init(u16 width, u16 height) {
|
||||||
error = FT_Init_FreeType(&library);
|
error = FT_Init_FreeType(&library);
|
||||||
|
@ -217,17 +156,17 @@ namespace K::Graphics {
|
||||||
ibh = bgfx::createIndexBuffer(bgfx::makeRef(quad_indices, sizeof(quad_indices)));
|
ibh = bgfx::createIndexBuffer(bgfx::makeRef(quad_indices, sizeof(quad_indices)));
|
||||||
vbh = bgfx::createVertexBuffer(bgfx::makeRef(quad_vert, sizeof(quad_vert)), pcvDecl);
|
vbh = bgfx::createVertexBuffer(bgfx::makeRef(quad_vert, sizeof(quad_vert)), pcvDecl);
|
||||||
|
|
||||||
imga_program = load_shader_program("ImageAlpha"); // RGBA + Opacity
|
imga_program = Resource::LoadShaderProgram("ImageAlpha"); // RGBA + Opacity
|
||||||
a_program = load_shader_program("AlphaStencil"); // A -> FFFA
|
a_program = Resource::LoadShaderProgram("AlphaStencil"); // A -> FFFA
|
||||||
|
|
||||||
imga_opacity = bgfx::createUniform("f_opacity", bgfx::UniformType::Vec4); // x -> alpha, yzw are dummies
|
imga_opacity = bgfx::createUniform("f_opacity", bgfx::UniformType::Vec4); // x -> alpha, yzw are dummies
|
||||||
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
|
s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
|
||||||
|
|
||||||
mmaker = Graphics::GetImageTextureFromFile("mmaker.png");
|
mmaker = Resource::LoadStill("mmaker.png");
|
||||||
bx::mtxTranslate(composite_view, 0.f, 0.f, 1.0f);
|
bx::mtxTranslate(composite_view, 0.f, 0.f, 1.0f);
|
||||||
composite_A = bgfx::createUniform("s_A", bgfx::UniformType::Sampler);
|
composite_A = bgfx::createUniform("s_A", bgfx::UniformType::Sampler);
|
||||||
composite_B = bgfx::createUniform("s_B", bgfx::UniformType::Sampler);
|
composite_B = bgfx::createUniform("s_B", bgfx::UniformType::Sampler);
|
||||||
composite_pg = load_shader_program("BinaryComposite");
|
composite_pg = Resource::LoadShaderProgram("BinaryComposite");
|
||||||
composite_mode = bgfx::createUniform("u_mode", bgfx::UniformType::Vec4);
|
composite_mode = bgfx::createUniform("u_mode", bgfx::UniformType::Vec4);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -238,12 +177,6 @@ namespace K::Graphics {
|
||||||
DestroyFont(bold);
|
DestroyFont(bold);
|
||||||
FT_Done_FreeType(library);
|
FT_Done_FreeType(library);
|
||||||
|
|
||||||
for (auto& img : imgs) {
|
|
||||||
DestroyImageTexture(img.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
bgfx::destroy(a_program);
|
|
||||||
bgfx::destroy(imga_program);
|
|
||||||
|
|
||||||
bgfx::destroy(ibh);
|
bgfx::destroy(ibh);
|
||||||
bgfx::destroy(vbh);
|
bgfx::destroy(vbh);
|
||||||
|
@ -253,7 +186,6 @@ namespace K::Graphics {
|
||||||
|
|
||||||
bgfx::destroy(composite_A);
|
bgfx::destroy(composite_A);
|
||||||
bgfx::destroy(composite_B);
|
bgfx::destroy(composite_B);
|
||||||
bgfx::destroy(composite_pg);
|
|
||||||
bgfx::destroy(composite_mode);
|
bgfx::destroy(composite_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,27 +211,15 @@ namespace K::Graphics {
|
||||||
DrawTextureWithTransform(view_id, tex, mtx3, state, pg);
|
DrawTextureWithTransform(view_id, tex, mtx3, state, pg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTextureImageAlpha(u32 view_id, const ImageTexture& img, i32 pos_x, i32 pos_y, f32 alpha) {
|
void DrawTextureImageAlpha(u32 view_id, const Resource::Resource<Resource::K_R_Still>& img, i32 pos_x, i32 pos_y, f32 alpha) {
|
||||||
static f32 pack[4]{};
|
static f32 pack[4]{};
|
||||||
pack[0] = alpha;
|
pack[0] = alpha;
|
||||||
bgfx::setUniform(imga_opacity, pack);
|
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);
|
DrawTexture(view_id, img.tex, 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->pg);
|
||||||
}
|
|
||||||
|
|
||||||
ImageTexture *GetImageTextureFromFile(const std::string& file) {
|
|
||||||
if (imgs.find(file) == imgs.end()) {
|
|
||||||
if (auto i = GetImageTexture(file)) {
|
|
||||||
imgs[file] = *i;
|
|
||||||
return &imgs[file];
|
|
||||||
}
|
|
||||||
else return nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return &imgs[file];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DrawTextureStencilAlpha(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h) {
|
void DrawTextureStencilAlpha(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h) {
|
||||||
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);
|
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->pg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y) {
|
void WalkGlyph(u32 view_id, Char c, i32& pos_x, i32& pos_y) {
|
||||||
|
@ -444,7 +364,7 @@ namespace K::Graphics {
|
||||||
bgfx::setTexture(1, composite_B, composite); // B
|
bgfx::setTexture(1, composite_B, composite); // B
|
||||||
bgfx::setUniform(composite_mode, pack); // A over B
|
bgfx::setUniform(composite_mode, pack); // A over B
|
||||||
bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
|
bgfx::setState(BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A);
|
||||||
bgfx::submit(view_id, composite_pg);
|
bgfx::submit(view_id, composite_pg->pg);
|
||||||
}
|
}
|
||||||
|
|
||||||
f64 GetCubicUniqueReal(f64 a, f64 b, f64 c, f64 d) {
|
f64 GetCubicUniqueReal(f64 a, f64 b, f64 c, f64 d) {
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
K::CompState state;
|
K::CompState state;
|
||||||
K::Graphics::ImageTexture *logo;
|
const K::Resource::Resource<K::Resource::Type::K_R_Still> *logo;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace K {
|
namespace K {
|
||||||
|
@ -86,6 +86,7 @@ namespace K {
|
||||||
bx::mtxOrtho(proj, 0.0f, app_state.window_width, 0.0f, app_state.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);
|
bgfx::setViewTransform(K::Graphics::K_VIEW_LOGO, view, proj);
|
||||||
|
|
||||||
|
K::Resource::Init();
|
||||||
K::UI::Init(app_state.window);
|
K::UI::Init(app_state.window);
|
||||||
|
|
||||||
if (!K::Graphics::Init(app_state.window_width, app_state.window_height)) {
|
if (!K::Graphics::Init(app_state.window_width, app_state.window_height)) {
|
||||||
|
@ -93,7 +94,7 @@ namespace K {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
logo = K::Graphics::GetImageTextureFromFile("Keishiki.png");
|
logo = K::Resource::LoadStill("Keishiki.png");
|
||||||
|
|
||||||
state.width = 1280;
|
state.width = 1280;
|
||||||
state.height = 550;
|
state.height = 550;
|
||||||
|
@ -169,6 +170,7 @@ namespace K {
|
||||||
void Shutdown() {
|
void Shutdown() {
|
||||||
K::Graphics::Shutdown();
|
K::Graphics::Shutdown();
|
||||||
K::UI::Shutdown(state);
|
K::UI::Shutdown(state);
|
||||||
|
K::Resource::Shutdown();
|
||||||
bgfx::shutdown();
|
bgfx::shutdown();
|
||||||
SDL_DestroyWindow(app_state.window);
|
SDL_DestroyWindow(app_state.window);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
107
Keishiki/Resource.cpp
Normal file
107
Keishiki/Resource.cpp
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
#include <Resource.h>
|
||||||
|
#include <stb_image.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
std::filesystem::path shader_path{};
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace K::Resource {
|
||||||
|
Dict<std::filesystem::path, std::variant<
|
||||||
|
Resource<K_R_Still>,
|
||||||
|
Resource<K_R_ShaderProgram>,
|
||||||
|
Resource<K_R_StillSequence>,
|
||||||
|
Resource<K_R_VideoAudio>,
|
||||||
|
Resource<K_R_AudioOnly>
|
||||||
|
>> resources{};
|
||||||
|
|
||||||
|
std::filesystem::path ffmpeg_path = "ffmpeg";
|
||||||
|
|
||||||
|
Resource<K_R_Still> *LoadStill(const std::filesystem::path& file) {
|
||||||
|
Resource<K_R_Still> res{};
|
||||||
|
res.buf = stbi_load(file.c_str(), &res.w, &res.h, &res.channels, 0);
|
||||||
|
if (res.buf == nullptr) {
|
||||||
|
K::LogError("Image loading failed for " + file.string());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
const bgfx::Memory *ref = bgfx::makeRef(res.buf, res.w * res.h * res.channels * sizeof(u8));
|
||||||
|
res.format = res.channels == 4 ? bgfx::TextureFormat::RGBA8 : bgfx::TextureFormat::RGB8;
|
||||||
|
res.tex = bgfx::createTexture2D(
|
||||||
|
res.w,
|
||||||
|
res.h,
|
||||||
|
false,
|
||||||
|
1,
|
||||||
|
res.format,
|
||||||
|
BGFX_TEXTURE_NONE | BGFX_SAMPLER_UVW_CLAMP,
|
||||||
|
ref);
|
||||||
|
auto [it, check] = resources.emplace(file, res);
|
||||||
|
return &std::get<Resource<K_R_Still>>(it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
bgfx::ShaderHandle LoadShader(const std::filesystem::path& file_path) {
|
||||||
|
FILE *file = fopen(file_path.c_str(), "rb");
|
||||||
|
fseek(file, 0, SEEK_END);
|
||||||
|
long fileSize = ftell(file);
|
||||||
|
fseek(file, 0, SEEK_SET);
|
||||||
|
|
||||||
|
const bgfx::Memory *mem = bgfx::alloc(fileSize + 1);
|
||||||
|
fread(mem->data, 1, fileSize, file);
|
||||||
|
mem->data[mem->size - 1] = '\0';
|
||||||
|
fclose(file);
|
||||||
|
|
||||||
|
return bgfx::createShader(mem);
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource<K_R_ShaderProgram> *LoadShaderProgram(const String& shader_name) {
|
||||||
|
const auto frag = shader_path / (shader_name + ".frag.bin"),
|
||||||
|
vert = shader_path / (shader_name + ".vert.bin");
|
||||||
|
auto [iter, check] = resources.emplace(shader_name, Resource<K_R_ShaderProgram>{
|
||||||
|
.frag_last_updated = std::filesystem::last_write_time(frag),
|
||||||
|
.pg = bgfx::createProgram(LoadShader(vert), LoadShader(frag), true)
|
||||||
|
});
|
||||||
|
return &std::get<Resource<K_R_ShaderProgram>>(iter->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Leave caller responsible for managing the returned handle */
|
||||||
|
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name) {
|
||||||
|
const auto frag = shader_path / (shader_name + ".frag.bin"),
|
||||||
|
vert = shader_path / (shader_name + ".vert.bin");
|
||||||
|
return bgfx::createProgram(LoadShader(vert), LoadShader(frag), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init() {
|
||||||
|
switch (bgfx::getRendererType()) {
|
||||||
|
case bgfx::RendererType::Noop:
|
||||||
|
case bgfx::RendererType::Direct3D11:
|
||||||
|
case bgfx::RendererType::Direct3D12: shader_path = "shaders/dx11/"; break;
|
||||||
|
case bgfx::RendererType::Gnm: shader_path = "shaders/pssl/"; break;
|
||||||
|
case bgfx::RendererType::Metal: shader_path = "shaders/metal/"; break;
|
||||||
|
case bgfx::RendererType::OpenGL: shader_path = "shaders/glsl/"; break;
|
||||||
|
case bgfx::RendererType::OpenGLES: shader_path = "shaders/essl/"; break;
|
||||||
|
case bgfx::RendererType::Vulkan: shader_path = "shaders/spirv/"; break;
|
||||||
|
default: K::LogError("Unsupported renderer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Shutdown() {
|
||||||
|
for (auto& r : resources)
|
||||||
|
std::visit([](auto&& arg){
|
||||||
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
if constexpr (std::is_same_v<T, Resource<K_R_Still>>) {
|
||||||
|
bgfx::destroy(arg.tex);
|
||||||
|
stbi_image_free(arg.buf);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource<K_R_ShaderProgram>>) {
|
||||||
|
bgfx::destroy(arg.pg);
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource<K_R_StillSequence>>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource<K_R_VideoAudio>>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource<K_R_AudioOnly>>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}, r.second);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,17 @@
|
||||||
#include <ShaderGraph.h>
|
#include <ShaderGraph.h>
|
||||||
#include "srell.hpp"
|
//#include "srell.hpp"
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
K::String BuildNode(const K::ShaderGraph::NodeInstance& n) {
|
K::String BuildNode(const K::ShaderGraph::NodeInstance& n) {
|
||||||
K::String r = n.node->shader_template;
|
K::String r = n.node->shader_template;
|
||||||
for (u32 i = 0; i < n.node->inputs.size(); i++) {
|
// for (u32 i = 0; i < n.node->inputs.size(); i++) {
|
||||||
K::String sub{};
|
// K::String sub{};
|
||||||
if (n.inputs[i] != nullptr)
|
// if (n.inputs[i] != nullptr)
|
||||||
sub = BuildNode(*n.inputs[i]);
|
// sub = BuildNode(*n.inputs[i]);
|
||||||
else
|
// else
|
||||||
sub = K::ShaderGraph::VarToString(n.values[i]); // should be made into uniform instead !!
|
// sub = K::ShaderGraph::VarToString(n.values[i]); // should be made into uniform instead !!
|
||||||
r = srell::regex_replace(r, srell::regex("\\{" + std::to_string(i) + "\\}"), sub);
|
// r = srell::regex_replace(r, srell::regex("\\{" + std::to_string(i) + "\\}"), sub);
|
||||||
}
|
// }
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,8 +140,6 @@ namespace K::UI {
|
||||||
save = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK | BGFX_TEXTURE_BLIT_DST);
|
save = bgfx::createTexture2D(s.width, s.height, false, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK | BGFX_TEXTURE_BLIT_DST);
|
||||||
save_buffer = static_cast<Byte *>(std::malloc(s.width * s.height * 4));
|
save_buffer = static_cast<Byte *>(std::malloc(s.width * s.height * 4));
|
||||||
|
|
||||||
bg.pg = K::Graphics::load_shader_program("Checkerboard");
|
|
||||||
bg.add_uniform("f_hw", ShaderGraph::Type::T_XYZ);
|
|
||||||
bg.uniforms.begin()->second.val = ShaderGraph::XYZ{ static_cast<f32>(s.width), static_cast<f32>(s.height), 0.0f };
|
bg.uniforms.begin()->second.val = ShaderGraph::XYZ{ static_cast<f32>(s.width), static_cast<f32>(s.height), 0.0f };
|
||||||
|
|
||||||
bx::mtxOrtho(proj, 0.0f, static_cast<f32>(s.width), 0.0f, static_cast<f32>(s.height),
|
bx::mtxOrtho(proj, 0.0f, static_cast<f32>(s.width), 0.0f, static_cast<f32>(s.height),
|
||||||
|
@ -164,10 +162,6 @@ namespace K::UI {
|
||||||
bgfx::destroy(save);
|
bgfx::destroy(save);
|
||||||
std::free(save_buffer);
|
std::free(save_buffer);
|
||||||
|
|
||||||
bgfx::destroy(bg.pg);
|
|
||||||
bgfx::destroy(bg.uniforms.begin()->second.handle);
|
|
||||||
bg.uniforms.erase(bg.uniforms.begin());
|
|
||||||
|
|
||||||
for (auto& layer : s.layers)
|
for (auto& layer : s.layers)
|
||||||
layer.track.clear();
|
layer.track.clear();
|
||||||
}
|
}
|
||||||
|
@ -1311,7 +1305,28 @@ namespace K::UI {
|
||||||
|
|
||||||
void Assets(CompState& s) {
|
void Assets(CompState& s) {
|
||||||
if (ImGui::Begin("Assets", &draw_assets)) {
|
if (ImGui::Begin("Assets", &draw_assets)) {
|
||||||
ImGui::Text("mmoker");
|
for (auto& r : Resource::resources) {
|
||||||
|
std::visit([](auto&& arg){
|
||||||
|
using T = std::decay_t<decltype(arg)>;
|
||||||
|
if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_Still>>) {
|
||||||
|
ImGui::Text("Still");
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_ShaderProgram>>) {
|
||||||
|
ImGui::Text("Shader");
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_StillSequence>>) {
|
||||||
|
ImGui::Text("Sequence");
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_VideoAudio>>) {
|
||||||
|
ImGui::Text("Video");
|
||||||
|
}
|
||||||
|
else if constexpr (std::is_same_v<T, Resource::Resource<Resource::K_R_AudioOnly>>) {
|
||||||
|
ImGui::Text("Audio");
|
||||||
|
}
|
||||||
|
}, r.second);
|
||||||
|
ImGui::SameLine();
|
||||||
|
ImGui::Text("%s", r.first.c_str());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
||||||
|
@ -1369,9 +1384,15 @@ namespace K::UI {
|
||||||
default:
|
default:
|
||||||
LogError("Unsupported Renderer");
|
LogError("Unsupported Renderer");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bg.pg = Resource::LoadShaderProgram("Checkerboard")->pg;
|
||||||
|
bg.add_uniform("f_hw", ShaderGraph::Type::T_XYZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Shutdown(CompState& s) {
|
void Shutdown(CompState& s) {
|
||||||
|
bgfx::destroy(bg.uniforms.begin()->second.handle);
|
||||||
|
bg.uniforms.erase(bg.uniforms.begin());
|
||||||
|
|
||||||
DestroyViewport(s);
|
DestroyViewport(s);
|
||||||
ImGui_Implbgfx_Shutdown();
|
ImGui_Implbgfx_Shutdown();
|
||||||
ImGui_ImplSDL2_Shutdown();
|
ImGui_ImplSDL2_Shutdown();
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace K {
|
||||||
bgfx::setUniform(u.handle, pack);
|
bgfx::setUniform(u.handle, pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::DrawTextureWithTransform(view_id, Graphics::mmaker->tx, transform,
|
Graphics::DrawTextureWithTransform(view_id, Graphics::mmaker->tex, transform,
|
||||||
BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A, pg);
|
BGFX_STATE_WRITE_RGB | BGFX_STATE_WRITE_A, pg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ namespace K {
|
||||||
}
|
}
|
||||||
for (auto& u : uniforms) {
|
for (auto& u : uniforms) {
|
||||||
f << "# define " << u.first << " __" << u.first;
|
f << "# define " << u.first << " __" << u.first;
|
||||||
std::visit([&u, &f](auto&& arg) {
|
std::visit([&f](auto&& arg) {
|
||||||
using T = std::decay_t<decltype(arg)>;
|
using T = std::decay_t<decltype(arg)>;
|
||||||
if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Float>::type> || std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Int>::type>)
|
if constexpr (std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Float>::type> || std::is_same_v<T, ShaderGraph::T_Map<ShaderGraph::T_Int>::type>)
|
||||||
f << ".x";
|
f << ".x";
|
||||||
|
@ -156,7 +156,7 @@ namespace K {
|
||||||
|
|
||||||
if (std::system(s.c_str()) == 0) {
|
if (std::system(s.c_str()) == 0) {
|
||||||
if (isValid(pg)) bgfx::destroy(pg);
|
if (isValid(pg)) bgfx::destroy(pg);
|
||||||
pg = Graphics::load_shader_program("temp");
|
pg = Resource::FetchUnmanagedShaderProgram("temp");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log("User shader compilation failed");
|
Log("User shader compilation failed");
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace K {
|
||||||
template <typename T> using Vector = std::vector<T>;
|
template <typename T> using Vector = std::vector<T>;
|
||||||
template <typename T, typename U> using Dict = std::unordered_map<T, U>; // to be replaced
|
template <typename T, typename U> using Dict = std::unordered_map<T, U>; // to be replaced
|
||||||
|
|
||||||
inline void LogBase(const std::string_view& s, u8 level) {
|
inline void LogBase(const String& s, u8 level) {
|
||||||
static const char *levels[] = {
|
static const char *levels[] = {
|
||||||
"Info",
|
"Info",
|
||||||
"Warning",
|
"Warning",
|
||||||
|
@ -33,10 +33,10 @@ namespace K {
|
||||||
};
|
};
|
||||||
level > 1 ? std::cerr : std::cout << "[" << levels[level] << "] Keishiki: " << s << std::endl;
|
level > 1 ? std::cerr : std::cout << "[" << levels[level] << "] Keishiki: " << s << std::endl;
|
||||||
}
|
}
|
||||||
inline void Log(const std::string_view& s) {
|
inline void Log(const String& s) {
|
||||||
LogBase(s, 0);
|
LogBase(s, 0);
|
||||||
}
|
}
|
||||||
inline void LogError(const std::string_view& s) {
|
inline void LogError(const String& s) {
|
||||||
LogBase(s, 2);
|
LogBase(s, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include <Resource.h>
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
|
||||||
#include <bgfx/bgfx.h>
|
#include <bgfx/bgfx.h>
|
||||||
|
|
||||||
namespace K::Graphics {
|
namespace K::Graphics {
|
||||||
|
extern const Resource::Resource<Resource::Type::K_R_Still> *mmaker; // TEMP
|
||||||
|
|
||||||
enum VIEW_ID {
|
enum VIEW_ID {
|
||||||
K_VIEW_UI,
|
K_VIEW_UI,
|
||||||
K_VIEW_LOGO,
|
K_VIEW_LOGO,
|
||||||
|
@ -18,18 +21,9 @@ namespace K::Graphics {
|
||||||
bool Init(u16 width, u16 height);
|
bool Init(u16 width, u16 height);
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
|
|
||||||
bgfx::ProgramHandle load_shader_program(const std::string& FILENAME);
|
|
||||||
|
|
||||||
struct ImageTexture {
|
|
||||||
i32 w, h, channels;
|
|
||||||
u8 *buffer;
|
|
||||||
bgfx::TextureHandle tx;
|
|
||||||
};
|
|
||||||
ImageTexture *GetImageTextureFromFile(const std::string& file); // Caller not responsible for freeing
|
|
||||||
|
|
||||||
void DrawTextureWithTransform(u32 view_id, const bgfx::TextureHandle& tex, f32 mtx[16], u64 state, const bgfx::ProgramHandle& pg);
|
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 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 DrawTextureImageAlpha(u32 view_id, const Resource::Resource<Resource::K_R_Still>& 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);
|
void DrawTextureStencilAlpha(u32 view_id, const bgfx::TextureHandle& tex, i32 pos_x, i32 pos_y, u32 w, u32 h);
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
|
@ -81,6 +75,7 @@ namespace K::Graphics {
|
||||||
|
|
||||||
K_V_Count
|
K_V_Count
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *BlendingToString[] = {
|
static const char *BlendingToString[] = {
|
||||||
"Alpha Over",
|
"Alpha Over",
|
||||||
|
|
||||||
|
@ -123,8 +118,6 @@ namespace K::Graphics {
|
||||||
|
|
||||||
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]);
|
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;
|
|
||||||
|
|
||||||
f64 GetCubicUniqueReal(f64 a, f64 b, f64 c, f64 d);
|
f64 GetCubicUniqueReal(f64 a, f64 b, f64 c, f64 d);
|
||||||
f64 CubicBezier(f64 a, f64 b, f64 c, f64 d, f64 t);
|
f64 CubicBezier(f64 a, f64 b, f64 c, f64 d, f64 t);
|
||||||
f64 InjectingCubicBezierFromX(f64 p2x, f64 p2y, f64 p3x, f64 p3y, f64 x);
|
f64 InjectingCubicBezierFromX(f64 p2x, f64 p2y, f64 p3x, f64 p3y, f64 x);
|
||||||
|
|
74
Keishiki/include/Resource.h
Normal file
74
Keishiki/include/Resource.h
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Common.h>
|
||||||
|
#include <bgfx/bgfx.h>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
namespace K::Resource {
|
||||||
|
extern std::filesystem::path ffmpeg_path;
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
K_R_Still,
|
||||||
|
K_R_StillSequence,
|
||||||
|
K_R_VideoAudio,
|
||||||
|
K_R_AudioOnly,
|
||||||
|
K_R_ShaderProgram,
|
||||||
|
|
||||||
|
// todo other data
|
||||||
|
K_R_Count
|
||||||
|
};
|
||||||
|
|
||||||
|
template <Type T>
|
||||||
|
struct Resource {
|
||||||
|
std::filesystem::file_time_type last_updated;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Resource<K_R_Still> {
|
||||||
|
std::filesystem::file_time_type last_updated;
|
||||||
|
bgfx::TextureHandle tex;
|
||||||
|
u8 *buf;
|
||||||
|
i32 h, w, channels;
|
||||||
|
bgfx::TextureFormat::Enum format;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Resource<K_R_StillSequence> {
|
||||||
|
std::filesystem::file_time_type last_updated;
|
||||||
|
u32 frames;
|
||||||
|
Vector<bgfx::TextureHandle> tex;
|
||||||
|
u32 h, w;
|
||||||
|
bgfx::TextureFormat::Enum format;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Resource<K_R_VideoAudio> {
|
||||||
|
std::filesystem::file_time_type last_updated;
|
||||||
|
u32 frames;
|
||||||
|
Vector<bgfx::TextureHandle> tex;
|
||||||
|
u32 h, w;
|
||||||
|
bgfx::TextureFormat::Enum format;
|
||||||
|
String scratch_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct Resource<K_R_ShaderProgram> {
|
||||||
|
std::filesystem::file_time_type frag_last_updated;
|
||||||
|
bgfx::ProgramHandle pg;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern Dict<std::filesystem::path, std::variant<
|
||||||
|
Resource<K_R_Still>,
|
||||||
|
Resource<K_R_ShaderProgram>,
|
||||||
|
Resource<K_R_StillSequence>,
|
||||||
|
Resource<K_R_VideoAudio>,
|
||||||
|
Resource<K_R_AudioOnly>
|
||||||
|
>> resources;
|
||||||
|
|
||||||
|
void Init();
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
Resource<K_R_Still> *LoadStill(const std::filesystem::path& file);
|
||||||
|
Resource<K_R_ShaderProgram> *LoadShaderProgram(const String& shader_name);
|
||||||
|
bgfx::ProgramHandle FetchUnmanagedShaderProgram(const String& shader_name);
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,12 @@
|
||||||
- [FreeType](https://freetype.org/)
|
- [FreeType](https://freetype.org/)
|
||||||
- [imgui_impl_bgfx](https://gist.github.com/pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb)
|
- [imgui_impl_bgfx](https://gist.github.com/pr0g/aff79b71bf9804ddb03f39ca7c0c3bbb)
|
||||||
- [SDL2](https://www.libsdl.org/)
|
- [SDL2](https://www.libsdl.org/)
|
||||||
|
- [stb](https://github.com/nothings/stb)
|
||||||
- [SRELL](https://www.akenotsuki.com/misc/srell/en/)
|
- [SRELL](https://www.akenotsuki.com/misc/srell/en/)
|
||||||
|
|
||||||
|
## Runtime Dependency
|
||||||
|
- [ffmpeg](https://ffmpeg.org/)
|
||||||
|
|
||||||
## Inspired by
|
## Inspired by
|
||||||
- [Automaton](https://github.com/0b5vr/automaton)
|
- [Automaton](https://github.com/0b5vr/automaton)
|
||||||
- [Blender](https://www.blender.org/)
|
- [Blender](https://www.blender.org/)
|
||||||
|
|
16
TODO.md
16
TODO.md
|
@ -1,6 +1,9 @@
|
||||||
# NOW
|
# NOW
|
||||||
## Chores
|
## UI
|
||||||
- Node groups
|
- Key selection in comp panel
|
||||||
|
- Graph editor
|
||||||
|
- Node loop detection (separate DFS (extra work) or be smart in recursion)
|
||||||
|
- detect time-sensitive nodes in tree and display on timeline
|
||||||
|
|
||||||
## Compositor
|
## Compositor
|
||||||
- Manage Resources
|
- Manage Resources
|
||||||
|
@ -18,11 +21,8 @@
|
||||||
- Non-negotiable - 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)
|
- Non-negotiable - 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)
|
||||||
- Non-negotiable - External data driving (csv, json or something else?) -- use a node to select source
|
- Non-negotiable - External data driving (csv, json or something else?) -- use a node to select source
|
||||||
|
|
||||||
## UI
|
## Chores
|
||||||
- Key selection in comp panel
|
- Node groups
|
||||||
- Graph editor
|
|
||||||
- Node loop detection (separate DFS (extra work) or be smart in recursion)
|
|
||||||
- detect time-sensitive nodes in tree and display on timeline
|
|
||||||
|
|
||||||
# Later
|
# Later
|
||||||
## IO
|
## IO
|
||||||
|
@ -37,6 +37,8 @@
|
||||||
|
|
||||||
## UI
|
## UI
|
||||||
- Adapt nodes for shader graph -- code editor will be fine for now
|
- Adapt nodes for shader graph -- code editor will be fine for now
|
||||||
|
- Shaders were using SRELL, I'm not sure about this anymore because it throws. We are doing dynamic replaces so CTRE can't work. Might be forced to go with PCRE or Re2.
|
||||||
|
|
||||||
- Viewport gizmos (Layer-specific & nodes -- can separate into different tools?) -- Not sure how to go about this
|
- Viewport gizmos (Layer-specific & nodes -- can separate into different tools?) -- Not sure how to go about this
|
||||||
- Baku vec2 drag is good, color drag is not so necessary because imgui has a good picker
|
- Baku vec2 drag is good, color drag is not so necessary because imgui has a good picker
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue