From 06bd795f3aab817247933c979f0c393c37deddaf Mon Sep 17 00:00:00 2001 From: Silverlan Date: Wed, 30 Oct 2024 10:14:21 +0100 Subject: [PATCH] feat(lua): add shader material bindings --- .../shader_material/shader_material.hpp | 9 ++ core/client/src/lua/c_luaclass.cpp | 94 ++++++++++++++++++- 2 files changed, 102 insertions(+), 1 deletion(-) diff --git a/core/client/include/pragma/rendering/shader_material/shader_material.hpp b/core/client/include/pragma/rendering/shader_material/shader_material.hpp index e43ae234e..c0b22dec6 100644 --- a/core/client/include/pragma/rendering/shader_material/shader_material.hpp +++ b/core/client/include/pragma/rendering/shader_material/shader_material.hpp @@ -106,6 +106,15 @@ namespace pragma::rendering::shader_material { } const Property *FindProperty(const char *key) const { return const_cast(this)->FindProperty(key); } + Texture *FindTexture(const char *key) + { + auto it = std::find_if(textures.begin(), textures.end(), [key](const Texture &tex) { return tex.name == key; }); + if(it == textures.end()) + return nullptr; + return &*it; + } + const Texture *FindTexture(const char *key) const { return const_cast(this)->FindTexture(key); } + bool LoadFromUdmData(udm::LinkedPropertyWrapperArg prop, std::string &outErr); std::string ToGlslStruct() const; }; diff --git a/core/client/src/lua/c_luaclass.cpp b/core/client/src/lua/c_luaclass.cpp index 14b245864..4f1db4866 100644 --- a/core/client/src/lua/c_luaclass.cpp +++ b/core/client/src/lua/c_luaclass.cpp @@ -57,6 +57,7 @@ #include "pragma/rendering/shaders/util/c_shader_compose_rma.hpp" #include "pragma/rendering/shaders/post_processing/c_shader_pp_glow.hpp" #include "pragma/rendering/shader_material/shader_material.hpp" +#include "pragma/lua/libraries/ludm.hpp" #include #include #include @@ -66,6 +67,7 @@ #include #include #include +#include #include #include #include @@ -106,6 +108,11 @@ static void reload_textures(CMaterial &mat) mat.SetTexture(pair.first, pair.second); } +static luabind::object shader_mat_value_to_lua_object(lua_State *l, const pragma::rendering::shader_material::PropertyValue &val) +{ + return std::visit([l](const auto &val) { return luabind::object {l, val}; }, val); +} + void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) { auto &modEngine = lua.RegisterLibrary("engine"); @@ -223,6 +230,16 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) if(shaderHandler) shaderHandler(&mat); })); + materialClassDef.def( + "GetPrimaryShader", +[](lua_State *l, ::Material &mat) -> luabind::object { + auto *shader = static_cast(mat).GetPrimaryShader(); + if(!shader) + return Lua::nil; + Lua::shader::push_shader(l, *shader); + auto o = luabind::object {luabind::from_stack(l, -1)}; + Lua::Pop(l, 1); + return o; + }); modGame[materialClassDef]; // prosper TODO @@ -298,6 +315,81 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) modShader[defBindState]; auto defMat = luabind::class_("ShaderMaterial"); + defMat.def( + "__tostring", +[](const pragma::rendering::shader_material::ShaderMaterial &shaderMat) -> std::string { return "ShaderMaterial"; }); + defMat.def( + "FindProperty", +[](const pragma::rendering::shader_material::ShaderMaterial &shaderMat, const std::string &name) -> const pragma::rendering::shader_material::Property * { return shaderMat.FindProperty(name.c_str()); }); + defMat.def( + "FindTexture", +[](const pragma::rendering::shader_material::ShaderMaterial &shaderMat, const std::string &name) -> const pragma::rendering::shader_material::Texture * { return shaderMat.FindTexture(name.c_str()); }); + defMat.def( + "GetProperties", +[](const pragma::rendering::shader_material::ShaderMaterial &shaderMat) -> std::vector { + std::vector props; + props.reserve(shaderMat.properties.size()); + for(auto &prop : shaderMat.properties) + props.push_back(&prop); + return props; + }); + defMat.def( + "GetTextures", +[](const pragma::rendering::shader_material::ShaderMaterial &shaderMat) -> std::vector { + std::vector textures; + textures.reserve(shaderMat.textures.size()); + for(auto &tex : shaderMat.textures) + textures.push_back(&tex); + return textures; + }); + + auto defProp = luabind::class_("Property"); + defProp.def( + "__tostring", +[](const pragma::rendering::shader_material::Property &prop) -> std::string { + std::stringstream ss; + ss << "Property"; + ss << "[" << prop.name << "]"; + ss << "[Type:" << magic_enum::enum_name(prop.type) << "]"; + return ss.str(); + }); + defProp.def_readonly("type", &pragma::rendering::shader_material::Property::type); + defProp.property( + "specializationType", +[](const pragma::rendering::shader_material::Property &prop) -> std::optional { return prop.specializationType ? *prop.specializationType : std::optional {}; }); + defProp.property( + "name", +[](const pragma::rendering::shader_material::Property &prop) -> std::string { return prop.name; }); + defProp.property( + "defaultValue", +[](lua_State *l, const pragma::rendering::shader_material::Property &prop) -> luabind::object { return shader_mat_value_to_lua_object(l, prop.defaultValue); }); + defProp.def_readonly("offset", &pragma::rendering::shader_material::Property::offset); + defProp.def("GetSize", &pragma::rendering::shader_material::Property::GetSize); + defProp.def( + "GetFlags", +[](const pragma::rendering::shader_material::Property &prop) -> std::optional> { + if(!prop.flags) + return {}; + return *prop.flags; + }); + defProp.def( + "GetOptions", +[](lua_State *l, const pragma::rendering::shader_material::Property &prop) -> std::optional> { + if(!prop.options) + return {}; + std::unordered_map options {}; + options.reserve(prop.options->size()); + for(auto &[name, value] : *prop.options) + options[name] = shader_mat_value_to_lua_object(l, value); + return options; + }); + defMat.scope[defProp]; + + auto defTex = luabind::class_("Texture"); + defTex.def( + "__tostring", +[](const pragma::rendering::shader_material::Texture &tex) -> std::string { + std::stringstream ss; + ss << "Texture"; + ss << "[" << tex.name << "]"; + return ss.str(); + }); + defTex.property( + "name", +[](const pragma::rendering::shader_material::Texture &tex) -> std::string { return tex.name; }); + defTex.def_readonly("defaultTexturePath", &pragma::rendering::shader_material::Texture::defaultTexturePath); + defTex.def_readonly("cubemap", &pragma::rendering::shader_material::Texture::cubemap); + defTex.def_readonly("colorMap", &pragma::rendering::shader_material::Texture::colorMap); + defTex.def_readonly("required", &pragma::rendering::shader_material::Texture::required); + defMat.scope[defTex]; + modShader[defMat]; auto defMatData = luabind::class_("ShaderMaterialData"); @@ -423,7 +515,7 @@ void ClientState::RegisterSharedLuaClasses(Lua::Interface &lua, bool bGUI) auto defShaderTextured3D = luabind::class_>("TexturedLit3D"); defShaderTextured3D.add_static_constant("PUSH_CONSTANTS_SIZE", sizeof(pragma::ShaderGameWorldLightingPass::PushConstants)); defShaderTextured3D.add_static_constant("PUSH_CONSTANTS_USER_DATA_OFFSET", sizeof(pragma::ShaderGameWorldLightingPass::PushConstants)); - + defShaderTextured3D.def("GetShaderMaterial", &pragma::ShaderGameWorldLightingPass::GetShaderMaterial); modShader[defShaderTextured3D]; auto defShaderGlow = luabind::class_>("Glow");